From: jenkins-bot Date: Fri, 13 Sep 2019 13:31:24 +0000 (+0000) Subject: Merge "output: Narrow Title type hint to LinkTarget" X-Git-Tag: 1.34.0-rc.0~237 X-Git-Url: https://git.heureux-cyclage.org/?p=lhc%2Fweb%2Fwiklou.git;a=commitdiff_plain;h=e19e6bfabcaf2b6aa5dd837ff7057bd6a25baef8;hp=1fa42d25ec6a72ddc3b0d143b62b38b91cffda5d Merge "output: Narrow Title type hint to LinkTarget" --- diff --git a/RELEASE-NOTES-1.34 b/RELEASE-NOTES-1.34 index 2cebf99a48..07f52d0c1b 100644 --- a/RELEASE-NOTES-1.34 +++ b/RELEASE-NOTES-1.34 @@ -162,8 +162,8 @@ $wgPasswordPolicy['policies']['default']['PasswordNotInLargeBlacklist'] = false; === Action API changes in 1.34 === * The 'recenteditcount' response property from action=query list=allusers, deprecated in 1.25, has been removed. -* (T60993) action=query list=filearchive no longer requires the 'deletedhistory' - user right. +* (T60993) action=query list=filearchive, list=alldeletedrevisions and + prop=deletedrevisions no longer require the 'deletedhistory' user right. === Action API internal changes in 1.34 === * The exception thrown in ApiModuleManager::getModule has been changed @@ -302,6 +302,7 @@ because of Phabricator reports. Use the mediawiki.String module instead. * mw.language.specialCharacters, deprecated in 1.33, has been removed. Use require( 'mediawiki.language.specialCharacters' ) instead. +* The jquery.colorUtil module was removed. Use jquery.color instead. * EditPage::submit(), deprecated in 1.29, has been removed. Use $this->edit() directly. * HTMLForm::getErrors(), deprecated in 1.28, has been removed. Use @@ -560,6 +561,9 @@ because of Phabricator reports. be used instead. * The UserIsHidden hook is deprecated. Use GetUserBlock instead, and add a system block that hides the user. +* The GetBlockedStatus hook is deprecated. Use GetUserBlock instead, to add or + remove a block. +* $wgContentHandlerUseDB is deprecated and should always be true. === Other changes in 1.34 === * … diff --git a/composer.json b/composer.json index c1f9037fb3..5785873bbe 100644 --- a/composer.json +++ b/composer.json @@ -28,7 +28,7 @@ "ext-xml": "*", "guzzlehttp/guzzle": "6.3.3", "liuggio/statsd-php-client": "1.0.18", - "oojs/oojs-ui": "0.34.0", + "oojs/oojs-ui": "0.34.1", "pear/mail": "1.4.1", "pear/mail_mime": "1.10.2", "pear/net_smtp": "1.8.1", diff --git a/docs/hooks.txt b/docs/hooks.txt index 43234c6590..43bfd8d4b4 100644 --- a/docs/hooks.txt +++ b/docs/hooks.txt @@ -1585,7 +1585,8 @@ entitled to be in. $user: user to promote. &$promote: groups that will be added. -'GetBlockedStatus': after loading blocking status of an user from the database +'GetBlockedStatus': DEPRECATED since 1.34 - use GetUserBlock instead. After +loading blocking status of a user from the database &$user: user (object) being checked 'GetCacheVaryCookies': Get cookies that should vary cache options. diff --git a/includes/DefaultSettings.php b/includes/DefaultSettings.php index c9bed29398..47fd073153 100644 --- a/includes/DefaultSettings.php +++ b/includes/DefaultSettings.php @@ -8619,6 +8619,7 @@ $wgContentHandlerTextFallback = 'ignore'; * handling is less robust and less flexible. * * @since 1.21 + * @deprecated since 1.34, and should always be set true. */ $wgContentHandlerUseDB = true; diff --git a/includes/Revision/RevisionRecord.php b/includes/Revision/RevisionRecord.php index ff9ac579e8..759180a984 100644 --- a/includes/Revision/RevisionRecord.php +++ b/includes/Revision/RevisionRecord.php @@ -531,8 +531,6 @@ abstract class RevisionRecord { $text = $title->getPrefixedText(); wfDebug( "Checking for $permissionlist on $text due to $field match on $bitfield\n" ); - $permissionManager = MediaWikiServices::getInstance()->getPermissionManager(); - foreach ( $permissions as $perm ) { if ( $permissionManager->userCan( $perm, $user, $title ) ) { return true; diff --git a/includes/ServiceWiring.php b/includes/ServiceWiring.php index 0b0aaf54c8..689a98e482 100644 --- a/includes/ServiceWiring.php +++ b/includes/ServiceWiring.php @@ -107,13 +107,10 @@ return [ }, 'BlockManager' => function ( MediaWikiServices $services ) : BlockManager { - $context = RequestContext::getMain(); return new BlockManager( new ServiceOptions( BlockManager::$constructorOptions, $services->getMainConfig() ), - $context->getUser(), - $context->getRequest(), $services->getPermissionManager() ); }, @@ -545,7 +542,8 @@ return [ $services->getContentLanguage(), AuthManager::singleton(), $services->getLinkRendererFactory()->create(), - $services->getNamespaceInfo() + $services->getNamespaceInfo(), + $services->getPermissionManager() ); $factory->setLogger( LoggerFactory::getInstance( 'preferences' ) ); diff --git a/includes/Setup.php b/includes/Setup.php index 39f0c8116f..518531aacf 100644 --- a/includes/Setup.php +++ b/includes/Setup.php @@ -808,22 +808,17 @@ if ( !defined( 'MW_NO_SESSION' ) && !$wgCommandLineMode ) { // Initialize the session try { $session = MediaWiki\Session\SessionManager::getGlobalSession(); - } catch ( OverflowException $ex ) { - if ( isset( $ex->sessionInfos ) && count( $ex->sessionInfos ) >= 2 ) { - // The exception is because the request had multiple possible - // sessions tied for top priority. Report this to the user. - $list = []; - foreach ( $ex->sessionInfos as $info ) { - $list[] = $info->getProvider()->describe( $wgContLang ); - } - $list = $wgContLang->listToText( $list ); - throw new HttpError( 400, - Message::newFromKey( 'sessionmanager-tie', $list )->inLanguage( $wgContLang )->plain() - ); + } catch ( MediaWiki\Session\SessionOverflowException $ex ) { + // The exception is because the request had multiple possible + // sessions tied for top priority. Report this to the user. + $list = []; + foreach ( $ex->getSessionInfos() as $info ) { + $list[] = $info->getProvider()->describe( $wgContLang ); } - - // Not the one we want, rethrow - throw $ex; + $list = $wgContLang->listToText( $list ); + throw new HttpError( 400, + Message::newFromKey( 'sessionmanager-tie', $list )->inLanguage( $wgContLang )->plain() + ); } if ( $session->isPersistent() ) { diff --git a/includes/Storage/DerivedPageDataUpdater.php b/includes/Storage/DerivedPageDataUpdater.php index 4903cf0095..b2c003ab4c 100644 --- a/includes/Storage/DerivedPageDataUpdater.php +++ b/includes/Storage/DerivedPageDataUpdater.php @@ -1531,7 +1531,9 @@ class DerivedPageDataUpdater implements IDBAccessObject, LoggerAwareInterface { if ( $this->options['changed'] && $title->getNamespace() == NS_USER_TALK && $shortTitle != $legacyUser->getTitleKey() - && !( $this->revision->isMinor() && $legacyUser->isAllowed( 'nominornewtalk' ) ) + && !( $this->revision->isMinor() && MediaWikiServices::getInstance() + ->getPermissionManager() + ->userHasRight( $legacyUser, 'nominornewtalk' ) ) ) { $recipient = User::newFromName( $shortTitle, false ); if ( !$recipient ) { diff --git a/includes/StreamFile.php b/includes/StreamFile.php index 2ad42e5616..2afd6519a1 100644 --- a/includes/StreamFile.php +++ b/includes/StreamFile.php @@ -25,8 +25,10 @@ */ class StreamFile { // Do not send any HTTP headers unless requested by caller (e.g. body only) + /** @deprecated since 1.34 */ const STREAM_HEADLESS = HTTPFileStreamer::STREAM_HEADLESS; // Do not try to tear down any PHP output buffers + /** @deprecated since 1.34 */ const STREAM_ALLOW_OB = HTTPFileStreamer::STREAM_ALLOW_OB; /** @@ -105,7 +107,6 @@ class StreamFile { case 'png': return 'image/png'; case 'jpg': - return 'image/jpeg'; case 'jpeg': return 'image/jpeg'; } diff --git a/includes/Title.php b/includes/Title.php index 1e93c44250..bdff7a759f 100644 --- a/includes/Title.php +++ b/includes/Title.php @@ -1059,7 +1059,7 @@ class Title implements LinkTarget, IDBAccessObject { $this->lazyFillContentModel( $this->loadFieldFromDB( 'page_content_model', $flags ) ); } elseif ( ( !$this->mContentModel || $flags & self::GAID_FOR_UPDATE ) && - $this->getArticleId( $flags ) + $this->getArticleID( $flags ) ) { $linkCache = MediaWikiServices::getInstance()->getLinkCache(); $linkCache->addLinkObj( $this ); # in case we already had an article ID @@ -4270,12 +4270,21 @@ class Title implements LinkTarget, IDBAccessObject { * on the number of links. Typically called on create and delete. */ public function touchLinks() { - DeferredUpdates::addUpdate( new HTMLCacheUpdate( $this, 'pagelinks', 'page-touch' ) ); + $jobs = []; + $jobs[] = HTMLCacheUpdateJob::newForBacklinks( + $this, + 'pagelinks', + [ 'causeAction' => 'page-touch' ] + ); if ( $this->mNamespace == NS_CATEGORY ) { - DeferredUpdates::addUpdate( - new HTMLCacheUpdate( $this, 'categorylinks', 'category-touch' ) + $jobs[] = HTMLCacheUpdateJob::newForBacklinks( + $this, + 'categorylinks', + [ 'causeAction' => 'category-touch' ] ); } + + JobQueueGroup::singleton()->lazyPush( $jobs ); } /** diff --git a/includes/actions/InfoAction.php b/includes/actions/InfoAction.php index 207721e583..9a8949f587 100644 --- a/includes/actions/InfoAction.php +++ b/includes/actions/InfoAction.php @@ -280,11 +280,10 @@ class InfoAction extends FormlessAction { // Language in which the page content is (supposed to be) written $pageLang = $title->getPageLanguage()->getCode(); - $permissionManager = $services->getPermissionManager(); - $pageLangHtml = $pageLang . ' - ' . Language::fetchLanguageName( $pageLang, $lang->getCode() ); // Link to Special:PageLanguage with pre-filled page title if user has permissions + $permissionManager = $services->getPermissionManager(); if ( $config->get( 'PageLanguageUseDB' ) && $permissionManager->userCan( 'pagelang', $user, $title ) ) { @@ -344,8 +343,7 @@ class InfoAction extends FormlessAction { ]; $unwatchedPageThreshold = $config->get( 'UnwatchedPageThreshold' ); - if ( - $services->getPermissionManager()->userHasRight( $user, 'unwatchedpages' ) || + if ( $permissionManager->userHasRight( $user, 'unwatchedpages' ) || ( $unwatchedPageThreshold !== false && $pageCounts['watchers'] >= $unwatchedPageThreshold ) ) { @@ -360,7 +358,7 @@ class InfoAction extends FormlessAction { ) { $minToDisclose = $config->get( 'UnwatchedPageSecret' ); if ( $pageCounts['visitingWatchers'] > $minToDisclose || - $services->getPermissionManager()->userHasRight( $user, 'unwatchedpages' ) ) { + $permissionManager->userHasRight( $user, 'unwatchedpages' ) ) { $pageInfo['header-basic'][] = [ $this->msg( 'pageinfo-visiting-watchers' ), $lang->formatNum( $pageCounts['visitingWatchers'] ) diff --git a/includes/api/ApiQueryAllDeletedRevisions.php b/includes/api/ApiQueryAllDeletedRevisions.php index 7d6d342113..2a499844a4 100644 --- a/includes/api/ApiQueryAllDeletedRevisions.php +++ b/includes/api/ApiQueryAllDeletedRevisions.php @@ -43,9 +43,6 @@ class ApiQueryAllDeletedRevisions extends ApiQueryRevisionsBase { * @return void */ protected function run( ApiPageSet $resultPageSet = null ) { - // Before doing anything at all, let's check permissions - $this->checkUserRightsAny( 'deletedhistory' ); - $user = $this->getUser(); $db = $this->getDB(); $params = $this->extractRequestParams( false ); @@ -144,8 +141,15 @@ class ApiQueryAllDeletedRevisions extends ApiQueryRevisionsBase { } // This means stricter restrictions - if ( $this->fetchContent ) { - $this->checkUserRightsAny( [ 'deletedtext', 'undelete' ] ); + if ( ( $this->fld_comment || $this->fld_parsedcomment ) && + !$this->getPermissionManager()->userHasRight( $user, 'deletedhistory' ) + ) { + $this->dieWithError( 'apierror-cantview-deleted-comment', 'permissiondenied' ); + } + if ( $this->fetchContent && + !$this->getPermissionManager()->userHasAnyRight( $user, 'deletedtext', 'undelete' ) + ) { + $this->dieWithError( 'apierror-cantview-deleted-revision-content', 'permissiondenied' ); } $miser_ns = null; @@ -235,8 +239,6 @@ class ApiQueryAllDeletedRevisions extends ApiQueryRevisionsBase { if ( !is_null( $params['user'] ) || !is_null( $params['excludeuser'] ) ) { // Paranoia: avoid brute force searches (T19342) - // (shouldn't be able to get here without 'deletedhistory', but - // check it again just in case) if ( !$this->getPermissionManager()->userHasRight( $user, 'deletedhistory' ) ) { $bitmask = RevisionRecord::DELETED_USER; } elseif ( !$this->getPermissionManager() diff --git a/includes/api/ApiQueryDeletedRevisions.php b/includes/api/ApiQueryDeletedRevisions.php index fc88499885..12fd20ae59 100644 --- a/includes/api/ApiQueryDeletedRevisions.php +++ b/includes/api/ApiQueryDeletedRevisions.php @@ -40,8 +40,6 @@ class ApiQueryDeletedRevisions extends ApiQueryRevisionsBase { protected function run( ApiPageSet $resultPageSet = null ) { $user = $this->getUser(); - // Before doing anything at all, let's check permissions - $this->checkUserRightsAny( 'deletedhistory' ); $pageSet = $this->getPageSet(); $pageMap = $pageSet->getGoodAndMissingTitlesByNamespace(); @@ -95,8 +93,15 @@ class ApiQueryDeletedRevisions extends ApiQueryRevisionsBase { } // This means stricter restrictions - if ( $this->fetchContent ) { - $this->checkUserRightsAny( [ 'deletedtext', 'undelete' ] ); + if ( ( $this->fld_comment || $this->fld_parsedcomment ) && + !$this->getPermissionManager()->userHasRight( $user, 'deletedhistory' ) + ) { + $this->dieWithError( 'apierror-cantview-deleted-comment', 'permissiondenied' ); + } + if ( $this->fetchContent && + !$this->getPermissionManager()->userHasAnyRight( $user, 'deletedtext', 'undelete' ) + ) { + $this->dieWithError( 'apierror-cantview-deleted-revision-content', 'permissiondenied' ); } $dir = $params['dir']; @@ -130,8 +135,6 @@ class ApiQueryDeletedRevisions extends ApiQueryRevisionsBase { if ( !is_null( $params['user'] ) || !is_null( $params['excludeuser'] ) ) { // Paranoia: avoid brute force searches (T19342) - // (shouldn't be able to get here without 'deletedhistory', but - // check it again just in case) if ( !$this->getPermissionManager()->userHasRight( $user, 'deletedhistory' ) ) { $bitmask = RevisionRecord::DELETED_USER; } elseif ( !$this->getPermissionManager() diff --git a/includes/api/ApiQueryStashImageInfo.php b/includes/api/ApiQueryStashImageInfo.php index 1924ca0339..c84de8c974 100644 --- a/includes/api/ApiQueryStashImageInfo.php +++ b/includes/api/ApiQueryStashImageInfo.php @@ -70,11 +70,37 @@ class ApiQueryStashImageInfo extends ApiQueryImageInfo { } } - private $propertyFilter = [ + private static $propertyFilter = [ 'user', 'userid', 'comment', 'parsedcomment', 'mediatype', 'archivename', 'uploadwarning', ]; + /** + * Returns all possible parameters to siiprop + * + * @param array|null $filter List of properties to filter out + * @return array + */ + public static function getPropertyNames( $filter = null ) { + if ( $filter === null ) { + $filter = self::$propertyFilter; + } + return parent::getPropertyNames( $filter ); + } + + /** + * Returns messages for all possible parameters to siiprop + * + * @param array|null $filter List of properties to filter out + * @return array + */ + public static function getPropertyMessages( $filter = null ) { + if ( $filter === null ) { + $filter = self::$propertyFilter; + } + return parent::getPropertyMessages( $filter ); + } + public function getAllowedParams() { return [ 'filekey' => [ @@ -87,9 +113,9 @@ class ApiQueryStashImageInfo extends ApiQueryImageInfo { 'prop' => [ ApiBase::PARAM_ISMULTI => true, ApiBase::PARAM_DFLT => 'timestamp|url', - ApiBase::PARAM_TYPE => self::getPropertyNames( $this->propertyFilter ), + ApiBase::PARAM_TYPE => self::getPropertyNames(), ApiBase::PARAM_HELP_MSG => 'apihelp-query+imageinfo-param-prop', - ApiBase::PARAM_HELP_MSG_PER_VALUE => self::getPropertyMessages( $this->propertyFilter ) + ApiBase::PARAM_HELP_MSG_PER_VALUE => self::getPropertyMessages() ], 'urlwidth' => [ ApiBase::PARAM_TYPE => 'integer', diff --git a/includes/api/ApiResetPassword.php b/includes/api/ApiResetPassword.php index 77838269b4..6b1c217017 100644 --- a/includes/api/ApiResetPassword.php +++ b/includes/api/ApiResetPassword.php @@ -21,6 +21,7 @@ */ use MediaWiki\Auth\AuthManager; +use MediaWiki\MediaWikiServices; /** * Reset password, with AuthManager @@ -63,7 +64,11 @@ class ApiResetPassword extends ApiBase { $this->requireOnlyOneParameter( $params, 'user', 'email' ); - $passwordReset = new PasswordReset( $this->getConfig(), AuthManager::singleton() ); + $passwordReset = new PasswordReset( + $this->getConfig(), + AuthManager::singleton(), + MediaWikiServices::getInstance()->getPermissionManager() + ); $status = $passwordReset->isAllowed( $this->getUser() ); if ( !$status->isOK() ) { diff --git a/includes/api/ApiRevisionDelete.php b/includes/api/ApiRevisionDelete.php index 1ee91c21f0..60b24f09f1 100644 --- a/includes/api/ApiRevisionDelete.php +++ b/includes/api/ApiRevisionDelete.php @@ -38,12 +38,6 @@ class ApiRevisionDelete extends ApiBase { $user = $this->getUser(); $this->checkUserRightsAny( RevisionDeleter::getRestriction( $params['type'] ) ); - // @TODO Use PermissionManager::isBlockedFrom() instead. - $block = $user->getBlock(); - if ( $block ) { - $this->dieBlocked( $block ); - } - if ( !$params['ids'] ) { $this->dieWithError( [ 'apierror-paramempty', 'ids' ], 'paramempty_ids' ); } @@ -97,6 +91,10 @@ class ApiRevisionDelete extends ApiBase { $this->dieWithError( [ 'apierror-revdel-needtarget' ], 'needtarget' ); } + if ( $this->getPermissionManager()->isBlockedFrom( $user, $targetObj ) ) { + $this->dieBlocked( $user->getBlock() ); + } + $list = RevisionDeleter::createList( $params['type'], $this->getContext(), $targetObj, $params['ids'] ); diff --git a/includes/api/ApiTag.php b/includes/api/ApiTag.php index aff01830e0..bb6c580385 100644 --- a/includes/api/ApiTag.php +++ b/includes/api/ApiTag.php @@ -20,7 +20,6 @@ */ use MediaWiki\MediaWikiServices; -use MediaWiki\Revision\RevisionStore; /** * @ingroup API @@ -28,7 +27,9 @@ use MediaWiki\Revision\RevisionStore; */ class ApiTag extends ApiBase { - /** @var RevisionStore */ + use ApiBlockInfoTrait; + + /** @var \MediaWiki\Revision\RevisionStore */ private $revisionStore; public function execute() { @@ -40,9 +41,9 @@ class ApiTag extends ApiBase { // make sure the user is allowed $this->checkUserRightsAny( 'changetags' ); - // @TODO Use PermissionManager::isBlockedFrom() instead. + // Fail early if the user is sitewide blocked. $block = $user->getBlock(); - if ( $block ) { + if ( $block && $block->isSitewide() ) { $this->dieBlocked( $block ); } @@ -85,6 +86,7 @@ class ApiTag extends ApiBase { } protected function processIndividual( $type, $params, $id ) { + $user = $this->getUser(); $idResult = [ $type => $id ]; // validate the ID @@ -92,9 +94,30 @@ class ApiTag extends ApiBase { switch ( $type ) { case 'rcid': $valid = RecentChange::newFromId( $id ); + if ( $valid && $this->getPermissionManager()->isBlockedFrom( $user, $valid->getTitle() ) ) { + $idResult['status'] = 'error'; + $idResult += $this->getErrorFormatter()->formatMessage( ApiMessage::create( + 'apierror-blocked', + 'blocked', + [ 'blockinfo' => $this->getBlockDetails( $user->getBlock() ) ] + ) ); + return $idResult; + } break; case 'revid': $valid = $this->revisionStore->getRevisionById( $id ); + if ( + $valid && + $this->getPermissionManager()->isBlockedFrom( $user, $valid->getPageAsLinkTarget() ) + ) { + $idResult['status'] = 'error'; + $idResult += $this->getErrorFormatter()->formatMessage( ApiMessage::create( + 'apierror-blocked', + 'blocked', + [ 'blockinfo' => $this->getBlockDetails( $user->getBlock() ) ] + ) ); + return $idResult; + } break; case 'logid': $valid = self::validateLogId( $id ); diff --git a/includes/api/i18n/ar.json b/includes/api/i18n/ar.json index 09d9c468a5..58d2deed51 100644 --- a/includes/api/i18n/ar.json +++ b/includes/api/i18n/ar.json @@ -1607,8 +1607,10 @@ "apierror-cantoverwrite-sharedfile": "الملف الهدف موجود في مستودع مشترك وليست لديك صلاحية لتجاوزه.", "apierror-cantsend": "لم تقم بتسجيل الدخول أو ليس لديك عنوان بريد إلكتروني مؤكد أو غير مسموح لك بإرسال بريد إلكتروني إلى مستخدمين آخرين; لذلك لا يمكنك إرسال بريد إلكتروني.", "apierror-cantundelete": "تعذر الاسترجاع: قد لا تكون المراجعات المطلوبة موجودة، أو ربما تم الاسترجاع بالفعل.", - "apierror-cantview-deleted-description": "ليست لديك صلايبة لعرض أوصاف الملفات المحذوفة.", - "apierror-cantview-deleted-metadata": "ليست لديك صلايبة لعرض البيانات الوصفية للملفات المحذوفة.", + "apierror-cantview-deleted-comment": "ليست لديك صلاحية لعرض التعليقات المحذوفة.", + "apierror-cantview-deleted-description": "ليست لديك صلاحية لعرض أوصاف الملفات المحذوفة.", + "apierror-cantview-deleted-metadata": "ليست لديك صلاحية لعرض البيانات الوصفية للملفات المحذوفة.", + "apierror-cantview-deleted-revision-content": "ليست لديك صلاحية لعرض محتوى المراجعات المحذوفة.", "apierror-changeauth-norequest": "فشل في إنشاء طلب التغيير.", "apierror-chunk-too-small": "الحد الأدنى لحجم القطعة هو $1 {{PLURAL:$1|بايت}} للقطع غير النهائية.", "apierror-cidrtoobroad": "لا يُقبَل مدى $1 CIDR أكبر من /$2.", diff --git a/includes/api/i18n/en.json b/includes/api/i18n/en.json index 35e45f1005..cc5e872cee 100644 --- a/includes/api/i18n/en.json +++ b/includes/api/i18n/en.json @@ -1727,8 +1727,10 @@ "apierror-cantoverwrite-sharedfile": "The target file exists on a shared repository and you do not have permission to override it.", "apierror-cantsend": "You are not logged in, you do not have a confirmed email address, or you are not allowed to send email to other users, so you cannot send email.", "apierror-cantundelete": "Couldn't undelete: the requested revisions may not exist, or may have been undeleted already.", + "apierror-cantview-deleted-comment": "You don't have permission to view deleted comments.", "apierror-cantview-deleted-description": "You don't have permission to view descriptions of deleted files.", "apierror-cantview-deleted-metadata": "You don't have permission to view metadata of deleted files.", + "apierror-cantview-deleted-revision-content": "You don't have permission to view content of deleted revisions.", "apierror-changeauth-norequest": "Failed to create change request.", "apierror-chunk-too-small": "Minimum chunk size is $1 {{PLURAL:$1|byte|bytes}} for non-final chunks.", "apierror-cidrtoobroad": "$1 CIDR ranges broader than /$2 are not accepted.", diff --git a/includes/api/i18n/fr.json b/includes/api/i18n/fr.json index 7c5d2b5676..5ce00f51a3 100644 --- a/includes/api/i18n/fr.json +++ b/includes/api/i18n/fr.json @@ -37,13 +37,13 @@ "Lucas Werkmeister (WMDE)" ] }, - "apihelp-main-extended-description": "
\n* [[mw:Special:MyLanguage/API:Main_page|Documentation]]\n* [[mw:Special:MyLanguage/API:FAQ|FAQ]]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api Liste de diffusion]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api-announce Annonces de l’API]\n* [https://phabricator.wikimedia.org/maniphest/query/GebfyV4uCaLd/#R Bogues et demandes]\n
\nÉtat : L’API MediaWiki est une interface stable et mature qui est supportée et améliorée de façon active. Bien que nous essayions de l’éviter, nous pouvons avoir parfois besoin de faire des modifications impactantes ; inscrivez-vous à [https://lists.wikimedia.org/pipermail/mediawiki-api-announce/ la liste de diffusion mediawiki-api-announce] pour être informé des mises à jour.\n\nRequêtes erronées : Si des requêtes erronées sont envoyées à l’API, un entête HTTP sera renvoyé avec la clé « MediaWiki-API-Error ». La valeur de cet entête et le code d’erreur renvoyé prendront la même valeur. Pour plus d’information, voyez [[mw:Special:MyLanguage/API:Errors_and_warnings|API:Errors and warnings]].\n\n

Test : Pour faciliter le test des requêtes à l’API, voyez [[Special:ApiSandbox]].

", + "apihelp-main-extended-description": "
\n* [[mw:Special:MyLanguage/API:Main_page|Documentation]]\n* [[mw:Special:MyLanguage/API:FAQ|FAQ]]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api Liste de diffusion]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api-announce Annonces de l’API]\n* [https://phabricator.wikimedia.org/maniphest/query/GebfyV4uCaLd/#R Bogues et demandes]\n
\nÉtat : l’API de MediaWiki est une interface stable et mature qui est supportée et améliorée de façon active. Bien que nous essayions de l’éviter, nous pouvons avoir parfois besoin de faire des modifications impactantes ; inscrivez-vous à [https://lists.wikimedia.org/pipermail/mediawiki-api-announce/ la liste de diffusion ''mediawiki-api-announce''] pour être informé des mises à jour.\n\nRequêtes erronées : si des requêtes erronées sont envoyées à l’API, un entête HTTP sera renvoyé avec la clé « MediaWiki-API-Error ». La valeur de cet entête et le code d’erreur renvoyé prendront la même valeur. Pour plus d’information, voyez [[mw:Special:MyLanguage/API:Errors_and_warnings|API:Errors and warnings]].\n\n

Test : Pour faciliter le test des requêtes à l’API, voyez [[Special:ApiSandbox]].

", "apihelp-main-param-action": "Quelle action effectuer.", "apihelp-main-param-format": "Le format de sortie.", - "apihelp-main-param-maxlag": "La latence maximale peut être utilisée quand MediaWiki est installé sur un cluster de base de données répliqué. Pour éviter des actions provoquant un supplément de latence de réplication de site, ce paramètre peut faire attendre le client jusqu’à ce que la latence de réplication soit inférieure à une valeur spécifiée. En cas de latence excessive, le code d’erreur maxlag est renvoyé avec un message tel que Attente de $host : $lag secondes de délai.
Voyez [[mw:Special:MyLanguage/Manual:Maxlag_parameter|Manuel: paramètre Maxlag]] pour plus d’information.", + "apihelp-main-param-maxlag": "La latence maximale peut être utilisée quand MediaWiki est installé sur une grappe de réplication de base de données. Pour éviter des actions provoquant un supplément de latence de réplication de site, ce paramètre peut faire attendre le client jusqu’à ce que la latence de réplication soit inférieure à une valeur spécifiée. En cas de latence excessive, le code d’erreur maxlag est renvoyé avec un message tel que Attente de $host : $lag secondes de délai.
Voyez [[mw:Special:MyLanguage/Manual:Maxlag_parameter|Manuel : paramètre Maxlag]] pour plus d’informations.", "apihelp-main-param-smaxage": "Fixer l’entête HTTP de contrôle de cache s-maxage à ce nombre de secondes. Les erreurs ne sont jamais mises en cache.", "apihelp-main-param-maxage": "Fixer l’entête HTTP de contrôle de cache max-age à ce nombre de secondes. Les erreurs ne sont jamais mises en cache.", - "apihelp-main-param-assert": "Vérifier si l’utilisateur est connecté si la valeur est user, ou s’il a le droit d’un utilisateur robot si la valeur est bot.", + "apihelp-main-param-assert": "Vérifier que l’utilisateur est connecté lorsque la valeur est user ou qu’il a le droit d’un utilisateur robot lorsque la valeur est bot.", "apihelp-main-param-assertuser": "Vérifier que l’utilisateur actuel est l’utilisateur nommé.", "apihelp-main-param-requestid": "Toute valeur fournie ici sera incluse dans la réponse. Peut être utilisé pour distinguer des demandes.", "apihelp-main-param-servedby": "Inclure le nom d’hôte qui a renvoyé la requête dans les résultats.", @@ -1630,8 +1630,10 @@ "apierror-cantoverwrite-sharedfile": "Le fichier cible existe dans un dépôt partagé et vous n’avez pas le droit de l’écraser.", "apierror-cantsend": "Vous n’êtes pas connecté, vous n’avez pas d’adresse de courriel confirmée, ou vous n’êtes pas autorisé à envoyer des courriels aux autres utilisateurs, donc vous ne pouvez envoyer de courriel.", "apierror-cantundelete": "Impossible d’annuler : les révisions demandées peuvent ne plus exister, ou avoir déjà été annulées.", + "apierror-cantview-deleted-comment": "Vous n’avez pas la permission de visualiser les commentaires supprimés.", "apierror-cantview-deleted-description": "Vous n’avez pas le droit d’afficher les descriptions des fichiers supprimés.", "apierror-cantview-deleted-metadata": "Vous n’avez pas le droit d’afficher les métadonnées des fichiers supprimés.", + "apierror-cantview-deleted-revision-content": "Vous n’avez pas la permission de visualiser le contenu des révisions supprimées.", "apierror-changeauth-norequest": "Échec à la création de la requête de modification.", "apierror-chunk-too-small": "La taille minimale d’un segment est de $1 {{PLURAL:$1|octet|octets}} pour les segments hors le dernier.", "apierror-cidrtoobroad": "Les plages CIDR $1 plus large que /$2 ne sont pas acceptées.", diff --git a/includes/api/i18n/it.json b/includes/api/i18n/it.json index e29c34af24..9d5d349ef9 100644 --- a/includes/api/i18n/it.json +++ b/includes/api/i18n/it.json @@ -684,6 +684,9 @@ "api-help-authmanagerhelper-continue": "Questa richiesta è una continuazione dopo una precedente risposta UI o REDIRECT. È necessario fornirlo, oppure fornire $1returnurl.", "api-help-authmanagerhelper-additional-params": "Questo modulo accetta parametri aggiuntivi a seconda delle richieste di autenticazione disponibili. Utilizza [[Special:ApiHelp/query+authmanagerinfo|action=query&meta=authmanagerinfo]] con amirequestsfor=$1 (o una precedente risposta da questo modulo, se applicabile) per determinare le richieste disponibili e i campi usati da queste.", "apierror-bad-badfilecontexttitle": "Titolo non valido nel parametro $1badfilecontexttitle.", + "apierror-cantview-deleted-description": "Non si dispone dei permessi necessari per vedere le descrizioni dei file cancellati.", + "apierror-cantview-deleted-metadata": "Non si dispone dei permessi necessari per vedere i metadati dei file cancellati.", + "apierror-cantview-deleted-revision-content": "Non si dispone dei permessi necessari per vedere il contenuto delle versioni cancellate.", "apierror-compare-notext": "Il parametro $1 non può essere usato senza $2.", "apierror-invalidoldimage": "Il parametro oldimage ha un formato non valido.", "apierror-invaliduserid": "L'ID utente $1 non è valido.", diff --git a/includes/api/i18n/ko.json b/includes/api/i18n/ko.json index c02963643e..612406692f 100644 --- a/includes/api/i18n/ko.json +++ b/includes/api/i18n/ko.json @@ -845,6 +845,8 @@ "apierror-cantimport-upload": "업로드된 페이지를 가져올 권한이 없습니다.", "apierror-cantimport": "페이지를 가져올 권한이 없습니다.", "apierror-cantsend": "로그인하지 않았거나 인증된 이메일 주소가 없거나 다른 사용자로 이메일을 보낼 권한이 없기 때문에 이메일을 보낼 수 없습니다.", + "apierror-cantview-deleted-description": "삭제된 파일의 설명을 볼 권한이 없습니다.", + "apierror-cantview-deleted-metadata": "삭제된 파일의 메타데이터를 볼 권한이 없습니다.", "apierror-compare-maintextrequired": "$1slots에 main이 포함되어 있다면 $1text-main 변수는 필수입니다. (메인 슬롯을 삭제할 수 없습니다)", "apierror-compare-notext": "$1 변수는 $2 없이 사용할 수 없습니다.", "apierror-emptynewsection": "비어있는 새 문단을 만들 수 없습니다.", diff --git a/includes/api/i18n/mk.json b/includes/api/i18n/mk.json index 59553e92d4..59eb62c751 100644 --- a/includes/api/i18n/mk.json +++ b/includes/api/i18n/mk.json @@ -576,6 +576,10 @@ "apierror-cantchangecontentmodel": "Немате дозвола за менување содржинскиот модел на страница.", "apierror-cantimport-upload": "Немате дозвола да увезувате подигнати страници.", "apierror-cantimport": "Немате дозвола за увезуваање страници.", + "apierror-cantview-deleted-comment": "Немате дозвола за прегледување на избришаните коментари.", + "apierror-cantview-deleted-description": "Немате дозвола за прегледување описи на избришаните податотеки.", + "apierror-cantview-deleted-metadata": "Немате дозвола за прегледување метаподатоци на избришаните податотеки.", + "apierror-cantview-deleted-revision-content": "Немате дозвола за прегледување содржина на избришаните преработки.", "apierror-copyuploadbaddomain": "Подигањето преку URL не е дозволено од овој домен.", "apierror-copyuploadbadurl": "Подигањето не е дозволено од оваа URL-адреса.", "apierror-emptynewsection": "Создавањето на нови празни поднаслови не е дозволено.", diff --git a/includes/api/i18n/pl.json b/includes/api/i18n/pl.json index d8ff5398c1..65a091389c 100644 --- a/includes/api/i18n/pl.json +++ b/includes/api/i18n/pl.json @@ -659,8 +659,10 @@ "apierror-cantimport": "Nie masz uprawnień do importowania stron.", "apierror-cantsend": "Nie jesteś zalogowany, nie masz potwierdzonego adresu e-mail, albo nie masz prawa wysyłać e-maili do innych użytkowników, więc nie możesz wysłać wiadomości e-mail.", "apierror-cantundelete": "Nie można przywrócić: dana wersja nie istnieje albo została już przywrócona.", + "apierror-cantview-deleted-comment": "Nie masz uprawnień do podglądu usuniętych komentarzy.", "apierror-cantview-deleted-description": "Nie masz uprawnień do podglądu opisów usuniętych plików.", "apierror-cantview-deleted-metadata": "Nie masz uprawnień do podglądu metadanych usuniętych plików.", + "apierror-cantview-deleted-revision-content": "Nie masz uprawnień do podglądu treści usuniętych wersji.", "apierror-exceptioncaught": "[$1] Stwierdzono wyjątek: $2", "apierror-filedoesnotexist": "Plik nie istnieje.", "apierror-import-unknownerror": "Nieznany błąd podczas importowania: $1.", diff --git a/includes/api/i18n/pt-br.json b/includes/api/i18n/pt-br.json index 6e2c1f13c2..77f927dd8e 100644 --- a/includes/api/i18n/pt-br.json +++ b/includes/api/i18n/pt-br.json @@ -1610,6 +1610,10 @@ "apierror-cantoverwrite-sharedfile": "O arquivo de destino existe em um repositório compartilhado e você não tem permissão para substituí-lo.", "apierror-cantsend": "Você não está logado, não possui um endereço de e-mail confirmado ou não tem permissão para enviar e-mails para outros usuários, por isso não pode enviar e-mails.", "apierror-cantundelete": "Não foi possível recuperar arquivos: as revisões solicitadas podem não existir ou talvez já tenham sido eliminadas.", + "apierror-cantview-deleted-comment": "Você não tem permissão para visualizar comentários excluídos.", + "apierror-cantview-deleted-description": "Você não tem permissão para visualizar descrições de arquivos excluídos.", + "apierror-cantview-deleted-metadata": "Você não tem permissão para visualizar os metadados dos arquivos excluídos.", + "apierror-cantview-deleted-revision-content": "Você não tem permissão para visualizar o conteúdo das revisões excluídas.", "apierror-changeauth-norequest": "Falha ao criar pedido de mudança.", "apierror-chunk-too-small": "O tamanho mínimo do bloco é $1 {{PLURAL:$1|byte|bytes}} para os pedaços não finais.", "apierror-cidrtoobroad": "Os intervalos CIDR $1 maiores que /$2 não são aceitos.", diff --git a/includes/api/i18n/qqq.json b/includes/api/i18n/qqq.json index e796d25016..b648443729 100644 --- a/includes/api/i18n/qqq.json +++ b/includes/api/i18n/qqq.json @@ -1615,8 +1615,10 @@ "apierror-cantoverwrite-sharedfile": "{{doc-apierror}}", "apierror-cantsend": "{{doc-apierror}}", "apierror-cantundelete": "{{doc-apierror}}", + "apierror-cantview-deleted-comment": "{{doc-apierror}}", "apierror-cantview-deleted-description": "{{doc-apierror}}", "apierror-cantview-deleted-metadata": "{{doc-apierror}}", + "apierror-cantview-deleted-revision-content": "{{doc-apierror}}", "apierror-changeauth-norequest": "{{doc-apierror}}", "apierror-chunk-too-small": "{{doc-apierror}}\n\nParameters:\n* $1 - Minimum size in bytes.", "apierror-cidrtoobroad": "{{doc-apierror}}\n\nParameters:\n* $1 - \"IPv4\" or \"IPv6\"\n* $2 - Minimum CIDR mask length.", diff --git a/includes/block/BlockManager.php b/includes/block/BlockManager.php index e27ebac7ef..2e20529bc8 100644 --- a/includes/block/BlockManager.php +++ b/includes/block/BlockManager.php @@ -41,16 +41,6 @@ use Wikimedia\IPSet; * @since 1.34 Refactored from User and Block. */ class BlockManager { - // TODO: This should be UserIdentity instead of User - /** @var User */ - private $currentUser; - - /** @var WebRequest */ - private $currentRequest; - - /** @var PermissionManager */ - private $permissionManager; - /** * TODO Make this a const when HHVM support is dropped (T192166) * @@ -71,20 +61,14 @@ class BlockManager { /** * @param ServiceOptions $options - * @param User $currentUser - * @param WebRequest $currentRequest * @param PermissionManager $permissionManager */ public function __construct( ServiceOptions $options, - User $currentUser, - WebRequest $currentRequest, PermissionManager $permissionManager ) { $options->assertRequiredOptions( self::$constructorOptions ); $this->options = $options; - $this->currentUser = $currentUser; - $this->currentRequest = $currentRequest; $this->permissionManager = $permissionManager; } @@ -93,51 +77,116 @@ class BlockManager { * return a composite block that combines the strictest features of the applicable * blocks. * - * TODO: $user should be UserIdentity instead of User + * Different blocks may be sought, depending on the user and their permissions. The + * user may be: + * (1) The global user (and can be affected by IP blocks). The global request object + * is needed for checking the IP address, the XFF header and the cookies. + * (2) The global user (and exempt from IP blocks). The global request object is + * needed for checking the cookies. + * (3) Another user (not the global user). No request object is available or needed; + * just look for a block against the user account. + * + * Cases #1 and #2 check whether the global user is blocked in practice; the block + * may due to their user account being blocked or to an IP address block or cookie + * block (or multiple of these). Case #3 simply checks whether a user's account is + * blocked, and does not determine whether the person using that account is affected + * in practice by any IP address or cookie blocks. * * @internal This should only be called by User::getBlockedStatus * @param User $user + * @param WebRequest|null $request The global request object if the user is the + * global user (cases #1 and #2), otherwise null (case #3). The IP address and + * information from the request header are needed to find some types of blocks. * @param bool $fromReplica Whether to check the replica DB first. * To improve performance, non-critical checks are done against replica DBs. * Check when actually saving should be done against master. * @return AbstractBlock|null The most relevant block, or null if there is no block. */ - public function getUserBlock( User $user, $fromReplica ) { - $isAnon = $user->getId() === 0; + public function getUserBlock( User $user, $request, $fromReplica ) { $fromMaster = !$fromReplica; + $ip = null; - // TODO: If $user is the current user, we should use the current request. Otherwise, - // we should not look for XFF or cookie blocks. - $request = $user->getRequest(); + // If this is the global user, they may be affected by IP blocks (case #1), + // or they may be exempt (case #2). If affected, look for additional blocks + // against the IP address. + $checkIpBlocks = $request && + !$this->permissionManager->userHasRight( $user, 'ipblock-exempt' ); - # We only need to worry about passing the IP address to the block generator if the - # user is not immune to autoblocks/hardblocks, and they are the current user so we - # know which IP address they're actually coming from - $ip = null; - $sessionUser = $this->currentUser; - // the session user is set up towards the end of Setup.php. Until then, - // assume it's a logged-out user. - $globalUserName = $sessionUser->isSafeToLoad() - ? $sessionUser->getName() - : IP::sanitizeIP( $this->currentRequest->getIP() ); - if ( $user->getName() === $globalUserName && - !$this->permissionManager->userHasRight( $user, 'ipblock-exempt' ) ) { - $ip = $this->currentRequest->getIP(); + if ( $request && $checkIpBlocks ) { + + // Case #1: checking the global user, including IP blocks + $ip = $request->getIP(); + // TODO: remove dependency on DatabaseBlock (T221075) + $blocks = DatabaseBlock::newListFromTarget( $user, $ip, $fromMaster ); + $this->getAdditionalIpBlocks( $blocks, $request, !$user->isRegistered(), $fromMaster ); + $this->getCookieBlock( $blocks, $user, $request ); + + } elseif ( $request ) { + + // Case #2: checking the global user, but they are exempt from IP blocks + // TODO: remove dependency on DatabaseBlock (T221075) + $blocks = DatabaseBlock::newListFromTarget( $user, null, $fromMaster ); + $this->getCookieBlock( $blocks, $user, $request ); + + } else { + + // Case #3: checking whether a user's account is blocked + // TODO: remove dependency on DatabaseBlock (T221075) + $blocks = DatabaseBlock::newListFromTarget( $user, null, $fromMaster ); + + } + + // Filter out any duplicated blocks, e.g. from the cookie + $blocks = $this->getUniqueBlocks( $blocks ); + + $block = null; + if ( count( $blocks ) > 0 ) { + if ( count( $blocks ) === 1 ) { + $block = $blocks[ 0 ]; + } else { + $block = new CompositeBlock( [ + 'address' => $ip, + 'byText' => 'MediaWiki default', + 'reason' => wfMessage( 'blockedtext-composite-reason' )->plain(), + 'originalBlocks' => $blocks, + ] ); + } } - // User/IP blocking - // After this, $blocks is an array of blocks or an empty array - // TODO: remove dependency on DatabaseBlock - $blocks = DatabaseBlock::newListFromTarget( $user, $ip, $fromMaster ); + Hooks::run( 'GetUserBlock', [ clone $user, $ip, &$block ] ); + + return $block; + } - // Cookie blocking + /** + * Get the cookie block, if there is one. + * + * @param AbstractBlock[] &$blocks + * @param UserIdentity $user + * @param WebRequest $request + * @return void + */ + private function getCookieBlock( &$blocks, UserIdentity $user, WebRequest $request ) { $cookieBlock = $this->getBlockFromCookieValue( $user, $request ); - if ( $cookieBlock instanceof AbstractBlock ) { + if ( $cookieBlock instanceof DatabaseBlock ) { $blocks[] = $cookieBlock; } + } + + /** + * Check for any additional blocks against the IP address or any IPs in the XFF header. + * + * @param AbstractBlock[] &$blocks Blocks found so far + * @param WebRequest $request + * @param bool $isAnon The user is logged out + * @param bool $fromMaster + * @return void + */ + private function getAdditionalIpBlocks( &$blocks, WebRequest $request, $isAnon, $fromMaster ) { + $ip = $request->getIP(); // Proxy blocking - if ( $ip !== null && !in_array( $ip, $this->options->get( 'ProxyWhitelist' ) ) ) { + if ( !in_array( $ip, $this->options->get( 'ProxyWhitelist' ) ) ) { // Local list if ( $this->isLocallyBlockedProxy( $ip ) ) { $blocks[] = new SystemBlock( [ @@ -156,24 +205,8 @@ class BlockManager { } } - // (T25343) Apply IP blocks to the contents of XFF headers, if enabled - if ( $this->options->get( 'ApplyIpBlocksToXff' ) - && $ip !== null - && !in_array( $ip, $this->options->get( 'ProxyWhitelist' ) ) - ) { - $xff = $request->getHeader( 'X-Forwarded-For' ); - $xff = array_map( 'trim', explode( ',', $xff ) ); - $xff = array_diff( $xff, [ $ip ] ); - // TODO: remove dependency on DatabaseBlock - $xffblocks = DatabaseBlock::getBlocksForIPList( $xff, $isAnon, $fromMaster ); - $blocks = array_merge( $blocks, $xffblocks ); - } - // Soft blocking - if ( $ip !== null - && $isAnon - && IP::isInRanges( $ip, $this->options->get( 'SoftBlockRanges' ) ) - ) { + if ( $isAnon && IP::isInRanges( $ip, $this->options->get( 'SoftBlockRanges' ) ) ) { $blocks[] = new SystemBlock( [ 'address' => $ip, 'byText' => 'MediaWiki default', @@ -183,26 +216,17 @@ class BlockManager { ] ); } - // Filter out any duplicated blocks, e.g. from the cookie - $blocks = $this->getUniqueBlocks( $blocks ); - - $block = null; - if ( count( $blocks ) > 0 ) { - if ( count( $blocks ) === 1 ) { - $block = $blocks[ 0 ]; - } else { - $block = new CompositeBlock( [ - 'address' => $ip, - 'byText' => 'MediaWiki default', - 'reason' => wfMessage( 'blockedtext-composite-reason' )->plain(), - 'originalBlocks' => $blocks, - ] ); - } + // (T25343) Apply IP blocks to the contents of XFF headers, if enabled + if ( $this->options->get( 'ApplyIpBlocksToXff' ) + && !in_array( $ip, $this->options->get( 'ProxyWhitelist' ) ) + ) { + $xff = $request->getHeader( 'X-Forwarded-For' ); + $xff = array_map( 'trim', explode( ',', $xff ) ); + $xff = array_diff( $xff, [ $ip ] ); + // TODO: remove dependency on DatabaseBlock (T221075) + $xffblocks = DatabaseBlock::getBlocksForIPList( $xff, $isAnon, $fromMaster ); + $blocks = array_merge( $blocks, $xffblocks ); } - - Hooks::run( 'GetUserBlock', [ clone $user, $ip, &$block ] ); - - return $block; } /** @@ -255,7 +279,7 @@ class BlockManager { $blockCookieId = $this->getIdFromCookieValue( $cookieValue ); if ( !is_null( $blockCookieId ) ) { - // TODO: remove dependency on DatabaseBlock + // TODO: remove dependency on DatabaseBlock (T221075) $block = DatabaseBlock::newFromID( $blockCookieId ); if ( $block instanceof DatabaseBlock && diff --git a/includes/changetags/ChangeTags.php b/includes/changetags/ChangeTags.php index 9ee000d590..ba6cb2ca6b 100644 --- a/includes/changetags/ChangeTags.php +++ b/includes/changetags/ChangeTags.php @@ -524,9 +524,7 @@ class ChangeTags { ->userHasRight( $user, 'applychangetags' ) ) { return Status::newFatal( 'tags-apply-no-permission' ); - } elseif ( $user->getBlock() ) { - // @TODO Ensure that the block does not apply to the `applychangetags` - // right. + } elseif ( $user->getBlock() && $user->getBlock()->isSitewide() ) { return Status::newFatal( 'tags-apply-blocked', $user->getName() ); } } @@ -601,9 +599,7 @@ class ChangeTags { ->userHasRight( $user, 'changetags' ) ) { return Status::newFatal( 'tags-update-no-permission' ); - } elseif ( $user->getBlock() ) { - // @TODO Ensure that the block does not apply to the `changetags` - // right. + } elseif ( $user->getBlock() && $user->getBlock()->isSitewide() ) { return Status::newFatal( 'tags-update-blocked', $user->getName() ); } } @@ -1023,9 +1019,7 @@ class ChangeTags { ->userHasRight( $user, 'managechangetags' ) ) { return Status::newFatal( 'tags-manage-no-permission' ); - } elseif ( $user->getBlock() ) { - // @TODO Ensure that the block does not apply to the `managechangetags` - // right. + } elseif ( $user->getBlock() && $user->getBlock()->isSitewide() ) { return Status::newFatal( 'tags-manage-blocked', $user->getName() ); } } @@ -1099,9 +1093,7 @@ class ChangeTags { ->userHasRight( $user, 'managechangetags' ) ) { return Status::newFatal( 'tags-manage-no-permission' ); - } elseif ( $user->getBlock() ) { - // @TODO Ensure that the block does not apply to the `managechangetags` - // right. + } elseif ( $user->getBlock() && $user->getBlock()->isSitewide() ) { return Status::newFatal( 'tags-manage-blocked', $user->getName() ); } } @@ -1200,9 +1192,7 @@ class ChangeTags { ->userHasRight( $user, 'managechangetags' ) ) { return Status::newFatal( 'tags-manage-no-permission' ); - } elseif ( $user->getBlock() ) { - // @TODO Ensure that the block does not apply to the `managechangetags` - // right. + } elseif ( $user->getBlock() && $user->getBlock()->isSitewide() ) { return Status::newFatal( 'tags-manage-blocked', $user->getName() ); } } @@ -1322,9 +1312,7 @@ class ChangeTags { ->userHasRight( $user, 'deletechangetags' ) ) { return Status::newFatal( 'tags-delete-no-permission' ); - } elseif ( $user->getBlock() ) { - // @TODO Ensure that the block does not apply to the `deletechangetags` - // right. + } elseif ( $user->getBlock() && $user->getBlock()->isSitewide() ) { return Status::newFatal( 'tags-manage-blocked', $user->getName() ); } } diff --git a/includes/deferred/CdnCacheUpdate.php b/includes/deferred/CdnCacheUpdate.php index ddffaa396b..70447489b7 100644 --- a/includes/deferred/CdnCacheUpdate.php +++ b/includes/deferred/CdnCacheUpdate.php @@ -24,12 +24,12 @@ use Wikimedia\Assert\Assert; use MediaWiki\MediaWikiServices; /** - * Handles purging appropriate CDN URLs given a title (or titles) + * Handles purging the appropriate CDN objects given a list of URLs or Title instances * @ingroup Cache */ class CdnCacheUpdate implements DeferrableUpdate, MergeableUpdate { /** @var string[] Collection of URLs to purge */ - protected $urls = []; + private $urls = []; /** * @param string[] $urlArr Collection of URLs to purge @@ -99,10 +99,9 @@ class CdnCacheUpdate implements DeferrableUpdate, MergeableUpdate { wfDebugLog( 'squid', __METHOD__ . ': ' . implode( ' ', $urlArr ) ); // Reliably broadcast the purge to all edge nodes - $relayer = MediaWikiServices::getInstance()->getEventRelayerGroup() - ->getRelayer( 'cdn-url-purges' ); $ts = microtime( true ); - $relayer->notifyMulti( + $relayerGroup = MediaWikiServices::getInstance()->getEventRelayerGroup(); + $relayerGroup->getRelayer( 'cdn-url-purges' )->notifyMulti( 'cdn-url-purges', array_map( function ( $url ) use ( $ts ) { diff --git a/includes/deferred/HTMLCacheUpdate.php b/includes/deferred/HTMLCacheUpdate.php index 29846bfb77..9e45241841 100644 --- a/includes/deferred/HTMLCacheUpdate.php +++ b/includes/deferred/HTMLCacheUpdate.php @@ -22,16 +22,15 @@ */ /** - * Class to invalidate the HTML cache of all the pages linking to a given title. + * Class to invalidate the HTML/file cache of all the pages linking to a given title * * @ingroup Cache */ class HTMLCacheUpdate extends DataUpdate { /** @var Title */ - public $mTitle; - + private $title; /** @var string */ - public $mTable; + private $table; /** * @param Title $titleTo @@ -42,16 +41,16 @@ class HTMLCacheUpdate extends DataUpdate { function __construct( Title $titleTo, $table, $causeAction = 'unknown', $causeAgent = 'unknown' ) { - $this->mTitle = $titleTo; - $this->mTable = $table; + $this->title = $titleTo; + $this->table = $table; $this->causeAction = $causeAction; $this->causeAgent = $causeAgent; } public function doUpdate() { $job = HTMLCacheUpdateJob::newForBacklinks( - $this->mTitle, - $this->mTable, + $this->title, + $this->table, [ 'causeAction' => $this->getCauseAction(), 'causeAgent' => $this->getCauseAgent() ] ); diff --git a/includes/deferred/LinksUpdate.php b/includes/deferred/LinksUpdate.php index 8345ee6575..c4e83413de 100644 --- a/includes/deferred/LinksUpdate.php +++ b/includes/deferred/LinksUpdate.php @@ -1066,6 +1066,7 @@ class LinksUpdate extends DataUpdate { private function invalidateProperties( $changed ) { global $wgPagePropLinkInvalidations; + $jobs = []; foreach ( $changed as $name => $value ) { if ( isset( $wgPagePropLinkInvalidations[$name] ) ) { $inv = $wgPagePropLinkInvalidations[$name]; @@ -1073,12 +1074,16 @@ class LinksUpdate extends DataUpdate { $inv = [ $inv ]; } foreach ( $inv as $table ) { - DeferredUpdates::addUpdate( - new HTMLCacheUpdate( $this->mTitle, $table, 'page-props' ) + $jobs[] = HTMLCacheUpdateJob::newForBacklinks( + $this->mTitle, + $table, + [ 'causeAction' => 'page-props' ] ); } } } + + JobQueueGroup::singleton()->lazyPush( $jobs ); } /** diff --git a/includes/deferred/SearchUpdate.php b/includes/deferred/SearchUpdate.php index a508746c55..84f6fc0eaf 100644 --- a/includes/deferred/SearchUpdate.php +++ b/includes/deferred/SearchUpdate.php @@ -50,7 +50,7 @@ class SearchUpdate implements DeferrableUpdate { */ public function __construct( $id, $title, $c = null ) { if ( is_string( $title ) ) { - wfDeprecated( __METHOD__ . " with a string for the title", 1.34 ); + wfDeprecated( __METHOD__ . " with a string for the title", '1.34' ); $this->title = Title::newFromText( $title ); if ( $this->title === null ) { throw new InvalidArgumentException( "Cannot construct the title: $title" ); @@ -62,10 +62,10 @@ class SearchUpdate implements DeferrableUpdate { $this->id = $id; // is_string() check is back-compat for ApprovedRevs if ( is_string( $c ) ) { - wfDeprecated( __METHOD__ . " with a string for the content", 1.34 ); + wfDeprecated( __METHOD__ . " with a string for the content", '1.34' ); $c = new TextContent( $c ); } elseif ( is_bool( $c ) ) { - wfDeprecated( __METHOD__ . " with a boolean for the content", 1.34 ); + wfDeprecated( __METHOD__ . " with a boolean for the content", '1.34' ); $c = null; } $this->content = $c; diff --git a/includes/export/WikiExporter.php b/includes/export/WikiExporter.php index ec0b344e3c..c1b35954e8 100644 --- a/includes/export/WikiExporter.php +++ b/includes/export/WikiExporter.php @@ -30,6 +30,7 @@ use MediaWiki\MediaWikiServices as MediaWikiServicesAlias; use MediaWiki\Storage\RevisionRecord; use Wikimedia\Rdbms\IResultWrapper; +use Wikimedia\Rdbms\IDatabase; /** * @ingroup SpecialPage Dump @@ -67,7 +68,7 @@ class WikiExporter { /** @var XmlDumpWriter */ private $writer; - /** @var Database */ + /** @var IDatabase */ protected $db; /** @var array|int */ @@ -86,7 +87,7 @@ class WikiExporter { } /** - * @param Database $db + * @param IDatabase $db * @param int|array $history One of WikiExporter::FULL, WikiExporter::CURRENT, * WikiExporter::RANGE or WikiExporter::STABLE, or an associative array: * - offset: non-inclusive offset at which to start the query @@ -303,29 +304,36 @@ class WikiExporter { if ( $cond ) { $where[] = $cond; } - # Get logging table name for logging.* clause - $logging = $this->db->tableName( 'logging' ); - $result = null; // Assuring $result is not undefined, if exception occurs early $commentQuery = CommentStore::getStore()->getJoin( 'log_comment' ); $actorQuery = ActorMigration::newMigration()->getJoin( 'log_user' ); + $tables = array_merge( + [ 'logging' ], $commentQuery['tables'], $actorQuery['tables'], [ 'user' ] + ); + $fields = [ + 'log_id', 'log_type', 'log_action', 'log_timestamp', 'log_namespace', + 'log_title', 'log_params', 'log_deleted', 'user_name' + ] + $commentQuery['fields'] + $actorQuery['fields']; + $options = [ + 'ORDER BY' => 'log_id', + 'USE INDEX' => [ 'logging' => 'PRIMARY' ], + 'LIMIT' => self::BATCH_SIZE, + ]; + $joins = [ + 'user' => [ 'JOIN', 'user_id = ' . $actorQuery['fields']['log_user'] ] + ] + $commentQuery['joins'] + $actorQuery['joins']; + $lastLogId = 0; while ( true ) { $result = $this->db->select( - array_merge( [ 'logging' ], $commentQuery['tables'], $actorQuery['tables'], [ 'user' ] ), - [ "{$logging}.*", 'user_name' ] + $commentQuery['fields'] + $actorQuery['fields'], + $tables, + $fields, array_merge( $where, [ 'log_id > ' . intval( $lastLogId ) ] ), __METHOD__, - [ - 'ORDER BY' => 'log_id', - 'USE INDEX' => [ 'logging' => 'PRIMARY' ], - 'LIMIT' => self::BATCH_SIZE, - ], - [ - 'user' => [ 'JOIN', 'user_id = ' . $actorQuery['fields']['log_user'] ] - ] + $commentQuery['joins'] + $actorQuery['joins'] + $options, + $joins ); if ( !$result->numRows() ) { diff --git a/includes/externalstore/ExternalStoreDB.php b/includes/externalstore/ExternalStoreDB.php index 4db351b25b..264eabcd44 100644 --- a/includes/externalstore/ExternalStoreDB.php +++ b/includes/externalstore/ExternalStoreDB.php @@ -26,6 +26,7 @@ use Wikimedia\Rdbms\IDatabase; use Wikimedia\Rdbms\DBConnRef; use Wikimedia\Rdbms\MaintainableDBConnRef; use Wikimedia\Rdbms\DatabaseDomain; +use Wikimedia\Rdbms\DBUnexpectedError; /** * DB accessible external objects. @@ -113,7 +114,11 @@ class ExternalStoreDB extends ExternalStoreMedium { */ public function store( $location, $data ) { $dbw = $this->getMaster( $location ); - $dbw->insert( $this->getTable( $dbw ), [ 'blob_text' => $data ], __METHOD__ ); + $dbw->insert( + $this->getTable( $dbw, $location ), + [ 'blob_text' => $data ], + __METHOD__ + ); $id = $dbw->insertId(); if ( !$id ) { throw new MWException( __METHOD__ . ': no insert ID' ); @@ -149,10 +154,11 @@ class ExternalStoreDB extends ExternalStoreMedium { /** * Get a replica DB connection for the specified cluster * + * @since 1.34 * @param string $cluster Cluster name * @return DBConnRef */ - public function getSlave( $cluster ) { + public function getReplica( $cluster ) { $lb = $this->getLoadBalancer( $cluster ); return $lb->getConnectionRef( @@ -163,6 +169,17 @@ class ExternalStoreDB extends ExternalStoreMedium { ); } + /** + * Get a replica DB connection for the specified cluster + * + * @param string $cluster Cluster name + * @return DBConnRef + * @deprecated since 1.34 + */ + public function getSlave( $cluster ) { + return $this->getReplica( $cluster ); + } + /** * Get a master database connection for the specified cluster * @@ -211,15 +228,55 @@ class ExternalStoreDB extends ExternalStoreMedium { * Get the 'blobs' table name for this database * * @param IDatabase $db + * @param string|null $cluster Cluster name * @return string Table name ('blobs' by default) */ - public function getTable( $db ) { - $table = $db->getLBInfo( 'blobs table' ); - if ( is_null( $table ) ) { - $table = 'blobs'; + public function getTable( $db, $cluster = null ) { + if ( $cluster !== null ) { + $lb = $this->getLoadBalancer( $cluster ); + $info = $lb->getServerInfo( $lb->getWriterIndex() ); + if ( isset( $info['blobs table'] ) ) { + return $info['blobs table']; + } } - return $table; + return $db->getLBInfo( 'blobs table' ) ?? 'blobs'; // b/c + } + + /** + * Create the appropriate blobs table on this cluster + * + * @see getTable() + * @since 1.34 + * @param string $cluster + */ + public function initializeTable( $cluster ) { + global $IP; + + static $supportedTypes = [ 'mysql', 'sqlite' ]; + + $dbw = $this->getMaster( $cluster ); + if ( !in_array( $dbw->getType(), $supportedTypes, true ) ) { + throw new DBUnexpectedError( $dbw, "RDBMS type '{$dbw->getType()}' not supported." ); + } + + $sqlFilePath = "$IP/maintenance/storage/blobs.sql"; + $sql = file_get_contents( $sqlFilePath ); + if ( $sql === false ) { + throw new RuntimeException( "Failed to read '$sqlFilePath'." ); + } + + $rawTable = $this->getTable( $dbw, $cluster ); // e.g. "blobs_cluster23" + $encTable = $dbw->tableName( $rawTable ); + $dbw->query( + str_replace( + [ '/*$wgDBprefix*/blobs', '/*_*/blobs' ], + [ $encTable, $encTable ], + $sql + ), + __METHOD__, + $dbw::QUERY_IGNORE_DBO_TRX + ); } /** @@ -251,15 +308,23 @@ class ExternalStoreDB extends ExternalStoreMedium { $this->logger->debug( "ExternalStoreDB::fetchBlob cache miss on $cacheID" ); - $dbr = $this->getSlave( $cluster ); - $ret = $dbr->selectField( $this->getTable( $dbr ), - 'blob_text', [ 'blob_id' => $id ], __METHOD__ ); + $dbr = $this->getReplica( $cluster ); + $ret = $dbr->selectField( + $this->getTable( $dbr, $cluster ), + 'blob_text', + [ 'blob_id' => $id ], + __METHOD__ + ); if ( $ret === false ) { $this->logger->info( "ExternalStoreDB::fetchBlob master fallback on $cacheID" ); // Try the master $dbw = $this->getMaster( $cluster ); - $ret = $dbw->selectField( $this->getTable( $dbw ), - 'blob_text', [ 'blob_id' => $id ], __METHOD__ ); + $ret = $dbw->selectField( + $this->getTable( $dbw, $cluster ), + 'blob_text', + [ 'blob_id' => $id ], + __METHOD__ + ); if ( $ret === false ) { $this->logger->error( "ExternalStoreDB::fetchBlob master failed to find $cacheID" ); } @@ -283,9 +348,9 @@ class ExternalStoreDB extends ExternalStoreMedium { * Unlocated ids are not represented */ private function batchFetchBlobs( $cluster, array $ids ) { - $dbr = $this->getSlave( $cluster ); + $dbr = $this->getReplica( $cluster ); $res = $dbr->select( - $this->getTable( $dbr ), + $this->getTable( $dbr, $cluster ), [ 'blob_id', 'blob_text' ], [ 'blob_id' => array_keys( $ids ) ], __METHOD__ @@ -302,7 +367,8 @@ class ExternalStoreDB extends ExternalStoreMedium { ); // Try the master $dbw = $this->getMaster( $cluster ); - $res = $dbw->select( $this->getTable( $dbr ), + $res = $dbw->select( + $this->getTable( $dbr, $cluster ), [ 'blob_id', 'blob_text' ], [ 'blob_id' => array_keys( $ids ) ], __METHOD__ ); diff --git a/includes/filerepo/file/File.php b/includes/filerepo/file/File.php index 0d5776bba2..60d4e29dac 100644 --- a/includes/filerepo/file/File.php +++ b/includes/filerepo/file/File.php @@ -1467,13 +1467,15 @@ abstract class File implements IDBAccessObject { // Delete thumbnails and refresh file metadata cache $this->purgeCache(); $this->purgeDescription(); - // Purge cache of all pages using this file $title = $this->getTitle(); if ( $title ) { - DeferredUpdates::addUpdate( - new HTMLCacheUpdate( $title, 'imagelinks', 'file-purge' ) + $job = HTMLCacheUpdateJob::newForBacklinks( + $title, + 'imagelinks', + [ 'causeAction' => 'file-purge' ] ); + JobQueueGroup::singleton()->lazyPush( $job ); } } diff --git a/includes/libs/filebackend/FSFileBackend.php b/includes/libs/filebackend/FSFileBackend.php index 9ed7ae3426..26f3d3a15c 100644 --- a/includes/libs/filebackend/FSFileBackend.php +++ b/includes/libs/filebackend/FSFileBackend.php @@ -73,7 +73,7 @@ class FSFileBackend extends FileBackendStore { /** @var string Required OS username to own files */ protected $fileOwner; - /** @var bool Whether the OS is Windows (otherwise assumed Unix-like)*/ + /** @var bool Whether the OS is Windows (otherwise assumed Unix-like) */ protected $isWindows; /** @var string OS username running this script */ protected $currentUser; diff --git a/includes/libs/filebackend/SwiftFileBackend.php b/includes/libs/filebackend/SwiftFileBackend.php index edea75f71a..5632d5e63c 100644 --- a/includes/libs/filebackend/SwiftFileBackend.php +++ b/includes/libs/filebackend/SwiftFileBackend.php @@ -1083,11 +1083,11 @@ class SwiftFileBackend extends FileBackendStore { protected function doStreamFile( array $params ) { $status = $this->newStatus(); - $flags = !empty( $params['headless'] ) ? StreamFile::STREAM_HEADLESS : 0; + $flags = !empty( $params['headless'] ) ? HTTPFileStreamer::STREAM_HEADLESS : 0; list( $srcCont, $srcRel ) = $this->resolveStoragePathReal( $params['src'] ); if ( $srcRel === null ) { - StreamFile::send404Message( $params['src'], $flags ); + HTTPFileStreamer::send404Message( $params['src'], $flags ); $status->fatal( 'backend-fail-invalidpath', $params['src'] ); return $status; @@ -1095,7 +1095,7 @@ class SwiftFileBackend extends FileBackendStore { $auth = $this->getAuthentication(); if ( !$auth || !is_array( $this->getContainerStat( $srcCont ) ) ) { - StreamFile::send404Message( $params['src'], $flags ); + HTTPFileStreamer::send404Message( $params['src'], $flags ); $status->fatal( 'backend-fail-stream', $params['src'] ); return $status; @@ -1104,7 +1104,7 @@ class SwiftFileBackend extends FileBackendStore { // If "headers" is set, we only want to send them if the file is there. // Do not bother checking if the file exists if headers are not set though. if ( $params['headers'] && !$this->fileExists( $params ) ) { - StreamFile::send404Message( $params['src'], $flags ); + HTTPFileStreamer::send404Message( $params['src'], $flags ); $status->fatal( 'backend-fail-stream', $params['src'] ); return $status; diff --git a/includes/libs/filebackend/fileophandle/FileBackendStoreOpHandle.php b/includes/libs/filebackend/fileophandle/FileBackendStoreOpHandle.php index 649225d839..8697f9f0b6 100644 --- a/includes/libs/filebackend/fileophandle/FileBackendStoreOpHandle.php +++ b/includes/libs/filebackend/fileophandle/FileBackendStoreOpHandle.php @@ -34,6 +34,8 @@ abstract class FileBackendStoreOpHandle { public $backend; /** @var array */ public $resourcesToClose = []; + /** @var callable name that identifies the function called */ + public $call; /** * Close all open file handles diff --git a/includes/libs/rdbms/lbfactory/LBFactoryMulti.php b/includes/libs/rdbms/lbfactory/LBFactoryMulti.php index 77b029f6d9..5d33e698db 100644 --- a/includes/libs/rdbms/lbfactory/LBFactoryMulti.php +++ b/includes/libs/rdbms/lbfactory/LBFactoryMulti.php @@ -60,7 +60,7 @@ class LBFactoryMulti extends LBFactory { private $masterTemplateOverrides = []; /** @var array[] Map of (host => server config map overrides) for main and external servers */ private $templateOverridesByServer = []; - /** @var string[]|bool[] A map of section name to read-only message */ + /** @var string[]|bool[] A map of section name to read-only message */ private $readOnlyBySection = []; /** @var string An ILoadMonitor class */ @@ -85,7 +85,7 @@ class LBFactoryMulti extends LBFactory { * data can be before the load balancer tries to avoid using it. The map can have 'is static' * set to disable blocking replication sync checks (intended for archive servers with * unchanging data). - + * * @see LBFactory::__construct() * @param array $conf Additional parameters include: * - hostsByName Optional (hostname => IP address) map. diff --git a/includes/libs/redis/RedisConnectionPool.php b/includes/libs/redis/RedisConnectionPool.php index eb645cc149..343e35c41b 100644 --- a/includes/libs/redis/RedisConnectionPool.php +++ b/includes/libs/redis/RedisConnectionPool.php @@ -90,6 +90,10 @@ class RedisConnectionPool implements LoggerAwareInterface { if ( !isset( $options['serializer'] ) || $options['serializer'] === 'php' ) { $this->serializer = Redis::SERIALIZER_PHP; } elseif ( $options['serializer'] === 'igbinary' ) { + if ( !defined( 'Redis::SERIALIZER_IGBINARY' ) ) { + throw new InvalidArgumentException( + __CLASS__ . ': configured serializer "igbinary" not available' ); + } $this->serializer = Redis::SERIALIZER_IGBINARY; } elseif ( $options['serializer'] === 'none' ) { $this->serializer = Redis::SERIALIZER_NONE; diff --git a/includes/logging/BlockLogFormatter.php b/includes/logging/BlockLogFormatter.php index d27643ce0d..d49e3c5710 100644 --- a/includes/logging/BlockLogFormatter.php +++ b/includes/logging/BlockLogFormatter.php @@ -22,6 +22,8 @@ * @since 1.25 */ +use MediaWiki\MediaWikiServices; + /** * This class formats block log entries. * @@ -138,7 +140,9 @@ class BlockLogFormatter extends LogFormatter { $linkRenderer = $this->getLinkRenderer(); if ( $this->entry->isDeleted( LogPage::DELETED_ACTION ) // Action is hidden || !( $subtype === 'block' || $subtype === 'reblock' ) - || !$this->context->getUser()->isAllowed( 'block' ) + || !MediaWikiServices::getInstance() + ->getPermissionManager() + ->userHasRight( $this->context->getUser(), 'block' ) ) { return ''; } diff --git a/includes/logging/ContentModelLogFormatter.php b/includes/logging/ContentModelLogFormatter.php index e05357cd68..23c582c30f 100644 --- a/includes/logging/ContentModelLogFormatter.php +++ b/includes/logging/ContentModelLogFormatter.php @@ -1,5 +1,7 @@ context->getLanguage(); @@ -12,7 +14,9 @@ class ContentModelLogFormatter extends LogFormatter { public function getActionLinks() { if ( $this->entry->isDeleted( LogPage::DELETED_ACTION ) // Action is hidden || $this->entry->getSubtype() !== 'change' - || !$this->context->getUser()->isAllowed( 'editcontentmodel' ) + || !MediaWikiServices::getInstance() + ->getPermissionManager() + ->userHasRight( $this->context->getUser(), 'editcontentmodel' ) ) { return ''; } diff --git a/includes/logging/DeleteLogFormatter.php b/includes/logging/DeleteLogFormatter.php index 3bc19ffd37..0abb6f62c4 100644 --- a/includes/logging/DeleteLogFormatter.php +++ b/includes/logging/DeleteLogFormatter.php @@ -23,6 +23,7 @@ * @since 1.22 */ +use MediaWiki\MediaWikiServices; use MediaWiki\Storage\RevisionRecord; /** @@ -136,7 +137,8 @@ class DeleteLogFormatter extends LogFormatter { public function getActionLinks() { $user = $this->context->getUser(); $linkRenderer = $this->getLinkRenderer(); - if ( !$user->isAllowed( 'deletedhistory' ) + $permissionManager = MediaWikiServices::getInstance()->getPermissionManager(); + if ( !$permissionManager->userHasRight( $user, 'deletedhistory' ) || $this->entry->isDeleted( LogPage::DELETED_ACTION ) ) { return ''; @@ -145,7 +147,7 @@ class DeleteLogFormatter extends LogFormatter { switch ( $this->entry->getSubtype() ) { case 'delete': // Show undelete link case 'delete_redir': - if ( $user->isAllowed( 'undelete' ) ) { + if ( $permissionManager->userHasRight( $user, 'undelete' ) ) { $message = 'undeletelink'; } else { $message = 'undeleteviewlink'; diff --git a/includes/logging/LogEventsList.php b/includes/logging/LogEventsList.php index 6791503bf7..2e7f065bf1 100644 --- a/includes/logging/LogEventsList.php +++ b/includes/logging/LogEventsList.php @@ -233,7 +233,10 @@ class LogEventsList extends ContextSource { foreach ( LogPage::validTypes() as $type ) { $page = new LogPage( $type ); $restriction = $page->getRestriction(); - if ( $this->getUser()->isAllowed( $restriction ) ) { + if ( MediaWikiServices::getInstance() + ->getPermissionManager() + ->userHasRight( $this->getUser(), $restriction ) + ) { $typesByName[$type] = $page->getName()->text(); } } @@ -450,11 +453,12 @@ class LogEventsList extends ContextSource { } $del = ''; + $permissionManager = MediaWikiServices::getInstance()->getPermissionManager(); // Don't show useless checkbox to people who cannot hide log entries - if ( $user->isAllowed( 'deletedhistory' ) ) { - $canHide = $user->isAllowed( 'deletelogentry' ); - $canViewSuppressedOnly = $user->isAllowed( 'viewsuppressed' ) && - !$user->isAllowed( 'suppressrevision' ); + if ( $permissionManager->userHasRight( $user, 'deletedhistory' ) ) { + $canHide = $permissionManager->userHasRight( $user, 'deletelogentry' ); + $canViewSuppressedOnly = $permissionManager->userHasRight( $user, 'viewsuppressed' ) && + !$permissionManager->userHasRight( $user, 'suppressrevision' ); $entryIsSuppressed = self::isDeleted( $row, LogPage::DELETED_RESTRICTED ); $canViewThisSuppressedEntry = $canViewSuppressedOnly && $entryIsSuppressed; if ( $row->log_deleted || $canHide ) { @@ -508,7 +512,9 @@ class LogEventsList extends ContextSource { in_array( $row->log_action, $action ) : $row->log_action == $action; if ( $match && $right ) { global $wgUser; - $match = $wgUser->isAllowed( $right ); + $match = MediaWikiServices::getInstance() + ->getPermissionManager() + ->userHasRight( $wgUser, $right ); } } @@ -572,7 +578,10 @@ class LogEventsList extends ContextSource { $user = $wgUser; } $logRestrictions = MediaWikiServices::getInstance()->getMainConfig()->get( 'LogRestrictions' ); - if ( isset( $logRestrictions[$type] ) && !$user->isAllowed( $logRestrictions[$type] ) ) { + if ( isset( $logRestrictions[$type] ) && !MediaWikiServices::getInstance() + ->getPermissionManager() + ->userHasRight( $user, $logRestrictions[$type] ) + ) { return false; } return true; @@ -783,7 +792,10 @@ class LogEventsList extends ContextSource { // Don't show private logs to unprivileged users foreach ( $wgLogRestrictions as $logType => $right ) { - if ( $audience == 'public' || !$user->isAllowed( $right ) ) { + if ( $audience == 'public' || !MediaWikiServices::getInstance() + ->getPermissionManager() + ->userHasRight( $user, $right ) + ) { $hiddenLogs[] = $logType; } } diff --git a/includes/logging/LogFormatter.php b/includes/logging/LogFormatter.php index 9e63ffee64..b4a682583c 100644 --- a/includes/logging/LogFormatter.php +++ b/includes/logging/LogFormatter.php @@ -163,7 +163,9 @@ class LogFormatter { $logRestrictions = $this->context->getConfig()->get( 'LogRestrictions' ); $type = $this->entry->getType(); return !isset( $logRestrictions[$type] ) - || $this->context->getUser()->isAllowed( $logRestrictions[$type] ); + || MediaWikiServices::getInstance() + ->getPermissionManager() + ->userHasRight( $this->context->getUser(), $logRestrictions[$type] ); } /** diff --git a/includes/logging/LogPager.php b/includes/logging/LogPager.php index 38710477cb..47aed56a64 100644 --- a/includes/logging/LogPager.php +++ b/includes/logging/LogPager.php @@ -146,7 +146,9 @@ class LogPager extends ReverseChronologicalPager { $needReindex = false; foreach ( $types as $type ) { if ( isset( $wgLogRestrictions[$type] ) - && !$user->isAllowed( $wgLogRestrictions[$type] ) + && !MediaWikiServices::getInstance() + ->getPermissionManager() + ->userHasRight( $user, $wgLogRestrictions[$type] ) ) { $needReindex = true; $types = array_diff( $types, [ $type ] ); @@ -462,12 +464,10 @@ class LogPager extends ReverseChronologicalPager { } $this->actionRestrictionsEnforced = true; $user = $this->getUser(); - if ( !$user->isAllowed( 'deletedhistory' ) ) { + $permissionManager = MediaWikiServices::getInstance()->getPermissionManager(); + if ( !$permissionManager->userHasRight( $user, 'deletedhistory' ) ) { $this->mConds[] = $this->mDb->bitAnd( 'log_deleted', LogPage::DELETED_ACTION ) . ' = 0'; - } elseif ( !MediaWikiServices::getInstance() - ->getPermissionManager() - ->userHasAnyRight( $user, 'suppressrevision', 'viewsuppressed' ) - ) { + } elseif ( !$permissionManager->userHasAnyRight( $user, 'suppressrevision', 'viewsuppressed' ) ) { $this->mConds[] = $this->mDb->bitAnd( 'log_deleted', LogPage::SUPPRESSED_ACTION ) . ' != ' . LogPage::SUPPRESSED_USER; } @@ -483,12 +483,10 @@ class LogPager extends ReverseChronologicalPager { } $this->performerRestrictionsEnforced = true; $user = $this->getUser(); - if ( !$user->isAllowed( 'deletedhistory' ) ) { + $permissionManager = MediaWikiServices::getInstance()->getPermissionManager(); + if ( !$permissionManager->userHasRight( $user, 'deletedhistory' ) ) { $this->mConds[] = $this->mDb->bitAnd( 'log_deleted', LogPage::DELETED_USER ) . ' = 0'; - } elseif ( !MediaWikiServices::getInstance() - ->getPermissionManager() - ->userHasAnyRight( $user, 'suppressrevision', 'viewsuppressed' ) - ) { + } elseif ( !$permissionManager->userHasAnyRight( $user, 'suppressrevision', 'viewsuppressed' ) ) { $this->mConds[] = $this->mDb->bitAnd( 'log_deleted', LogPage::SUPPRESSED_USER ) . ' != ' . LogPage::SUPPRESSED_ACTION; } diff --git a/includes/logging/MergeLogFormatter.php b/includes/logging/MergeLogFormatter.php index 7a6fb9df48..925c976d7a 100644 --- a/includes/logging/MergeLogFormatter.php +++ b/includes/logging/MergeLogFormatter.php @@ -22,6 +22,8 @@ * @since 1.25 */ +use MediaWiki\MediaWikiServices; + /** * This class formats merge log entries. * @@ -47,7 +49,9 @@ class MergeLogFormatter extends LogFormatter { public function getActionLinks() { if ( $this->entry->isDeleted( LogPage::DELETED_ACTION ) // Action is hidden - || !$this->context->getUser()->isAllowed( 'mergehistory' ) + || !MediaWikiServices::getInstance() + ->getPermissionManager() + ->userHasRight( $this->context->getUser(), 'mergehistory' ) ) { return ''; } diff --git a/includes/logging/MoveLogFormatter.php b/includes/logging/MoveLogFormatter.php index 637a8e7821..6797f98f04 100644 --- a/includes/logging/MoveLogFormatter.php +++ b/includes/logging/MoveLogFormatter.php @@ -23,6 +23,8 @@ * @since 1.22 */ +use MediaWiki\MediaWikiServices; + /** * This class formats move log entries. * @@ -60,7 +62,9 @@ class MoveLogFormatter extends LogFormatter { public function getActionLinks() { if ( $this->entry->isDeleted( LogPage::DELETED_ACTION ) // Action is hidden || $this->entry->getSubtype() !== 'move' - || !$this->context->getUser()->isAllowed( 'move' ) + || !MediaWikiServices::getInstance() + ->getPermissionManager() + ->userHasRight( $this->context->getUser(), 'move' ) ) { return ''; } diff --git a/includes/logging/ProtectLogFormatter.php b/includes/logging/ProtectLogFormatter.php index ba02457319..6e3b26b17f 100644 --- a/includes/logging/ProtectLogFormatter.php +++ b/includes/logging/ProtectLogFormatter.php @@ -101,7 +101,10 @@ class ProtectLogFormatter extends LogFormatter { ]; // Show change protection link - if ( $this->context->getUser()->isAllowed( 'protect' ) ) { + if ( !MediaWikiServices::getInstance() + ->getPermissionManager() + ->userHasRight( $this->context->getUser(), 'protect' ) + ) { $links[] = $linkRenderer->makeKnownLink( $title, $this->msg( 'protect_change' )->text(), diff --git a/includes/mail/EmailNotification.php b/includes/mail/EmailNotification.php index cba68ef587..4d176fb0bc 100644 --- a/includes/mail/EmailNotification.php +++ b/includes/mail/EmailNotification.php @@ -129,7 +129,10 @@ class EmailNotification { if ( $watchers === [] && !count( $wgUsersNotifiedOnAllChanges ) ) { $sendEmail = false; // Only send notification for non minor edits, unless $wgEnotifMinorEdits - if ( !$minorEdit || ( $wgEnotifMinorEdits && !$editor->isAllowed( 'nominornewtalk' ) ) ) { + if ( !$minorEdit || ( $wgEnotifMinorEdits && !MediaWikiServices::getInstance() + ->getPermissionManager() + ->userHasRight( $editor, 'nominornewtalk' ) ) + ) { $isUserTalkPage = ( $title->getNamespace() == NS_USER_TALK ); if ( $wgEnotifUserTalk && $isUserTalkPage @@ -214,7 +217,10 @@ class EmailNotification { $userTalkId = false; - if ( !$minorEdit || ( $wgEnotifMinorEdits && !$editor->isAllowed( 'nominornewtalk' ) ) ) { + if ( !$minorEdit || ( $wgEnotifMinorEdits && !MediaWikiServices::getInstance() + ->getPermissionManager() + ->userHasRight( $editor, 'nominornewtalk' ) ) + ) { if ( $wgEnotifUserTalk && $isUserTalkPage && $this->canSendUserTalkEmail( $editor, $title, $minorEdit ) diff --git a/includes/mail/UserMailer.php b/includes/mail/UserMailer.php index 47fa16f87f..07830683fd 100644 --- a/includes/mail/UserMailer.php +++ b/includes/mail/UserMailer.php @@ -34,8 +34,8 @@ class UserMailer { * Send mail using a PEAR mailer * * @param Mail_smtp $mailer - * @param string $dest - * @param string $headers + * @param string[]|string $dest + * @param array $headers * @param string $body * * @return Status @@ -382,6 +382,8 @@ class UserMailer { throw new MWException( 'PEAR mail package is not installed' ); } + $recips = array_map( 'strval', $to ); + Wikimedia\suppressWarnings(); // Create the mail object using the Mail::factory method @@ -397,13 +399,13 @@ class UserMailer { $headers['Subject'] = self::quotedPrintable( $subject ); // When sending only to one recipient, shows it its email using To: - if ( count( $to ) == 1 ) { - $headers['To'] = $to[0]->toString(); + if ( count( $recips ) == 1 ) { + $headers['To'] = $recips[0]; } // Split jobs since SMTP servers tends to limit the maximum // number of possible recipients. - $chunks = array_chunk( $to, $wgEnotifMaxRecips ); + $chunks = array_chunk( $recips, $wgEnotifMaxRecips ); foreach ( $chunks as $chunk ) { $status = self::sendWithPear( $mail_object, $chunk, $headers, $body ); // FIXME : some chunks might be sent while others are not! diff --git a/includes/media/JpegMetadataExtractor.php b/includes/media/JpegMetadataExtractor.php index 8a26f606f9..dffb1f988b 100644 --- a/includes/media/JpegMetadataExtractor.php +++ b/includes/media/JpegMetadataExtractor.php @@ -122,14 +122,17 @@ class JpegMetadataExtractor { $temp = self::jpegExtractMarker( $fh ); // check what type of app segment this is. if ( substr( $temp, 0, 29 ) === "http://ns.adobe.com/xap/1.0/\x00" && $showXMP ) { - $segments["XMP"] = substr( $temp, 29 ); + // use trim to remove trailing \0 chars + $segments["XMP"] = trim( substr( $temp, 29 ) ); } elseif ( substr( $temp, 0, 35 ) === "http://ns.adobe.com/xmp/extension/\x00" && $showXMP ) { - $segments["XMP_ext"][] = substr( $temp, 35 ); + // use trim to remove trailing \0 chars + $segments["XMP_ext"][] = trim( substr( $temp, 35 ) ); } elseif ( substr( $temp, 0, 29 ) === "XMP\x00://ns.adobe.com/xap/1.0/\x00" && $showXMP ) { // Some images (especially flickr images) seem to have this. // I really have no idea what the deal is with them, but // whatever... - $segments["XMP"] = substr( $temp, 29 ); + // use trim to remove trailing \0 chars + $segments["XMP"] = trim( substr( $temp, 29 ) ); wfDebug( __METHOD__ . ' Found XMP section with wrong app identifier ' . "Using anyways.\n" ); } elseif ( substr( $temp, 0, 6 ) === "Exif\0\0" ) { diff --git a/includes/page/Article.php b/includes/page/Article.php index 1c2e782b6b..4bede965ab 100644 --- a/includes/page/Article.php +++ b/includes/page/Article.php @@ -1310,7 +1310,10 @@ class Article implements Page { } $outputPage->preventClickjacking(); - if ( $user->isAllowed( 'writeapi' ) ) { + if ( MediaWikiServices::getInstance() + ->getPermissionManager() + ->userHasRight( $user, 'writeapi' ) + ) { $outputPage->addModules( 'mediawiki.page.patrol.ajax' ); } @@ -1827,7 +1830,10 @@ class Article implements Page { [ 'delete', $this->getTitle()->getPrefixedText() ] ) ) { # Flag to hide all contents of the archived revisions - $suppress = $request->getCheck( 'wpSuppress' ) && $user->isAllowed( 'suppressrevision' ); + + $suppress = $request->getCheck( 'wpSuppress' ) && MediaWikiServices::getInstance() + ->getPermissionManager() + ->userHasRight( $user, 'suppressrevision' ); $this->doDelete( $reason, $suppress ); @@ -1986,8 +1992,8 @@ class Article implements Page { ] ); } - - if ( $user->isAllowed( 'suppressrevision' ) ) { + $permissionManager = MediaWikiServices::getInstance()->getPermissionManager(); + if ( $permissionManager->userHasRight( $user, 'suppressrevision' ) ) { $fields[] = new OOUI\FieldLayout( new OOUI\CheckboxInputWidget( [ 'name' => 'wpSuppress', @@ -2045,7 +2051,7 @@ class Article implements Page { ] ) ); - if ( $user->isAllowed( 'editinterface' ) ) { + if ( $permissionManager->userHasRight( $user, 'editinterface' ) ) { $link = Linker::linkKnown( $ctx->msg( 'deletereason-dropdown' )->inContentLanguage()->getTitle(), wfMessage( 'delete-edit-reasonlist' )->escaped(), diff --git a/includes/page/ImageHistoryList.php b/includes/page/ImageHistoryList.php index 9edacccd52..cf2497f94e 100644 --- a/includes/page/ImageHistoryList.php +++ b/includes/page/ImageHistoryList.php @@ -130,11 +130,10 @@ class ImageHistoryList extends ContextSource { $row = $selected = ''; // Deletion link - if ( $local && ( $pm->userHasAnyRight( $user, 'delete', 'deletedhistory' ) ) - ) { + if ( $local && ( $pm->userHasAnyRight( $user, 'delete', 'deletedhistory' ) ) ) { $row .= ''; # Link to remove from history - if ( $user->isAllowed( 'delete' ) ) { + if ( $pm->userHasRight( $user, 'delete' ) ) { $q = [ 'action' => 'delete' ]; if ( !$iscur ) { $q['oldimage'] = $img; @@ -146,9 +145,10 @@ class ImageHistoryList extends ContextSource { ); } # Link to hide content. Don't show useless link to people who cannot hide revisions. - $canHide = $user->isAllowed( 'deleterevision' ); - if ( $canHide || ( $user->isAllowed( 'deletedhistory' ) && $file->getVisibility() ) ) { - if ( $user->isAllowed( 'delete' ) ) { + $canHide = $pm->userHasRight( $user, 'deleterevision' ); + if ( $canHide || ( $pm->userHasRight( $user, 'deletedhistory' ) + && $file->getVisibility() ) ) { + if ( $pm->userHasRight( $user, 'delete' ) ) { $row .= '
'; } // If file is top revision or locked from this user, don't link diff --git a/includes/page/ImagePage.php b/includes/page/ImagePage.php index 653e443a66..bb15532c1e 100644 --- a/includes/page/ImagePage.php +++ b/includes/page/ImagePage.php @@ -603,7 +603,10 @@ EOT ); } - if ( $wgEnableUploads && $user->isAllowed( 'upload' ) ) { + if ( $wgEnableUploads && MediaWikiServices::getInstance() + ->getPermissionManager() + ->userHasRight( $user, 'upload' ) + ) { // Only show an upload link if the user can upload $uploadTitle = SpecialPage::getTitleFor( 'Upload' ); $nofile = [ diff --git a/includes/page/WikiPage.php b/includes/page/WikiPage.php index bad75da4fb..f0a656dd99 100644 --- a/includes/page/WikiPage.php +++ b/includes/page/WikiPage.php @@ -1896,7 +1896,8 @@ class WikiPage implements Page, IDBAccessObject { // TODO: this check is here for backwards-compatibility with 1.31 behavior. // Checking the minoredit right should be done in the same place the 'bot' right is // checked for the EDIT_FORCE_BOT flag, which is currently in EditPage::attemptSave. - if ( ( $flags & EDIT_MINOR ) && !$user->isAllowed( 'minoredit' ) ) { + $permissionManager = MediaWikiServices::getInstance()->getPermissionManager(); + if ( ( $flags & EDIT_MINOR ) && !$permissionManager->userHasRight( $user, 'minoredit' ) ) { $flags = ( $flags & ~EDIT_MINOR ); } @@ -1916,7 +1917,6 @@ class WikiPage implements Page, IDBAccessObject { // TODO: this logic should not be in the storage layer, it's here for compatibility // with 1.31 behavior. Applying the 'autopatrol' right should be done in the same // place the 'bot' right is handled, which is currently in EditPage::attemptSave. - $permissionManager = MediaWikiServices::getInstance()->getPermissionManager(); if ( $needsPatrol && $permissionManager->userCan( 'autopatrol', $user, $this->getTitle() @@ -3249,14 +3249,12 @@ class WikiPage implements Page, IDBAccessObject { // Save $flags = EDIT_UPDATE | EDIT_INTERNAL; - if ( $guser->isAllowed( 'minoredit' ) ) { + $permissionManager = MediaWikiServices::getInstance()->getPermissionManager(); + if ( $permissionManager->userHasRight( $guser, 'minoredit' ) ) { $flags |= EDIT_MINOR; } - if ( $bot && ( MediaWikiServices::getInstance() - ->getPermissionManager() - ->userHasAnyRight( $guser, 'markbotedits', 'bot' ) ) - ) { + if ( $bot && ( $permissionManager->userHasAnyRight( $guser, 'markbotedits', 'bot' ) ) ) { $flags |= EDIT_FORCE_BOT; } @@ -3291,7 +3289,6 @@ class WikiPage implements Page, IDBAccessObject { // TODO: this logic should not be in the storage layer, it's here for compatibility // with 1.31 behavior. Applying the 'autopatrol' right should be done in the same // place the 'bot' right is handled, which is currently in EditPage::attemptSave. - $permissionManager = MediaWikiServices::getInstance()->getPermissionManager(); if ( $wgUseRCPatrol && $permissionManager->userCan( 'autopatrol', $guser, $this->getTitle() @@ -3308,7 +3305,7 @@ class WikiPage implements Page, IDBAccessObject { // Set patrolling and bot flag on the edits, which gets rollbacked. // This is done even on edit failure to have patrolling in that case (T64157). $set = []; - if ( $bot && $guser->isAllowed( 'markbotedits' ) ) { + if ( $bot && $permissionManager->userHasRight( $guser, 'markbotedits' ) ) { // Mark all reverted edits as bot $set['rc_bot'] = 1; } diff --git a/includes/preferences/DefaultPreferencesFactory.php b/includes/preferences/DefaultPreferencesFactory.php index 66c2bc33e5..56db81222e 100644 --- a/includes/preferences/DefaultPreferencesFactory.php +++ b/includes/preferences/DefaultPreferencesFactory.php @@ -20,7 +20,6 @@ namespace MediaWiki\Preferences; -use Config; use DateTime; use DateTimeZone; use Exception; @@ -37,6 +36,7 @@ use MediaWiki\Auth\PasswordAuthenticationRequest; use MediaWiki\Config\ServiceOptions; use MediaWiki\Linker\LinkRenderer; use MediaWiki\MediaWikiServices; +use MediaWiki\Permissions\PermissionManager; use MessageLocalizer; use MWException; use MWTimestamp; @@ -77,6 +77,9 @@ class DefaultPreferencesFactory implements PreferencesFactory { /** @var NamespaceInfo */ protected $nsInfo; + /** @var PermissionManager */ + protected $permissionManager; + /** * TODO Make this a const when we drop HHVM support (T192166) * @@ -114,35 +117,34 @@ class DefaultPreferencesFactory implements PreferencesFactory { /** * Do not call this directly. Get it from MediaWikiServices. * - * @param ServiceOptions|Config $options Config accepted for backwards compatibility + * @param ServiceOptions $options * @param Language $contLang * @param AuthManager $authManager * @param LinkRenderer $linkRenderer - * @param NamespaceInfo|null $nsInfo + * @param NamespaceInfo $nsInfo + * @param PermissionManager|null $permissionManager */ public function __construct( - $options, + ServiceOptions $options, Language $contLang, AuthManager $authManager, LinkRenderer $linkRenderer, - NamespaceInfo $nsInfo = null + NamespaceInfo $nsInfo, + PermissionManager $permissionManager = null ) { - if ( $options instanceof Config ) { - wfDeprecated( __METHOD__ . ' with Config parameter', '1.34' ); - $options = new ServiceOptions( self::$constructorOptions, $options ); - } - $options->assertRequiredOptions( self::$constructorOptions ); - if ( !$nsInfo ) { - wfDeprecated( __METHOD__ . ' with no NamespaceInfo argument', '1.34' ); - $nsInfo = MediaWikiServices::getInstance()->getNamespaceInfo(); + if ( !$permissionManager ) { + // TODO: this is actually hard-deprecated, left for jenkins to pass + // together with GlobalPreferences extension. Will be removed in a followup. + $permissionManager = MediaWikiServices::getInstance()->getPermissionManager(); } $this->options = $options; $this->contLang = $contLang; $this->authManager = $authManager; $this->linkRenderer = $linkRenderer; $this->nsInfo = $nsInfo; + $this->permissionManager = $permissionManager; $this->logger = new NullLogger(); } @@ -209,7 +211,7 @@ class DefaultPreferencesFactory implements PreferencesFactory { # # Make sure that form fields have their parent set. See T43337. $dummyForm = new HTMLForm( [], $context ); - $disable = !$user->isAllowed( 'editmyoptions' ); + $disable = !$this->permissionManager->userHasRight( $user, 'editmyoptions' ); $defaultOptions = User::getDefaultOptions(); $userOptions = $user->getOptions(); @@ -390,8 +392,8 @@ class DefaultPreferencesFactory implements PreferencesFactory { ]; } - $canViewPrivateInfo = $user->isAllowed( 'viewmyprivateinfo' ); - $canEditPrivateInfo = $user->isAllowed( 'editmyprivateinfo' ); + $canViewPrivateInfo = $this->permissionManager->userHasRight( $user, 'viewmyprivateinfo' ); + $canEditPrivateInfo = $this->permissionManager->userHasRight( $user, 'editmyprivateinfo' ); // Actually changeable stuff $defaultPreferences['realname'] = [ @@ -631,7 +633,9 @@ class DefaultPreferencesFactory implements PreferencesFactory { ]; } - if ( $this->options->get( 'EnableUserEmail' ) && $user->isAllowed( 'sendemail' ) ) { + if ( $this->options->get( 'EnableUserEmail' ) && + $this->permissionManager->userHasRight( $user, 'sendemail' ) + ) { $defaultPreferences['disablemail'] = [ 'id' => 'wpAllowEmail', 'type' => 'toggle', @@ -921,7 +925,7 @@ class DefaultPreferencesFactory implements PreferencesFactory { 'label-message' => 'tog-numberheadings', ]; - if ( $user->isAllowed( 'rollback' ) ) { + if ( $this->permissionManager->userHasRight( $user, 'rollback' ) ) { $defaultPreferences['showrollbackconfirmation'] = [ 'type' => 'toggle', 'section' => 'rendering/advancedrendering', @@ -961,7 +965,7 @@ class DefaultPreferencesFactory implements PreferencesFactory { ]; } - if ( $user->isAllowed( 'minoredit' ) ) { + if ( $this->permissionManager->userHasRight( $user, 'minoredit' ) ) { $defaultPreferences['minordefault'] = [ 'type' => 'toggle', 'section' => 'editing/editor', @@ -1107,7 +1111,7 @@ class DefaultPreferencesFactory implements PreferencesFactory { $watchlistdaysMax = ceil( $this->options->get( 'RCMaxAge' ) / ( 3600 * 24 ) ); # # Watchlist ##################################### - if ( $user->isAllowed( 'editmywatchlist' ) ) { + if ( $this->permissionManager->userHasRight( $user, 'editmywatchlist' ) ) { $editWatchlistLinks = ''; $editWatchlistModes = [ 'edit' => [ 'subpage' => false, 'flags' => [] ], @@ -1221,20 +1225,20 @@ class DefaultPreferencesFactory implements PreferencesFactory { ]; // Kinda hacky - if ( $user->isAllowed( 'createpage' ) || $user->isAllowed( 'createtalk' ) ) { + if ( $this->permissionManager->userHasAnyRight( $user, 'createpage', 'createtalk' ) ) { $watchTypes['read'] = 'watchcreations'; } - if ( $user->isAllowed( 'rollback' ) ) { + if ( $this->permissionManager->userHasRight( $user, 'rollback' ) ) { $watchTypes['rollback'] = 'watchrollback'; } - if ( $user->isAllowed( 'upload' ) ) { + if ( $this->permissionManager->userHasRight( $user, 'upload' ) ) { $watchTypes['upload'] = 'watchuploads'; } foreach ( $watchTypes as $action => $pref ) { - if ( $user->isAllowed( $action ) ) { + if ( $this->permissionManager->userHasRight( $user, $action ) ) { // Messages: // tog-watchdefault, tog-watchmoves, tog-watchdeletion, tog-watchcreations, tog-watchuploads // tog-watchrollback @@ -1606,7 +1610,9 @@ class DefaultPreferencesFactory implements PreferencesFactory { $hiddenPrefs = $this->options->get( 'HiddenPrefs' ); $result = true; - if ( !$user->isAllowedAny( 'editmyprivateinfo', 'editmyoptions' ) ) { + if ( !$this->permissionManager + ->userHasAnyRight( $user, 'editmyprivateinfo', 'editmyoptions' ) + ) { return Status::newFatal( 'mypreferencesprotected' ); } @@ -1617,14 +1623,14 @@ class DefaultPreferencesFactory implements PreferencesFactory { // (not really "private", but still shouldn't be edited without permission) if ( !in_array( 'realname', $hiddenPrefs ) - && $user->isAllowed( 'editmyprivateinfo' ) + && $this->permissionManager->userHasRight( $user, 'editmyprivateinfo' ) && array_key_exists( 'realname', $formData ) ) { $realName = $formData['realname']; $user->setRealName( $realName ); } - if ( $user->isAllowed( 'editmyoptions' ) ) { + if ( $this->permissionManager->userHasRight( $user, 'editmyoptions' ) ) { $oldUserOptions = $user->getOptions(); foreach ( $this->getSaveBlacklist() as $b ) { diff --git a/includes/resourceloader/ResourceLoader.php b/includes/resourceloader/ResourceLoader.php index 693afcf62a..6121bbf304 100644 --- a/includes/resourceloader/ResourceLoader.php +++ b/includes/resourceloader/ResourceLoader.php @@ -812,9 +812,9 @@ class ResourceLoader implements LoggerAwareInterface { $errorText = implode( "\n\n", $this->errors ); $errorResponse = self::makeComment( $errorText ); if ( $context->shouldIncludeScripts() ) { - $errorResponse .= 'if (window.console && console.error) {' - . Xml::encodeJsCall( 'console.error', [ $errorText ] ) - . "}\n"; + $errorResponse .= 'if (window.console && console.error) { console.error(' + . self::encodeJsonForScript( $errorText ) + . "); }\n"; } // Prepend error info to the response @@ -1273,8 +1273,7 @@ MESSAGE; /** * Returns JS code which, when called, will register a given list of messages. * - * @param mixed $messages Either an associative array mapping message key to value, or a - * JSON-encoded message blob containing the same data, wrapped in an XmlJsCode object. + * @param mixed $messages Associative array mapping message key to value. * @return string JavaScript code */ public static function makeMessageSetScript( $messages ) { @@ -1324,7 +1323,7 @@ MESSAGE; * @internal * @since 1.32 * @param mixed $data - * @return string JSON + * @return string|false JSON string, false on error */ public static function encodeJsonForScript( $data ) { // Keep output as small as possible by disabling needless escape modes @@ -1545,20 +1544,16 @@ MESSAGE; * @throws Exception */ public static function makeConfigSetScript( array $configuration ) { - $js = Xml::encodeJsCall( - 'mw.config.set', - [ $configuration ], - self::inDebugMode() - ); - if ( $js === false ) { + $json = self::encodeJsonForScript( $configuration ); + if ( $json === false ) { $e = new Exception( 'JSON serialization of config data failed. ' . 'This usually means the config data is not valid UTF-8.' ); MWExceptionHandler::logException( $e ); - $js = Xml::encodeJsCall( 'mw.log.error', [ $e->__toString() ] ); + return 'mw.log.error(' . self::encodeJsonForScript( $e->__toString() ) . ');'; } - return $js; + return "mw.config.set($json);"; } /** diff --git a/includes/resourceloader/ResourceLoaderClientHtml.php b/includes/resourceloader/ResourceLoaderClientHtml.php index 151b5fd502..ea35de6bea 100644 --- a/includes/resourceloader/ResourceLoaderClientHtml.php +++ b/includes/resourceloader/ResourceLoaderClientHtml.php @@ -478,7 +478,7 @@ JAVASCRIPT; ] ); } else { $chunk = ResourceLoader::makeInlineScript( - Xml::encodeJsCall( 'mw.loader.load', [ $url ] ), + 'mw.loader.load(' . ResourceLoader::encodeJsonForScript( $url ) . ');', $nonce ); } diff --git a/includes/resourceloader/ResourceLoaderLanguageDataModule.php b/includes/resourceloader/ResourceLoaderLanguageDataModule.php index 7a7ab892ce..c0a0921e11 100644 --- a/includes/resourceloader/ResourceLoaderLanguageDataModule.php +++ b/includes/resourceloader/ResourceLoaderLanguageDataModule.php @@ -52,16 +52,11 @@ class ResourceLoaderLanguageDataModule extends ResourceLoaderFileModule { * @return string JavaScript code */ public function getScript( ResourceLoaderContext $context ) { - $fileScript = parent::getScript( $context ); - $langDataScript = Xml::encodeJsCall( - 'mw.language.setData', - [ - $context->getLanguage(), - $this->getData( $context ) - ], - ResourceLoader::inDebugMode() - ); - return $fileScript . $langDataScript; + return parent::getScript( $context ) + . 'mw.language.setData(' + . ResourceLoader::encodeJsonForScript( $context->getLanguage() ) . ',' + . ResourceLoader::encodeJsonForScript( $this->getData( $context ) ) + . ');'; } /** diff --git a/includes/resourceloader/ResourceLoaderUserDefaultsModule.php b/includes/resourceloader/ResourceLoaderUserDefaultsModule.php index b9dc098268..61cff822c9 100644 --- a/includes/resourceloader/ResourceLoaderUserDefaultsModule.php +++ b/includes/resourceloader/ResourceLoaderUserDefaultsModule.php @@ -40,10 +40,8 @@ class ResourceLoaderUserDefaultsModule extends ResourceLoaderModule { * @return string JavaScript code */ public function getScript( ResourceLoaderContext $context ) { - return Xml::encodeJsCall( - 'mw.user.options.set', - [ User::getDefaultOptions() ], - ResourceLoader::inDebugMode() - ); + return 'mw.user.options.set(' + . ResourceLoader::encodeJsonForScript( User::getDefaultOptions() ) + . ');'; } } diff --git a/includes/resourceloader/ResourceLoaderUserOptionsModule.php b/includes/resourceloader/ResourceLoaderUserOptionsModule.php index 0d40ad71ea..ecbb50193c 100644 --- a/includes/resourceloader/ResourceLoaderUserOptionsModule.php +++ b/includes/resourceloader/ResourceLoaderUserOptionsModule.php @@ -52,11 +52,12 @@ class ResourceLoaderUserOptionsModule extends ResourceLoaderModule { */ public function getScript( ResourceLoaderContext $context ) { // Use FILTER_NOMIN annotation to prevent needless minification and caching (T84960). - return ResourceLoader::FILTER_NOMIN . Xml::encodeJsCall( - 'mw.user.options.set', - [ $context->getUserObj()->getOptions( User::GETOPTIONS_EXCLUDE_DEFAULTS ) ], - ResourceLoader::inDebugMode() - ); + return ResourceLoader::FILTER_NOMIN + . 'mw.user.options.set(' + . ResourceLoader::encodeJsonForScript( + $context->getUserObj()->getOptions( User::GETOPTIONS_EXCLUDE_DEFAULTS ) + ) + . ');'; } /** diff --git a/includes/resourceloader/ResourceLoaderUserTokensModule.php b/includes/resourceloader/ResourceLoaderUserTokensModule.php index ae4fb67b8d..85c14cb992 100644 --- a/includes/resourceloader/ResourceLoaderUserTokensModule.php +++ b/includes/resourceloader/ResourceLoaderUserTokensModule.php @@ -53,11 +53,10 @@ class ResourceLoaderUserTokensModule extends ResourceLoaderModule { */ public function getScript( ResourceLoaderContext $context ) { // Use FILTER_NOMIN annotation to prevent needless minification and caching (T84960). - return ResourceLoader::FILTER_NOMIN . Xml::encodeJsCall( - 'mw.user.tokens.set', - [ $this->contextUserTokens( $context ) ], - ResourceLoader::inDebugMode() - ); + return ResourceLoader::FILTER_NOMIN + . 'mw.user.tokens.set(' + . ResourceLoader::encodeJsonForScript( $this->contextUserTokens( $context ) ) + . ');'; } /** diff --git a/includes/session/SessionManager.php b/includes/session/SessionManager.php index 09cdf72f46..a3380ff82f 100644 --- a/includes/session/SessionManager.php +++ b/includes/session/SessionManager.php @@ -505,11 +505,10 @@ final class SessionManager implements SessionManagerInterface { } if ( count( $retInfos ) > 1 ) { - $ex = new \OverflowException( + throw new SessionOverflowException( + $retInfos, 'Multiple sessions for this request tied for top priority: ' . implode( ', ', $retInfos ) ); - $ex->sessionInfos = $retInfos; - throw $ex; } return $retInfos ? $retInfos[0] : null; diff --git a/includes/session/SessionOverflowException.php b/includes/session/SessionOverflowException.php new file mode 100644 index 0000000000..2a5ed2b80a --- /dev/null +++ b/includes/session/SessionOverflowException.php @@ -0,0 +1,34 @@ +sessionInfos = $sessionInfos; + } + + /** + * @return SessionInfo[] + */ + public function getSessionInfos() : array { + return $this->sessionInfos; + } +} diff --git a/includes/skins/SkinTemplate.php b/includes/skins/SkinTemplate.php index 70df73bc21..327061c681 100644 --- a/includes/skins/SkinTemplate.php +++ b/includes/skins/SkinTemplate.php @@ -595,7 +595,7 @@ class SkinTemplate extends Skin { # $this->getTitle() will just give Special:Badtitle, which is # not especially useful as a returnto parameter. Use the title # from the request instead, if there was one. - if ( $this->getUser()->isAllowed( 'read' ) ) { + if ( $permissionManager->userHasRight( $this->getUser(), 'read' ) ) { $page = $this->getTitle(); } else { $page = Title::newFromText( $request->getVal( 'title', '' ) ); @@ -636,7 +636,7 @@ class SkinTemplate extends Skin { 'active' => ( $href == $pageurl ) ]; - if ( $this->getUser()->isAllowed( 'viewmywatchlist' ) ) { + if ( $permissionManager->userHasRight( $this->getUser(), 'viewmywatchlist' ) ) { $href = self::makeSpecialUrl( 'Watchlist' ); $personal_urls['watchlist'] = [ 'text' => $this->msg( 'mywatchlist' )->text(), @@ -689,9 +689,8 @@ class SkinTemplate extends Skin { $useCombinedLoginLink = false; } - $loginlink = $this->getUser()->isAllowed( 'createaccount' ) && $useCombinedLoginLink - ? 'nav-login-createaccount' - : 'pt-login'; + $loginlink = $permissionManager->userHasRight( $this->getUser(), 'createaccount' ) + && $useCombinedLoginLink ? 'nav-login-createaccount' : 'pt-login'; $login_url = [ 'text' => $this->msg( $loginlink )->text(), @@ -727,7 +726,7 @@ class SkinTemplate extends Skin { if ( $authManager->canCreateAccounts() - && $this->getUser()->isAllowed( 'createaccount' ) + && $permissionManager->userHasRight( $this->getUser(), 'createaccount' ) && !$useCombinedLoginLink ) { $personal_urls['createaccount'] = $createaccount_url; @@ -1074,8 +1073,7 @@ class SkinTemplate extends Skin { if ( $permissionManager->quickUserCan( 'protect', $user, $title ) && $title->getRestrictionTypes() && - $permissionManager->getNamespaceRestrictionLevels( $title->getNamespace(), - $user ) !== [ '' ] + $permissionManager->getNamespaceRestrictionLevels( $title->getNamespace(), $user ) !== [ '' ] ) { $mode = $title->isProtected() ? 'unprotect' : 'protect'; $content_navigation['actions'][$mode] = [ @@ -1345,7 +1343,10 @@ class SkinTemplate extends Skin { 'href' => self::makeSpecialUrlSubpage( 'Log', $rootUser ) ]; - if ( $this->getUser()->isAllowed( 'block' ) ) { + if ( MediawikiServices::getInstance() + ->getPermissionManager() + ->userHasRight( $this->getUser(), 'block' ) + ) { $nav_urls['blockip'] = [ 'text' => $this->msg( 'blockip', $rootUser )->text(), 'href' => self::makeSpecialUrlSubpage( 'Block', $rootUser ) diff --git a/includes/specialpage/LoginSignupSpecialPage.php b/includes/specialpage/LoginSignupSpecialPage.php index ce80c1a311..94be8521a3 100644 --- a/includes/specialpage/LoginSignupSpecialPage.php +++ b/includes/specialpage/LoginSignupSpecialPage.php @@ -95,9 +95,8 @@ abstract class LoginSignupSpecialPage extends AuthManagerSpecialPage { /** * Load basic request parameters for this Special page. - * @param string $subPage */ - private function loadRequestParameters( $subPage ) { + private function loadRequestParameters() { if ( $this->mLoadedRequest ) { return; } @@ -105,7 +104,6 @@ abstract class LoginSignupSpecialPage extends AuthManagerSpecialPage { $request = $this->getRequest(); $this->mPosted = $request->wasPosted(); - $this->mIsReturn = $subPage === 'return'; $this->mAction = $request->getVal( 'action' ); $this->mFromHTTP = $request->getBool( 'fromhttp', false ) || $request->getBool( 'wpFromhttp', false ); @@ -124,7 +122,7 @@ abstract class LoginSignupSpecialPage extends AuthManagerSpecialPage { protected function load( $subPage ) { global $wgSecureLogin; - $this->loadRequestParameters( $subPage ); + $this->loadRequestParameters(); if ( $this->mLoaded ) { return; } @@ -203,7 +201,7 @@ abstract class LoginSignupSpecialPage extends AuthManagerSpecialPage { protected function beforeExecute( $subPage ) { // finish initializing the class before processing the request - T135924 - $this->loadRequestParameters( $subPage ); + $this->loadRequestParameters(); return parent::beforeExecute( $subPage ); } @@ -977,7 +975,11 @@ abstract class LoginSignupSpecialPage extends AuthManagerSpecialPage { } } if ( !$this->isSignup() && $this->showExtraInformation() ) { - $passwordReset = new PasswordReset( $this->getConfig(), AuthManager::singleton() ); + $passwordReset = new PasswordReset( + $this->getConfig(), + AuthManager::singleton(), + MediaWikiServices::getInstance()->getPermissionManager() + ); if ( $passwordReset->isAllowed( $this->getUser() )->isGood() ) { $fieldDefinitions['passwordReset'] = [ 'type' => 'info', @@ -1074,7 +1076,10 @@ abstract class LoginSignupSpecialPage extends AuthManagerSpecialPage { private function showCreateAccountLink() { if ( $this->isSignup() ) { return true; - } elseif ( $this->getUser()->isAllowed( 'createaccount' ) ) { + } elseif ( MediaWikiServices::getInstance() + ->getPermissionManager() + ->userHasRight( $this->getUser(), 'createaccount' ) + ) { return true; } else { return false; diff --git a/includes/specialpage/SpecialPage.php b/includes/specialpage/SpecialPage.php index 7d3303584d..ba8e318bcd 100644 --- a/includes/specialpage/SpecialPage.php +++ b/includes/specialpage/SpecialPage.php @@ -292,7 +292,9 @@ class SpecialPage implements MessageLocalizer { * @return bool Does the user have permission to view the page? */ public function userCanExecute( User $user ) { - return $user->isAllowed( $this->mRestriction ); + return MediaWikiServices::getInstance() + ->getPermissionManager() + ->userHasRight( $user, $this->mRestriction ); } /** diff --git a/includes/specialpage/SpecialPageFactory.php b/includes/specialpage/SpecialPageFactory.php index 3f9c491576..b83be91cba 100644 --- a/includes/specialpage/SpecialPageFactory.php +++ b/includes/specialpage/SpecialPageFactory.php @@ -192,7 +192,12 @@ class SpecialPageFactory { 'ApiHelp' => \SpecialApiHelp::class, 'Blankpage' => \SpecialBlankpage::class, 'Diff' => \SpecialDiff::class, - 'EditTags' => \SpecialEditTags::class, + 'EditTags' => [ + 'class' => \SpecialEditTags::class, + 'services' => [ + 'PermissionManager', + ], + ], 'Emailuser' => \SpecialEmailUser::class, 'Movepage' => \MovePageForm::class, 'Mycontributions' => \SpecialMycontributions::class, @@ -204,7 +209,12 @@ class SpecialPageFactory { 'NewSection' => \SpecialNewSection::class, 'PermanentLink' => \SpecialPermanentLink::class, 'Redirect' => \SpecialRedirect::class, - 'Revisiondelete' => \SpecialRevisionDelete::class, + 'Revisiondelete' => [ + 'class' => \SpecialRevisionDelete::class, + 'services' => [ + 'PermissionManager', + ], + ], 'RunJobs' => \SpecialRunJobs::class, 'Specialpages' => \SpecialSpecialpages::class, 'PageData' => \SpecialPageData::class, diff --git a/includes/specials/SpecialApiSandbox.php b/includes/specials/SpecialApiSandbox.php index 9e496845f8..f4a33c8c54 100644 --- a/includes/specials/SpecialApiSandbox.php +++ b/includes/specials/SpecialApiSandbox.php @@ -21,6 +21,8 @@ * @ingroup SpecialPage */ +use MediaWiki\MediaWikiServices; + /** * @ingroup SpecialPage * @since 1.27 @@ -35,7 +37,10 @@ class SpecialApiSandbox extends SpecialPage { $out = $this->getOutput(); $this->addHelpLink( 'Help:ApiSandbox' ); - $out->addJsConfigVars( 'apihighlimits', $this->getUser()->isAllowed( 'apihighlimits' ) ); + $out->addJsConfigVars( 'apihighlimits', MediaWikiServices::getInstance() + ->getPermissionManager() + ->userHasRight( $this->getUser(), 'apihighlimits' ) + ); $out->addModuleStyles( [ 'mediawiki.special', 'mediawiki.hlist', diff --git a/includes/specials/SpecialAutoblockList.php b/includes/specials/SpecialAutoblockList.php index 34c3371bf2..3f98e93045 100644 --- a/includes/specials/SpecialAutoblockList.php +++ b/includes/specials/SpecialAutoblockList.php @@ -21,6 +21,8 @@ * @ingroup SpecialPage */ +use MediaWiki\MediaWikiServices; + /** * A special page that lists autoblocks * @@ -81,7 +83,10 @@ class SpecialAutoblockList extends SpecialPage { 'ipb_parent_block_id IS NOT NULL' ]; # Is the user allowed to see hidden blocks? - if ( !$this->getUser()->isAllowed( 'hideuser' ) ) { + if ( !MediaWikiServices::getInstance() + ->getPermissionManager() + ->userHasRight( $this->getUser(), 'hideuser' ) + ) { $conds['ipb_deleted'] = 0; } diff --git a/includes/specials/SpecialBlock.php b/includes/specials/SpecialBlock.php index 07214af4fa..1b0db7345c 100644 --- a/includes/specials/SpecialBlock.php +++ b/includes/specials/SpecialBlock.php @@ -25,6 +25,7 @@ use MediaWiki\Block\DatabaseBlock; use MediaWiki\Block\Restriction\PageRestriction; use MediaWiki\Block\Restriction\NamespaceRestriction; use MediaWiki\MediaWikiServices; +use MediaWiki\User\UserIdentity; /** * A special page that allows users with 'block' right to block users from @@ -269,7 +270,10 @@ class SpecialBlock extends FormSpecialPage { ]; # Allow some users to hide name from block log, blocklist and listusers - if ( $user->isAllowed( 'hideuser' ) ) { + if ( MediaWikiServices::getInstance() + ->getPermissionManager() + ->userHasRight( $user, 'hideuser' ) + ) { $a['HideUser'] = [ 'type' => 'check', 'label-message' => 'ipbhidename', @@ -363,7 +367,10 @@ class SpecialBlock extends FormSpecialPage { // If the username was hidden (ipb_deleted == 1), don't show the reason // unless this user also has rights to hideuser: T37839 - if ( !$block->getHideName() || $this->getUser()->isAllowed( 'hideuser' ) ) { + if ( !$block->getHideName() || MediaWikiServices::getInstance() + ->getPermissionManager() + ->userHasRight( $this->getUser(), 'hideuser' ) + ) { $fields['Reason']['default'] = $block->getReason(); } else { $fields['Reason']['default'] = ''; @@ -545,7 +552,8 @@ class SpecialBlock extends FormSpecialPage { $user = $this->getUser(); # Link to edit the block dropdown reasons, if applicable - if ( $user->isAllowed( 'editinterface' ) ) { + $permissionManager = MediaWikiServices::getInstance()->getPermissionManager(); + if ( $permissionManager->userHasRight( $user, 'editinterface' ) ) { $links[] = $linkRenderer->makeKnownLink( $this->msg( 'ipbreason-dropdown' )->inContentLanguage()->getTitle(), $this->msg( 'ipb-edit-dropdown' )->text(), @@ -579,7 +587,7 @@ class SpecialBlock extends FormSpecialPage { $text .= $out; # Add suppression block entries if allowed - if ( $user->isAllowed( 'suppressionlog' ) ) { + if ( $permissionManager->userHasRight( $user, 'suppressionlog' ) ) { LogEventsList::showLogExtract( $out, 'suppress', @@ -828,7 +836,10 @@ class SpecialBlock extends FormSpecialPage { } if ( $data['HideUser'] ) { - if ( !$performer->isAllowed( 'hideuser' ) ) { + if ( !MediaWikiServices::getInstance() + ->getPermissionManager() + ->userHasRight( $performer, 'hideuser' ) + ) { # this codepath is unreachable except by a malicious user spoofing forms, # or by race conditions (user has hideuser and block rights, loads block form, # and loses hideuser rights before submission); so need to fail completely @@ -938,7 +949,10 @@ class SpecialBlock extends FormSpecialPage { } # If the name was hidden and the blocking user cannot hide # names, then don't allow any block changes... - if ( $currentBlock->getHideName() && !$performer->isAllowed( 'hideuser' ) ) { + if ( $currentBlock->getHideName() && !MediaWikiServices::getInstance() + ->getPermissionManager() + ->userHasRight( $performer, 'hideuser' ) + ) { return [ 'cant-see-hidden-user' ]; } @@ -1106,13 +1120,15 @@ class SpecialBlock extends FormSpecialPage { /** * Can we do an email block? - * @param User $user The sysop wanting to make a block + * @param UserIdentity $user The sysop wanting to make a block * @return bool */ - public static function canBlockEmail( $user ) { + public static function canBlockEmail( UserIdentity $user ) { global $wgEnableUserEmail, $wgSysopEmailBans; - return ( $wgEnableUserEmail && $wgSysopEmailBans && $user->isAllowed( 'blockemail' ) ); + return ( $wgEnableUserEmail && $wgSysopEmailBans && MediaWikiServices::getInstance() + ->getPermissionManager() + ->userHasRight( $user, 'blockemail' ) ); } /** @@ -1138,7 +1154,10 @@ class SpecialBlock extends FormSpecialPage { if ( $performer->getBlock() ) { if ( $target instanceof User && $target->getId() == $performer->getId() ) { # User is trying to unblock themselves - if ( $performer->isAllowed( 'unblockself' ) ) { + if ( MediaWikiServices::getInstance() + ->getPermissionManager() + ->userHasRight( $performer, 'unblockself' ) + ) { return true; # User blocked themselves and is now trying to reverse it } elseif ( $performer->blockedBy() === $performer->getName() ) { diff --git a/includes/specials/SpecialBlockList.php b/includes/specials/SpecialBlockList.php index b3d2358193..2dd682f305 100644 --- a/includes/specials/SpecialBlockList.php +++ b/includes/specials/SpecialBlockList.php @@ -22,6 +22,7 @@ */ use MediaWiki\Block\DatabaseBlock; +use MediaWiki\MediaWikiServices; /** * A special page that lists existing blocks @@ -82,8 +83,9 @@ class SpecialBlockList extends SpecialPage { 'Options' => [ 'type' => 'multiselect', 'options-messages' => [ - 'blocklist-userblocks' => 'userblocks', 'blocklist-tempblocks' => 'tempblocks', + 'blocklist-indefblocks' => 'indefblocks', + 'blocklist-userblocks' => 'userblocks', 'blocklist-addressblocks' => 'addressblocks', 'blocklist-rangeblocks' => 'rangeblocks', ], @@ -136,8 +138,12 @@ class SpecialBlockList extends SpecialPage { */ protected function getBlockListPager() { $conds = []; + $db = $this->getDB(); # Is the user allowed to see hidden blocks? - if ( !$this->getUser()->isAllowed( 'hideuser' ) ) { + if ( !MediaWikiServices::getInstance() + ->getPermissionManager() + ->userHasRight( $this->getUser(), 'hideuser' ) + ) { $conds['ipb_deleted'] = 0; } @@ -153,7 +159,7 @@ class SpecialBlockList extends SpecialPage { case DatabaseBlock::TYPE_IP: case DatabaseBlock::TYPE_RANGE: list( $start, $end ) = IP::parseRange( $target ); - $conds[] = wfGetDB( DB_REPLICA )->makeList( + $conds[] = $db->makeList( [ 'ipb_address' => $target, DatabaseBlock::getRangeCond( $start, $end ) @@ -174,9 +180,6 @@ class SpecialBlockList extends SpecialPage { if ( in_array( 'userblocks', $this->options ) ) { $conds['ipb_user'] = 0; } - if ( in_array( 'tempblocks', $this->options ) ) { - $conds['ipb_expiry'] = 'infinity'; - } if ( in_array( 'addressblocks', $this->options ) ) { $conds[] = "ipb_user != 0 OR ipb_range_end > ipb_range_start"; } @@ -184,10 +187,21 @@ class SpecialBlockList extends SpecialPage { $conds[] = "ipb_range_end = ipb_range_start"; } + $hideTemp = in_array( 'tempblocks', $this->options ); + $hideIndef = in_array( 'indefblocks', $this->options ); + if ( $hideTemp && $hideIndef ) { + // If both types are hidden, ensure query doesn't produce any results + $conds[] = '1=0'; + } elseif ( $hideTemp ) { + $conds['ipb_expiry'] = $db->getInfinity(); + } elseif ( $hideIndef ) { + $conds[] = "ipb_expiry != " . $db->addQuotes( $db->getInfinity() ); + } + if ( $this->blockType === 'sitewide' ) { - $conds[] = 'ipb_sitewide = 1'; + $conds['ipb_sitewide'] = 1; } elseif ( $this->blockType === 'partial' ) { - $conds[] = 'ipb_sitewide = 0'; + $conds['ipb_sitewide'] = 0; } return new BlockListPager( $this, $conds ); @@ -243,4 +257,13 @@ class SpecialBlockList extends SpecialPage { protected function getGroupName() { return 'users'; } + + /** + * Return a IDatabase object for reading + * + * @return IDatabase + */ + protected function getDB() { + return wfGetDB( DB_REPLICA ); + } } diff --git a/includes/specials/SpecialBrokenRedirects.php b/includes/specials/SpecialBrokenRedirects.php index 9431cefbaf..392b4e970d 100644 --- a/includes/specials/SpecialBrokenRedirects.php +++ b/includes/specials/SpecialBrokenRedirects.php @@ -21,6 +21,7 @@ * @ingroup SpecialPage */ +use MediaWiki\MediaWikiServices; use Wikimedia\Rdbms\IResultWrapper; use Wikimedia\Rdbms\IDatabase; @@ -114,6 +115,8 @@ class SpecialBrokenRedirects extends QueryPage { } $linkRenderer = $this->getLinkRenderer(); + $permissionManager = MediaWikiServices::getInstance()->getPermissionManager(); + // $toObj may very easily be false if the $result list is cached if ( !is_object( $toObj ) ) { return '' . $linkRenderer->makeLink( $fromObj ) . ''; @@ -129,7 +132,7 @@ class SpecialBrokenRedirects extends QueryPage { // if the page is editable, add an edit link if ( // check user permissions - $this->getUser()->isAllowed( 'edit' ) && + $permissionManager->userHasRight( $this->getUser(), 'edit' ) && // check, if the content model is editable through action=edit ContentHandler::getForTitle( $fromObj )->supportsDirectEditing() ) { @@ -145,7 +148,7 @@ class SpecialBrokenRedirects extends QueryPage { $out = $from . $this->msg( 'word-separator' )->escaped(); - if ( $this->getUser()->isAllowed( 'delete' ) ) { + if ( $permissionManager->userHasRight( $this->getUser(), 'delete' ) ) { $links[] = $linkRenderer->makeKnownLink( $fromObj, $this->msg( 'brokenredirects-delete' )->text(), diff --git a/includes/specials/SpecialChangeContentModel.php b/includes/specials/SpecialChangeContentModel.php index 01f7e56769..46fa17e054 100644 --- a/includes/specials/SpecialChangeContentModel.php +++ b/includes/specials/SpecialChangeContentModel.php @@ -1,5 +1,7 @@ oldRevision ? EDIT_UPDATE : EDIT_NEW; $flags |= EDIT_INTERNAL; - if ( $user->isAllowed( 'bot' ) ) { + if ( MediaWikiServices::getInstance() + ->getPermissionManager() + ->userHasRight( $user, 'bot' ) + ) { $flags |= EDIT_FORCE_BOT; } diff --git a/includes/specials/SpecialChangeEmail.php b/includes/specials/SpecialChangeEmail.php index c95aa1b558..7331cd7c2b 100644 --- a/includes/specials/SpecialChangeEmail.php +++ b/includes/specials/SpecialChangeEmail.php @@ -23,6 +23,7 @@ use MediaWiki\Auth\AuthManager; use MediaWiki\Logger\LoggerFactory; +use MediaWiki\MediaWikiServices; /** * Let users change their email address. @@ -74,7 +75,10 @@ class SpecialChangeEmail extends FormSpecialPage { // This could also let someone check the current email address, so // require both permissions. - if ( !$this->getUser()->isAllowed( 'viewmyprivateinfo' ) ) { + if ( !MediaWikiServices::getInstance() + ->getPermissionManager() + ->userHasRight( $this->getUser(), 'viewmyprivateinfo' ) + ) { throw new PermissionsError( 'viewmyprivateinfo' ); } diff --git a/includes/specials/SpecialConfirmEmail.php b/includes/specials/SpecialConfirmEmail.php index f86a133a13..2c42cd386a 100644 --- a/includes/specials/SpecialConfirmEmail.php +++ b/includes/specials/SpecialConfirmEmail.php @@ -21,6 +21,8 @@ * @ingroup SpecialPage */ +use MediaWiki\MediaWikiServices; + /** * Special page allows users to request email confirmation message, and handles * processing of the confirmation code when the link in the email is followed @@ -57,7 +59,10 @@ class SpecialConfirmEmail extends UnlistedSpecialPage { // This could also let someone check the current email address, so // require both permissions. - if ( !$this->getUser()->isAllowed( 'viewmyprivateinfo' ) ) { + if ( !MediaWikiServices::getInstance() + ->getPermissionManager() + ->userHasRight( $this->getUser(), 'viewmyprivateinfo' ) + ) { throw new PermissionsError( 'viewmyprivateinfo' ); } diff --git a/includes/specials/SpecialContributions.php b/includes/specials/SpecialContributions.php index 40c0edf542..e8b85fa024 100644 --- a/includes/specials/SpecialContributions.php +++ b/includes/specials/SpecialContributions.php @@ -126,7 +126,10 @@ class SpecialContributions extends IncludableSpecialPage { // Allows reverts to have the bot flag in recent changes. It is just here to // be passed in the form at the top of the page - if ( $user->isAllowed( 'markbotedits' ) && $request->getBool( 'bot' ) ) { + if ( MediaWikiServices::getInstance() + ->getPermissionManager() + ->userHasRight( $user, 'markbotedits' ) && $request->getBool( 'bot' ) + ) { $this->opts['bot'] = '1'; } @@ -373,7 +376,9 @@ class SpecialContributions extends IncludableSpecialPage { ); } - if ( $sp->getUser()->isAllowed( 'block' ) ) { # Block / Change block / Unblock links + # Block / Change block / Unblock links + $permissionManager = MediaWikiServices::getInstance()->getPermissionManager(); + if ( $permissionManager->userHasRight( $sp->getUser(), 'block' ) ) { if ( $target->getBlock() && $target->getBlock()->getType() != DatabaseBlock::TYPE_AUTO ) { $tools['block'] = $linkRenderer->makeKnownLink( # Change block link SpecialPage::getTitleFor( 'Block', $username ), @@ -400,7 +405,7 @@ class SpecialContributions extends IncludableSpecialPage { ); # Suppression log link (T61120) - if ( $sp->getUser()->isAllowed( 'suppressionlog' ) ) { + if ( $permissionManager->userHasRight( $sp->getUser(), 'suppressionlog' ) ) { $tools['log-suppression'] = $linkRenderer->makeKnownLink( SpecialPage::getTitleFor( 'Log', 'suppress' ), $sp->msg( 'sp-contributions-suppresslog', $username )->text(), @@ -412,7 +417,7 @@ class SpecialContributions extends IncludableSpecialPage { # Don't show some links for IP ranges if ( !$isRange ) { # Uploads: hide if IPs cannot upload (T220674) - if ( !$isIP || $target->isAllowed( 'upload' ) ) { + if ( !$isIP || $permissionManager->userHasRight( $target, 'upload' ) ) { $tools['uploads'] = $linkRenderer->makeKnownLink( SpecialPage::getTitleFor( 'Listfiles', $username ), $sp->msg( 'sp-contributions-uploads' )->text() @@ -428,7 +433,7 @@ class SpecialContributions extends IncludableSpecialPage { # Add link to deleted user contributions for priviledged users # Todo: T183457 - if ( $sp->getUser()->isAllowed( 'deletedhistory' ) ) { + if ( $permissionManager->userHasRight( $sp->getUser(), 'deletedhistory' ) ) { $tools['deletedcontribs'] = $linkRenderer->makeKnownLink( SpecialPage::getTitleFor( 'DeletedContributions', $username ), $sp->msg( 'sp-contributions-deleted', $username )->text() @@ -628,7 +633,10 @@ class SpecialContributions extends IncludableSpecialPage { $filters = []; - if ( $this->getUser()->isAllowed( 'deletedhistory' ) ) { + if ( MediaWikiServices::getInstance() + ->getPermissionManager() + ->userHasRight( $this->getUser(), 'deletedhistory' ) + ) { $filters[] = Html::rawElement( 'span', [ 'class' => 'mw-input-with-label' ], diff --git a/includes/specials/SpecialCreateAccount.php b/includes/specials/SpecialCreateAccount.php index cc2fc80970..637025c985 100644 --- a/includes/specials/SpecialCreateAccount.php +++ b/includes/specials/SpecialCreateAccount.php @@ -57,7 +57,9 @@ class SpecialCreateAccount extends LoginSignupSpecialPage { } public function userCanExecute( User $user ) { - return $user->isAllowed( 'createaccount' ); + return MediaWikiServices::getInstance() + ->getPermissionManager() + ->userHasRight( $user, 'createaccount' ); } public function checkPermissions() { diff --git a/includes/specials/SpecialDoubleRedirects.php b/includes/specials/SpecialDoubleRedirects.php index cccca5063a..540ac5aaef 100644 --- a/includes/specials/SpecialDoubleRedirects.php +++ b/includes/specials/SpecialDoubleRedirects.php @@ -21,6 +21,7 @@ * @ingroup SpecialPage */ +use MediaWiki\MediaWikiServices; use Wikimedia\Rdbms\IResultWrapper; use Wikimedia\Rdbms\IDatabase; @@ -155,7 +156,9 @@ class SpecialDoubleRedirects extends QueryPage { // if the page is editable, add an edit link if ( // check user permissions - $this->getUser()->isAllowed( 'edit' ) && + MediaWikiServices::getInstance() + ->getPermissionManager() + ->userHasRight( $this->getUser(), 'edit' ) && // check, if the content model is editable through action=edit ContentHandler::getForTitle( $titleA )->supportsDirectEditing() ) { diff --git a/includes/specials/SpecialEditTags.php b/includes/specials/SpecialEditTags.php index 70a1bd4783..48357aa7ad 100644 --- a/includes/specials/SpecialEditTags.php +++ b/includes/specials/SpecialEditTags.php @@ -19,6 +19,8 @@ * @ingroup SpecialPage */ +use MediaWiki\Permissions\PermissionManager; + /** * Special page for adding and removing change tags to individual revisions. * A lot of this is copied out of SpecialRevisiondelete. @@ -51,8 +53,18 @@ class SpecialEditTags extends UnlistedSpecialPage { /** @var string */ private $reason; - public function __construct() { + /** @var PermissionManager */ + private $permissionManager; + + /** + * @inheritDoc + * + * @param PermissionManager $permissionManager + */ + public function __construct( PermissionManager $permissionManager ) { parent::__construct( 'EditTags', 'changetags' ); + + $this->permissionManager = $permissionManager; } public function doesWrites() { @@ -67,13 +79,6 @@ class SpecialEditTags extends UnlistedSpecialPage { $user = $this->getUser(); $request = $this->getRequest(); - // Check blocks - // @TODO Use PermissionManager::isBlockedFrom() instead. - $block = $user->getBlock(); - if ( $block ) { - throw new UserBlockedError( $block ); - } - $this->setHeaders(); $this->outputHeader(); @@ -124,7 +129,7 @@ class SpecialEditTags extends UnlistedSpecialPage { $this->ids ); - $this->isAllowed = $user->isAllowed( 'changetags' ); + $this->isAllowed = $this->permissionManager->userHasRight( $user, 'changetags' ); $this->reason = $request->getVal( 'wpReason' ); // We need a target page! @@ -132,6 +137,12 @@ class SpecialEditTags extends UnlistedSpecialPage { $output->addWikiMsg( 'undelete-header' ); return; } + + // Check blocks + if ( $this->permissionManager->isBlockedFrom( $user, $this->targetObj ) ) { + throw new UserBlockedError( $user->getBlock() ); + } + // Give a link to the logs/hist for this page $this->showConvenienceLinks(); diff --git a/includes/specials/SpecialEmailUser.php b/includes/specials/SpecialEmailUser.php index b42cdea08a..c8b92bd10d 100644 --- a/includes/specials/SpecialEmailUser.php +++ b/includes/specials/SpecialEmailUser.php @@ -253,7 +253,10 @@ class SpecialEmailUser extends UnlistedSpecialPage { return 'mailnologin'; } - if ( !$user->isAllowed( 'sendemail' ) ) { + if ( !MediaWikiServices::getInstance() + ->getPermissionManager() + ->userHasRight( $user, 'sendemail' ) + ) { return 'badaccess'; } diff --git a/includes/specials/SpecialExpandTemplates.php b/includes/specials/SpecialExpandTemplates.php index ef1b3d89f1..72e881f967 100644 --- a/includes/specials/SpecialExpandTemplates.php +++ b/includes/specials/SpecialExpandTemplates.php @@ -273,7 +273,10 @@ class SpecialExpandTemplates extends SpecialPage { // allowed and a valid edit token is not provided (T73111). However, MediaWiki // does not currently provide logged-out users with CSRF protection; in that case, // do not show the preview unless anonymous editing is allowed. - if ( $user->isAnon() && !$user->isAllowed( 'edit' ) ) { + if ( $user->isAnon() && !MediaWikiServices::getInstance() + ->getPermissionManager() + ->userHasRight( $user, 'edit' ) + ) { $error = [ 'expand_templates_preview_fail_html_anon' ]; } elseif ( !$user->matchEditToken( $request->getVal( 'wpEditToken' ), '', $request ) ) { $error = [ 'expand_templates_preview_fail_html' ]; @@ -282,7 +285,7 @@ class SpecialExpandTemplates extends SpecialPage { } if ( $error ) { - $out->wrapWikiMsg( "
\n$1\n
", $error ); + $out->wrapWikiMsg( "
\n$1\n
", $error ); return; } } diff --git a/includes/specials/SpecialExport.php b/includes/specials/SpecialExport.php index 5a6358147f..e680d240c0 100644 --- a/includes/specials/SpecialExport.php +++ b/includes/specials/SpecialExport.php @@ -327,7 +327,9 @@ class SpecialExport extends SpecialPage { * @return bool */ private function userCanOverrideExportDepth() { - return $this->getUser()->isAllowed( 'override-export-depth' ); + return MediaWikiServices::getInstance() + ->getPermissionManager() + ->userHasRight( $this->getUser(), 'override-export-depth' ); } /** diff --git a/includes/specials/SpecialImport.php b/includes/specials/SpecialImport.php index f21c20651b..cfefa47642 100644 --- a/includes/specials/SpecialImport.php +++ b/includes/specials/SpecialImport.php @@ -135,18 +135,19 @@ class SpecialImport extends SpecialPage { } $user = $this->getUser(); + $permissionManager = MediaWikiServices::getInstance()->getPermissionManager(); if ( !$user->matchEditToken( $request->getVal( 'editToken' ) ) ) { $source = Status::newFatal( 'import-token-mismatch' ); } elseif ( $this->sourceName === 'upload' ) { $isUpload = true; $this->usernamePrefix = $this->fullInterwikiPrefix = $request->getVal( 'usernamePrefix' ); - if ( $user->isAllowed( 'importupload' ) ) { + if ( $permissionManager->userHasRight( $user, 'importupload' ) ) { $source = ImportStreamSource::newFromUpload( "xmlimport" ); } else { throw new PermissionsError( 'importupload' ); } } elseif ( $this->sourceName === 'interwiki' ) { - if ( !$user->isAllowed( 'import' ) ) { + if ( !$permissionManager->userHasRight( $user, 'import' ) ) { throw new PermissionsError( 'import' ); } $this->interwiki = $this->fullInterwikiPrefix = $request->getVal( 'interwiki' ); @@ -325,10 +326,11 @@ class SpecialImport extends SpecialPage { private function showForm() { $action = $this->getPageTitle()->getLocalURL( [ 'action' => 'submit' ] ); $user = $this->getUser(); + $permissionManager = MediaWikiServices::getInstance()->getPermissionManager(); $out = $this->getOutput(); $this->addHelpLink( 'https://meta.wikimedia.org/wiki/Special:MyLanguage/Help:Import', true ); - if ( $user->isAllowed( 'importupload' ) ) { + if ( $permissionManager->userHasRight( $user, 'importupload' ) ) { $mappingSelection = $this->getMappingFormPart( 'upload' ); $out->addHTML( Xml::fieldset( $this->msg( 'import-upload' )->text() ) . @@ -401,7 +403,7 @@ class SpecialImport extends SpecialPage { $out->addWikiMsg( 'importnosources' ); } - if ( $user->isAllowed( 'import' ) && !empty( $this->importSources ) ) { + if ( $permissionManager->userHasRight( $user, 'import' ) && !empty( $this->importSources ) ) { # Show input field for import depth only if $wgExportMaxLinkDepth > 0 $importDepth = ''; if ( $this->getConfig()->get( 'ExportMaxLinkDepth' ) > 0 ) { diff --git a/includes/specials/SpecialLinkSearch.php b/includes/specials/SpecialLinkSearch.php index f2a3f80df1..60aeddaf84 100644 --- a/includes/specials/SpecialLinkSearch.php +++ b/includes/specials/SpecialLinkSearch.php @@ -32,6 +32,12 @@ use Wikimedia\Rdbms\IDatabase; class SpecialLinkSearch extends QueryPage { /** @var array|bool */ private $mungedQuery = false; + /** @var string|null */ + private $mQuery; + /** @var int|null */ + private $mNs; + /** @var string|null */ + private $mProt; function setParams( $params ) { $this->mQuery = $params['query']; diff --git a/includes/specials/SpecialLog.php b/includes/specials/SpecialLog.php index ac8baa12c1..7c858147e1 100644 --- a/includes/specials/SpecialLog.php +++ b/includes/specials/SpecialLog.php @@ -94,7 +94,9 @@ class SpecialLog extends SpecialPage { if ( !LogPage::isLogType( $type ) ) { $opts->setValue( 'type', '' ); } elseif ( isset( $logRestrictions[$type] ) - && !$this->getUser()->isAllowed( $logRestrictions[$type] ) + && !MediaWikiServices::getInstance() + ->getPermissionManager() + ->userHasRight( $this->getUser(), $logRestrictions[$type] ) ) { throw new PermissionsError( $logRestrictions[$type] ); } diff --git a/includes/specials/SpecialMovepage.php b/includes/specials/SpecialMovepage.php index 6da362dd1b..0767fafe67 100644 --- a/includes/specials/SpecialMovepage.php +++ b/includes/specials/SpecialMovepage.php @@ -209,7 +209,9 @@ class MovePageForm extends UnlistedSpecialPage { } if ( count( $err ) == 1 && isset( $err[0][0] ) && $err[0][0] == 'file-exists-sharedrepo' - && $user->isAllowed( 'reupload-shared' ) + && MediaWikiServices::getInstance() + ->getPermissionManager() + ->userHasRight( $user, 'reupload-shared' ) ) { $out->wrapWikiMsg( "
\n$1\n
\n", @@ -374,7 +376,10 @@ class MovePageForm extends UnlistedSpecialPage { ); } - if ( $user->isAllowed( 'suppressredirect' ) ) { + if ( MediaWikiServices::getInstance() + ->getPermissionManager() + ->userHasRight( $user, 'suppressredirect' ) + ) { if ( $handlerSupportsRedirects ) { $isChecked = $this->leaveRedirect; $isDisabled = false; @@ -520,6 +525,7 @@ class MovePageForm extends UnlistedSpecialPage { function doSubmit() { $user = $this->getUser(); + $permissionManager = MediaWikiServices::getInstance()->getPermissionManager(); if ( $user->pingLimiter( 'move' ) ) { throw new ThrottledError; @@ -540,7 +546,7 @@ class MovePageForm extends UnlistedSpecialPage { # Show a warning if the target file exists on a shared repo $repoGroup = $services->getRepoGroup(); if ( $nt->getNamespace() == NS_FILE - && !( $this->moveOverShared && $user->isAllowed( 'reupload-shared' ) ) + && !( $this->moveOverShared && $permissionManager->userHasRight( $user, 'reupload-shared' ) ) && !$repoGroup->getLocalRepo()->findFile( $nt ) && $repoGroup->findFile( $nt ) ) { @@ -551,7 +557,7 @@ class MovePageForm extends UnlistedSpecialPage { # Delete to make way if requested if ( $this->deleteAndMove ) { - $permErrors = $nt->getUserPermissionsErrors( 'delete', $user ); + $permErrors = $permissionManager->getPermissionErrors( 'delete', $user, $nt ); if ( count( $permErrors ) ) { # Only show the first error $this->showForm( $permErrors, true ); @@ -592,7 +598,7 @@ class MovePageForm extends UnlistedSpecialPage { if ( !$handler->supportsRedirects() ) { $createRedirect = false; - } elseif ( $user->isAllowed( 'suppressredirect' ) ) { + } elseif ( $permissionManager->userHasRight( $user, 'suppressredirect' ) ) { $createRedirect = $this->leaveRedirect; } else { $createRedirect = true; @@ -607,7 +613,6 @@ class MovePageForm extends UnlistedSpecialPage { $this->moveTalk = false; } if ( $this->moveSubpages ) { - $permissionManager = $services->getPermissionManager(); $this->moveSubpages = $permissionManager->userCan( 'move-subpages', $user, $ot ); } diff --git a/includes/specials/SpecialPagesWithProp.php b/includes/specials/SpecialPagesWithProp.php index 3c009c3966..527b910fcf 100644 --- a/includes/specials/SpecialPagesWithProp.php +++ b/includes/specials/SpecialPagesWithProp.php @@ -39,6 +39,11 @@ class SpecialPagesWithProp extends QueryPage { */ private $existingPropNames = null; + /** + * @var string|null + */ + private $ns; + /** * @var bool */ @@ -78,6 +83,13 @@ class SpecialPagesWithProp extends QueryPage { 'label-message' => 'pageswithprop-prop', 'required' => true, ], + 'namespace' => [ + 'type' => 'namespaceselect', + 'name' => 'namespace', + 'label-message' => 'namespace', + 'all' => null, + 'default' => null, + ], 'reverse' => [ 'type' => 'check', 'name' => 'reverse', @@ -108,6 +120,7 @@ class SpecialPagesWithProp extends QueryPage { public function onSubmit( $data, $form ) { $this->propName = $data['propname']; + $this->ns = $data['namespace']; parent::execute( $data['propname'] ); } @@ -134,7 +147,7 @@ class SpecialPagesWithProp extends QueryPage { } public function getQueryInfo() { - return [ + $query = [ 'tables' => [ 'page_props', 'page' ], 'fields' => [ 'page_id' => 'pp_page', @@ -153,6 +166,12 @@ class SpecialPagesWithProp extends QueryPage { ], 'options' => [] ]; + + if ( $this->ns && isset( $this->ns ) ) { + $query['conds']['page_namespace'] = $this->ns; + } + + return $query; } function getOrderFields() { diff --git a/includes/specials/SpecialPasswordReset.php b/includes/specials/SpecialPasswordReset.php index 3524d79e65..2ef96ad854 100644 --- a/includes/specials/SpecialPasswordReset.php +++ b/includes/specials/SpecialPasswordReset.php @@ -22,6 +22,7 @@ */ use MediaWiki\Auth\AuthManager; +use MediaWiki\MediaWikiServices; /** * Special page for requesting a password reset email. @@ -52,7 +53,11 @@ class SpecialPasswordReset extends FormSpecialPage { private function getPasswordReset() { if ( $this->passwordReset === null ) { - $this->passwordReset = new PasswordReset( $this->getConfig(), AuthManager::singleton() ); + $this->passwordReset = new PasswordReset( + $this->getConfig(), + AuthManager::singleton(), + MediaWikiServices::getInstance()->getPermissionManager() + ); } return $this->passwordReset; } diff --git a/includes/specials/SpecialPreferences.php b/includes/specials/SpecialPreferences.php index 0bc9147fad..d541eadcd6 100644 --- a/includes/specials/SpecialPreferences.php +++ b/includes/specials/SpecialPreferences.php @@ -115,7 +115,10 @@ class SpecialPreferences extends SpecialPage { } protected function showResetForm() { - if ( !$this->getUser()->isAllowed( 'editmyoptions' ) ) { + if ( !MediaWikiServices::getInstance() + ->getPermissionManager() + ->userHasRight( $this->getUser(), 'editmyoptions' ) + ) { throw new PermissionsError( 'editmyoptions' ); } @@ -134,7 +137,10 @@ class SpecialPreferences extends SpecialPage { } public function submitReset( $formData ) { - if ( !$this->getUser()->isAllowed( 'editmyoptions' ) ) { + if ( !MediaWikiServices::getInstance() + ->getPermissionManager() + ->userHasRight( $this->getUser(), 'editmyoptions' ) + ) { throw new PermissionsError( 'editmyoptions' ); } diff --git a/includes/specials/SpecialRecentChanges.php b/includes/specials/SpecialRecentChanges.php index 0bfe1855df..4683fe6861 100644 --- a/includes/specials/SpecialRecentChanges.php +++ b/includes/specials/SpecialRecentChanges.php @@ -185,7 +185,9 @@ class SpecialRecentChanges extends ChangesListSpecialPage { if ( !$this->including() && $this->getUser()->isLoggedIn() && - $this->getUser()->isAllowed( 'viewmywatchlist' ) + MediaWikiServices::getInstance() + ->getPermissionManager() + ->userHasRight( $this->getUser(), 'viewmywatchlist' ) ) { $this->registerFiltersFromDefinitions( [ $this->watchlistFilterGroupDefinition ] ); $watchlistGroup = $this->getFilterGroup( 'watchlist' ); @@ -279,7 +281,10 @@ class SpecialRecentChanges extends ChangesListSpecialPage { $join_conds = array_merge( $join_conds, $rcQuery['joins'] ); // JOIN on watchlist for users - if ( $user->isLoggedIn() && $user->isAllowed( 'viewmywatchlist' ) ) { + if ( $user->isLoggedIn() && MediaWikiServices::getInstance() + ->getPermissionManager() + ->userHasRight( $user, 'viewmywatchlist' ) + ) { $tables[] = 'watchlist'; $fields[] = 'wl_user'; $fields[] = 'wl_notificationtimestamp'; diff --git a/includes/specials/SpecialRecentChangesLinked.php b/includes/specials/SpecialRecentChangesLinked.php index 26f3665597..0921adaab8 100644 --- a/includes/specials/SpecialRecentChangesLinked.php +++ b/includes/specials/SpecialRecentChangesLinked.php @@ -21,6 +21,8 @@ * @ingroup SpecialPage */ +use MediaWiki\MediaWikiServices; + /** * This is to display changes made to all articles linked in an article. * @@ -91,7 +93,10 @@ class SpecialRecentChangesLinked extends SpecialRecentChanges { // left join with watchlist table to highlight watched rows $uid = $this->getUser()->getId(); - if ( $uid && $this->getUser()->isAllowed( 'viewmywatchlist' ) ) { + if ( $uid && MediaWikiServices::getInstance() + ->getPermissionManager() + ->userHasRight( $this->getUser(), 'viewmywatchlist' ) + ) { $tables[] = 'watchlist'; $select[] = 'wl_user'; $join_conds['watchlist'] = [ 'LEFT JOIN', [ diff --git a/includes/specials/SpecialRedirect.php b/includes/specials/SpecialRedirect.php index 50867dd879..82d8b73b1f 100644 --- a/includes/specials/SpecialRedirect.php +++ b/includes/specials/SpecialRedirect.php @@ -90,7 +90,9 @@ class SpecialRedirect extends FormSpecialPage { } $userpage = Title::makeTitle( NS_USER, $username ); - return Status::newGood( $userpage->getFullURL( '', false, PROTO_CURRENT ) ); + return Status::newGood( [ + $userpage->getFullURL( '', false, PROTO_CURRENT ), 302 + ] ); } /** diff --git a/includes/specials/SpecialRevisionDelete.php b/includes/specials/SpecialRevisionDelete.php index 7444225360..698e5907cf 100644 --- a/includes/specials/SpecialRevisionDelete.php +++ b/includes/specials/SpecialRevisionDelete.php @@ -21,7 +21,9 @@ * @ingroup SpecialPage */ +use MediaWiki\MediaWikiServices; use MediaWiki\Storage\RevisionRecord; +use MediaWiki\Permissions\PermissionManager; /** * Special page allowing users with the appropriate permissions to view @@ -66,6 +68,9 @@ class SpecialRevisionDelete extends UnlistedSpecialPage { /** @var string */ private $otherReason; + /** @var PermissionManager */ + private $permissionManager; + /** * UI labels for each type. */ @@ -107,8 +112,15 @@ class SpecialRevisionDelete extends UnlistedSpecialPage { ], ]; - public function __construct() { + /** + * @inheritDoc + * + * @param PermissionManager $permissionManager + */ + public function __construct( PermissionManager $permissionManager ) { parent::__construct( 'Revisiondelete', 'deleterevision' ); + + $this->permissionManager = $permissionManager; } public function doesWrites() { @@ -124,13 +136,6 @@ class SpecialRevisionDelete extends UnlistedSpecialPage { $output = $this->getOutput(); $user = $this->getUser(); - // Check blocks - // @TODO Use PermissionManager::isBlockedFrom() instead. - $block = $user->getBlock(); - if ( $block ) { - throw new UserBlockedError( $block ); - } - $this->setHeaders(); $this->outputHeader(); $request = $this->getRequest(); @@ -180,12 +185,19 @@ class SpecialRevisionDelete extends UnlistedSpecialPage { return; } + // Check blocks + if ( $this->permissionManager->isBlockedFrom( $user, $this->targetObj ) ) { + throw new UserBlockedError( $user->getBlock() ); + } + $this->typeLabels = self::$UILabels[$this->typeName]; $list = $this->getList(); $list->reset(); - $this->mIsAllowed = $user->isAllowed( RevisionDeleter::getRestriction( $this->typeName ) ); - $canViewSuppressedOnly = $this->getUser()->isAllowed( 'viewsuppressed' ) && - !$this->getUser()->isAllowed( 'suppressrevision' ); + $permissionManager = MediaWikiServices::getInstance()->getPermissionManager(); + $this->mIsAllowed = $permissionManager->userHasRight( $user, + RevisionDeleter::getRestriction( $this->typeName ) ); + $canViewSuppressedOnly = $permissionManager->userHasRight( $user, 'viewsuppressed' ) && + !$permissionManager->userHasRight( $user, 'suppressrevision' ); $pageIsSuppressed = $list->areAnySuppressed(); $this->mIsAllowed = $this->mIsAllowed && !( $canViewSuppressedOnly && $pageIsSuppressed ); @@ -202,7 +214,7 @@ class SpecialRevisionDelete extends UnlistedSpecialPage { [ 'revdelete-hide-comment', 'wpHideComment', RevisionRecord::DELETED_COMMENT ], [ 'revdelete-hide-user', 'wpHideUser', RevisionRecord::DELETED_USER ] ]; - if ( $user->isAllowed( 'suppressrevision' ) ) { + if ( $permissionManager->userHasRight( $user, 'suppressrevision' ) ) { $this->checks[] = [ 'revdelete-hide-restricted', 'wpHideRestricted', RevisionRecord::DELETED_RESTRICTED ]; } @@ -214,7 +226,7 @@ class SpecialRevisionDelete extends UnlistedSpecialPage { $this->showForm(); } - if ( $user->isAllowed( 'deletedhistory' ) ) { + if ( $permissionManager->userHasRight( $user, 'deletedhistory' ) ) { $qc = $this->getLogQueryCond(); # Show relevant lines from the deletion log $deleteLogPage = new LogPage( 'delete' ); @@ -228,7 +240,7 @@ class SpecialRevisionDelete extends UnlistedSpecialPage { ); } # Show relevant lines from the suppression log - if ( $user->isAllowed( 'suppressionlog' ) ) { + if ( $permissionManager->userHasRight( $user, 'suppressionlog' ) ) { $suppressLogPage = new LogPage( 'suppress' ); $output->addHTML( "

" . $suppressLogPage->getName()->escaped() . "

\n" ); LogEventsList::showLogExtract( @@ -267,7 +279,10 @@ class SpecialRevisionDelete extends UnlistedSpecialPage { [ 'action' => 'history' ] ); # Link to deleted edits - if ( $this->getUser()->isAllowed( 'undelete' ) ) { + if ( MediaWikiServices::getInstance() + ->getPermissionManager() + ->userHasRight( $this->getUser(), 'undelete' ) + ) { $undelete = SpecialPage::getTitleFor( 'Undelete' ); $links[] = $linkRenderer->makeKnownLink( $undelete, @@ -471,7 +486,10 @@ class SpecialRevisionDelete extends UnlistedSpecialPage { Xml::closeElement( 'fieldset' ) . "\n" . Xml::closeElement( 'form' ) . "\n"; // Show link to edit the dropdown reasons - if ( $this->getUser()->isAllowed( 'editinterface' ) ) { + if ( MediaWikiServices::getInstance() + ->getPermissionManager() + ->userHasRight( $this->getUser(), 'editinterface' ) + ) { $link = $this->getLinkRenderer()->makeKnownLink( $this->msg( 'revdelete-reason-dropdown' )->inContentLanguage()->getTitle(), $this->msg( 'revdelete-edit-reasonlist' )->text(), @@ -497,7 +515,10 @@ class SpecialRevisionDelete extends UnlistedSpecialPage { 'revdelete-text-others' ); - if ( $this->getUser()->isAllowed( 'suppressrevision' ) ) { + if ( MediaWikiServices::getInstance() + ->getPermissionManager() + ->userHasRight( $this->getUser(), 'suppressrevision' ) + ) { $this->getOutput()->addWikiMsg( 'revdelete-suppress-text' ); } @@ -602,7 +623,9 @@ class SpecialRevisionDelete extends UnlistedSpecialPage { } # Can the user set this field? if ( $bitParams[RevisionRecord::DELETED_RESTRICTED] == 1 - && !$this->getUser()->isAllowed( 'suppressrevision' ) + && !MediaWikiServices::getInstance() + ->getPermissionManager() + ->userHasRight( $this->getUser(), 'suppressrevision' ) ) { throw new PermissionsError( 'suppressrevision' ); } diff --git a/includes/specials/SpecialRunJobs.php b/includes/specials/SpecialRunJobs.php index 375694be08..530c5802cf 100644 --- a/includes/specials/SpecialRunJobs.php +++ b/includes/specials/SpecialRunJobs.php @@ -52,7 +52,8 @@ class SpecialRunJobs extends UnlistedSpecialPage { } // Validate request parameters - $optional = [ 'maxjobs' => 0, 'maxtime' => 30, 'type' => false, 'async' => true ]; + $optional = [ 'maxjobs' => 0, 'maxtime' => 30, 'type' => false, + 'async' => true, 'stats' => false ]; $required = array_flip( [ 'title', 'tasks', 'signature', 'sigexpiry' ] ); $params = array_intersect_key( $this->getRequest()->getValues(), $required + $optional ); $missing = array_diff_key( $required, $params ); @@ -95,14 +96,20 @@ class SpecialRunJobs extends UnlistedSpecialPage { DeferredUpdates::POSTSEND ); } else { - $this->doRun( $params ); - print "Done\n"; + $stats = $this->doRun( $params ); + + if ( $params['stats'] ) { + $this->getRequest()->response()->header( 'Content-Type: application/json' ); + print FormatJson::encode( $stats ); + } else { + print "Done\n"; + } } } protected function doRun( array $params ) { $runner = new JobRunner( LoggerFactory::getInstance( 'runJobs' ) ); - $runner->run( [ + return $runner->run( [ 'type' => $params['type'], 'maxJobs' => $params['maxjobs'] ?: 1, 'maxTime' => $params['maxtime'] ?: 30 diff --git a/includes/specials/SpecialTags.php b/includes/specials/SpecialTags.php index 9a95249c75..2c8d43297d 100644 --- a/includes/specials/SpecialTags.php +++ b/includes/specials/SpecialTags.php @@ -21,6 +21,8 @@ * @ingroup SpecialPage */ +use MediaWiki\MediaWikiServices; + /** * A special page that lists tags for edits * @@ -77,9 +79,10 @@ class SpecialTags extends SpecialPage { $out->wrapWikiMsg( "
\n$1\n
", 'tags-intro' ); $user = $this->getUser(); - $userCanManage = $user->isAllowed( 'managechangetags' ); - $userCanDelete = $user->isAllowed( 'deletechangetags' ); - $userCanEditInterface = $user->isAllowed( 'editinterface' ); + $permissionManager = MediaWikiServices::getInstance()->getPermissionManager(); + $userCanManage = $permissionManager->userHasRight( $user, 'managechangetags' ); + $userCanDelete = $permissionManager->userHasRight( $user, 'deletechangetags' ); + $userCanEditInterface = $permissionManager->userHasRight( $user, 'editinterface' ); // Show form to create a tag if ( $userCanManage ) { @@ -329,7 +332,9 @@ class SpecialTags extends SpecialPage { protected function showDeleteTagForm( $tag ) { $user = $this->getUser(); - if ( !$user->isAllowed( 'deletechangetags' ) ) { + if ( !MediaWikiServices::getInstance() + ->getPermissionManager() + ->userHasRight( $user, 'deletechangetags' ) ) { throw new PermissionsError( 'deletechangetags' ); } @@ -388,7 +393,9 @@ class SpecialTags extends SpecialPage { $actionStr = $activate ? 'activate' : 'deactivate'; $user = $this->getUser(); - if ( !$user->isAllowed( 'managechangetags' ) ) { + if ( !MediaWikiServices::getInstance() + ->getPermissionManager() + ->userHasRight( $user, 'managechangetags' ) ) { throw new PermissionsError( 'managechangetags' ); } diff --git a/includes/specials/SpecialUnblock.php b/includes/specials/SpecialUnblock.php index 9b8022b7c2..931b179a36 100644 --- a/includes/specials/SpecialUnblock.php +++ b/includes/specials/SpecialUnblock.php @@ -22,6 +22,7 @@ */ use MediaWiki\Block\DatabaseBlock; +use MediaWiki\MediaWikiServices; /** * A special page for unblocking users @@ -208,7 +209,10 @@ class SpecialUnblock extends SpecialPage { # If the name was hidden and the blocking user cannot hide # names, then don't allow any block removals... - if ( !$performer->isAllowed( 'hideuser' ) && $block->getHideName() ) { + if ( !MediaWikiServices::getInstance() + ->getPermissionManager() + ->userHasRight( $performer, 'hideuser' ) && $block->getHideName() + ) { return [ 'unblock-hideuser' ]; } diff --git a/includes/specials/SpecialUndelete.php b/includes/specials/SpecialUndelete.php index 075b5df0c2..d3d3bd7b06 100644 --- a/includes/specials/SpecialUndelete.php +++ b/includes/specials/SpecialUndelete.php @@ -33,18 +33,28 @@ use Wikimedia\Rdbms\IResultWrapper; * @ingroup SpecialPage */ class SpecialUndelete extends SpecialPage { - private $mAction; - private $mTarget; - private $mTimestamp; - private $mRestore; - private $mRevdel; - private $mInvert; - private $mFilename; - private $mTargetTimestamp; - private $mAllowed; - private $mCanView; - private $mComment; - private $mToken; + private $mAction; + private $mTarget; + private $mTimestamp; + private $mRestore; + private $mRevdel; + private $mInvert; + private $mFilename; + private $mTargetTimestamp; + private $mAllowed; + private $mCanView; + private $mComment; + private $mToken; + /** @var bool|null */ + private $mPreview; + /** @var bool|null */ + private $mDiff; + /** @var bool|null */ + private $mDiffOnly; + /** @var bool|null */ + private $mUnsuppress; + /** @var int[]|null */ + private $mFileVersions; /** @var Title */ private $mTargetObj; @@ -92,7 +102,9 @@ class SpecialUndelete extends SpecialPage { $this->mDiff = $request->getCheck( 'diff' ); $this->mDiffOnly = $request->getBool( 'diffonly', $this->getUser()->getOption( 'diffonly' ) ); $this->mComment = $request->getText( 'wpComment' ); - $this->mUnsuppress = $request->getVal( 'wpUnsuppress' ) && $user->isAllowed( 'suppressrevision' ); + $this->mUnsuppress = $request->getVal( 'wpUnsuppress' ) && MediaWikiServices::getInstance() + ->getPermissionManager() + ->userHasRight( $user, 'suppressrevision' ); $this->mToken = $request->getVal( 'token' ); $block = $user->getBlock(); @@ -143,7 +155,7 @@ class SpecialUndelete extends SpecialPage { if ( $this->mTargetObj !== null ) { return $permissionManager->userCan( $permission, $user, $this->mTargetObj ); } else { - return $user->isAllowed( $permission ); + return $permissionManager->userHasRight( $user, $permission ); } } @@ -169,7 +181,10 @@ class SpecialUndelete extends SpecialPage { $out->addWikiMsg( 'undelete-header' ); # Not all users can just browse every deleted page from the list - if ( $user->isAllowed( 'browsearchive' ) ) { + if ( MediaWikiServices::getInstance() + ->getPermissionManager() + ->userHasRight( $user, 'browsearchive' ) + ) { $this->showSearchForm(); } @@ -764,7 +779,8 @@ class SpecialUndelete extends SpecialPage { LogEventsList::showLogExtract( $out, 'delete', $this->mTargetObj ); # Show relevant lines from the suppression log: $suppressLogPage = new LogPage( 'suppress' ); - if ( $this->getUser()->isAllowed( 'suppressionlog' ) ) { + $permissionManager = MediaWikiServices::getInstance()->getPermissionManager(); + if ( $permissionManager->userHasRight( $this->getUser(), 'suppressionlog' ) ) { $out->addHTML( Xml::element( 'h2', null, $suppressLogPage->getName()->text() ) . "\n" ); LogEventsList::showLogExtract( $out, 'suppress', $this->mTargetObj ); } @@ -816,7 +832,7 @@ class SpecialUndelete extends SpecialPage { ] ) ); - if ( $this->getUser()->isAllowed( 'suppressrevision' ) ) { + if ( $permissionManager->userHasRight( $this->getUser(), 'suppressrevision' ) ) { $fields[] = new OOUI\FieldLayout( new OOUI\CheckboxInputWidget( [ 'name' => 'wpUnsuppress', @@ -856,7 +872,7 @@ class SpecialUndelete extends SpecialPage { if ( $haveRevisions ) { # Show the page's stored (deleted) history - if ( $this->getUser()->isAllowed( 'deleterevision' ) ) { + if ( $permissionManager->userHasRight( $this->getUser(), 'deleterevision' ) ) { $history .= Html::element( 'button', [ diff --git a/includes/specials/SpecialUpload.php b/includes/specials/SpecialUpload.php index 81c9d567f1..e7c2e42a77 100644 --- a/includes/specials/SpecialUpload.php +++ b/includes/specials/SpecialUpload.php @@ -311,16 +311,18 @@ class SpecialUpload extends SpecialPage { protected function showViewDeletedLinks() { $title = Title::makeTitleSafe( NS_FILE, $this->mDesiredDestName ); $user = $this->getUser(); + $permissionManager = MediaWikiServices::getInstance()->getPermissionManager(); // Show a subtitle link to deleted revisions (to sysops et al only) if ( $title instanceof Title ) { $count = $title->isDeleted(); - if ( $count > 0 && $user->isAllowed( 'deletedhistory' ) ) { + if ( $count > 0 && $permissionManager->userHasRight( $user, 'deletedhistory' ) ) { $restorelink = $this->getLinkRenderer()->makeKnownLink( SpecialPage::getTitleFor( 'Undelete', $title->getPrefixedText() ), $this->msg( 'restorelink' )->numParams( $count )->text() ); - $link = $this->msg( $user->isAllowed( 'delete' ) ? 'thisisdeleted' : 'viewdeleted' ) - ->rawParams( $restorelink )->parseAsBlock(); + $link = $this->msg( + $permissionManager->userHasRight( $user, 'delete' ) ? 'thisisdeleted' : 'viewdeleted' + )->rawParams( $restorelink )->parseAsBlock(); $this->getOutput()->addHTML( Html::rawElement( 'div', diff --git a/includes/specials/SpecialUserrights.php b/includes/specials/SpecialUserrights.php index 5747f67b83..585699ddd0 100644 --- a/includes/specials/SpecialUserrights.php +++ b/includes/specials/SpecialUserrights.php @@ -21,6 +21,8 @@ * @ingroup SpecialPage */ +use MediaWiki\MediaWikiServices; + /** * Special page to allow managing user group membership * @@ -161,7 +163,10 @@ class UserrightsPage extends SpecialPage { * (e.g. they don't have the userrights permission), then don't * allow them to change any user rights. */ - if ( !$user->isAllowed( 'userrights' ) ) { + if ( !MediaWikiServices::getInstance() + ->getPermissionManager() + ->userHasRight( $user, 'userrights' ) + ) { $block = $user->getBlock(); if ( $block && $block->isSitewide() ) { throw new UserBlockedError( $block ); @@ -515,7 +520,10 @@ class UserrightsPage extends SpecialPage { if ( WikiMap::isCurrentWikiId( $dbDomain ) ) { $dbDomain = ''; } else { - if ( $writing && !$this->getUser()->isAllowed( 'userrights-interwiki' ) ) { + if ( $writing && !MediaWikiServices::getInstance() + ->getPermissionManager() + ->userHasRight( $this->getUser(), 'userrights-interwiki' ) + ) { return Status::newFatal( 'userrights-no-interwiki' ); } if ( !UserRightsProxy::validDatabase( $dbDomain ) ) { diff --git a/includes/specials/SpecialWatchlist.php b/includes/specials/SpecialWatchlist.php index 3d563309de..84b3331d5c 100644 --- a/includes/specials/SpecialWatchlist.php +++ b/includes/specials/SpecialWatchlist.php @@ -381,12 +381,10 @@ class SpecialWatchlist extends ChangesListSpecialPage { // Log entries with DELETED_ACTION must not show up unless the user has // the necessary rights. - if ( !$user->isAllowed( 'deletedhistory' ) ) { + $permissionManager = MediaWikiServices::getInstance()->getPermissionManager(); + if ( !$permissionManager->userHasRight( $user, 'deletedhistory' ) ) { $bitmask = LogPage::DELETED_ACTION; - } elseif ( !MediaWikiServices::getInstance() - ->getPermissionManager() - ->userHasAnyRight( $user, 'suppressrevision', 'viewsuppressed' ) - ) { + } elseif ( !$permissionManager->userHasAnyRight( $user, 'suppressrevision', 'viewsuppressed' ) ) { $bitmask = LogPage::DELETED_ACTION | LogPage::DELETED_RESTRICTED; } else { $bitmask = 0; diff --git a/includes/specials/SpecialWhatLinksHere.php b/includes/specials/SpecialWhatLinksHere.php index 2840086526..5fe3605a93 100644 --- a/includes/specials/SpecialWhatLinksHere.php +++ b/includes/specials/SpecialWhatLinksHere.php @@ -21,6 +21,7 @@ * @todo Use some variant of Pager or something; the pagination here is lousy. */ +use MediaWiki\MediaWikiServices; use Wikimedia\Rdbms\IDatabase; /** @@ -416,7 +417,9 @@ class SpecialWhatLinksHere extends IncludableSpecialPage { // if the page is editable, add an edit link if ( // check user permissions - $this->getUser()->isAllowed( 'edit' ) && + MediaWikiServices::getInstance() + ->getPermissionManager() + ->userHasRight( $this->getUser(), 'edit' ) && // check, if the content model is editable through action=edit ContentHandler::getForTitle( $target )->supportsDirectEditing() ) { diff --git a/includes/specials/forms/PreferencesFormOOUI.php b/includes/specials/forms/PreferencesFormOOUI.php index ea23973de4..b1bfd0bb32 100644 --- a/includes/specials/forms/PreferencesFormOOUI.php +++ b/includes/specials/forms/PreferencesFormOOUI.php @@ -73,16 +73,18 @@ class PreferencesFormOOUI extends OOUIHTMLForm { * @return string */ function getButtons() { - if ( !MediaWikiServices::getInstance() - ->getPermissionManager() - ->userHasAnyRight( $this->getModifiedUser(), 'editmyprivateinfo', 'editmyoptions' ) - ) { + $permissionManager = MediaWikiServices::getInstance()->getPermissionManager(); + if ( !$permissionManager->userHasAnyRight( + $this->getModifiedUser(), + 'editmyprivateinfo', + 'editmyoptions' + ) ) { return ''; } $html = parent::getButtons(); - if ( $this->getModifiedUser()->isAllowed( 'editmyoptions' ) ) { + if ( $permissionManager->userHasRight( $this->getModifiedUser(), 'editmyoptions' ) ) { $t = $this->getTitle()->getSubpage( 'reset' ); $html .= new OOUI\ButtonWidget( [ diff --git a/includes/specials/forms/UploadForm.php b/includes/specials/forms/UploadForm.php index 1e5f8168d6..0b4e0589c0 100644 --- a/includes/specials/forms/UploadForm.php +++ b/includes/specials/forms/UploadForm.php @@ -76,7 +76,10 @@ class UploadForm extends HTMLForm { parent::__construct( $descriptor, $context, 'upload' ); # Add a link to edit MediaWiki:Licenses - if ( $this->getUser()->isAllowed( 'editinterface' ) ) { + if ( MediaWikiServices::getInstance() + ->getPermissionManager() + ->userHasRight( $this->getUser(), 'editinterface' ) + ) { $this->getOutput()->addModuleStyles( 'mediawiki.special' ); $licensesLink = $linkRenderer->makeKnownLink( $this->msg( 'licenses' )->inContentLanguage()->getTitle(), diff --git a/includes/specials/pagers/ActiveUsersPager.php b/includes/specials/pagers/ActiveUsersPager.php index 0f5355d383..c9c3b07f81 100644 --- a/includes/specials/pagers/ActiveUsersPager.php +++ b/includes/specials/pagers/ActiveUsersPager.php @@ -19,6 +19,8 @@ * @ingroup Pager */ +use MediaWiki\MediaWikiServices; + /** * This class is used to get a list of active users. The ones with specials * rights (sysop, bureaucrat, developer) will have them displayed @@ -43,6 +45,12 @@ class ActiveUsersPager extends UsersPager { */ private $blockStatusByUid; + /** @var int */ + private $RCMaxAge; + + /** @var string[] */ + private $excludegroups; + /** * @param IContextSource|null $context * @param FormOptions $opts @@ -118,7 +126,10 @@ class ActiveUsersPager extends UsersPager { ] ]; $conds['ug2.ug_user'] = null; } - if ( !$this->getUser()->isAllowed( 'hideuser' ) ) { + if ( !MediaWikiServices::getInstance() + ->getPermissionManager() + ->userHasRight( $this->getUser(), 'hideuser' ) + ) { $conds[] = 'NOT EXISTS (' . $dbr->selectSQLText( 'ipblocks', '1', [ 'ipb_user=user_id', 'ipb_deleted' => 1 ] ) . ')'; diff --git a/includes/specials/pagers/AllMessagesTablePager.php b/includes/specials/pagers/AllMessagesTablePager.php index c804b091a3..6b8b93b90a 100644 --- a/includes/specials/pagers/AllMessagesTablePager.php +++ b/includes/specials/pagers/AllMessagesTablePager.php @@ -46,6 +46,11 @@ class AllMessagesTablePager extends TablePager { */ protected $prefix; + /** + * @var string + */ + protected $suffix; + /** * @var Language */ diff --git a/includes/specials/pagers/BlockListPager.php b/includes/specials/pagers/BlockListPager.php index 4441a33314..718da6da0f 100644 --- a/includes/specials/pagers/BlockListPager.php +++ b/includes/specials/pagers/BlockListPager.php @@ -137,7 +137,10 @@ class BlockListPager extends TablePager { $value, /* User preference timezone */true ) ); - if ( $this->getUser()->isAllowed( 'block' ) ) { + if ( MediaWikiServices::getInstance() + ->getPermissionManager() + ->userHasRight( $this->getUser(), 'block' ) + ) { $links = []; if ( $row->ipb_auto ) { $links[] = $linkRenderer->makeKnownLink( @@ -358,7 +361,10 @@ class BlockListPager extends TablePager { $info['conds'][] = 'ipb_expiry > ' . $db->addQuotes( $db->timestamp() ); # Is the user allowed to see hidden blocks? - if ( !$this->getUser()->isAllowed( 'hideuser' ) ) { + if ( !MediaWikiServices::getInstance() + ->getPermissionManager() + ->userHasRight( $this->getUser(), 'hideuser' ) + ) { $info['conds']['ipb_deleted'] = 0; } diff --git a/includes/specials/pagers/ContribsPager.php b/includes/specials/pagers/ContribsPager.php index d76dfb8825..3a56a87ede 100644 --- a/includes/specials/pagers/ContribsPager.php +++ b/includes/specials/pagers/ContribsPager.php @@ -269,6 +269,7 @@ class ContribsPager extends RangeChronologicalPager { 'options' => [], 'join_conds' => $revQuery['joins'], ]; + $permissionManager = MediaWikiServices::getInstance()->getPermissionManager(); // WARNING: Keep this in sync with getTargetTable()! $user = User::newFromName( $this->target, false ); @@ -313,14 +314,11 @@ class ContribsPager extends RangeChronologicalPager { $queryInfo['conds'] = array_merge( $queryInfo['conds'], $this->getNamespaceCond() ); // Paranoia: avoid brute force searches (T19342) - if ( !$user->isAllowed( 'deletedhistory' ) ) { + if ( !$permissionManager->userHasRight( $user, 'deletedhistory' ) ) { $queryInfo['conds'][] = $this->mDb->bitAnd( 'rev_deleted', RevisionRecord::DELETED_USER ) . ' = 0'; - } elseif ( !MediaWikiServices::getInstance() - ->getPermissionManager() - ->userHasAnyRight( $user, 'suppressrevision', 'viewsuppressed' ) - ) { + } elseif ( !$permissionManager->userHasAnyRight( $user, 'suppressrevision', 'viewsuppressed' ) ) { $queryInfo['conds'][] = $this->mDb->bitAnd( 'rev_deleted', RevisionRecord::SUPPRESSED_USER ) . ' != ' . RevisionRecord::SUPPRESSED_USER; diff --git a/includes/specials/pagers/DeletedContribsPager.php b/includes/specials/pagers/DeletedContribsPager.php index cd6294d67f..2893759eae 100644 --- a/includes/specials/pagers/DeletedContribsPager.php +++ b/includes/specials/pagers/DeletedContribsPager.php @@ -90,13 +90,11 @@ class DeletedContribsPager extends IndexPager { ]; $conds = array_merge( $userCond, $this->getNamespaceCond() ); $user = $this->getUser(); + $permissionManager = MediaWikiServices::getInstance()->getPermissionManager(); // Paranoia: avoid brute force searches (T19792) - if ( !$user->isAllowed( 'deletedhistory' ) ) { + if ( !$permissionManager->userHasRight( $user, 'deletedhistory' ) ) { $conds[] = $this->mDb->bitAnd( 'ar_deleted', RevisionRecord::DELETED_USER ) . ' = 0'; - } elseif ( !MediaWikiServices::getInstance() - ->getPermissionManager() - ->userHasAnyRight( $user, 'suppressrevision', 'viewsuppressed' ) - ) { + } elseif ( !$permissionManager->userHasAnyRight( $user, 'suppressrevision', 'viewsuppressed' ) ) { $conds[] = $this->mDb->bitAnd( 'ar_deleted', RevisionRecord::SUPPRESSED_USER ) . ' != ' . RevisionRecord::SUPPRESSED_USER; } @@ -325,8 +323,9 @@ class DeletedContribsPager extends IndexPager { ); $user = $this->getUser(); + $permissionManager = MediaWikiServices::getInstance()->getPermissionManager(); - if ( $user->isAllowed( 'deletedtext' ) ) { + if ( $permissionManager->userHasRight( $user, 'deletedtext' ) ) { $last = $linkRenderer->makeKnownLink( $undelete, $this->messages['diff'], @@ -344,7 +343,9 @@ class DeletedContribsPager extends IndexPager { $comment = Linker::revComment( $rev ); $date = $this->getLanguage()->userTimeAndDate( $rev->getTimestamp(), $user ); - if ( !$user->isAllowed( 'undelete' ) || !$rev->userCan( RevisionRecord::DELETED_TEXT, $user ) ) { + if ( !$permissionManager->userHasRight( $user, 'undelete' ) || + !$rev->userCan( RevisionRecord::DELETED_TEXT, $user ) + ) { $link = htmlspecialchars( $date ); // unusable link } else { $link = $linkRenderer->makeKnownLink( diff --git a/includes/specials/pagers/MergeHistoryPager.php b/includes/specials/pagers/MergeHistoryPager.php index 9415cea12b..81c3ffb74c 100644 --- a/includes/specials/pagers/MergeHistoryPager.php +++ b/includes/specials/pagers/MergeHistoryPager.php @@ -30,10 +30,15 @@ class MergeHistoryPager extends ReverseChronologicalPager { /** @var array */ public $mConds; + /** @var int */ + private $articleID; + + /** @var int */ + private $maxTimestamp; + public function __construct( SpecialMergeHistory $form, $conds, Title $source, Title $dest ) { $this->mForm = $form; $this->mConds = $conds; - $this->title = $source; $this->articleID = $source->getArticleID(); $dbr = wfGetDB( DB_REPLICA ); diff --git a/includes/specials/pagers/ProtectedPagesPager.php b/includes/specials/pagers/ProtectedPagesPager.php index 747dea284a..bb5592ce95 100644 --- a/includes/specials/pagers/ProtectedPagesPager.php +++ b/includes/specials/pagers/ProtectedPagesPager.php @@ -20,6 +20,7 @@ */ use MediaWiki\Linker\LinkRenderer; +use MediaWiki\MediaWikiServices; class ProtectedPagesPager extends TablePager { @@ -159,7 +160,10 @@ class ProtectedPagesPager extends TablePager { $formatted = htmlspecialchars( $this->getLanguage()->formatExpiry( $value, /* User preference timezone */true ) ); $title = Title::makeTitleSafe( $row->page_namespace, $row->page_title ); - if ( $this->getUser()->isAllowed( 'protect' ) && $title ) { + if ( $title && MediaWikiServices::getInstance() + ->getPermissionManager() + ->userHasRight( $this->getUser(), 'protect' ) + ) { $changeProtection = $linkRenderer->makeKnownLink( $title, $this->msg( 'protect_change' )->text(), diff --git a/includes/specials/pagers/ProtectedTitlesPager.php b/includes/specials/pagers/ProtectedTitlesPager.php index 296fe1112d..a00b37125c 100644 --- a/includes/specials/pagers/ProtectedTitlesPager.php +++ b/includes/specials/pagers/ProtectedTitlesPager.php @@ -34,6 +34,12 @@ class ProtectedTitlesPager extends AlphabeticPager { */ public $mConds; + /** @var string|null */ + private $level; + + /** @var int|null */ + private $namespace; + /** * @param SpecialProtectedtitles $form * @param array $conds @@ -50,7 +56,6 @@ class ProtectedTitlesPager extends AlphabeticPager { $this->mConds = $conds; $this->level = $level; $this->namespace = $namespace; - $this->size = intval( $size ); parent::__construct( $form->getContext() ); } @@ -90,7 +95,7 @@ class ProtectedTitlesPager extends AlphabeticPager { $conds['pt_create_perm'] = $this->level; } - if ( !is_null( $this->namespace ) ) { + if ( $this->namespace !== null ) { $conds[] = 'pt_namespace=' . $this->mDb->addQuotes( $this->namespace ); } diff --git a/includes/specials/pagers/UsersPager.php b/includes/specials/pagers/UsersPager.php index 57b575b8ec..ee0ac003ae 100644 --- a/includes/specials/pagers/UsersPager.php +++ b/includes/specials/pagers/UsersPager.php @@ -23,6 +23,8 @@ * @ingroup Pager */ +use MediaWiki\MediaWikiServices; + /** * This class is used to get a list of user. The ones with specials * rights (sysop, bureaucrat, developer) will have them displayed @@ -37,6 +39,24 @@ class UsersPager extends AlphabeticPager { */ protected $userGroupCache; + /** @var string */ + protected $requestedGroup; + + /** @var bool */ + protected $editsOnly; + + /** @var bool */ + protected $temporaryGroupsOnly; + + /** @var bool */ + protected $creationSort; + + /** @var bool|null */ + protected $including; + + /** @var string */ + protected $requestedUser; + /** * @param IContextSource|null $context * @param array|null $par (Default null) @@ -105,7 +125,10 @@ class UsersPager extends AlphabeticPager { $conds = []; // Don't show hidden names - if ( !$this->getUser()->isAllowed( 'hideuser' ) ) { + if ( !MediaWikiServices::getInstance() + ->getPermissionManager() + ->userHasRight( $this->getUser(), 'hideuser' ) + ) { $conds[] = 'ipb_deleted IS NULL OR ipb_deleted = 0'; } diff --git a/includes/upload/UploadBase.php b/includes/upload/UploadBase.php index 3368e29aed..d7dfffa39f 100644 --- a/includes/upload/UploadBase.php +++ b/includes/upload/UploadBase.php @@ -20,7 +20,10 @@ * @file * @ingroup Upload */ + +use MediaWiki\MediaWikiServices; use MediaWiki\Shell\Shell; +use MediaWiki\User\UserIdentity; /** * @defgroup Upload Upload related @@ -145,12 +148,13 @@ abstract class UploadBase { * identifying the missing permission. * Can be overridden by subclasses. * - * @param User $user + * @param UserIdentity $user * @return bool|string */ - public static function isAllowed( $user ) { + public static function isAllowed( UserIdentity $user ) { + $permissionManager = MediaWikiServices::getInstance()->getPermissionManager(); foreach ( [ 'upload', 'edit' ] as $permission ) { - if ( !$user->isAllowed( $permission ) ) { + if ( !$permissionManager->userHasRight( $user, $permission ) ) { return $permission; } } @@ -1954,7 +1958,10 @@ abstract class UploadBase { * wfFindFile finds a file, it exists in a shared repository. */ $file = wfFindFile( $this->getTitle(), [ 'latest' => true ] ); - if ( $file && !$user->isAllowed( 'reupload-shared' ) ) { + if ( $file && !MediaWikiServices::getInstance() + ->getPermissionManager() + ->userHasRight( $user, 'reupload-shared' ) + ) { return [ 'fileexists-shared-forbidden', $file->getName() ]; } @@ -1969,9 +1976,10 @@ abstract class UploadBase { * @return bool */ public static function userCanReUpload( User $user, File $img ) { - if ( $user->isAllowed( 'reupload' ) ) { + $permissionManager = MediaWikiServices::getInstance()->getPermissionManager(); + if ( $permissionManager->userHasRight( $user, 'reupload' ) ) { return true; // non-conditional - } elseif ( !$user->isAllowed( 'reupload-own' ) ) { + } elseif ( !$permissionManager->userHasRight( $user, 'reupload-own' ) ) { return false; } diff --git a/includes/upload/UploadFromUrl.php b/includes/upload/UploadFromUrl.php index b92fcc5aa9..b87810d540 100644 --- a/includes/upload/UploadFromUrl.php +++ b/includes/upload/UploadFromUrl.php @@ -1,7 +1,4 @@ isAllowed( 'upload_by_url' ) ) { + public static function isAllowed( UserIdentity $user ) { + if ( !MediaWikiServices::getInstance() + ->getPermissionManager() + ->userHasRight( $user, 'upload_by_url' ) + ) { return 'upload_by_url'; } @@ -167,7 +170,9 @@ class UploadFromUrl extends UploadBase { $url = $request->getVal( 'wpUploadFileURL' ); return !empty( $url ) - && $wgUser->isAllowed( 'upload_by_url' ); + && MediaWikiServices::getInstance() + ->getPermissionManager() + ->userHasRight( $wgUser, 'upload_by_url' ); } /** diff --git a/includes/user/LocalIdLookup.php b/includes/user/LocalIdLookup.php index ca3db5b07d..4c9099e8b6 100644 --- a/includes/user/LocalIdLookup.php +++ b/includes/user/LocalIdLookup.php @@ -20,6 +20,8 @@ * @file */ +use MediaWiki\MediaWikiServices; + /** * A CentralIdLookup provider that just uses local IDs. Useful if the wiki * isn't part of a cluster or you're using shared user tables. @@ -69,7 +71,10 @@ class LocalIdLookup extends CentralIdLookup { 'user_id' => array_map( 'intval', array_keys( $idToName ) ), ]; $join = []; - if ( $audience && !$audience->isAllowed( 'hideuser' ) ) { + if ( $audience && !MediaWikiServices::getInstance() + ->getPermissionManager() + ->userHasRight( $audience, 'hideuser' ) + ) { $tables[] = 'ipblocks'; $join['ipblocks'] = [ 'LEFT JOIN', 'ipb_user=user_id' ]; $fields[] = 'ipb_deleted'; @@ -100,7 +105,10 @@ class LocalIdLookup extends CentralIdLookup { 'user_name' => array_map( 'strval', array_keys( $nameToId ) ), ]; $join = []; - if ( $audience && !$audience->isAllowed( 'hideuser' ) ) { + if ( $audience && !MediaWikiServices::getInstance() + ->getPermissionManager() + ->userHasRight( $audience, 'hideuser' ) + ) { $tables[] = 'ipblocks'; $join['ipblocks'] = [ 'LEFT JOIN', 'ipb_user=user_id' ]; $where[] = 'ipb_deleted = 0 OR ipb_deleted IS NULL'; diff --git a/includes/user/PasswordReset.php b/includes/user/PasswordReset.php index fd8eb3fac1..38707dec5b 100644 --- a/includes/user/PasswordReset.php +++ b/includes/user/PasswordReset.php @@ -22,6 +22,7 @@ use MediaWiki\Auth\AuthManager; use MediaWiki\Auth\TemporaryPasswordAuthenticationRequest; +use MediaWiki\Permissions\PermissionManager; use Psr\Log\LoggerAwareInterface; use Psr\Log\LoggerInterface; use MediaWiki\Logger\LoggerFactory; @@ -40,6 +41,9 @@ class PasswordReset implements LoggerAwareInterface { /** @var AuthManager */ protected $authManager; + /** @var PermissionManager */ + private $permissionManager; + /** @var LoggerInterface */ protected $logger; @@ -50,9 +54,14 @@ class PasswordReset implements LoggerAwareInterface { */ private $permissionCache; - public function __construct( Config $config, AuthManager $authManager ) { + public function __construct( + Config $config, + AuthManager $authManager, + PermissionManager $permissionManager + ) { $this->config = $config; $this->authManager = $authManager; + $this->permissionManager = $permissionManager; $this->permissionCache = new MapCacheLRU( 1 ); $this->logger = LoggerFactory::getInstance( 'authentication' ); } @@ -93,7 +102,7 @@ class PasswordReset implements LoggerAwareInterface { } elseif ( !$this->config->get( 'EnableEmail' ) ) { // Maybe email features have been disabled $status = StatusValue::newFatal( 'passwordreset-emaildisabled' ); - } elseif ( !$user->isAllowed( 'editmyprivateinfo' ) ) { + } elseif ( !$this->permissionManager->userHasRight( $user, 'editmyprivateinfo' ) ) { // Maybe not all users have permission to change private data $status = StatusValue::newFatal( 'badaccess' ); } elseif ( $this->isBlocked( $user ) ) { diff --git a/includes/user/User.php b/includes/user/User.php index 3e84b0b430..d71750bcfd 100644 --- a/includes/user/User.php +++ b/includes/user/User.php @@ -1718,9 +1718,31 @@ class User implements IDBAccessObject, UserIdentity { // overwriting mBlockedby, surely? $this->load(); + // TODO: Block checking shouldn't really be done from the User object. Block + // checking can involve checking for IP blocks, cookie blocks, and/or XFF blocks, + // which need more knowledge of the request context than the User should have. + // Since we do currently check blocks from the User, we have to do the following + // here: + // - Check if this is the user associated with the main request + // - If so, pass the relevant request information to the block manager + $request = null; + + // The session user is set up towards the end of Setup.php. Until then, + // assume it's a logged-out user. + $sessionUser = RequestContext::getMain()->getUser(); + $globalUserName = $sessionUser->isSafeToLoad() + ? $sessionUser->getName() + : IP::sanitizeIP( $sessionUser->getRequest()->getIP() ); + + if ( $this->getName() === $globalUserName ) { + // This is the global user, so we need to pass the request + $request = $this->getRequest(); + } + // @phan-suppress-next-line PhanAccessMethodInternal It's the only allowed use $block = MediaWikiServices::getInstance()->getBlockManager()->getUserBlock( $this, + $request, $fromReplica ); @@ -1741,7 +1763,7 @@ class User implements IDBAccessObject, UserIdentity { // Avoid PHP 7.1 warning of passing $this by reference $thisUser = $this; // Extensions - Hooks::run( 'GetBlockedStatus', [ &$thisUser ] ); + Hooks::run( 'GetBlockedStatus', [ &$thisUser ], '1.34' ); } /** diff --git a/includes/user/UserNamePrefixSearch.php b/includes/user/UserNamePrefixSearch.php index c185babcfb..b3489a2256 100644 --- a/includes/user/UserNamePrefixSearch.php +++ b/includes/user/UserNamePrefixSearch.php @@ -20,6 +20,8 @@ * @file */ +use MediaWiki\MediaWikiServices; + /** * Handles searching prefixes of user names * @@ -46,7 +48,10 @@ class UserNamePrefixSearch { $joinConds = []; // Filter out hidden user names - if ( $audience === 'public' || !$audience->isAllowed( 'hideuser' ) ) { + if ( $audience === 'public' || !MediaWikiServices::getInstance() + ->getPermissionManager() + ->userHasRight( $audience, 'hideuser' ) + ) { $tables[] = 'ipblocks'; $cond['ipb_deleted'] = [ 0, null ]; $joinConds['ipblocks'] = [ 'LEFT JOIN', 'user_id=ipb_user' ]; diff --git a/includes/widget/CheckMatrixWidget.php b/includes/widget/CheckMatrixWidget.php index 06d8095ed4..3ae00ea6a9 100644 --- a/includes/widget/CheckMatrixWidget.php +++ b/includes/widget/CheckMatrixWidget.php @@ -9,14 +9,22 @@ namespace MediaWiki\Widget; * @license MIT */ class CheckMatrixWidget extends \OOUI\Widget { - - protected $name = ''; - protected $columns = []; - protected $rows = []; - protected $tooltips = []; - protected $values = []; - protected $forcedOn = []; - protected $forcedOff = []; + /** @var string|null */ + protected $name; + /** @var string|null */ + protected $id; + /** @var array */ + protected $columns; + /** @var array */ + protected $rows; + /** @var array */ + protected $tooltips; + /** @var array */ + protected $values; + /** @var array */ + protected $forcedOn; + /** @var array */ + protected $forcedOff; /** * Operates similarly to MultiSelectWidget, but instead of using an array of diff --git a/includes/widget/ComplexTitleInputWidget.php b/includes/widget/ComplexTitleInputWidget.php index 77370674f5..913816cc52 100644 --- a/includes/widget/ComplexTitleInputWidget.php +++ b/includes/widget/ComplexTitleInputWidget.php @@ -9,7 +9,8 @@ namespace MediaWiki\Widget; * @license MIT */ class ComplexTitleInputWidget extends \OOUI\Widget { - + /** @var array */ + protected $config; protected $namespace = null; protected $title = null; diff --git a/includes/widget/NamespaceInputWidget.php b/includes/widget/NamespaceInputWidget.php index 7802a2a017..a360fb8e91 100644 --- a/includes/widget/NamespaceInputWidget.php +++ b/includes/widget/NamespaceInputWidget.php @@ -9,8 +9,10 @@ namespace MediaWiki\Widget; * @license MIT */ class NamespaceInputWidget extends \OOUI\DropdownInputWidget { - - protected $includeAllValue = null; + /** @var string */ + protected $includeAllValue; + /** @var int[] */ + protected $exclude; /** * @param array $config Configuration options diff --git a/includes/widget/SelectWithInputWidget.php b/includes/widget/SelectWithInputWidget.php index a946653e6e..a792172b23 100644 --- a/includes/widget/SelectWithInputWidget.php +++ b/includes/widget/SelectWithInputWidget.php @@ -12,9 +12,12 @@ use OOUI\TextInputWidget; * @license MIT */ class SelectWithInputWidget extends \OOUI\Widget { - - protected $textinput = null; - protected $dropdowninput = null; + /** @var array */ + protected $config; + /** @var TextInputWidget */ + protected $textinput; + /** @var DropdownInputWidget */ + protected $dropdowninput; /** * A version of the SelectWithInputWidget, with `or` set to true. diff --git a/includes/widget/SizeFilterWidget.php b/includes/widget/SizeFilterWidget.php index 18c05bf6bc..26935b1214 100644 --- a/includes/widget/SizeFilterWidget.php +++ b/includes/widget/SizeFilterWidget.php @@ -13,9 +13,14 @@ use \OOUI\LabelWidget; * @license MIT */ class SizeFilterWidget extends \OOUI\Widget { - - protected $radioselectinput = null; - protected $textinput = null; + /** @var array */ + protected $config; + /** @var LabelWidget */ + protected $label; + /** @var RadioSelectInputWidget */ + protected $radioselectinput; + /** @var TextInputWidget */ + protected $textinput; /** * RadioSelectInputWidget and a TextInputWidget to set minimum or maximum byte size diff --git a/includes/widget/TagMultiselectWidget.php b/includes/widget/TagMultiselectWidget.php index 43e184cab2..e96160c715 100644 --- a/includes/widget/TagMultiselectWidget.php +++ b/includes/widget/TagMultiselectWidget.php @@ -12,41 +12,34 @@ use OOUI\MultilineTextInputWidget; * @license MIT */ abstract class TagMultiselectWidget extends \OOUI\Widget { - - protected $selectedArray = []; - protected $inputName = null; - protected $inputPlaceholder = null; - protected $tagLimit = null; + /** @var array */ + protected $selectedArray; + /** @var string|null */ + protected $inputName; + /** @var string|null */ + protected $inputPlaceholder; + /** @var array */ + protected $input; + /** @var int|null */ + protected $tagLimit; /** * @param array $config Configuration options * - array $config['default'] Array of items to use as preset data - * - array $config['name'] Name attribute (used in forms) - * - array $config['placeholder'] Placeholder message for input + * - string $config['name'] Name attribute (used in forms) + * - string $config['placeholder'] Placeholder message for input * - array $config['input'] Config options for the input widget - * - number $config['tagLimit'] Maximum number of selected items + * - int $config['tagLimit'] Maximum number of selected items */ public function __construct( array $config = [] ) { parent::__construct( $config ); // Properties - if ( isset( $config['default'] ) ) { - $this->selectedArray = $config['default']; - } - if ( isset( $config['name'] ) ) { - $this->inputName = $config['name']; - } - if ( isset( $config['placeholder'] ) ) { - $this->inputPlaceholder = $config['placeholder']; - } - if ( isset( $config['input'] ) ) { - $this->input = $config['input']; - } else { - $this->input = []; - } - if ( isset( $config['tagLimit'] ) ) { - $this->tagLimit = $config['tagLimit']; - } + $this->selectedArray = $config['default'] ?? []; + $this->inputName = $config['name'] ?? null; + $this->inputPlaceholder = $config['placeholder'] ?? null; + $this->input = $config['input'] ?? []; + $this->tagLimit = $config['tagLimit'] ?? null; $textarea = new MultilineTextInputWidget( array_merge( [ 'name' => $this->inputName, diff --git a/jsduck.json b/jsduck.json index 6ba7796162..e675889a53 100644 --- a/jsduck.json +++ b/jsduck.json @@ -12,7 +12,7 @@ "--exclude": [ "resources/src/jquery.tablesorter", "resources/src/jquery.tipsy", - "resources/src/jquery/jquery.color.js", + "resources/src/jquery.color/jquery.color.js", "resources/src/jquery/jquery.highlightText.js", "resources/src/jquery/jquery.mw-jump.js", "resources/src/mediawiki.base/legacy.wikibits.js", diff --git a/languages/i18n/ar.json b/languages/i18n/ar.json index fc8e5f78f6..7d93d5b087 100644 --- a/languages/i18n/ar.json +++ b/languages/i18n/ar.json @@ -126,6 +126,7 @@ "tog-useeditwarning": "حذّرني عندما أغادر تحرير صفحة فيها تغييرات لم أحفظها", "tog-prefershttps": "استخدم دائما اتصالا آمنا عند تسجيل الدخول", "tog-showrollbackconfirmation": "إظهار رسالة تأكيد عند النقر على رابط الاسترجاع", + "tog-requireemail": "تتطلب البريد الإلكتروني لإعادة تعيين كلمة المرور", "underline-always": "دائما", "underline-never": "أبدا", "underline-default": "وفق المظهر أو المتصفح", @@ -1165,6 +1166,7 @@ "prefs-help-email": "تحديد عنوان البريد الإلكتروني اختياري، ولكنه يلزم لإعادة تعيين كلمة المرور في حال نسيت كلمة المرور الخاصة بك.", "prefs-help-email-others": "يمكنك أيضا أن تسمح للآخرين الاتصال بك عن طريق وصلة في صفحة المستخدم أو نقاش المستخدم الخاصة بك. لا يكشف بريدك الإلكتروني عندما يراسلك أحد بهذه الطريقة، ولكن إذا قمت بالرد سيرى بريدك الإلكتروني.", "prefs-help-email-required": "عنوان البريد الإلكتروني مطلوب.", + "prefs-help-requireemail": "إذا تم تحديده، فسوف يرسل رسائل البريد الإلكتروني الخاصة بإعادة تعيين كلمة المرور فقط إذا كان الشخص الذي قام بإعادة الضبط قد قدم اسم المستخدم والبريد الإلكتروني لهذا الحساب.", "prefs-info": "المعلومات الأساسية", "prefs-i18n": "الترجمة", "prefs-signature": "التوقيع", @@ -2618,6 +2620,7 @@ "ipblocklist-legend": "إيجاد مستخدم ممنوع", "blocklist-userblocks": "أخفِ منع الحسابات", "blocklist-tempblocks": "أخفِ المنع المؤقت", + "blocklist-indefblocks": "إخفاء عمليات المنع غير المحددة", "blocklist-addressblocks": "أخفِ منع عنوان أيبي واحد", "blocklist-type": "النوع:", "blocklist-type-opt-all": "الكل", diff --git a/languages/i18n/ban.json b/languages/i18n/ban.json index 37e59477b1..52dfc220b7 100644 --- a/languages/i18n/ban.json +++ b/languages/i18n/ban.json @@ -13,12 +13,13 @@ "Joseagush", "Wandering ant", "Kadek Ayu Sulastri", - "Luh Gede Krismayanti" + "Luh Gede Krismayanti", + "Amire80" ] }, "tog-underline": "Garis ring beten pranala:", - "tog-hideminor": "engkebang suntingan ring gentosan sane pinih anyar", - "tog-hidepatrolled": "engkebang suntingan mapatrol ring gentosan sane pinih anyar", + "tog-hideminor": "Engkebang uahan alit saking uahan sané mangkin", + "tog-hidepatrolled": "Engkebang uahan sané kapatroli saking uahan sané mangkin", "tog-newpageshidepatrolled": "engkebang lembar mapatrol saking saking kepahan lembar anyar", "tog-hidecategorization": "Engkebang kacané", "tog-extendwatchlist": "kembangang kepahan pangiwasan antuk nampilang samian panguwahan, nenten sane anyar kewanten", @@ -73,7 +74,7 @@ "mon": "Som", "tue": "Ang", "wed": "Bud", - "thu": "Wrs", + "thu": "Wra", "fri": "Suk", "sat": "San", "january": "Januari", @@ -107,34 +108,34 @@ "may": "Méi", "jun": "Jun", "jul": "Jul", - "aug": "Ags", + "aug": "Agu", "sep": "Sép", "oct": "Okt", "nov": "Nop", "dec": "Dés", - "january-date": "Januari $1", - "february-date": "Februari $1", - "march-date": "Maret $1", - "april-date": "April $1", - "may-date": "Mei $1", - "june-date": "Juni $1", - "july-date": "Juli $1", - "august-date": "Agustus $1", - "september-date": "September $1", - "october-date": "Oktober $1", - "november-date": "November $1", - "december-date": "Desember $1", + "january-date": "$1 Januari", + "february-date": "$1 Pébruari", + "march-date": "$1 Maret", + "april-date": "$1 April", + "may-date": "$1 Méi", + "june-date": "$1 Juni", + "july-date": "$1 Juli", + "august-date": "$1 Agustus", + "september-date": "$1 Séptémber", + "october-date": "$1 Oktober", + "november-date": "$1 Nopémber", + "december-date": "$1 Désémber", "period-am": "AM", "period-pm": "PM", "pagecategories": "{{PLURAL:$1|Kategori}}", "category_header": "Kaca ring ketegori \"$1\"", "subcategories": "Subkategori", "category-media-header": "Média ring kategori \"$1\"", - "category-empty": "\"mangkin, nenten madaging lembar utawi pekakas ring golongan puniki\"", - "hidden-categories": "{{plural:$1|punduhan sane kaengkebang| punduhan sane kaengkebang}}", - "hidden-category-category": "Kategori mengkeb", - "category-subcat-count": "{{PLURAL:$2| golongan puniki madue {{PLURAL:$1|$1 subkategori}} puniki, saking genepan $2.}}", - "category-article-count": "{{PLURAL:$2|golongan puniki madue{{PLURAL:$1|$1 lembar}}, saking total $2.}}", + "category-empty": "Kategori puniki mangkin nénten madaging kaca utawi média.", + "hidden-categories": "{{plural:$1|Kategori sané kaengkebang}}", + "hidden-category-category": "Kategori sané kaengkebang", + "category-subcat-count": "{{PLURAL:$2|Kategori iki wantah madué subkategori ring sor puniki|Kategori iki madué {{PLURAL:$1|subkategori|$1 subkategori}} ring sor puniki, saking $2 akéhnyané.}}", + "category-article-count": "{{PLURAL:$2|Kategori puniki wantah madué kaca ring sor puniki.|{{PLURAL:$1|Kaca|$1 kaca}} ring sor puniki wénten ring kategori puniki, saking $2 akéhnyané.}}", "category-file-count": "{{PLURAL:$2|golongan puniki madue{{PLURAL:$1|$1 lembar}}, saking total $2.}}", "listingcontinuesabbrev": "lant.", "index-category": "Lembar sane maindeks", @@ -152,7 +153,7 @@ "and": " miwah", "faq": "FAQ (pitaken sane jagi katakonang)", "actions": "Parilaksana", - "namespaces": "Genah wastan", + "namespaces": "Genah aran", "variants": "Varian", "navigation-heading": "Menu navigasi", "errorpagetitle": "Kaiwangan", @@ -173,8 +174,8 @@ "view": "Cingak", "view-foreign": "Cingak ring $1", "edit": "Uah", - "create": "Karyanin", - "create-local": "Icénin daging sané marupa paparan lokal", + "create": "Kardi", + "create-local": "Tambeh déskripsi lokal", "delete": "Usap", "viewdeleted_short": "Cingak {{PLURAL:$1|siki uahan sané kausapin|$1 uahan sané kausapin}}", "protect": "Saib", @@ -186,10 +187,10 @@ "personaltools": "Pekakas praragan", "talk": "Pabligbagan", "views": "Pakantenan", - "toolbox": "Pekakas", + "toolbox": "Piranti", "tool-link-emailuser": "Kirim surel ring {{GENDER:$1|pengguna}} puniki", "imagepage": "Cingak kaca berkas", - "mediawikipage": "Cingak kaca séwalapatra", + "mediawikipage": "Cingak kaca séwala", "templatepage": "Cingak kaca cétakan", "viewhelppage": "Cingak kaca wantuan", "categorypage": "Cingak kaca kategori", @@ -206,6 +207,7 @@ "pool-errorunknown": "Iwang sané durung kauningin", "aboutsite": "Indik {{SITENAME}}", "aboutpage": "Project:Indik", + "copyright": "Daging kasayagayang ring sor $1 ri tatkala nénten wénten uahan.", "copyrightpage": "{{ns:project}}:Hak cipta", "currentevents": "Kawéntenané mangkin", "currentevents-url": "Project:Kawéntenané mangkin", @@ -221,12 +223,12 @@ "privacypage": "Project:Awig-awig indik data praragan", "ok": "OK", "retrievedfrom": "Kapolihang saking \"$1\"", - "youhavenewmessages": "{{PLURAL:$3|Jero madué}} $1 ($2)", - "youhavenewmessagesfromusers": "{{PLURAL:$4|Ida dané madué}} $1 saking {{PLURAL:$3|$3 sang anganggé lianan}} ($2).", + "youhavenewmessages": "{{PLURAL:$3|Ragané madué}} $1 ($2)", + "youhavenewmessagesfromusers": "{{PLURAL:$4|Ragané madué}} $1 saking {{PLURAL:$3|$3 sang anganggé lianan}} ($2).", "youhavenewmessagesmanyusers": "Jero madué $1 saking akéh sang anganggé ($2).", - "newmessageslinkplural": "{{PLURAL:$1|séwalapatra anyar abesik|999=séwalapatra anyar}}", + "newmessageslinkplural": "{{PLURAL:$1|séwala anyar abesik|999=séwala anyar}}", "newmessagesdifflinkplural": "$1 {{PLURAL:$1|uahan}}", - "youhavenewmessagesmulti": "Ida dané madué séwalapatra anyar ring $1", + "youhavenewmessagesmulti": "Ragané madué séwala anyar ring $1", "editsection": "uah", "editold": "uah", "viewsourceold": "cingak wit", @@ -252,7 +254,7 @@ "nstab-special": "Kaca kusus", "nstab-project": "Kaca proyék", "nstab-image": "Depukan", - "nstab-mediawiki": "Séwalapatra", + "nstab-mediawiki": "Séwala", "nstab-template": "Cétakan", "nstab-help": "Kaca wantuan", "nstab-category": "Kategori", @@ -261,7 +263,7 @@ "nospecialpagetext": "Ida nagih kaca pinih luwih sane nenten patut.\n\nWacakan kaca pinih luwih dados kacingak ring [[Special:SpecialPages|{{int:specialpages}}]].", "error": "Kaiwangan", "databaseerror": "Database kaluputan", - "databaseerror-query": "Kueri: $1", + "databaseerror-query": "Kuéri: $1", "databaseerror-function": "Pungsi: $1", "databaseerror-error": "Pelih: $1", "missing-article": "data utama nenten prasida nemu tulisan saking lembar sane sepatutne wenten, inggih punika $1, $2\n\nindike puniki biasane keranayang olih pranala kaon nuju pabenahan sane dumun lembar sane sampun kaicalang\n\nyening nenten puniki sane ngranayang, ida dane minab sampun manggihin kaiwangang ring sajeroning piranti lunak.\nDurus sadokang indik puniki rin silih sinunggil anak \n\n[[Special:ListUsers/sysop|Pengurus]], antuk ngetik alamat URL sane katuju", @@ -270,13 +272,13 @@ "badtitletext": "Judul halaman sane katagih nenten patut, kosong, atau judul antarbahasa atau antarwiki yang salah sambung.\n\nmurda lembar sane kaarsa nenten sida kaedengang, kosong, utawi murda murda antarbasa utawi antarwiki sane iwang", "viewsource": "Cingak wit", "viewsource-title": "Cingak wit saking $1", - "viewsourcetext": "Jero dados nyingakin miwah nurun wit kaca puniki.", + "viewsourcetext": "Ragané dados nyingakin miwah nurun wit saking kaca puniki.", "yourname": "Peséngan sang anganggé:", "userlogin-yourname": "Peséngan sang anganggé", - "userlogin-yourname-ph": "Dagingin peséngan sang anganggé jero", + "userlogin-yourname-ph": "Dagingin peséngan sang anganggé ragané", "yourpassword": "Kruna sandi:", "userlogin-yourpassword": "Kruna sandi", - "userlogin-yourpassword-ph": "Dagingin kruna sandi jero", + "userlogin-yourpassword-ph": "Dagingin kruna sandi ragané", "createacct-yourpassword-ph": "Dagingin kruna sandi", "yourpasswordagain": "jumunin kruna sandi", "createacct-yourpasswordagain": "Mastiang kruna kunci", @@ -291,13 +293,13 @@ "notloggedin": "Durung manjing log", "userlogin-noaccount": "Durung madué akun?", "userlogin-joinproject": "Nyarengin {{SITENAME}}", - "createaccount": "Karyanin akun", + "createaccount": "Kardi akun", "userlogin-resetpassword-link": "Engsap ring kruna kunci?", "userlogin-helplink2": "Wantuan indik manjing log", - "createacct-emailoptional": "Alamat email (becikang kadagingin)", - "createacct-email-ph": "Dagingin alamat email jero", - "createacct-submit": "Karyanin akun jero", - "createacct-benefit-heading": "{{SITENAME}} kakaryanin olih anak sakadi jero.", + "createacct-emailoptional": "Alamat séwala éléktronik (opsional)", + "createacct-email-ph": "Dagingin alamat séwala éléktronik ragané", + "createacct-submit": "Kardi akun ragané", + "createacct-benefit-heading": "{{SITENAME}} kakaryanin antuk anak sakadi ragané.", "createacct-benefit-body1": "{{PLURAL:$1|uahan}}", "createacct-benefit-body2": "{{PLURAL:$1|kaca}}", "createacct-benefit-body3": "{{PLURAL:$1|sang anuut}} sané mangkin", @@ -305,7 +307,7 @@ "loginlanguagelabel": "Basa: $1", "pt-login": "Manjing log", "pt-login-button": "Manjing log", - "pt-createaccount": "Ngaryanin akun", + "pt-createaccount": "Kardi akun", "pt-userlogout": "Medal log", "botpasswords-label-create": "Ngae", "botpasswords-label-cancel": "Wangdé", @@ -313,50 +315,54 @@ "botpasswords-label-resetpassword": "Nyumu kruna sandi", "resetpass-submit-cancel": "Wangdé", "passwordreset": "Nyumu kruna sandi", - "bold_sample": "teks puniki mesurat tebel", - "bold_tip": "teks puniki mesurat tebel", + "bold_sample": "Suratan tebel", + "bold_tip": "téks puniki mesurat tebel", "italic_sample": "teks puniki masurat sendeh", "italic_tip": "teks puniki masurat sendeh", "link_sample": "murda pranala", "link_tip": "pranala tengah", "extlink_sample": "http://www.example.com murda pranala", "extlink_tip": "pranala sisi (sampunang lali kakawitin http://)", - "headline_sample": "teks murda", + "headline_sample": "téks murda", "headline_tip": "subgolongan undag 2", "nowiki_sample": "lebuang teks sane nenten jagi keformat ring driki", "nowiki_tip": "campahang format wiki", "image_tip": "cantumin pupulan", "media_tip": "Pranala depukan", - "sig_tip": "tanda tangan ida dane sareng tanda waktu", + "sig_tip": "tanda tangan ida dané sareng tanda waktu", "hr_tip": "garis horizontal", "summary": "Ringkesan:", "minoredit": "Puniki uahan alit", - "watchthis": "tinjo lembar puniki", + "watchthis": "Awasin kaca puniki", "savearticle": "Raksa kaca", "publishpage": "Terbitang kaca", "savearticle-start": "Raksa kaca...", "publishpage-start": "Terbitang kaca…", - "preview": "tayangan sadurungnyane", - "showpreview": "Sinahang preview", + "preview": "Pracingak", + "showpreview": "Édengang pracingak", "showdiff": "Cingak uahan", "anoneditwarning": "Pingetan: Ida dané nénten kacatet ngranjing. Alamat IP ida dané jagi kacatet ring sejarah (indik sané dumunan) ring lembar puniki. Yening ida dane [$1 log in] utawi [$2 create an account], your edits will be attributed to your username, along with other benefits.", + "blockedtext": "Peséngan penganggé utawi genah IP ragané kablokir .\n\nBlokir puniki kalaksanayang olih $1.\nKablokir krana $2.\n\n* Kablokir saking: $8\n* Blokir kadaluwarsa ring: $6\n* Tetujon ngablokir: $7\n\nRagané dados ngubungin $1 utawi [[{{MediaWiki:Grouppage-sysop}}|prajuru]] antuk mabligbagin.\nRagané nénten dados nganggén fitur puniki \"{{int:emailuser}}\" sajabaning ragané sampun ngranjingang email sané patut ring [[Special:Preferences|pustaka]] tur ragané nénten kablokir antuk nganggén\nGenah IP ragané sané pinih anyar inggih punika $3, tur ID pamblokiran inggih punika #$5.\nTulung genahang silih sinunggil utawi kalih pidarta ring pitakén sané kakaryanin.", "loginreqlink": "manjing log", "newarticle": "(Anyar)", "newarticletext": "ida dane ngiring pranala nuju lembar sane durung wenten. yening jagi ngaryanang lembar punika, ketik daging lembar ring kotak sane wenten ring beten puniki. (cingak [$1 lembar wantuan] anggen wacana salanturnyane). yening ida dane nenten nyelapang neked ring lembar puniki, klik tombol \"back\" ring \"penjelajah web\" ida dane.", - "noarticletext": "mangkin nenten wenten teks ring lembar puniki. ida dane prasida [[Special:Search/{{PAGENAME}}|ngrereh murda nganggen lembar puniki]] ring lembar-lembar sane lianan, [{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} ngrereh log sane mapaiketan], utawi [{{fullurl:{{FULLPAGENAME}}|action=edit}} nguwah lembar puniki].", - "noarticletext-nopermission": "mangkin nenten wenten teks ring lembar puniki. ida dane prasida [[Special:Search/{{PAGENAME}}|ngarereh murda anggen lembar puniki]] ring lembar-lembar sane lianan, [{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} ngarereh log sane mapaiketan], utawi [{{fullurl:{{FULLPAGENAME}}|action=edit}} ngubah lembar puniki].", + "anontalkpagetext": "Niki inggih punika kaca pabligbagan sang penganggé sané nénten nguningayang wasta utawi nénten nganggén wasta. Nika mawinan penganggé punika patut nganggén genah IP sané mawentuk angka antuk manyihnayang.\nGenah IP punika prasida kaanggén sareng-sareng olih makudang-kudang panganggé sané lianan. \nYéning Ragané sang penganggé sané nénten mawasta tur marasa ngamolihang pidarta sané nénten patut, ngiring \n[[Special:CreateAccount|ngaryanin akun]] utawi [[Special:UserLogin|sang penganggé ngranjing log]] antuk ngelidin kabingungan saking sang penganggé sané lianan ring galah sané lianan.", + "noarticletext": "Mangkin nénten wénten suratan ring kaca puniki.\nRagané prasida [[Special:Search/{{PAGENAME}}|ngrereh murda kaca puniki]] ring kaca lianan,\n[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} ngrereh log sané mapaiketan],\nutawi [{{fullurl:{{FULLPAGENAME}}|action=edit}} ngardi kaca puniki].", + "noarticletext-nopermission": "Mangkin nénten wénten suratan ring kaca puniki.\nRagané prasida [[Special:Search/{{PAGENAME}}|ngrereh murda kaca puniki]] ring kaca lianan,\n[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} ngrereh log sané mapaiketan], nanging ragané tan kalugra ngardi kaca puniki.", "userpage-userdoesnotexist-view": "Akun sang anganggé \"$1\" nénten madaptar.", - "previewnote": "\"elingang yening puniki wantah sane lintang.\" Panguwahan ida dane durung kasimpen!", + "clearyourcache": "Catetan:Sesampun karaksayang, Ragané patut ngentasin tembolok peramban wéb antuk nyingakin uahan.\n* Firefox/Safari: Tahan Shift ritatkala ngaklik Reload, utawi teken Ctrl-F5 utawi Ctrl-R (⌘-R ring Mac)\n* Google Chrome: Teken Ctrl-Shift-R (⌘-Shift-R ring Mac)\n* Internet Explorer: Teken Ctrl ritatkala ngaklik Refresh, utawi teken Ctrl-F5\n* Opera: Ngranjing ka Ménu → Pengaturan (Opera → Pustaka ring Mac) Salanturnyané ka Privacy & security → Clear browsing data → Cached images and files.", + "previewnote": "Éling yéning puniki wantah pracingak.\nUahan ragané durung karaksa!", "continue-editing": "Magingsir ka genah ngauwah", "editing": "Nguahin $1", "creating": "Makarya $1", "editingsection": "Nguahin $1 (pahan)", "editingcomment": "Nguahin $1 (pahan anyar)", "templatesused": "{{PLURAL:$1|Citakan}} sané kaanggén ring kaca puniki:", + "templatesusedpreview": "{{PLURAL:$1|Citakan}} sané kaanggén ring pracingak puniki:", "template-protected": "(kasaibin)", "template-semiprotected": "(semi-kasaibin)", "hiddencategories": "lembar niki inggih punika krama saking {{PLURAL:$1|1 golongan sane mengkeb|$1 golongan sane mengkeb}}", - "permissionserrors": "Kaiwangan ritatkala ngranjing", + "permissionserrors": "Pikobet lugra", "permissionserrorstext-withaction": "ida dané nénten madué kuasa ngranjing anggén $2, riantukan {{PLURAL:$1|alasan}} ring sor puniki:", "recreate-moveddeleted-warn": "\"pingetan\" ida dane ngawe malih lembar sane naenin maapus.'''\n\nmangda kayunin malih napike pantes lanturang suntingan ida dane. puniki log pengapusan lan pangisidan saking lembar puniki:", "moveddeleted-notice": "Kaca puniki sampun kausapin.\nAnggen pewarah, proteksi, lan pengisidan log saking lembar puniki cingakin pustaka beten.", @@ -367,19 +373,20 @@ "post-expand-template-inclusion-category": "lembar sane maukuran templat sane nglangkungin wates", "post-expand-template-argument-warning": "\"peminget\" lembar puniki madaging kiranglangkungnyane siki argumen templat anggen ukuran ekspansi sane kaliwat ageng. argumen-argumen punika sampun kacampahang.", "post-expand-template-argument-category": "lembar sane medaging argumen templat sane kacampahang", + "undo-failure": "Uwahan puniki nénten prasida kabalikang krana wénten konflik panguwahan antara.", "viewpagelogs": "Cingak log saking kaca puniki", - "currentrev-asof": "pabecikan sane anyar ring pinanggal$1", + "currentrev-asof": "Révisi sané pinih anyar ring $1", "revisionasof": "Uahan ri tatkala $1", - "revision-info": "Panguwahan per $1 olih {{GENDER:$6|$2}}$7", + "revision-info": "Révisi ri tatkala $1 antuk {{GENDER:$6|$2}}$7", "previousrevision": "← Uahan sadurungnyané", "nextrevision": "Uahan salanturnyané →", "currentrevisionlink": "Uahan sané mangkin", "cur": "mgkn", "last": "sdrg", "histlegend": "pilih kalih tombol radio lantur pecik tombol \"bandingang\" anggen ngebandingang indik lianan. klik siki tanggal anggen nyingak indik lianan lembar ring pinanggal punika.
(skr)= binanne saking indik lianan sane mangkin, (untat) = binanne saking indik lianan sane dumunan, '''k''' = panguwahan alit, '''b''' = panguwahan bot, → = panguwahan kepahan, ← = reringkesan otomatis", - "history-fieldset-title": "Nyaringin révisi", + "history-fieldset-title": "Saring révisi", "history-show-deleted": "wantah sane kaapus", - "histfirst": "pinih suwe", + "histfirst": "pinih sué", "histlast": "pinih anyar", "history-feed-title": "Babad uahan", "history-feed-description": "Babad uahan kaca puniki ring wiki", @@ -394,44 +401,44 @@ "mergelog": "Gabung log", "revertmerge": "tansida nyarengin", "history-title": "Babad uahan saking \"$1\"", - "difference-title": "$1: sane malianan ring revisi", + "difference-title": "Bina pantaraning révisi \"$1\"", "lineno": "Carik $1:", "compareselectedversions": "bandingang penguwahan sane kapilih", "editundo": "nguliang", "diff-empty": "(Nénten wénten sané malianan)", "diff-multi-sameuser": "({{PLURAL:$1|$1 revisi pantaraning}} olih pangawi sane pateh nenten kacumawisang)", "diff-multi-otherusers": "({{PLURAL:$1|Siki pamecikan pantaraning|$1 pamecikan pantaraning}} olih {{PLURAL:$2|siki pangangge lianan|$2 panggange}} nenten katampilan)", - "searchresults": "asil pangrereh", + "searchresults": "Asil pangrereh", "searchresults-title": "Asil pangrereh anggén \"$1\"", "prevn": "{{PLURAL:$1|$1}} sadurungnyané", "nextn": "{{PLURAL:$1|$1}} salanturnyané", "prev-page": "kaca sadurungnyané", - "prevn-title": "$1 {{PLURAL:$1|asil}} sadurunge", + "prevn-title": "$1 {{PLURAL:$1|asil}} sadurungnyané", "nextn-title": "$1 {{PLURAL:$1|asil}} selanturnyane", "shown-title": "Sinahang $1 {{PLURAL:$1|asil}} per kaca", "viewprevnext": "Cingak ($1 {{int:pipe-separator}}$2)($3)", "searchmenu-exists": "wenten lembar sane mamurda \"[[:$1]]\" ring wiki puniki. {{PLURAL:$2|0=| cingakin taler asil rerehan lianan sane kapolihang}}", - "searchmenu-new": " ngawi lembar \"[[:$1]] ring wiki puniki ! {{{{PLURAL:$2|}}| 0 = | cingak teler lembar sane kapolihang ring pangreregan | cingak taler asil pangrerehan sane kapolihang}}", + "searchmenu-new": "Kardi kaca \"[[:$1]]\" ring wiki puniki! {{PLURAL:$2|0=|Taler cingak kaca sané temunin ragané.|Taler cingak asil pangrereh.}}", "searchprofile-articles": "Kaca daging", - "searchprofile-images": "multimedia", + "searchprofile-images": "Multimédia", "searchprofile-everything": "Samian", - "searchprofile-advanced": "lanturane", + "searchprofile-advanced": "Lanturan", "searchprofile-articles-tooltip": "Rereh ring $1", "searchprofile-images-tooltip": "Rereh depukan", - "searchprofile-everything-tooltip": "pangrereh ring samian isi (taler lembar wecana)", - "searchprofile-advanced-tooltip": "Rereh ring genah wastan sané kapilih", + "searchprofile-everything-tooltip": "Rereh ring samian daging (rumasuk kaca pabligbagan)", + "searchprofile-advanced-tooltip": "Rereh ring genah aran sané kapilih", "search-result-size": "$1 ({{PLURAL:$2|1 kruna|$2 kruna}})", "search-result-category-size": "{{PLURAL:$1|1 krama|$1 krama}}({{PLURAL:$2|1 subgolongan|$2 subgolongan}}, {{PLURAL:$3|1 pupulan|$3 pupulan}})", "search-redirect": "(gingsiran saking $1)", "search-section": "(pahan $1)", "search-file-match": "(anut ring daging depukan)", - "search-suggest": "minab sane kearsaang $1", + "search-suggest": "Minab sané aptiang ragané: $1", "searchrelated": "paiketan", "searchall": "samian", "search-showingresults": "{{PLURAL:$4|Asil $1 of $3|Asil-asil $1 – $2 saking $3}}", - "search-nonefound": "nenten wenten asil sane caklek ring arsa", + "search-nonefound": "nénten wénten asil sané caklek ring arsa", "powersearch-ns": "Rereh ring genah wastan:", - "mypreferences": "Preferensi", + "mypreferences": "Préferénsi", "prefs-user-pages": "Kaca sang anganggé", "saveprefs": "Raksa", "prefs-editing": "Nguahin", @@ -447,16 +454,18 @@ "grouppage-bot": "{{ns:project}}:Bot", "grouppage-sysop": "{{ns:project}}:Prajuru", "right-edit": "Uah kaca", - "right-writeapi": "nganggén API sasuratan", + "right-writeapi": "Anggé API sasuratan", "right-delete": "Usap kaca", "right-editprotected": "Uah kaca sané kasaibin \"{{int:protect-level-sysop}}\"", "grant-createeditmovepage": "Karyanin, uah, miwah gingsirang kaca", "grant-editprotected": "Uah kaca sané kasaibin", + "grant-rollback": "Waliang uahan ring kaca", "newuserlogpage": "Log makarya sang anganggé", + "rightslog": "Log panguwahan hak ngaksés", "action-read": "wacén kaca puniki", "action-edit": "uah kaca puniki", "action-createpage": "karyanin kaca puniki", - "action-createaccount": "karyanin akun sang anganggé puniki", + "action-createaccount": "kardi akun sang anganggé puniki", "action-delete": "usap kaca puniki", "action-deletedhistory": "cingak babad kaca sané kausapin", "action-browsearchive": "rereh kaca sané kausapin", @@ -469,7 +478,7 @@ "recentchanges-summary": "Track uahan sané mangkin ring wikiné indik kaca puniki.", "recentchanges-noresult": "Nénten wénten uahan ring galahnyané puniki sané anut sareng praciri puniki.", "recentchanges-feed-description": "molihang pagentosan anyar ring wiki ring \"umpan\" puniki", - "recentchanges-label-newpage": "Uahan puniki makarya kaca anyar", + "recentchanges-label-newpage": "Uahan puniki ngardi kaca anyar", "recentchanges-label-minor": "Punika uahan alit", "recentchanges-label-bot": "Uahan puniki kalaksanayang antuk bot", "recentchanges-label-unpatrolled": "Uahan puniki durung kapatroli", @@ -503,7 +512,7 @@ "rcshowhidemine-show": "Sinahang", "rcshowhidemine-hide": "Engkebang", "rcshowhidecategorization-show": "Sinahang", - "rclinks": "Edengang untat $1 gentosan anyar $2 dina kaping untat", + "rclinks": "Sinahang $1 uahan sané untat ring $2 dina sané lintang", "diff": "bina", "hist": "bbd", "hide": "Engkebang", @@ -512,13 +521,13 @@ "newpageletter": "A", "boteditletter": "b", "rc-change-size-new": "$1 {{PLURAL:$1|bita}} sasampun kauah", - "rc-enhanced-expand": "edengang rerincian", - "rc-enhanced-hide": "engkebang rerincian", - "rc-old-title": "witnyané kakaryanin pinaka \"$1\"", + "rc-enhanced-expand": "Sinahang rerincian", + "rc-enhanced-hide": "Engkebang rerincian", + "rc-old-title": "witnyané kakardi pinaka \"$1\"", "recentchangeslinked": "Uahan mapaiketan", "recentchangeslinked-toolbox": "Uahan mapaiketan", "recentchangeslinked-title": "Uahan sané mapaiketan $1", - "recentchangeslinked-summary": "lembar kautamayang puniki ngicenin kepahan penguwahan kaping untat ring lembar-lembar sana mapaiket. Lembar sane [[Special:Watchlist|ida dane iwasin]] mapinget antuk sesuratan tebel", + "recentchangeslinked-summary": "Dagingin aran kaca antuk nyingakin uahan ring kaca-kaca sané kasambung kaca punika. (Antuk nyingakin kapahan kategori, dagingin {{ns:category}}:Aran kategori). Uahan kaca-kaca ring [[Special:Watchlist|Pangawasan ragané]] kasurat tebel.", "recentchangeslinked-page": "Peséngan kaca:", "recentchangeslinked-to": "Sinahang uahan saking kaca-kaca sané linked kaca puniki", "upload": "Unggahang depukan", @@ -535,25 +544,26 @@ "listfiles": "Bacakan depukan", "file-anchor-link": "Depukan", "filehist": "Babad berkas", - "filehist-help": "klik ring pinanggal/galah anggen nyingakin pupulan niki rikala punika", + "filehist-help": "Klik ring tanggal/galah anggén nyingakin berkas puniki ri tatkala galah punika.", "filehist-deleteall": "usap samian", - "filehist-revert": "buwungang", - "filehist-current": "sané mangkin", + "filehist-revert": "wangdéang", + "filehist-current": "mangkin", "filehist-datetime": "Tanggal/Galah", "filehist-thumb": "Miniatur", "filehist-thumbtext": "miniatur anggen versi ring $1", "filehist-nothumb": "Tusing ade miniatur", "filehist-user": "Sang anganggé", - "filehist-dimensions": "ukuran", - "filehist-comment": "tureksa", + "filehist-dimensions": "Diménsi", + "filehist-comment": "Pasaur", "imagelinks": "Panganggén depukan", "linkstoimage": "{{PLURAL:$1|Kaca|$1 kaca}} ring sor puniki nganggén depukan puniki:", + "linkstoimage-more": "Langkungan saking $1 {{PLURAL:$1|kaca|kaca-kaca}} nganggén berkas puniki.\nPupulan puniki nyinahang {{PLURAL:$1|kaca kapertama nganggén pranala langsung|$1 kaca sané nganggén pranala langsung}} ka berkasé puniki\nA [[Special:WhatLinksHere/$2|pupulan sané jangkep]] taler kasayagayang.", "nolinkstoimage": "Nénten wénten kaca sané nganggén berkas puniki.", "linkstoimage-redirect": "$1 (gingsiran berkas) $2", "sharedupload-desc-here": "Depukan puniki mawit saking $1 lan minab kaanggén olih proyék-proyék sané lianan. Déskripsinnyané ring [$2 kaca déskripsi depukannyané] kaarahin ring ungkur puniki.", "filepage-nofile": "Nentén wénten berkas sané mamurda sakadi punika", "shared-repo-name-wikimediacommons": "Wikimedia Commons", - "upload-disallowed-here": "Jero nénten dados numpuk depukan puniki.", + "upload-disallowed-here": "Ragané nénten dados numpuk depukan puniki.", "filedelete": "Usap $1", "filedelete-submit": "Usap", "filedelete-success": "$1 sampun kausapin.", @@ -586,17 +596,19 @@ "booksources-search-legend": "Rereh wit buku", "booksources-search": "Rereh", "specialloguserlabel": "Panggange", + "speciallogtitlelabel": "Tetujon (Murda utawi {{ns:user}}:sang panganggé antuk penganggé)", "log": "Log", "logeventslist-submit": "Sinahang", "all-logs-page": "Makasami log publik", + "alllogstext": "Pupulan tampilan log makasami sané kasayagayang ring {{SITENAME}}.\nRagané dados ngalaksanayang watesan tampilan nganggén ngamilih soroh log, sang anganggé (sénsitif kapitalisasi), utawi murdan kaca (taler sénsitif kapitalisasi).", "logempty": "Nenten katemonin entri log sane patut", "allpages": "Makasami kaca", "allarticles": "Makasami kaca", "allinnamespace": "Makasami kaca (genah wastan $1)", "allpagessubmit": "Lanturang", "allpages-bad-ns": "{{SITENAME}} nénten madué genah wastan \"$1\".", - "allpages-hide-redirects": "Ngengkebang pagingsirian", - "categories": "Golongan", + "allpages-hide-redirects": "Engkebang kaca gingsirian", + "categories": "Kategori", "categories-submit": "Sinahang", "deletedcontributions": "Pituut sang anganggé sané kausapin", "linksearch-ns": "Genah wastan:", @@ -604,17 +616,19 @@ "listusers-submit": "Sinahang", "listgrouprights-members": "kepahan krama", "emailuser": "email sane nganggo niki", - "emailmessage": "Séwalapatra:", - "usermessage-editor": "Séwalapatra sistem", - "watchlist": "kepahan peninjoan", - "mywatchlist": "kepahan peninjoan", + "emailmessage": "Séwala:", + "usermessage-editor": "Séwala sistem", + "watchlist": "Pangawasan", + "mywatchlist": "Pangawasan", "watchlistfor2": "Anggén $1 $2", - "watch": "cingak", + "watch": "Awasin", "unwatch": "tan sida maninjo", - "watchlist-details": "{{PLURAL:$1|$1 kaca}} wénten ring bacakan pantauan ida dané (rumasuk kaca pabligbagan).", + "watchlist-details": "{{PLURAL:$1|$1 kaca}} wénten ring Pangawasan ragané (rumasuk kaca pabligbagan).", + "wlheader-showupdated": "Kaca-kaca puniki sampun kauwah saking kunjungan ragané sané pinih untat, kasinahang sareng tebel.", + "wlnote": "Ring sor puniki {{PLURAL:$1|uahan sané pinih untat| $1 uahan}} pinih untat {{PLURAL:$2|jam|$2 jam}},ngantos $3, $4.", "watchlist-submit": "Sinahang", "wlshowhideminor": "uahan alit", - "watchlist-options": "milih kepahan peninjo", + "watchlist-options": "Opsi pangawasan", "enotif_reset": "Cihnayang makasami kaca sané sampun karauhin", "enotif_subject_deleted": "Kaca {{SITENAME}} $1 sampun {{GENDER:$2|kausap}} $2", "enotif_body_intro_deleted": "Kaca{{SITENAME}} $1 sampun {{GENDER:$2|kausapin}} ring $PAGEEDITDATE olih $2, cingak $3.", @@ -623,107 +637,112 @@ "historyaction-submit": "Sinahang uahan", "actioncomplete": "pelaksanan sampun wusan", "actionfailed": "pelaksana luput", - "dellogpage": "log pangapus", + "dellogpage": "Log pangusap", + "rollback-confirmation-yes": "Waliang", "rollback-confirmation-no": "Wangdé", - "rollbacklink": "mabalik", - "rollbacklinkcount": "balikang $1 {{PLURAL:$1|suratan}}", + "rollbacklink": "waliang", + "rollbacklinkcount": "waliang $1 {{PLURAL:$1|uahan}}", "changecontentmodel-title-label": "Murda kaca", "protectlogpage": "Log saiban", "protectedarticle": "nyaib \"[[$1]]\"", + "modifiedarticleprotection": "nguwah tingkatan panyambi antuk \"[[$1]]\"", "protect-default": "Lugra makasami sang anganggé", "restriction-edit": "Uah", "restriction-move": "Gingsirang", "undelete": "Cingak kaca sané kausapin", "undeleterevisions": "$1 {{PLURAL:$1|uahan}} kausapin", - "undeletelink": "cingak/uliang", + "undeletelink": "cingak/waliang", "undeleteviewlink": "cingak", "undelete-search-title": "Rereh kaca sané kausapin", - "namespace": "Genah wastan:", - "invert": "uliang pilihan", - "tooltip-invert": "Centang kotak puniki mangdané ngengkebang lembar sané kauwah ring genah wastan sané kapilih (miwah genah wastan sané mapaiketan yéning kacentang)", - "namespace_association": "Genah wasta sané mapaiketan", - "tooltip-namespace_association": "Céntang kotak puniki anggén nagingin genah wasta pabligbagan utawi subjék sané mapaiketan sareng genah wasta sané kapilih", + "namespace": "Genah aran:", + "invert": "Waliang pilihan", + "tooltip-invert": "Céntang kotak puniki mangda ngengkebang uahan kaca ring genah aran sané kapilih (miwah genah aran sané mapaiketan yéning kacéntang)", + "namespace_association": "Genah aran sané mapaiketan", + "tooltip-namespace_association": "Céntang kotak puniki mangda marengang genah aran pabligbagan utawi subyék sané mapaiketan genah aran sané kapilih", "blanknamespace": "(Utama)", "contributions": "Pituut {{GENDER:$1|sang anganggé}}", "contributions-title": "Pituut sang anganggé $1", "mycontris": "Pituut", "anoncontribs": "Pituut", - "contribsub2": "antuk {{GENDER:$3|$1}} ($2)", + "contribsub2": "Antuk {{GENDER:$3|$1}} ($2)", + "nocontribs": "Nénten wénten uwahan sané patut sareng cihna punika.", "uctop": "sane mangkin", "month": "Saking sasih (miwah sadurungnyané)", "year": "Saking warsa (miwah sadurungnyané):", - "sp-contributions-blocklog": "log pemblokiran", + "sp-contributions-blocklog": "log pangempet", "sp-contributions-deleted": "pituut {{GENDER:$1|sang anganggé}} sané kausapin", "sp-contributions-uploads": "unggahan", "sp-contributions-logs": "log", "sp-contributions-talk": "pabligbagan", "sp-contributions-search": "Rereh pituut", "sp-contributions-username": "Alamat IP wiadin peséngan sang anganggé:", - "sp-contributions-toponly": "tampilang wantah panguwahan sane anyar", - "sp-contributions-newonly": "Tampilang wantah panguwahan sane anyar", + "sp-contributions-toponly": "Wantah édéngang uahan sané pinih anyar", + "sp-contributions-newonly": "Wantah édéngang uahan sané ngardi kaca", "sp-contributions-submit": "Rereh", "whatlinkshere": "Pranala iriki", - "whatlinkshere-title": "lembar-lembar sane maduwe pranala kaping \"$1\"", + "whatlinkshere-title": "Kaca sané kasambung ring \"$1\"", "whatlinkshere-page": "Kaca:", "linkshere": "lembar puniki maduwe pranala ke '''$2'''", "nolinkshere": "Nénten wénten kaca sané madué pranala ring $2.", "isredirect": "Kaca gingsiran", "istemplate": "sareng kasurat", "isimage": "pranala pupulan-pupulan", - "whatlinkshere-prev": "{{PLURAL:$1|sadurungnyane|$1 sadurungnyane}}", - "whatlinkshere-next": "{{PLURAL:$1|selanturnyane}}", + "whatlinkshere-prev": "{{PLURAL:$1|sadurungnyané|$1 sadurungnyané}}", + "whatlinkshere-next": "{{PLURAL:$1|salanturnyané|$1 salanturnyané}}", "whatlinkshere-links": "← pranala", - "whatlinkshere-hideredirs": "$1 pangalihan", + "whatlinkshere-hideredirs": "$1 kaca gingsiran", "whatlinkshere-hidetrans": "$1 transklusi", "whatlinkshere-hidelinks": "$1 pranala", "whatlinkshere-hideimages": "$1 pranala berkas", - "whatlinkshere-filters": "Panyaring", + "whatlinkshere-filters": "Panyaringan", "ipboptions": "2 jam:2 hours,1 dina:1 day,3 dina:3 days,1 minggu:1 week,2 minggu:2 weeks,1 sasih:1 month,3 sasih:3 months,6 sasih:6 months,1 taun:1 year,tanpa wates:infinite", "ipb-pages-label": "Kaca", "ipb-namespaces-label": "Genah wastan", "block-prevent-edit": "Nguahin", - "ipblocklist": "ngempetin sane nganggo", + "ipblocklist": "Sang anganggé sané kaempetin", "infiniteblock": "Nénten kawates", "blocklist-nousertalk": "tan prasida nguahin kaca pabligbagan praragan", "blocklist-editing-page": "kaca", "blocklist-editing-ns": "genah wastan", - "blocklink": "ngempetin", + "blocklink": "empet", "unblocklink": "ngicalang kaempetan", - "change-blocklink": "gentosin empetin", + "change-blocklink": "uah pangempet", "contribslink": "pituut", - "blocklogpage": "log pemblokiran", + "blocklogpage": "Log pangempet", "blocklogentry": "mlokir [[$1]] anggen pangwates galah $2$3", + "reblock-logentry": "nguwah blokiran aturan antuk [[$1]] sareng galah kadaluwarsa $2 $3", "block-log-flags-nocreate": "ngawe akun kaicalang", + "proxyblocker": "Sané ngablokir proxy", "movelogpage": "Log gingsiran", - "revertmove": "buwungang", + "revertmove": "wangdéang", "export": "ekspor lembar", "export-download": "Raksa pinaka berkas", - "allmessages": "Séwalapatra sistem", + "allmessages": "Séwala sistem", "allmessagesname": "pesengan", "allmessagesdefault": "teks lingga", "thumbnail-more": "Ngedénang", "thumbnail_error": "luput ngaryanin bentuk cenik $1", "import-interwiki-sourcepage": "Kaca wit:", "importlogpage": "Log impor", - "tooltip-pt-userpage": "Kaca {{GENDER:|sang anganggé jero}}", - "tooltip-pt-mytalk": "Kaca pabligbagan {{GENDER:|jero}}", - "tooltip-pt-preferences": "Preferensi {{GENDER:|jero}}", + "tooltip-pt-userpage": "Kaca {{GENDER:|sang anganggé ragané}}", + "tooltip-pt-mytalk": "Kaca pabligbagan {{GENDER:|ragané}}", + "tooltip-pt-preferences": "Préferénsi {{GENDER:|ragané}}", "tooltip-pt-watchlist": "kepahan-kepahan lembar sane katinjo titiang", - "tooltip-pt-mycontris": "Bacakan pituut {{GENDER:|jero}}", - "tooltip-pt-login": "Jero kaaptiang mangda manjing log; yadiastun nénten wajib", + "tooltip-pt-mycontris": "Bacakan pituut {{GENDER:|ragané}}", + "tooltip-pt-login": "Ragané kaaptiang mangda manjing log; yadiastun nénten wajib", "tooltip-pt-logout": "Medal log", - "tooltip-pt-createaccount": "Jero kaaptiang mangda makarya akun miwah manjing log; yadiastun nénten wajib", + "tooltip-pt-createaccount": "Ragané kaaptiang mangda ngardi akun miwah manjing log; yadiastun nénten wajib", "tooltip-ca-talk": "Pabligbagan indik kaca daging", "tooltip-ca-edit": "Uah kaca puniki", - "tooltip-ca-addsection": "nyumunin kepahan anyar", - "tooltip-ca-viewsource": "Kaca puniki kasaibin.\nJero wantah prasida nyingakin witnyané", + "tooltip-ca-addsection": "Wiwit bagian anyar", + "tooltip-ca-viewsource": "Kaca puniki kasaibin.\nRagané wantah prasida nyingakin witnyané", "tooltip-ca-history": "Uahan sadurungnyané saking kaca puniki", "tooltip-ca-protect": "Saib kaca puniki", "tooltip-ca-unprotect": "Uah saiban kaca puniki", "tooltip-ca-delete": "Usap kaca puniki", "tooltip-ca-move": "Gingsirang kaca puniki", - "tooltip-ca-watch": "Imbuhin kaca puniki ring bacakan pantauan ida dané", - "tooltip-ca-unwatch": "apus lembar niki ring daftar paninjoan ida dane", + "tooltip-ca-watch": "Tambeh kaca puniki ring pangawasan ragané", + "tooltip-ca-unwatch": "Usap kaca puniki saking pangawasan ragané", "tooltip-search": "Rereh ring {{SITENAME}}", "tooltip-search-go": "Rereh kaca sané mapeséngan pateh sakadi puniki yéning wénten", "tooltip-search-fulltext": "Rereh kaca sané madaging sesuratan puniki", @@ -746,51 +765,58 @@ "tooltip-t-permalink": "Pranala ajeg anggén révisinnyané kacané puniki", "tooltip-ca-nstab-main": "Cingak kaca daging", "tooltip-ca-nstab-user": "Cingak kaca sang anganggé", - "tooltip-ca-nstab-special": "Puniki kaca kusus tur nénten prasida kauwah", + "tooltip-ca-nstab-special": "Puniki kaca kusus tur nénten prasida kauah", "tooltip-ca-nstab-project": "Cingak kaca proyek", "tooltip-ca-nstab-image": "Cingak kaca depukannyané", - "tooltip-ca-nstab-mediawiki": "Cingak séwalapatra sistem", + "tooltip-ca-nstab-mediawiki": "Cingak séwala sistem", "tooltip-ca-nstab-template": "Cingak citakan", "tooltip-ca-nstab-help": "Cingak kaca wantuan", "tooltip-ca-nstab-category": "Cingak kaca kategori", "tooltip-minoredit": "pingetin puniki dados panguwahan kidik", - "tooltip-save": "Raksa uahan jero", - "tooltip-preview": "Pagentosan sane dumun duwen ida dane, mangda anggen niki sadurung jagi nyimpen!", - "tooltip-diff": "Sinahang uahan sané karyanin jero ring sesuratannyané", - "tooltip-compareselectedversions": "cingak binane makekalih kepahan lembar sane kasudi", - "tooltip-watch": "imbuhin lembar niki ring daftar paninjoan ida dane", - "tooltip-rollback": "\"nguliang\" muwungan jagi ngabecikang ring lembar puniki nuju haturan sane untat ngangge apisan klik", + "tooltip-save": "Raksa uahan ragané", + "tooltip-preview": "Pracingak uahan ragané. Rarisang nganggén pracingak puniki sadurung ngraksa.", + "tooltip-diff": "Édéngang uahan sané karyanin ragané ring suratannyané", + "tooltip-compareselectedversions": "Cingak bina pantaraning kalih révisi kaca puniki sané kapilih", + "tooltip-watch": "Tambeh kaca puniki ring pangawasan ragané", + "tooltip-rollback": "\"Waliang\" wantah ngwangdéang uahan kontributor sané pinih untat ring kaca puniki antuk klik apisan", "tooltip-undo": "\"nguliang\" ngabuwungin jagi ngabecikang niki lan ngagah kotak mecikang ngangge mode pratayang. dasar ipun prasida kaimbuhin ring kotak pamicutet", "tooltip-summary": "Dagingin ringkesan", - "simpleantispam-label": "Pamariksa anti-spam.\nPuniki wenten kaisi!", + "simpleantispam-label": "Panuréksa anti-spam.\nSampunang nagingin puniki!", "pageinfo-title": "Pidarta indik \"$1\"", "pageinfo-header-basic": "Pidarta kaca", "pageinfo-header-edits": "Babad uahan", "pageinfo-header-restrictions": "Saiban kaca", - "pageinfo-header-properties": "Properti suratan", - "pageinfo-display-title": "Edengang judul", + "pageinfo-header-properties": "Properti kaca", + "pageinfo-display-title": "Murda tampilan", + "pageinfo-default-sort": "Kunci urut sané baku", "pageinfo-length": "Dawannyané kaca (ring bita)", "pageinfo-namespace": "Genah wastan", "pageinfo-article-id": "ID kaca", "pageinfo-language": "Basa ring daging kaca", "pageinfo-content-model": "Modél antuk daging kaca", + "pageinfo-robot-policy": "Kaindéksang antuk robot", "pageinfo-robot-index": "Kalugra", "pageinfo-robot-noindex": "Tan kalugra", - "pageinfo-watchers": "Akéh nomér sané negdeg kaca", - "pageinfo-few-watchers": "Kirang saking $1 {{PLURAL:$1|tamiu}}", + "pageinfo-watchers": "Akéh sané ngawasin kaca", + "pageinfo-few-watchers": "Kirang saking $1 {{PLURAL:$1|sané ngawasin}}", "pageinfo-redirects-name": "Akéh nomer sané magingsir ka kaca puniki", "pageinfo-subpages-name": "Kapahan kaca saking kaca puniki", + "pageinfo-subpages-value": "$1 ($2 {{PLURAL:$2|kaalihang}}; $3 {{PLURAL:$3|nénten-kaalihang}})", "pageinfo-firstuser": "Sang makarya kaca", - "pageinfo-firsttime": "Galah ritatkala ngripta kaca", + "pageinfo-firsttime": "Tanggal ngardi kaca", "pageinfo-lastuser": "Panguwah sané pinih anyar", "pageinfo-lasttime": "Galah antuk uahan sané pinih anyar", - "pageinfo-edits": "Akéh nomer sané kauwah", + "pageinfo-edits": "Akéh uahan", "pageinfo-authors": "Akéh nomer makasami antuk panyurat sané lianan", "pageinfo-recent-edits": "Akéh nomer sané kauwah (ring $1 sané sampun lintang)", "pageinfo-recent-authors": "Akéh nomer antuk panyurat sané lianan", + "pageinfo-magic-words": "{{PLURAL:$1Kruna}} sakti ($1)", + "pageinfo-hidden-categories": "{{PLURAL:$1|Kategori}} sané kaengkebang ($1)", + "pageinfo-templates": "Katranslusi {{PLURAL:$1|template|templates}} ($1)", "pageinfo-toolboxlink": "Pidarta kaca", "pageinfo-contentpage": "Kapeték dados kaca daging", "pageinfo-contentpage-yes": "Inggih", + "patrol-log-page": "Log patroli", "previousdiff": "← Uahan sadurungnyané", "nextdiff": "Uahan sané pinih anyar →", "widthheightpage": "$1 × $2, $3 {{PLURAL:$3|kaca}}", @@ -800,13 +826,13 @@ "svg-long-desc": "Berkas SVG, jimbarnyané $1 × $2 piksel, agengnyané berkas: $3", "show-big-image": "Depukan sujati", "show-big-image-preview": "Agengnyané pratuduh puniki: $1.", - "show-big-image-other": "{{PLURAL:$2|Resolusi}} iianan: $1.", + "show-big-image-other": "{{PLURAL:$2|Résolusi}} lianan: $1.", "show-big-image-size": "$1 × $2 piksel", "sunday-at": "Redite jam $1", "bad_image_list": "bentukne sekadi puniki:\n\nwantah kepahan daftar ( baris sane kakawitin anggen tanda *) sane kaitung pranala kapertama ring baris mangda pranala ring berkas sane kaon.\nPranala-Pranala sane selanturnyane ring baris sane pateh kamanahang antuk pinangging, inggih punika lembar sane prasida ngedengang berkas punika.", "metadata": "Métadata", "metadata-help": "pupulan puniki madaging wacana imbuhan minab sane kaimbuhin olih kamera digital utawi scanner sane kaanggen antuk ngawi atawi \"mendigitalisasi\" pupulan. Yening pupulan niki sampun taen kautak-atik, rerincine sane wenten minab nenten samian nyiriang wacan saking gambar sane sampun kautak-atik niki.", - "metadata-fields": "Widang métadata gambar sané kacantumang ring séwalapatra puniki jagi kalebuang ring tampilan kaca gambar ri tatkala tabél métadata kacenikang.\nSané lianan jagi kasenetang.\n* make\n* model\n* datetimeoriginal\n* exposuretime\n* fnumber\n* isospeedratings\n* focallength\n* artist\n* copyright\n* imagedescription\n* gpslatitude\n* gpslongitude\n* gpsaltitude", + "metadata-fields": "Widang métadata gambar ring séwala puniki jagi kalebuang ring tampilan kaca gambar ri tatkala tabél métadata kacenikang.\nSané lianan jagi kasenetang.\n* make\n* model\n* datetimeoriginal\n* exposuretime\n* fnumber\n* isospeedratings\n* focallength\n* artist\n* copyright\n* imagedescription\n* gpslatitude\n* gpslongitude\n* gpsaltitude", "namespacesall": "samian", "monthsall": "samian", "confirmemail_invalidated": "Konfirmasi alamat email kawangdéang", @@ -817,8 +843,8 @@ "table_pager_prev": "Kaca sadurungnyané", "watchlisttools-clear": "Ngicalang pupulan sané sampun karauhin", "watchlisttools-view": "Cingak uahan sane relevan", - "watchlisttools-edit": "Cingak miwah uah bacakan pantauan", - "watchlisttools-raw": "Uah kepahan paninjo mentah", + "watchlisttools-edit": "Cingak miwah uah pangawasan", + "watchlisttools-raw": "Uah pangawasan matah", "signature": "[[{{ns:user}}:$1|$2]] ([[{{ns:user_talk}}:$1|pabligbagan]])", "duplicate-defaultsort": "pingetan: sereg pangurutan lingga \"$2\" nyampahang sereg pangurutan lingga sadurunge \"$1\"", "version-specialpages": "Kaca kusus", @@ -833,8 +859,10 @@ "redirect-file": "Wastan berkas", "specialpages": "Kaca kusus", "external_image_whitelist": "#banggiang baris niki sapunapi kawentenanne
\n#anggen fragmen akspresi reguler (wantah kepahan ring kekelaih//) ring sor puniki\n#fragmen-fragmen puniki jagi kaadungang sareng URL saking gambar-gambar eksternal (sane kasambungang langsung)\n#fragmen sane adung jagi katampilang dados gambar, sisanne wantah dados pranala kewanten\n#baris sane kakawitin antuk # jagi kadadosang baris komentar\n#niki nenten ngabinayang aksara ageng lan alit\n#genahang samian fragmen ekspresi reguler ring sor baris puniki. banggiang baris niki sapunapi kawentennane
", - "tag-filter": "filter [[Special:Tags|tag]]:", + "tag-filter": "Panyaring [[Special:Tags|tag]]:", "tag-list-wrapper": "[[Special:Tags|{{PLURAL:$1|Tag}}]]: $2", + "tag-mw-rollback": "Waliang", + "tag-mw-rollback-description": "Uahan sané ngwaliang uahan sadurungnyané nganggén pranala waliang", "tags-active-yes": "Inggih", "tags-active-no": "Nénten", "tags-edit": "uah", @@ -845,17 +873,18 @@ "logentry-delete-delete": "$1 {{GENDER:$2|ngusapin}} kaca $3", "logentry-delete-restore": "$1 {{GENDER:$2|ngwalikan}} kaca $3 ($4)", "logentry-delete-revision": "$1 {{GENDER:$2|mauah}} kaca utama {{PLURAL:$5|$5 pamecikan}} ring kaca $3: $4", - "revdelete-content-hid": "dagingnyané kaengkebang", + "revdelete-content-hid": "daging kaengkebang", "logentry-move-move": "$1 {{GENDER:$2|ngingsirang}} kaca $3 ring $4", "logentry-move-move-noredirect": "$1 {{GENDER:$2|maglisiran}} kaca $3 ka $4 tur nenten ngawe pengalihan", "logentry-move-move_redir": "$1 {{GENDER:$2|maglisiran}} kaca $3 ka $4 tur nenten ngawe pengalihan", - "logentry-newusers-create": "Akun sang anganggé $1 {{GENDER:$2|kakaryanin}}", - "logentry-newusers-autocreate": "Akun sang anganggé $1 {{GENDER:$2|kakaryanin}} otomatis", + "logentry-patrol-patrol-auto": "$1 otomatis {{GENDER:$2|kacihnayang}} sampun kabecikang $4 saking kaca $3 kaawasin", + "logentry-newusers-create": "Akun sang anganggé $1 {{GENDER:$2|kakardi}}", + "logentry-newusers-autocreate": "Akun sang anganggé $1 {{GENDER:$2|kakardi}} otomatis", "logentry-protect-protect": "$1 {{GENDER:$2|nyaibin}} $3 $4", "logentry-upload-upload": "$1 {{GENDER:$2|ngunggahang}} $3", "logentry-upload-overwrite": "$1 {{GENDER:$2|ngunggahang}} vèrsi anyar saking $3", "feedback-cancel": "Wangdé", - "feedback-message": "Séwalapatra:", + "feedback-message": "Séwala:", "searchsuggest-search": "Rereh ring {{SITENAME}}", "duration-days": "$1 {{PLURAL:$1|rahina}}", "pagelanguage": "Uah basa ring kaca", diff --git a/languages/i18n/bg.json b/languages/i18n/bg.json index 485c9fe2a9..1a0775b08f 100644 --- a/languages/i18n/bg.json +++ b/languages/i18n/bg.json @@ -3219,13 +3219,13 @@ "dberr-again": "Изчакайте няколко минути и опитайте да презаредите.", "dberr-info": "(Няма достъп до базата от данни: $1)", "dberr-info-hidden": "(Няма връзка със сървъра на базата данни)", - "htmlform-invalid-input": "Има проблеми с част от въведения от вас вход", + "htmlform-invalid-input": "Има проблеми с част от въведения от вас текст", "htmlform-select-badoption": "Посочената от вас стойност не е валидна алтернатива.", "htmlform-int-invalid": "Въведената от вас стойност не е цяло число.", "htmlform-float-invalid": "Посочената стойност не е число.", "htmlform-int-toolow": "Посочената от вас стойност е под минимално допустимата $1.", "htmlform-int-toohigh": "Посочената от вас стойност надхвърля максимално допустимата $1.", - "htmlform-required": "Тази стойност се изисква", + "htmlform-required": "Тази стойност е задължителна.", "htmlform-submit": "Изпращане", "htmlform-reset": "Отказване на промените", "htmlform-selectorother-other": "Друга", diff --git a/languages/i18n/bn.json b/languages/i18n/bn.json index 224e4ae2bf..c5274a3cd1 100644 --- a/languages/i18n/bn.json +++ b/languages/i18n/bn.json @@ -87,6 +87,7 @@ "tog-useeditwarning": "কোনো সম্পাদনা পাতা ত্যাগের সময় পরিবর্তনগুলি সংরক্ষিত না হয়ে থাকলে আমাকে সাবধান করা হোক", "tog-prefershttps": "অ্যাকাউন্টে প্রবেশ করার সময় সবসময় নিরাপদ সংযোগ ব্যবহার করুন", "tog-showrollbackconfirmation": "একটি রোলব্যাক লিঙ্ক ক্লিক করার সময় একটি নিশ্চিতকরণ বার্তা দেখান", + "tog-requireemail": "পাসওয়ার্ড পুনঃস্থাপন করার জন্য ইমেল প্রয়োজন", "underline-always": "সব সময়", "underline-never": "কখনো নয়", "underline-default": "আবরণ বা ব্রাউজারে যেমনভাবে নির্দিষ্ট করা আছে", @@ -826,6 +827,7 @@ "undo-norev": "সম্পাদনাটি বাতিল করা যাচ্ছেনা কারণ এটি আর নেই বা মুছে ফেলা হয়েছে।", "undo-nochange": "সম্পাদনাটি পূর্বেই বাতিল করা হয়েছে।", "undo-summary": "[[Special:Contributions/$2|$2]] ([[User talk:$2|আলাপ]])-এর সম্পাদিত $1 নম্বর সংশোধনটি বাতিল করা হয়েছে", + "undo-summary-anon": "[[Special:Contributions/$2|$2]]-এর সম্পাদিত $1 নম্বর সংশোধনটি বাতিল করা হয়েছে", "undo-summary-username-hidden": "একজন লুকানো ব্যবহারকারীর করা $1 নং সংশোধনটি বাতিল করা হয়েছে", "cantcreateaccount-text": "[[User:$3|$3]] এই আইপি ঠিকানা('''$1''') থেকে অ্যাকাউন্ট সৃষ্টিতে বাধা দিয়েছেন।\n\n$3-এর দেয়া কারণ হল ''$2''", "cantcreateaccount-range-text": "[[User:$3|$3]] কর্তৃক আইপি ঠিকানার ব্যাপ্তি $1-এর মধ্যে অ্যাকাউন্ট তৈরি করা অবরুদ্ধ করা হয়েছে। যাতে আপনার আইপি ঠিকানাও ($4) রয়েছে। \n\n$3 কর্তৃক $2 কারণ দেখানো হয়েছে।", diff --git a/languages/i18n/cs.json b/languages/i18n/cs.json index e8c22b492d..7975de7bc8 100644 --- a/languages/i18n/cs.json +++ b/languages/i18n/cs.json @@ -92,6 +92,7 @@ "tog-useeditwarning": "Upozornit, když budu opouštět editaci bez uložení změn", "tog-prefershttps": "Po přihlášení vždy používat zabezpečené připojení", "tog-showrollbackconfirmation": "Při kliknutí na odkaz pro vrácení editace zobrazit žádost o potvrzení", + "tog-requireemail": "Pro obnovu hesla vyžadovat e-mail", "underline-always": "Vždy", "underline-never": "Nikdy", "underline-default": "Podle nastavení prohlížeče nebo vzhledu", @@ -2574,6 +2575,7 @@ "ipblocklist-legend": "Hledat zablokovaného uživatele", "blocklist-userblocks": "Skrýt zablokované účty", "blocklist-tempblocks": "Skrýt dočasná zablokování", + "blocklist-indefblocks": "Skrýt zablokování do odvolání", "blocklist-addressblocks": "Skrýt blokování jedné IP adresy", "blocklist-type": "Typ:", "blocklist-type-opt-all": "Vše", diff --git a/languages/i18n/diq.json b/languages/i18n/diq.json index b64046bcf5..bfed4357d2 100644 --- a/languages/i18n/diq.json +++ b/languages/i18n/diq.json @@ -1923,7 +1923,7 @@ "checkbox-all": "Pêro", "checkbox-none": "Çıniyo", "checkbox-invert": "Dimlaşt ke", - "allpages": "Perri pêro", + "allpages": "Peli pêro", "nextpage": "Pela bahdoyêne ($1)", "prevpage": "Pela veri ($1)", "allpagesfrom": "Herfa kı pa liste bo:", diff --git a/languages/i18n/dty.json b/languages/i18n/dty.json index 9ea6ec5dc0..28fee085e6 100644 --- a/languages/i18n/dty.json +++ b/languages/i18n/dty.json @@ -37,7 +37,7 @@ "tog-shownumberswatching": "निगरानी गरिरहेका प्रयोगकर्ताहरूको संख्या धेखाउन्या", "tog-oldsig": "तमरो अहिलको हस्ताक्षर:", "tog-fancysig": "मेरा दस्तखतलाई विकि पाठको रुपमी लिने (स्वत लिङ्क बिना)", - "tog-uselivepreview": "प्रत्यक्ष पैल्लीकोरुप प्रयोग गर", + "tog-uselivepreview": "पृष्ठ पुनर्भरण नअरेइ पूर्वावलोकन धेकाः", "tog-forceeditsummary": "खाली सम्पादन शीर्षक प्रविष्टि गरेपछा मलाई सोधन्या", "tog-watchlisthideown": "मेरा सम्पादनहरू निगनारी सूचीबठेई लुकाऊन्या", "tog-watchlisthidebots": "बोट सम्पादनहरू ध्यान सूचीबठेई लुकाउन्या", @@ -53,6 +53,7 @@ "tog-norollbackdiff": "पैलास्थितिमी फर्काएपछा भिन्नता हटाउन्या", "tog-useeditwarning": "सम्पादनहरू सङ्ग्रह नगरिएका अवस्थामी अर्को पानामी जान खोज्या चेतावनी धेखाउन्या", "tog-prefershttps": "प्रवेश गरन्ज्या जबलै सुरक्षित जडानको प्रयोग गर्न्या", + "tog-requireemail": "पासवर्ड पुनःचयन खिलाइ इमेल चायीन्छ", "underline-always": "जबलै", "underline-never": "कभैई नाई", "underline-default": "खोल और ब्राउजर निर्धारित", @@ -141,6 +142,8 @@ "index-category": "क्रमाङ्कित पानाहरू", "noindex-category": "अनुक्रमित नअरियाऽ पन्नाअन", "broken-file-category": "टुटेको फाइल लिङ्कहरूसितको पाना", + "categoryviewer-pagedlinks": "($1) ($2)", + "category-header-numerals": "$1–$2", "about": "बारेमी", "article": "सामाग्री पानो", "newwindow": "(नौलो विन्डोमी खुलन्छ)", @@ -161,6 +164,7 @@ "returnto": "$1 मी फर्क।", "tagline": "{{SITENAME}} बठेइ", "help": "मद्दत", + "help-mediawiki": "मिडियाविकि का बारेमी मद्दत", "search": "खोजी", "search-ignored-headings": " #
\n# Headings that will be ignored by search.\n# Changes to this take effect as soon as the page with the heading is indexed.\n# You can force page reindexing by doing a null edit.\n# The syntax is as follows:\n#   * Everything from a \"#\" character to the end of the line is a comment.\n#   * Every non-blank line is the exact title to ignore, case and everything.\nReferences\nExternal links\nSee also\n #
", "searchbutton": "खोज:", @@ -207,14 +211,14 @@ "redirectto": "पठाएको पाना:", "lastmodifiedat": "यै पन्नालाई छाड्डीबार $1मी $2 बजे सम्पादन गरियाऽ थ्यो।", "viewcount": "यो पाना हेरियाको थियो {{PLURAL:$1|एकपटक|$1 पटक}}", - "protectedpage": "सुरक्षित गर्याका पानाहरू", + "protectedpage": "सुरक्षित गरियाका पन्नाअन", "jumpto": "यैमी फट्टाक:", "jumptonavigation": "भ्रमण गरऽ", "jumptosearch": "खोजऽ", "view-pool-error": "माफ गर्या , अहिल सर्भरहरूमी कामको भार भौत रह्या छ।\nभौत भौत प्रयोगकर्ताहरू यै पाना हेद्या प्रयास गरी रह्या छन्।\nकृपया यो पाना पुन: हेर्नु अगाडि थोक्कै पख ।\n\n$1", "generic-pool-error": "माफ गर्या , अहिल सर्भरहरूमी कामको भार भौत रह्या छ।\nभौत भौत प्रयोगकर्ताहरू यै पाना हेद्या प्रयास गरी रह्या छन् ।\nकृपया यो पाना पुन: हेर्नु अगाडि थोक्कै पख ।", - "pool-timeout": "समय सकियो बन्द गर्ने प्रतीक्षामी", - "pool-queuefull": "प्रतीक्षा पङ्क्ति भरियो", + "pool-timeout": "बन्द गद्दाइ समयसीमा सकीन्या प्रतिक्षा मी", + "pool-queuefull": "प्रतिक्षा पङ्क्ति भरियो", "pool-errorunknown": "अज्ञात गल्ती", "pool-servererror": "पुल काउन्टर सेवा उपलब्ध नाइथिन् ($1)।", "poolcounter-usage-error": "प्रयोग गल्ती:$1", @@ -241,6 +245,9 @@ "versionrequired": "MediaWiki संस्करण $1 चाईन्या", "versionrequiredtext": "ये पाना प्रयोग गर्नका लागि MediaWiki $1 संस्करण चाहिन्छ ।\nहेर [[Special:Version|version page]]", "ok": "भयो", + "pagetitle": "$1 - {{SITENAME}}", + "pagetitle-view-mainpage": "{{SITENAME}}", + "backlinksubtitle": "← $1", "retrievedfrom": " \"$1\" बठे निकालियाऽ", "youhavenewmessages": "{{PLURAL:$3|तम सित छन}} $1 ($2)।", "youhavenewmessagesfromusers": "{{PLURAL:$3|अर्खा प्रयोगकर्ता|$3 प्रयोगकर्ताअन}} ($2) मी है {{PLURAL:$4|तम सित}} $1 छन।", @@ -272,6 +279,7 @@ "site-atom-feed": "$1 एटम फीड", "page-rss-feed": "\"$1\" आरएसएस फिड", "page-atom-feed": "\"$1\" एटम फिड", + "feed-rss": "आरएसएस", "red-link-title": "$1 (पन्ना उपलब्ध नाइँथिन)", "sort-descending": "अवरोहण क्रममी मिलाउन्या", "sort-ascending": "आरोहण क्रममी मिलाउन्या", @@ -322,6 +330,7 @@ "badarticleerror": "यो कार्य यै पनामी गर्न नाईंमिल्लो।", "cannotdelete": "\"$1\" पाना वा फाइल मेट्ट सकिएन।\nयो पैल्लीबठे मेटियाको हुनु पडन्छ।", "cannotdelete-title": "पाना \"$1\" लाई मेट्टू सकिएन", + "delete-scheduled": "$1 पन्ना मेटौनाइ खिलाइ समय निर्धारित अरीरैछ।\nकृपया धीरज राखः।", "delete-hook-aborted": "हुकले सम्पादनकार्य बन्द गरिदियो ।\nकोइ कारण दिइएन ।", "no-null-revision": "$1 पाना लागि खालि पुनरावलोकन सिर्जना गर्न सकिएन", "badtitle": "गलत शीर्षक", @@ -359,6 +368,7 @@ "ns-specialprotected": "विशेष पृष्ठहरू सम्पादन अद्दु नाइँ सकिनो।", "titleprotected": "[[User:$1|$1]]द्वारा ये शीर्षक निर्माणहुनबठे जोगाइया छ।\nकारण $2 हो ।", "filereadonlyerror": "\"$1\" फाइललाई परिवर्तन अद्दु नाइँ सकिनो क्याईकि फाइल भण्डार \"$2\" केवल पड्ड्या स्थिति (read-only mode)मी छ।\n\nयेलाई सुरक्षित अद्द्या प्रवन्धकले यो कारण दीराइछ: ''$3''।", + "invalidtitle": "अमान्य शीर्षक", "invalidtitle-knownnamespace": "\"$2\" नाउँबार रे \"$3\" पाठ भया: अमान्य शीर्षक", "invalidtitle-unknownnamespace": "अपछ्याणो नाउँबार अङ्क $1 रे पाठ \"$2\" भया: अमान्य शीर्षक", "exception-nologin": "प्रवेश (लग ईन) नगरिएको", @@ -368,6 +378,8 @@ "virus-scanfailed": "जँचाई असफल(कोड $1)", "virus-unknownscanner": "थानभया एन्टीभाइरस:", "logouttext": "तमी अहिल बाहिर निस्क्याका छौ।\n\nयाद राख्या तमीले ब्राउजरको क्याच खालि नगर्यासम्म कुनै पानाहरूमी तमी अझैं प्रवेश गरिरख्याको धेकाउन सक्छ।", + "logging-out-notify": "तम लगआउट हुन्नाछः, पख्याः हाँ।", + "logout-failed": "अइल लगआउट नाइहोइसकियो: $1", "cannotlogoutnow-title": "अईल भाईर निकल्ल नाइँ पाईनो", "cannotlogoutnow-text": "भाईर निकल्ल असंभव छ जब प्रयोग $1", "welcomeuser": "$1स्वागत छ!", @@ -444,6 +456,7 @@ "mailmypassword": "पासवर्ड पूर्वनिर्धारित गर", "passwordremindertitle": "{{SITENAME}}का लागि नयाँ अस्थायी पासवर्ड", "passwordremindertext": "कसैले (सायद तमी, IP ठेगाना $1 बाट), {{SITENAME}}($4) को लागि नौलो पासवर्ड अनुरोध गर्या छ । प्रयोगकर्ता \"$2\" को लागि नौलो अस्थायी पासवर्ड \"$3\"तयार पारिया छ । यदि यो तमरो इच्छामी भयाको भया अहिले तमीले लगइन गरीबर नौलो पासवर्ड छान्नु पड्ड्या हुन्छ ।\nतमरो अस्थायी पासवर्ड {{PLURAL:$5|एक दिन|$5 दिनहरू पछि}} अमान्य हुन्याछ ।\n\nयदि कोही अरुले नै अनुरोध गर्याको हो भण्या , या तमीले आफ्नो पासवर्ड सम्झ्यौ भण्या, अथवा\nत्यैलाई परिवर्तन गर्न चाहन्नौ भण्या, तमीले यो सन्देसको वेवास्ता गद्दसक्द्याहौ र पुरानै पासवर्ड प्रयोग गरिरहन सक्द्याहौ ।", + "noemailcreate": "तम ले मान्य इमेल ठिगाना दिन आवश्यक छ।", "blocked-mailpassword": "तमरा IP ठेगानालाई सम्पादन गद्द बठे रोक लाइराइछ। दुरुपयोग रोक्दाइ, तमरा IP ठेगाना बठेइ प्रवेसशब्द पुनर्लाभ प्रक्रिया प्रयोग अद्द्या अनुमति आथिन।", "mailerror": " चिठी :$1 पठाउँदा गल्ती भयो", "noemailprefs": "निम्न सुविधाहरू राम्डरी काम गद्दको लागि तमरो रोजाईमी आफ्नो ई-मेल ठेगाना खुलाओ ।", @@ -556,7 +569,7 @@ "anoneditwarning": "चेतावनी: तमले प्रवेश अरेको नाइथिन । तमरो आइपि ठेगाना पाना सम्पादन इतिहासमि दर्ता गरिन्या छ र यो सब्बैले हेद्द सक्कान । यदि तमलाईँ [$1 लगईन] वा [$2 नयाँ खाता बनाउन्या] गर्याभण्या तमबठे गरियाको सम्पादन तमरो प्रयोगकर्तानाममि जोडिन्याछ ।", "missingsummary": "'''यादगर्या :''' तमीले सम्पादन सारांश दियाका छैनौ ।\nयदि तमीले \"$1\" थिच्यौ भण्या , सारांश बिना नै सङ्ग्रहित गरिन्या छ ।", "selfredirect": "चेतावनी: तम यै पानालाई आफुमी पुनः निर्देशित गद्द लाग्याछौ ।\nहुनसक्छ तम अनुप्रेषितको लागि गलत लक्ष्य निर्दिष्ट गद्द लाग्याछौ, वा गलत पानाको सम्पादन गद्द लाग्याछौ ।\nतम पुनः एकपल्ट \"$1\" क्लिक गद्दाछौ, पुनः निर्देशित तसै लै बनाइन्याछ।", - "missingcommenttext": "कृपया तलतिर टिप्पणी राख ।", + "missingcommenttext": "कृपया टिप्पणी राखः।", "missingcommentheader": "'''याद गर :''' तमले टिप्पणीमी विषय /शीर्ष पंक्ति दियाका छैनौ ।\nतमले फेरि \"$1\" थिच्यौ भण्या , तमरो सम्पादन यसै रुपमी संग्रहित हुन्याछ ।", "summary-preview": "सम्पादन सारांशोः पूर्वालोकन:", "subject-preview": "विषयोः पूर्वरुप:", @@ -658,12 +671,12 @@ "page_first": "पैल्लो", "page_last": "छाड्डीबारको", "histlegend": "अन्तर चयन:संशोधनहरूको तुलनाको लागि रेडियो बाकसमी क्लिक गरिबर इण्टर गर अथवा तल दियाको बटनमी थिच
\nलिजेंड: (चालू): '''({{int:cur}})''' = अवतरणको बीचमी अन्तर, '''({{int:last}})''' = पैल्लीका अवतरणको बीचमी अन्तर, '''{{int:minoreditletter}}''' = नानो परिवर्तन।", - "history-fieldset-title": "संशोधनअन खिलाइ खोजऽ", + "history-fieldset-title": "संशोधनअन छानः", "history-show-deleted": "संशोधन मेटियाको मात्तरै", "histfirst": "सबहै पुरानो", "histlast": "नयाँ", "historysize": "({{PLURAL:$1|१ अक्षर|$1 अक्षरहरू}})", - "historyempty": "(खाली)", + "historyempty": "खालि", "history-feed-title": "पुनरावलोकन इतिहास", "history-feed-description": "विकीमा यो पानको पुनरावलोकन इतिहास", "history-feed-item-nocomment": "$1 $2मी", @@ -672,7 +685,7 @@ "rev-deleted-user": "(प्रयोगकर्ता नाम हटाइयो)", "rev-deleted-event": "(लग विवरण हटाइयो)", "rev-suppressed-text-unhide": "यै पानाको पुनरावलोकन '''दमन''' गरियाको छ ।\nविस्तृत जानकारी [{{fullurl:{{#Special:Log}}/delete|पानो={{FULLPAGENAMEE}}}} दमन लग] पाउन सकिन्छ ।\nयदि तम अगाडि बढ्ड चाहन्छौ भण्या पनि तमीले [$1 यि संशोधनहरू हेद्द] पाउन्या हौ ।", - "rev-delundel": "दधेखाउने/लुकाउन्या", + "rev-delundel": "दृश्यता बदेलः", "rev-showdeleted": "धेकाउन्या", "revisiondelete": "पुनरावलोकनअन मेट्याऽ/मेट्याऽ रद्द अद्द्या", "revdelete-nooldid-title": "अमान्य पुनरावलोकन लक्ष", @@ -806,7 +819,7 @@ "prefs-editwatchlist-clear": "तमरो अवलोकनसूची मेटा", "prefs-watchlist-days": "ध्यान सूचीमी धेकाउने दिनहरू:", "prefs-watchlist-days-max": "बर्ती है बर्ती $1 {{PLURAL:$1|दिन|दिनअन}}", - "prefs-watchlist-edits": "उच्चतम परिवर्तन संख्या बढाइएको निगरानी सूचीमी धकाउनका लागि :", + "prefs-watchlist-edits": "अवलोकनसूची मी धेकौना परिवर्तनअन को उच्चतम संख्या:", "prefs-watchlist-edits-max": "सबै है ज्यादा संख्या : १०००", "prefs-watchlist-token": "अवलोकन सूची टोकन:", "prefs-misc": "साधारण", @@ -840,14 +853,14 @@ "timezoneregion-europe": "युरोप", "timezoneregion-indian": "हिन्द महासागर", "timezoneregion-pacific": "प्राशान्त महासागर", - "allowemail": "और प्रयोगकर्ताबठे पौन्या ईमेल सक्षम गर।", + "allowemail": "और प्रयोगकर्ताअन लाइ मुइ लाइ ईमेल पठौनेइ अनुमति दिय", "prefs-searchoptions": "खोज", "prefs-namespaces": "नामठौर:", "default": "पूर्वनिर्धारित", "prefs-files": "फाइलहरू", "prefs-custom-css": "अनुकुलित CSS", "prefs-custom-js": "अनुकुल जाभास्क्रिप्ट", - "prefs-common-config": "साझा CSS/जाभा स्क्रिप्ट सबै कि लेखा:", + "prefs-common-config": "सबै खोलअन खिलाइ साझा सीएसएस/जेसन/जावास्क्रिप्ट:", "prefs-reset-intro": "तम ये पृष्ठलाई आफनो अभिरुचीहरू साइट पूर्वावस्थामी फर्काउनत फर्काउन प्रयोग गद्दु सकन्छौ । तै पाछा ये लाई रद्द गद्दु सकन्छौ ।", "prefs-emailconfirm-label": "इ-मेल एकिन प्रक्रिया:", "youremail": "ईमेल", @@ -915,7 +928,7 @@ "grouppage-bureaucrat": "{{ns:project}}:प्रशासकअन", "grouppage-suppress": "{{ns:project}}:लुकौन्या", "right-read": "पृष्ठहरू पढ", - "right-edit": "पृष्ठहरू सम्पादन गर", + "right-edit": "पन्नाअन सम्पादन गरः", "right-createpage": "पृष्ठ निर्माण गर(छलफल पृष्ठहरू बाहेक)", "right-createtalk": "छलफल पृष्ठ सृजना गर", "right-createaccount": "नयाँ प्रयोगकर्ता खाता सृजना गर।", @@ -931,7 +944,7 @@ "right-reupload-own": "आफैले अपलोड गरया रई आया फाइल अधिलेखन गर्न्या", "right-reupload-shared": "साझा मिडिया भण्डारमी स्थानियरुपमी फाइलहरू अधिक्रमण गर्न्या", "right-upload_by_url": "URL बठे फाइल उर्ध्वभरण गर्ने", - "right-purge": "साइटको क्याश( cache) निश्चित नगरिकनै पर्ज(Purge) गर्ने", + "right-purge": "येइ पन्ना को साइट क्याश(cache) पर्ज(Purge) गरः", "right-writeapi": "लेखन API प्रयोग गद्य्या", "right-delete": "पृष्ठहरू मेट्ने", "right-bigdelete": "लामो इतिहास भयाका पानाहरू मेट्ट्या", @@ -953,8 +966,8 @@ "right-userrights-interwiki": "अन्य विकिहरूमी प्रयोगकर्ताहरूको अधिकार सम्पादन गद्या", "right-override-export-depth": "गहिराइ ५ सम्म लिंक गरियाका पानाहरू सहित निर्यात गद्या", "right-sendemail": "अन्य प्रयोगकर्तानलाई इमेल पठाउन्या", - "grant-editmycssjs": "तमरो प्रयोगकर्ता CSS/JavaScript सम्पादन गरऽ", - "grant-editmyoptions": "तमरा प्रयोगकर्ता अभिरुचीइनलाई सम्पादन गरऽ", + "grant-editmycssjs": "तमरो प्रयोगकर्ता CSS/JSON/JavaScript सम्पादन गरः", + "grant-editmyoptions": "तमरा प्रयोगकर्ता अभिरुचिइन रे जेसन(JSON) मिलान सम्पादन गरः", "grant-editmywatchlist": "तमरो अवलोकनसूची सम्पादन गर", "grant-editpage": "भैरया पृष्ठहरू सम्पादन गर", "grant-editprotected": "सुरक्षित पृष्ठ सम्पादन", @@ -985,7 +998,7 @@ "recentchanges-legend-heading": "आदर्श वाक्य:", "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} ([[Special:NewPages|नौला पानाको सूची]] यैलाई लै हेरिदिय)", "rcfilters-savedqueries-rename": "पुनर्नामकरण", - "rcfilters-savedqueries-remove": "हटाऽ", + "rcfilters-savedqueries-remove": "मेटः", "rcfilters-savedqueries-new-name-label": "नाउँ", "rcfilters-savedqueries-cancel-label": "रद्द", "rcfilters-filter-editsbyself-label": "तम हताँ अरियाऽ फेरबदेलाअन", @@ -993,7 +1006,7 @@ "rcfilters-filter-editsbyother-label": "अउर हताँ अरियाऽ फेरबदेलाअन", "rcfilters-filter-editsbyother-description": "तमरा आफ्फुनाइ बाहेक अउर सप्पै फेरबदेलाअन।", "rcfilters-filtergroup-lastrevision": "छाड्डीबारोः संशोधन", - "rcfilters-filter-lastrevision-label": "छाड्डीबारोः संशोधन", + "rcfilters-filter-lastrevision-label": "सबहै नौलो संशोधन", "rclistfrom": "$3 $2 देखिका नयाँ परिवर्तनहरू देखाउन्या", "rcshowhideminor": "$1 सानतिनो सम्पादन", "rcshowhideminor-show": "धेकाइदिय", @@ -1070,7 +1083,7 @@ "filehist-comment": "टिप्पणी", "imagelinks": "फाइल उपयोग", "linkstoimage": "यै चित्रमी निम्न{{PLURAL:$1|पाना जोडिनान{{PLURAL:$1|}}|$1 पानाहरू जोडिनान्}}:", - "nolinkstoimage": "यो चित्रसित लिंकभयाकि कोइ पाना नाइथी", + "nolinkstoimage": "येइ फाइल प्रयोग भयाः कोइ लै पन्ना नाइथिन।", "morelinkstoimage": "यै फाइलको [[Special:WhatLinksHere/$1|थप लिंकहरू]] हेर ।", "sharedupload-desc-here": "यो फाइल $1 बठे हो र और परियोजनाहरू बठे पन प्रयोग गद्द सकिन्याछ । \nताखाइ यैको [$2 फ़ाइल विवरण पानो]मि रयाका विवरण तल्तिर दियाको छ।", "filepage-nofile": "येइ नाउँ को कोइ लै फाइल नाइथिन।", @@ -1301,7 +1314,7 @@ "tooltip-rollback": "\"पूर्वरुप\" ले यो पानाक्क सम्पादन(हरू) खारेज अरिबरे पानालाई एक क्लिकमि पाछाडीको सम्पादनमि पुगाइदिन्छ ।", "tooltip-undo": "\"रद्द\"ले पछिल्लो सम्पादन खारेज गरिबरे पूर्वावलोकनमा धेकाउछ ।\nयैले सारांशमा कारण राख्ख दिन्याछ।", "tooltip-summary": "नानो सारांश हालिदिय", - "siteusers": "{{SITENAME}} {{PLURAL:$2|प्रयोगकर्ता|प्रयोगकर्ताहरू}} $1", + "siteusers": "{{SITENAME}} {{PLURAL:$2|{{GENDER:$1|प्रयोगकर्ता}}|प्रयोगकर्ताअन}} $1", "anonusers": "{{SITENAME}} का नाम नभयाका {{PLURAL:$2| प्रयोगकर्ता|प्रयोगकर्ताहरू}} $1", "simpleantispam-label": "ऐन्टी-स्प्याम जाँच।\nयैलाई नाइँ भद्य्या!", "pageinfo-title": "\"$1\" खिलाइ जानकारी", @@ -1366,7 +1379,7 @@ "imgmultipagenext": "अर्खो पन्ना →", "imgmultigo": "जाऽ!", "imgmultigoto": "$1 पन्ना मैं जाऽ", - "size-bytes": "$1 अक्षरहरू", + "size-bytes": "$1 {{PLURAL:$1|बाइट|बाइटअन}}", "size-kilobytes": "$1 किलोबाइट", "size-megabytes": "$1 मेगाबाइट", "size-gigabytes": "$1 गिगाबाइट", diff --git a/languages/i18n/en.json b/languages/i18n/en.json index 9c4f508893..82826c513f 100644 --- a/languages/i18n/en.json +++ b/languages/i18n/en.json @@ -2696,6 +2696,7 @@ "ipblocklist-legend": "Find a blocked user", "blocklist-userblocks": "Hide account blocks", "blocklist-tempblocks": "Hide temporary blocks", + "blocklist-indefblocks": "Hide indefinite blocks", "blocklist-addressblocks": "Hide single IP blocks", "blocklist-type": "Type:", "blocklist-type-opt-all": "All", diff --git a/languages/i18n/exif/nb.json b/languages/i18n/exif/nb.json index d2c74f5c32..ae5341684a 100644 --- a/languages/i18n/exif/nb.json +++ b/languages/i18n/exif/nb.json @@ -272,6 +272,12 @@ "exif-scenetype-1": "Direktefotografert bilde", "exif-customrendered-0": "Normal prosess", "exif-customrendered-1": "Tilpasset prosess", + "exif-customrendered-2": "HDR (ingen original lagret)", + "exif-customrendered-3": "HDR (original lagret)", + "exif-customrendered-4": "Original (for HDR)", + "exif-customrendered-6": "Panorama", + "exif-customrendered-7": "Portrett-HDR", + "exif-customrendered-8": "Portrett", "exif-exposuremode-0": "Automatisk eksponering", "exif-exposuremode-1": "Manuell eksponering", "exif-exposuremode-2": "Automatisk alternativeksponering", diff --git a/languages/i18n/fi.json b/languages/i18n/fi.json index 994b1e1de5..2869768e43 100644 --- a/languages/i18n/fi.json +++ b/languages/i18n/fi.json @@ -3531,7 +3531,7 @@ "logentry-partialblock-block-page": "{{PLURAL:$1|sivua|sivuja}} $2", "logentry-partialblock-block-ns": "{{PLURAL:$1|nimiavaruutta|nimiavaruuksia}} $2", "logentry-partialblock-block": "$1 {{GENDER:$2|esti}} käyttäjää {{GENDER:$4|$3}} muokkaamasta $7. Eston kesto on $5 $6", - "logentry-partialblock-reblock": "$1 {{GENDER:$2|muutti}} käyttäjän {{GENDER:$4|$3}} muokkauseston asetuksia estäen muokkausten tekemisen $7. Eston kesto on $5 $6", + "logentry-partialblock-reblock": "$1 {{GENDER:$2|muutti}} käyttäjän {{GENDER:$4|$3}} muokkauseston asetuksia niin, että hän ei voi muokata $7. Eston kesto on $5 $6", "logentry-non-editing-block-block": "$1 {{GENDER:$2|esti}} käyttäjää {{GENDER:$4|$3}} suorittamasta määrättyjä toimenpiteitä (lukuun ottamatta muokkaamista). Eston kesto on $5 $6", "logentry-non-editing-block-reblock": "$1 {{GENDER:$2|muutti}} käyttäjän {{GENDER:$4|$3}} toimintaeston asetuksia, jotka koskevat määrättyjä toimenpiteitä. Eston kesto on $5 $6", "logentry-suppress-block": "$1 {{GENDER:$2|esti}} käyttäjän {{GENDER:$4|$3}}. Eston kesto on $5 $6", diff --git a/languages/i18n/fr.json b/languages/i18n/fr.json index 41b229309a..2e6ccf1481 100644 --- a/languages/i18n/fr.json +++ b/languages/i18n/fr.json @@ -218,6 +218,7 @@ "tog-useeditwarning": "M’avertir quand je quitte une page en cours de modification sans avoir sauvegardé", "tog-prefershttps": "Toujours utiliser une connexion sécurisée lorsque je suis connecté", "tog-showrollbackconfirmation": "Afficher une demande de confirmation en cliquant sur un lien d’annulation", + "tog-requireemail": "Nécessiter un courriel pour les réinitialisations de mot de passe", "underline-always": "Toujours", "underline-never": "Jamais", "underline-default": "Valeur par défaut du thème ou du navigateur", @@ -611,7 +612,7 @@ "badretype": "Les mots de passe que vous avez saisis ne correspondent pas.", "usernameinprogress": "Une création de compte pour ce nom d’utilisateur est déjà en cours.\nVeuillez patienter.", "userexists": "Le nom d’utilisateur saisi est déjà utilisé.\nVeuillez choisir un nom différent.", - "createacct-normalization": "Votre nom d’utilisateur sera modifié en « $2 » à cause de restrictions techniques.", + "createacct-normalization": "Votre nom d’utilisateur sera modifié en « $2 » à cause de restrictions techniques.", "loginerror": "Erreur de connexion", "createacct-error": "Erreur lors de la création du compte", "createaccounterror": "Impossible de créer le compte : $1", @@ -623,7 +624,7 @@ "noname": "Vous n’avez pas saisi un nom d’utilisateur valide.", "loginsuccesstitle": "Connecté", "loginsuccess": "Vous êtes maintenant connecté{{GENDER:$1||e|(e)}} à {{SITENAME}} en tant que « $1 ».", - "nosuchuser": "L’utilisateur « $1 » n’existe pas.\nLes noms d’utilisateur sont sensibles à la casse.\nVérifiez l’orthographe, ou [[Special:CreateAccount|créez un nouveau compte]].", + "nosuchuser": "L’utilisateur « $1 » n’existe pas.\nLes noms d’utilisateur sont sensibles à la casse.\nVérifiez l’orthographe ou [[Special:CreateAccount|créez un nouveau compte]].", "nosuchusershort": "Il n’y a pas de contributeur avec le nom « $1 ».\nVeuillez vérifier l’orthographe.", "nouserspecified": "Vous devez saisir un nom d’utilisateur.", "login-userblocked": "{{GENDER:$1|Cet utilisateur|Cette utilisatrice}} est bloqué{{GENDER:$1||e}}. La connexion n’est pas autorisée.", @@ -637,7 +638,7 @@ "password-login-forbidden": "L’utilisation de ce nom d’utilisateur ou de ce mot de passe a été interdite.", "mailmypassword": "Réinitialiser le mot de passe", "passwordremindertitle": "Nouveau mot de passe temporaire pour {{SITENAME}}", - "passwordremindertext": "Quelqu’un (depuis l’adresse IP $1) a demandé un nouveau mot de\npasse pour {{SITENAME}} ($4). Un mot de passe temporaire pour l’utilisateur\n« $2 » a été créé et défini comme « $3 ». Si c’était bien votre intention,\nvous devrez vous connecter et choisir un nouveau mot de passe.\nVotre mot de passe temporaire expirera dans $5 jour{{PLURAL:$5||s}}.\n\nSi vous n’êtes pas l’auteur de cette demande, ou si vous vous avez retrouvé votre mot de passe et ne souhaitez plus en changer, vous pouvez ignorer ce message\net continuer à utiliser votre ancien mot de passe.", + "passwordremindertext": "Quelqu’un (depuis l’adresse IP $1) a demandé un nouveau mot de passe\npour {{SITENAME}} ($4). Un mot de passe temporaire pour l’utilisateur\n« $2 » a été créé et défini comme « $3 ». Si c’était bien votre intention,\nvous devrez vous connecter et choisir un nouveau mot de passe.\nVotre mot de passe temporaire expirera dans $5 jour{{PLURAL:$5||s}}.\n\nSi vous n’êtes pas l’auteur de cette demande ou si vous vous avez retrouvé votre\nmot de passe et ne souhaitez plus en changer, vous pouvez ignorer ce message et\ncontinuer à utiliser votre ancien mot de passe.", "noemail": "Aucune adresse de courriel n’a été enregistrée pour l’utilisat{{GENDER:$1|eur|rice}} « $1 ».", "noemailcreate": "Vous devez fournir une adresse de courriel valide", "passwordsent": "Un nouveau mot de passe a été envoyé à l’adresse de courriel de l’utilisat{{GENDER:$1|eur|rice}} « $1 ».\nVeuillez vous reconnecter après l’avoir reçu.", @@ -699,8 +700,8 @@ "botpasswords-help-grants": "Les autorisations permettent d’accéder aux droits déjà accordés à votre compte utilisateur. Activer une autorisation ici ne fournit l’accès à aucun droit que votre compte utilisateur n’aurait pas par ailleurs. Voyez le [[Special:ListGrants|tableau des autorisations]] pour plus d’informations.", "botpasswords-label-grants-column": "Accordé", "botpasswords-bad-appid": "Le nom de robot « $1 » n’est pas valide.", - "botpasswords-insert-failed": "Échec de l’ajout du nom de robot « $1 ». A-t-il déjà été ajouté ?", - "botpasswords-update-failed": "Échec à la mise à jour du nom de robot « $1 ». A-t-il déjà été supprimé ?", + "botpasswords-insert-failed": "Échec de l’ajout du nom de robot « $1 ». A-t-il déjà été ajouté ?", + "botpasswords-update-failed": "Échec à la mise à jour du nom de robot « $1 ». A-t-il déjà été supprimé ?", "botpasswords-created-title": "Mot de passe de robots créé", "botpasswords-created-body": "Le mot de passe pour le robot « $1 » de l’{{GENDER:$2|utilisateur|utilisatrice}} « $2 » a été créé.", "botpasswords-updated-title": "Mot de passe de robots mis à jour", @@ -710,9 +711,9 @@ "botpasswords-newpassword": "Le nouveau mot de passe pour se connecter à $1 est $2. Veuillez l’enregistrer pour y faire référence ultérieurement.
(Pour les anciens robots qui nécessitent que le nom fourni à la connexion soit le même que le nom d'utilisateur éventuel, vous pouvez aussi utiliser $3 comme nom d'utilisateur et $4 comme mot de passe).", "botpasswords-no-provider": "BotPasswordsSessionProvider n’est pas disponible.", "botpasswords-restriction-failed": "Les restrictions de mot de passe de robots empêchent cette connexion.", - "botpasswords-invalid-name": "Le nom d’utilisateur spécifié ne contient pas de séparateur de mot de passe de robots (« $1 »).", - "botpasswords-not-exist": "L’utilisat{{GENDER:$1|eur|rice}} « $1 » n’a pas de mot de passe de robot nommé « $2 ».", - "botpasswords-needs-reset": "Le mot de passe du robot nommé « $2 » de l’utilisat{{GENDER:$1|eur|rice}} « $1 » doit être réinitialisé.", + "botpasswords-invalid-name": "Le nom d’utilisateur spécifié ne contient pas de séparateur de mot de passe de robots (« $1 »).", + "botpasswords-not-exist": "L’utilisat{{GENDER:$1|eur|rice}} « $1 » n’a pas de mot de passe de robot nommé « $2 ».", + "botpasswords-needs-reset": "Le mot de passe du robot nommé « $2 » de l’utilisat{{GENDER:$1|eur|rice}} « $1 » doit être réinitialisé.", "botpasswords-locked": "Vous ne pouvez pas vous connecter avec un mot de passe de robot, car votre compte est bloqué.", "resetpass_forbidden": "Les mots de passe ne peuvent pas être changés", "resetpass_forbidden-reason": "Les mots de passe ne peuvent pas être modifiés : $1", @@ -725,9 +726,9 @@ "resetpass-temp-password": "Mot de passe temporaire :", "resetpass-abort-generic": "La modification du mot de passe a été annulée par une extension.", "resetpass-expired": "Votre mot de passe a expiré. Veuillez en fournir un nouveau pour vous connecter.", - "resetpass-expired-soft": "Votre mot de passe a expiré, et doit être modifié. Veuillez en choisir un nouveau maintenant ou cliquer sur « {{int:authprovider-resetpass-skip-label}} » pour le faire plus tard.", + "resetpass-expired-soft": "Votre mot de passe a expiré, et doit être modifié. Veuillez en choisir un nouveau maintenant ou cliquer sur « {{int:authprovider-resetpass-skip-label}} » pour le faire plus tard.", "resetpass-validity": "Votre mot de passe est non valide : $1\n\nVeuillez entrer un nouveau mot de passe pour vous connecter.", - "resetpass-validity-soft": "Votre mot de passe n’est pas valide : $1\n\nVeuillez choisir un nouveau mot de passe maintenant, ou cliquez sur « {{int:authprovider-resetpass-skip-label}} » pour le modifier plus tard.", + "resetpass-validity-soft": "Votre mot de passe n’est pas valide : $1\n\nVeuillez choisir un nouveau mot de passe maintenant, ou cliquez sur « {{int:authprovider-resetpass-skip-label}} » pour le modifier plus tard.", "passwordreset": "Réinitialisation du mot de passe", "passwordreset-text-one": "Remplissez ce formulaire pour réinitialiser votre mot de passe.", "passwordreset-text-many": "{{PLURAL:$1|Remplissez un des champs pour recevoir un mot de passe temporaire par courriel.}}", @@ -799,21 +800,21 @@ "preview": "Prévisualisation", "showpreview": "Prévisualiser", "showdiff": "Voir les modifications", - "blankarticle": "Attention : la page que vous créez est vide.\nSi vous cliquez de nouveau sur « $1 », la page sera créée sans aucun contenu.", + "blankarticle": "Attention : la page que vous créez est vide.\nSi vous cliquez de nouveau sur « $1 », la page sera créée sans aucun contenu.", "anoneditwarning": "Attention : vous n’êtes pas connecté(e). Votre adresse IP sera visible de tout le monde si vous faites des modifications. Si vous [$1 vous connectez] ou [$2 créez un compte], vos modifications seront attribuées à votre propre nom d’utilisateur(rice) et vous aurez d’autres avantages.", "anonpreviewwarning": "Vous n’êtes pas connecté(e). Sauvegarder enregistrera votre adresse IP dans l’historique des modifications de la page.", "missingsummary": "Rappel : vous n’avez pas encore fourni le résumé de votre modification.\nSi vous cliquez de nouveau sur le bouton « $1 », vos modifications seront sauvegardées sans résumé.", - "selfredirect": "Attention : vous êtes en train de rediriger la page vers elle-même.\nIl se peut que vous ayez spécifié la mauvaise cible pour la redirection, ou que vous modifiez peut-être la mauvaise page.\nSi vous cliquez de nouveau sur « $1 », la redirection sera tout de même créée.", + "selfredirect": "Attention : vous êtes en train de rediriger la page vers elle-même.\nIl se peut que vous ayez spécifié la mauvaise cible pour la redirection, ou que vous modifiez peut-être la mauvaise page.\nSi vous cliquez de nouveau sur « $1 », la redirection sera tout de même créée.", "missingcommenttext": "Veuillez entrer un commentaire.", - "missingcommentheader": "Rappel : vous n’avez pas fourni de sujet pour ce commentaire.\nSi vous cliquez de nouveau sur « $1 », votre modification sera enregistrée sans sujet.", + "missingcommentheader": "Rappel : vous n’avez pas fourni de sujet pour ce commentaire.\nSi vous cliquez de nouveau sur « $1 », votre modification sera enregistrée sans sujet.", "summary-preview": "Aperçu du résumé de modification :", "subject-preview": "Aperçu du sujet :", "previewerrortext": "Une erreur s’est produite lors de la tentative de prévisualisation de vos modifications.", "blockedtitle": "L’utilisateur est bloqué.", "blocked-email-user": "Votre nom d’utilisateur a été bloqué pour l’envoi de courriels. Vous pouvez toujours modifier d’autres pages sur ce wiki. Vous pouvez voir tous les détails du blocage sur [[Special:MyContributions|contributions du compte]].\n\nCe blocage a été fait par $1.\n\nLe motif fourni est $2.\n\n* Début du blocage : $8\n* Expiration du blocage : $6\n* Cible souhaitée du blocage : $7\n* ID du blocage nº $5", "blockedtext-partial": "Votre nom d’utilisateur ou votre adresse IP a été bloqué pour effectuer des modifications sur cette page. Vous pouvez toujours modifier d’autres pages sur ce wiki. Vous pouvez voir tous les détails sur ce blocage sur [[Special:MyContributions|contributions du compte]].\n\nLe blocage a été effectué par $1.\n\nLe motif fourni est $2.\n\n* Début du blocage : $8\n* Expiration du blocage : $6\n* Cible souhaitée du blocage : $7\n* ID du blocage nº $5", - "blockedtext": "Votre compte utilisateur ou votre adresse IP a été bloqué.\n\nLe blocage a été effectué par $1.\nLa raison invoquée est la suivante : $2.\n\n* Début du blocage : $8\n* Expiration du blocage : $6\n* Compte bloqué : $7.\n\nVous pouvez contacter $1 ou un autre [[{{MediaWiki:Grouppage-sysop}}|administrateur]] pour en discuter.\nVous ne pouvez utiliser la fonction « {{int:emailuser}} » que si une adresse de courriel valide est spécifiée dans vos [[Special:Preferences|préférences]] et que si cette fonctionnalité ne vous a pas été bloquée.\nVotre adresse IP actuelle est $3 et votre identifiant de blocage est $5.\nVeuillez inclure tous les détails ci-dessus dans chacune des requêtes que vous ferez.", - "autoblockedtext": "Votre adresse IP a été bloquée automatiquement car elle a été utilisée par un autre utilisateur, lui-même bloqué par $1.\nLa raison invoquée est :\n\n: $2.\n\n* Début du blocage : $8\n* Expiration du blocage : $6\n* Compte bloqué : $7\n\nVous pouvez contacter $1 ou l’un des autres [[{{MediaWiki:Grouppage-sysop}}|administrateurs]] pour discuter de ce blocage.\n\nNotez que vous ne pourrez utiliser la fonctionnalité « {{int:emailuser}} » que si vous avez une adresse de courriel validée dans vos [[Special:Preferences|préférences]] et que cette fonctionnalité ne vous a pas été désactivée.\n\nVotre adresse IP actuelle est $3, et le numéro de blocage est $5.\nVeuillez inclure tous les détails ci-dessus dans chacune des requêtes que vous ferez.", + "blockedtext": "Votre compte utilisateur ou votre adresse IP a été bloqué.\n\nLe blocage a été effectué par $1.\nLa raison invoquée est la suivante : $2.\n\n* Début du blocage : $8\n* Expiration du blocage : $6\n* Compte bloqué : $7.\n\nVous pouvez contacter $1 ou un autre [[{{MediaWiki:Grouppage-sysop}}|administrateur]] pour en discuter.\nVous ne pouvez utiliser la fonction « {{int:emailuser}} » que si une adresse de courriel valide est spécifiée dans vos [[Special:Preferences|préférences]] et que si cette fonctionnalité ne vous a pas été bloquée.\nVotre adresse IP actuelle est $3 et votre identifiant de blocage est $5.\nVeuillez inclure tous les détails ci-dessus dans chacune des requêtes que vous ferez.", + "autoblockedtext": "Votre adresse IP a été bloquée automatiquement car elle a été utilisée par un autre utilisateur, lui-même bloqué par $1.\nLa raison invoquée est :\n\n: $2.\n\n* Début du blocage : $8\n* Expiration du blocage : $6\n* Compte bloqué : $7\n\nVous pouvez contacter $1 ou l’un des autres [[{{MediaWiki:Grouppage-sysop}}|administrateurs]] pour discuter de ce blocage.\n\nNotez que vous ne pourrez utiliser la fonctionnalité « {{int:emailuser}} » que si vous avez une adresse de courriel validée dans vos [[Special:Preferences|préférences]] et que cette fonctionnalité ne vous a pas été désactivée.\n\nVotre adresse IP actuelle est $3, et le numéro de blocage est $5.\nVeuillez inclure tous les détails ci-dessus dans chacune des requêtes que vous ferez.", "systemblockedtext": "Votre nom d'utilisateur ou votre adresse IP ont été bloqués automatiquement par MediaWiki.\nLa raison donnée est la suivante:\n\n: $2.\n\n* Le début du blocage: $8\n* Expiration du délai de blocage: $6\n* Elément concerné: $7\n\nVotre adresse IP actuelle est $3.\nVeuillez inclure tous les détails ci-dessus dans chacune des requêtes que vous ferez.", "blockednoreason": "aucune raison donnée", "blockedtext-composite": "Votre nom d'utilisateur ou votre adresse IP ont été bloqués.\n\nLa raison invoquée est :\n\n: $2.\n\n* Début du blocage : $8\n* Expiration du blocage le plus long : $6\n* $5\n\nVotre adresse IP actuelle est $3.\nVeuillez inclure tous les détails ci-dessus dans chaque demande que vous ferez.", @@ -834,27 +835,27 @@ "anontalkpagetext": "----\nVous êtes sur la page de discussion d’un utilisateur anonyme qui n’a pas encore créé de compte ou qui n’en utilise pas.\nPour cette raison, nous devons utiliser son adresse IP pour l'identifier.\nUne telle adresse IP peut être partagée par plusieurs utilisateurs.\nSi vous êtes un{{GENDER:||e|}} utilisat{{GENDER:|eur|rice|eur}} anonyme et si vous constatez que des commentaires qui ne vous concernent pas vous ont été adressés, vous pouvez [[Special:CreateAccount|créer un compte]] ou [[Special:UserLogin|vous connecter]] afin d’éviter toute confusion future avec d’autres contributeurs anonymes.", "noarticletext": "Il n’y a pour l’instant aucun texte sur cette page.\nVous pouvez [[Special:Search/{{PAGENAME}}|lancer une recherche sur ce titre]] dans les autres pages,\n[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} rechercher dans les opérations liées]\nou [{{fullurl:{{FULLPAGENAME}}|action=edit}} créer cette page].", "noarticletext-nopermission": "Il n’y a pour l’instant aucun texte sur cette page.\nVous pouvez [[Special:Search/{{PAGENAME}}|faire une recherche sur ce titre]] dans les autres pages,\nou [{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} rechercher dans les journaux associés], mais vous n’avez pas la permission de créer cette page.", - "missing-revision": "La révision nº $1 de la page intitulée « {{FULLPAGENAME}} » n’existe pas.\n\nCela survient en général en suivant un lien historique désuet vers une page qui a été supprimée.\nVous pouvez trouver plus de détails dans le [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} journal des suppressions].", + "missing-revision": "La révision nº $1 de la page intitulée « {{FULLPAGENAME}} » n’existe pas.\n\nCela survient en général en suivant un lien historique désuet vers une page qui a été supprimée.\nVous pouvez trouver plus de détails dans le [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} journal des suppressions].", "userpage-userdoesnotexist": "Le compte utilisateur « $1 » n’est pas enregistré. Veuillez vérifier que vous voulez créer cette page.", "userpage-userdoesnotexist-view": "Le compte utilisateur « $1 » n'est pas enregistré.", "blocked-notice-logextract": "Cet utilisateur est actuellement bloqué.\nLa dernière entrée du journal des blocages est affichée ci-dessous pour référence :", - "clearyourcache": "Note : après avoir enregistré vos modifications, il se peut que vous deviez forcer le rechargement complet du cache de votre navigateur pour voir les changements.\n* Firefox / Safari : maintenez la touche Maj (Shift) en cliquant sur le bouton Actualiser ou pressez Ctrl-F5 ou Ctrl-R (⌘-R sur un Mac) \n* Google Chrome : appuyez sur Ctrl-Maj-R (⌘-Shift-R sur un Mac) \n* Internet Explorer : maintenez la touche Ctrl en cliquant sur le bouton Actualiser ou pressez Ctrl-F5 \n* Opera : allez dans Menu → Settings (Opera → Préférences sur un Mac) et ensuite à Confidentialité & sécurité → Effacer les données d’exploration → Images et fichiers en cache.", + "clearyourcache": "Note : après avoir enregistré vos modifications, il se peut que vous deviez forcer le rechargement complet du cache de votre navigateur pour voir les changements.\n* Firefox / Safari : maintenez la touche Maj (Shift) en cliquant sur le bouton Actualiser ou pressez Ctrl-F5 ou Ctrl-R (⌘-R sur un Mac).\n* Google Chrome : appuyez sur Ctrl-Maj-R (⌘-Shift-R sur un Mac).\n* Internet Explorer : maintenez la touche Ctrl en cliquant sur le bouton Actualiser ou pressez Ctrl-F5.\n* Opera : allez dans Menu → Settings (Opera → Préférences sur un Mac) et ensuite à Confidentialité et sécurité → Effacer les données d’exploration → Images et fichiers en cache.", "usercssyoucanpreview": "Astuce : utilisez le bouton « {{int:showpreview}} » pour tester votre nouvelle feuille CSS avant de l’enregistrer.", - "userjsonyoucanpreview": "Conseil : utilisez le bouton « {{int:showpreview}} » pour tester votre nouveau JSON avant enregistrement.", + "userjsonyoucanpreview": "Conseil : utilisez le bouton « {{int:showpreview}} » pour tester votre nouveau JSON avant enregistrement.", "userjsyoucanpreview": "Astuce : utilisez le bouton « {{int:showpreview}} » pour tester votre nouvelle feuille JavaScript avant de l’enregistrer.", - "usercsspreview": "Rappelez-vous que vous ne faites que prévisualiser votre propre feuille CSS. \nElle n’a pas encore été enregistrée !", + "usercsspreview": "Rappelez-vous que vous ne faites que prévisualiser votre propre feuille CSS.\nElle n’a pas encore été enregistrée !", "userjsonpreview": "Rappelez-vous que vous êtes seulement en train de tester/voir un aperçu de votre configuration utilisateur JSON.\nElle n’a pas encore été enregistrée !", - "userjspreview": "Rappelez-vous que vous ne faites que visualiser ou tester votre code JavaScript.\nIl n’a pas encore été enregistré !", - "sitecsspreview": "Rappelez-vous que vous ne faites que prévisualiser cette feuille de style. \nElle n’a pas encore été enregistrée !", + "userjspreview": "Rappelez-vous que vous ne faites que visualiser ou tester votre code JavaScript.\nIl n’a pas encore été enregistré !", + "sitecsspreview": "Rappelez-vous que vous ne faites que prévisualiser cette feuille de style. \nElle n’a pas encore été enregistrée !", "sitejsonpreview": "Souvenez-vous que vous ne faites que regarder un aperçu de cette configuration JSON.\nElle n’a pas encore été enregistrée !", - "sitejspreview": "Rappelez-vous que vous ne faites que prévisualiser ce code JavaScript. \nIl n’a pas encore été enregistré !", - "userinvalidconfigtitle": "Attention : il n’existe pas d’habillage « $1 ».\nLes pages personnelles avec extensions .css, .json et .js utilisent des titres en minuscules, par exemple {{ns:user}}:Foo/vector.css et non {{ns:user}}:Foo/Vector.css.", + "sitejspreview": "Rappelez-vous que vous ne faites que prévisualiser ce code JavaScript.\nIl n’a pas encore été enregistré !", + "userinvalidconfigtitle": "Attention : il n’existe pas d’habillage « $1 ».\nLes pages personnelles avec extensions .css, .json et .js utilisent des titres en minuscules, par exemple {{ns:user}}:Foo/vector.css et non {{ns:user}}:Foo/Vector.css.", "updated": "(Mis à jour)", "note": "Note :", "previewnote": "Rappelez-vous que ce n’est qu’une prévisualisation.\nVos modifications n’ont pas encore été enregistrées !", "continue-editing": "Aller à la zone de modification", "previewconflict": "Cette prévisualisation montre le texte de la boîte supérieure de modification tel qu’il apparaîtra si vous choisissez de le publier.", - "session_fail_preview": "Désolé, nous ne pouvons enregistrer votre modification à cause d’une perte d’informations concernant votre session.\n\nVous avez peut-être été déconnecté. Veuillez vérifier que vous êtes toujours connecté et réessayer.\nSi cela échoue de nouveau, essayez en vous [[Special:UserLogout|déconnectant]], puis en vous reconnectant, et vérifiez que votre navigateur accepte les témoins (''cookies'') de ce site.", + "session_fail_preview": "Désolé, nous ne pouvons enregistrer votre modification à cause d’une perte d’informations concernant votre session.\n\nVous avez peut-être été déconnecté. Veuillez vérifier que vous êtes toujours connecté et réessayer.\nSi cela échoue de nouveau, essayez en vous [[Special:UserLogout|déconnectant]] puis en vous reconnectant. Vérifiez également que votre navigateur accepte les témoins (''cookies'') de ce site.", "session_fail_preview_html": "Désolé, nous ne pouvons enregistrer votre modification à cause d’une perte d’informations concernant votre session.\n\nParce que {{SITENAME}} a activé le HTML brut, la prévisualisation est masquée afin de prévenir les attaques par JavaScript.\n\nSi la tentative de modification est légitime, veuillez réessayer.\nSi cela échoue de nouveau, [[Special:UserLogout|déconnectez-vous]], puis reconnectez-vous, et vérifiez que votre navigateur accepte les témoins (''cookies'') de ce site.", "token_suffix_mismatch": "Votre modification n’a pas été acceptée car votre navigateur a mal codé les caractères de ponctuation dans l’identifiant de modification.\nCe rejet est nécessaire pour empêcher la corruption du texte de la page.\nCe problème se produit parfois lorsque vous utilisez un serveur mandataire anonyme problématique basé sur le web.", "edit_form_incomplete": "Certaines parties du formulaire de modification n’ont pas atteint le serveur, vérifiez que vos modifications sont intactes et essayez à nouveau.", @@ -863,21 +864,21 @@ "editingsection": "Modification de $1 (section)", "editingcomment": "Modification de $1 (nouvelle section)", "editconflict": "Conflit de modification : $1", - "explainconflict": "Cette page a été changée après que vous avez commencé à la modifier.\nLa zone de modification supérieure contient le texte tel qu’il est actuellement enregistré dans la base de données.\nVos modifications apparaissent dans la zone de modification inférieure.\nVous allez devoir fusionner vos modifications dans le texte existant.\nSeul le texte de la zone supérieure sera sauvegardé si vous cliquez sur « $1 ».", + "explainconflict": "Cette page a été changée après que vous avez commencé à la modifier.\nLa zone de modification supérieure contient le texte tel qu’il est actuellement enregistré dans la base de données.\nVos modifications apparaissent dans la zone de modification inférieure.\nVous allez devoir fusionner vos modifications dans le texte existant.\nSeul le texte de la zone supérieure sera sauvegardé si vous cliquez sur « $1 ».", "yourtext": "Votre texte", "storedversion": "La version enregistrée", "editingold": "Attention : vous êtes en train de modifier une ancienne version de cette page.\nSi vous la publiez, toutes les modifications effectuées depuis cette version seront perdues.", - "unicode-support-fail": "Votre navigateur semble ne pas rendre en charge l'Unicode. Ceci est nécessaire pour modifier les pages, aussi vos modifications n'ont pas été sauvegardées.", + "unicode-support-fail": "Votre navigateur semble ne pas rendre en charge l’Unicode. Ceci est nécessaire pour modifier les pages, aussi vos modifications n'ont pas été sauvegardées.", "yourdiff": "Différences", - "copyrightwarning": "Toutes les contributions à {{SITENAME}} sont considérées comme publiées sous les termes de la $2 (voir $1 pour plus de détails). \nSi vous ne désirez pas que vos écrits soient modifiés et distribués à volonté, merci de ne pas les soumettre ici.
\nVous nous promettez aussi que vous avez écrit ceci vous-même, ou que vous l’avez copié d’une source provenant du domaine public ou d’une ressource libre similaire. \nN’UTILISEZ PAS DE TRAVAUX SOUS DROIT D’AUTEUR SANS AUTORISATION EXPRESSE !", - "copyrightwarning2": "Notez bien que toutes les contributions à {{SITENAME}} peuvent être modifiées, transformées ou supprimées par d’autres utilisateurs. \nSi vous ne désirez pas que vos écrits soient modifiés contre votre gré, merci de ne pas les soumettre ici.
\nVous nous promettez aussi que vous avez écrit ceci vous-même, ou que vous l’avez copié d’une source provenant du domaine public, ou d’une ressource libre. (voir $1 pour plus de détails).\nN’UTILISEZ PAS DE TRAVAUX SOUS DROIT D’AUTEUR SANS AUTORISATION EXPRESSE !", + "copyrightwarning": "Toutes les contributions à {{SITENAME}} sont considérées comme publiées sous les termes de la $2 (voir $1 pour plus de détails). \nSi vous ne désirez pas que vos écrits soient modifiés et distribués à volonté, merci de ne pas les soumettre ici.
\nVous nous promettez aussi que vous avez écrit ceci vous-même, ou que vous l’avez copié d’une source provenant du domaine public ou d’une ressource libre similaire.\nN’UTILISEZ PAS DE TRAVAUX SOUS DROIT D’AUTEUR SANS AUTORISATION EXPRESSE !", + "copyrightwarning2": "Notez bien que toutes les contributions à {{SITENAME}} peuvent être modifiées, transformées ou supprimées par d’autres utilisateurs.\nSi vous ne désirez pas que vos écrits soient modifiés contre votre gré, merci de ne pas les soumettre ici.
\nVous nous promettez aussi que vous avez écrit ceci vous-même ou que vous l’avez copié d’une source provenant du domaine public ou d’une ressource libre (voir $1 pour plus de détails).\nN’UTILISEZ PAS DE TRAVAUX SOUS DROIT D’AUTEUR SANS AUTORISATION EXPRESSE !", "editpage-cannot-use-custom-model": "Le modèle de contenu de cette page ne peut pas être modifié.", "longpageerror": "Erreur : Le texte que vous avez soumis fait {{PLURAL:$1|un Kio|$1 Kio}}, ce qui dépasse la limite fixée à {{PLURAL:$2|un Kio|$2 Kio}}.\nIl ne peut pas être sauvegardé.", - "readonlywarning": "AVERTISSEMENT : la base de données a été verrouillée pour des opérations de maintenance. Vous ne pouvez donc pas publier vos modifications pour l’instant.\nVous pouvez copier et coller votre texte dans un fichier texte et l’enregistrer pour plus tard.\n\nL’administrateur système ayant verrouillé la base de données a donné l’explication suivante : $1", - "protectedpagewarning": "AVERTISSEMENT : cette page est protégée afin que seuls les utilisateurs ayant le statut d'administrateur puissent la modifier.\nLa dernière entrée du journal est affichée ci-dessous pour référence :", - "semiprotectedpagewarning": "Note :Cette page a été protégée pour que seuls les contributeurs confirmés automatiquement puissent la modifier. \nLa dernière entrée du journal est affichée ci-dessous pour référence :", - "cascadeprotectedwarning": "ATTENTION : Cette page a été protégée de manière à ce que seuls les utilisateurs avec [[Special:ListGroupRights|des droits spécifiques]] puissent la modifier car elle est incluse dans {{PLURAL:$1|la page suivante, protégée en cascade|les pages suivantes, protégées en cascade}} :", - "titleprotectedwarning": "ATTENTION : Cette page a été protégée de telle manière que des [[Special:ListGroupRights|droits spécifiques]] sont requis pour pouvoir la créer. \nLa dernière entrée du journal est affichée ci-dessous pour référence :", + "readonlywarning": "AVERTISSEMENT : la base de données a été verrouillée pour des opérations de maintenance. Vous ne pouvez donc pas publier vos modifications pour l’instant.\nVous pouvez copier et coller votre texte dans un fichier texte et l’enregistrer pour plus tard.\n\nL’administrateur système ayant verrouillé la base de données a donné l’explication suivante : $1", + "protectedpagewarning": "AVERTISSEMENT : cette page est protégée afin que seuls les utilisateurs ayant le statut d’administrateur puissent la modifier.\nLa dernière entrée du journal est affichée ci-dessous pour référence :", + "semiprotectedpagewarning": "Note :Cette page a été protégée pour que seuls les contributeurs confirmés automatiquement puissent la modifier.\nLa dernière entrée du journal est affichée ci-dessous pour référence :", + "cascadeprotectedwarning": "ATTENTION : cette page a été protégée de manière à ce que seuls les utilisateurs avec [[Special:ListGroupRights|des droits spécifiques]] puissent la modifier car elle est incluse dans {{PLURAL:$1|la page suivante, protégée en cascade|les pages suivantes, protégées en cascade}} :", + "titleprotectedwarning": "ATTENTION : cette page a été protégée de telle manière que des [[Special:ListGroupRights|droits spécifiques]] sont requis pour pouvoir la créer.\nLa dernière entrée du journal est affichée ci-dessous pour référence :", "templatesused": "{{PLURAL:$1|Modèle utilisé|Modèles utilisés}} par cette page :", "templatesusedpreview": "{{PLURAL:$1|Modèle utilisé|Modèles utilisés}} dans cette prévisualisation :", "templatesusedsection": "{{PLURAL:$1|Modèle utilisé|Modèles utilisés}} dans cette section :", @@ -887,16 +888,16 @@ "edittools": "", "edittools-upload": "—", "nocreatetext": "{{SITENAME}} a restreint la possibilité de créer de nouvelles pages.\nVous pouvez revenir en arrière et modifier une page existante, ou bien [[Special:UserLogin|vous connecter ou créer un compte]].", - "nocreate-loggedin": "Vous n'avez pas la permission de créer de nouvelles pages.", + "nocreate-loggedin": "Vous n’avez pas la permission de créer de nouvelles pages.", "sectioneditnotsupported-title": "Modification de section non prise en charge", "sectioneditnotsupported-text": "La modification d’une section n’est pas prise en charge pour cette page.", "modeleditnotsupported-title": "Modification non prise en charge", "modeleditnotsupported-text": "La modification n’est pas prise en charge pour le modèle de contenu $1.", "permissionserrors": "Erreur de permissions", - "permissionserrorstext": "Vous n'avez pas la permission d'effectuer l'opération demandée pour {{PLURAL:$1|la raison suivante|les raisons suivantes}} :", - "permissionserrorstext-withaction": "Vous ne pouvez pas $2, pour {{PLURAL:$1|la raison suivante|les raisons suivantes}} :", + "permissionserrorstext": "Vous n’avez pas la permission d'effectuer l'opération demandée pour {{PLURAL:$1|la raison suivante|les raisons suivantes}} :", + "permissionserrorstext-withaction": "Vous ne pouvez pas $2, pour {{PLURAL:$1|la raison suivante|les raisons suivantes}} :", "contentmodelediterror": "Vous ne pouvez pas modifier cette révision car son modèle de contenu est $1, ce qui diffère du modèle de contenu actuel de la page $2.", - "recreate-moveddeleted-warn": "Attention : vous êtes en train de recréer une page qui a été précédemment supprimée.\n\nAssurez-vous qu'il est pertinent de poursuivre les modifications sur cette page.\nLes journaux des suppressions et déplacements pour cette page sont fournis ici pour information :", + "recreate-moveddeleted-warn": "Attention : vous êtes en train de recréer une page qui a été précédemment supprimée.\n\nAssurez-vous qu’il est pertinent de poursuivre les modifications sur cette page.\nLes journaux des suppressions et déplacements pour cette page sont fournis ici pour information :", "moveddeleted-notice": "Cette page a été supprimée.\nLes journaux des suppressions, protections et déplacements pour la page sont fournis ci-dessous pour référence.", "moveddeleted-notice-recent": "Désolé, cette page a été récemment supprimée (dans les dernières 24 heures).\nLes journaux des suppressions, protections et déplacements pour la page sont fournis ci-dessous pour référence.", "log-fulllog": "Voir le journal complet", @@ -904,9 +905,9 @@ "edit-gone-missing": "N’a pas pu mettre à jour la page.\nIl semble qu’elle ait été supprimée.", "edit-conflict": "Conflit de modification.", "edit-no-change": "Votre modification a été ignorée car aucun changement n’a été apporté au texte.", - "edit-slots-cannot-add": "{{PLURAL:$1|L’emplacement suivant n’est pas supporté|Les emplacements suivants ne sont pas supportés}} ici : $2.", - "edit-slots-cannot-remove": "{{PLURAL:$1|L’emplacement suivant est obligatoire et ne peut pas être supprimé|Les emplacements suivants sont obligatoires et ne peuvent pas être supprimés}} : $2.", - "edit-slots-missing": "{{PLURAL:$1|L’emplacement suivant est absent|Les emplacements suivants sont absents}} : $2.", + "edit-slots-cannot-add": "{{PLURAL:$1|L’emplacement suivant n’est pas supporté|Les emplacements suivants ne sont pas supportés}} ici : $2.", + "edit-slots-cannot-remove": "{{PLURAL:$1|L’emplacement suivant est obligatoire et ne peut pas être supprimé|Les emplacements suivants sont obligatoires et ne peuvent pas être supprimés}} : $2.", + "edit-slots-missing": "{{PLURAL:$1|L’emplacement suivant est absent|Les emplacements suivants sont absents}} : $2.", "postedit-confirmation-created": "La page a été créée.", "postedit-confirmation-restored": "La page a été restaurée.", "postedit-confirmation-saved": "Votre modification a été enregistrée.", @@ -915,12 +916,12 @@ "defaultmessagetext": "Message par défaut", "content-failed-to-parse": "Échec de l’analyse syntaxique du contenu de $2 pour le modèle $1 : $3", "invalid-content-data": "Données du contenu non valides", - "content-not-allowed-here": "Le contenu « $1 » n’est pas autorisé sur la page [[:$2]] dans l’emplacement « $3 »", - "editwarning-warning": "Quitter cette page vous fera perdre toutes les modifications que vous avez faites.\nSi vous êtes connecté{{GENDER:||e}}, vous pouvez désactiver cet avertissement dans la section « {{int:prefs-editing}} » de vos préférences.", + "content-not-allowed-here": "Le contenu « $1 » n’est pas autorisé sur la page [[:$2]] dans l’emplacement « $3 »", + "editwarning-warning": "Quitter cette page vous fera perdre toutes les modifications que vous avez faites.\nSi vous êtes connecté{{GENDER:||e}}, vous pouvez désactiver cet avertissement dans la section « {{int:prefs-editing}} » de vos préférences.", "editpage-invalidcontentmodel-title": "Modèle de contenu non pris en charge", - "editpage-invalidcontentmodel-text": "Le modèle de contenu \"$1\" n'est pas pris en charge.", + "editpage-invalidcontentmodel-text": "Le modèle de contenu « $1 » n’est pas pris en charge.", "editpage-notsupportedcontentformat-title": "Format de contenu non pris en charge", - "editpage-notsupportedcontentformat-text": "Le format de contenu $1 n'est pas pris en charge par le modèle de contenu $2 .", + "editpage-notsupportedcontentformat-text": "Le format de contenu $1 n’est pas pris en charge par le modèle de contenu $2 .", "slot-name-main": "Principal", "content-model-wikitext": "wikitexte", "content-model-text": "texte brut", @@ -933,20 +934,20 @@ "unsupported-content-diff": "Les diffs ne sont pas supportés pour le modèle de contenu $1.", "unsupported-content-diff2": "Les diffs entre les modèles de contenu $1 et $2 ne sont pas supportés sur ce wiki.", "deprecated-self-close-category": "Pages utilisant des balises HTML auto-fermantes non valides", - "deprecated-self-close-category-desc": "La page contient des balises HTML auto-fermantes non valides, comme <b/> ou <span/>. Le comportement de celles-ci changera prochainement pour être en accord avec la spécification HTML5, donc leur utilisation dans le wikitexte est désuète.", - "duplicate-args-warning": "Avertissement : [[:$1]] appelle [[:$2]] avec plus d'une valeur pour le paramètre « $3 ». Seule la dernière valeur fournie sera utilisée.", + "deprecated-self-close-category-desc": "La page contient des balises HTML auto-fermantes non valides, comme <b/> ou <span/>. Le comportement de celles-ci changera prochainement pour être en accord avec la spécification HTML5, donc leur utilisation dans le wikitexte est désormais désuète.", + "duplicate-args-warning": "Avertissement : [[:$1]] appelle [[:$2]] avec plus d'une valeur pour le paramètre « $3 ». Seule la dernière valeur fournie sera utilisée.", "duplicate-args-category": "Pages utilisant des arguments dupliqués dans les appels de modèle", "duplicate-args-category-desc": "La page contient des appels de modèle qui utilisent des arguments dupliqués, comme {{foo|bar=1|bar=2}} ou {{foo|bar|1=baz}}.", "expensive-parserfunction-warning": "Attention : cette page contient de trop nombreux appels à des fonctions coûteuses de l’analyseur syntaxique.\n\nIl devrait y avoir moins de $2 appel{{PLURAL:$2||s}}, alors qu’il y en a maintenant $1.", - "expensive-parserfunction-category": "Pages avec trop d'appels dispendieux aux fonctions de l'analyseur syntaxique", + "expensive-parserfunction-category": "Pages avec trop d’appels dispendieux aux fonctions de l’analyseur syntaxique", "post-expand-template-inclusion-warning": "Attention : cette page contient trop d’inclusions de modèles. Certaines inclusions ne seront pas effectuées.", "post-expand-template-inclusion-category": "Pages contenant trop d'inclusions de modèles", - "post-expand-template-argument-warning": "Attention : cette page contient au moins un paramètre de modèle dont la taille après expansion est trop importante. \nCes arguments n’ont donc pas été inclus.", + "post-expand-template-argument-warning": "Attention : cette page contient au moins un paramètre de modèle dont la taille après expansion est trop importante.\nCes arguments n’ont donc pas été inclus.", "post-expand-template-argument-category": "Pages contenant des paramètres de modèle non évalués", "parser-template-loop-warning": "Modèle en boucle détecté : [[$1]]", "template-loop-category": "Pages avec des boucles de modèle", - "template-loop-category-desc": "La page contient une boucle dans le modèle, c.à.d. un modèle qui s’appelle lui-même récursivement.", - "template-loop-warning": "Avertissement : Cette page appelle [[:$1]] ce qui provoque une boucle de modèles (un appel récursif infini).", + "template-loop-category-desc": "La page contient une boucle de modèle, c.à.d. un modèle qui s’appelle lui-même récursivement.", + "template-loop-warning": "Avertissement : cette page appelle [[:$1]] ce qui provoque une boucle de modèles (un appel récursif potentiellement infini).", "parser-template-recursion-depth-warning": "Limite de profondeur des appels récursifs de modèles dépassée ($1)", "language-converter-depth-warning": "Limite de profondeur du convertisseur de langue dépassée ($1)", "node-count-exceeded-category": "Pages dépassant le nombre de nœuds maximal", @@ -955,22 +956,22 @@ "expansion-depth-exceeded-category": "Pages dépassant la profondeur d'expansion maximale", "expansion-depth-exceeded-category-desc": "La page dépasse la profondeur d’expansion maximale.", "expansion-depth-exceeded-warning": "Page dépassant la profondeur d’expansion maximale", - "parser-unstrip-loop-warning": "Boucle non dépilable détectée", - "unstrip-depth-warning": "Limite de récursion non dépilable dépassée ($1)", + "parser-unstrip-loop-warning": "Boucle de développement (unstrip) détectée", + "unstrip-depth-warning": "Limite de récursion de développement (unstrip) dépassée ($1)", "unstrip-depth-category": "Pages où la limite de profondeur de développement est dépassée", - "unstrip-size-warning": "Limite de taille de développement dépassée ($1)", + "unstrip-size-warning": "Limite de taille de développement (unstrip) dépassée ($1)", "unstrip-size-category": "Pages où la limite de taille de développement est dépassée", "converter-manual-rule-error": "Erreur détectée dans la règle manuelle de conversion de langue", - "undo-success": "Cette modification va être annulée.\nVeuillez vérifier les différences ci-dessous, puis publier l’annulation si c’est bien ce que vous voulez faire.", + "undo-success": "La précédente modification va être annulée.\nVeuillez vérifier les différences ci-dessous, puis publier l’annulation ci-dessous si c’est bien ce que vous voulez faire.", "undo-failure": "Cette modification ne peut pas être défaite : cela entrerait en conflit avec les modifications intermédiaires.", - "undo-main-slot-only": "La modification n'a pas pu être annulée car elle implique un contenu en dehors de la tranche principale.", + "undo-main-slot-only": "La modification n’a pas pu être annulée car elle implique un contenu en dehors de la tranche principale.", "undo-norev": "La modification n’a pas pu être défaite parce qu’elle est inexistante ou qu’elle a été supprimée.", "undo-nochange": "Il semblerait que la modification ait déjà été annulée.", "undo-summary": "Annulation des modifications $1 de [[Special:Contributions/$2|$2]] ([[User talk:$2|discussion]])", "undo-summary-anon": "Annuler la modification $1 de [[Special:Contributions/$2|$2]]", "undo-summary-username-hidden": "Annuler la révision $1 par un utilisateur masqué", - "cantcreateaccount-text": "La création de compte depuis cette adresse IP ($1) a été bloquée par [[User:$3|$3]]. \n\nLa raison donnée par $3 était : $2", - "cantcreateaccount-range-text": "La création de compte depuis les adresses IP de la plage $1, où se trouve votre adresse IP ($4), a été bloquée par [[User:$3|$3]].\n\nLe motif fourni par $3 est $2", + "cantcreateaccount-text": "La création de compte depuis cette adresse IP ($1) a été bloquée par [[User:$3|$3]]. \n\nLa raison donnée par $3 était : $2", + "cantcreateaccount-range-text": "La création de compte depuis les adresses IP de la plage $1, où se trouve votre adresse IP ($4), a été bloquée par [[User:$3|$3]].\n\nLe motif fourni par $3 est : $2", "viewpagelogs": "Voir les opérations sur cette page", "nohistory": "Il n’existe pas d’historique des modifications pour cette page.", "currentrev": "Version actuelle", @@ -985,17 +986,17 @@ "last": "diff", "page_first": "première", "page_last": "dernière", - "histlegend": "Sélection du diff : cochez les boutons radio des versions à comparer et appuyez sur entrée ou sur le bouton en bas.
\nLégende : ({{int:cur}}) = différence avec la dernière version, ({{int:last}}) = différence avec la version précédente, {{int:minoreditletter}} = modification mineure.", - "history-fieldset-title": "Filtrer les versions", + "histlegend": "Sélection du diff : cochez les boutons radio des versions à comparer et appuyez sur entrée ou sur le bouton en bas.
\nLégende : ({{int:cur}}) = différence avec la dernière version, ({{int:last}}) = différence avec la version précédente, {{int:minoreditletter}} = modification mineure.", + "history-fieldset-title": "Filtrer les révisions", "history-show-deleted": "Révision supprimée uniquement", "histfirst": "les plus anciennes", "histlast": "les plus récentes", "historysize": "($1 octet{{PLURAL:$1||s}})", "historyempty": "vide", "history-feed-title": "Historique des versions", - "history-feed-description": "Historique des versions pour cette page sur le wiki", + "history-feed-description": "Historique des révisions pour cette page sur le wiki", "history-feed-item-nocomment": "$1 le $2", - "history-feed-empty": "La page demandée n'existe pas.\nElle a peut-être été effacée ou renommée.\nEssayez de [[Special:Search|rechercher sur le wiki]] pour trouver de nouvelles pages en rapport avec le sujet.", + "history-feed-empty": "La page demandée n’existe pas.\nElle a peut-être été effacée ou renommée.\nEssayez de [[Special:Search|rechercher sur le wiki]] pour trouver de nouvelles pages en rapport avec le sujet.", "history-edit-tags": "Modifier les balises des versions sélectionnées", "rev-deleted-comment": "(résumé de modification retiré)", "rev-deleted-user": "(nom d'utilisateur retiré)", @@ -1017,35 +1018,35 @@ "rev-showdeleted": "afficher", "revisiondelete": "Supprimer ou restaurer des événements", "revdelete-nooldid-title": "Version cible non valide", - "revdelete-nooldid-text": "Vous n’avez pas précisé de révision(s) cible(s) pour cette fonction, ou bien la révision spécifiée n’existe pas, ou bien vous tentez de masquer la révision actuelle.", + "revdelete-nooldid-text": "Vous n’avez pas précisé de révision(s) cible(s) pour cette fonction, ou la révision spécifiée n’existe pas, ou bien vous tentez de masquer la révision actuelle.", "revdelete-no-file": "Le fichier spécifié n'existe pas.", - "revdelete-show-file-confirm": "Êtes-vous sûr{{GENDER:||e}} de vouloir voir la révision supprimée du fichier « $1 » datant du $2 à $3 ?", + "revdelete-show-file-confirm": "Êtes-vous sûr{{GENDER:||e}} de vouloir voir la révision supprimée du fichier « $1 » datant du $2 à $3 ?", "revdelete-show-file-submit": "Oui", - "revdelete-selected-text": "{{PLURAL:$1|Révision sélectionnée|Révisions sélectionnées}} de [[:$2]] :", - "revdelete-selected-file": "{{PLURAL:$1|Version de fichier sélectionnée|Versions de fichier sélectionnées}} de [[:$2]] :", - "logdelete-selected": "{{PLURAL:$1|Événement d'historique sélectionné|Événements d'historique sélectionnés}} :", + "revdelete-selected-text": "{{PLURAL:$1|Révision sélectionnée|Révisions sélectionnées}} de [[:$2]] :", + "revdelete-selected-file": "{{PLURAL:$1|Version de fichier sélectionnée|Versions de fichier sélectionnées}} de [[:$2]] :", + "logdelete-selected": "{{PLURAL:$1|Événement d’historique sélectionné|Événements d’historique sélectionnés}} :", "revdelete-text-text": "Les révisions supprimées continueront à apparaître dans l’historique de la page, mais une partie de leur contenu sera inaccessible au public.", "revdelete-text-file": "Les versions de fichier supprimées continueront à apparaître dans l’historique des fichiers, mais une partie de leur contenu sera indisponible au public.", - "logdelete-text": "Les évènements supprimés du journal continueront à apparaître dans les journaux, mais une partie de leur contenu sera indisponible au public.", - "revdelete-text-others": "Les autres administrateurs seront toujours en mesure d'accéder au contenu caché et le restaurer, à moins que des restrictions supplémentaires soient fixées.", - "revdelete-confirm": "Confirmez que vous voulez effectuer cette action, que vous en comprenez les conséquences, et que vous le faites en accord avec [[{{MediaWiki:Policy-url}}|les règles]].", - "revdelete-suppress-text": "La suppression ne doit être utilisée que dans les cas suivants :\n* informations potentiellement diffamatoires\n* informations personnelles inappropriées\n*: adresse, numéro de téléphone, numéro de sécurité sociale, …", + "logdelete-text": "Les événements supprimés du journal continueront à apparaître dans les journaux, mais une partie de leur contenu sera indisponible au public.", + "revdelete-text-others": "Les autres administrateurs seront toujours en mesure d’accéder au contenu caché et le restaurer, à moins que des restrictions supplémentaires soient fixées.", + "revdelete-confirm": "Confirmez que vous voulez effectuer cette action, que vous en comprenez les conséquences et que vous le faites en accord avec [[{{MediaWiki:Policy-url}}|les règles]].", + "revdelete-suppress-text": "La suppression ne doit être utilisée que dans les cas suivants :\n* informations potentiellement diffamatoires\n* informations personnelles inappropriées\n*: adresse, numéro de téléphone, numéro de sécurité sociale, …", "revdelete-legend": "Mettre en place des restrictions de visibilité", "revdelete-hide-text": "Texte de la révision", "revdelete-hide-image": "Masquer le contenu du fichier", "revdelete-hide-name": "Masquer la cible et les paramètres", "revdelete-hide-comment": "Résumé de modification", - "revdelete-hide-user": "Nom d’utilisateur/Adresse IP de l’éditeur", - "revdelete-hide-restricted": "Supprimer ces données aux administrateurs ainsi qu'aux autres", + "revdelete-hide-user": "Nom d’utilisateur / adresse IP de l’auteur", + "revdelete-hide-restricted": "Supprimer ces données aux administrateurs ainsi qu’aux autres", "revdelete-radio-same": "(ne pas changer)", "revdelete-radio-set": "Masqué", "revdelete-radio-unset": "Visible", "revdelete-suppress": "Masquer également les données pour les administrateurs", "revdelete-unsuppress": "Enlever les restrictions sur les versions restaurées", - "revdelete-log": "Motif :", + "revdelete-log": "Motif :", "revdelete-submit": "Appliquer {{PLURAL:$1|à la révision sélectionnée|aux révisions sélectionnées}}", "revdelete-success": "Visibilité des versions mise à jour.", - "revdelete-failure": "'''La visibilité de la version n'a pas pu être mise à jour :'''\n$1", + "revdelete-failure": "'''La visibilité de la version n'a pas pu être mise à jour :'''\n$1", "logdelete-success": "Visibilité du journal modifiée.", "logdelete-failure": "'''La visibilité du journal n'a pas pu être définie :'''\n$1", "revdel-restore": "modifier la visibilité", @@ -1268,6 +1269,7 @@ "prefs-help-email": "L'adresse de courriel est facultative, mais elle est nécessaire pour réinitialiser votre mot de passe, en cas d'oubli.", "prefs-help-email-others": "Vous pouvez aussi choisir de laisser les autres vous contacter par courriel via un lien sur votre page de discussion ou page utilisateur. \nVotre adresse courriel n'est pas révélée quand les autres utilisateurs vous contactent.", "prefs-help-email-required": "Une adresse de courriel est requise.", + "prefs-help-requireemail": "Si coché, enverra seulement les courriels de réinitialisation des mots de passe si la personne qui réinitialise a fourni à la fois un nom d’utilisateur et un courriel pour ce compte.", "prefs-info": "Informations de base", "prefs-i18n": "Internationalisation", "prefs-signature": "Signature", @@ -2733,6 +2735,7 @@ "ipblocklist-legend": "Chercher un utilisateur bloqué", "blocklist-userblocks": "Masquer les blocages de comptes", "blocklist-tempblocks": "Masquer les blocages temporaires", + "blocklist-indefblocks": "Masquer les blocs non définis", "blocklist-addressblocks": "Masquer les blocages d’adresses IP uniques", "blocklist-type": "Type :", "blocklist-type-opt-all": "Tous", diff --git a/languages/i18n/gl.json b/languages/i18n/gl.json index d8dffa5958..38139ab401 100644 --- a/languages/i18n/gl.json +++ b/languages/i18n/gl.json @@ -675,6 +675,7 @@ "systemblockedtext": "O seu nome de usuario ou enderezo IP foi bloqueado automaticamente polo sistema MediaWiki.\nO motivo do bloqueo é:\n\n:$2\n\n* Comezo do bloqueo: $8\n* Expiración do bloqueo: $6\n* Destinatario do bloqueo: $7\n\nO seu enderezo IP actual é $3.\nPor favor, inclúa todos estes detalles en calquera consulta que realice.", "blockednoreason": "non se deu ningunha razón", "blockedtext-composite": "O seu nome de usuario ou enderezo IP foron bloqueados.\n\nO motivo dado é:\n\n:$2.\n\n* Comezo do bloqueo: $8\n* Remate do bloqueo máis longo: $6\n\n* $5\n\nO seu enderezo IP actual é $3.\nPor favor, inclúa todos os detalles de arriba en calquera contacto sobre este asunto.", + "blockedtext-composite-ids": "Identificadores de bloqueo relevantes: $1 (o seu enderezo IP pode atoparse tamén nalgunha lista negra)", "blockedtext-composite-no-ids": "O seu enderezo IP aparece en múltiples listas negras", "blockedtext-composite-reason": "Existen varios bloqueos contra a súa conta ou enderezo IP", "whitelistedittext": "Debe $1 para poder editar páxinas.", @@ -747,6 +748,7 @@ "nocreate-loggedin": "Non ten os permisos necesarios para crear páxinas novas.", "sectioneditnotsupported-title": "A edición de seccións non está soportada", "sectioneditnotsupported-text": "A edición de seccións non está soportada nesta páxina.", + "modeleditnotsupported-title": "Non se permite a edición", "permissionserrors": "Erro de permisos", "permissionserrorstext": "Non ten os permisos necesarios para facelo {{PLURAL:$1|pola seguinte razón|polas seguintes razóns}}:", "permissionserrorstext-withaction": "Non ten os permisos necesarios para $2, {{PLURAL:$1|pola seguinte razón|polas seguintes razóns}}:", diff --git a/languages/i18n/gom-deva.json b/languages/i18n/gom-deva.json index 2a427a291b..9a45be130e 100644 --- a/languages/i18n/gom-deva.json +++ b/languages/i18n/gom-deva.json @@ -24,15 +24,15 @@ "tog-previewonfirst": "पयल्याच संपादनाचेर पुर्वनियाळ दाखय", "tog-enotifwatchlistpages": "म्हज्या सादुरवळेरेंतलें पान वा फायल बदल्ली जाल्यार म्हाका इमेल करात", "tog-shownumberswatching": "ध्यान दवरपी वांगड्यांची संख्या दाखय", - "tog-oldsig": "सद्याची निशाणी", - "tog-uselivepreview": "लायव पुर्वनियाळाचो वापर", + "tog-oldsig": "तुज्या सध्याची निशाणी", + "tog-uselivepreview": "पान परत उगडनासताना झलक दाखय", "tog-watchlisthideown": "सादुरवळेरीतलें म्हजे संपादन लिपय", "tog-watchlisthidebots": "ध्यानसुचीतले रोबोट संपादन लिपय", "tog-watchlisthideminor": "सादुरवळेरीतले ल्हान संपादन लिपय", "tog-showhiddencats": "लिपोवन दवरिल्ले विभाग दाखय", "underline-always": "सदा (केधन्नय) (केन्नय)", "underline-never": "केधन्नयना (केन्नना)", - "underline-default": "ब्राउज़र डिफ़ॉल्ट", + "underline-default": "स्कीन वा ब्रावसरा प्रमाणें", "sunday": "आयतार", "monday": "सोमार", "tuesday": "मंगळार", @@ -99,20 +99,21 @@ "category_header": "\"$1\" ह्या वर्गातलीं पानां", "subcategories": "उपवर्ग", "category-media-header": "\"$1\" वर्गातलें प्रसार माध्यम", + "category-empty": "ह्या वर्गान सध्या एकूय पान वा माध्यम ना.", "hidden-categories": "{{PLURAL:$1|लिपिल्लें वर्ग|लिपिल्लें वर्ग }}", "hidden-category-category": "लिपयिल्ले विभाग", "category-subcat-count": "{{PLURAL:$2|ह्या वर्गान फकत सकयल दिल्ले उपविभाग आसात.|ह्या वर्गातल्या $2 वट्ट {{PLURAL:$1|सकयल दिल्ले उपवर्ग आसात.|$1सकयल दिल्ले उपवर्ग आसात.}}}}", "category-article-count": "{{PLURAL:$2|ह्या वर्गांत सकयल दिल्लीं पानां आसात.|ह्या वर्गांत सकलय दिल्लीं {{PLURAL:$1|पानां आसात|$1 पानां आसात}}, वट्ट पानां $2}}", "category-file-count": "{{PLURAL:$2|ह्या वर्गांत फकत सकयली फायल आसपावता.|ह्या वर्गांत सकयल दिल्लीं {{PLURAL:$1|फायल|$1 फायलीं}} आसता, वट्ट फायलीं $2}}", "listingcontinuesabbrev": "चालू.", - "noindex-category": "बिननिर्देशांकी पानां", + "noindex-category": "सुचीपत्रान जोडूंक-नासलेलीं पानां", "broken-file-category": "तुटलेल्या फायलींचो दुवे आसलेलीं पानां", "about": "विशीं", "article": "मजकूराचीं पानां", "newwindow": "(नव्या ज़ोणेलांत उकतें जाता)", "cancel": "रद्द करात", "moredotdotdot": "आनीक", - "morenotlisted": "ही सूची पूर्ण ना", + "morenotlisted": "ही सुची पूर्ण नासूंक शक्ता.", "mypage": "पान", "mytalk": "चर्चा", "navigation": "दिशा-नियंत्रण", @@ -189,6 +190,10 @@ "privacypage": "Project:गुप्ततायेचें धोरण", "ok": "बरें", "retrievedfrom": "\"$1\" चे कडल्यान परतून मेळयलें", + "youhavenewmessages": "{{PLURAL:$3|तुमकां}} $1 ($2) आसात.", + "youhavenewmessagesfromusers": "तुका {{PLURAL:$3एक वापरपी|$3 वापरपी}} कडल्यान $1 {{PLURAL:$4|आसा|आसात}} ($2).‎", + "newmessageslinkplural": "{{PLURAL:$1|नवो संदेश|999=नवे संदेश}}‎", + "newmessagesdifflinkplural": "{{PLURAL:$1|निमाणो बदल|999=निमाणे बदल}}", "youhavenewmessagesmulti": "$1 चेर तुका नवो संदेश आसा", "editsection": "बदल", "editold": "बदल", @@ -203,7 +208,7 @@ "collapsible-expand": "विस्तार", "confirmable-yes": "हय", "confirmable-no": "ना", - "thisisdeleted": "पळय आनी परतून हाड 1?", + "thisisdeleted": "$1 पळय वा परत हाड?", "viewdeleted": "दाखयात $1?", "feedlinks": "पुरवय :", "feed-invalid": "चुकीचें सब्सक्रिप्शन फीड प्रकार", @@ -233,7 +238,7 @@ "databaseerror-textcl": "डॅटाबेज विरोध त्रुटी आयिल्ली आसा", "databaseerror-query": "अनुरोध: $1", "databaseerror-error": "चूक: $1", - "missing-article": "डेटाबेजाक \"$1\" $2 ह्या नांवाचें जे मजकूराचें पान मेळूंक जाय आसलें तें मेळ्ळेंना. हें चड करून जेन्ना काडून उडयिल्ल्या पानाक मुजत सोंपिळ्ळे डिफ वा इतिहासाचो दुवो दिवप जाता तेन्ना घडटा..जर अशें नासत तर तुमकां सॉफ्टवेरांत चूक सांपडूंक जाय हें अँडमिनिस्ट्रेटराक URLची नोंद करून कळयात.", + "missing-article": "डेटाबेजाक \"$1\" $2 ह्या नांवाचें जे मजकूराचें पान मेळूंक जाय आसलें तें मेळ्ळेंना. हें चड करून जेन्ना काडून उडयिल्ल्या पानाक मुजत सोंपिळ्ळे डिफ वा इतिहासाचो दुवो दिवप जाता तेन्ना घडटा..जर अशें नासत तर तुमकां सॉफ्टवेरांत चूक सांपडूंक जाय हें अँडमिनिस्ट्रेटराक URLची नोंद करून कळयात.\n\n\nम्हायतीकोश (Database) हांतूत मेळूंक जाय आसलें तें मजकूर \"$1\" $2 मेळूंक नां.\n\nहरर्शीं, अशें एक पोरणें एक फरक वा एका पानाच्या इतिहासाचो दुवो काडून उडयला, तेन्ना जाता.\n\nअशें न्हय जाल्यार, तुका सोफ्टवेरान चूक सांपडलेया जायत.\nउपकार करून एका [[Special:ListUsers/sysop|कार्भारीच्या]] नतरेक हाड, अतरजाळ्यांत जागो सोदपी (यु. आर. एल.) हाची नोंद घेवन.", "missingarticle-rev": "पुनर्नियाळ $1", "badtitle": "चुकीचो माथाळो", "badtitletext": "विनवणी केल्लें पानाचो माथाळो अवैध, रितो वा अयोग्य तरेन आंतरभाशी वा आंतर विकी माथाळ्या कडे जोडिल्लो आशिल्लो. तातूंत माथाळ्यांत वापरुं नजो अशी एक वा चड अक्षरां आसूं येतात.", @@ -284,11 +289,11 @@ "loginerror": "लॉन इन त्रुटी", "createacct-error": "खातें निर्माण त्रुटी", "createaccounterror": "खातें तयार करूंक जायना: $1", - "loginsuccesstitle": "लॉन इन यशस्वी जालां", + "loginsuccesstitle": "सत्रारंभ जालें", "nosuchusershort": "\"$1\" ह्या नांवान कोण वापरपी ना.\nउतरां तपासून पळय", "nouserspecified": "वापरप्याचें नांव तुवें सांगूंक जाय", "login-userblocked": "ह्या वापरप्याक बंद केला. लॉग इन करूंक जायना.", - "wrongpassword": "चुकिचें गुपीत उतर घातलां.\nउपकार करून परतून यत्न कर.", + "wrongpassword": "चुकीचें वापरप्याचें नांव वा गुपीतउतर घातलां.\nउपकार करून परतून प्रयत्न कर.", "wrongpasswordempty": "गुपीत उतर घालूंक ना.\nउपकार करून परतून यत्न कर.", "passwordtoolong": "गुपीत उतर हाच्या परस चड व्हड आसूंक फावना{{PLURAL:$1|1 वर्ण|$1 वर्णां}}.", "password-name-match": "तुजें गुपीत उतर वापरप्याच्या नांवा परस वेगळें आसूंक जाय.", @@ -302,7 +307,7 @@ "emaildisabled": "ही साइट मेल धाडपाक शकना.", "accountcreated": "खातें तयाओर केलें", "createaccount-title": "{{SITENAME}} हाका लागून खातें तयार केलां", - "login-abort-generic": "तुमचें लॉग इन अपेशी थारलां - निश्फलीत", + "login-abort-generic": "तुजें सत्रारंभ अपेशी थारलां – निशफळीत", "login-migrated-generic": "तुमचें खातें स्थलांतरीत जालां आनी तुजें वापरप्याचें नांव ह्या विकीचेर उपस्थीत ना.", "loginlanguagelabel": "भास:$1", "pt-login": "सत्रारंभ", @@ -315,7 +320,7 @@ "newpassword": "नवें गुपीत उतर", "retypenew": "नवें गुपीत उतर परतून टाइप कर", "resetpass_submit": "गुपीत उतर तयार कर आनी लॉग इन कर", - "changepassword-success": "तुजें गुपीत उतर बदलप यशस्वी थारलां", + "changepassword-success": "तुजें गुपीतउतर बदल्लां!", "resetpass_forbidden": "गुपीत उतरां बदलूंक शकनात", "resetpass-submit-loggedin": "गुपीत उतर बदलात", "resetpass-submit-cancel": "रद्द करात", @@ -327,8 +332,8 @@ "passwordreset-domain": "डोमेन:", "passwordreset-email": "ईमेल नामो:", "passwordreset-emailelement": "वापरप्याचें नांव: \n$1\n\nतात्पुरतें गुपीत उतर: \n$2", - "passwordreset-emailsentemail": "गुपीत उतर परतून तयार करपाचो ईमेल धाडला", - "changeemail": "ईमेल संदेश बदल्ला", + "passwordreset-emailsentemail": "हो ईमेल पत्तो तुज्या हिशोबांत जोडलोलों आसा जाल्यार, गुपीतउतर परतून थारावपाचो ईमेल धाडलेलें जातेलें.", + "changeemail": "ईमेल पत्तो बदल वा काड", "changeemail-oldemail": "सद्याचो ईमेल नामो:", "changeemail-newemail": "नवो ईमेल नामो:", "changeemail-none": "(कांय ना)", @@ -365,26 +370,32 @@ "showpreview": "पूर्वनियाळ दाखय", "showdiff": "बदल दाखयात", "anoneditwarning": "'''शिटकावणी:''' तुवें सत्रारंभ करूंक ना.\nतुजो IP पत्तो ह्या पानाच्या संपादन इतिहासांत नोंद जातलो.जर तुमी [$1 सत्रारंभ] करता वा [$2 खातें उगडटा] जाल्यार हेर सुविधांसयत तुमच्या संपादनाचें श्रेय तुमच्या सदस्य नांवाचेर दितलें.", - "missingcommenttext": "उपकार करून तुमच्यो शिरो सकयल घाल.", + "missingcommenttext": "उपकार करून तुजो शेरो बरय.", "blockedtitle": "वापरप्याक बंद केला", + "blockedtext": "तुजें वापरप्याचें नांव वा आय पा पत्तो आडावपांत आयला.\n\nआडावप $1 हाणें केलां.\nकारण दिलां तें $2.\n\n* आडावपाची सुरवात: $8\n* आडावप सोंपोवपाचो वेळ: $6\n* आडावपाक येवजिला: $7\n\nतुज्यान $1-आक वा दूसऱ्या [[{{MediaWiki:Grouppage-sysop}}|कारभार्याक]] आडावणे विशीं भासाभास करुंक संपर्क करुंक जाता. तुज्यान \"{{int:emailuser}}\" सभावगूण वापरुंक जायना खेरीज एक वैद ईमेल पत्तो तुज्या [[Special:Preferences|खातें पसंतिंत]] निशचीत केल्या शिवाय आनी तुका तें वापरपाक आडावंक ना जाल्यार. तुजो चालंत IP पत्तो आसा $3, आनी आडावणेच्यो आंक #$5 आसा. सगळ्यो वयल्यो बारिकसाणी तूं करताय त्या विचारांत समावेश कर.", "blockednoreason": "कांयच कारण दिवंक ना", "loginreqtitle": "लॉग इन जाय", "loginreqlink": "सत्रारंभ करात", "accmailtitle": "गुपीत उतर धाडलां", "newarticle": "(नवें)", "newarticletext": "जें पान अजून अस्तित्वांत ना अशा पानाचे दुवे फाटल्यान तुमी आसात. पान रचपाक सकयले चौकटींत टायप करपाक सुरु करात (चड म्हायती खातीर [$1 आदाराचें पान] पळेयात) जर ह्या पानार तुमी चुकून पावल्यात तर ब्रावजराचो बॅक (फटीं) हो बटन दामात", + "anontalkpagetext": "----\nहें भासाभासेचें पान एक निनामी वापरप्याक जाणें अजून एक खातें उगडुंक ना, वो तो तें वापर्ना.\nह्या खातीर आमकां आंकड्यांचो IP पत्तो वापरुंक पडता ताका वळखुंक.\nतसलो IP पत्तो साबार वापरप्यानी वापरूं येता.\nतूं जर एक निनामी वापरपी आसा आनी तुका दिसता की तुमका संबंद नासलेले शेरे तुजे विशीं केल्यात, उपकार करून [[Special:CreateAccount|एक खातें रच]] वा[[Special:UserLogin|सत्रारंभ कर]] फुडले गुस्पप निनामी वापरप्या ताळूंक.‎", "noarticletext": "सध्याक हें पान रिंते आसा.\nतुज्यान दूसऱ्या पानानी [[Special:Search/{{PAGENAME}}| ह्या पानाचे नांव सोदूंक जाता]], [{{fullurl:{{#Special:Log}}|page={{FULLPAGENAME}}}} संबंधी सत्रानी सोदूंक जाता], वा [{{fullurl:{{FULLPAGENAME}}|action=edit}} हें पान रचूंक जाता].", "noarticletext-nopermission": "तुर्ताक ह्या पानाचेर कसलोच मजकूर ना. तुमी हेर पानांचेर [[Special:Search/{{PAGENAME}}|ह्या माथाळ्याचो सोद]] घेवं शकतात,\nवा [{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} संबंदीत लॉग सोदूं शकतात], पूण तुमकां हें पानाची रचणूक करपाची परवानगी ना।", "userpage-userdoesnotexist-view": "\"$1\" ह्या वापरप्याच्या खात्याची नोंदणी करूंक ना.", + "clearyourcache": "चत्राय: सांबाळ्ळ्या उपरांत, तुका घडयेक तुज्या ब्रावसराचो कॅश कडसरावंक पडत बदल पळोंवचे खातीर.\n* Firefox / Safari: Shift > धर Reload क्लीक करताना, वा दाम Ctrl-F5 वा Ctrl-R (⌘-R मॅक-आचेर)\n* Google Chrome: Ctrl-Shift-R दाम (⌘-Shift-R एका मॅक-आचेर)\n* Internet Explorer: Ctrl dhor Refresh क्लीक करताना, वा दाम Ctrl-F5\n* Opera: हांगा वच: Menu → Settings (Opera → Preferences मॅक-आचेर) आनी उपरांत Privacy & security → Clear browsing data → Cached images and files.‎", "previewnote": "'''ही फकत एक दाखवण हें मतींत दवरात.'''\nतुमचें बदल आडून राखून दवरूंक ना!", + "continue-editing": "संपादन करपाच्या जाग्यार वच", "editing": "संपादता $1", "creating": "$1 रोचता", "editingsection": "(विभाग) $1 संपादन", "yourtext": "तुमचो मजकूर", "templatesused": "ह्या पानाचेर {{PLURAL:$1|वापरिल्लें}} सांचे", + "templatesusedpreview": "{{PLURAL:$1सांचो|सांचे}} ह्या झलकेंत वापरल्यात:‎", "template-protected": "(राखिल्लें)", "template-semiprotected": "(अर्द-सुरक्षीत)", "hiddencategories": "हें पान {{PLURAL:$1|लिपिल्ले वर्गाचें}} आसा", + "permissionserrors": "परवांगेची चूक", "permissionserrorstext-withaction": "ह्या {{PLURAL:$1|कारण|कारणां}}: खातीर तुका $2 मान्यताय ना.", "recreate-moveddeleted-warn": "शिटकावणीः तुमी आदीं काडून उडयिल्लें पान परतून तयार करतात ह्या पानाचे फासून उडोवपी आनी दुसरे कडे व्हरपी लाग फकत सोपेपणा खातीर दिल्यात", "moveddeleted-notice": "हें पान काडून उडयला.\nह्या पानाचें काडून उडोवपाचें, राखपाचें, आनी हालोवपाचें सत्र संदर्भा खातीर सकयल दिला.", @@ -394,6 +405,7 @@ "post-expand-template-inclusion-category": "जंय सांचे धरून आवांठ व्हड जाता अशीं पानां", "post-expand-template-argument-warning": "शिटकावणीः ह्या पानाचेर खुब व्हड आंवाठ आशिल्लो एक तरी सांच्याचो मुद्दो आसा. हे मुद्दे भायरायल्यात", "post-expand-template-argument-category": "भायरायिल्ल्या सांच्यांसंबंदीचे मुद्दे आशिल्लीं पानां", + "undo-failure": "बदल परतावूंक जावंक ना कित्याक गुस्पणेचे मदले बदल आसात.", "viewpagelogs": "ह्या पाना खातीर सोत्रां पळेयात", "currentrev-asof": "$1 मेरेनचो सगळ्यांत निमणो पुनर्नियाळ", "revisionasof": " $1 मेरेन पुनर्नियाळ", @@ -408,9 +420,11 @@ "page_last": "निमणें", "histlegend": "फरकाची निवडणी : पुनर्नियाळांची तुळा करपा खातीर रेडियो चौकटीं चेर कुरु करात आनी ''एंटर'' ना तर तळाकडे आशिल्लो बुतांव दामात।
\nविवरण : ({{int:cur}}) = हालींची पुनर्नियाळा बरोबर फरक, ({{int:last}}) = आदली पुनर्नियाळा बरोबर फरक, {{int:minoreditletter}} = दाक्टें बदल।", "history-fieldset-title": "उजळण्यो चाळ", - "history-show-deleted": "फकत काडून उडयिल्लें", + "history-show-deleted": "फकत उजळणी काडून उदयलेलें", "histfirst": "पोरणो", "histlast": "नवो ताल्ल", + "history-feed-title": "पुनर्नियाळाचो इतिहास", + "history-feed-description": "विकीचेर ह्या पाना खातीर पुनर्नियाळाचो इतिहास", "history-feed-item-nocomment": "$1 हांगा $2", "rev-delundel": "दृश्य मानताय बदलात", "rev-showdeleted": "दाखयात", @@ -421,13 +435,16 @@ "revdel-restore": "दृश्य मानताय बदलात", "pagehist": "पानाचो इतिहास", "mergehistory-reason": "कारण:", + "mergelog": "विलीन करपाचें सत्र", "revertmerge": "वेगळावप", "history-title": "\"$1\" च्या पुनर्नियाळाचो इतिहास", "difference-title": "\"$1\" च्या आवृत्तींत अंतर", "lineno": "$1 वळ :", "compareselectedversions": "वेंचिल्ल्या पुनर्नियाळांची तुळा करात", "editundo": "केल्लें परतावचें", + "diff-empty": "(कांय फरक ना)‎", "diff-multi-sameuser": "(ह्या वांगड्या सयत {{PLURAL:$1|केल्लें मदलें एक अवतरण दाखोवंक ना|केल्लें मदलें $1 अवतरण दाखोवंक ना}})", + "diff-multi-otherusers": "({{PLURAL:$2|एक हेर वापरप्या|$2 हेर वापरप्यां}} वर्वीं {{PLURAL:$1|एक मदली उजळणी|$1 मदल्यो उजळण्यो}} दाखोवंक ना)‎", "searchresults": "सोदाचो निकाल", "searchresults-title": "\"$1\" हाच्या सोदाचे परिणामां", "prevn": "आदलें{{PLURAL:$1|$1}}", @@ -448,9 +465,10 @@ "searchprofile-everything-tooltip": "सगळो मजकूर सोदात(चर्चेचें पाना सयत)", "searchprofile-advanced-tooltip": "खाशेल्या नांवथोळाणी सोदात", "search-result-size": "$1 ({{PLURAL:$2|1 उतर|$2 उतरां}})", - "search-result-category-size": "{PLURAL:$1|1 सदस्य|$1 सदस्य}} ({{PLURAL:$2|1 उपगट|$2 उपगट}}, {{PLURAL:$3|1 फायल|$3 फायलीं}})", + "search-result-category-size": "{{PLURAL:$1|$1 वांगडी}} ({{PLURAL:$2|$2 उपवर्ग}}, {{PLURAL:$3|1 फायल|$3 फायली}})", "search-redirect": "($1 सावन पुनर्निर्देशीत)", "search-section": "(विभाग $1)", + "search-file-match": "(फायलीच्या मजकुराक जुळटा)‎", "search-suggest": "तुमकां $1 अशें म्हणपाचें आसलें?", "search-rewritten": "$1 हाचो निकाल दाखयता.नाजाल्यार $2 हें सोदात.", "search-interwiki-more": "(आनी)", @@ -468,10 +486,16 @@ "prefs-watchlist": "सादुरवळेरी", "youremail": "इमेल", "yourrealname": "खरें नांवः", + "group-bot": "रोबोटां", + "group-sysop": "कारभारी", + "grouppage-bot": "{{ns:project}}:रोबोटां", + "grouppage-sysop": "{{ns:project}}:कारभारी", "right-writeapi": "Write API चो उपेग", "newuserlogpage": "वापरपी रोचनेचे वळेरी", + "rightslog": "वापरप्याच्या हकांचो सत्र", "action-edit": "हें पान संपादीत कर", - "nchanges": "$1 {{PLURAL:$1|बदल|बदल}}", + "action-createaccount": "हें वापरप्याचें खातें रच", + "nchanges": "$1 {{PLURAL:$1|बदल}}", "enhancedrc-history": "इतिहास", "recentchanges": "हालींचे बदल", "recentchanges-legend": "हालींच जाल्ल्या बदलाचो विकल्प", @@ -499,6 +523,7 @@ "rcshowhideanons": "$1 निनांवी वापरपी", "rcshowhideanons-show": "दाखयात", "rcshowhideanons-hide": "लिपयात", + "rcshowhidepatr": "$1 पारो केलेले सुदारप", "rcshowhidepatr-show": "दाखयात", "rcshowhidepatr-hide": "लिपयात", "rcshowhidemine": "$1 म्हजें संपादन आंकडे", @@ -515,6 +540,7 @@ "rc-change-size-new": "$1 {{PLURAL:$1|बाय्ट|बाय्टी}} बदल केल्या उपरांत", "rc-enhanced-expand": "म्हायती दाखय", "rc-enhanced-hide": "म्हायती लिपय", + "rc-old-title": "आरंभांत रचलली \"$1\" ह्या नांवान‎", "recentchangeslinked": "संबंदित बदल", "recentchangeslinked-toolbox": "संबंदीत बदल", "recentchangeslinked-title": "\"$1\" च्या संबंदातले बदल", @@ -523,6 +549,7 @@ "recentchangeslinked-to": "ह्या पाना बदला दिल्ल्या पानांक जडून आशिल्ल्या पानांचे बदल दाखय", "upload": "फायल अपलोड करात", "uploadbtn": "फायल अपलोड करात", + "uploadlogpage": "अपलोडाचें सत्र", "filedesc": "सारांश", "fileuploadsummary": "आपरोस:", "license": "लायसन्सीग", @@ -543,24 +570,30 @@ "filehist-datetime": "दिस / वेळ", "filehist-thumb": "ल्हान-इमाज़", "filehist-thumbtext": " $1मेरेनचे आवृत्ती खातीर ल्हान-इमाज़", + "filehist-nothumb": "ल्हान-इमाज ना", "filehist-user": "वापरपी", "filehist-dimensions": "परिमाण", "filehist-comment": "शेरो", "imagelinks": "फायलिचो वापर", "linkstoimage": "{{PLURAL:$1|हें पान|$1 हीं पानां}} ही फायल {{PLURAL:$1|वापरता|वापरतात}}:", + "linkstoimage-more": "$1 परस अदीक {{PLURAL:$1|पान वापरता|पानां वापरतात}} ही फायल.\nसकयली वळेरी दाखयता {{PLURAL:$1|पयलें पान|पयलीं $1 पानां}} जें हीच फायल वापरता. एक [[Special:WhatLinksHere/$2|पूर्ण वळेरी]] उपलब्ध आसा.‎", "nolinkstoimage": "ह्या फायलीक वापरतात तसलीं पानां नांत.", + "linkstoimage-redirect": "$1 (फायल पुनर्देशन) $2", "sharedupload-desc-here": "ही फयल $1 हांगाची आनी ती हे प्रकल्पां खातीर वापरल्यार चलता. (तिच्या $2 ह्या फयलींतलें वर्णनाचे पान) तातूंतलें वर्णन सकयल दिलां.", + "filepage-nofile": "ह्या नांवाची फायल असतित्वांत ना.", "upload-disallowed-here": "तूं ह्या फायलीचेर अधिलेखीत करूंक शकना", "randompage": "खंयचेंय पान", "statistics": "संख्याशास्त्र", "statistics-pages": "पान:", "statistics-files": "फायल अपलोड करात", + "double-redirect-fixer": "पुनर्निर्देशन थारावपी", "brokenredirects-edit": "बदल", "brokenredirects-delete": "काडून उडयात", "nbytes": "$1 {{PLURAL:$1|बाय्ट}}", "nmembers": "$1 {{PLURAL:$1|वांगडी}}", "prefixindex": "उपसर्ग आशिल्लीं सगळीं पानां", - "usercreated": "$1 ह्या दिसा $2 ह्या वेळार तयार केलें", + "listusers": "वापरप्यांची वळेरी", + "usercreated": "$3 हाणें $1 दिसा $2 वोराचेर {{GENDER:$3|रचलेलें}}", "newpages": "नवीं पानां", "move": "हालय", "pager-newer-n": "{{PLURAL:$1|नवो 1|नवें $1}}", @@ -568,12 +601,18 @@ "booksources": "पुस्तकांचो स्त्रोत", "booksources-search-legend": "पुस्तकाचे स्त्रोत सोदात", "booksources-search": "सोद", + "specialloguserlabel": "करपी:", + "speciallogtitlelabel": "मोख (माथाळो वा {{ns:user}}:वापरप्याचें नांव):", "log": "सोत्रां", + "all-logs-page": "सगळीं भौसाचीं सत्रां", + "alllogstext": "{{SITENAME}} हाच्यो सगळ्या उपलब्ध सत्रांची एकठांय दाखोवणी.\nतुज्यान तुजो देखावो अर्नूं येता एक सत्राचो प्रकार विंचून, वापरप्याचें नांव (व्हदल्या आनी धाकट्या अक्षरा मदें फरक पडटा), वा पोरणें जालेलें पान (हांगाय व्ह़डले आनी धाक्टे अक्षरा मदें फरक पडटा).‎", + "logempty": "सत्रान जुळपी नग नांत.‎", "allpages": "सगळीं पाना", "nextpage": "फुडलें पान ($1)", "prevpage": "फाटलें पान ($1)", "allarticles": "सगळीं पानां", "allpagessubmit": "वचात", + "allpages-hide-redirects": "पुनर्देर्शनां लिपय", "categories": "वर्ग", "linksearch-ns": "नांवाची सुवात", "linksearch-ok": "सोद", @@ -582,14 +621,18 @@ "listgrouprights-members": "सदस्यांची वळेरी", "emailuser": "ह्या वापरप्याक इमेल करात.", "emailusername": "वापरप्याचे नांव", + "usermessage-editor": "यंत्रणाचो संदेशकार", "watchlist": "सादुरवळेरी", "mywatchlist": "सादुरवळेरी", "watchlistfor2": "$1 $2 खातीर", "addedwatchtext": "\"[[:$1]]\" आनी हाचे भासाभास पान तुमचें [[Special:Watchlist|सादुरवळेरेक]] जोडलां.", "watch": "नदर दवरात", "unwatch": "पळोवंक नासलें", - "watchlist-details": "लक्ष {{PLURAL:$1|$1वळेरींतलें|$1 वळेंरींतली}} {{PLURAL:$1|$1पान|$1 पानां}} उलोवपाची पानां सोडून", + "watchlist-details": "तुज्या सादूरवळेरिंत {{PLURAL:$1|$1 पान आसा|$1 पानां आसात}} (त्या भायर उलोवपाचीं पानां आसात).", + "wlheader-showupdated": "तुज्या फाटले भेटे सावन बदल्ल्यान तीं पानां दाट दाखयल्यांत.", + "wlnote": "सकयल {{PLURAL:$1|हो निमाणो बदल|हें निमाण्यो $1 बदल}} निमाण्या {{PLURAL:$2|वोरान|$2वोरानीं}}, $3, $4 पर्यान.‎", "watchlist-options": "सादुरवळेरींतलो पर्याय", + "enotif_reset": "सगळीं पानां भेट दिलेलीं म्हूण खुणाय", "delete-legend": "काडून उडयात", "actioncomplete": "क्रिया पुराय जाल्या", "actionfailed": "क्रिया अपेस जाल्या", @@ -600,6 +643,8 @@ "changecontentmodel-reason-label": "कारण:", "protectlogpage": "सुरक्षितेचें सोत्र", "protectedarticle": "राखिल्ले\"[[$1]]\"", + "modifiedarticleprotection": "सुरक्षेची पातळी \"[[$1]]\"‎ हाचे खातीर बदल्ल्या", + "protect-default": "सगळ्या वापरप्यांक परवांगी दी", "restriction-edit": "बदल", "restriction-move": "दुसरेकडे व्हरात", "restriction-create": "निर्माण कर", @@ -616,6 +661,7 @@ "mycontris": "योगदान", "anoncontribs": "योगदान", "contribsub2": "{{GENDER:$3|$1}} हाच्यो ($2)", + "nocontribs": "ह्या निशकशांक खयंचेच बदल जूळ्ळेले मेळूंक नांत.", "uctop": "हालीचें", "month": "ह्या म्हयन्या सावन (आनी आदलें):", "year": "ह्या वर्सा सावन (आनी आदलें):", @@ -642,16 +688,19 @@ "whatlinkshere-hideredirs": "$1 पुनर्निर्देशन", "whatlinkshere-hidetrans": "$1 दुरास्थ-समावेस", "whatlinkshere-hidelinks": "$1 दुवे", - "whatlinkshere-hideimages": "$1 फायल दुवे", + "whatlinkshere-hideimages": "$1 फायलींचे दुवे", "whatlinkshere-filters": "गाळणे", "ipboptions": "2 वरां:2 hours,1 दीस:1 day,3 दीस:3 days,1 सुमान:1 week,2 सुमनां:2 weeks,1 म्हयनो:1 month,3 म्हयने:3 months,6 म्हयने:6 months,1 वर्स:1 year,शेवट ना:infinite", "ipblocklist": "आडायल्लें वापरपी", + "infiniteblock": "शेवट ना", "blocklink": "आडावणी", "change-blocklink": "विभाग सुदारप", "contribslink": "योगदान", "blocklogpage": "कार्यवळेरी आडायात", - "blocklogentry": "$2 $3 हो सोंपपी वेळ आशिल्लो $1 बंद दवरल्ला", + "blocklogentry": "[[$1]] आक आडायला, इतल्या वेळाक: $2, कारण: $3", + "reblock-logentry": "आडावपाचें बसोवप बदल्लां [[$1]] हाचे खातीर सोंपोवपाचो वेळ दिला $2 $3‎", "block-log-flags-nocreate": "खातें निर्माण जावूंक ना", + "proxyblocker": "प्रतिनिधी सिरविदोर आडावपी‎", "movepagebtn": "पान हालय", "movelogpage": "पान हालोवण्यांचो सोत्र", "revertmove": "मूळ पदार व्हरप", @@ -660,6 +709,7 @@ "allmessagesdefault": "पूर्वनिर्धारित संदेशाचो मजकूर", "thumbnail-more": "व्हड करात", "thumbnail_error": "$1ः लघुप्रतिमा करतांनाची चूक", + "importlogpage": "आयाताचें सत्र", "tooltip-pt-userpage": "{{GENDER:|तुमचें वापरप्याचें}} पान", "tooltip-pt-mytalk": "{{GENDER:|तुमचें}} भासाभासाचें पान", "tooltip-pt-preferences": "{{GENDER:|तुमची}} पसंती", @@ -703,6 +753,7 @@ "tooltip-ca-nstab-special": "हें एक खेरीत पान, आनी हें बदलूंक जायना", "tooltip-ca-nstab-project": "प्रकल्पाचें पान पळेयात", "tooltip-ca-nstab-image": "फायलीचें पान पळेयात", + "tooltip-ca-nstab-mediawiki": "यंत्रणाचो संदेश पळय", "tooltip-ca-nstab-template": "सांचो पळेयात", "tooltip-ca-nstab-category": "वर्गांचे पान पळेयात", "tooltip-minoredit": "हो ल्हानसो बदल म्हूण कुरू करात", @@ -715,11 +766,45 @@ "tooltip-undo": "\"आदलें स्थितीर हाडचें\" ह्या बदलाक परत व्हरुन संपादन स्थितीन झलक रितीन दाखयतात.\nहाचेवरवीं सारांशान आदल्या स्थितीर हाडपाचें कारण बरोवं शकता.", "tooltip-summary": "आपरोसाची नोंदणी करात", "simpleantispam-label": "स्पमविरूध तपासणी.\nहें भर नाका!", + "pageinfo-title": "\"$1\" ‎खातीर म्हायती", + "pageinfo-header-basic": "मूळ म्हायती", + "pageinfo-header-edits": "बदलाचो इतिहास", + "pageinfo-header-restrictions": "पानाची सुरक्षा", + "pageinfo-header-properties": "पानाचे गुणधर्म", + "pageinfo-display-title": "मांडलेलें माथाळें", + "pageinfo-default-sort": "डिफोल्ट आरीन मांडूंक चावी", + "pageinfo-length": "पानाची लांबाय (बायटांत)‎", + "pageinfo-article-id": "पानाचो आंक", + "pageinfo-language": "पानाच्या मजकुराची भास", + "pageinfo-content-model": "पानाच्या मजकुराचो नमुनो", + "pageinfo-robot-policy": "रोबोटां कडल्यान सुचेंत घालप", + "pageinfo-robot-index": "परवांगी आसा", + "pageinfo-robot-noindex": "परवांगी ना", + "pageinfo-watchers": "पानाचेर दिश्ट दवरतेल्यांचो आंकडो", + "pageinfo-few-watchers": "$1 परस थोडें {{PLURAL:$1|दिश्ट दवरपी}}‎", + "pageinfo-redirects-name": "ह्या पाना खातीर पुनर्निर्देशनांचो आंकडो", + "pageinfo-subpages-name": "ह्या पानाच्या ऊप-पानाचो आंकडो", + "pageinfo-subpages-value": "$1 ($2 {{PLURAL:$2|पुनर्निर्देशन|पुनर्निर्देशनां}}; $3 {{PLURAL:$3|पुनर्निर्देशन नासलेलें}})‎", + "pageinfo-firstuser": "पान रचपी", + "pageinfo-firsttime": "पान रचपाची तारीख", + "pageinfo-lastuser": "हालींचो संपादक", + "pageinfo-lasttime": "हालींच्या बदलाची तारीख", + "pageinfo-edits": "एकूण बदलाचो आंकडो", + "pageinfo-authors": "वेगळे बरोवप्यांचो एकूण आंकडो", + "pageinfo-recent-edits": "हालींच्या बदलांचे आंकडे (गेले $1)‎", + "pageinfo-recent-authors": "हालींचे वेगळे बरोवपी", + "pageinfo-magic-words": "{{PLURAL:$1|जादवाचें उतर|जादवाचीं उतरां}} ($1)‎", + "pageinfo-hidden-categories": "लिपयलेले {{PLURAL:$1|वर्ग}} ($1)", + "pageinfo-templates": "{{PLURAL:$1|सांचो दुरास्थ-समावेस जाला|सांचे दुरास्थ-समावेस जाले}} ($1)‎", "pageinfo-toolboxlink": "पानाची म्हायती", + "pageinfo-contentpage": "एक मजकुराचें पान कशें धरपांत आयलां", "pageinfo-contentpage-yes": "हय", + "patrol-log-page": "पारो करप्याचे सत्र", "previousdiff": "← आदलें संपादन", "nextdiff": "नवें संपादन →", + "widthheightpage": "$1 × $2, $3 {{PLURAL:$3|पान|पानां}}", "file-info-size": "$1 × $2 चित्रतत्व, फायलीचो आकार: $3, माइम प्रकार: $4", + "file-info-size-pages": "$1 × $2 चित्रत्वां, फायलिचो आकार: $3, MIME प्रकार: $4, $5 {{PLURAL:$5|पान|पानां}}‎", "file-nohires": "हाच्या परस वयले बारिक्साय उपल्बद ना", "svg-long-desc": "SVG फायल, नांवाक $1 × $2 चित्रतत्वां, फायलीचो आकार: $3", "show-big-image": "मुळावी फायल", @@ -734,22 +819,44 @@ "monthsall": "सगळे", "confirm-rollback-button": "बरें", "confirm-rollback-top": "ह्या पाना वयलें संपादन आशिल्ले तशें करात?", + "imgmultipagenext": "फुडलें पान →", + "imgmultigo": "वचात!", + "imgmultigoto": "$1 ‎पानार वचात", + "watchlisttools-clear": "सादूरवळेरी निवळ कर", "watchlisttools-view": "प्रस्तूत बदल पळयात.", "watchlisttools-edit": "सादुरवळेरी पळय आनी संपादीत करात", + "watchlisttools-raw": "सादूरवळेरिची मूळान बदल कर", "signature": "[[{{ns:user}}:$1|$2]] ([[{{ns:user_talk}}:$1|उलयात]])", + "redirect": "फायल, वापरपी, पान, उजळणी वा सत्र आंक‎ वर्वीं पुनर्देशन कर", + "redirect-summary": "हें विशेश पान पुनर्देशीत करता एका फायलीक (फायलीचें नांव दिल्यार), एका पानाक (उजळणेचो आंक वा पानाचो आंक दिल्यार), एक वापरप्याच्या पानाक (एके वापरप्याचो आंक दिल्यार), वा एक सत्र नोंद (सत्राचो आंक दिल्यार). वापर: [[{{#Special:Redirect}}/file/देखीक.jpg]], [[{{#Special:Redirect}}/page/64308]], [[{{#Special:Redirect}}/revision/328429]], [[{{#Special:Redirect}}/user/101]], vo [[{{#Special:Redirect}}/logid/186]].", "redirect-submit": "वचात", + "redirect-lookup": "सुचींत पळय:", "redirect-value": "मोल:", + "redirect-user": "वापरप्यांचो आंक", + "redirect-page": "पानाचो आंक", + "redirect-revision": "पानाची उजळणी", + "redirect-file": "फायलीचें नांव", "specialpages": "विशेश पानां", "tag-filter": "[[Special:Tags|कुर्वेचीट]] गाळणो:", "tag-list-wrapper": "[[Special:Tags|{{PLURAL:$1|कुरवेचीट|कुरवेचीटी}}]]: $2", "tags-active-yes": "हय", "tags-active-no": "ना", + "tags-hitcount": "$1 {{PLURAL:$1|बदल}}", "htmlform-title-not-exists": "$1 अस्तित्वांत ना.", "logentry-delete-delete": "$1 {{GENDER:$2|काडून उडयल्ले पान}} $3", + "logentry-delete-restore": "$1 हाणें {{GENDER:$2|परत हाडलां}} पान $3 ($4)‎", + "logentry-delete-revision": "$1 हाणें {{PLURAL:$5|उजळणेचें}} दिसणे $3, ह्या पानार {{GENDER:$2|बदल्ला}}: $4‎", + "revdelete-content-hid": "मजकूर लिपयला", "logentry-move-move": "$1 हाणें $3 पानाक $4 {{GENDER:$2|हालयला}}", + "logentry-move-move-noredirect": "$1, हाणें पान $3 सावन $4 {{GENDER:$2|हालयलां}} पुनर्देर्शन दवरिनासतानां", + "logentry-move-move_redir": "$1 हाणें पान $3 सावन $4 {{GENDER:$2||हालयल्लो}} पुनर्दिशनावयर", + "logentry-patrol-patrol-auto": "$1-आन $3, ह्या पानाचें $4, ह्या उजळणेचो पारो केलां म्हण आपोआप {{GENDER:$2|खुणायलां}}", "logentry-newusers-create": "उपयोगकत्याचें $1 {{GENDER:$2|तयार केलें}}", + "logentry-newusers-autocreate": "वापरप्याचें खातें $1 आपोआप {{GENDER:$2|रचून}} आयलें", "logentry-upload-upload": "$1 {{GENDER:$2|अपलोड केला}} $3", + "logentry-upload-overwrite": "$1, हाणें $3‎, हाची एक नवी आवृत्ती {{GENDER:$2|अपलोड केलां}}", "searchsuggest-search": "{{SITENAME}} सोद", + "duration-days": "$1 {{PLURAL:$1|दीस}}", "special-characters-group-latin": "रोमी", "special-characters-group-latinextended": "रोमी (आनिंक-उइ)", "special-characters-group-ipa": "IPA", @@ -771,5 +878,6 @@ "special-characters-group-khmer": "ख्मेर", "mw-widgets-dateinput-no-date": "तारीख निवडूंक ना", "mw-widgets-dateinput-placeholder-day": "वर्स-म्हयनो-दीस", - "mw-widgets-dateinput-placeholder-month": "वर्स-म्हयनो" + "mw-widgets-dateinput-placeholder-month": "वर्स-म्हयनो", + "randomrootpage": "खयंचेंय मूळ पान" } diff --git a/languages/i18n/gom-latn.json b/languages/i18n/gom-latn.json index 9f1f7067f4..6832f35fd6 100644 --- a/languages/i18n/gom-latn.json +++ b/languages/i18n/gom-latn.json @@ -375,18 +375,18 @@ "anoneditwarning": "Chotrai: Tuven sotrorombh korunk nai. Tu bodol korit zalear tuzo IP pot'to soglleank polleunk zatelem. Tu [$1 sotrorombh korit] vo [$2 kont rochit] zalear, tuje bodol tuzo vaporpeachem nanvak zoddteleo ani anik-ui faide asat.", "missingcommenttext": "Upkar korun tuzo xero boroi.", "blockedtitle": "Vapurpeak addaila", - "blockedtext": "Tujem vaporpeachem nanv vo IP pot'to addavpant aila.\n\nAddavop $1 hannem kelam.\nKaronn dilam tem $2.\n\n* Addavpachi survat: $8\n* Addavop sompovpacho vell: $6\n* Addavpak ievjila: $7\n\nTujean $1-ak vo dusrea [[{{MediaWiki:Grouppage-sysop}}|karbhariak]] addavnne bodol bhasabhas korunk sompork korunk zata. Tujean \"{{int:emailuser}}\" sobhavgunn vaprunk zaina kheriz ek void email pot'to tujea [[Special:Preferences|khatem posontint]] nischit kelea xivai ani tuka tem vaporpak addavnk na zalear. Tuzo chalont IP pot'to asa $3, ani addavnnecheo ank #$5 asa. Soglleo voileo bariksanno tum kortai tea vicharant somavex kor.", + "blockedtext": "Tujem vaporpeachem nanv vo IP pot'to addavpant aila.\n\nAddavop $1 hannem kelam.\nKaronn dilam tem $2.\n\n* Addavpachi survat: $8\n* Addavop sompovpacho vell: $6\n* Addavpak ievjila: $7\n\nTujean $1-ak vo dusrea [[{{MediaWiki:Grouppage-sysop}}|karbhariak]] addavnne vixim bhasabhas korunk sompork korunk zata. Tujean \"{{int:emailuser}}\" sobhavgunn vaprunk zaina kheriz ek void email pot'to tujea [[Special:Preferences|khatem posontint]] nischit kelea xivai ani tuka tem vaporpak addavnk na zalear. Tuzo chalont IP pot'to asa $3, ani addavnnecheo ank #$5 asa. Soglleo voileo bariksanno tum kortai tea vicharant somavex kor.", "blockednoreason": "Kainch karonn diunk na", "loginreqtitle": "Sotrorombh gorjechem", "loginreqlink": "sotrorombh kor", "accmailtitle": "Gupitutor dhaddlea", "newarticle": "(Novem)", "newarticletext": "Tuven ek duveche patlav kelai, zachem pan azun rochunk na.\nPan rochunk, khallchea chovkottan boroi (anik mahitik [$1 adar pan] polloi).\nTu hangasor chukin pavlai zalear tujea internet browser-achi Fatim vo Back butao dab.", - "anontalkpagetext": "----\nHem bhasabhasechem pan ek ninami vaporpeak zannem ozun ek khatem ugddunk na, vo to tem vaporna.\nHea khatir amkam ankddeancho IP pot'to vaprunk podta taka vollkhunk.\nToslo IP pot'to sabar vaporpeamni vaprum ieta.\nTum zor ek ninami vaporpi asa ani tuka dista ki sombondit xere tuje vixim keleat, upkar korun [[Special:CreateAccount|ek khatem roch]] vo [[Special:UserLogin|log in]] fuddle guspop ninami vaporpeanchem tallunk.‎", + "anontalkpagetext": "----\nHem bhasabhasechem pan ek ninami vaporpeak zannem ozun ek khatem ugddunk na, vo to tem vaporna.\nHea khatir amkam ankddeancho IP pot'to vaprunk podta taka vollkhunk.\nToslo IP pot'to sabar vaporpeamni vaprum ieta.\nTum zor ek ninami vaporpi asa ani tuka dista ki tukam sombond naslele xere tuje vixim keleat, upkar korun [[Special:CreateAccount|ek khatem roch]] vo [[Special:UserLogin|sotrarombh kor]] fuddle guspop ninami vaporpeanchem tallunk.‎", "noarticletext": "Sodheak hem pan ritem asa.\nTujean dusrea panani [[Special:Search/{{PAGENAME}}|hea panache nanv sodunk zata]], [{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} sombondhi sotrani sodunk zata], vo [{{fullurl:{{FULLPAGENAME}}|action=edit}} hem pan rochunk zata].", "noarticletext-nopermission": "Sodheak hem pan ritem asa.\nTujean dusrea panani [[Special:Search/{{PAGENAME}}|hea panache nanv sodunk zata]], vo [{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} sombondhi sotrani sodunk zata], pun tuka hem pan rochunk porvangi na.", "userpage-userdoesnotexist-view": "\"$1\" hea vapurpeachea khateachi nondnni korunk na.", - "clearyourcache": "Note: Samball’llea uprant, tuka ghoddiek tujea browseracho cache koddsoravnk poddot bodol pollonvche khatir.\n* Firefox / Safari: Shift dhor Reload klik kortana, vo dam Ctrl-F5 vo Ctrl-R (⌘-R Mac-acher)\n* Google Chrome: Ctrl-Shift-R dam (⌘-Shift-R eka Mac-acher)\n* Internet Explorer: Ctrl dhor Refresh klik kortana, vo dam Ctrl-F5\n* Opera: Hanga voch: Menu → Settings (Opera → Preferences Mac-acher) ani uprant Privacy & security → Clear browsing data → Cached images and files.‎", + "clearyourcache": "Chotrai: Samball’llea uprant, tuka ghoddiek tujea browseracho cache koddsoravnk poddot bodol pollonvche khatir.\n* Firefox / Safari: Shift dhor Reload klik kortana, vo dam Ctrl-F5 vo Ctrl-R (⌘-R Mac-acher)\n* Google Chrome: Ctrl-Shift-R dam (⌘-Shift-R eka Mac-acher)\n* Internet Explorer: Ctrl dhor Refresh klik kortana, vo dam Ctrl-F5\n* Opera: Hanga voch: Menu → Settings (Opera → Preferences Mac-acher) ani uprant Privacy & security → Clear browsing data → Cached images and files.‎", "previewnote": "Hem fokot ek zholok mhonn ugddas dhor.\nTuje bodol azun sambhallun dovrunk nant!", "continue-editing": "Sompadon korpachea zagear voch", "editing": "Sompadon kortai: $1", @@ -448,7 +448,7 @@ "editundo": "kel'lem portavchem", "diff-empty": "(Kaim forok na)‎", "diff-multi-sameuser": "(Heach vaporpean {{PLURAL:$1|kel'lo modlo ek bodol dakhounk na|kel'le modle $1 bodol dakhounk nan}})", - "diff-multi-otherusers": "({{PLURAL:$1|Ek modli uzollnni|$1 modleo uzollnneo}} {{PLURAL:$2|ek her vaporpi|$2 her vaporpi}}, hache vorvim dakhovnk na)‎", + "diff-multi-otherusers": "({{PLURAL:$2|Ek her vaporpea|$2 her vaporpeam}} vorvim {{PLURAL:$1|ek modli uzollnni|$1 modleo uzollnneo}} dakhovnk na)", "searchresults": "Sodache porinaman", "searchresults-title": "\"$1\" -khatir sodache porinaman", "prevn": "adlem {{PLURAL:$1|$1}}", @@ -520,6 +520,7 @@ "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} ([[Special:NewPages|nove pananchi suchi]]-ui polloi)", "rcfilters-tag-remove": "'$1' kadd", "rcfilters-legend-heading": "Sonkxepachi volleri:", + "rcfilters-group-results-by-page": "Pana pormonnem pongddache porinnam", "rcfilters-activefilters": "Kriaxil challnneo", "rcfilters-activefilters-hide": "Lipoi", "rcfilters-activefilters-show": "Dakhoi", @@ -541,7 +542,9 @@ "rcfilters-savedqueries-unsetdefault": "Default aslolem kaddun uddoi", "rcfilters-savedqueries-remove": "Kadun udoi", "rcfilters-savedqueries-new-name-label": "Nanv", + "rcfilters-savedqueries-new-name-placeholder": "Challnnecho hetu vornnon kor", "rcfilters-savedqueries-apply-label": "Challnni roch", + "rcfilters-savedqueries-apply-and-setdefault-label": "Default challnni roch", "rcfilters-savedqueries-cancel-label": "Rod'd kor", "rcfilters-savedqueries-add-new-title": "Chalont challnnechi manddavoll samball", "rcfilters-savedqueries-already-saved": "Heo challnneo adinch samball’lloleo asat. Ek novi Samball’lloli Challnni rochunk, tujeo manddavolleo bodol.", @@ -555,15 +558,21 @@ "rcfilters-filterlist-feedbacklink": "Hea challnnechea avtam vixim tuka kitem dista tem amkam sang", "rcfilters-highlightmenu-title": "Ek rong vinch", "rcfilters-filterlist-noresults": "Kosleoch challnneo mellunk nant", + "rcfilters-state-message-fullcoverage": "Hea pongddantle soglleo challnneo vinchop mhonnche kainch vinchop na, hea khatir he challnnek kainch porinnam na. Pongddant hacho somavex asa: $1", "rcfilters-filtergroup-authorship": "Iogdanachem borovp", "rcfilters-filter-editsbyself-label": "Tuven kel'leo bodol", "rcfilters-filter-editsbyself-description": "Tujeo svotacheo yogdanam.", "rcfilters-filter-editsbyother-label": "Dusreanim kel'le bodol", "rcfilters-filter-editsbyother-description": "Tuje khas bhairavn, soglle bodol", "rcfilters-filtergroup-user-experience-level": "Vaporpeachi nondnni ani onnbhov", + "rcfilters-filter-user-experience-level-registered-label": "Nondnni kelolem", "rcfilters-filter-user-experience-level-registered-description": "Sotrarombh zalole sompadok.", + "rcfilters-filter-user-experience-level-unregistered-label": "Nondnni korunk naslolem", + "rcfilters-filter-user-experience-level-unregistered-description": "Sompadok je sotrarombhit nant.", "rcfilters-filter-user-experience-level-learner-label": "Xikpi", + "rcfilters-filter-user-experience-level-learner-description": "Nondnni kelole sompadok zancho onnubhov \"Nove ievpi\" ani \"Onnbhovi vaporpi\" modem urta.", "rcfilters-filter-user-experience-level-experienced-label": "Onnbhovi vaporpi", + "rcfilters-filter-user-experience-level-experienced-description": "500 odik sompadon ani 30 disanchem kario aslolem nondnni kelolem sompadok.", "rcfilters-filtergroup-automated": "Apoap zalolem iogdan", "rcfilters-filter-bots-label": "Robot", "rcfilters-filter-bots-description": "Apoap avtamni kelolem sompadon", @@ -571,6 +580,9 @@ "rcfilters-filter-humans-description": "Monxani kelolem sompadon", "rcfilters-filter-reviewstatus-unpatrolled-description": "Paro kela mhonn hatan vo apoap khunnavnk naslolem sompadon.", "rcfilters-filter-reviewstatus-unpatrolled-label": "Paro korunk naslolem", + "rcfilters-filter-reviewstatus-manual-description": "Sompadon zaka paro kelam mhonn hatan khunnailam.", + "rcfilters-filter-reviewstatus-manual-label": "Hatan paro korpant ailolem", + "rcfilters-filter-reviewstatus-auto-label": "Apoap paro korpant ailolem", "rcfilters-filtergroup-significance": "Mhotv", "rcfilters-filter-minor-label": "Dhakte bodol", "rcfilters-filter-minor-description": "Borovpean dhaktem mhonn khunne chitt kelolem sompadon", @@ -578,9 +590,10 @@ "rcfilters-filter-major-description": "Dhaktem mhonn khunne chitt korunk naslolem sompadon", "rcfilters-filtergroup-watchlist": "Sadurvollerintlim panam", "rcfilters-filter-watchlist-watched-label": "Sadurvollerintlim", + "rcfilters-filter-watchlist-watched-description": "Tujea Sadurvollerichea panamche bodol.", "rcfilters-filter-watchlist-watchednew-label": "Sadurvolleriche nove bodol", "rcfilters-filter-watchlist-watchednew-description": "Bodol ghoddleat ten’na savn tuvem bhett divnk nant tea sadurvollerintlim panache bodol.", - "rcfilters-filter-watchlist-notwatched-label": "Sadurvollerintlim nhoi", + "rcfilters-filter-watchlist-notwatched-label": "Sadurvollerint na", "rcfilters-filter-watchlist-notwatched-description": "Sadurvollerichim panank bodol soddun her sogllem.", "rcfilters-filtergroup-watchlistactivity": "Sadurvollerichem kario", "rcfilters-filter-watchlistactivity-unseen-label": "Pollovnk naslole bodol", @@ -604,9 +617,13 @@ "rcfilters-view-tags": "Khunnechittichem sompadon", "rcfilters-view-tags-tooltip": "Sompadonacheo khunne chitti vaprun porinnam chall", "rcfilters-view-tags-help-icon-tooltip": "Khunnechittichem sompadona babtint odik xikun ghe", + "rcfilters-liveupdates-button-title-off": "Nove bodol ghoddtta ten’na dakhol kor", "rcfilters-watchlist-markseen-button": "Soglle bodol polleleat mhonn khunnai.", + "rcfilters-watchlist-edit-watchlist-button": "Nodor dovorlolea panachi volleri sompadon kor", "rcfilters-watchlist-showupdated": "Bodol zal'leak savn je panank tuvem bhett dinvk na, te bodol datt okxoramni, ani ghott khunnamni dileat.", + "rcfilters-filter-showlinkedfrom-option-label": "Vinchlolea panant savn zulltat tim panam", "rcfilters-filter-showlinkedto-label": "Panak zoddtat tea panache bodol dakhoi", + "rcfilters-filter-showlinkedto-option-label": "Vinchlolea panak zulltat tim pana", "rcfilters-target-page-placeholder": "Ek panache nanv ( vo vorg) ghal", "rcnotefrom": "Sokoil $3, $4 savn {{PLURAL:$5|zalelem bodol dilam|zalelem bodol dileant}} ($1 meren {{PLURAL:$5|dakhoilam|dakhoileant}}).", "rclistfrom": "$3 $2 savn suru zatelim nove bodol dakhoi", @@ -678,7 +695,7 @@ "filehist-comment": "Xero", "imagelinks": "Faylicho vapor", "linkstoimage": "{{PLURAL:$1|Hem pan|$1 Him panam}} hi fayl {{PLURAL:$1|vaporta|vaportat}}:", - "linkstoimage-more": "$1 poros odik {{PLURAL:$1|pan vaporta|panam vaporta}} hi fayl.\nSokoili volleri dakhoita {{PLURAL:$1|poilem pan|poilim $1 panam}} jem hich fayl vaporta. Ek [[Special:WhatLinksHere/$2|purnn volleri]] uplobdh asa.‎", + "linkstoimage-more": "$1 poros odik {{PLURAL:$1|pan vaporta|panam vaportat}} hi fayl.\nSokoili volleri dakhoita {{PLURAL:$1|poilem pan|poilim $1 panam}} jem hich fayl vaporta. Ek [[Special:WhatLinksHere/$2|purnn volleri]] uplobdh asa.‎", "nolinkstoimage": "Hea faylik vaportat toslim panam nant", "linkstoimage-redirect": "$1 (fayl punornirdexon) $2", "sharedupload-desc-here": "Hi fayl $1, hachi ani dusrea prokolpanim hachem upeog korunk zata.\nHachem [$2 faylichem vivron panan] asleli vivron khala dilea:", @@ -812,7 +829,7 @@ "change-blocklink": "Addavnnni bodol", "contribslink": "yogdan", "blocklogpage": "addavnnechem sotr", - "blocklogentry": "[[$1]] addailelem $2 asun vellacho ont: $3", + "blocklogentry": "[[$1]] ak addaila, itlea vellak: $2, karonn: $3", "reblock-logentry": "addavpachem bosovp bodol’lam [[$1]] hache khatir sompovpacho vell dila $2 $3‎", "block-log-flags-nocreate": "Khatem rochop opatr kelam", "proxyblocker": "Protinidhi-sirvidor addavpi‎", diff --git a/languages/i18n/he.json b/languages/i18n/he.json index 6480a93794..85c86adfd7 100644 --- a/languages/i18n/he.json +++ b/languages/i18n/he.json @@ -87,6 +87,7 @@ "tog-useeditwarning": "הצגת אזהרה בעת עזיבת דף עריכה עם שינויים שטרם נשמרו", "tog-prefershttps": "תמיד להשתמש בתקשורת מאובטחת לאחר הכניסה לחשבון", "tog-showrollbackconfirmation": "הצגת הודעת אישור לאחר לחיצה על קישור \"שחזור\"", + "tog-requireemail": "דרישת דואר אלקטרוני כדי לאפס סיסמה", "underline-always": "תמיד", "underline-never": "לעולם לא", "underline-default": "ברירת המחדל של העיצוב או של הדפדפן", @@ -788,9 +789,9 @@ "content-model-css": "CSS", "content-json-empty-object": "אובייקט ריק", "content-json-empty-array": "מערך ריק", - "unsupported-content-model": "אזהרה: מודל התוכן $1 אינו נתמך בוויקי הזה.", - "unsupported-content-diff": "השוואות אינן נתמכות במודל התוכן $1.", - "unsupported-content-diff2": "השוואות בין מודל התוכן $1 לבין מודל $2 אינן נתמכות בוויקי הזה.", + "unsupported-content-model": "אזהרה: מודל התוכן $1 אינו נתמך באתר הוויקי הזה.", + "unsupported-content-diff": "השוואה בין גרסאות אינה נתמכת במודל התוכן $1.", + "unsupported-content-diff2": "השוואה בין גרסאות ממודל התוכן $1 לגרסאות ממודל התוכן $2 אינה נתמכת באתר הוויקי הזה.", "deprecated-self-close-category": "דפים שמשתמשים בתגיות HTML עם סגירה עצמית בלתי־תקינה", "deprecated-self-close-category-desc": "הדף מכיל תגיות HTML עם סגירה עצמית בלתי־תקינה, כגון <b/> או <span/>. ההתנהגות של תגיות אלה תשתנה בקרוב לצורך תאימות עם מפרט HTML5, ולכן יש להימנע משימוש בהן בקוד ויקי.", "duplicate-args-warning": "אזהרה: [[:$1]] קורא לדף [[:$2]] עם יותר מערך אחד עבור הפרמטר \"$3\". ייעשה שימוש רק בערך האחרון.", @@ -826,6 +827,7 @@ "undo-norev": "לא ניתן היה לבטל את העריכה כי היא אינה קיימת או כי היא נמחקה.", "undo-nochange": "נראה שהעריכה כבר בוטלה.", "undo-summary": "ביטול גרסה $1 של [[Special:Contributions/$2|$2]] ([[User talk:$2|שיחה]])", + "undo-summary-anon": "ביטול גרסה $1 של [[Special:Contributions/$2|$2]]", "undo-summary-username-hidden": "ביטול גרסה $1 של משתמש מוסתר", "cantcreateaccount-text": "אפשרות יצירת החשבונות מכתובת ה־IP הזאת ($1) נחסמה על־ידי [[User:$3|$3]].\n\nהסיבה שניתנה על־ידי $3 היא: $2", "cantcreateaccount-range-text": "אפשרות יצירת החשבונות מכתובות IP בתוך הטווח $1, כולל כתובת ה־IP שלך ($4), נחסמה על־ידי [[User:$3|$3]].\n\nהסיבה שניתנה על־ידי $3 היא: $2", @@ -1123,6 +1125,7 @@ "prefs-help-email": "כתובת דואר אלקטרוני היא אופציונלית, אבל היא חיונית לאיפוס הסיסמה במקרה ש{{GENDER:|תשכח|תשכחי}} אותה.", "prefs-help-email-others": "באפשרותך גם לאפשר למשתמשים ליצור איתך קשר באמצעות דוא\"ל דרך קישור בדף המשתמש או בדף השיחה שלך.\nכתובת הדוא\"ל שלך לא תיחשף כשמשתמשים יצרו איתך קשר.", "prefs-help-email-required": "כתובת דואר אלקטרוני נדרשת לכתיבה באתר.", + "prefs-help-requireemail": "אם אפשרות זו סומנה, האתר ישלח הודעת דוא\"ל המאפשרת את איפוס הסיסמה רק לאחר שמי שביקש אותה יספק גם את שם המשתמש וגם את כתובת הדוא\"ל של החשבון הזה.", "prefs-info": "מידע בסיסי", "prefs-i18n": "בינאום", "prefs-signature": "חתימה", @@ -1760,8 +1763,8 @@ "backend-fail-contenttype": "לא ניתן היה לקבוע את סוג התוכן של הקובץ לאחסון ב־\"$1\".", "backend-fail-batchsize": "למאגר אחסון הקבצים הפנימי הועבר אוסף של {{PLURAL:$1|פעולת קובץ אחת|$1 פעולות קובץ}}; המגבלה היא {{PLURAL:$2|פעולה אחת|$2 פעולות}}.", "backend-fail-usable": "קריאת או כתיבת הקובץ \"$1\" לא הצליחה כיוון שההרשאות אינן מספיקות או כיוון שהספריות/המכלים חסרים.", - "backend-fail-stat": "לא היה אפשר לקרוא את המצב של הקובץ \"$1\".", - "backend-fail-hash": "לא היה אפשר להחליט מהו גיבוב ההצפנה של הקובץ \"$1\".", + "backend-fail-stat": "קריאת מצב הקובץ \"$1\" לא הצליחה.", + "backend-fail-hash": "מציאת ערך הגיבוב הקריפטוגרפי של הקובץ \"$1\" לא הצליחה.", "filejournal-fail-dbconnect": "לא ניתן היה להתחבר לבסיס הנתונים של היומן עבור מאגר אחסון הקבצים הפנימי \"$1\".", "filejournal-fail-dbquery": "לא ניתן היה לעדכן את בסיס הנתונים של היומן עבור מאגר אחסון הקבצים הפנימי \"$1\".", "lockmanager-notlocked": "פתיחת הנעילה של \"$1\" לא הצליחה; הוא לא נעול.", @@ -2342,6 +2345,7 @@ "alreadyrolled": "לא ניתן לשחזר את העריכה של [[User:$2|$2]] ([[User talk:$2|שיחה]]{{int:pipe-separator}}[[Special:Contributions/$2|{{int:contribslink}}]]) בדף [[:$1]];\nהדף כבר נערך או שוחזר.\n\nהעריכה האחרונה הייתה של [[User:$3|$3]] ([[User talk:$3|שיחה]]{{int:pipe-separator}}[[Special:Contributions/$3|{{int:contribslink}}]]).", "editcomment": "תקציר העריכה היה: $1.", "revertpage": "שוחזר מעריכות של [[Special:Contributions/$2|$2]] ([[User talk:$2|שיחה]]) לעריכה האחרונה של [[User:$1|$1]]", + "revertpage-anon": "שוחזר מעריכות של [[Special:Contributions/$2|$2]] לעריכה האחרונה של [[User:$1|$1]]", "revertpage-nouser": "שוחזר מעריכות של משתמש מוסתר לעריכה האחרונה של {{GENDER:$1|[[User:$1|$1]]}}", "rollback-success": "שוחזר מעריכות של {{GENDER:$3|$1}}\nלעריכה האחרונה של {{GENDER:$4|$2}}.", "sessionfailure-title": "בעיה בחיבור", @@ -2578,6 +2582,7 @@ "ipblocklist-legend": "מציאת משתמש חסום", "blocklist-userblocks": "הסתרת חסימות של משתמשים רשומים", "blocklist-tempblocks": "הסתרת חסימות זמניות", + "blocklist-indefblocks": "הסתרת חסימות בלתי מוגבלות בזמן", "blocklist-addressblocks": "הסתרת חסימות של כתובות IP בודדות", "blocklist-type": "סוג:", "blocklist-type-opt-all": "הכול", diff --git a/languages/i18n/io.json b/languages/i18n/io.json index 28cbba6d4a..d8070a01c5 100644 --- a/languages/i18n/io.json +++ b/languages/i18n/io.json @@ -1799,7 +1799,7 @@ "movepagetext": "Uzante ica formularo onu povas rinomizar pagino, movante olua omna versionaro ad la nova titulo.\nLa antea titulo konvertesos a ridirektilo a la nova titulo.\nLa ligili a la antea titulo dil pagino ne chanjesos.\nVoluntez certigar ke ne esas [[Special:DoubleRedirects|duopla]] o [[Special:BrokenRedirects|ruptota ridirektili]].\nVu responsas ke la ligili duros direktante a la pagino korespondanta.\n\nMemorez ke la pagino '''ne''' rinomizesos se ja existus pagino kun la nova titulo, eceptuante ke la pagino esas vakua o ridirektilo sen versionaro.\nIco signifikas ke vu povos rinomizar pagino a olua originala titulo se eroras skribante la nova titulo, ma ne povos riskribar existanta pagino.\n\n'''EGARDEZ!'''\nIca povas esar drastika chanjo e ne-esperinda por populara pagino;\nvoluntez certigar ke vu komprenas la konsequi qui eventos ante durar adavane.", "movepagetext-noredirectfixer": "Uzar la formulario infre rinomizos la pagino, e tota lua historio-listo a la nova nomo.\nL'anciena titulo ridirektesos a la nova titulo.\nVerifikez la [[Special:DoubleRedirects|duopla]] e/o la [[Special:BrokenRedirects|krevita ridirekti]].\nEsas vua responso verifikar se omna ligili esas korekta.\n\nVidez ke la pagino ne rinomizesos se existar pagino kun la sama titulo, ecepte se ol ridirektesas a la prezenta pagino e ne havas pasinta historio pri redaktado.\nTo signifikas ke vu povas retroe rinomizar pagino a lua antea nomo se ol rinomizesis erore, e ke vu ne povas supresar existanta pagino per ridirektado di altra pagino.\n\nAtencez:\nLa rinomizo povas esar drastika chanjo por pagini qui esas populara;\nhavez klara certezo pri la konsequi di la posibla rinomizo di la pagino, ante facar ol!", "movepagetalktext": "Se vu markizos ca buxo, la diskuto-pagino asociita anke modifikesos a la nova titulo, ecepte se diskuto-pagino nevakua ja existar ibe.\n\nCakaze, vu propra mustos movar la diskuto-pagino o mixar la du texti, se vu deziros.", - "movecategorypage-warning": "Atencez: Vu balde rinomizos pagino di \"KATEGORIO\". Nur la titulo di la kategorio chanjesos, ma nula pagino kategoriizita segun l'anciena kategorio modifikesos automatale por la nova kategorio.", + "movecategorypage-warning": "Atencez: Vu balde rinomizos pagino pri \"KATEGORIO\". Nur la titulo di la kategorio chanjesos, ma nula pagino kategoriizita segun l'anciena kategorio modifikesos automatale por la nova kategorio.", "movenologintext": "Vu mustas esar registragita uzero ed [[Special:UserLogin|enirir]] por rinomizar pagino.", "newtitle": "Nova titulo:", "move-watch": "Surveyar ca pagino", diff --git a/languages/i18n/jv.json b/languages/i18n/jv.json index 243c68cb9c..9a6d4474ef 100644 --- a/languages/i18n/jv.json +++ b/languages/i18n/jv.json @@ -3036,7 +3036,7 @@ "feedback-cancel": "Wurung", "feedback-close": "Rampung", "feedback-external-bug-report-button": "Kirim ayahan tèhnis", - "feedback-dialog-title": "Awèh saran", + "feedback-dialog-title": "Kirimi pamrayoga", "feedback-error1": "Masalah: Kasil ora dingertèni saka API", "feedback-error2": "Masalah: Besutané wurung", "feedback-error3": "Masalah: Ora ana tanggepan saka API", diff --git a/languages/i18n/ka.json b/languages/i18n/ka.json index ffdeba8468..94aeafd84a 100644 --- a/languages/i18n/ka.json +++ b/languages/i18n/ka.json @@ -1008,6 +1008,7 @@ "prefs-watchlist-edits": "კონტროლის სიაში საჩვენებელი ცვლილებების მაქსიმალური რაოდენობა:", "prefs-watchlist-edits-max": "მაქსიმალური რაოდენობა: 1000", "prefs-watchlist-token": "კონტროლის სიის ტოკენი:", + "prefs-watchlist-managetokens": "ტოკენების მართვა", "prefs-misc": "სხვადასხვა", "prefs-resetpass": "შეცვალეთ პაროლი", "prefs-changeemail": "ელ-ფოსტის მისამართის შეცვლა ან წაშლა", diff --git a/languages/i18n/lv.json b/languages/i18n/lv.json index b50b012412..ed6500b81d 100644 --- a/languages/i18n/lv.json +++ b/languages/i18n/lv.json @@ -192,7 +192,7 @@ "history": "hronoloģija", "history_short": "Vēsture", "history_small": "vēsture", - "updatedmarker": "atjaunināts kopš mana pēdējā apmeklējuma", + "updatedmarker": "atjaunināts kopš tava pēdējā apmeklējuma", "printableversion": "Drukājama versija", "permalink": "Pastāvīgā saite", "print": "Drukāt", @@ -599,7 +599,7 @@ "anonpreviewwarning": "''Tu neesi ienācis. Saglabājot lapu, Tava IP adrese tiks ierakstīta šīs lapas hronoloģijā.''", "missingsummary": "'''Atgādinājums''': Tu neesi norādījis izmaiņu kopsavilkumu. Vēlreiz klikšķinot uz \"Saglabāt lapu\", Tavas izmaiņas tiks saglabātas bez kopsavilkuma.", "missingcommenttext": "Lūdzu, ievadi komentāru.", - "missingcommentheader": "'''Atgādinājums:''' Tu šim komentāram neesi norādījis virsrakstu/tematu.\nJa tu vēlreiz spiedīsi uz \"$1\", tavas izmaiņas tiks saglabātas bez virsraksta.", + "missingcommentheader": "Atgādinājums: Šim komentāram nav norādīts temats.\nVēlreiz spiežot uz \"$1\", tavs labojums tiks saglabāts bez tā.", "summary-preview": "Labojuma kopsavilkuma priekšskatījums:", "subject-preview": "Temata pirmskats:", "blockedtitle": "Dalībnieks ir bloķēts.", @@ -666,6 +666,8 @@ "nocreate-loggedin": "Tev nav atļaujas veidot jaunas lapas.", "sectioneditnotsupported-title": "Sadaļa rediģēšana nav atbalstīta", "sectioneditnotsupported-text": "Sadaļu rediģēsana šajā lapā nav atļauta.", + "modeleditnotsupported-title": "Labošana nav atbalstīta", + "modeleditnotsupported-text": "Satura modelim \"$1\" labošana nav atbalstīta.", "permissionserrors": "Atļauju kļūda", "permissionserrorstext": "Tev nav atļauts veikt šo darbību {{PLURAL:$1|šādu iemeslu|šāda iemesla|šādu iemeslu}} dēļ:", "permissionserrorstext-withaction": "Tev nav atļauts $2 {{PLURAL:$1|šādu iemeslu|šāda iemesla|šādu iemeslu}} dēļ:", @@ -689,6 +691,7 @@ "editpage-invalidcontentmodel-text": "Satura modelis \"$1\" nav atbalstīts.", "editpage-notsupportedcontentformat-title": "Satura formāts nav atbalstīts", "editpage-notsupportedcontentformat-text": "Satura formātu $1 neatbalsta satura modelis $2.", + "slot-name-main": "Galvenais", "content-model-wikitext": "vikiteksts", "content-model-text": "vienkāršs teksts", "content-model-javascript": "JavaScript kods", @@ -1637,6 +1640,7 @@ "prefixindex": "Meklēt pēc virsraksta pirmajiem burtiem", "prefixindex-namespace": "Visas lapas ar prefiksu ($1 vārdtelpa)", "prefixindex-submit": "Rādīt", + "prefixindex-strip": "Rezultātos paslēpt prefiksu", "shortpages": "Īsākās lapas", "longpages": "Garākās lapas", "deadendpages": "Lapas bez izejošām saitēm", @@ -1864,6 +1868,7 @@ "dellogpagetext": "Šajā lapā ir pēdējo dzēsto lapu saraksts.", "deletionlog": "dzēšanas reģistrs", "log-name-create": "Lapu izveides žurnāls", + "logentry-create-create": "$1 {{GENDER:$2|izveidoja}} lapu $3", "reverted": "Atjaunots uz iepriekšējo versiju", "deletecomment": "Iemesls:", "deleteotherreason": "Cits/papildu iemesls:", @@ -1889,8 +1894,8 @@ "sessionfailure": "Ir radusies problēma ar sesijas autentifikāciju;\nšī darbība ir atcelta, lai novērstu lietotājvārda iespējami ļaunprātīgu izmantošanu.\nLūdzu, spied \"''back''\" un atjaunini iepriekšējo lapu. Tad mēģini vēlreiz.", "changecontentmodel": "Mainīt lapas satura modeli", "changecontentmodel-legend": "Mainīt satura modeli", - "changecontentmodel-title-label": "Lapas nosaukums", - "changecontentmodel-model-label": "Jauns satura modelis", + "changecontentmodel-title-label": "Lapas nosaukums:", + "changecontentmodel-model-label": "Jaunais satura modelis:", "changecontentmodel-reason-label": "Iemesls:", "changecontentmodel-submit": "Mainīt", "changecontentmodel-success-title": "Satura modelis tika izmainīts", @@ -2203,7 +2208,7 @@ "fix-double-redirects": "Automātiski izmainīt visas pāradresācijas, kas ved uz sākotnējo nosaukumu", "move-leave-redirect": "Atstāt pāradresāciju", "protectedpagemovewarning": "'''Brīdinājums:''' Šī lapa ir aizsargāta, tikai lietotāji ar administratora privilēģijām var to pārvietot.\nPēdējais reģistra ieraksts ir apskatāms zemāk:", - "semiprotectedpagemovewarning": "'''Piezīme:''' Šī lapa ir aizsargāta, tikai reģistrētie lietotāji var to pārvietot.\nPēdējais reģistra ieraksts ir apskatāms zemāk:", + "semiprotectedpagemovewarning": "Piezīme: Šī lapa ir aizsargāta tā, lai tikai pašpārbaudītie lietotāji varētu to pārvietot.\nPēdējais reģistra ieraksts ir apskatāms zemāk:", "move-over-sharedrepo": "[[:$1]] jau pastāv koplietotā repozitorijā. Pārvietošana uz šo nosaukumu aizstās koplietoto failu.", "file-exists-sharedrepo": "Šis faila nosaukums jau tiek izmantots kopīgajā failu krātuvē.\nLūdzu, izvēlies citu nosaukumu.", "export": "Eksportēt lapas", @@ -2265,7 +2270,7 @@ "importcantopen": "Nevarēja atvērt importējamo failu", "importbadinterwiki": "Slikta starpviki saite", "importsuccess": "Importēšana pabeigta!", - "importnosources": "Tiešā hronoloģijas augšuplāde ir atslēgta. Nav definēts neviens ''Transwiki'' importa avots (''source'').", + "importnosources": "Nav definēta neviena vikivietne, no kuras importēt un tiešā hronoloģijas augšupielāde ir atslēgta.", "importnofile": "Neviens importējamais fails netika augšupielādēts.", "importuploaderrorsize": "Augšupielādēt importējamo failu neizdevās. \nŠis fails ir lielāks par atļauto augšupielādes lielumu.", "importuploaderrorpartial": "Importējamā faila augšupielāde neizdevās.\nFails tika tikai daļēji importēts.", @@ -2323,6 +2328,7 @@ "tooltip-feed-atom": "Šīs lapas Atom barotne", "tooltip-t-contributions": "{{GENDER:$1|Šī dalībnieka|Šīs dalībnieces}} ieguldījumu uzskaitījums", "tooltip-t-emailuser": "Sūtīt e-pastu {{GENDER:$1|šim dalībniekam|šai dalībniecei}}", + "tooltip-t-info": "Vairāk informācijas par šo lapu", "tooltip-t-upload": "Augšupielādēt failus", "tooltip-t-specialpages": "Visu īpašo lapu uzskaitījums", "tooltip-t-print": "Drukājama lapas versija", @@ -2727,8 +2733,10 @@ "diff-form-submit": "Parādīt atšķirības", "permanentlink": "Pastāvīgā saite", "permanentlink-revid": "Versijas ID", + "permanentlink-submit": "Doties uz versiju", "newsection": "Jauna sadaļa", "newsection-page": "Mērķa lapa", + "newsection-submit": "Doties uz lapu", "dberr-problems": "Atvainojiet!\nŠai vietnei ir radušās tehniskas problēmas.", "dberr-again": "Uzgaidiet dažas minūtes un pārlādējiet šo lapu.", "dberr-info": "(Nevar piekļūt datubāzei: $1)", @@ -2748,6 +2756,7 @@ "htmlform-chosen-placeholder": "Izvēlieties iespēju", "htmlform-cloner-create": "Pievienot vairāk", "htmlform-cloner-delete": "Noņemt", + "htmlform-cloner-required": "Vismaz viena vērtība ir obligāta.", "htmlform-date-placeholder": "GGGG-MM-DD", "htmlform-title-not-creatable": "\"$1\" nav izveidojams lapas nosaukums", "htmlform-title-not-exists": "$1 nepastāv.", @@ -2899,6 +2908,7 @@ "randomrootpage": "Nejauša saknes lapa", "log-action-filter-block": "Bloķēšanas veids:", "log-action-filter-protect": "Aizsardzības veids:", + "log-action-filter-rights": "Tiesību izmaiņas veids:", "log-action-filter-suppress": "Cenzēšanas veids:", "log-action-filter-upload": "Augšupielādes veids:", "log-action-filter-block-unblock": "Atbloķēšana", diff --git a/languages/i18n/mk.json b/languages/i18n/mk.json index 410e3abded..37611e221c 100644 --- a/languages/i18n/mk.json +++ b/languages/i18n/mk.json @@ -71,6 +71,7 @@ "tog-useeditwarning": "Предупреди ме кога сакам да напуштам страница за уредување без да ги имам зачувано промените", "tog-prefershttps": "Секогаш најавувај ме преку безбедна врска", "tog-showrollbackconfirmation": "Прикажи потврдница при стискање на врската за отповикување", + "tog-requireemail": "Барај е-пошта за ставање нова лозинка", "underline-always": "Секогаш", "underline-never": "Никогаш", "underline-default": "Според рувото или прелистувачот", @@ -1114,6 +1115,7 @@ "prefs-help-email": "Е-поштата е незадолжителна, но ќе ви треба за добивање на нова лозинка ако си ја заборавите постоечката.", "prefs-help-email-others": "Можете да изберете другите да ве контактираат преку вашата корисничка страница без да го откриете вашиот идентитет.", "prefs-help-email-required": "Е-поштенска адреса е задолжително да се наведе.", + "prefs-help-requireemail": "Ако е штиклирано, можноста за нова лозинка ќе ја имаат само корисниците што навеле корисничко име и е-пошта.", "prefs-info": "Основни информации", "prefs-i18n": "Јазик", "prefs-signature": "Потпис", @@ -2571,6 +2573,7 @@ "ipblocklist-legend": "Најди блокиран корисник", "blocklist-userblocks": "Скриј блокирања на корис. сметки", "blocklist-tempblocks": "Скриј привремени блокирања", + "blocklist-indefblocks": "Скриј бесконечни блокови", "blocklist-addressblocks": "Скри блокирања на поединечни IP-адреси", "blocklist-type": "Вид:", "blocklist-type-opt-all": "Сите", diff --git a/languages/i18n/my.json b/languages/i18n/my.json index cd64fb3c78..fef0de86ad 100644 --- a/languages/i18n/my.json +++ b/languages/i18n/my.json @@ -2417,8 +2417,11 @@ "tag-mw-undo": "နောက်ပြန် ပြန်ပြင်ခြင်း", "tags-title": "အမည်တွဲများ", "tags-tag": "အမည်တွဲ အမည်", + "tags-display-header": "ပြောင်းလဲချက် စာရင်းများပေါ်တွင် ပေါ်ထင်မှု", "tags-description-header": "ဆိုလိုရင်းအဓိပ္ပာယ် အပြည့်အစုံ", "tags-source-header": "ရင်းမြစ်", + "tags-active-header": "သက်ဝင်?", + "tags-hitcount-header": "အမည်တွဲထားသော ပြောင်းလဲမှုများ", "tags-actions-header": "ဆောင်ရွက်ချက်များ", "tags-active-yes": "မှန်", "tags-active-no": "မလုပ်ပါ", diff --git a/languages/i18n/nb.json b/languages/i18n/nb.json index 7ccdd86e45..88c7bc7299 100644 --- a/languages/i18n/nb.json +++ b/languages/i18n/nb.json @@ -100,6 +100,7 @@ "tog-useeditwarning": "Si ifra dersom jeg forlater en side uten å lagre den.", "tog-prefershttps": "Bruk alltid en trygg forbindelse når du er innlogget", "tog-showrollbackconfirmation": "Be om bekreftelse når man klikker på en tilbakestillingslenke", + "tog-requireemail": "Krev epost for tilbakestilling av passord", "underline-always": "Alltid", "underline-never": "Aldri", "underline-default": "Drakta eller nettleserens standardinnstillinger", @@ -840,6 +841,7 @@ "undo-norev": "Redigeringen kunne ikke fjernes fordi den ikke eksisterer eller ble slettet", "undo-nochange": "Det ser ut til at redigeringen allerede er tilbakestilt.", "undo-summary": "Fjerner revisjon $1 av [[Special:Contributions/$2|$2]] ([[User talk:$2|diskusjon]])", + "undo-summary-anon": "Fjerner revisjon $1 av [[Special:Contributions/$2|$2]]", "undo-summary-username-hidden": "Fjern revisjon $1 av en skjult bruker", "cantcreateaccount-text": "Kontooppretting fra denne IP-adressen ('''$1''') har blitt blokkert av [[User:$3|$3]].\n\nGrunnen som ble oppgitt av $3 er ''$2''", "cantcreateaccount-range-text": "Opprettelsen av en brukerkonto fra IP-adresser i intervallet $1, som inneholder din IP-adresse ($4), er blitt blokkert av [[User:$3|$3]].\n\nÅrsaken angitt av $3 er $2", @@ -1137,6 +1139,7 @@ "prefs-help-email": "Å angi e-postadresse er valgfritt, men er nødvendig for å få tilsendt nytt passord om du skulle glemme det gamle.", "prefs-help-email-others": "Du kan også velge å la andre brukere kontakte deg via brukersiden din uten å røpe identiteten din.", "prefs-help-email-required": "E-postadresse er påkrevd.", + "prefs-help-requireemail": "Hvis denne er valgt vil vi kunne sende eposter om tilbakestilling av passord dersom den som ber om det oppgir både brukernavn og epostadresse for kontoen.", "prefs-info": "Grunnleggende informasjon", "prefs-i18n": "Internasjonalisering", "prefs-signature": "Signatur", @@ -2353,6 +2356,7 @@ "alreadyrolled": "Kan ikke fjerne den siste redigeringen på [[$1]] av [[User:$2|$2]] ([[User talk:$2|diskusjon]]{{int:pipe-separator}}[[Special:Contributions/$2|{{int:contribslink}}]]); en annen har allerede redigert siden eller fjernet redigeringen.\n\nDen siste redigeringen ble foretatt av [[User:$3|$3]] ([[User talk:$3|diskusjon]]{{int:pipe-separator}}[[Special:Contributions/$3|{{int:contribslink}}]]).", "editcomment": "Redigeringskommentaren var: $1", "revertpage": "Tilbakestilte endringer av [[Special:Contributions/$2|$2]] ([[User talk:$2|brukerdiskusjon]]) til siste versjon av [[User:$1|$1]]", + "revertpage-anon": "Tilbakestilte endringer av [[Special:Contributions/$2|$2]] til siste versjon av [[User:$1|$1]]", "revertpage-nouser": "Tilbakestilt endringer av skjult bruker til siste versjon av\n{{GENDER:$1|[[User:$1|$1]]}}", "rollback-success": "Tilbakestilte endringer av {{GENDER:$3|$1}}; endret til siste versjon av {{GENDER:$4|$2}}.", "sessionfailure-title": "Sesjonsfeil", diff --git a/languages/i18n/nds-nl.json b/languages/i18n/nds-nl.json index 4bf2965b23..626fbc8642 100644 --- a/languages/i18n/nds-nl.json +++ b/languages/i18n/nds-nl.json @@ -23,49 +23,49 @@ "PiefPafPier" ] }, - "tog-underline": "Verwiezingen onderstrepen", - "tog-hideminor": "Kleine wiezigingen verbargen in \"Leste wiezigingen\"", - "tog-hidepatrolled": "Wiezigingen die emarkeerd bin verbargen in \"Leste wiezigingen\"", - "tog-newpageshidepatrolled": "Ziejen die emarkeerd bin, verbargen in de lieste mit nieje artikels", - "tog-extendwatchlist": "Volglieste uutbreien, zodat alle wiezigingen zichtbaor bin, en niet allinnig de leste wieziging", - "tog-usenewrc": "Groepeer wiezigingen per zied in \"Leste wiezigingen\" en \"Mien volglieste\"", - "tog-numberheadings": "Koppen vanzelf nummeren", - "tog-editondblclick": "Mit dubbelklik bewarken", - "tog-editsectiononrightclick": "Bewarken van deelziejen meugelik maken mit n rechtermuusklik op n tussenkop", - "tog-watchcreations": "Spul wa'k anmake op mien volglieste zetten", - "tog-watchdefault": "Spul wa'k bewarke op mien volglieste zetten", - "tog-watchmoves": "Spul wa'k herneume op mien volglieste zetten", - "tog-watchdeletion": "Spul wa'k vortdo op mien volglieste zetten", - "tog-watchrollback": "Ziejen waorvan ik bewarkingen weerummedreid hebbe automaties volgen", - "tog-minordefault": "Markeer alle veraanderingen as 'kleine wieziging'", - "tog-previewontop": "De naokiekzied boven t bewarkingsveld zetten", - "tog-previewonfirst": "Naokieken bie eerste wieziging", - "tog-enotifwatchlistpages": "Stuur mien n berichjen over zied- of bestaandswiezigingen uut mien volglieste.", - "tog-enotifusertalkpages": "Stuur mien n berichjen as mien overlegzied ewiezigd is.", - "tog-enotifminoredits": "Stuur mien oek n berichjen bie kleine bewarkingen van ziejen en bestaanden", - "tog-enotifrevealaddr": "Mien netpostadres laoten zien in netposttiejigen", - "tog-shownumberswatching": "t Antal gebrukers bekieken die disse zied volgt", - "tog-oldsig": "Bestaonde haandtekening:", - "tog-fancysig": "Ondertekening zien as wikitekste (zonder automatiese verwiezing)", - "tog-uselivepreview": "Gebruuk \"rechtstreeks naokieken\"", - "tog-forceeditsummary": "Geef n melding bie n lege samenvatting", - "tog-watchlisthideown": "Verbarg mien eigen bewarkingen", - "tog-watchlisthidebots": "Verbarg botgebrukers", - "tog-watchlisthideminor": "Verbarg kleine wiezigingen in mien volglieste", - "tog-watchlisthideliu": "Bewarkingen van an-emelde gebrukers op mien volglieste verbargen", - "tog-watchlisthideanons": "Bewarkingen van anonieme gebrukers op mien volglieste verbargen", - "tog-watchlisthidepatrolled": "Wiezigingen die emarkeerd bin op volglieste verbargen", - "tog-ccmeonemails": "Stuur mien kopieën van berichten an aandere gebrukers", - "tog-diffonly": "Laot de inhoud van ziejen niet onder de an-egeven wiezigingen zien.", - "tog-showhiddencats": "Laot verbörgen kategorieën zien", - "tog-norollbackdiff": "Wiezigingen vortlaoten nao t weerummedreien", - "tog-useeditwarning": "Waorschuw mien a'k n bewörken zied aof wil sluten die nog niet op-esleugen is", - "tog-prefershttps": "Altied n beveiligde verbiending gebruken a'j an-emeld bin", - "underline-always": "Altied", + "tog-underline": "Verwysingen understreapen", + "tog-hideminor": "Kleine wysigingen verbargen in \"Lätste wysigingen\"", + "tog-hidepatrolled": "Wysigingen dee markeerd binnet verbargen in \"Lätste wysigingen\"", + "tog-newpageshidepatrolled": "Syden dee markeerd binnet, verbargen in de lyste mid nye artikels", + "tog-extendwatchlist": "Volglyste uutbreiden, sodat alle wysigingen sichtbår binnet, en neet allinnig de lätste wysigingen", + "tog-usenewrc": "Gruppeer wysigingen per syde in \"Lätste wysigingen\" en \"Myn volglyste\"", + "tog-numberheadings": "Upskrivten vanselv nummeren", + "tog-editondblclick": "Mid dubbelklik bewarken", + "tog-editsectiononrightclick": "Bewarken van deylsyden möägelik maken mid een rechtermuusklik up een tüskenupskrivt", + "tog-watchcreations": "Spül wat ik anmake up myn volglyste setten", + "tog-watchdefault": "Spül wat ik bewarke up myn volglyste setten", + "tog-watchmoves": "Spül wat ik hernöme up myn volglyste setten", + "tog-watchdeletion": "Spül wat ik vordsmyte up myn volglyste setten", + "tog-watchrollback": "Syden wårvan ik bewarkingen weaderümmedraid hebbe automatisk volgen", + "tog-minordefault": "Markeer alle veranderingen as 'kleine wysiging'", + "tog-previewontop": "De nåkyksyde boaven et bewarkingsveld setten", + "tog-previewonfirst": "Nåkyken by eyrste wysiging", + "tog-enotifwatchlistpages": "Stüür my een bericht oaver syd- of bestandswysigingen uut myn volglyste.", + "tog-enotifusertalkpages": "Stüür my een bericht as myn oaverlegsyde wysigd is.", + "tog-enotifminoredits": "Stüür my ouk een bericht by kleine bewarkingen van syden en bestanden", + "tog-enotifrevealaddr": "Myn e-postadres låten seen in e-postberichten", + "tog-shownumberswatching": "Et antal brukers bekyken dee disse syde volgt", + "tog-oldsig": "Bestånde handteykening:", + "tog-fancysig": "Underteykening seen as wikitekst (sunder automatiske verwysing)", + "tog-uselivepreview": "Nåkyksyde låten seen sunder eyrst te herladen", + "tog-forceeditsummary": "Geav een melding by een leadige samenvatting", + "tog-watchlisthideown": "Verbarg myn eigen bewarkingen", + "tog-watchlisthidebots": "Verbarg botbrukers", + "tog-watchlisthideminor": "Verbarg kleine wysigingen in myn volglyste", + "tog-watchlisthideliu": "Bewarkingen van anmeldede brukers up myn volglyste verbargen", + "tog-watchlisthideanons": "Bewarkingen van anonyme brukers up myn volglyste verbargen", + "tog-watchlisthidepatrolled": "Wysigingen dee markeerd binnet up volglyste verbargen", + "tog-ccmeonemails": "Stüür my kopien van berichten an andere brukers", + "tog-diffonly": "Under wysigingen neet de syde-inhold låten seen.", + "tog-showhiddencats": "Låt verbörgen kategoryen seen", + "tog-norollbackdiff": "Wysigingen vordlåten nå et weaderümmedraien", + "tog-useeditwarning": "Wårschüw my as ik een bewarkede syde afsluten wil dee noch neet seakerd is", + "tog-prefershttps": "Altyd een beveiligde verbinding bruken as jy anmelded binnet", + "underline-always": "Altyd", "underline-never": "Nooit", - "underline-default": "Standard in joew vormgeving of webkieker", - "editfont-style": "Lettertype veur de tekste t bewarkingsveld:", - "editfont-monospace": "Lettertype waorvan t tekenbreedte vaste steet", + "underline-default": "Standard in juw formgeaving of webkyker", + "editfont-style": "Lettertype vöär de tekst in et bewarkingsveld:", + "editfont-monospace": "Lettertype wårvan de teykenbreydte vast steyt", "editfont-sansserif": "Sans-seriflettertype", "editfont-serif": "Seriflettertype", "sunday": "sündag", @@ -96,7 +96,7 @@ "december": "december", "january-gen": "januåri", "february-gen": "februåri", - "march-gen": "meert", + "march-gen": "määrt", "april-gen": "april", "may-gen": "mei", "june-gen": "juni", @@ -105,7 +105,7 @@ "september-gen": "september", "october-gen": "oktober", "november-gen": "november", - "december-gen": "desember", + "december-gen": "december", "jan": "jan", "feb": "feb", "mar": "mrt", @@ -118,9 +118,9 @@ "oct": "okt", "nov": "nov", "dec": "dec", - "january-date": "$1 jannewaori", - "february-date": "$1 febrewaori", - "march-date": "$1 meert", + "january-date": "$1 januåri", + "february-date": "$1 februåri", + "march-date": "$1 määrt", "april-date": "$1 april", "may-date": "$1 mei", "june-date": "$1 juni", @@ -129,42 +129,42 @@ "september-date": "$1 september", "october-date": "$1 oktober", "november-date": "$1 november", - "december-date": "$1 desember", + "december-date": "$1 december", "pagecategories": "{{PLURAL:$1|Kategory|Kategoryen}}", "category_header": "Artikels in kategory $1", - "subcategories": "Subkategorieën", - "category-media-header": "Media in kategorie \"$1\"", - "category-empty": "''In disse kategoria staon op t moment nog gien artikels of media.''", + "subcategories": "Subkategoryen", + "category-media-header": "Media in kategory \"$1\"", + "category-empty": "In disse kategory stån up et moment noch geen syden of media.", "hidden-categories": "Verbörgen {{PLURAL:$1|kategory|kategoryen}}", - "hidden-category-category": "Verbörgen kategorieën", + "hidden-category-category": "Verbörgen kategoryen", "category-subcat-count": "{{PLURAL:$2|Disse kategory hevt de volgende subkategory.|Disse kategory hevt de volgende {{PLURAL:$1|subkategory|$1 subkategoryen}}, van in totaal $2.}}", - "category-subcat-count-limited": "Disse kategorie hef de volgende {{PLURAL:$1|subkategorie|$1 subkategorieën}}.", + "category-subcat-count-limited": "Disse kategory hevt de volgende {{PLURAL:$1|subkategory|$1 subkategoryen}}.", "category-article-count": "{{PLURAL:$2|In disse kategory steyt allinnig de volgende syde.|De volgende {{PLURAL:$1|syde steyt|$1 syden stån}} in disse kategory, van in totaal $2.}}", - "category-article-count-limited": "In disse kategorie {{PLURAL:$1|steet de volgende zied|staon de volgende $1 ziejen}}.", - "category-file-count": "In disse kategorie {{PLURAL:$2|steet t volgende bestaand|staon de volgende $1 bestaanden, van in totaal $2}}.", - "category-file-count-limited": "In disse kategorie {{PLURAL:$1|steet t volgende bestaand|staon de volgende $1 bestaanden}}.", + "category-article-count-limited": "In disse kategory {{PLURAL:$1|steyt de volgende syde|stån de volgende $1 syden}}.", + "category-file-count": "In disse kategory {{PLURAL:$2|steyt et volgende bestand|stån de volgende $1 bestanden, van in totaal $2}}.", + "category-file-count-limited": "In disse kategory {{PLURAL:$1|steyt et volgende bestand|stån de volgende $1 bestanden}}.", "listingcontinuesabbrev": "(vervolg)", - "index-category": "Te indexeren ziejen", + "index-category": "Te indekseren syden", "noindex-category": "Syden dee neet indexeerd binnen", - "broken-file-category": "Ziejen mit verkeerde bestaandsverwiezingen", - "about": "Informasie", + "broken-file-category": "Syden mid verkeyrde bestandsverwysingen", + "about": "Informaty", "article": "Artikel", - "newwindow": "(niej vienster)", + "newwindow": "(ny vinster)", "cancel": "Afbreaken", - "moredotdotdot": "Meer...", - "morenotlisted": "Disse lieste is niet kompleet...", - "mypage": "Gebrukerszied", + "moredotdotdot": "Meyr...", + "morenotlisted": "Disse lyste is möägelik neet kompleet.", + "mypage": "Brukerssyde", "mytalk": "Myn oaverleg", "anontalk": "Oaverleg", "navigation": "Navigaty", "and": " en", - "faq": "Vragen die vake esteld wörden", - "actions": "Haandeling", + "faq": "Vake stelde vrågen", + "actions": "Handelingen", "namespaces": "Naamruumdes", "variants": "Varianten", "navigation-heading": "Navigatymenü", "errorpagetitle": "Foutmelding", - "returnto": "Weerumme naor $1.", + "returnto": "Weaderümme nå $1.", "tagline": "Van {{SITENAME}}", "help": "Hülpe", "search": "Söken", @@ -176,50 +176,50 @@ "updatedmarker": "bie-ewörken sinds mien leste bezeuk", "printableversion": "Afdrükbåre versy", "permalink": "Vaste verwysing", - "print": "Aofdrokken", + "print": "Afdrükken", "view": "Leasen", "view-foreign": "Bekyken up $1", "edit": "Bewarken", "edit-local": "Lokale beschrieving bewarken", "create": "Anmaken", - "create-local": "Lokale beschrieving derbie doon", - "delete": "Vortdoon", - "undelete_short": "$1 {{PLURAL:$1|versie|versies}} weerummeplaotsen", - "viewdeleted_short": "{{PLURAL:$1|Eén versie die vortedaon is|$1 versies die vortedaon bin}} bekieken", + "create-local": "Lokale beskryving tovogen", + "delete": "Vordsmyten", + "undelete_short": "$1 {{PLURAL:$1|versy|versys}} weaderümmeplaatsen", + "viewdeleted_short": "{{PLURAL:$1|Eyn versy dee vordsmeaten is|$1 versys dee vortsmeaten binnet}} bekyken", "protect": "Beveiligen", - "protect_change": "wiezigen", + "protect_change": "wysigen", "unprotect": "Beveiliging wysigen", - "newpage": "Nieje zied", + "newpage": "Nye syde", "talkpagelinktext": "Oaverleg", "specialpage": "Speciale syde", "personaltools": "Persoonlike instellingen", "talk": "Oaverleg", "views": "Weadergåven", - "toolbox": "Hülpmiddels", - "tool-link-userrights": "{{GENDER:$1|Gebrukersgruppen}} wysigen", - "tool-link-emailuser": "Disse {{GENDER:$1|gebruker}} een bericht stüren", - "imagepage": "Bestaandszied bekieken", - "mediawikipage": "Tiejige bekieken", - "templatepage": "Mal bekieken", - "viewhelppage": "Hulpzied bekieken", - "categorypage": "Kategoriezied bekieken", - "viewtalkpage": "Bekiek overlegzied", + "toolbox": "Warktügen", + "tool-link-userrights": "{{GENDER:$1|Brukersgruppen}} wysigen", + "tool-link-emailuser": "Disse {{GENDER:$1|bruker}} een bericht stüren", + "imagepage": "Bestandssyde bekyken", + "mediawikipage": "Berichtsyde bekyken", + "templatepage": "Mal bekyken", + "viewhelppage": "Hülpsyde bekyken", + "categorypage": "Kategorysyde bekyken", + "viewtalkpage": "Bekyk oaverlegsyde", "otherlanguages": "Andere språken", "redirectedfrom": "(döärstüürd vanaf \"$1\")", - "redirectpagesub": "Deurverwieszied", - "redirectto": "Deurverwiezen naor:", + "redirectpagesub": "Döärverwyssyde", + "redirectto": "Döärverwysen nå:", "lastmodifiedat": "Disse syde is et lätst wysigd up $1 üm $2.", - "viewcount": "Disse zied is $1 {{PLURAL:$1|keer|keer}} bekeken.", - "protectedpage": "Beveiligden zied", + "viewcount": "Disse syde is $1 {{PLURAL:$1|keyr}} bekeaken.", + "protectedpage": "Beveiligde syde", "jumpto": "Gå nå:", "jumptonavigation": "navigaty", "jumptosearch": "söök", - "view-pool-error": "De servers bin op heden overbelast.\nTe veule gebrukers proberen disse zied te bekieken.\nWacht effen veurda'j opniej toegang proberen te kriegen tot disse zied.\n\n$1", - "generic-pool-error": "De servers bin op heden overbelast.\nTe veule gebrukers proberen disse zied te bekieken.\nWacht effen veurda'j opniej toegang proberen te kriegen tot disse zied.", - "pool-timeout": "De maximumwachttied veur databankvergrendeling is verleupen.", - "pool-queuefull": "De wachtrie van de poel is vol", - "pool-errorunknown": "Onbekende fout", - "pool-servererror": "De dienst \"pool counter\" is niet beschikbaor ($1).", + "view-pool-error": "De servers binnet momenteel oaverbelasted.\nTe vöäle lüde proberet disse syde te bekyken.\nWacht evven vöärdat jy upny togang proberet te krygen tot disse syde.\n\n$1", + "generic-pool-error": "De servers binnet momenteel oaverbelasted.\nTe vöäle lüde proberet disse syde te bekyken.\nWacht evven vöärdat jy upny togang proberet te krygen tot disse syde.", + "pool-timeout": "De maksimumwachttyd vöär databankvergrendeling is verlöypen.", + "pool-queuefull": "De wachtryge van de pool is vul", + "pool-errorunknown": "Unbekende faut", + "pool-servererror": "De deenst \"pool counter\" is neet beskikbår ($1).", "aboutsite": "Oaver {{SITENAME}}", "aboutpage": "Project:Info", "copyright": "De inhoud is beschikbaor onder de $1 as der niks aanders an-egeven is.", @@ -228,8 +228,8 @@ "currentevents-url": "Project:In et nys", "disclaimers": "Vöärbehold", "disclaimerpage": "Project:Vöärbehold", - "edithelp": "Hulpe mit bewarken", - "helppage-top-gethelp": "Hulpe", + "edithelp": "Hülpe mid bewarken", + "helppage-top-gethelp": "Hülpe", "mainpage": "Vöärblad", "mainpage-description": "Vöärblad", "policy-url": "Project:Beleid", @@ -237,100 +237,100 @@ "portal-url": "Project:Gemeynskapsportaal", "privacy": "Gegeavensbeleid", "privacypage": "Project:Gegeavensbeleid", - "badaccess": "Gien toestemming", - "badaccess-group0": "Je hebben gien toestemming um disse aksie uut te voeren.", - "badaccess-groups": "Disse aksie kan allinnig uutevoerd wörden deur gebrukers uut {{PLURAL:$2|de groep|één van de groepen}}: $1.", - "versionrequired": "Versie $1 van MediaWiki is neudig", - "versionrequiredtext": "Versie $1 van MediaWiki is neudig um disse zied te gebruken. Zie [[Special:Version|Versie]].", - "ok": "Best", + "badaccess": "Geen tostemming", + "badaccess-group0": "Jy hebbet geen tostemming üm disse akty uut te voren.", + "badaccess-groups": "Disse akty kan allinnig uutvoord wörden döär brukers uut {{PLURAL:$2|de grup|eyn van de gruppen}}: $1.", + "versionrequired": "Versy $1 van MediaWiki is nöydig", + "versionrequiredtext": "Versy $1 van MediaWiki is nöydig üm disse syde te bruken. See [[Special:Version|Versy]].", + "ok": "Okee", "retrievedfrom": "Van \"$1\"", - "youhavenewmessages": "Je hebben $1 ($2).", - "youhavenewmessagesfromusers": "Je hebben $1 van {{PLURAL:$3|n aandere gebruker|$3 gebrukers}} ($2).", - "youhavenewmessagesmanyusers": "Je hebben $1 van n bulte gebrukers ($2).", - "newmessageslinkplural": "{{PLURAL:$1|n niej bericht|999=nieje berichten}}", - "newmessagesdifflinkplural": "leste {{PLURAL:$1|wieziging|999=wiezigingen}}", + "youhavenewmessages": "{{PLURAL:$3|Jy hebbet}} $1 ($2).", + "youhavenewmessagesfromusers": "{{PLURAL:$4|Jy hebbet}} $1 van {{PLURAL:$3|een andere bruker|$3 brukers}} ($2).", + "youhavenewmessagesmanyusers": "Jy hebbet $1 van een bült brukers ($2).", + "newmessageslinkplural": "{{PLURAL:$1|een ny bericht|999=nye berichten}}", + "newmessagesdifflinkplural": "läste {{PLURAL:$1|wysiging|999=wysigingen}}", "youhavenewmessagesmulti": "Jy hebbet nye berichten up $1", "editsection": "bewark", "editold": "bewark", - "viewsourceold": "brontekste bekyken", + "viewsourceold": "brontekst bekyken", "editlink": "bewark", "viewsourcelink": "brontekst bekyken", "editsectionhint": "Bewarkingsveld: $1", "toc": "Inhold", - "showtoc": "Bekieken", - "hidetoc": "Verbarg", + "showtoc": "bekyken", + "hidetoc": "verbargen", "collapsible-collapse": "Inklappen", "collapsible-expand": "Uutklappen", - "confirmable-confirm": "{{GENDER:$1|Bi'j}} daor wisse van?", + "confirmable-confirm": "{{GENDER:$1|Bin jy}} dår wisse van?", "confirmable-yes": "Ja", - "confirmable-no": "Nee", - "thisisdeleted": "Bekieken of herstellen van $1?", - "viewdeleted": "Bekiek $1?", - "restorelink": "{{PLURAL:$1|versie die vortedaon is|versies die vortedaon bin}}", - "feedlinks": "Voer:", - "feed-invalid": "Voertype wörden niet ondersteunt.", - "feed-unavailable": "Syndicakievoer is niet beschikbaor", - "site-rss-feed": "$1 RSS-voer", - "site-atom-feed": "$1 Atom-voer", - "page-rss-feed": "\"$1\" RSS-voer", - "page-atom-feed": "\"$1\" Atom-voer", + "confirmable-no": "Ney", + "thisisdeleted": "Bekyken of herstellen van $1?", + "viewdeleted": "Bekyk $1?", + "restorelink": "{{PLURAL:$1|versy dee vordsmeaten is|versys dee vordsmeaten binnet}}", + "feedlinks": "Voder:", + "feed-invalid": "Vodertype wördt neet understöänt.", + "feed-unavailable": "Syndikatyvoder is neet beskikbår", + "site-rss-feed": "$1 RSS-voder", + "site-atom-feed": "$1 Atom-voder", + "page-rss-feed": "\"$1\" RSS-voder", + "page-atom-feed": "\"$1\" Atom-voder", "red-link-title": "$1 (syde besteyt noch neet)", - "sort-descending": "Aoflopend sorteren", - "sort-ascending": "Oplopend sorteren", - "nstab-main": "Artikel", - "nstab-user": "Gebruker", - "nstab-media": "Media", + "sort-descending": "Afloupend sorteren", + "sort-ascending": "Uploupend sorteren", + "nstab-main": "Syde", + "nstab-user": "Brukerssyde", + "nstab-media": "Mediasyde", "nstab-special": "Speciale syde", "nstab-project": "Projektsyde", "nstab-image": "Bestand", - "nstab-mediawiki": "Bericht", + "nstab-mediawiki": "Systeembericht", "nstab-template": "Mal", "nstab-help": "Hülpe", "nstab-category": "Kategory", "mainpage-nstab": "Vöärblad", - "nosuchaction": "De op-egeven haandeling besteet niet", - "nosuchactiontext": "De opdrachte in t webadres in ongeldig.\nJe hebben t webadres misschien verkeerd in-etikt of de verkeerde verwiezing evolgd.\nDit kan oek dujen op n fout in de programmatuur van {{SITENAME}}.", - "nosuchspecialpage": "Der besteet gien spesiale zied mit disse naam", - "nospecialpagetext": "Disse spesiale zied wörden niet herkend deur de programmatuur.\n\nn Lieste mit bestaonde spesiale ziejen ku'j vienen op [[Special:SpecialPages|{{int:specialpages}}]].", - "error": "Foutmelding", - "databaseerror": "Fout in de databanke", - "databaseerror-text": "Der is wat mis egaon bie n databankzeukopdrachte.\nDit kan betekenen dat der n fout in de programmtuur zit.", - "databaseerror-textcl": "Der is wat mis egaon bie n databankzeukopdrachte.", - "databaseerror-query": "Zeukopdrachte: $1", - "databaseerror-function": "Funksie: $1", - "databaseerror-error": "Fout: $1", - "laggedslavemode": "Waorschuwing: t is meugelik dat leste wiezigingen in de tekste van dit artikel nog niet verwarkt bin.", + "nosuchaction": "De upgeaven handeling besteyt neet", + "nosuchactiontext": "De updracht in et webadres in ungeldig.\nJy hebbet et webadres meskeen verkeyrd intyped of de verkeyrde verwysing volgd.\nDit kan ouk düden up een faut in de programmatuur van {{SITENAME}}.", + "nosuchspecialpage": "Der besteyt geen speciale syde mid disse name", + "nospecialpagetext": "Disse speciale syde wördt neet herkend döär de programmatuur.\n\nEen lyste mid bestånde speciale syden kün jy vinden up [[Special:SpecialPages|{{int:specialpages}}]].", + "error": "Faut", + "databaseerror": "Databankfaut", + "databaseerror-text": "Der is wat mis gån by een databanksöökupdracht.\nDit kan beteykenen dat der een faut in de programmtuur sit.", + "databaseerror-textcl": "Der is wat mis gån by een databanksöökupdracht.", + "databaseerror-query": "Söökupdracht: $1", + "databaseerror-function": "Funkty: $1", + "databaseerror-error": "Faut: $1", + "laggedslavemode": "Wårschüwing: et kan weasen dat de lätste wysigingen up disse syde noch neet upnöämen binnet.", "readonly": "De databanke is beveiligd", - "enterlockreason": "Waorumme en veur hoe lange is t eblokkeerd?", - "readonlytext": "De databanke van {{SITENAME}} is noen esleuten veur nieje bewarkingen en wiezigingen, warschienlik veur bestaandsonderhoud. De verantwoordelike systeembeheerder gaf hierveur de volgende reden op: '''$1'''", - "missing-article": "In de databanke steet gien tekste veur de zied \"$1\" die der wel in zol mutten staon ($2).\n\nDit kan koemen deurda'j n ouwe verwiezing naor t verschil tussen twee versies van n zied volgen of n versie opvragen die vortedaon is.\n\nAs dat niet zo is, dan he'j misschien n fout in de programmatuur evunnen.\nMeld t dan effen bie n [[Special:ListUsers/sysop|systeembeheerder]] van {{SITENAME}} en vermeld derbie de internetverwiezing van disse zied.", - "missingarticle-rev": "(versienummer: $1)", - "missingarticle-diff": "(Wieziging: $1, $2)", - "readonly_lag": "De databanke is automaties beveilig, zodat de ondergeschikten servers zich kunnen synchroniseren mit de sentrale server.", - "internalerror": "Interne fout", - "internalerror_info": "Interne fout: $1", - "filecopyerror": "Kon bestaand \"$1\" niet naor \"$2\" kopiëren.", - "filerenameerror": "Bestaandsnaamwieziging \"$1\" naor \"$2\" niet meugelik.", - "filedeleteerror": "Kon bestaand \"$1\" niet vortdoon.", - "directorycreateerror": "Map \"$1\" kon niet an-emaakt wörden.", - "directoryreadonlyerror": "De map \"$1\" is allinnig-lezen.", - "directorynotreadableerror": "De map \"$1\" kan niet elezen wörden.", - "filenotfound": "Kon bestaand \"$1\" niet vienen.", - "unexpected": "Onverwachten weerde: \"$1\"=\"$2\".", - "formerror": "Fout: kon formulier niet versturen", - "badarticleerror": "Disse haandeling kan op disse zied niet uutevoerd wörden.", - "cannotdelete": "De zied of t bestaand \"$1\" kon niet vortedaon wörden.\nt Kan ween dat n aander t al vortedaon hef.", - "cannotdelete-title": "Zied \"$1\" kan niet vortedaon wörden", - "delete-hook-aborted": "t Vortdoon wördt in t wiere eschopt deur n toepassige van MediaWiki.\nDer is gien veerdere informasie beschikbaor.", - "no-null-revision": "Kon gien lege nieje versie maken veur de zied \"$1\"", - "badtitle": "Ongeldige naam", - "badtitletext": "De naam van de op-evreugen zied is niet geldig, leeg, of n interwiki-verwiezing naor n onbekende of ongeldige wiki.", - "perfcached": "Disse gegevens koemen uut t tussengeheugen en bin misschien niet aktueel. Der {{PLURAL:$1|is hooguut een resultaot|bin hooguut $1 resultaoten}} beschikbaor in t tussengeheugen.", - "perfcachedts": "Disse gegevens koemen uut t tussengeheugen die veur t lest bie-ewörken is op $2 um $3. Der {{PLURAL:$4|is hooguut een resultaot|bin hooguut $4 resultaoten}} beschikbaor in t tussengeheugen.", - "querypage-no-updates": "'''Disse zied wördt niet meer bie-ewörken.'''", + "enterlockreason": "Voor een readen in vöär de vergrendeling, en geav up wanneyr et ungeaver vrygeaven wördt.", + "readonlytext": "De databanke is up et moment slöäten vöär nye inbreng en andere wysigingen, wårskynlik vöär rutinemåtig underhold, wårnå et weader lös geyt. \n\nDe systeembeheyrder gav hyrvöär de volgende readen up: $1", + "missing-article": "In de databanke steyt geen tekst vöär de syde \"$1\" dee der wel in sol mütten stån ($2).\n\nDit geböärt meystentyds as jy een olde verwysing nå et verskil tüsken twey versys van een syde volgen of as jy een versy upvrågen dee vordsmeaten is.\n\nAs dat neet so is, dan heb jy meskeen een faut in de programmatuur evünden.\nMeld et dan by een [[Special:ListUsers/sysop|systeembeheyrder]], en vermeld et webadres derby.", + "missingarticle-rev": "(versynummer: $1)", + "missingarticle-diff": "(Wysiging: $1, $2)", + "readonly_lag": "De databanke is automatisk vergrendeld terwyl de undergeskikede servers sik synchroniseren künnet mid de centrale server.", + "internalerror": "Interne faut", + "internalerror_info": "Interne faut: $1", + "filecopyerror": "Kun bestand \"$1\" neet nå \"$2\" kopieren.", + "filerenameerror": "\"$1\" kun neet hernöömd wörden nå \"$2\".", + "filedeleteerror": "Bestand \"$1\" kun neet vordsmeaten wörden.", + "directorycreateerror": "De map \"$1\" kun neet anmaked wörden.", + "directoryreadonlyerror": "De map \"$1\" is allinnig-leasen.", + "directorynotreadableerror": "De map \"$1\" kan neet leasen wörden.", + "filenotfound": "Bestand \"$1\" kun neet vünden wörden.", + "unexpected": "Unverwachtede waerde: \"$1\"=\"$2\".", + "formerror": "Faut: kun formulier neet verstüren", + "badarticleerror": "Disse handeling kan up disse syde neet uutvoord wörden.", + "cannotdelete": "De syde of et bestand \"$1\" kun neet vordsmeaten wörden.\nEt kan weasen dat een ander et al vordsmeaten hevt.", + "cannotdelete-title": "Syde \"$1\" kan neet vordsmeaten wörden", + "delete-hook-aborted": "Et vordsmyten wördt in et wyre skopped döär een topassing van MediaWiki.\nDer is wyder geen informaty beskikbår.", + "no-null-revision": "Kun geen leadige nye versy maken vöär de syde \"$1\"", + "badtitle": "Ungeldige name", + "badtitletext": "De name van de upvrågde syde is neet geldig, leadig, of der stünd een verkeyrde interspråk- of interwikiverwysing in.\nMöägelik binnet der eyn of meyr teykens bruked dee neet in titels tostån binnet.", + "perfcached": "Disse gegeavens kummen uut et tüskengehöägen en binnet meskeen neet aktueel. Der {{PLURAL:$1|is houguut eyn resultaat|binnet houguut $1 resultaten}} beskikbår in et tüskengehöägen.", + "perfcachedts": "Disse gegeavens kummen uut et tüskengehöägen dee vöär et lätst bywarked is up $2 üm $3. Der {{PLURAL:$4|is houguut eyn resultaat|binnet houguut $4 resultaten}} beskikbår in et tüskengehöägen.", + "querypage-no-updates": "Disse syde wördt neet bywarked.\nGegeavens up disse syde wördet neet vervarsd.", "viewsource": "Brontekst bekyken", - "viewsource-title": "Bron bekieken van $1", - "actionthrottled": "Haandeling tegenehöllen", + "viewsource-title": "Bron bekyken van $1", + "actionthrottled": "Handeling teagenholden", "actionthrottledtext": "As maotregel tegen t plaotsen van alderhaande moek, is t antal keren da'j disse haandeling in n korte tied uutvoeren kunnen beteund. Je hebben de limiet overschrejen. Probeer t over n antal minuten weer.", "protectedpagetext": "Disse zied is beveiligd. Bewarken of aandere haandelingen bin niet meugelik.", "viewsourcetext": "Je kunnen de brontekste van disse zied bewarken en bekieken.", @@ -534,10 +534,10 @@ "anoneditwarning": "Waorschuwing: je bin niet an-emeld.\nJoew IP-adres zal op-esleugen wörden a'j wiezigingen op disse zied anbrengen. A'j je eigen [$1 anmelden] of [$2 inschrieven] dan koemen joew bewarkingen onder joew gebrukersnaam te staon, samen mit aandere veurdelen.", "anonpreviewwarning": "''Je bin niet an-emeld.''\n''Deur de bewarking op te slaon wörden joew IP-adres op-esleugen in de ziedgeschiedenisse.''", "missingsummary": "'''Herinnering:''' je hebben gien samenvatting op-egeven veur de bewarking. A'j noen weer op ''Opslaon'' klikken wörden de bewarking zonder samenvatting op-esleugen.", - "missingcommenttext": "Plaots joew opmarking hieronder.", + "missingcommenttext": "Skryv een upmarking.", "missingcommentheader": "Waorschuwing: je hebben der gien onderwarptitel bie ezet. A'j noen weer op \"$1\" klikken, dan wörden de bewarking op-esleugen zonder onderwarptitel.", - "summary-preview": "Samenvatting naokieken:", - "subject-preview": "Onderwarp naokieken:", + "summary-preview": "Samenvatting nåkyken:", + "subject-preview": "Underwarp nåkyken:", "blockedtitle": "Gebruker is eblokkeerd", "blockedtext": "Juw brukersname of IP-adres is blokkeerd.\n\nJy binnet blokkeerd döär $1.\nDe upgeaven readen is $2.\n\n* Blokkeerd vanaf: $8\n* Blokkeerd tot: $6\n* Bedoold üm te blokkeren: $7\n\nJy künnet kontakt upneamen mid $1 of een andere [[{{MediaWiki:Grouppage-sysop}}|beheyrder]] üm de blokkering te bepråten.\nJy künnet de funkty \"{{int:emailuser}}\" neet bruken, behalven as jy een geldig e-postadres in juw [[Special:Preferences|instellingen]] upgeaven hebbet en et gebruuk van disse funkty neet blokkeerd is.\nEt IP-adres wat jy nu bruket is $3, en et blokkeringsnummer is #$5.\nVermeld de gegeavens dee hyrboaven stån as jy argens up disse blokkering reageren.", "autoblockedtext": "Joew IP-adres is automaties eblokkeerd umdat t gebruukt wördt deur n aandere gebruker, die eblokkeerd wördt deur $1.\nDe reden hierveur was:\n\n:''$2''\n\n* Begint: $8\n* Löp of nao: $6\n* Wee eblokkeerd wördt: $7\n\nJe kunnen kontakt opnemen mit $1 of n van de aandere\n[[{{MediaWiki:Grouppage-sysop}}|beheerders]] um de blokkering te bepraoten.\n\nNB: je kunnen de opsie \"n bericht sturen\" niet gebruken, behalven a'j n geldig netpostadres op-egeven hebben in de [[Special:Preferences|gebrukersveurkeuren]] en je niet eblokkeerd bin.\n\nJoew IP-adres is $3 en joew blokkeernummer is $5.\nGeef disse nummers deur a'j kontakt mit ene opnemen over de blokkering.", @@ -671,7 +671,7 @@ "histfirst": "Eerste", "histlast": "Leste", "historysize": "({{PLURAL:$1|1 byte|$1 bytes}})", - "historyempty": "(leeg)", + "historyempty": "leadig", "history-feed-title": "Wiezigingsoverzichte", "history-feed-description": "Wiezigingsoverzichte veur disse zied op de wiki", "history-feed-item-nocomment": "$1 op $2", @@ -803,7 +803,7 @@ "search-section": "(onderwarp $1)", "search-file-match": "(kümt oavereyne mid de inhold van et bestand)", "search-suggest": "Bedoelden je: $1", - "search-interwiki-caption": "Zusterprojekten", + "search-interwiki-caption": "Resultaten van süsterprojekten", "search-interwiki-default": "Resultaoten van $1:", "search-interwiki-more": "(meer)", "search-relatedarticle": "Verwaant", @@ -1087,22 +1087,22 @@ "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}}
(see ouk de [[Special:NewPages|lyste mid nye syden]])", "recentchanges-submit": "Bekiek", "rcfilters-legend-heading": "Lyste mid afkortingen:", - "rcfilters-group-results-by-page": "Resultaoten per zied groeperen", + "rcfilters-group-results-by-page": "Resultaten per syde grupperen", "rcfilters-activefilters": "Aktive filters", "rcfilters-activefilters-hide": "Verbarg", "rcfilters-activefilters-show": "Bekiek", "rcfilters-activefilters-hide-tooltip": "Verbarg aktive filters", "rcfilters-activefilters-show-tooltip": "Laot aktive filters seen", - "rcfilters-limit-title": "Resultåten üm te låten seen", + "rcfilters-limit-title": "Resultaten üm te låten seen", "rcfilters-limit-and-date-label": "$1 {{PLURAL:$1|wysiging|wysigingen}}, $2", "rcfilters-date-popup-title": "Tydsperiode üm te döärsöken", "rcfilters-days-title": "De vöärbye dagen", "rcfilters-hours-title": "De lätste uren", "rcfilters-days-show-days": "$1 {{PLURAL:$1|dag|dagen}}", "rcfilters-days-show-hours": "$1 {{PLURAL:$1|uur|uren}}", - "rcfilters-quickfilters": "Upeslöägen filters", + "rcfilters-quickfilters": "Seakerde filters", "rcfilters-quickfilters-placeholder-title": "Noch geen filters up-eslöägen", - "rcfilters-quickfilters-placeholder-description": "Üm juuw filterinstellingen up te slån en et låter te gebruken, klik up et bladwyserikoon underan by \"Aktive filters\".", + "rcfilters-quickfilters-placeholder-description": "Üm juw filterinstellingen te seakeren en et later te herbruken, klik up et bladwyserpiktogram underan by \"Aktive filters\".", "rcfilters-savedqueries-apply-label": "Instellingen opslaon", "rcfilters-savedqueries-cancel-label": "Aofbreken", "rcfilters-savedqueries-add-new-title": "Filterinstellingen seakeren", @@ -1111,7 +1111,7 @@ "rcfilters-show-new-changes": "Låt nyste wysigingen seen", "rcfilters-search-placeholder": "Filter wysigingen (bruuk et menü of söök up filtername)", "rcfilters-filterlist-feedbacklink": "Låt uns weaten wat jy van disse (nye) filterhülpmiddels vinden", - "rcfilters-highlightbutton-title": "Resultåten markeren", + "rcfilters-highlightbutton-title": "Resultaten markeren", "rcfilters-highlightmenu-title": "Kies n kleur", "rcfilters-filtergroup-user-experience-level": "Gebrukersanmelding en ervåring", "rcfilters-filter-user-experience-level-registered-label": "An-emeld", @@ -1147,7 +1147,7 @@ "rcfilters-filter-newpages-description": "Bewarkingen wårmead jy een nye syde anmaket.", "rcfilters-filter-categorization-label": "Kategorywysigingen", "rcfilters-filter-categorization-description": "Upgave van syden dee to-evoogd of vordedån wörden uut kategoryen.", - "rcfilters-filter-logactions-label": "Eregistreerde aktys", + "rcfilters-filter-logactions-label": "Registreerde aktys", "rcfilters-filter-logactions-description": "Administrative handelingen, nye kontos, vordedåne syden, upladingen…", "rcfilters-filtergroup-lastrevision": "Lätste versys", "rcfilters-filter-lastrevision-label": "Lätste versy", @@ -1155,8 +1155,8 @@ "rcfilters-filter-previousrevision-label": "Neet de lätste versy", "rcfilters-filter-previousrevision-description": "Alle wysigingen dee neet de \"lätste versy\" binnen.", "rcfilters-view-tags": "Emarkeerde wysigingen", - "rcfilters-view-namespaces-tooltip": "Filter resultåten up naamruumte", - "rcfilters-view-tags-tooltip": "Filter resultåten döär gebrüük te maken van bewarkingsetiketten", + "rcfilters-view-namespaces-tooltip": "Filter resultaten up naamruumde", + "rcfilters-view-tags-tooltip": "Filter resultaten döär bewarkingsetiketten te bruken", "rcfilters-liveupdates-button": "Rechtstreakse aktualisering", "rcfilters-liveupdates-button-title-off": "Nye wysigingen voorddalik låten seen", "rcnotefrom": "Wysigingen sinds $3, $4 (maximaal $1 {{PLURAL:$1|wysiging|wysigingen}}).", @@ -2531,7 +2531,7 @@ "compare-invalid-title": "De titel die'j op-egeven hebben, is ongeldig.", "compare-title-not-exists": "De titel die'j op-egeven hebben, besteet niet.", "compare-revision-not-exists": "De versie die'j op-egeven hebben, besteet niet.", - "diff-form": "een '''formelier'''", + "diff-form": "Wysigingen", "dberr-problems": "t Spiet ons, mer disse webstee hef op t moment wat techniese problemen.", "dberr-again": "Wach n paor minuten en probeer t daornao opniej.", "dberr-info": "(Kan gien verbiending maken mit de databankeserver: $1)", @@ -2634,7 +2634,7 @@ "expandtemplates": "Mallen substitueren", "expand_templates_intro": "Disse spesiale zied leest de op-egeven tekste en substitueert rekursief alle mallen in de tekste. Oek ondersteunde parserfunksies zo as {{#language:…}} en variabels zo as {{CURRENTDAY}}&mdash. Zwat alle teksten tussen dubbelde krulhaken wörden esubstitueerd.", "expand_templates_title": "Titel, veur {{FULLPAGENAME}}, enz.:", - "expand_templates_input": "Invoertekste:", + "expand_templates_input": "Wikitekst invoren:", "expand_templates_output": "Resultaot", "expand_templates_xml_output": "XML-uutvoer", "expand_templates_ok": "Oké", @@ -2673,7 +2673,7 @@ "special-characters-title-minus": "minteken", "mw-widgets-abandonedit": "Bi'j der wisse van da'j de naokiekmodus verlaoten willen zonder eerst op te slaon?", "mw-widgets-abandonedit-discard": "Wiezigingen vortsmieten", - "mw-widgets-abandonedit-keep": "Verdan gaon mit bewarken", - "mw-widgets-abandonedit-title": "Wee'j t zeker?", + "mw-widgets-abandonedit-keep": "Vöärdan gån mid bewarken", + "mw-widgets-abandonedit-title": "Bin jy dår wisse van?", "randomrootpage": "Willeköärige stamsyde" } diff --git a/languages/i18n/ne.json b/languages/i18n/ne.json index a2e6203532..6b35dab346 100644 --- a/languages/i18n/ne.json +++ b/languages/i18n/ne.json @@ -157,9 +157,9 @@ "category-empty": "''यो श्रेणीमा हाल कुनै पृष्ठ या मिडियाहरु रहेका छैनन् ।''", "hidden-categories": "{{PLURAL:$1|लुकाइएको श्रेणी|लुकाइएका श्रेणीहरू}}", "hidden-category-category": "लुकाइएका श्रेणीहरू", - "category-subcat-count": "{{PLURAL:$2|यो श्रेणीमा निम्न उपश्रेणीहरू मात्र छन्।|यो श्रेणीको निम्न {{PLURAL:$1|उपश्रेणी|$1 उपश्रेणीहरू}}, $2 कुल मध्ये श्रेणीहरू छन् ।}}", + "category-subcat-count": "{{PLURAL:$2|यो श्रेणीमा निम्न उपश्रेणीहरू मात्र छन्।|यो श्रेणीको निम्न {{PLURAL:$1|उपश्रेणी|$1 उपश्रेणीहरू}}, $2 कुल मध्ये श्रेणीहरू छन्।}}", "category-subcat-count-limited": "यो श्रेणीमा निम्न {{PLURAL:$1|उपश्रेणी|$1 उपश्रेणीहरू}} छन् ।", - "category-article-count": "{{PLURAL:$2|यो श्रेणीमा एक मात्र पृष्ठरहेको छ।|कुल $2 मध्ये यो श्रेणीमा {{PLURAL:$1|पृष्ठ|$1 पृष्ठहरू}} रहेका छन् । }}", + "category-article-count": "{{PLURAL:$2|यो श्रेणीमा एक मात्र पृष्ठरहेको छ।|कुल $2 मध्ये यो श्रेणीमा {{PLURAL:$1|पृष्ठ|$1 पृष्ठहरू}} रहेका छन्।}}", "category-article-count-limited": "निम्न {{PLURAL:$1|पृष्ठ|$1 पृष्ठहरू}} यस श्रेणीमा रहेको ।", "category-file-count": "{{PLURAL:$2|यो श्रेणीमा निम्न फाइल मात्र छ ।|निम्न श्रेणीमा {{PLURAL:$1|फाइल|$1 फाइलहरू}} , कुल $2 मध्ये रहेको ।}}", "category-file-count-limited": "निम्न {{PLURAL:$1|फाइल|$1 फाइलहरू}} यस श्रेणीमा रहेको ।", @@ -195,7 +195,7 @@ "history": "पृष्ठको इतिहास", "history_short": "पृष्ठको इतिहास", "history_small": "इतिहास", - "updatedmarker": "मेरो अन्तिम भ्रमण पछि अद्यतन गरिएको", + "updatedmarker": "तपाईँको अन्तिम भ्रमण पछि अद्यतन गरिएको", "printableversion": "छाप्नयोग्य संस्करण", "permalink": "स्थायी लिङ्क", "print": "छाप्नुहोस्", @@ -649,7 +649,7 @@ "newarticle": "(नयाँ)", "newarticletext": "तपाईंले अहिले सम्म नभएको पृष्ठको लिङ्क पहिल्याउनु भएको छ।\nयो पृष्ठ निर्माण गर्न तलको कोष्ठमा टाइप गर्नुहोस् ।(थप जानकारीको लागि [$1 help page] हेर्नुहोस् )।\nयहाँ त्यत्तिकै आइपुग्नु भएको हो भने , ब्राउजरको '''back''' बटन थिच्नुहोस् ।", "anontalkpagetext": "----''यो वार्तालाप पृष्ठ अज्ञात प्रयोगकर्ताको हो जसले अहिलेसम्म खाता बनाएकै छैन, अथवा जसले यस पृष्ठको उपयोग गर्दैन।\nयस कारण हामीले उसलाई उसको आइपी ठेगानाले चिन्न सक्छौं। \nयस्तो आइपी ठेगाना धेरै प्रयोगकर्ताहरूको साझा हुनसक्छ।\nयदि तपाईं अज्ञात प्रयोगकर्ता हुनुहुन्छ र तपाईंमाथि नचाहिँदो टिप्पणी भएको अनुभव गर्नुहुन्छ भने भविष्यमा अन्य अज्ञात प्रयोगकर्तासित अलमलिनबाट बच्न कृपया [[Special:CreateAccount|खाता खोल्नुहोस्]] अथवा [[Special:UserLogin|प्रवेश गर्नुहोस्]] ''", - "noarticletext": "यस लेखमा अहिले केहि पनि पाठ छैन ।\nतपाईंले अन्य पृष्ठमा [[Special:Search/{{PAGENAME}}|यस पृष्ठको शीर्षकको लागि खोज]] गर्न सक्नुहुन्छ ।\n[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} पृष्ठ सम्बन्धित ढड्डामा खोज],\nवा [{{fullurl:{{FULLPAGENAME}}|action=edit}} यसै पृष्ठलाई सम्पादन गर्ने].", + "noarticletext": "यस लेखमा अहिले केहि पनि पाठ छैन।\nतपाईँले अन्य पृष्ठमा [[Special:Search/{{PAGENAME}}|यस पृष्ठको शीर्षकको लागि खोज]] गर्न सक्नुहुन्छ।\n[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} पृष्ठ सम्बन्धित ढड्डामा खोज्ने],\nवा [{{fullurl:{{FULLPAGENAME}}|action=edit}} यसै पृष्ठलाई सम्पादन गर्ने]।", "noarticletext-nopermission": "यस लेखमा अहिले कुनै पनि पाठ छैन ।\nतपाईंले अन्य पृष्ठमा [[Special:Search/{{PAGENAME}}|यस पृष्ठको शीर्षकको लागि खोज]] गर्न सक्नुहुन्छ,\nअथवा [{{fullurl:{{#Special:Log}}|पृष्ठ={{FULLPAGENAMEE}}}} सम्बन्धित लगहरू खोज्न सक्नुहुनेछ ] तर तपाईंलाई नयाँ पृष्ठ बनाउने अधिकार छैन।", "missing-revision": "\"{{FULLPAGENAME}}\" पृष्ठको अवतरण #$1 रहेको छैन।\n\nसामान्य रूपमा यसो एउटा हटाइएको पृष्ठको पुरानो लिङ्कमा क्लिक गर्दा हुन्छ।\nअधिक जानकारीको लागि तपाईं [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} हटाएको लग] हेर्न सक्नुहुन्छ।", "userpage-userdoesnotexist": "प्रयोगकर्ताको खाता \"$1\" दर्ता गरिएको छैन ।\nतपाईंले पृष्ठ निर्माण/सम्पादन गर्न चाहनु भएको भए जाँच गर्नुहोस् ।", @@ -795,7 +795,7 @@ "rev-deleted-text-view": "यस पृष्ठको संशोधन '''मेटिएकोछ'''।\nतपाईंले हेर्न सक्नुहुन्छ; [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} मेटिएको लगमा विवरण पाउन सकिन्छ]।", "rev-suppressed-text-view": "यस पृष्ठको पुनरावलोकन थिचिएको छ।\nप्रबन्धकको हैसियतले हेर्न सक्नुहुन्छ; [{{fullurl:{{#Special:Log}}/delete|पृष्ठ={{FULLPAGENAMEE}}}}को थिचिएको लगमा विवरण पाउन सकिन्छ]", "rev-deleted-no-diff": "तपाईंले यसको भिन्नता पाउन सक्नुहुन्न किनभने यस पृष्ठको पुनरावलोकन मेटाइएको छ'।\nयसको विवरण [{{fullurl:{{#Special:Log}}/delete|पृष्ठ={{FULLPAGENAMEE}}}}को मेटाइएको लगमा पाउन सक्नुहुन्छ]।", - "rev-suppressed-no-diff": "तपाईं यसको भिन्नता हेर्न सक्नुहुन्न किनभने यसको एउटा संशोधन मेटाइएकोछ।", + "rev-suppressed-no-diff": "तपाईँ यसको भिन्नता हेर्न सक्नुहुन्न किनभने यसको एउटा संशोधन मेटाइएकोछ।", "rev-deleted-unhide-diff": "यस पृष्ठका पुनरावलोकनहरू मध्ये एउटा भिन्नता मेटाइएकोछ।\nयसको पूर्ण विवरण [{{fullurl:{{#Special:Log}}/delete|पृष्ठ={{FULLPAGENAMEE}}}}को मेटाइएको लगमा पाउन सकिन्छ]।\nयदि चाहनु भयो भने प्रवन्धकको हैसियतले [यो भिन्नता $1] हेर्न सक्नुहुन्छ।", "rev-suppressed-unhide-diff": "यस पृष्ठको पुनरावलोकनहरू मध्ये एउटा भिन्नता थिचिएको छ।\nयसको पूर्ण विवरण [{{fullurl:{{#Special:Log}}/suppress|पृष्ठ={{FULLPAGENAMEE}}}}को थिचिएको लगमा पाउन सकिन्छ]।\nयदि चाहनु भयो भने प्रबन्धकको हैसियतमा [यो भिन्नता $1] हेर्न सक्नुहुन्छ।", "rev-deleted-diff-view": "यस भिन्नताका संशोधनहरू मध्येको एउटा चाहिं मेटियो। \nतपाईंले यस भिन्नतालाई हेर्न सक्नुहुन्छ; सबै विवरण [{{fullurl:{{#Special:Log}}/delete|पृष्ठ={{FULLPAGENAMEE}}}} मेटाइएको लग]मा पाउन सकिनेछ।", @@ -882,7 +882,7 @@ "difference-title": "\"$1\" को बिचमा भिन्नता", "difference-title-multipage": "\"$1\" तथा \"$2\" को बिचमा भिन्नता", "difference-multipage": "(पृष्ठहरूमा भिन्नता)", - "lineno": "पंक्ति $1:", + "lineno": "पङ्क्ति $1:", "compareselectedversions": "छानिएका संस्करणहरू दाँज्नुहोस्", "showhideselectedversions": "छानिएका पुनरावलोकनहरू देखाउने/लुकाउने", "editundo": "रद्द गर्ने", @@ -1249,7 +1249,7 @@ "recentchanges-label-minor": "यो साधारण सम्पादन हो", "recentchanges-label-bot": "यो सम्पादन बोटद्वारा गरिएको थियो", "recentchanges-label-unpatrolled": "यो सम्पादन अहिले सम्म गस्ती गरिएको छैन", - "recentchanges-label-plusminus": "यति बाइटहरू संख्याले पृष्ठको आकार परिवर्तन भएको छ", + "recentchanges-label-plusminus": "यति बाइट सङ्ख्याले यस पृष्ठको आकार परिवर्तन भएको छ", "recentchanges-legend-heading": "आदर्श वाक्य:", "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} ([[Special:NewPages|नयाँ पृष्ठहरूको सूची]] यो पनि हेर्नुहोस्)", "recentchanges-legend-plusminus": "(''±१२३'')", @@ -1280,7 +1280,7 @@ "rcfilters-filter-categorization-label": "परिवर्तित श्रेणी", "rcfilters-filter-lastrevision-label": "हालको संस्करण", "rcnotefrom": "तल $2 देखि ($1 सम्म) {{PLURAL:$5|भएका परिवर्तनहरू देखाइएको छ|भएका परिवर्तनहरू देखाइन्छ}}।", - "rclistfrom": "$3 $2 देखिका नयाँ परिवर्तनहरू देखाउनु", + "rclistfrom": "$3 $2 देखिका नयाँ परिवर्तनहरू देखाउनुहोस्", "rcshowhideminor": "$1 सामान्य सम्पादन", "rcshowhideminor-show": "देखाउनुहोस्", "rcshowhideminor-hide": "लुकाउनुहोस्", @@ -1320,7 +1320,7 @@ "recentchangeslinked-feed": "सम्बन्धित परिवर्तनहरू", "recentchangeslinked-toolbox": "सम्बन्धित परिवर्तनहरू", "recentchangeslinked-title": "\"$1\" सँग सम्बन्धित परिवर्तन", - "recentchangeslinked-summary": "कुनै पृष्ठको वा यससँग सम्बन्धित परिवर्तन हेर्नको लागि उक्त पृष्ठको नाम हाल्नुहोस। (कुनै श्रेणीको सामाग्रीहरुको लागि {{ns:category}}: श्रेणीको नाम हल्नुहोस । [[Special:Watchlist|तपाईंको अवलोकन सूची]]का पृष्ठहरू गाढा अक्षरमा छन् ।", + "recentchangeslinked-summary": "कुनै पृष्ठको वा यससँग सम्बन्धित परिवर्तन हेर्नको लागि उक्त पृष्ठको नाम हाल्नुहोस्। (कुनै श्रेणीको सामाग्रीहरूको लागि {{ns:category}}:श्रेणीको नाम) हाल्नुहोस्। [[Special:Watchlist|तपाईँको अवलोकन सूची]]का पृष्ठहरू गाढा अक्षरमा छन्।", "recentchangeslinked-page": "पृष्ठ नाम:", "recentchangeslinked-to": "यसको सट्टा यो पृष्ठसँग जोडिएका पृष्ठहरूको परिवर्तन देखाउने", "upload": "फाइल उर्ध्वभरण", @@ -1537,9 +1537,9 @@ "filehist-filesize": "फाइल आकार", "filehist-comment": "टिप्पणी", "imagelinks": "फाइलको प्रयोगहरू", - "linkstoimage": "यस फाइलमा निम्न{{PLURAL:$1|पृष्ठ जोडिन्छ|$1 पृष्ठहरू जोडिन्छन्}}:", + "linkstoimage": "यस फाइलमा निम्न {{PLURAL:$1|पृष्ठ जोडिन्छ|$1 पृष्ठहरू जोडिन्छन्}}:", "linkstoimage-more": "$1 भन्दा अधिक {{PLURAL:$1|पृष्ठ लिङ्क|पृष्ठ लिङ्कहरू}} यस फाइलसँग जोडिएको छ। \nनिम्नलिखित सूची फाइलसँग {{PLURAL:$1|पहिलो पृष्ठ लिङ्क|पहिलो $1 पृष्ठ लिङ्कहरू}} जोडिने देखाउँछ।\n[[Special:WhatLinksHere/$2|पूर्ण सूची]] पनि उपलब्ध छ।", - "nolinkstoimage": "यो फाईलसंग लिंकभएको कुनै पृष्ठ छैन.", + "nolinkstoimage": "यो फाइलसँग कुनै पनि पृष्ठ जोडिएको छैन।", "morelinkstoimage": "यस फाइलको [[Special:WhatLinksHere/$1|थप लिंकहरू]] हेर्नुहोस् ।", "linkstoimage-redirect": "$1 (फाइल अनुप्रेषण) $2", "duplicatesoffile": "निम्नलिखित {{PLURAL:$1|फाइलको प्रतिलिपि हो|$1 फाइलहरूको प्रतिलिपि हो}} ([[Special:FileDuplicateSearch/$2|अधिक जानकारीहरू]]):", @@ -1944,7 +1944,7 @@ "rollback-success": "$1द्वारा उल्टाइएका सम्पादनहरू;\nपछिल्लो संशोधनमा $2द्वारा परिवर्तन गरि पुनः फर्काइएको।", "sessionfailure-title": "सत्र त्रुटी", "sessionfailure": "यस्तो लाग्दैछ कि तपाईंको लगइन सत्रसँग कुनै समस्या छ। सत्र अपहरणबाट बचाउन को लागि सावधानीको रूपमा तपाईंको यो क्रियाकलाप रद्द गरिएको छ। कृपया पछाडी जानुहोस र पृष्ठलाई पुनः लोड गर्नुहोस्, अनि फेरी प्रयास गर्नुहोला।", - "changecontentmodel-title-label": "पाना शीर्षक", + "changecontentmodel-title-label": "पृष्ठ शीर्षक:", "changecontentmodel-reason-label": "कारण:", "changecontentmodel-submit": "परिवर्तन गर्नुहोस्", "logentry-contentmodel-change-revertlink": "पहिलेको रुपमा फर्काउने", @@ -2011,7 +2011,7 @@ "undeletepagetext": "निम्नलिखित {{PLURAL:$1|पृष्ठ मेटिएकोछ तर पूरालेखभित्रै छ|$1 पृष्ठ मेटिएकाछन् तर पूरालेखभित्रै छन्}} र पुनर्स्थापित गर्न सकिन्छ।\nपूरालेखको समय-समयमा सफाई गर्न सकिन्छ।", "undelete-fieldset-title": "पुनरावलोकनहरू पूर्वावस्थामा ल्याउनुहोस्", "undeleteextrahelp": "यस पृष्ठको पुरै इतिहास पूर्वरुपमा फर्काउनको लागि छनोट सन्दुकहरूलाई नछानी '''''{{int:undeletebtn}}''''' मा क्लिक गर्नुहोस।\nअनुकुल पूर्वरुपमा फर्काउने कार्य गर्न छनौट चाहिएका संस्करणका सन्दुकहरूलाई छानेर '''''{{int:undeletebtn}}'''''मा क्लिक गर्नुहोस।", - "undeleterevisions": "$1 {{PLURAL:$1|संशोधन|संशोधनहरू}} संग्रहित", + "undeleterevisions": "$1 {{PLURAL:$1|संशोधन|संशोधनहरू}} मेटाइयो", "undeletehistory": "यदि कुनै पृष्टलाई पुन: स्थापन गराउनु भयो भने सम्पूर्ण संस्करणहरू इतिहासमा पुन:स्थापन हुनेछन् ।\nयदि यसै नामबाट नयाँ पृष्ठ निर्माण भैसकेको छ भने पुन: स्थापित संस्करणहरू पूर्व इतिहासको रुपमा स्थापित हुनेछन् ।", "undeleterevdel": "यदि यो माथिल्लो पृष्ठ बन्छ या फाइल संस्करणहरू आंशिक मेटिएका छन् भने मेट्ने काम रद्द गरिने छैन।\nत्यस अवस्थामा तपाईंले छनौटमा अन्तिम मेटिएको नयाँ संस्करण नलुकाउनेमा चिनो लगाउनु पर्छ ।", "undeletehistorynoadmin": "यस पृष्ठ मेटिएको छ।\nमेटिनाको कारण निम्न जानकारीहरुमा खुलाइएको छ र मेटिनु अगिका योगदानकर्ताहरुको नाम पनि \nमेटिएका पृष्ठको पूरा पाठ प्रवन्धकहरुलाई मात्र उपलब्ध हुन्छ ।", @@ -2043,10 +2043,10 @@ "undelete-show-file-submit": "हो", "namespace": "नामस्थान:", "invert": "रोजाइ उल्टाउने", - "tooltip-invert": "छानिएका नेमस्पेसहरूमा रहेका पृष्ठहरूमा गरिएका परिवर्तनहरू लुकाउन यसमा चिनो लगाउनुहोस् (र सम्बन्धित नेमस्पेस यदि छानिएका भए)", + "tooltip-invert": "छानिएका नामपदहरूमा रहेका पृष्ठहरूमा गरिएका परिवर्तनहरू लुकाउन यसमा चिनो लगाउनुहोस् (र छानिएका भए सम्बन्धित नामपद)", "tooltip-whatlinkshere-invert": "छानिएको नामस्थानको पृष्ठहरूसँग लिङ्कहरूलाई लुकाउनका लागि यस बाकसलाई चिन्हित गर्नुहोस", - "namespace_association": "सम्बन्धित नेमस्पेस", - "tooltip-namespace_association": "वार्तालाप या विषय नेमस्पेसहरुलाई सम्वन्धित नेमस्पेसको रुपमा लिनको लागि सन्दुकमा चिनो लगाउनुहोस।", + "namespace_association": "सम्बन्धित नामपद", + "tooltip-namespace_association": "वार्तालाप या विषय नामपदहरूलाई सम्बन्धित नामपदको रुपमा लिनको लागि सन्दुकमा चिनो लगाउनुहोस्।", "blanknamespace": "(मुख्य)", "contributions": "{{GENDER:$1|प्रयोगकर्ता}}का योगदानहरू", "contributions-title": "$1को प्रयोगकर्ता योगदानहरू", @@ -2060,11 +2060,11 @@ "year": "वर्ष देखि( र पहिले):", "sp-contributions-blocklog": "रोकावट लग", "sp-contributions-suppresslog": "प्रयोगकर्ताको योगदानहरू दबाइएको छ ।", - "sp-contributions-deleted": "प्रयोगकर्ताका योगदानहरू मेटाइयो", + "sp-contributions-deleted": " {{GENDER:$1|प्रयोगकर्ता}}का योगदानहरू मेटाइयो", "sp-contributions-uploads": "उर्ध्वभरणहरू", "sp-contributions-logs": "लगहरू", "sp-contributions-talk": "वार्ता", - "sp-contributions-userrights": "प्रयोगकर्ता अधिकार व्यवस्थापन", + "sp-contributions-userrights": "{{GENDER:$1|प्रयोगकर्ता}} अधिकार व्यवस्थापन", "sp-contributions-blocked-notice": "यो प्रयोगकर्तालाई अहिले रोक लगाइएको छ।\nनवीनतम रोकाइ गरेको लग प्रविष्टि सन्दर्भको निम्ति तल दिएकोछ:", "sp-contributions-blocked-notice-anon": "यो IP ठेगानालाई अहिले रोक लगाइएको छ।\nनवीनतम रोकाइ गरेको लग प्रविष्टि सन्दर्भको निम्ति तल दिएकोछ:", "sp-contributions-search": "योगदानहरू खोज्नुहोस्", @@ -2230,7 +2230,7 @@ "cant-move-to-user-page": "तपाईंलाई पृष्ठहरू प्रयोगकर्ता पृष्ठमा सार्न अनुमती छैन (प्रयोगकर्ता सहपृष्ठहरूमा बाहेक)", "cant-move-category-page": "तपाईंलाई श्रेणीको पृष्ठहरू सार्ने अनुमति छैन ।", "cant-move-to-category-page": "कुनै श्रेणी पृष्ठमा सार्नको लागी तपाईँलाई अनुमति छैन ।", - "newtitle": "नयाँ शीर्षकमा :", + "newtitle": "नयाँ शीर्षक:", "move-watch": "यो पृष्ठ निगरानीमा राख्नुहोस्", "movepagebtn": "पृष्ठ सार्नुहोस्", "pagemovedsub": "सार्ने काम सफल भयो", @@ -2253,7 +2253,7 @@ "movenosubpage": "यस पृष्ठका उप पृष्ठहरू छैनन्।", "movereason": "कारण :", "revertmove": "पूर्ववत्", - "delete_and_move_text": "== मेटाउनु आवश्यक ==\nलक्ष्य गरिएको पृष्ठ \"[[:$1]]\" पहिलादेखि छ\nके तपाईं यो त्यहाँ सार्न त्यसलाई मेट्न चाहनुहुन्छ?", + "delete_and_move_text": "लक्ष्य गरिएको पृष्ठ \"[[:$1]]\" पहिल्यै छ।\nके तपाईं यसलाई मेटाएर यस कदमको लागि बाटो खुला गर्न चाहनुहुन्छ?", "delete_and_move_confirm": "हो, पृष्ठ मेट्नुहोस्", "delete_and_move_reason": " \"[[$1]]\"बाट सार्नलाई बाटो खुलाउन मेटियो", "selfmove": "स्रोत तथा लक्ष्य गरिएको पृष्ठको शीर्षक एउटै भएकाले;\nयसैमाथि पृष्ठ सार्न मिल्दैन", @@ -2379,7 +2379,7 @@ "tooltip-pt-mycontris": "{{GENDER:|तपाईंका}} योगदानहरूको सूची", "tooltip-pt-login": "तपाईंलाई प्रवेस गर्न सुझाव दिइन्छ ; तर यो जरुरी भने छैन", "tooltip-pt-logout": "निर्गमन", - "tooltip-pt-createaccount": "तपाईंलाई खाता बनाउन र लग इन गर्न हामि प्रोत्साहित गर्छौ; तथापि, यो अनिवार्य भने छैन ।", + "tooltip-pt-createaccount": "तपाईँलाई खाता बनाउन र प्रवेश गर्न हामी प्रोत्साहित गर्छौं; तथापि, यो अनिवार्य भने छैन।", "tooltip-ca-talk": "सामग्री पृष्ठबारेमा छलफल", "tooltip-ca-edit": "यो पृष्ठ सम्पादन गर्ने", "tooltip-ca-addsection": "नयाँ खण्ड सुरु गर्नुहोस्", @@ -2413,8 +2413,8 @@ "tooltip-t-upload": "फाइल अपलोड गर्ने", "tooltip-t-specialpages": "सबै विशेष पृष्ठहरूको सूची", "tooltip-t-print": "यो पृष्ठको मुद्रण योग्य संस्करण", - "tooltip-t-permalink": "पृष्ठको यो पुनरावलोकनको लागि स्थाई लिङ्क", - "tooltip-ca-nstab-main": "सामग्री पृष्ठ हेर्नुहोस", + "tooltip-t-permalink": "पृष्ठको यो पुनरावलोकनको लागि स्थायी लिङ्क", + "tooltip-ca-nstab-main": "सामग्री पृष्ठ हेर्नुहोस्", "tooltip-ca-nstab-user": "प्रयोगकर्ता पृष्ठ हेर्नुहोस्", "tooltip-ca-nstab-media": "मिडिया पृष्ठ हेर्नुहोस्", "tooltip-ca-nstab-special": "यो विशेष पृष्ठ हो, यो सम्पादन गर्न सकिदैन", @@ -2660,7 +2660,7 @@ "autoredircomment": "पृष्ठ[[$1]]मा पठाइएको", "autosumm-new": " $1 को साथमा पृष्ठ शृजना भयो", "autosumm-newblank": "खाली पृष्ठ तयार गर्ने", - "size-bytes": "$1 बाइटहरू", + "size-bytes": "$1 {{PLURAL:$1|बाइट|बाइटहरू}}", "size-kilobytes": "$1 किलोबाइटहरू", "size-megabytes": "$1 मेगाबाइटहरू", "size-gigabytes": "$1 गिगाबाइटहरू", @@ -2679,7 +2679,7 @@ "watchlistedit-raw-done": "तपाईंको निगरानी सूची अद्यावधिक गरिएको छ।", "watchlistedit-raw-added": "{{PLURAL:$1|१ शिर्षक|$1 शिर्षकरु}} थपियो:", "watchlistedit-raw-removed": "{{PLURAL:$1|१ शिर्षक|$1 शिर्षकरु}} हटाइयो:", - "watchlistedit-clear-title": "अवलोकन सूची खाली गरियो", + "watchlistedit-clear-title": "अवलोकनसूची खाली गर्नुहोस्", "watchlistedit-clear-legend": "अवलोकन सूची खाली गर्ने", "watchlistedit-clear-explain": "तपाईंको अवलोकन सूचीबाट सम्पूर्ण शिर्षकहरू मेटाइदै", "watchlistedit-clear-titles": "शीर्षकहरू :", @@ -2813,7 +2813,7 @@ "fileduplicatesearch-result-1": "फाइल\"$1\" को दुरुस्त नक्कलहरु छैनन् ।", "fileduplicatesearch-result-n": "फाइल\"$1\" को {{PLURAL:$2|1 दुरुस्त नक्कल|$2 दुरुस्त नक्कलहरु}} छन् ।", "fileduplicatesearch-noresults": "\"$1\" नामको फाइल पाइएन।", - "specialpages": "विशेष पृष्ठ", + "specialpages": "विशेष पृष्ठहरू", "specialpages-note-top": "आदर्श वाक्य", "specialpages-note-restricted": "* साधारण विशेष पृष्ठहरू।\n* निषेधित विशेष पृष्ठहरू।", "specialpages-group-maintenance": "मर्मत प्रतिवेदनहरू", @@ -2848,7 +2848,7 @@ "tags-actions-header": "कार्यहरु", "tags-active-yes": "हो", "tags-active-no": "हैन", - "tags-source-extension": "एक्सटेन्सनद्वारा परिभाषित गर्ने", + "tags-source-extension": "सफ्टवेयरद्वारा परिभाषित", "tags-source-manual": "प्रयोगकर्ताहरू तथा बोटहरूबाट म्यानुअल्ली लागु गरिएको", "tags-source-none": "प्रयोगमा नरहेको", "tags-edit": "सम्पादन गर्नुहोस्", @@ -2905,7 +2905,7 @@ "tags-edit-revision-legend": "ट्यागहरू {{PLURAL:$1|यस संशोधन|सबै $1 संशोधनहरू}}सँग जोड्ने वा हटाउने।", "tags-edit-logentry-legend": "ट्यागहरू {{PLURAL:$1|यस लग प्रविष्टि|सबै $1 लग प्रविष्टिहरू}}सँग जोड्ने वा हटाउने।", "tags-edit-existing-tags": "हाल भएको ट्यागहरूः", - "tags-edit-existing-tags-none": "''कुनै पनि होइन''", + "tags-edit-existing-tags-none": "कुनै पनि होइन", "tags-edit-new-tags": "नयाँ ट्यागहरूः", "tags-edit-add": "यी ट्यागहरू थप्नेः", "tags-edit-remove": "यी ट्यागहरू हटाउनेः", @@ -2915,7 +2915,7 @@ "tags-edit-reason": "कारण:", "tags-edit-revision-submit": "{{PLURAL:$1|यस संस्करण|$1 संस्करणहरू}} मा परिवर्तनहरूलाई लागु गर्ने", "tags-edit-logentry-submit": "{{PLURAL:$1|यस लग प्रविष्टी|$1 लग प्रविष्टीहरू}} मा परिवर्तनहरूलाई लागु गर्ने", - "tags-edit-success": "परिवर्तनहरू सफलता पूर्वक लागु भैसक्यो", + "tags-edit-success": "परिवर्तनहरू लागु गरियो", "tags-edit-failure": "यी परिवर्तनहरू लागु गर्न सकिएनः\n$1", "tags-edit-nooldid-title": "अवैध संशोधन लक्ष्य", "tags-edit-nooldid-text": "या त तपाईंले कुनै लक्षित संशोधनको विवरण दिनुभएको छैन जहाँ यस कार्यलाई सम्पन्न गर्नु पर्नेछ, या विवरण गरिएको संशोधन छंदै छैन।", @@ -2995,7 +2995,7 @@ "logentry-rights-autopromote": "$1 को प्रयोगकर्ता समूह स्वतः $4 बाट परिवर्तन गरेर $5 {{GENDER:$2|गरिएको}} थियो", "logentry-upload-upload": "$1 ले $3 {{GENDER:$2|अपलोड गरेका छन्}}", "logentry-upload-overwrite": "$1 ले $3 को नयाँ संस्करण {{GENDER:$2|अपलोड गरेका छन्}}", - "logentry-upload-revert": "$1 ले $3 {{GENDER:$2|अपलोड गरेका छन्}}", + "logentry-upload-revert": "$1ले $3लाई पुरानो संस्करणमा {{GENDER:$2|उल्टाउनुभयो}}", "log-name-managetags": "ट्याग व्यवस्थापन लग", "log-description-managetags": "यस पृष्ठमा ती प्रवन्धन कार्यहरूको सूची छ जुन [[Special:Tags|ट्यागहरू]]सँग सम्बन्धित छ। लगमा मात्रै ती क्रियाहरूको बयान गरिएको छ जुन मानवीय रूपले कुनै प्रवन्धकद्वारा पुरा गरिएको छ। ट्यागहरूलाई विकि सफ्टवेयरद्वारा बनउनु वा हटाउन सकिनेछ जसको प्रविष्टि लगमा हुनु आवश्यक छैन।", "logentry-managetags-create": "$1 ले ट्याग $4 {{GENDER:$2|तयार गरेको छ}}", @@ -3039,7 +3039,7 @@ "api-error-emptypage": "नयाँ तयार गर्दै, खाली पृष्ठ तयार गर्न अनुमति छैन ।", "api-error-publishfailed": "आन्तरिक समस्याः अस्थायी फाइल प्रकाशन गर्न सर्भर असफर भयो ।", "api-error-stashfailed": "आन्तरिक त्रुटि: अस्थाई फाइल राख्न सर्वर असफल भयो।", - "api-error-unknown-warning": "अज्ञात चेतावनी: \"$1\"", + "api-error-unknown-warning": "अज्ञात चेतावनी:\"$1\"।", "api-error-unknownerror": "अज्ञात त्रुटि: \"$1\".", "duration-seconds": "$1 {{PLURAL:$1|सेकेण्ड|सेकेण्डहरू}}", "duration-minutes": "$1 {{PLURAL:$1|मिनेट|मिनेटहरू}}", @@ -3147,11 +3147,11 @@ "special-characters-title-emdash": "इएम ड्यास", "special-characters-title-minus": "घटाउने चिन्ह", "mw-widgets-abandonedit": "के तपाई सम्पादन सङ्ग्रह नगरीकन सम्पादनबाट बाहिरिनेमा निश्चित हुनुहुन्छ?", - "mw-widgets-abandonedit-discard": "सम्पादन रद्द गर्नु", - "mw-widgets-abandonedit-keep": "सम्पादन जारी राख्ने", - "mw-widgets-abandonedit-title": "निश्चित हुनुहुन्छ ?", + "mw-widgets-abandonedit-discard": "सम्पादनहरू रद्द गर्नुहोस्", + "mw-widgets-abandonedit-keep": "सम्पादन जारी राख्नुहोस्", + "mw-widgets-abandonedit-title": "के तपाईँ पक्का हुनुहुन्छ?", "mw-widgets-titleinput-description-new-page": "हालसम्म पृष्ठ उपलब्ध छैन्", - "mw-widgets-titleinput-description-redirect": "$1 मा जाने", + "mw-widgets-titleinput-description-redirect": "$1 मा पुनर्निर्देश", "randomrootpage": "यादृच्छिक शीर्ष पृष्ठ", "log-action-filter-all": "सबै", "log-action-filter-block-block": "रोक्ने", diff --git a/languages/i18n/nl.json b/languages/i18n/nl.json index 2ea7cdce3b..bcd51afa7c 100644 --- a/languages/i18n/nl.json +++ b/languages/i18n/nl.json @@ -2635,6 +2635,7 @@ "ipblocklist-legend": "Een geblokkeerde gebruiker zoeken", "blocklist-userblocks": "Geblokkeerde accounts verbergen", "blocklist-tempblocks": "Tijdelijke blokkades verbergen", + "blocklist-indefblocks": "Verberg blokkades met een oneindige loopduur", "blocklist-addressblocks": "Blokkades van één IP-adres verbergen", "blocklist-type": "Soort:", "blocklist-type-opt-all": "Alle", diff --git a/languages/i18n/nqo.json b/languages/i18n/nqo.json index e55b7534ed..f474a8bd61 100644 --- a/languages/i18n/nqo.json +++ b/languages/i18n/nqo.json @@ -1050,6 +1050,7 @@ "grant-editpage": "ߞߐߜߍ߫ ߓߍߓߊ߮ ߡߊߦߟߍ߬ߡߊ߲߫", "grant-editprotected": "ߞߐߜߍ߫ ߟߊߞߊ߲ߘߊߣߍ߲ ߡߊߦߟߍ߬ߡߊ߲߫", "grant-highvolume": "ߢߊ߲ߞߊ߲-ߛߊ߲ߘߐߕߊ ߡߊߦߟߍߡߊ߲ ߦߴߌ ߘߐ߫", + "grant-oversight": "ߟߊ߬ߓߊ߰ߙߊ߬ߟߊ ߢߡߊߘߏ߲߰ ߊ߬ ߣߌ߫ ߞߊ߬ ߟߢߊ߬ߟߌ ߟߎ߬ ߖߏ߬ߛߌ߬.", "grant-patrol": "ߞߐߜߍ ߟߎ߬ ߓߍ߬ߙߍ߲߬ߓߍ߬ߙߍ߲߬ߠߌ߲ ߡߊ߬ߦߟߍ߬ߡߊ߲߬ߠߌ߲", "grant-privateinfo": "ߘߎ߲߬ߘߎ߬ߡߊ߬ ߞߌߓߊߙߏߦߊ ߟߊߛߐ߬ߘߐ߲߬", "grant-protect": "ߞߐߜߍ ߟߎ߬ ߟߊߞߊ߲ߘߊ߫ ߊ߬ ߣߌ߫ ߞߵߊ߬ߟߎ߬ ߟߊߞߊ߲ߘߊߣߍ߲ ߓߐ߫", @@ -1084,13 +1085,16 @@ "action-writeapi": "ߛߓߍߟߌ API ߟߊߓߊ߯ߙߊ߫", "action-delete": "ߞߐߜߍ ߣߌ߲߬ ߖߏ߰ߛߌ߬", "action-deleterevision": "ߟߢߊ߬ߟߌ ߟߎ߬ ߖߏ߬ߛߌ߬", + "action-deletelogentry": "ߘߊ߲ߖߐ ߡߎ߰ߡߍ ߖߏ߬ߛߌ߬", "action-deletedhistory": "ߞߐߜߍ ߟߎ߬ ߖߏ߰ߛߌ߬ߟߌ ߘߐ߬ߝߐ ߦߋ߫", "action-deletedtext": "ߟߢߊ߬ߟߌ ߖߏ߰ߛߌ߬ߣߍ߲ ߠߎ߬ ߛߓߍߟߌ ߦߋ߫.", "action-browsearchive": "ߞߐߜߍ߬ ߖߏ߰ߛߌ߬ߣߍ߲ ߠߎ߬ ߢߌߣߌ߲߫", "action-undelete": "ߞߐߜߍ ߖߏ߰ߛߌ߬ߓߊߟߌ ߟߎ߬", + "action-suppressrevision": "ߟߢߊ߬ߟߌ߬ ߢߡߊߘߏ߲߰ߣߍ߲ ߠߎ߬ ߦߋ߫ ߊ߬ ߣߌ߫ ߞߵߊ߬ߟߎ߬ ߟߊߞߎߣߎ߲߫.", "action-suppressionlog": "ߘߎ߲߬ߘߎ߬ߡߊ߬ ߘߎ߲ߛߓߍ ߣߌ߲߬ ߦߋ߫", "action-block": "ߟߊ߬ߓߊ߰ߙߊ߬ߟߊ ߣߌ߲߬ ߓߊ߬ߟߌ߬ ߡߊ߬ߦߟߍ߬ߡߊ߲߬ߠߌ߲ ߡߊ߬", "action-protect": "ߞߐߜߍ ߣߌ߲߬ ߟߊ߬ߞߊ߲߬ߘߊ߬ߟߌ߬ ߞߛߊߞߊ ߡߊߝߊ߬ߟߋ߲߬", + "action-rollback": "ߟߊ߬ߓߊ߰ߙߊ߬ߟߊ ߞߐߟߕߊ ߟߊ߫ ߡߊ߬ߦߟߍ߬ߡߊ߲߬ߠߌ߲ ߟߊߞߐߛߊ߬ߦߌ߬ ߖߏߣߊߖߏߣߊ߫߹ ߡߍ߲ ߞߊ߬ ߞߐߜߍ߫ ߞߙߍߞߙߍߣߍ߲ ߡߊߦߟߍ߬ߡߊ߲߫.", "action-import": "ߞߐߜߍ ߟߎ߬ ߟߊߛߣߍ߫ ߞߊ߬ ߓߐ߫ ߥߞߌ ߕߐ߭ ߟߎ߬ ߘߐ߫", "action-importupload": "ߞߐߜߍ ߟߎ߬ ߟߊߛߣߍ߫ ߞߊ߬ ߓߐ߫ ߞߐߕߐ߯ ߟߊߦߟߍ߬ߣߍ߲ ߠߎ߬ ߘߐ߫", "action-patrol": "ߟߊ߬ߓߊ߰ߙߊ߬ߟߊ ߘߏ ߟߎ߬ ߟߊ߫ ߡߊ߬ߦߟߍ߬ߡߊ߲߬ߠߌ߲ ߠߎ߬ ߣߐ߬ߣߐ߬ ߓߍ߬ߙߍ߲߬ߓߍ߬ߙߍ߲߬ߣߍ߲ ߘߌ߫", @@ -1110,6 +1114,13 @@ "action-managechangetags": "ߘߎ߲ߛߓߍ ߟߎ߬ ߛߌ߲ߘߟߌ ߣߴߊ߬ߟߎ߬ ߓߐߒߠߊߟߌ", "action-applychangetags": "ߘߎ߲ߛߓߍ ߟߎ߬ ߟߊߓߊ߯ߙߊ߫ ߌ ߟߊ߫ ߡߝߊ߬ߟߋ߲߬ߠߌ߲ ߠߎ߬ ߞߊ߲߬", "action-deletechangetags": "ߘߎ߲ߛߓߍ ߟߎ߬ ߖߏ߬ߛߌ߬ ߞߊ߬ ߓߐ߫ ߓߟߏߡߟߊ ߝߊ߲ ߞߊ߲߬", + "action-purge": "ߞߐߜߍ ߣߌ߲߬ ߛߊߣߌ߲ߧߊ߫", + "action-apihighlimits": "API ߡߊߢߌߣߌ߲ߣߍ߲ ߛߊ߲ߘߐߕߊ ߟߊߓߊ߯ߙߊ߫", + "action-bigdelete": "ߞߐߜߍ߫ ߘߝߐ߬ ߓߟߋ߬ߓߟߋ߬ߡߊ ߟߎ߬ ߖߏ߰ߛߌ߬", + "action-blockemail": "ߟߊ߬ߓߊ߰ߙߊ߬ߟߊ ߓߊ߬ߟߌ߬ ߢߎߡߍߙߋ߲ ߗߋߟߌ ߡߊ߬", + "action-editprotected": "ߞߐߜߍ ߟߎ߬ ߡߊߦߟߍ߬ߡߊ߲߫ ߡߍ߲ ߠߎ߬ ߟߊߞߊ߲ߘߊߣߍ߲߫ ߦߋ߫ \"{{int:protect-level-sysop}}\" ߓߟߏ߫.", + "action-editsemiprotected": "ߞߐߜߍ ߟߎ߬ ߡߊߦߟߍ߬ߡߊ߲߫ ߡߍ߲ ߠߎ߬ ߟߊߞߊ߲ߘߊߣߍ߲߫ ߦߋ߫ \"{{int:protect-level-autoconfirmed}}\"", + "action-editinterface": "ߟߊ߬ߓߊ߰ߙߊ߬ߟߊ ߟߊ߫ ߢߐ߲߯ߕߍߞߣߍ ߡߊߦߟߍ߬ߡߊ߲߫", "action-editusercss": "ߟߊ߬ߓߊ߰ߙߊ߬ߟߊ ߘߏ ߟߎ߬ CSS ߟߊ߬ߓߊ߰ߙߊ߬ߟߌ߬ ߞߐߕߐ߮ ߡߊߦߟߍ߬ߡߊ߲߫", "action-edituserjson": "ߟߊ߬ߓߊ߰ߙߊ߬ߟߊ ߘߏ ߟߎ߬ ߟߊ߫ JSON ߞߐߕߐ߮ ߟߎ߬ ߡߊߦߟߍ߬ߡߊ߲߫", "action-edituserjs": "ߟߊ߬ߓߊ߰ߙߊ߬ߟߊ ߘߏ ߟߎ߬ ߟߊ߫ JavaScript ߞߐߕߐ߮ ߟߎ߬ ߡߊߦߟߍ߬ߡߊ߲߫", @@ -1119,8 +1130,16 @@ "action-editmyusercss": "ߌ ߖߘߍ߬ߞߊ߬ߣߌ߲߬ CSS ߟߊ߬ߓߊ߰ߙߊ߬ߟߌ߬ ߞߐߕߐ߮ ߡߊߦߟߍ߬ߡߊ߲߫", "action-editmyuserjson": "ߌ ߖߘߍ߬ߞߊ߬ߣߌ߲߬ JSON ߞߐߕߐ߮ ߟߎ߬ ߡߊߦߟߍ߬ߡߊ߲߫", "action-editmyuserjs": "ߌ ߖߘߍ߬ߞߊ߬ߣߌ߲߬ JavaScript ߞߐߕߐ߮ ߟߎ߬ ߡߊߦߟߍ߬ߡߊ߲߫", + "action-editmyuserjsredirect": "ߌ ߖߘߍ߬ߞߊ߬ߣߌ߲߬ JavaScript ߞߐߕߐ߮ ߟߎ߬ ߡߊߦߟߍ߬ߡߊ߲߫ ߡߍ߲ ߠߎ߬ ߓߘߊ߫ ߟߊߞߎ߲߬ߛߌ߲߫.", "action-viewsuppressed": "ߟߊ߬ߓߊ߰ߙߊ߬ߟߊ ߘߏ ߟߎ߬ ߟߊ߫ ߟߢߊ߬ߟߌ߬ ߢߡߊߘߏ߲߰ߣߍ߲ ߠߎ߬ ߦߋ߫", + "action-hideuser": "ߟߊ߬ߓߊ߰ߙߊ߬ߟߊ߫ ߟߎ߫ ߓߊ߬ߟߌ߬߸ ߡߍ߲ ߠߎ߬ ߢߡߊߘߏ߲߰ߣߍ߲߬ ߦߋ߫ ߖߊ߬ߡߊ ߟߊ߫ ߦߋߟߌ ߡߊ߬.", "action-unblockself": "ߌ ߖߍ߬ߘߍ ߓߊ߬ߟߌ߬ߣߍ߲ ߓߐ߫", + "action-reupload-own": "ߌ ߖߘߍ߬ߞߊߣߌ߲ ߠߊ߫ ߞߐߕߐ߯ ߟߊߦߟߍ߬ߣߍ߲ ߠߎ߬ ߖߏ߰ߛߌ߬", + "action-nominornewtalk": "ߡߊ߬ߦߟߍ߬ߡߊ߲߬ߠߌ߲߬ ߘߋ߬ߣߍ߲߬ ߞߏ ߕߍ߫ ߘߊߘߐߖߊߥߏ ߞߐߜߍ ߟߎ߬ ߘߐ߫߸ ߗߋߛߓߍ߫ ߞߎߘߊ߫ ߘߊߡߌ߬ߣߊ߬ ߞߊߟߌߦߊ߫ ߘߐ߫.", + "action-markbotedits": "ߡߊ߬ߦߟߍ߬ߡߊ߲߬ߠߌ߲߬ ߟߊߞߐߛߊ߬ߦߌ߬ߣߍ߲ ߠߎ߬ ߣߐ߬ߣߐ߬ ߓߏߕ ߡߊ߬ߦߟߍ߬ߡߊ߲߬ߠߌ߲߬ߣߐ ߘߌ߫.", + "action-patrolmarks": "ߡߊ߬ߦߟߍ߬ߡߊ߲߬ߠߌ߲߬ ߞߎߘߊ ߟߎ߬ ߦߌ߬ߘߊ߬ ߓߍ߬ߙߍ߲߬ߓߍ߬ߙߍ߲߬ߠߌ߲߫ ߣߐ߬ߣߐ߬ߣߍ߲ ߘߌ߫", + "action-override-export-depth": "ߞߐߜߍ ߟߎ߬ ߟߊߝߏ߬ߦߌ߬߸ ߤߊߟߌ߬ ߞߐߜߍ߫ ߜߋ߲߭ߞߘߎ߬ߣߍ߲ߢߐ߲߰ߠߊ ߡߍ߲ ߠߎ߬ ߦߋ߫ ߅ ߘߎ߲߰ߧߊ ߛߊ߲ߘߐ߫.", + "action-suppressredirect": "ߟߊ߬ߞߎ߲߬ߛߌ߲߬ߠߌ߲ ߞߊߣߊ߬ ߟߊߘߊ߲߫ ߓߐߛߎ߲ ߞߐߜߍ ߟߎ߬ ߟߊ߫ ߞߐߜߍ ߟߎ߬ ߓߐ߫ ߕߎߡߊ ߟߴߊ߬ߟߎ߫ ߣߐ߭ ߘߐ߫.", "nchanges": "$1 {{PLURAL:$1|ߡߊ߬ߦߟߍ߬ߡߊ߲߬ߠߌ߲|ߡߊ߬ߦߟߍ߬ߡߊ߲߬ߠߌ߲ ߠߎ߬}}", "enhancedrc-since-last-visit": "$1 {{PLURAL:$1|ߞߊ߬ߦߌ߯ ߓߐߒߡߊߟߌ ߟߊߓߊ߲}}", "enhancedrc-history": "ߘߐ߬ߝߐ", @@ -1131,6 +1150,7 @@ "recentchanges-timeout": "ߢߌߣߌ߲ߣߌ߲ ߣߌ߲߬ ߕߎ߬ߡߊ ߓߘߊ߫ ߕߊ߬ߡߌ߲߬. ߌ ߞߊߞߊ߲߫ ߞߊ߬ ߢߊߢߌߣߌ߲߫ ߜߘߍ߫ ߟߊ߬ߓߍ߲߬ߢߐ߲߰ߡߊ ߞߍ߫.", "recentchanges-network": "ߞߊ߬ ߓߍ߲߬ ߛߋߒߞߏߟߦߊ ߝߎ߬ߕߎ߲߬ߕߌ ߡߊ߬߸ ߞߐߝߟߌ߫ ߛߌ߫ ߕߍ߫ ߣߊ߬ ߛߋ߫ ߟߊ߫ ߟߊߢߎ߲߫ ߠߊ߫. ߌ ߞߊߘߊ߲߫ ߞߊ߬ ߞߐߜߍ ߣߌ߲߬ ߠߊߛߎߡߦߊ߫ ߖߊ߰ߣߌ߲߫.", "recentchanges-notargetpage": "ߞߐߜߍ ߕߐ߮ ߟߊߘߏ߲߬ ߛߊ߲ߝߍ߬߸ ߦߟߍ߬ߡߊ߲ ߡߍ߲ ߦߋ߫ ߞߐߜߍ ߘߐ߫߸ ߞߵߏ߬ ߦߋ߫.", + "recentchanges-feed-description": "ߥߞߌ ߣߌ߲߬ ߡߊ߬ߦߟߍ߬ߡߊ߲߬ߠߌ߲߬ ߞߐ߯ߟߕߊ ߟߎ߬ ߣߐ߬ߣߐ߬ ߓߊߟߏ ߣߌ߲߬ ߘߐ߫.", "recentchanges-label-newpage": "ߡߊ߬ߦߟߍ߬ߡߊ߲߬ߠߌ߲ ߣߌ߲߬ ߓߘߊ߫ ߘߐߜߍ߫ ߞߎߘߊ ߟߊߘߊ߲߫", "recentchanges-label-minor": "ߢߟߊߞߎߘߦߊ߫ ߝߕߌߣߍ߲ ߠߋ߬", "recentchanges-label-bot": "ߡߐ߰ߡߐ߮ ߟߋ߫ ߣߐ߬ ߡߊ߬ߦߟߍ߬ߡߊ߲߬ߠߌ ߣߌ߲߬ ߞߍ߫ ߟߊ߫", @@ -1572,6 +1592,7 @@ "wantedpages": "ߞߐߜߍ߫ ߜߋ߬ߟߎ߲߬ߣߍ߲ ߠߎ߬", "wantedpages-badtitle": "ߞߎ߲߬ߕߐ߮ ߓߍ߲߬ߣߍ߲߬ ߕߍ߫ ߞߐߝߟߌ߫ ߦߌ߬ߘߊ߬ߣߍ߲: $1 ߘߐ߫", "wantedfiles": "ߞߐߜߍ߫ ߜߋ߬ߟߎ߲߬ߣߍ߲ ߠߎ߬", + "wantedfiletext-nocat-noforeign": "ߞߐߕߐ߮ ߢߌ߲߬ ߠߎ߬ ߓߘߊ߫ ߟߊߓߊ߯ߙߊ߫ ߞߏ߬ߣߵߊ߬ߟߎ߬ ߕߴߦߋ߲߬.", "wantedtemplates": "ߞߙߊߞߏ ߞߊ߬ߣߌ߲߬ߣߍ߲ ߠߎ߬", "mostlinked": "ߛߘߌ߬ߜߋ߲߬ ߦߙߌߞߊ߫ ߦߋ߫ ߞߐߜߍ ߡߍ߲ ߠߎ߬ ߘߐ߫", "mostlinkedcategories": "ߛߘߌ߬ߜߋ߲߬ ߦߙߌߞߊ߫ ߦߋ߫ ߦߌߟߡߊ ߡߍ߲ ߠߎ߬ ߘߐ߫", @@ -1590,6 +1611,7 @@ "protectedpages": "ߞߐߜߍ߫ ߟߊߞߊ߲ߘߊߣߍ߲ ߠߎ߬", "protectedpages-filters": "ߛߍ߲ߛߍ߲ߟߊ߲ ߠߎ߬:", "protectedpages-indef": "ߟߊ߬ߞߊ߲߬ߘߊ߬ߟߌ ߘߊ߲߬ߠߊߕߍ߰ߓߊߟߌ ߘߐߙߐ߲߫", + "protectedpages-summary": "ߞߐߜߍ ߛߙߍߘߍ ߢߌ߲߬ ߠߎ߬ ߦߋ߫ ߦߋ߫ ߞߐߜߍ߫ ߟߎ߫ ߟߋ߬ ߘߐ߫ ߡߍ߲ ߠߎ߬ ߟߊߞߊ߲ߘߊߣߍ߲߫ ߦߋ߫ ߕߊ߲߫. ߣߵߌ ߦߋ߫ ߞߎ߲߬ߕߐ߮ ߛߙߍߘߍ߫ ߟߎ߫ ߟߋ߬ ߞߐ߫ ߡߍ߲ ߠߎ߬ ߟߊߞߊ߲ߘߊߣߍ߲߫ ߦߋ߫ ߛߌ߲ߘߟߌ ߡߊ߬߸ ߣߌ߲߬ ߘߐߜߍ߫ [[{{#special:ProtectedTitles}}|{{int:protectedtitles}}]].", "protectedpages-noredirect": "ߟߊ߬ߞߎ߲߬ߛߌ߲߬ߠߌ߲ ߢߡߊߘߏ߲߰", "protectedpages-timestamp": "ߕߎ߬ߡߊ ߓߊ߬ߘߌ߬ߟߊ߲", "protectedpages-page": "ߞߐߜߍ", @@ -2535,10 +2557,49 @@ "specialpages-group-developer": "ߟߊ߬ߥߙߌ߬ߞߌ߬ߟߌ ߖߐ߯ߙߊ߲ ߠߎ߬", "blankpage": "ߞߐߜߍ߫ ߘߐߞߏߟߏ߲", "tag-filter": "[[Special:Tags|ߞߊ߲ߠߊߛߓߍ]] ߢߡߊߘߏ߲߰ߣߍ߲", + "tag-filter-submit": "ߥߊ߬ߣߊߙߌ", "tag-list-wrapper": "[[Special:Tags|{{PLURAL:$1|ߡߊ߬ߛߙߋ |ߡߊ߬ߛߙߋ ߟߎ߬ }}]]: $2", + "tag-mw-contentmodelchange": "ߞߣߐߘߐ ߛߎ߯ߦߊ ߡߊߝߊ߬ߟߋ߲߬ߠߌ߲", + "tag-mw-contentmodelchange-description": "ߣߌ߲߬ ߡߊߦߟߍ߬ߡߊ߲߫\n[https://www.mediawiki.org/wiki/Special:MyLanguage/Help:ߞߣߐߘߐߛߎ߯ߦߊߡߊߝߊ߬ߟߋ߲߬ ߞߣߐߘߐ ߛߎ߯ߦߊ ߡߊߝߊ߬ߟߋ߲߬] ߞߐߜߍ ߘߐ߫", + "tag-mw-new-redirect": "ߟߊ߬ߞߎ߲߬ߛߌ߲߬ߠߌ߲߬ ߞߎߘߊ", + "tag-mw-new-redirect-description": "ߡߊ߬ߦߟߍ߬ߡߊ߲߬ߠߌ߲ ߡߍ߲ ߠߎ߬ ߞߊ߬ ߟߊ߬ߞߎ߲߬ߛߌ߲߬ߠߌ߲ ߠߊߘߊ߲߫ ߥߟߊ߫ ߞߊ߬ ߞߐߜߍ ߦߟߍ߬ߡߊ߲߫ ߞߊ߬ ߞߍ߫ ߟߊ߬ߞߎ߲߬ߛߌ߲߬ߠߌ߲ ߘߌ߫", + "tag-mw-removed-redirect": "ߟߊ߬ߞߎ߲߬ߛߌ߲߬ߠߌ߲ ߛߋ߲߬ߓߐ߫", + "tag-mw-removed-redirect-description": "ߡߊ߬ߦߟߍ߬ߡߊ߲߬ߠߌ߲ ߡߍ߲ ߠߎ߬ ߞߊ߬ ߕߋ߲߭ߕߋ߲߭ ߟߊ߬ߞߎ߲߬ߛߌ߲߬ߠߌ߲ ߡߊߦߟߍ߬ߡߊ߲߫ ߞߵߊ߬ ߞߍ߫ ߟߊ߬ߞߎ߲߬ߛߌ߲߬ߓߊߟߌ ߘߌ߫", + "tag-mw-changed-redirect-target": "ߟߊ߬ߞߎ߲߬ߛߌ߲߬ߠߌ߲ ߞߏ߲߭ ߓߘߊ߫ ߡߊߝߊ߬ߟߋ߲߬", + "tag-mw-changed-redirect-target-description": "ߡߊ߬ߦߟߍ߬ߡߊ߲߬ߠߌ߲ ߡߍ߲ ߠߎ߬ ߞߊ߬ ߟߊ߬ߞߎ߲߬ߛߌ߲߬ߠߌ߲ ߞߏ߲߭ ߡߊߝߊ߬ߟߋ߲߬", + "tag-mw-blank": "ߖߏ߰ߛߌ߬ߟߌ ߦߵߌ ߘߐ߫", + "tag-mw-blank-description": "ߡߊ߬ߦߟߍ߬ߡߊ߲߬ߠߌ߲ ߡߍ߲ ߠߎ߬ ߞߊ߬ ߞߐߜߍ ߖߏ߰ߛߌ߬", + "tag-mw-replace": "ߊ߬ ߓߘߊ߫ ߓߐ߫ ߊ߬ ߣߐ߭ ߘߐ߫", + "tag-mw-replace-description": "ߡߊ߬ߦߟߍ߬ߡߊ߲߬ߠߌ߲ ߡߍ߲ ߠߎ߬ ߞߊ߬ ߞߣߐߘߐ %߉߀ ߛߋ߲߬ߓߐ߫ ߞߐߜߍ ߘߐ߫", + "tag-mw-rollback": "ߟߊߞߐߛߊ߬ߦߌ߬", + "tag-mw-undo": "ߊ߬ ߘߐߛߊ߬", + "tag-mw-undo-description": "ߡߊߦߟߍ߬ߡߊ߲߬ߠߌ߲ ߡߍ߲ ߠߎ߬ ߞߊ߬ ߡߊ߬ߦߟߍ߬ߡߊ߲߬ߠߌ߲߬ ߟߐ߯ߟߊߣߍ߲ ߠߎ߬ ߘߐߛߊ߬ ߞߊ߬ ߘߐ߬ߛߊ߬ߟߌ ߛߘߌ߬ߜߋ߲ ߠߊߓߊ߯ߙߊ߫.", + "tags-title": "ߘߎ߲ߛߓߍ ߟߎ߬", + "tags-tag": "ߘߎ߲ߛߓߍ ߕߐ߮", + "tags-display-header": "ߟߊ߲ߞߣߍߡߊߟߌ ߡߊ߬ߦߟߍ߬ߡߊ߲߬ߠߌ߲߬ ߛߙߍߘߍ ߘߐ߫", + "tags-description-header": "ߞߘߐߝߐߟߌ ߞߊ߲߬ߛߓߍ߬ߟߌ߬ ߘߝߊߣߍ߲", + "tags-source-header": "ߛߎ߲", + "tags-active-header": "ߊ߬ ߟߊߞߎߣߎ߲߫ ߣߍ߲߫؟", + "tags-hitcount-header": "ߞߏ߲߭ ߓߘߊ߫ ߡߊߝߊ߬ߟߋ߲߬", + "tags-actions-header": "ߞߍߟߌ ߟߎ߬", "tags-active-yes": "ߐ߲߬ߐ߲߬ߐ߲߫", "tags-active-no": "ߍ߲߬ߍ߲ߍ߲߬", + "tags-source-extension": "ߡߊ߬ߕߍ߰ߣߍ߲ ߠߎ߬ ߛߎ߲ߝߘߍ ߓߟߏ߫", + "tags-source-manual": "ߟߊ߬ߓߊ߰ߙߊ߬ߟߊ ߣߌ߫ ߓߏߕ ߟߎ߬ ߟߊ߫ ߓߟߏߟߊ߫ ߞߍߟߌ", + "tags-source-none": "ߊ߬ ߕߍߣߊ߬ ߥߊ߯ߕߌߖߊ߲߫ ߞߍ߫ ߟߊ߫ ߓߊ߯ߙߊ ߘߐ߫ ߡߎ߬ߕߎ߲߬", + "tags-edit": "ߊ߬ ߡߊߦߟߍ߬ߡߊ߲߬", + "tags-delete": "ߊ߬ ߖߏ߰ߛߌ߬", + "tags-activate": "ߊ߬ ߟߊߞߎߣߎ߲߫", + "tags-deactivate": "ߊ߬ ߟߊߛߎ߬ߣߐ߬", "tags-hitcount": "{{PLURAL:$1|ߦߟߍ߬ߡߊ߲߬ߠߌ|$1 ߦߟߍ߬ߡߊ߲߬ߠߌ ߠߎ߬}}", + "tags-manage-no-permission": "ߌ ߟߊߘߌ߬ߢߍ߬ߣߍ߲߬ ߕߍ߫ ߞߊ߬ ߘߎ߲ߛߓߍ ߡߊߦߟߍ߬ߡߊ߲߬ߠߌ߲ ߡߊߞߍ߲߰.", + "tags-manage-blocked": "ߌ ߕߍ߫ ߣߊ߬ ߛߋ߫ ߟߊ߫ ߘߎ߲ߛߓߍ ߡߊߦߟߍ߬ߡߊ߲߬ߠߌ߲ ߡߊߞߍ߲߰ ߠߊ߫ ߞߊ߬ {{GENDER:$1|ߌ}} ߓߊ߬ߟߌ߬ߣߍ߲ ߕߏ߫.", + "tags-create-heading": "ߘߎ߲ߛߓߍ߫ ߞߎߘߊ߫ ߛߌ߲ߘߌ", + "tags-create-explanation": "ߘߊ߲ߛߎ߲ ߞߏߛߐ߲߬߸ ߘߎ߲ߛߓߍ ߟߊߘߊ߲ߣߍ߲߫ ߞߎߘߊ ߟߎ߬ ߘߌ߫ ߣߊ߬ ߛߌ߲ߘߌ߫߸ ߊ߬ ߣߌ߫ ߞߊ߬ ߞߍ߫ ߦߋ߲߬ ߟߊ߬ߓߊ߰ߙߊ߬ߟߊ ߣߌ߫ ߓߏߕ ߟߊ߫ ߟߊ߬ߓߊ߰ߙߊ߬ߟߌ ߞߊ߲ߡߊ߬.", + "tags-create-tag-name": "ߘߎ߲ߛߓߍ ߕߐ߮:", + "tags-create-reason": "ߊ߬ ߛߊߓߎ:", + "tags-create-submit": "ߟߊ߬ߘߊ߲߬ߠߌ߲", + "tags-create-no-name": "ߌ ߞߊߞߊ߲߫ ߞߊ߬ ߘߎ߲ߛߓߍ ߕߐ߮ ߘߏ߫ ߞߙߍߞߙߍ߫.", "logentry-delete-delete": "$1 {{GENDER:$2|deleted}} ߞߐߜߍ $3", "logentry-delete-restore": "$1 $3($4) ߞߐߜߍ {{GENDER:$2|ߓߘߊ߫ ߟߊߛߊ߬ߦߌ߬ ߞߐ߫}}", "logentry-delete-revision": "$1 {{GENDER:$2|ߓߘߊ߫ ߦߟߍ߬ߡߊ߲߬ߠߌ߲ ߞߍ߫}} ߣߌ߲߬ ߦߋߗߏ߮ ߟߊ߫ {{PLURAL:$5|a revision|$5 revisions}} ߞߐߜߍ ߣߌ߲߬ $3: $4 ߘߐ߫", diff --git a/languages/i18n/pl.json b/languages/i18n/pl.json index 04fec53574..2ec2e449bb 100644 --- a/languages/i18n/pl.json +++ b/languages/i18n/pl.json @@ -102,7 +102,8 @@ "Vlad5250", "CiaPan", "BadDog", - "Rail" + "Rail", + "Maro21" ] }, "tog-underline": "Podkreślenie linków:", @@ -149,6 +150,7 @@ "tog-useeditwarning": "Ostrzegaj mnie, gdy opuszczam stronę edycji bez zapisania zmian", "tog-prefershttps": "Zawsze używaj bezpiecznego połączenia po zalogowaniu", "tog-showrollbackconfirmation": "Wyświetl komunikat potwierdzający kliknięcie linku wycofującego edycje", + "tog-requireemail": "Wymagaj adresu e-mail przy resetowaniu hasła", "underline-always": "Zawsze", "underline-never": "Nigdy", "underline-default": "według ustawień skórki lub przeglądarki", @@ -1078,7 +1080,7 @@ "searchall": "wszystkie", "showingresults": "Poniżej znajduje się lista {{PLURAL:$1|z '''1''' wynikiem|'''$1''' wyników}}, rozpoczynając od wyniku numer '''$2'''.", "showingresultsinrange": "Poniżej wyświetlono co najwyżej {{PLURAL:$1|1 wynik|$1 wyniki|$1 wyników}} w zakresie od $2 do $3.", - "search-showingresults": "{{PLURAL:$4|Wynik $1 z $3|Wyniki $1 - $2 z $3}}", + "search-showingresults": "{{PLURAL:$4|Wynik $1 z $3|Wyniki $1 – $2 z $3}}", "search-nonefound": "Brak wyników spełniających kryteria podane w zapytaniu.", "search-nonefound-thiswiki": "Brak wyników spełniających kryteria podane w zapytaniu.", "powersearch-legend": "Wyszukiwanie zaawansowane", @@ -1188,6 +1190,7 @@ "prefs-help-email": "Podanie adresu e‐mail nie jest obowiązkowe, lecz jest konieczne do zresetowania zapomnianego hasła.", "prefs-help-email-others": "Możesz również umożliwić innym użytkownikom wysłanie do Ciebie e‐maila poprzez Twoją stronę użytkownika lub stronę dyskusji (bez ujawniania Twojego adresu).", "prefs-help-email-required": "Wymagany jest adres e‐mail.", + "prefs-help-requireemail": "Po zaznaczeniu wiadomości e-mail z linkiem do resetu hasła będą wysyłane dopiero gdy resetujący użytkownik wprowadzi zarówno nazwę użytkownika jak i adres e-mail przypisane do tego konta.", "prefs-info": "Podstawowe informacje", "prefs-i18n": "Ustawienia językowe", "prefs-signature": "Podpis", @@ -2640,6 +2643,7 @@ "ipblocklist-legend": "Znajdź zablokowanego użytkownika", "blocklist-userblocks": "Ukryj blokady konta", "blocklist-tempblocks": "Ukryj tymczasowe blokady", + "blocklist-indefblocks": "Ukryj blokady nałołożone na zawsze", "blocklist-addressblocks": "Ukryj blokady pojedynczych adresów IP", "blocklist-type": "Typ:", "blocklist-type-opt-all": "Wszystkie", @@ -2929,7 +2933,7 @@ "tooltip-p-logo": "Strona główna", "tooltip-n-mainpage": "Zobacz stronę główną", "tooltip-n-mainpage-description": "Przejdź na stronę główną", - "tooltip-n-portal": "O projekcie - co możesz zrobić, gdzie możesz znaleźć informacje", + "tooltip-n-portal": "O projekcie – co możesz zrobić, gdzie możesz znaleźć informacje", "tooltip-n-currentevents": "Informacje o aktualnych wydarzeniach", "tooltip-n-recentchanges": "Lista ostatnich zmian w {{GRAMMAR:MS.lp|{{SITENAME}}}}.", "tooltip-n-randompage": "Załaduj losową stronę", diff --git a/languages/i18n/pt-br.json b/languages/i18n/pt-br.json index 1106f5f309..622ab5185d 100644 --- a/languages/i18n/pt-br.json +++ b/languages/i18n/pt-br.json @@ -167,6 +167,7 @@ "tog-useeditwarning": "Avisar-me quando eu deixar uma janela de edição sem ter salvo as alterações", "tog-prefershttps": "Usar sempre uma conexão segura enquanto estiver conectado", "tog-showrollbackconfirmation": "Mostrar um aviso de confirmação ao clicar em um link de reversão", + "tog-requireemail": "Exigir e-mail para redefinições de senha", "underline-always": "Sempre", "underline-never": "Nunca", "underline-default": "Padrão do navegador/tema", @@ -1217,6 +1218,7 @@ "prefs-help-email": "O endereço de e-mail é opcional, mas será necessário para recriar sua senha caso esqueça a antiga.", "prefs-help-email-others": "Você também pode optar por permitir que outros entrem em contato com você através de sua página de usuário ou de discussão sem ter de revelar seus dados pessoais.", "prefs-help-email-required": "O endereço de e-mail é requerido.", + "prefs-help-requireemail": "Se marcado, só enviará emails de redefinição de senha se a pessoa que redefiniu tiver fornecido o nome de usuário e o e-mail para esta conta.", "prefs-info": "Informações básicas", "prefs-i18n": "Internacionalização", "prefs-signature": "Assinatura", @@ -2684,6 +2686,7 @@ "ipblocklist-legend": "Procurar por um usuário bloqueado", "blocklist-userblocks": "Esconder bloqueios de contas", "blocklist-tempblocks": "Esconder bloqueios temporários", + "blocklist-indefblocks": "Ocultar bloqueios indefinidos", "blocklist-addressblocks": "Esconder bloqueios de IP único", "blocklist-type": "Tipo:", "blocklist-type-opt-all": "Todos", diff --git a/languages/i18n/qqq.json b/languages/i18n/qqq.json index 4061556438..a33608f5fb 100644 --- a/languages/i18n/qqq.json +++ b/languages/i18n/qqq.json @@ -2906,6 +2906,7 @@ "ipblocklist-legend": "Used as legend of the form in [[Special:BlockList]].\n\nSee also:\n* {{msg-mw|Ipblocklist-legend}}\n* {{msg-mw|Ipblocklist-submit}}", "blocklist-userblocks": "Used as the label for the multi-select checkbox in the form on [[Special:BlockList]].\n{{Related|Blocklist-blocks}}", "blocklist-tempblocks": "Used as the label for the multi-select checkbox in the form on [[Special:BlockList]].\n{{Related|Blocklist-blocks}}", + "blocklist-indefblocks": "Used as the label for the multi-select checkbox in the form on [[Special:BlockList]].\n{{Related|Blocklist-blocks}}", "blocklist-addressblocks": "Used as the label for the multi-select checkbox in the form on [[Special:BlockList]].\n{{Related|Blocklist-blocks}}", "blocklist-type": "Used as label for dropdown box in [[Special:BlockList]].", "blocklist-type-opt-all": "Used as option for dropdown box in [[Special:BlockList]]. This is the default option and indicates that \"all\" blocks will be listed\n{{Identical|All}}", diff --git a/languages/i18n/roa-tara.json b/languages/i18n/roa-tara.json index a55c17d97c..ceb5005413 100644 --- a/languages/i18n/roa-tara.json +++ b/languages/i18n/roa-tara.json @@ -182,7 +182,7 @@ "printableversion": "Versione ca se stambe", "permalink": "Collegamende ca remane pe sembre", "print": "Stambe", - "view": "Vide", + "view": "'Ndruche", "view-foreign": "'Ndruche sus a $1", "edit": "Cange", "edit-local": "Cange 'a descrizione locale", @@ -190,7 +190,7 @@ "create-local": "Aggiunge 'a descrizione locale", "delete": "Scangìlle", "undelete_short": "Annulle {{PLURAL:$1|'nu camgiamende|$1 cangiaminde}}", - "viewdeleted_short": "Vide {{PLURAL:$1|'nu cangiamende scangellate|$1 cangiaminde scangellate}}", + "viewdeleted_short": "'Ndruche {{PLURAL:$1|'nu cangiamende scangellate|$1 cangiaminde scangellate}}", "protect": "Prutette", "protect_change": "cange", "unprotect": "Cange 'a protezione", @@ -204,12 +204,12 @@ "tool-link-userrights": "Cange le gruppe {{GENDER:$1|utinde}}", "tool-link-userrights-readonly": "'Ndruche le gruppe {{GENDER:$1|utinde}}", "tool-link-emailuser": "Manne 'na mail a stu {{GENDER:$1|utende}}", - "imagepage": "Vide a pàgene de le file", - "mediawikipage": "Vide a pàgene de le messàgge", - "templatepage": "Vide a pàgene de le template", - "viewhelppage": "Vide a pàgene de l'ajute", - "categorypage": "Vide a pàgene de le categorije", - "viewtalkpage": "Vide le 'ngazzaminde", + "imagepage": "'Ndruche 'a pàgene de le file", + "mediawikipage": "'Ndruche 'a pàgene de le messàgge", + "templatepage": "'Ndruche 'a pàgene de le template", + "viewhelppage": "'Ndruche 'a pàgene de l'ajute", + "categorypage": "'Ndruche 'a pàgene de le categorije", + "viewtalkpage": "'Ndruche le 'ngazzaminde", "otherlanguages": "Jndr'à l'otre lènghe", "redirectedfrom": "(Riderette da $1)", "redirectpagesub": "Pàgene de redirezione", @@ -2400,6 +2400,7 @@ "ipblocklist-legend": "Iacchije 'n'utende blocchete", "blocklist-userblocks": "Scunne le blocche sus a le cunde de l'utinde", "blocklist-tempblocks": "Scunne le blocche temboranèe", + "blocklist-indefblocks": "Scunne le blocche indefinite", "blocklist-addressblocks": "Scunne le blocche de le IP singole", "blocklist-type": "Tipe:", "blocklist-type-opt-all": "Tutte", diff --git a/languages/i18n/ru.json b/languages/i18n/ru.json index d6094cd56e..b103404ae0 100644 --- a/languages/i18n/ru.json +++ b/languages/i18n/ru.json @@ -193,6 +193,7 @@ "tog-useeditwarning": "Предупреждать, когда я покидаю страницу с несохранёнными изменениями", "tog-prefershttps": "Всегда использовать защищённое соединение после представления системе", "tog-showrollbackconfirmation": "Запрашивать подтверждение при нажатии ссылки для отката", + "tog-requireemail": "Требовать адрес электронной почты для сброса пароля", "underline-always": "Всегда", "underline-never": "Никогда", "underline-default": "Использовать настройки браузера", @@ -939,6 +940,7 @@ "undo-norev": "Правка не может быть отменена, так как её не существует или она была удалена.", "undo-nochange": "Правка, похоже, уже была отменена.", "undo-summary": "Отмена правки $1, сделанной [[Special:Contributions/$2|$2]] ([[User talk:$2|обсуждение]])", + "undo-summary-anon": "Отмена версии $1 от [[Special:Contributions/$2|$2]]", "undo-summary-username-hidden": "Отмена правки $1, сделанной участником, чьё имя скрыто", "cantcreateaccount-text": "Создание учётных записей с этого IP-адреса ($1) было заблокировано {{GENDER:$3|участником|участницей|}} [[User:$3|$3]].\n\n$3 {{GENDER:$3|указал|указала}} следующую причину: $2.", "cantcreateaccount-range-text": "{{GENDER:$3|Участник|Участница}} [[User:$3|$3]] {{GENDER:$3|установил|установила}} запрет на создание учётных записей для диапазона IP-адресов $1, включающего ваш IP-адрес ($4). \n\nБыла указана следующая причина: $2.", @@ -1236,6 +1238,7 @@ "prefs-help-email": "Адрес почты не обязателен, но это единственный способ восстановить забытый пароль.", "prefs-help-email-others": "Он также позволит другим участникам связаться с вами по электронной почте с помощью ссылки на вашей персональной странице или на вашей странице обсуждения. При этом ваш адрес электронной почты не будет никому раскрыт.", "prefs-help-email-required": "Необходимо указать адрес электронной почты.", + "prefs-help-requireemail": "Если этот флажок установлен, электронные письма для сброса пароля будут отправляться только в том случае, если лицо, осуществляющее сброс, указало для этой учётной записи и имя пользователя, и адрес электронной почты.", "prefs-info": "Основные сведения", "prefs-i18n": "Интернационализация", "prefs-signature": "Подпись", @@ -2456,6 +2459,7 @@ "alreadyrolled": "Невозможно откатить последние изменения страницы «[[:$1]]», совершённые [[User:$2|$2]] ([[User talk:$2|обсуждение]]{{int:pipe-separator}}[[Special:Contributions/$2|{{int:contribslink}}]]),\nпоскольку кто-то другой уже успел откатить эти правки или отредактировать страницу.\n\nПоследние изменения {{GENDER:$3|внёс|внесла}} [[User:$3|$3]] ([[User talk:$3|обсуждение]]{{int:pipe-separator}}[[Special:Contributions/$3|{{int:contribslink}}]]).", "editcomment": "Было дано описание изменения: $1.", "revertpage": "Откат правок [[Special:Contributions/$2|$2]] ([[User talk:$2|обсуждение]]) к версии [[User:$1|$1]]", + "revertpage-anon": "Откат правок [[Special:Contributions/$2|$2]] к последней версии от [[User:$1|$1]]", "revertpage-nouser": "Откат правок (имя участника скрыто) к версии {{GENDER:$1|[[User:$1|$1]]}}", "rollback-success": "Откачены правки {{GENDER:$3|$1}}; возвращена последняя версия {{GENDER:$4|$2}}.", "sessionfailure-title": "Ошибка сеанса", @@ -2692,6 +2696,7 @@ "ipblocklist-legend": "Поиск заблокированного участника", "blocklist-userblocks": "Скрыть блокировки учётных записей", "blocklist-tempblocks": "Скрыть временные блокировки", + "blocklist-indefblocks": "Скрыть неопределённые блокировки", "blocklist-addressblocks": "Скрыть блокировки отдельных IP", "blocklist-type": "Тип:", "blocklist-type-opt-all": "Все", diff --git a/languages/i18n/sh.json b/languages/i18n/sh.json index a4c30f82bd..fc3c4f33b7 100644 --- a/languages/i18n/sh.json +++ b/languages/i18n/sh.json @@ -67,6 +67,7 @@ "tog-useeditwarning": "Upozori me kad napuštam stranicu za uređivanje bez snimanja izmjena", "tog-prefershttps": "Uvijek koristi sigurnu vezu dok sam prijavljen", "tog-showrollbackconfirmation": "Prikaži potvrdnicu kada kliknete vezu za opoziv", + "tog-requireemail": "Zahtijevaj e-poštu za stavljanje novu lozinku", "underline-always": "Uvijek", "underline-never": "Nikad", "underline-default": "prema skinu ili postavkama preglednika", @@ -801,6 +802,7 @@ "undo-norev": "Izmjena se ne može vratiti jer ne postoji ranija ili je obrisana.", "undo-nochange": "Ovo je uređivanje izgleda već bilo poništeno.", "undo-summary": "Poništena izmjena $1 [[Special:Contribs/$2|korisnika $2]] ([[User talk:$2|razgovor]])", + "undo-summary-anon": "Poništi izmjenu $1 {{GENDER:$2|korisnika|korisnice}} [[Special:Contributions/$2|$2]]", "undo-summary-username-hidden": "Poništi izmjenu $1 od skrivenog korisnika", "cantcreateaccount-text": "Pravljenje korisničkog računa sa ove IP adrese ('''$1''') je blokirano od strane [[User:$3|$3]].\n\nRazlog koji je naveo $3 je ''$2''", "cantcreateaccount-range-text": "Stvaranje računa od IP adresa iz pojasa$1, koji uključuje vašu IP adresu ($4), je blokirao/la [[User:$3|$3]].\n\nRazlog koji je dao/la $3 je $2", @@ -1098,6 +1100,7 @@ "prefs-help-email": "E-mail adresa je opcionalna, ali je potrebna jer omogućava da Vam se pošalje nova šifra u slučaju da je izgubite ili zaboravite.", "prefs-help-email-others": "Također možete da odaberete da vas drugi kontaktiraju putem vaše korisničke stranice ili stranice za razgovor bez otkrivanja vašeg identiteta.", "prefs-help-email-required": "Neophodno je navesti e-mail adresu.", + "prefs-help-requireemail": "Ako je štiklirano, mogućnost za novu lozinku će imaju samo korisnici koji naveli su korisničko ime i e-poštu.", "prefs-info": "Osnovne informacije", "prefs-i18n": "Internacionalizacija", "prefs-signature": "Potpis", @@ -2310,6 +2313,7 @@ "alreadyrolled": "Ne može se vratiti posljednja izmjena [[:$1]] od korisnika [[User:$2|$2]] ([[User talk:$2|razgovor]]{{int:pipe-separator}}[[Special:Contributions/$2|{{int:contribslink}}]]); neko drugi je već izmjenio ili vratio članak.\n\nPosljednja izmjena je bila od korisnika [[User:$3|$3]] ([[User talk:$3|razgovor]]{{int:pipe-separator}}[[Special:Contributions/$3|{{int:contribslink}}]]).", "editcomment": "Sažetak izmjene je bio: $1.", "revertpage": "Vraćene izmjene [[Special:Contributions/$2|$2]] ([[User talk:$2|razgovor]]) na posljednju izmjenu korisnika [[User:$1|$1]]", + "revertpage-anon": "Vraćene izmjene [[Special:Contributions/$2|$2]] na posljednju izmjenu korisnika [[User:$1|$1]]", "revertpage-nouser": "Vraćene izmjene skrivenog korisnika na posljednju reviziju, koju je {{GENDER:$1|napravio|napravila}} [[User:$1|$1]]", "rollback-success": "Vraćene su izmjene korisnika {{GENDER:$3|$1}};\nvraćeno na posljednju verziju koju je snimio {{GENDER:$4|$2}}.", "sessionfailure-title": "Greška u sesiji", @@ -2546,6 +2550,7 @@ "ipblocklist-legend": "Traži blokiranog korisnika", "blocklist-userblocks": "Sakrij blokade računa", "blocklist-tempblocks": "Sakrij privremene blokade", + "blocklist-indefblocks": "Sakrij beskonačne blokade", "blocklist-addressblocks": "Sakrij pojedinačne IP blokade", "blocklist-type": "Vrsta:", "blocklist-type-opt-all": "Sve", diff --git a/languages/i18n/sl.json b/languages/i18n/sl.json index 7cd6220cbd..9a40d38c97 100644 --- a/languages/i18n/sl.json +++ b/languages/i18n/sl.json @@ -64,6 +64,7 @@ "tog-useeditwarning": "Opozori me, ko skušam zapreti urejevalno polje z neshranjenimi spremembami", "tog-prefershttps": "Med prijavo vedno uporabljaj varno povezavo", "tog-showrollbackconfirmation": "Pokaži potrditveno okno ob kliku na povezavo za vrnitev", + "tog-requireemail": "Zahtevaj e-poštni naslov za ponastavitev gesla", "underline-always": "Vedno", "underline-never": "Nikoli", "underline-default": "Koža ali privzeto v brskalniku", @@ -804,6 +805,7 @@ "undo-norev": "Urejanja ni mogoče razveljaviti, ker ne obstaja ali je bilo izbrisano.", "undo-nochange": "Zdi se, da je urejanje nekdo že razveljavil.", "undo-summary": "Redakcija $1 uporabnika [[Special:Contributions/$2|$2]] ([[User talk:$2|pogovor]]) razveljavljena", + "undo-summary-anon": "Razveljavitev redakcije $1 uporabnika [[Special:Contributions/$2|$2]]", "undo-summary-username-hidden": "Razveljavi redakcijo $1 skritega uporabnika", "cantcreateaccount-text": "Registracije z IP-naslova ('''$1''') je administrator(ka) [[User:$3|$3]] blokiral(a).\n\nRazlog, ki ga je $3 podal(a), je ''$2''.", "cantcreateaccount-range-text": "Ustvarjanje računov z IP-naslovov v območju $1, ki vključuje vaš IP-naslov ($4), je blokiral(-a) [[User:$3|$3]].\n\nRazlog, ki ga je podal(-a) $3, je $2.", @@ -1102,6 +1104,7 @@ "prefs-help-email": "E-poštni naslov ni obvezen, vendar omogoča, da vam v primeru pozabljenega gesla pošljemo novo.", "prefs-help-email-others": "Omogočite lahko tudi možnost, da vam lahko ostali uporabniki pošiljajo e-pošto prek vaše uporabniške ali pogovorne strani.\nKo vas drugi uporabniki kontaktirajo, jim vašega e-poštnega naslova ne bomo razkrili.", "prefs-help-email-required": "E-poštni naslov je obvezen.", + "prefs-help-requireemail": "Če je označeno, bo e-pošta za ponastavitev gesla poslana samo, če je oseba, ki je sprožila ponastavitev, vnesla tako uporabniško ime kot e-poštni naslov tega računa.", "prefs-info": "Osnovni podatki", "prefs-i18n": "Internacionalizacija", "prefs-signature": "Podpis", @@ -2316,6 +2319,7 @@ "alreadyrolled": "Zadnje spremembe [[:$1]] uporabnika [[User:$2|$2]] ([[User talk:$2|pogovor]]{{int:pipe-separator}}[[Special:Contributions/$2|{{int:contribslink}}]]) ne morem vrniti;\nstran je spremenil ali vrnil že nekdo drug.\n\nZadnji je stran urejal uporabnik [[User:$3|$3]] ([[User talk:$3|pogovor]]{{int:pipe-separator}}[[Special:Contributions/$3|{{int:contribslink}}]]).", "editcomment": "Povzetek urejanja je bil: $1.", "revertpage": "vrnitev sprememb uporabnika [[Special:Contributions/$2|$2]] ([[User talk:$2|pogovor]]) na zadnje urejanje uporabnika [[User:$1|$1]]", + "revertpage-anon": "Vrnjena urejanja uporabnika [[Special:Contributions/$2|$2]] na zadnjo redakcijo uporabnika [[User:$1|$1]]", "revertpage-nouser": "vrnitev sprememb skritega uporabnika na zadnjo redakcijo {{GENDER:$1|[[User:$1|$1]]}}", "rollback-success": "Razveljavljene spremembe {{GENDER:$3|uporabnika|uporabnice}} $1;\nvrnjeno na urejanje {{GENDER:$4|uporabnika|uporabnice}} $2.", "sessionfailure-title": "Neuspeh seje", diff --git a/languages/i18n/sv.json b/languages/i18n/sv.json index dcc686b910..7dd965f8fe 100644 --- a/languages/i18n/sv.json +++ b/languages/i18n/sv.json @@ -130,6 +130,7 @@ "tog-useeditwarning": "Varna mig om jag lämnar en redigeringssida med osparade ändringar", "tog-prefershttps": "Använd alltid en säker anslutning medan jag är inloggad", "tog-showrollbackconfirmation": "Visa en bekräftelsedialog när man klickar på en tillbakarullningslänk", + "tog-requireemail": "Kräv e-postadress för att återställa lösenord", "underline-always": "Alltid", "underline-never": "Aldrig", "underline-default": "Webbläsarens eller utseendets standardinställning", @@ -1168,6 +1169,7 @@ "prefs-help-email": "Att ange e-postadress är valfritt, men gör det möjligt att få ditt lösenord mejlat till dig om du glömmer det.", "prefs-help-email-others": "Du kan också välja att låta andra kontakta dig via e-post genom en länk på din användar- eller diskussionssida. \nDin e-postadress avslöjas inte när andra användare kontaktar dig.", "prefs-help-email-required": "E-postadress måste anges.", + "prefs-help-requireemail": "Om detta markeras kommer lösenordsåterställningar endast skickas via e-post om återställaren har angivit både användarnamn och e-postadress för detta konto.", "prefs-info": "Grundläggande information", "prefs-i18n": "Internationalisering", "prefs-signature": "Signatur", diff --git a/languages/i18n/szl.json b/languages/i18n/szl.json index 8446ebd584..31492ed5a3 100644 --- a/languages/i18n/szl.json +++ b/languages/i18n/szl.json @@ -252,8 +252,8 @@ "viewsourcelink": "pokŏż zdrzōdło", "editsectionhint": "Edytuj sekcyjõ: $1", "toc": "Wykŏz treści", - "showtoc": "uobejrzij", - "hidetoc": "schrůń", + "showtoc": "pokŏż", + "hidetoc": "skryj", "collapsible-collapse": "Skryj", "collapsible-expand": "Pokŏż", "thisisdeleted": "Pokŏzać abo stworzić zaś $1?", @@ -271,7 +271,7 @@ "sort-ascending": "Sortuj rosnůnco", "nstab-main": "Strōna", "nstab-user": "{{GENDER:{{BASEPAGENAME}}|Strōna ôd używŏcza|Strōna ôd używŏczki}}", - "nstab-media": "Pliki", + "nstab-media": "Zbiōr", "nstab-special": "Specjalnŏ strōna", "nstab-project": "Strōna projektu", "nstab-image": "Zbiōr", @@ -478,7 +478,7 @@ "changeemail-newemail": "Nowŏ e-mailowŏ adresa:", "changeemail-none": "podstawowo", "changeemail-submit": "Spamjyntej nowy", - "resettokens": "Resetuj tokeny", + "resettokens": "Resetuj tokyny", "bold_sample": "Ruby tekst", "bold_tip": "Ruby tekst", "italic_sample": "Kursywa", @@ -501,6 +501,7 @@ "watchthis": "Ôbserwuj tã strōnã", "savearticle": "Spamiyntej", "publishpage": "Ôpublikuj strōnã", + "publishchanges": "Ôpublikuj zmiany", "publishpage-start": "Ôpublikuj strōnã...", "preview": "Podglōnd", "showpreview": "Pokŏż podglōnd", @@ -560,7 +561,7 @@ "editingold": "'''Dej pozůr: Sprowjosz inkszo wersyjo zajty kej bjeżůnco. Jeli jům naszkryflosz, wszyjske půźńyjsze pomjyńańa bydům wyćepane.'''", "yourdiff": "Rōżnice", "copyrightwarning": "Pamjyntej uo tym, aże cołki wkłod do {{SITENAME}} udostympńůmy wedle zasad $2 (dokładńij we $1). Jak ńy chcesz, coby kożdy můg go půmjyńać a dalij rozpowszychńoć, ńy wćepuj uůnygo sam. Szkryflajůnc sam tukej pośwjadczosz tyż, co te pisańy je twoje własne, abo żeś go wźůn(a) ze materjołůw kere sům na ''public domain'', abo kůmpatybilne.
\n'''PROSZA ŃY WĆEPYWAĆ SAM MATYRJOŁŮW KERE SŮM CHRŮŃONE AUTORSKIM PRAWYM BEZ DOZWOLEŃO WŁAŚĆIĆELA!'''", - "copyrightwarning2": "Pamjyntej uo tym, aże cołki wkłod do {{GRAMMAR:MS.lp|{{SITENAME}}}} może być sprowjany, pomjyńany abo wyćepany bez inkszych użytkownikůw. Jak ńy chcysz, coby kożdy můg uůnygo zmjyńać a dalij rozpowszychńoć bez uograniczyń, ńy wćepuj go sam.
\nSzkryflajůnc sam tukej pośwjadczosz tyż, co te pisańy je twoje własne, abo żeś go wźůn(a) ze matyrjołůw kere sům na public domain, abo kůmpatybilne (kuknij tyż: $1).\n'''PROSZA ŃY WĆEPYWAĆ SAM MATYRJOŁŮW KERE SŮM CHRŮŃONE PRAWYM AUTORSKIM BEZ DOZWOLEŃO WŁAŚĆIĆELA!'''", + "copyrightwarning2": "Dej pozōr, iże cołki wkłŏd na {{SITENAME}} może być edytowany, zmiyniany abo kasowany ôd inkszych używŏczōw. Jeźli niy chcesz, żeby twōj tekst bōł niymiyłosiernie edytowany, to niy wkludzej go sam.
\nPrzirzekŏsz tyż nōm, iże wszyjsko je napisane ôd ciebie abo skopiowane ze dōmyny publicznyj abo podobnego wolnego zdrzōdła (po wiyncyj informacyji patrz $1).\nNiy wkludzej dzieł chrōniōnych autorskimi prawami bez przizwolyniŏ!", "longpageerror": "''Feler: Tekst kery żeś sam wćepywoł mo {{PLURAL:$1|jedyn kilobajt|$1 kilobajtůw}}. Maksymalno dugość tekstu ńy może być srogszo kej {{PLURAL:$2|jedyn kilobajt|$2 kilobajtůw}}. Twůj tekst ńy bydźe sam naszkryflany.'''", "readonlywarning": "'''Dej pozůr: Baza danych zostoua filowo zawarto skuli potřeb admińistracyjnych. Bestůž ńy do śe terozki naškryflać Twojich pomjyńań. Radzymy přećepać nowy tekst kajś do plika tekstowego (wytnij/wklej) a wćepać sam zaś po uodymkńyńću bazy.'''\n\nAdmińistrator kery zawar baza dou take wyjaśńyńe: $1", "protectedpagewarning": "'''Dej pozůr: Sprowjańe tyj zajty zostoło zawarte. Mogům jům sprowjać ino użytkowńicy ze uprawńyńami admińistratora.'''\nUostatńy wpis w rejerze je poniżej.", @@ -568,7 +569,7 @@ "cascadeprotectedwarning": "'''Dej pozůr:''' Ta zajta zostoła zawarto a ino użytkowńicy ze uprawńyńami admińistratora mogům jům sprowjać. Zajta ta je podpjynto pod {{PLURAL:$1|nastympujůnco zajta, kero zostoła zawarto|nastympujůncych zajtach, kere zostouy zawarte}} ze załůnczonům uopcjům dźedźiczyńo:", "titleprotectedwarning": "'''Dej pozůr: Zajta uo tym titlu zostoła zawarto a ino [[Special:ListGroupRights|ńykerzi użytkowńicy]] mogům jům wćepać.'''\nUostatńy wpis z rejera je ńyżej.", "templatesused": "{{PLURAL:$1|Muster użyty|Mustry użyte}} na tyj strōnie:", - "templatesusedpreview": "{{PLURAL:$1|Muster użyty|Mustry użyte}} na tyj podglōńdzie:", + "templatesusedpreview": "{{PLURAL:$1|Muster użyty|Mustry użyte}} na tym podglōńdzie:", "templatesusedsection": "{{PLURAL:$1|Szablon|Szablůny}} użyte we tyj tajli:", "template-protected": "(chrōniōny)", "template-semiprotected": "(pōłzawarte)", @@ -589,7 +590,7 @@ "edit-no-change": "Twoje sprowjyńe uostoło zignorowane pů takymu, aże ńic żeś we tekśće ńy zmjyńůł.", "postedit-confirmation-saved": "Spamjyntano twoje sprowjyńe.", "edit-already-exists": "Ńy idźe utworzić nowyj zajty.\nTako zajta już sam je.", - "defaultmessagetext": "Tekst důmyślny", + "defaultmessagetext": "Wychodny tekst wiadōmości", "content-model-wikitext": "wikitekst", "expensive-parserfunction-warning": "Dej pozůr: ta zajta mo za dużo uodwouań do funkcyji parsera, kere mocno uobćůnżajům systym.\n\nPowinno być myńi jak $2 {{PLURAL:$2|wywołańy|wywołańo|wywołań}}, a terozki {{PLURAL:$1|je $1 wywołańy|sům $1 wywołańo|je $1 wywołań}}.", "expensive-parserfunction-category": "Zajty kere majům za dużo uodwołań do funkcyji parsera, kere mocno uobćůnżajům systym.", @@ -750,7 +751,7 @@ "search-showingresults": "{{PLURAL:$4|Rezultat $1 ze $3|Rezultaty $1 – $2 ze $3}}", "search-nonefound": "Żŏdne wyniki niy ôdpowiadajōm tymu zapytaniu.", "powersearch-legend": "Sznupańy zaawansowane", - "powersearch-ns": "Sznupej we przestrzyńach mjan:", + "powersearch-ns": "Szukej we przestrzyniach mian:", "powersearch-togglelabel": "Ôznŏcz:", "powersearch-toggleall": "Wszyjsko", "powersearch-togglenone": "Nic", @@ -762,12 +763,12 @@ "prefs-edits": "Liczba edycyji:", "prefs-skin": "Skůrka", "skin-preview": "podglůnd", - "datedefault": "Důmyślny", + "datedefault": "Wychodny", "prefs-labs": "Funkcyje \"labs\"", "prefs-user-pages": "Zajty ôd używŏczōw", "prefs-personal": "Dane używocza", "prefs-rc": "Ôstatnie zmiany", - "prefs-watchlist": "Pozůrlista", + "prefs-watchlist": "Ôbserwowane", "prefs-watchlist-days": "Liczba dńůw widocznych na liśće artikli, na kere dowosz pozůr:", "prefs-watchlist-days-max": "Max $1 {{PLURAL:$1|dźyń|dńi}}", "prefs-watchlist-edits": "Liczba půmjyńań pokozywanych we rozszyrzůnyj liśće artiklůw, na kere dowosz pozůr:", @@ -788,8 +789,8 @@ "recentchangesdays": "Liczba dńůw do pokazańo we půmjyńanych na uostatku:", "recentchangesdays-max": "(maksymalńy $1 {{PLURAL:$1|dźyń|dńi}})", "recentchangescount": "Liczba pozycyji na liśće půmjyńanych na uostatku, we historyje zajtůw a zajtach rejerůw:", - "prefs-help-recentchangescount": "Ze listům ńydawnych pomjyńan, gyszichta zajt a rejer.", - "savedprefs": "Twoje sztalowańo we preferyncyjach zostoły naszkryflane.", + "prefs-help-recentchangescount": "Maksymalnŏ wielość: 1000", + "savedprefs": "Twoje sztelōnki były spamiyntane.", "timezonelegend": "Czasowo sztrefa", "localtime": "Lokalny czas:", "timezoneuseserverdefault": "Użyj domyślnygo czasu serwera ($1)", @@ -810,7 +811,7 @@ "prefs-searchoptions": "Sznupańe", "prefs-namespaces": "Raumy mjan", "default": "důmyślńy", - "prefs-files": "Pliki", + "prefs-files": "Zbiory", "youremail": "E-mail:", "username": "{{GENDER:$1|Mjano używocza}}:", "prefs-memberingroups": "Należy do {{PLURAL:$1|grupy|grup:}}", @@ -890,7 +891,7 @@ "right-bigdelete": "Wyćep zajty s dugům historyjům půmjyńań", "right-deleterevision": "Wyćepywańy a wćepywańy nazod wskazanych sprowjyń zajtůw", "right-deletedhistory": "Pokazuj historyjo usuńyntych sprowjyń, bez tekstu uopisu", - "right-browsearchive": "Sznupej za wyćepanymi zajtůma", + "right-browsearchive": "Szukej we skasowanych strōnach", "right-undelete": "Prziwrŏcanie skasowanych strōn", "right-suppressrevision": "Přyglůndańy i uodtwařańy sprowjyń schrůńůnych před admińistratorami", "right-suppressionlog": "Pokoż prywatne lůgi", @@ -918,9 +919,9 @@ "right-userrights-interwiki": "Edytuj uprawniynia używŏczōw na inkszych wiki", "right-siteadmin": "Zawjerańy i uodmykańy bazy danych", "newuserlogpage": "Ksiōnżka nowych używŏczōw", - "newuserlogpagetext": "To je rejer uostatńo utworzůnych kůnt użytkowńikůw", + "newuserlogpagetext": "To je regest tworzōnych używŏczōw.", "rightslog": "Regest uprawniyń używŏczōw", - "rightslogtext": "Rejer půmjyńań uprawńyń užytkowńikůw.", + "rightslogtext": "To je regest zmian uprawniyń używŏczōw.", "action-read": "přeglůndańo tyj zajty", "action-edit": "edycyje tyj strōny", "action-createpage": "tworzyńo zajtůw", @@ -1142,12 +1143,13 @@ "filedelete-reason-otherlist": "Inkszy powůd", "filedelete-reason-dropdown": "* Nojczynstsze powody wyćepańa\n** Naruszyńy praw autorskych\n** Kopja plika kery już sam jest", "filedelete-edit-reasonlist": "Sprowjańe powodůw wyćepańo zajty", - "mimesearch": "Sznupej MIME", + "mimesearch": "Szukanie podle typu MIME", "mimesearch-summary": "Ta zajta ůmožliwjo šnupańe za plikůma wedle jeich typu MIME. Užyće: typtreśći/podtyp, np. image/jpeg.", "mimetype": "Typ MIME:", "download": "pobier", "unwatchedpages": "Zajty na kere ńy je dowany pozůr", "listredirects": "Lista przekerowań", + "listduplicatedfiles": "Lista zbiorōw ze tuplikatami", "unusedtemplates": "Niyużywane mustry", "unusedtemplatestext": "Půńižej znojdowo śe lista wšyjstkich zajtůw s přestřyńi mjan {{ns:template}}, kere ńy sům užywane bez inkše zajty. Sprowdź inkše adresowańa ku šablůnům, ńim wyćepńeš ta zajta.", "unusedtemplateswlh": "ku adresatu", @@ -1162,7 +1164,7 @@ "statistics-articles": "Zajty", "statistics-pages": "Zajty", "statistics-pages-desc": "Wszyjstke zajty na wiki, wroz ze zajtami godki, przekerowańami a t.p.", - "statistics-files": "Wćepane pliki", + "statistics-files": "Zaladowane zbiory", "statistics-edits": "Sprowjyńa wykůnane uod powstańo {{grammar:D.lp|{{SITENAME}}}}", "statistics-edits-average": "Strzedńo liczba sprowjyń na zajta", "statistics-users": "Zarejerowanych użytkowńikůw", @@ -1201,12 +1203,13 @@ "wantedpages": "Potrzebne strōny", "wantedfiles": "Potrzebne zbiory", "wantedtemplates": "Potrzebne mustry", - "mostlinked": "Nojczyńśćij adresowane", - "mostlinkedcategories": "Kategoryje we kerych je nojwjyncyj artikli", + "mostlinked": "Nojczyńścij linkowane", + "mostlinkedcategories": "Nojwiyncyj używane kategoryje", "mostlinkedtemplates": "Nojczyńśćij adresowane mustry", - "mostcategories": "Zajty kere majům nojwiyncyj kategoryjůw", - "mostimages": "Nojczyńśćij adresowane pliki", - "mostrevisions": "Nojczyńśćij sprowjane artikle", + "mostcategories": "Strōny, co majōm nojwiyncyj kategoryji", + "mostimages": "Nojczyńścij używane zbiory", + "mostinterwikis": "Strōny, co majōm nojwiyncyj linkōw interwiki", + "mostrevisions": "Nojwiyncyj edytowane strōny", "prefixindex": "Wszyjske strōny ze prefiksym", "shortpages": "Nojkrōtsze strōny", "longpages": "Duge strōny", @@ -1217,7 +1220,7 @@ "protectedpages-cascade": "Yno zajty zabezpjeczůne rekursywńy", "protectedpagesempty": "Żodno zajta ńy je terozki zawarto ze podanymi parametrami.", "protectedtitles": "Zastawiōne tytuły", - "protectedtitlesempty": "Do tych štalowań utwořyńy artikla uo dowolnym mjańy ńy je zawarte", + "protectedtitlesempty": "Żŏdne strōny niy sōm terŏz zawarte ze tymi parametrami.", "listusers": "Lista używŏczōw", "listusers-editsonly": "Pokoż yno użytkowńikůw kere majům sprowjyńa", "usereditcount": "$1 {{PLURAL:$1|sprowjyńe|sprowjyńa|sprowjyń}}", @@ -1244,7 +1247,7 @@ "specialloguserlabel": "Fto:", "speciallogtitlelabel": "Cyl (nazwa abo {{ns:user}}:miano ôd używŏcza):", "log": "Regest ôperacyji", - "all-logs-page": "Wszyjske óperacyje", + "all-logs-page": "Wszyjske ôperacyje", "alllogstext": "Spōlne pokŏzanie wszyjskich dostympnych regestōw {{SITENAME}}.\nMożesz uakuratnić widok bez ôbranie zorty regestu, miana ôd używŏcza, abo tykanyj strōny (dŏwŏ pozōr na małe i sroge litery).", "logempty": "Niy ma we regeście zgodliwych elymyntōw.", "log-title-wildcard": "Szukej tytułōw, co sie zaczynajōm ôd tego tekstu", @@ -1263,10 +1266,10 @@ "categories": "Kategoryje", "categoriespagetext": "Zajta przedstowjo lista katygoryji s zajtůma a plikůma.\n[[Special:UnusedCategories|Ńyużywane kategoryj]] ńy zostoły tukej pokozane.\nKukńij tyż [[Special:WantedCategories|ńyistńyjůnce kategoryje]].", "categoriesfrom": "Pokož kategoryje začynajůnc uod:", - "deletedcontributions": "Wyćepane sprowjyńa użytkowńika", - "deletedcontributions-title": "Wyćepane sprowjyńa użytkowńika", + "deletedcontributions": "Skasowany wkłŏd ôd używŏcza", + "deletedcontributions-title": "Skasowany wkłŏd ôd używŏcza", "sp-deletedcontributions-contribs": "wkłŏd", - "linksearch": "Necowe uodwołańa", + "linksearch": "Szukanie zewnyntrznych linkōw", "linksearch-pat": "Wzorzec sznupańo", "linksearch-ns": "Przestrzyń mjan", "linksearch-ok": "Šnupej", @@ -1313,8 +1316,8 @@ "emailsend": "Wyślij", "emailccme": "Wyślij mi kopja moiy wjadomości.", "emailccsubject": "Kopja Twojej wjadůmośći do $1: $2", - "emailsent": "Wjadůmość zostoua wysuano", - "emailsenttext": "Twoja wjadůmość zostoua wysuano.", + "emailsent": "E-mail wysłany", + "emailsenttext": "Twoja wiadōmość e-mail je wysłanŏ.", "emailuserfooter": "Wjadůmość e-brif zostoła wysłano s {{GRAMMAR:D.lp|{{SITENAME}}}} ku $2 bez $1 s użyćym „Wyślij e-brif ku tym użytkowńikowi”.", "usermessage-editor": "Nadŏwca systymowych kōmunikatōw", "watchlist": "Ôbserwowane", @@ -1330,7 +1333,7 @@ "unwatch": "Niy ôbserwuj", "unwatchthispage": "Přestoń dować pozůr", "notanarticle": "To ńy je artikel", - "notvisiblerev": "Wersyja zostoua wyćepano", + "notvisiblerev": "Ôstatniŏ wersyjŏ ôd inkszego używŏcza była skasowanŏ", "watchlist-details": "Na Twojij liście ôbserwowanych {{PLURAL:$1|je $1 strōna|sōm $1 strōny|je $1 strōn}} (plus strōny dyskusyje).", "wlheader-enotif": "Wysůuańy powjadůmjyń na adres e-brif je zouůnčůne", "wlheader-showupdated": "Zajty, co były zmiyniane ôd twojij ôstatnij nŏwiydzki na nich ôstały ukŏzane na rubo.", @@ -1357,10 +1360,10 @@ "confirmdeletetext": "Zarŏz wyciepniesz artikel i cołkõ ôd niygo historyjõ. Przitupluj, iże na isto chcesz to zrobić, miarkujesz kōnsekwyncyje, i co robisz to podle [[{{MediaWiki:Policy-url}}|prawideł]].", "actioncomplete": "Fertig", "actionfailed": "Ńy udało śe.", - "deletedtext": "Wyćepano \"$1\". Rejer uostatnio zrobiůnych wyćepań možeš uobejžyć tukej: $2.", + "deletedtext": "Strōna „$1” była skasowanŏ.\nWejzdrzij na $2 po regest ôstatnich skasowań.", "dellogpage": "Regest kasowań", "dellogpagetext": "To je lista uostatńo wykůnanych wyćepań.", - "deletionlog": "rejer wyćepań", + "deletionlog": "regest skasowań", "reverted": "Prziwrōcōnŏ poprzedniõ wersyjõ", "deletecomment": "Čymu:", "deleteotherreason": "Inkšy powůd:", @@ -1373,7 +1376,7 @@ "rollbacklink": "cŏfej", "rollbacklinkcount": "cŏfnij $1 {{PLURAL:$1|edycyjõ|edycyje|edycyji}}", "rollbackfailed": "Niy szło wycŏfać zmiany", - "cantrollback": "Ńy idże cofnůńć pomjyńyńo, sam je ino jedna wersyja tyi zajty.", + "cantrollback": "Niy idzie cŏfnōńć edycyje;\nôstatni edytōr to je jedyny autōr tyj strōny.", "alreadyrolled": "Ńy idźe lů zajty [[:$1|$1]] cofnůńć uostatńygo pomjyńeńa, kere wykonoł [[User:$2|$2]] ([[User talk:$2|godka]]{{int:pipe-separator}}[[Special:Contributions/$2|{{int:contribslink}}]]).\nKto inkszy zdůnżůł już to zrobić abo wprowadźił własne poprowki do treśći zajty.\n\nAutorym ostatńygo pomjyńyńo je terozki [[User:$3|$3]] ([[User talk:$3|godka]]{{int:pipe-separator}}[[Special:Contributions/$3|{{int:contribslink}}]]).", "editcomment": "Sprowjyńe uopisano: $1.", "revertpage": "Wycofano sprowjyńe użytkowńika [[Special:Contributions/$2|$2]] ([[User talk:$2|godka]]). Autor prziwrůcůnej wersyji to [[User:$1|$1]].", @@ -1385,14 +1388,14 @@ "modifiedarticleprotection": "zmiyniōł(yła) poziōm zawarciŏ „[[$1]]”", "unprotectedarticle": "uodymknyu [[$1]]", "movedarticleprotection": "przekludzůno sztalowańa zabezpjeczyńo s „[[$2]]” ku „[[$1]]”", - "protect-title": "Pomjyńeńe poźomu zawarćo „$1”", + "protect-title": "Zmiana poziōmu zawarciŏ „$1”", "prot_1movedto2": "[[$1]] přećepano do [[$2]]", "protect-legend": "Potwjyrdź zawarće", "protectcomment": "Čymu:", - "protectexpiry": "Wygaso:", + "protectexpiry": "Wygasŏ:", "protect_expiry_invalid": "Čas wygaśńjyńćo je zuy.", "protect_expiry_old": "Čas wygaśńjyńćo je w downiej ńiž terozki.", - "protect-text": "Sam tukej možyš uobejžeć i pomjyńyć poźům zawarcia zajty '''$1'''.", + "protect-text": "Sam możesz ôbejzdrzeć i zmiynić poziōmy zawarciŏ strōny $1.", "protect-locked-blocked": "Ńy možeš půmjyńać poźůmůw zawarćo kej žeś sům je zawarty uod sprowjyń. Terozki štalowańa dla zajty '''$1''' to:", "protect-locked-dblock": "Ńy idźe půmjyńić poźůmu zawarća s kuli tygo co baza danych tyž je zawarto. Uobecne štalowańa dla zajty '''$1''' to:", "protect-locked-access": "Ńy moš uprowńyń coby pomjyńyć poziům zawarcia zajty. Uobecne ustawjyńo dlo zajty '''$1''' to:", @@ -1404,7 +1407,7 @@ "protect-summary-cascade": "dźedźičyńy", "protect-expiring": "wygaso $1 (UTC)", "protect-expiry-indefinite": "na zowdy", - "protect-cascade": "Dźedźyčyńe zawarćo - zawřij wšyskie zajty kere sům na tyi zajće.", + "protect-cascade": "Zawrzij strōny, co sōm wrażōne do tyj strōny (erbowanie zawarciŏ)", "protect-cantedit": "Ńy možeš pomjyńyć poziůmu zawarća tyi zajty, po takiymu, co uona je dlo Ćebje zawarto uod pomjyńańa.", "protect-othertime": "Inkszy uokres:", "protect-othertime-op": "inkszy uokres", @@ -1412,10 +1415,10 @@ "protect-otherreason": "Inkszy/dodatkowy powůd:", "protect-otherreason-op": "inkszy/dodatkowy powůd", "protect-dropdown": "*Nojczynstsze powody zawarćo uod sprowjyń\n** Czynste wandalizmy\n** Czynste spamowańy\n** Wojna edycyjno\n** Wygupy", - "protect-edit-reasonlist": "Sprowjej powody zawarćo uod sprowjyń", + "protect-edit-reasonlist": "Edytuj powody zawarciŏ", "protect-expiry-options": "2 godźiny:2 hours,1 dźyń:1 day,3 dńi:3 days,1 tydźyń:1 week,2 tygodńy:2 weeks,1 mjeśůnc:1 month,3 mjeśůnce:3 months,6 mjeśency:6 months,1 rok:1 year,ńyskůńčůny:infińite", "restriction-type": "Pozwolyńy:", - "restriction-level": "Poźům:", + "restriction-level": "Poziōm:", "minimum-size": "Minimalnŏ srogość", "maximum-size": "Maksymalnŏ srogość:", "pagesize": "(bajtōw)", @@ -1446,8 +1449,8 @@ "undeleteinvert": "Zaznocz na uopy", "undeletecomment": "Powůd wćepańo nazod:", "cannotundelete": "Wćepańy nazod ńy powjodo śe.\nKto inkšy můgu wćepać nazod zajta pjyrwšy.", - "undeletedpage": "'''Wćepano nazod zajta $1.'''\n\nUobejřij [[Special:Log/delete|rejer wyćepań]], kejbyś chćou přeglůndnůnć uostatnie uoperacyje wyćepywańo i wćepywańo nazod zajtůw.", - "undelete-header": "Uobejřij [[Special:Log/delete|rejer wyćepań]] coby sprawdźić uostatńo wyćepane zajty.", + "undeletedpage": "Strōna „$1” była prziwrōcōnŏ\n\nWejzdrzij do [[Special:Log/delete|regestu skasowań]] po lista ôstatnich skasowań i prziwrōcyń.", + "undelete-header": "Wejzdrzij na [[Special:Log/delete|regest skasowań]] po ôstatnio skasowane strōny.", "undelete-search-box": "Šnupej za wyćepńjyntymi zajtami", "undelete-search-prefix": "Strōny, co sie zaczynajōm ôd:", "undelete-search-submit": "Šnupej", @@ -1561,7 +1564,7 @@ "block-log-flags-noemail": "e-mail zablokowany", "block-log-flags-nousertalk": "ńy może sprowjać włosnyj zajty godki", "block-log-flags-angry-autoblock": "rozszerzůne automatyczne zawjyrańe załůnczůne", - "range_block_disabled": "Možliwość zawjerańo zakresu adresůw IP zostoua wůuůnčůno.", + "range_block_disabled": "Blokowanie zŏkresu adres IP je zakŏzane.", "ipb_expiry_invalid": "Felerny čas wygaśńjyńćo zawarća.", "ipb_expiry_temp": "Schrůńůne mjano użytkowńika noleży zawrzić trwale.", "ipb_already_blocked": "\"$1\" je już zawarty uod sprowjyń", @@ -1582,10 +1585,10 @@ "lockbtn": "Zawřij baza danych", "unlockbtn": "Uodymkńij baza danych", "locknoconfirm": "Ńy zaznačůužeś potwjerdzyńo.", - "lockdbsuccesssub": "Baza danych zostoua půmyślńy zawarto", - "unlockdbsuccesssub": "Baza danych zostoua půmyślńy uodymkńynto", - "lockdbsuccesstext": "Baza danych zostoua zawarto.
\nPamjyntej coby [[Special:UnlockDB|jům uodymknůńć]] po zakůńčyńu dźouań admińistracyjnych.", - "unlockdbsuccesstext": "Baza danych zostoua uodymkńynto.", + "lockdbsuccesssub": "Zablokowanie bazy danych sie podarziło", + "unlockdbsuccesssub": "Blokada bazy danych symniyntŏ", + "lockdbsuccesstext": "Baza danych je zablokowanŏ.
\nPamiyntej, żeby [[Special:UnlockDB|jōm ôtworzić]] jak robota bydzie skōńczōnŏ.", + "unlockdbsuccesstext": "Baza danych je ôdblokowanŏ.", "lockfilenotwritable": "Ńy idźe naškreflać plika zawarća bazy danych.\nZawjerańy i uodmykańy bazy danych wymogo coby plik můgu być naškreflany bez web serwer.", "databasenotlocked": "Baza danych ńy je zawarto.", "move-page": "Przećep $1", @@ -1639,7 +1642,7 @@ "export-templates": "Douůnč šablůny", "allmessages": "Komunikaty", "allmessagesname": "Mjano", - "allmessagesdefault": "Tekst důmyślny", + "allmessagesdefault": "Wychodny tekst wiadōmości", "allmessagescurrent": "Tekst uobecny", "allmessagestext": "Uoto lista wšyjstkych kůmůńikatůw systymowych dostympnych w přestřyńi mjan MedjaWiki.\nUodwjydź [https://www.mediawiki.org/wiki/Special:MyLanguage/Localisation Tuůmačyńy MediaWiki] a tyž [https://translatewiki.net translatewiki.net] kejbyś chćou učestńičyć w tuůmačyńu uoprůgramowańo MediaWiki.", "allmessages-not-supported-database": "Ta zajta ńy može być užyta, bez tůž co zmjynna '''$wgUseDatabaseMessages''' je wůuůnčůno.", @@ -1679,7 +1682,7 @@ "import-token-mismatch": "Straćiły śe dane ze sesyje. Prosza spróbować zaś.", "import-invalid-interwiki": "Ńy idźe importować s podanyj wiki.", "importlogpage": "Regest importōw", - "importlogpagetext": "Rejer přeprowadzůnych importůw zajtůw s inkšych serwisůw wiki.", + "importlogpagetext": "Regest importōw strōn społym ze jejich historyjami ze inkszych wiki.", "import-logentry-upload-detail": "$1 {{PLURAL:$1|wersyja|wersyje|wersyji}}", "import-logentry-interwiki-detail": "$1 {{PLURAL:$1|wersyja|wersyje|wersyji}} ze $2", "tooltip-pt-userpage": "{{GENDER:|Moja}} strōna", @@ -1826,7 +1829,7 @@ "show-big-image-preview": "Srogość tego podglōndu: $1.", "show-big-image-other": "{{PLURAL:$2|Inkszŏ rozdzielczość|Inksze rozdzielczości}}: $1.", "show-big-image-size": "$1 x $2 pikselōw", - "newimages": "Galerjo nowych uobrozkůw", + "newimages": "Galeryjŏ nowych ôbrŏzkōw", "imagelisttext": "Půnižyj na {{PLURAL:$1||posortowanyj $2}} liśće {{PLURAL:$1|znojdowo|znojdujům|znojdowo}} śe '''$1''' {{PLURAL:$1|plik|pliki|plikůw}}.", "newimages-summary": "Na tyj ekstra zajće prezyntowane sům uostatńo wćepńynte pliki.", "newimages-legend": "Filtruj", @@ -1848,7 +1851,7 @@ "confirmemail_text": "Projekt {{SITENAME}} wymago weryfikacyji adresa e-brif před užyćym fůnkcyji kořistajůncych s počty.\nWćiś knefel půńižy coby wysúać na swůj adres list s linkym do zajty WWW.\nList bydźe zawjeroú link do zajty, w kerym zakodowany bydźe idyntyfikator.\nUodymkńij tyn link we přyglůndarce, čym potwjerdźiš, co ježeś užytkowńikym tygo adresa e-brif.", "confirmemail_pending": "Kod potwierdzyniŏ bōł prawie do Ciebie wysłany. Jak Twoje kōnto było niydŏwno zaregistrowane, to poczekej pŏrã minut na jego dotarcie, podwiela wyślesz prośbã ô nowy.", "confirmemail_send": "Wyślij kod potwjerdzyńo", - "confirmemail_sent": "Wjadůmość e-brif s kodym uwjeřitelńajůncym zostoua wysuano.", + "confirmemail_sent": "E-mail ze potwiyrdzyniym wysłany.", "confirmemail_oncreate": "Link s kodym potwjerdzyńo zostou wysuany na Twůj adres e-brif.\nKod tyn ńy je wymagany coby śe sam lůgować, ale bydźeš muśou go aktywować uodmykajůnc uotřimany link we přyglůndarce ńim zouůnčyš ńykere uopcyje e-brif na wiki.", "confirmemail_sendfailed": "{{SITENAME}} ńy poradźiła wysłać potwjerdzajůncyj wjadůmośći e-brif.\nSprowdź aże we adreśe ńy ma felernyj buchsztaby.\n\nSystym pocztowy zwrůćił kůmůńikat: $1", "confirmemail_invalid": "Felerny kod potwjerdzyńo.\nKod može być předawńůny", @@ -1889,13 +1892,13 @@ "watchlistedit-normal-legend": "Wyćep zajty s listy artikli na kere dowoš pozůr", "watchlistedit-normal-explain": "Půńiżyj mosz lista artikli na kere dowosz pozůr.\nCoby wyćepać z ńij jako zajta, zaznocz pole przi ńij i naćiś knefel „{{int:Watchlistedit-normal-submit}}”.\nMożesz tyż skorzistać ze [[Special:EditWatchlist/raw|tekstowygo sprowjorza listy artikli na kere dowosz pozůr]].", "watchlistedit-normal-submit": "Wyćep s listy", - "watchlistedit-normal-done": "Z Twoi listy artikli na kere dowoš pozůr {{PLURAL:$1|zostoua wyćepano 1 zajta|zostouy wyćepane $1 zajty|zostouo wyćepanych $1 zajtůw}}:", + "watchlistedit-normal-done": "{{PLURAL:$1|Była skasowanŏ jedna strōna|Były skasowane $1 strōny|Było skasowanych $1 strōn}} ze twojij listy ôbserwowanych:", "watchlistedit-raw-title": "Tekstowy edytor listy artikli na kere dowosz pozůr", "watchlistedit-raw-legend": "Tekstowy edytor listy artikli na kere dowoš pozůr", "watchlistedit-raw-explain": "Půńižy moš lista artikli na kere dowoš pozůr. W koždej lińii znojdowo śe titel jydnygo artikla. Lista možeš sprowjać dodajůnc nowe zajty i wyćepujůnc te kere na ńij sům. Jak skůńčyš, naćiś knefel „Uaktualńij lista zajtůw na kere dowům pozůr”.\nMožeš tyž [[Special:EditWatchlist|užyć standardowygo edytora]].", "watchlistedit-raw-titles": "Title:", "watchlistedit-raw-submit": "Uaktualńij lista", - "watchlistedit-raw-done": "Lista zajtůw na kere dowoš pozůr zostoua uaktualńůna", + "watchlistedit-raw-done": "Lista twojich ôbserwowanych była zaktualizowanŏ.", "watchlistedit-raw-added": "Dodano {{PLURAL:$1|1 pozycyja|$1 pozycyje|$1 pozycyji}} do listy artikli na kere dowoš pozůr:", "watchlistedit-raw-removed": "Wyćepano {{PLURAL:$1|1 pozycyja|$1 pozycyje|$1 pozycyji}} z listy zajtůw na kere dowoš pozůr:", "watchlisttools-clear": "Wysnŏż ôbserwowane", @@ -1930,7 +1933,7 @@ "redirect-page": "Idyntyfikatōr strōny", "redirect-revision": "Wersyjŏ strōny", "redirect-file": "Miano zbioru", - "fileduplicatesearch": "Šnupej za duplikatym plika", + "fileduplicatesearch": "Szukej tuplikatōw zbioru", "fileduplicatesearch-summary": "Šnupej za duplikatůma plika na podstawje wartośći fůnkcyji skrůtu.", "fileduplicatesearch-filename": "Mjano pliku:", "fileduplicatesearch-submit": "Šnupej", @@ -1940,16 +1943,16 @@ "specialpages": "Ekstra strōny", "specialpages-note-restricted": "* Ekstra zajty uogůlńy dostympne.\n* Ekstra zajty do kerych dostymp je uograńiczůny.", "specialpages-group-maintenance": "Reporty kōnserwacyjne", - "specialpages-group-other": "Inkše ekstra zajty", + "specialpages-group-other": "Inksze ekstra strōny", "specialpages-group-login": "Logowanie / registracyjŏ", - "specialpages-group-changes": "Pomjyńane na uostatku a rejery", - "specialpages-group-media": "Pliki", + "specialpages-group-changes": "Ôstatnie zmiany i regesty", + "specialpages-group-media": "Zbiory", "specialpages-group-users": "Używŏcze i uprawniynia", - "specialpages-group-highuse": "Zajty čynsto užywane", + "specialpages-group-highuse": "Czynsto używane strōny", "specialpages-group-pages": "Listy strōn", - "specialpages-group-pagetools": "Nořyńdźa zajtůw", - "specialpages-group-wiki": "Informacyje a werkcojgi wiki", - "specialpages-group-redirects": "Ekstra zajty, kere kerujům", + "specialpages-group-pagetools": "Norzyńdzia strōn", + "specialpages-group-wiki": "Norzyńdzia i dane", + "specialpages-group-redirects": "Ekstra zajty przekerowaniŏ", "specialpages-group-spam": "Nořyńdźa do wyćepywanio spamu", "blankpage": "Pusto zajta", "intentionallyblankpage": "Ta zajta nauůmyślńy uostoua śe pusto", @@ -1978,7 +1981,9 @@ "searchsuggest-search": "Szukej we {{SITENAME}}", "duration-days": "$1 {{PLURAL:$1|dziyń|dni}}", "expand_templates_ok": "OK", + "mediastatistics": "Statystyki mediōw", "randomrootpage": "Losowŏ strōna (bez podstrōn)", "changecredentials": "Zmiyń poświadczynia", - "changecredentials-submit": "Zmiyń poświadczynia" + "changecredentials-submit": "Zmiyń poświadczynia", + "removecredentials": "Kasowanie poświadczyń" } diff --git a/languages/i18n/uk.json b/languages/i18n/uk.json index 519a35581f..cc2e66471e 100644 --- a/languages/i18n/uk.json +++ b/languages/i18n/uk.json @@ -97,7 +97,7 @@ "tog-watchdefault": "Додавати змінені мною сторінки та файли до мого списку спостереження", "tog-watchmoves": "Додавати перейменовані мною сторінки та файли до мого списку спостереження", "tog-watchdeletion": "Додавати вилучені мною сторінки та файли до мого списку спостереження", - "tog-watchuploads": "Додавати до мого списку спостереження нові файли, завантажені мною", + "tog-watchuploads": "Додавати файли, завантажені мною до списку спостереження", "tog-watchrollback": "Додавати відкочені мною сторінки до мого списку спостереження", "tog-minordefault": "Позначати всі зміни як незначні за замовчуванням", "tog-previewontop": "Показувати попередній перегляд перед вікном редагування, а не після", @@ -127,6 +127,7 @@ "tog-useeditwarning": "Попереджати мене, якщо я залишаю сторінку редагування з незбереженими змінами", "tog-prefershttps": "Завжди використовувати безпечне з'єднання при вході в систему", "tog-showrollbackconfirmation": "Показати підтверджувальне вікно при натисканні на посилання відкоту", + "tog-requireemail": "Вимагає вказання електронної пошти для скидання пароля", "underline-always": "Завжди", "underline-never": "Ніколи", "underline-default": "Використовувати налаштування браузера", @@ -205,7 +206,7 @@ "category-empty": "''Ця категорія зараз порожня.''", "hidden-categories": "{{PLURAL:$1|1=Прихована категорія|Приховані категорії}}", "hidden-category-category": "Приховані категорії", - "category-subcat-count": "{{PLURAL:$2|Показано $1 {{PLURAL:$1|підкатегорію з|підкатегорії з|підкатегорій із}} $2.|1=Ця категорія має тільки таку підкатегорію.}}", + "category-subcat-count": "{{PLURAL:$2|1=Ця категорія має тільки таку підкатегорію.|Показано $1 {{PLURAL:$1|підкатегорію з|підкатегорії з|підкатегорій із}} $2.}}", "category-subcat-count-limited": "У цій категорії {{PLURAL:$1|$1 підкатегорія|$1 підкатегорії|$1 підкатегорій}}.", "category-article-count": "Показано $1 {{PLURAL:$1|сторінку|сторінки|сторінок}} цієї категорії (із $2).", "category-article-count-limited": "У цій категорії {{PLURAL:$1|$1 сторінка|$1 сторінки|$1 сторінок}}.", @@ -667,7 +668,7 @@ "changeemail-nochange": "Будь ласка, введіть адресу електронної пошти, відмінну від попередньої.", "resettokens": "Скидання токенів", "resettokens-text": "Ви можете скинути токени, що забезпечують доступ до певних особистих даних, пов'язаних тут із вашим обліковим записом.\nВам слід це зробити, якщо ви випадково поділились токенами з кимось, або якщо ваш обліковий запис було зламано.", - "resettokens-no-tokens": "Немає жетонів до скидання.", + "resettokens-no-tokens": "Немає токенів до скидання.", "resettokens-tokens": "Токени:", "resettokens-token-label": "$1 (поточне значення: $2)", "resettokens-watchlist-token": "Маркер стрічки новин (Atom/RSS) щодо [[Special:Watchlist|зміни на сторінці з вашого списку спостереження]]", @@ -873,6 +874,7 @@ "undo-norev": "Редагування не може бути скасоване, бо його не існує або було вилучено.", "undo-nochange": "Схоже, редагування вже було скасовано.", "undo-summary": "Скасування редагування № $1 користувача [[Special:Contribs/$2|$2]] ([[User talk:$2|обговорення]])", + "undo-summary-anon": "Скасування версії $1 від [[Special:Contributions/$2|$2]]", "undo-summary-username-hidden": "Скасувати версію $1, виконану прихованим користувачем", "cantcreateaccount-text": "Створення облікових записів із цієї IP-адреси ('''$1''') було заблоковане [[User:$3|користувачем $3]].\n\n$3 зазначив таку причину: ''$2''", "cantcreateaccount-range-text": "Створення облікового запису із IP-адрес у діапазоні $1, який включає вашу IP-адресу ($4), було заблоковано користувачем [[User:$3|$3]].\n\nКористувач $3 вказав як причину $2", @@ -1172,6 +1174,7 @@ "prefs-help-email": "Адреса електронної пошти не є обов'язковою, але необхідна для скидання пароля, якщо Ви його забудете.", "prefs-help-email-others": "Також вона дозволить іншим користувачам зв'язатися з Вами через посилання на Вашій сторінці користувача чи на сторінці обговорення. При цьому Ваша електронна адреса залишиться нерозкритою.", "prefs-help-email-required": "Потрібно зазначити адресу електронної пошти.", + "prefs-help-requireemail": "Якщо вибране, то надішле електронного листа із скинутим паролем за умови, що в обліковому записі було вказано ім'я користувача та електронна пошта.", "prefs-info": "Основні відомості", "prefs-i18n": "Інтернаціоналізація", "prefs-signature": "Підпис", @@ -2395,6 +2398,7 @@ "alreadyrolled": "Неможливо відкинути останні редагування [[:$1]], зроблені [[User:$2|$2]] ([[User talk:$2|обговорення]]{{int:pipe-separator}}[[Special:Contributions/$2|{{int:contribslink}}]]), оскільки хтось інший уже змінив чи відкинув редагування цієї статті.\n\nОстанні редагування зроблено [[User:$3|$3]] ([[User talk:$3|обговорення]]{{int:pipe-separator}}[[Special:Contributions/$3|{{int:contribslink}}]]).", "editcomment": "Пояснення редагування було: «$1.».", "revertpage": "Відкинуто редагування [[Special:Contributions/$2|$2]] ([[User talk:$2|обговорення]]) до зробленого [[User:$1|$1]]", + "revertpage-anon": "Відкинуто правки [[Special:Contributions/$2|$2]] до останньої версії [[User:$1|$1]]", "revertpage-nouser": "Відкинуто редагування прихованого користувача до останньої версії, зробленої {{GENDER:$1|[[User:$1|$1]]}}", "rollback-success": "Відкинуті редагування {{GENDER:$3|користувача|користувачки}} $1; повернення до версії {{GENDER:$4|користувача|користувачки}} $2.", "sessionfailure-title": "Помилка сеансу", @@ -2631,6 +2635,7 @@ "ipblocklist-legend": "Пошук заблокованого користувача", "blocklist-userblocks": "Сховати блокування облікових записів", "blocklist-tempblocks": "Сховати тимчасові блокування", + "blocklist-indefblocks": "Сховати безстрокові блокування", "blocklist-addressblocks": "Приховати блокування окремих IP-адрес", "blocklist-type": "Тип:", "blocklist-type-opt-all": "Всі", diff --git a/languages/i18n/zgh.json b/languages/i18n/zgh.json index d0d4c8a8c5..edf53b2887 100644 --- a/languages/i18n/zgh.json +++ b/languages/i18n/zgh.json @@ -170,7 +170,7 @@ "history": "ⴰⵎⵣⵔⴰⵢ ⵏ ⵜⴰⵙⵏⴰ", "history_short": "ⴰⵎⵣⵔⵓⵢ", "history_small": "ⴰⵎⵣⵔⵓⵢ", - "updatedmarker": "ⵜⵡⴰⵙⵙⵏⴼⵍ ⵜⵉⴳⵉⵔⴰ ⵏ ⵓⵔⵣⴰⴼ ⵉⵏⵓ", + "updatedmarker": "ⵜⵡⴰⵙⵙⵏⴼⵍ ⵜⵉⴳⵉⵔⴰ ⵏ ⵓⵔⵣⴰⴼ ⵏⴽ:", "printableversion": "ⵜⵓⵏⵖⵉⵍⵜ ⵉⵜⵜⵡⴰⵙⵉⴳⴳⵣⵏ", "permalink": "ⴰⵙⵖⵏ ⴰⵎⵖⵍⴰⵍ", "print": "ⵙⵉⴳⴳⵣ", @@ -517,7 +517,7 @@ "accmailtitle": "ⵜⴰⴳⵓⵔⵉ ⵓⵣⵔⴰⵢ ⵜⴻⵜⵜⵡⴰⵣⵏ", "newarticle": "(ⴰⵎⴰⵢⵏⵓ)", "newarticletext": "ⵜⴹⴼⴰⵔⴷ ⵢⴰⵏ ⵓⵙⵖⵏ ⵖⵔ ⵢⴰⵜ ⵜⴰⵙⵏⴰ ⵏⵏⴰ ⵓⵔ ⵜⴰ ⵉⵍⵍⵉⵏ. \nⴰⴼⴰⴷ ⴰⴷ ⵜⵙⵏⵓⵍⴼⵓⴷ ⵜⴰⵙⵏⴰ, ⵙⵙⵏⵜⵉ ⵜⵉⵔⵔⴰ ⴳ ⵓⴼⵏⵉⵇ ⴳ ⵉⵣⴷⴷⴰⵔ (ⵥⵔ [$1 ⵜⴰⵙⵏⴰ ⵏ ⵜⵡⵉⵙⵉ] ⵉ ⵡⵓⴳⴳⴰⵔ ⵏ ⵉⵏⵖⵎⵉⵙⵏ). \nⵎⴽ ⵜⵍⵍⵉⴷ ⴷⴰ ⵙ ⵓⵣⴳⴰⵍ, ⴰⴽⵍ ⵖⴼ ⴰⵖⵓⵍ ⴳ ⵓⵙⴰⵔⴰ ⵏⵏⴽ.", - "anontalkpagetext": "----\nⵜⵍⵍⵉⴷ ⴳ ⵜⴰⵙⵏ ⵏ ⵓⵎⵙⴰⵡⴰⵍ ⵏ ⵢⴰⵏ ⵓⵏⵙⵙⵎⵔⵙ ⵡⴰⵔⵉⵙⵎ ⵏⵏⴰ ⵜⴰ ⵓⵔ ⵉⵙⴽⵉⵔⵏ ⴰⵎⵉⴹⴰⵏ ⵏⵖ ⵏⵏⴰ ⵜ ⵓⵔ ⵉⵙⵙⵎⵔⵉⵙⵏ.\nⴰⵢⴰ ⴰ ⵖⴼ ⵉⴼⵓⴽⴽ ⴰⴷ ⵏⵙⵙⵎⵔⵙ ⵜⴰⵏⵙⴰ ⵏⵏⵙ IP ⴼⴰⴷ ⴰⴷ ⵜ ⵏⵙⵎⴰⴳⵉ.\nⵢⴰⵜ ⵜⴰⵏⵙⴰ IP ⵥⴹⴰⵔⵏ ⴰⴷ ⵜⵜ ⵙⵙⵓⵔⵏ ⵎⵏⵏⴰⵡ ⵏ ⵉⵏⵙⵙⵎⵔⵙⵏ.\nⵎⴽ ⵜⴳⵉⴷ ⵢⴰⵏ ⵓⵏⵙⵙⵎⵔⵙ ⵡⴰⵔⵉⵙⵎ ⴷ ⴽ ⵜⵖⴹⴼⴷ ⵎⴰⵙ ⴽ ⵡⴰⵜⵙⵏ ⴽⵔⴰ ⵏ ⵉⵅⴼⴰⵡⴰⵍⵏ ⵓⵔ ⵙⵉⴽ ⵉⵥⵍⵉⵏ, ⵜⵓⴼⵉⴷ ⴰⴷ [[Special:CreateAccount|ⵙⴽⵔ ⵢⴰⵏ ⵓⵎⵉⴹⴰⵏ]] ⵏⵖ ⴷ [[Special:UserLogin|ⴽⵛⵎ]] ⴱⴰⵔ ⴰⴷ ⵜⴰⵏⴼⴷ ⵉ ⴽⵔⴰⵢⴳⴰⵜ ⴰⵎⵔⴽⵙ ⴷ ⵉⵎⴷⵔⴰⵡⵏ ⵢⴰⴹⵏ.", + "anontalkpagetext": "----\nⵜⵍⵍⵉⴷ ⴳ ⵜⴰⵙⵏ ⵏ ⵓⵎⵙⴰⵡⴰⵍ ⵏ ⵢⴰⵏ ⵓⵏⵙⵙⵎⵔⵙ ⵡⴰⵔⵉⵙⵎ ⵏⵏⴰ ⵜⴰ ⵓⵔ ⵉⵙⴽⵉⵔⵏ ⴰⵎⵉⴹⴰⵏ ⵏⵖ ⵏⵏⴰ ⵜ ⵓⵔ ⵉⵙⵙⵎⵔⵉⵙⵏ.\nⴰⵢⴰ ⴰ ⵖⴼ ⵉⴼⵓⴽⴽ ⴰⴷ ⵏⵙⵙⵎⵔⵙ ⵜⴰⵏⵙⴰ ⵏⵏⵙ IP ⴼⴰⴷ ⴰⴷ ⵜⵏ ⵏⵙⵎⴰⴳⵉ.\nⵢⴰⵜ ⵜⴰⵏⵙⴰ IP ⵥⴹⴰⵔⵏ ⴰⴷ ⵜⵜ ⵙⵙⵓⵔⵏ ⵎⵏⵏⴰⵡ ⵏ ⵉⵏⵙⵙⵎⵔⵙⵏ.\nⵎⴽ ⵜⴳⵉⴷ ⵢⴰⵏ ⵓⵏⵙⵙⵎⵔⵙ ⵡⴰⵔⵉⵙⵎ ⴷ ⴽ ⵜⵖⴹⴼⴷ ⵎⴰⵙ ⴽ ⵡⴰⵜⵙⵏ ⴽⵔⴰ ⵏ ⵉⵅⴼⴰⵡⴰⵍⵏ ⵓⵔ ⵙⵉⴽ ⵉⵥⵍⵉⵏ, ⵜⵓⴼⵉⴷ ⴰⴷ [[Special:CreateAccount|ⵙⴽⵔ ⵢⴰⵏ ⵓⵎⵉⴹⴰⵏ]] ⵏⵖ ⴷ [[Special:UserLogin|ⴽⵛⵎ]] ⴱⴰⵔ ⴰⴷ ⵜⴰⵏⴼⴷ ⵉ ⴽⵔⴰⵢⴳⴰⵜ ⴰⵎⵔⴽⵙ ⴷ ⵉⵎⴷⵔⴰⵡⵏ ⵢⴰⴹⵏ.", "noarticletext": "ⵓⵔ ⵉⵍⵍⵉ ⴽⵔⴰ ⵏ ⵓⴹⵔⵉⵙ ⴳ ⵜⴰⵙⵏⴰ ⴰⴷ ⵖⵉⵍⴰ. \nⵜⵣⵎⵔⴷ ⴰⴷ [[Special:Search/{{PAGENAME}}|ⵜⵔⵣⵓⴷ ⵖⴼ ⵓⵣⵡⵍ ⵏⵏⵙ]] ⴳ ⵜⴰⵙⵏⵉⵡⵉⵏ ⵢⴰⴹⵏ, [{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} ⵔⵣⵓ ⵖⴼ logs ⵖⵔⵙ ⵉⵇⵇⵏⴻⵏ],\nⵏⵖ [{{fullurl:{{FULLPAGENAME}}|action=edit}} ⵙⵏⵓⵍⴼⵓ ⵜⴰⵙⵏⴰ].", "noarticletext-nopermission": "ⴷⵖⵉ ⵓⵔ ⵉⵍⵍⵉ ⴰⵡⴷ ⴽⵔⴰ ⵏ ⵓⴹⵔⵉⵚ ⴳ ⵜⴰⵙⵏⴰ ⴰ.\nⵜⵣⵎⵔⴷ ⴰⴷ [[Special:Search/{{PAGENAME}}|ⵜⵔⵣⵓⴷ ⵖⴼ ⵓⵣⵡⵍ ⵏⵏⵙ]] ⴳ ⵜⴰⵙⵏⵉⵡⵉⵏ ⵢⴰⴹⵏⵉⵏ, ⵏⵖ [{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} ⵔⵣⵓ ⵖⴼ ⵉⵣⵎⵎⴻⵎⵏ ⵉⵣⴷⵉⵏ], ⵎⴰⵛⴰ ⵓⵔ ⴷⴰⵔⴽ ⵜⵓⵔⴰⴳⵜ ⴰⴷ ⵜⵙⵏⵓⵍⴼⵓⴷ ⵜⴰⵙⵏⴰ ⴰ.", "userpage-userdoesnotexist-view": "ⴰⵎⵉⴹⴰⵏ ⵏ ⵓⵎⵙⵙⵎⵔⵙ $1 ⵓⵔ ⵉⵜⵜⵓⵣⵎⵎⴻⵎ.", @@ -551,7 +551,7 @@ "last": "ⵓⵣⵡⵔ", "page_last": "ⴰⵎⴳⴳⴰⵔⵓ", "histlegend": "ⴰⵙⵜⴰⵢ ⵏ ⵓⵎⵣⴰⵔⴰⵢ : ⵔⵛⵎ ⵜⴰⵏⴽⵓⵍⵉⵏ ⵏ ⵜⵓⵏⵖⵉⵍⵉⵏ ⵏⵏⴰ ⵜⵔⵉⴷ ⴰⴷ ⵜⵙⵎⵣⴰⵣⴰⵍⴷ ⵜⴰⴷⵔⴷ ⵉ ⴰⴽⵎ ⵏⵖ ⵉ ⵜⵙⴰⵔⵓⵜ ⵏ ⵢⵉⵣⴷⴰⵔ.
\nⵜⴰⴱⴰⴷⵓⵜ : ({{int:cur}}) = ⴰⵎⵣⴰⵔⴰⵢ ⴰⴽⴷ ⵜⵓⵏⵖⵉⵍⵜ ⵜⴰⵎⴳⴳⴰⵔⵓⵜ, ({{int:last}}) = ⴰⵎⵣⴰⵔⴰⵢ ⴰⴽⴷ ⵜⵓⵏⵖⵉⵍⵜ ⵉⵣⵔⵉⵏ, {{int:minoreditletter}} = ⵉⵙⵏⵉⴼⵉⵍⵏ ⵉⵎⵥⵥⵉⵢⵏ.", - "history-fieldset-title": "ⵔⵣⵓ ⵖⴼ ⵉⵣⵣⵔⴰⵢⵏ", + "history-fieldset-title": "ⵙⵜⵉ ⵉⵣⵣⵔⴰⵢⵏ", "histfirst": "ⴰⵇⴱⵓⵔ", "histlast": "ⴰⵎⴰⵢⵏⵓ", "history-feed-title": "ⴰⵎⵣⵔⵓⵢ ⵏ ⵓⵣⵣⵔⴰⵢ", @@ -769,7 +769,7 @@ "rcfilters-savedqueries-already-saved": "ⵜⵉⵎⵣⵉⵣⴷⴳⵉⵜⵉⵏ ⴰⴷ ⵜⵜⵡⴰⵃⴹⴰⵏⵜ ⵢⴰⴷ. ⵙⵏⴼⵍ ⵜⵉⵙⵖⴰⵍ ⵏⴽ ⵃⵎⴰ ⴰⴷ ⵜⵙⵏⴼⵍⴷ ⵜⵉⵎⵣⵉⵣⴷⴳⵜ ⵜⴰⵎⴰⵢⵏⵓⵜ ⵉⵜⵜⵡⴰⵃⴹⴰⵏ.", "rcfilters-restore-default-filters": "ⵔⴰⵔ ⴷ ⵜⵉⵎⵣⵉⵣⴷⴳⵉⵜⵉⵏ ⵙ ⵓⵎⵕⴰⴹ", "rcfilters-clear-all-filters": "ⵚⵚⴼⴹ ⴰⴽⴽⵯ ⵜⵉⵎⵣⵉⵣⴷⴳⵉⵜⵉⵏ", - "rcfilters-show-new-changes": "ⵙⴽⵏ ⵉⵙⵏⴼⵍⵏ ⵉⵎⴰⵢⵏⵓⵜⵏ", + "rcfilters-show-new-changes": "ⵙⴽⵏ ⵉⵙⵏⴼⵍⵏ ⵉⵎⴰⵢⵏⵓⵜⵏ ⵣⴳ $1", "rcfilters-search-placeholder": "ⵣⵉⵣⴷⵉⴳ ⵉⵙⵏⴼⵍⵏ (ⵙⵎⵔⵙ ⵓⵎⵓⵖ ⵏⵖ ⵔⵣⵓ ⵖⴼ ⵉⵙⵎ ⵏ ⵜⵎⵣⵉⵣⴷⴳⵜ)", "rcfilters-invalid-filter": "ⵜⵉⵎⵣⵉⵣⴷⴳⵜ ⵓⵔ ⵉⵖⵥⴰⵏⵏ", "rcfilters-empty-filter": "ⵃⵜⵜⴰ ⴽⵔⴰ ⵏ ⵜⵉⵎⵣⵉⵣⴷⴳⵜ ⵉⵙⵡⵓⵔⵉⵏ. ⴰⴽⴽⵯ ⵉⵙⵏⵍⵏ ⵜⵜⵡⴰⵙⴽⵏⵏ.", diff --git a/languages/i18n/zh-hant.json b/languages/i18n/zh-hant.json index c2cd05bedd..4ccd526260 100644 --- a/languages/i18n/zh-hant.json +++ b/languages/i18n/zh-hant.json @@ -3560,7 +3560,7 @@ "logentry-import-upload": "$1 已由檔案上傳{{GENDER:$2|匯入}} $3", "logentry-import-upload-details": "$1 已使用檔案上傳{{GENDER:$2|匯入}} $3 ($4 {{PLURAL:$4|修訂|修訂}})", "logentry-import-interwiki": "$1 已由其他 wiki {{GENDER:$2|匯入}} $3", - "logentry-import-interwiki-details": "$1 已自 $5 {{GENDER:$2|匯入}} $3 ($4 {{PLURAL:$4|修訂|修訂}})", + "logentry-import-interwiki-details": "$1已自$5{{GENDER:$2|匯入}}$3($4{{PLURAL:$4|修訂|修訂}})", "logentry-merge-merge": "$1 將 $3 {{GENDER:$2|合併}}至 $4 (修訂版本至 $5)", "logentry-move-move": "$1 {{GENDER:$2|已移動}}頁面 $3 至 $4", "logentry-move-move-noredirect": "$1 {{GENDER:$2|已移動}}頁面 $3 至 $4,不留重新導向", diff --git a/maintenance/install.php b/maintenance/install.php index 28a1746d9e..16b8ccf837 100644 --- a/maintenance/install.php +++ b/maintenance/install.php @@ -133,6 +133,8 @@ class CommandLineInstaller extends Maintenance { if ( !$envChecksOnly ) { $status = $installer->execute(); if ( !$status->isGood() ) { + $installer->showStatusMessage( $status ); + return false; } $installer->writeConfigurationFile( $this->getOption( 'confpath', $IP ) ); diff --git a/maintenance/storage/blobs.sql b/maintenance/storage/blobs.sql index 979e68a94e..e3c6c02bc3 100644 --- a/maintenance/storage/blobs.sql +++ b/maintenance/storage/blobs.sql @@ -1,6 +1,6 @@ -- Blobs table for external storage -CREATE TABLE /*$wgDBprefix*/blobs ( +CREATE TABLE IF NOT EXISTS /*$wgDBprefix*/blobs ( blob_id integer UNSIGNED NOT NULL AUTO_INCREMENT, blob_text longblob, PRIMARY KEY (blob_id) diff --git a/maintenance/storage/checkStorage.php b/maintenance/storage/checkStorage.php index 060f32768d..37625cf2f0 100644 --- a/maintenance/storage/checkStorage.php +++ b/maintenance/storage/checkStorage.php @@ -232,7 +232,7 @@ class CheckStorage { } foreach ( $externalConcatBlobs as $cluster => $xBlobIds ) { $blobIds = array_keys( $xBlobIds ); - $extDb =& $this->dbStore->getSlave( $cluster ); + $extDb =& $this->dbStore->getReplica( $cluster ); $blobsTable = $this->dbStore->getTable( $extDb ); $res = $extDb->select( $blobsTable, [ 'blob_id' ], @@ -433,7 +433,7 @@ class CheckStorage { foreach ( $externalConcatBlobs as $cluster => $oldIds ) { $blobIds = array_keys( $oldIds ); - $extDb =& $this->dbStore->getSlave( $cluster ); + $extDb =& $this->dbStore->getReplica( $cluster ); $blobsTable = $this->dbStore->getTable( $extDb ); $headerLength = strlen( self::CONCAT_HEADER ); $res = $extDb->select( $blobsTable, diff --git a/maintenance/userOptions.php b/maintenance/userOptions.php index 98f1c24a86..2f8941f3da 100644 --- a/maintenance/userOptions.php +++ b/maintenance/userOptions.php @@ -110,11 +110,10 @@ The new option is NOT validated.' ); $ret[$option][$userValue] = ( $ret[$option][$userValue] ?? 0 ) + 1; } } else { - foreach ( $defaultOptions as $name => $defaultValue ) { $userValue = $user->getOption( $name ); if ( $userValue != $defaultValue ) { - $ret[$option][$userValue] = ( $ret[$option][$userValue] ?? 0 ) + 1; + $ret[$name][$userValue] = ( $ret[$name][$userValue] ?? 0 ) + 1; } } } diff --git a/resources/Resources.php b/resources/Resources.php index 1388128fc0..180ed65a43 100644 --- a/resources/Resources.php +++ b/resources/Resources.php @@ -175,11 +175,10 @@ return [ 'targets' => [ 'desktop', 'mobile' ], ], 'jquery.color' => [ - 'scripts' => 'resources/src/jquery/jquery.color.js', - 'dependencies' => 'jquery.colorUtil', - ], - 'jquery.colorUtil' => [ - 'scripts' => 'resources/src/jquery/jquery.colorUtil.js', + 'scripts' => [ + 'resources/src/jquery.color/jquery.colorUtil.js', + 'resources/src/jquery.color/jquery.color.js', + ], ], 'jquery.confirmable' => [ 'scripts' => [ @@ -895,6 +894,7 @@ return [ 'dependencies' => [ 'mediawiki.api', 'oojs', + 'mediawiki.Uri', ], 'targets' => [ 'desktop', 'mobile' ], ], @@ -940,6 +940,9 @@ return [ 'scripts' => [ 'resources/src/mediawiki.htmlform.checker.js', ], + 'dependencies' => [ + 'mediawiki.util', + ], 'targets' => [ 'desktop', 'mobile' ], ], 'mediawiki.htmlform.ooui' => [ @@ -1252,8 +1255,8 @@ return [ ] ], 'mediawiki.util' => [ - 'localBasePath' => "$IP/resources/src/mediawiki.util/", - 'remoteBasePath' => "$wgResourceBasePath/resources/src/mediawiki.util/", + 'localBasePath' => "$IP/resources/src/mediawiki.util", + 'remoteBasePath' => "$wgResourceBasePath/resources/src/mediawiki.util", 'packageFiles' => [ 'util.js', 'jquery.accessKeyLabel.js', @@ -2313,7 +2316,6 @@ return [ 'dependencies' => [ 'mediawiki.api', 'mediawiki.jqueryMsg', - 'jquery.throttle-debounce', 'mediawiki.htmlform.checker', ], ], diff --git a/resources/lib/foreign-resources.yaml b/resources/lib/foreign-resources.yaml index 9ab1b496ab..5db52a419d 100644 --- a/resources/lib/foreign-resources.yaml +++ b/resources/lib/foreign-resources.yaml @@ -253,8 +253,8 @@ oojs-router: ooui: type: tar - src: https://registry.npmjs.org/oojs-ui/-/oojs-ui-0.34.0.tgz - integrity: sha384-DVG3XayKF02r0rqXSJUEWJImcK8XJeiIVC/Ii5R20cINYpTaAs+x4rdCU52VaKKw + src: https://registry.npmjs.org/oojs-ui/-/oojs-ui-0.34.1.tgz + integrity: sha384-QXYp5vK60xpu4nkv/JStszI6U4TYGCNe7uXb5rYb7FYURLTR41mtNO74gl7HXgpz dest: # Main stuff diff --git a/resources/lib/ooui/History.md b/resources/lib/ooui/History.md index 9408e9bc4e..501b7688ec 100644 --- a/resources/lib/ooui/History.md +++ b/resources/lib/ooui/History.md @@ -1,4 +1,16 @@ # OOUI Release History +## v0.34.1 / 2019-09-10 +### Deprecating changes +* [DEPRECATING CHANGE] icons: Rename 'beaker' to 'labFlask' (Volker E.) + +### Styles +* icons: Add 'userGroup' (Volker E.) + +### Code +* Wrap long strings in popups (Sam Wilson) +* demos: Add missing file to PHP demo to fix infusion (Bartosz Dziewoński) + + ## v0.34.0 / 2019-09-04 ### Breaking changes * [BREAKING CHANGE] Use OOjs v3.0.0, up from v2.2.2 (James D. Forrester) diff --git a/resources/lib/ooui/i18n/fr.json b/resources/lib/ooui/i18n/fr.json index 6bfe4d6228..8595f6173d 100644 --- a/resources/lib/ooui/i18n/fr.json +++ b/resources/lib/ooui/i18n/fr.json @@ -42,11 +42,11 @@ "ooui-item-remove": "Supprimer", "ooui-dialog-message-accept": "OK", "ooui-dialog-message-reject": "Annuler", - "ooui-dialog-process-error": "Quelque chose s'est mal passé", + "ooui-dialog-process-error": "Quelque chose s’est mal passé", "ooui-dialog-process-dismiss": "Fermer", "ooui-dialog-process-retry": "Réessayer", "ooui-dialog-process-continue": "Continuer", - "ooui-combobox-button-label": "Liste déroulante de combobox", + "ooui-combobox-button-label": "Liste déroulante pour boîte de saisie", "ooui-selectfile-button-select": "Sélectionner un fichier", "ooui-selectfile-not-supported": "La sélection de fichier n’est pas prise en charge", "ooui-selectfile-placeholder": "Aucun fichier sélectionné", diff --git a/resources/lib/ooui/i18n/pl.json b/resources/lib/ooui/i18n/pl.json index affc066a66..d13cb451ae 100644 --- a/resources/lib/ooui/i18n/pl.json +++ b/resources/lib/ooui/i18n/pl.json @@ -18,7 +18,8 @@ "Gloria sah", "Andrzej aa", "The Polish", - "Railfail536" + "Railfail536", + "Rail" ] }, "ooui-outline-control-move-down": "Przesuń w dół", diff --git a/resources/lib/ooui/oojs-ui-apex.js b/resources/lib/ooui/oojs-ui-apex.js index d48a492eed..667f11e5a0 100644 --- a/resources/lib/ooui/oojs-ui-apex.js +++ b/resources/lib/ooui/oojs-ui-apex.js @@ -1,12 +1,12 @@ /*! - * OOUI v0.34.0-pre (d5e74518ab) + * OOUI v0.34.1-pre (3913589098) * https://www.mediawiki.org/wiki/OOUI * * Copyright 2011–2019 OOUI Team and other contributors. * Released under the MIT license * http://oojs.mit-license.org * - * Date: 2019-09-04T18:28:52Z + * Date: 2019-09-10T23:46:03Z */ ( function ( OO ) { diff --git a/resources/lib/ooui/oojs-ui-core-apex.css b/resources/lib/ooui/oojs-ui-core-apex.css index bb5819025f..e06ece006a 100644 --- a/resources/lib/ooui/oojs-ui-core-apex.css +++ b/resources/lib/ooui/oojs-ui-core-apex.css @@ -1,12 +1,12 @@ /*! - * OOUI v0.34.0-pre (d5e74518ab) + * OOUI v0.34.1-pre (3913589098) * https://www.mediawiki.org/wiki/OOUI * * Copyright 2011–2019 OOUI Team and other contributors. * Released under the MIT license * http://oojs.mit-license.org * - * Date: 2019-09-04T18:28:59Z + * Date: 2019-09-10T23:46:11Z */ .oo-ui-element-hidden { display: none !important; @@ -917,6 +917,8 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout { .oo-ui-popupWidget-popup { position: relative; overflow: hidden; + word-wrap: break-word; + overflow-wrap: break-word; } .oo-ui-popupWidget-anchor { display: none; diff --git a/resources/lib/ooui/oojs-ui-core-wikimediaui.css b/resources/lib/ooui/oojs-ui-core-wikimediaui.css index cfbf7d6134..d4eaea52e5 100644 --- a/resources/lib/ooui/oojs-ui-core-wikimediaui.css +++ b/resources/lib/ooui/oojs-ui-core-wikimediaui.css @@ -1,12 +1,12 @@ /*! - * OOUI v0.34.0-pre (d5e74518ab) + * OOUI v0.34.1-pre (3913589098) * https://www.mediawiki.org/wiki/OOUI * * Copyright 2011–2019 OOUI Team and other contributors. * Released under the MIT license * http://oojs.mit-license.org * - * Date: 2019-09-04T18:28:59Z + * Date: 2019-09-10T23:46:11Z */ .oo-ui-element-hidden { display: none !important; @@ -1059,6 +1059,8 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout { .oo-ui-popupWidget-popup { position: relative; overflow: hidden; + word-wrap: break-word; + overflow-wrap: break-word; } .oo-ui-popupWidget-anchor { display: none; diff --git a/resources/lib/ooui/oojs-ui-core.js b/resources/lib/ooui/oojs-ui-core.js index 11e132ea12..9754fb8b93 100644 --- a/resources/lib/ooui/oojs-ui-core.js +++ b/resources/lib/ooui/oojs-ui-core.js @@ -1,12 +1,12 @@ /*! - * OOUI v0.34.0-pre (d5e74518ab) + * OOUI v0.34.1-pre (3913589098) * https://www.mediawiki.org/wiki/OOUI * * Copyright 2011–2019 OOUI Team and other contributors. * Released under the MIT license * http://oojs.mit-license.org * - * Date: 2019-09-04T18:28:52Z + * Date: 2019-09-10T23:46:03Z */ ( function ( OO ) { diff --git a/resources/lib/ooui/oojs-ui-toolbars-apex.css b/resources/lib/ooui/oojs-ui-toolbars-apex.css index fda6a81e21..768d107a36 100644 --- a/resources/lib/ooui/oojs-ui-toolbars-apex.css +++ b/resources/lib/ooui/oojs-ui-toolbars-apex.css @@ -1,12 +1,12 @@ /*! - * OOUI v0.34.0-pre (d5e74518ab) + * OOUI v0.34.1-pre (3913589098) * https://www.mediawiki.org/wiki/OOUI * * Copyright 2011–2019 OOUI Team and other contributors. * Released under the MIT license * http://oojs.mit-license.org * - * Date: 2019-09-04T18:28:59Z + * Date: 2019-09-10T23:46:11Z */ .oo-ui-tool > .oo-ui-tool-link > .oo-ui-tool-checkIcon { display: none; diff --git a/resources/lib/ooui/oojs-ui-toolbars-wikimediaui.css b/resources/lib/ooui/oojs-ui-toolbars-wikimediaui.css index c0119427ea..5e8b9c9893 100644 --- a/resources/lib/ooui/oojs-ui-toolbars-wikimediaui.css +++ b/resources/lib/ooui/oojs-ui-toolbars-wikimediaui.css @@ -1,12 +1,12 @@ /*! - * OOUI v0.34.0-pre (d5e74518ab) + * OOUI v0.34.1-pre (3913589098) * https://www.mediawiki.org/wiki/OOUI * * Copyright 2011–2019 OOUI Team and other contributors. * Released under the MIT license * http://oojs.mit-license.org * - * Date: 2019-09-04T18:28:59Z + * Date: 2019-09-10T23:46:11Z */ .oo-ui-tool { -webkit-box-sizing: border-box; diff --git a/resources/lib/ooui/oojs-ui-toolbars.js b/resources/lib/ooui/oojs-ui-toolbars.js index 000b9eb73e..e8a571e27a 100644 --- a/resources/lib/ooui/oojs-ui-toolbars.js +++ b/resources/lib/ooui/oojs-ui-toolbars.js @@ -1,12 +1,12 @@ /*! - * OOUI v0.34.0-pre (d5e74518ab) + * OOUI v0.34.1-pre (3913589098) * https://www.mediawiki.org/wiki/OOUI * * Copyright 2011–2019 OOUI Team and other contributors. * Released under the MIT license * http://oojs.mit-license.org * - * Date: 2019-09-04T18:28:52Z + * Date: 2019-09-10T23:46:03Z */ ( function ( OO ) { diff --git a/resources/lib/ooui/oojs-ui-widgets-apex.css b/resources/lib/ooui/oojs-ui-widgets-apex.css index 854d8e36be..f94e98b1a1 100644 --- a/resources/lib/ooui/oojs-ui-widgets-apex.css +++ b/resources/lib/ooui/oojs-ui-widgets-apex.css @@ -1,12 +1,12 @@ /*! - * OOUI v0.34.0-pre (d5e74518ab) + * OOUI v0.34.1-pre (3913589098) * https://www.mediawiki.org/wiki/OOUI * * Copyright 2011–2019 OOUI Team and other contributors. * Released under the MIT license * http://oojs.mit-license.org * - * Date: 2019-09-04T18:28:59Z + * Date: 2019-09-10T23:46:11Z */ .oo-ui-draggableElement-handle:not( .oo-ui-draggableElement-undraggable ).oo-ui-widget { cursor: move; diff --git a/resources/lib/ooui/oojs-ui-widgets-wikimediaui.css b/resources/lib/ooui/oojs-ui-widgets-wikimediaui.css index 73da6f8383..8bc82a87e9 100644 --- a/resources/lib/ooui/oojs-ui-widgets-wikimediaui.css +++ b/resources/lib/ooui/oojs-ui-widgets-wikimediaui.css @@ -1,12 +1,12 @@ /*! - * OOUI v0.34.0-pre (d5e74518ab) + * OOUI v0.34.1-pre (3913589098) * https://www.mediawiki.org/wiki/OOUI * * Copyright 2011–2019 OOUI Team and other contributors. * Released under the MIT license * http://oojs.mit-license.org * - * Date: 2019-09-04T18:28:59Z + * Date: 2019-09-10T23:46:11Z */ .oo-ui-draggableElement-handle:not( .oo-ui-draggableElement-undraggable ).oo-ui-widget { cursor: move; diff --git a/resources/lib/ooui/oojs-ui-widgets.js b/resources/lib/ooui/oojs-ui-widgets.js index bdf0d2f24f..7afac69be9 100644 --- a/resources/lib/ooui/oojs-ui-widgets.js +++ b/resources/lib/ooui/oojs-ui-widgets.js @@ -1,12 +1,12 @@ /*! - * OOUI v0.34.0-pre (d5e74518ab) + * OOUI v0.34.1-pre (3913589098) * https://www.mediawiki.org/wiki/OOUI * * Copyright 2011–2019 OOUI Team and other contributors. * Released under the MIT license * http://oojs.mit-license.org * - * Date: 2019-09-04T18:28:52Z + * Date: 2019-09-10T23:46:03Z */ ( function ( OO ) { diff --git a/resources/lib/ooui/oojs-ui-wikimediaui.js b/resources/lib/ooui/oojs-ui-wikimediaui.js index 75f1acdfd4..5355835d1f 100644 --- a/resources/lib/ooui/oojs-ui-wikimediaui.js +++ b/resources/lib/ooui/oojs-ui-wikimediaui.js @@ -1,12 +1,12 @@ /*! - * OOUI v0.34.0-pre (d5e74518ab) + * OOUI v0.34.1-pre (3913589098) * https://www.mediawiki.org/wiki/OOUI * * Copyright 2011–2019 OOUI Team and other contributors. * Released under the MIT license * http://oojs.mit-license.org * - * Date: 2019-09-04T18:28:52Z + * Date: 2019-09-10T23:46:03Z */ ( function ( OO ) { diff --git a/resources/lib/ooui/oojs-ui-windows-apex.css b/resources/lib/ooui/oojs-ui-windows-apex.css index 8ac442f48c..5a11914b7c 100644 --- a/resources/lib/ooui/oojs-ui-windows-apex.css +++ b/resources/lib/ooui/oojs-ui-windows-apex.css @@ -1,12 +1,12 @@ /*! - * OOUI v0.34.0-pre (d5e74518ab) + * OOUI v0.34.1-pre (3913589098) * https://www.mediawiki.org/wiki/OOUI * * Copyright 2011–2019 OOUI Team and other contributors. * Released under the MIT license * http://oojs.mit-license.org * - * Date: 2019-09-04T18:28:59Z + * Date: 2019-09-10T23:46:11Z */ .oo-ui-window { diff --git a/resources/lib/ooui/oojs-ui-windows-wikimediaui.css b/resources/lib/ooui/oojs-ui-windows-wikimediaui.css index e406188090..b1a067bce6 100644 --- a/resources/lib/ooui/oojs-ui-windows-wikimediaui.css +++ b/resources/lib/ooui/oojs-ui-windows-wikimediaui.css @@ -1,12 +1,12 @@ /*! - * OOUI v0.34.0-pre (d5e74518ab) + * OOUI v0.34.1-pre (3913589098) * https://www.mediawiki.org/wiki/OOUI * * Copyright 2011–2019 OOUI Team and other contributors. * Released under the MIT license * http://oojs.mit-license.org * - * Date: 2019-09-04T18:28:59Z + * Date: 2019-09-10T23:46:11Z */ .oo-ui-window { diff --git a/resources/lib/ooui/oojs-ui-windows.js b/resources/lib/ooui/oojs-ui-windows.js index 8885525f1f..d8db8d1a34 100644 --- a/resources/lib/ooui/oojs-ui-windows.js +++ b/resources/lib/ooui/oojs-ui-windows.js @@ -1,12 +1,12 @@ /*! - * OOUI v0.34.0-pre (d5e74518ab) + * OOUI v0.34.1-pre (3913589098) * https://www.mediawiki.org/wiki/OOUI * * Copyright 2011–2019 OOUI Team and other contributors. * Released under the MIT license * http://oojs.mit-license.org * - * Date: 2019-09-04T18:28:52Z + * Date: 2019-09-10T23:46:03Z */ ( function ( OO ) { diff --git a/resources/lib/ooui/themes/apex/icons-editing-advanced.json b/resources/lib/ooui/themes/apex/icons-editing-advanced.json index 732d70ffbc..516dc08d57 100644 --- a/resources/lib/ooui/themes/apex/icons-editing-advanced.json +++ b/resources/lib/ooui/themes/apex/icons-editing-advanced.json @@ -15,7 +15,8 @@ "file": "../wikimediaui/images/icons/attachment.svg" }, "beaker": { - "file": "../wikimediaui/images/icons/beaker.svg" + "file": "../wikimediaui/images/icons/labFlask.svg", + "deprecated": "Renamed since v0.34.1, use 'labFlask' instead." }, "calendar": { "file": "../wikimediaui/images/icons/calendar.svg" @@ -38,6 +39,9 @@ "imageLayoutThumbnail": { "file": "../wikimediaui/images/icons/imageLayoutThumbnail.svg" }, + "labFlask": { + "file": "../wikimediaui/images/icons/labFlask.svg" + }, "language": { "file": "../wikimediaui/images/icons/language.svg" }, diff --git a/resources/lib/ooui/themes/apex/icons-user.json b/resources/lib/ooui/themes/apex/icons-user.json index e13bb1db62..de7a1183db 100644 --- a/resources/lib/ooui/themes/apex/icons-user.json +++ b/resources/lib/ooui/themes/apex/icons-user.json @@ -11,6 +11,12 @@ "userAvatarOutline": { "file": "../wikimediaui/images/icons/userAvatarOutline.svg" }, + "userGroup": { + "file": { + "ltr": "../wikimediaui/images/icons/userGroup-ltr.svg", + "rtl": "../wikimediaui/images/icons/userGroup-rtl.svg" + } + }, "userTalk": { "file": { "ltr": "../wikimediaui/images/icons/userTalk-ltr.svg", diff --git a/resources/lib/ooui/themes/wikimediaui/icons-editing-advanced.json b/resources/lib/ooui/themes/wikimediaui/icons-editing-advanced.json index 4f4fd4e062..23dd607da9 100644 --- a/resources/lib/ooui/themes/wikimediaui/icons-editing-advanced.json +++ b/resources/lib/ooui/themes/wikimediaui/icons-editing-advanced.json @@ -38,7 +38,8 @@ "file": "images/icons/attachment.svg" }, "beaker": { - "file": "images/icons/beaker.svg" + "file": "images/icons/labFlask.svg", + "deprecated": "Renamed since v0.34.1, use 'labFlask' instead." }, "calendar": { "file": "images/icons/calendar.svg" @@ -61,6 +62,9 @@ "imageLayoutThumbnail": { "file": "images/icons/imageLayoutThumbnail.svg" }, + "labFlask": { + "file": "images/icons/labFlask.svg" + }, "language": { "file": "images/icons/language.svg" }, diff --git a/resources/lib/ooui/themes/wikimediaui/icons-user.json b/resources/lib/ooui/themes/wikimediaui/icons-user.json index 7266d3426f..5a382ce75a 100644 --- a/resources/lib/ooui/themes/wikimediaui/icons-user.json +++ b/resources/lib/ooui/themes/wikimediaui/icons-user.json @@ -34,6 +34,12 @@ "userAvatarOutline": { "file": "images/icons/userAvatarOutline.svg" }, + "userGroup": { + "file": { + "ltr": "images/icons/userGroup-ltr.svg", + "rtl": "images/icons/userGroup-rtl.svg" + } + }, "userTalk": { "file": { "ltr": "images/icons/userTalk-ltr.svg", diff --git a/resources/lib/ooui/themes/wikimediaui/images/icons/beaker-invert.png b/resources/lib/ooui/themes/wikimediaui/images/icons/beaker-invert.png deleted file mode 100644 index 89d2d3db79..0000000000 Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/beaker-invert.png and /dev/null differ diff --git a/resources/lib/ooui/themes/wikimediaui/images/icons/beaker-invert.svg b/resources/lib/ooui/themes/wikimediaui/images/icons/beaker-invert.svg deleted file mode 100644 index c031dafabd..0000000000 --- a/resources/lib/ooui/themes/wikimediaui/images/icons/beaker-invert.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - - beaker - - - diff --git a/resources/lib/ooui/themes/wikimediaui/images/icons/beaker-progressive.png b/resources/lib/ooui/themes/wikimediaui/images/icons/beaker-progressive.png deleted file mode 100644 index 78736aca78..0000000000 Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/beaker-progressive.png and /dev/null differ diff --git a/resources/lib/ooui/themes/wikimediaui/images/icons/beaker-progressive.svg b/resources/lib/ooui/themes/wikimediaui/images/icons/beaker-progressive.svg deleted file mode 100644 index 1f8efbdee7..0000000000 --- a/resources/lib/ooui/themes/wikimediaui/images/icons/beaker-progressive.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - - beaker - - - diff --git a/resources/lib/ooui/themes/wikimediaui/images/icons/beaker.png b/resources/lib/ooui/themes/wikimediaui/images/icons/beaker.png deleted file mode 100644 index 63a1a80b27..0000000000 Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/beaker.png and /dev/null differ diff --git a/resources/lib/ooui/themes/wikimediaui/images/icons/beaker.svg b/resources/lib/ooui/themes/wikimediaui/images/icons/beaker.svg deleted file mode 100644 index 7a37c5a7ad..0000000000 --- a/resources/lib/ooui/themes/wikimediaui/images/icons/beaker.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - - beaker - - - diff --git a/resources/lib/ooui/themes/wikimediaui/images/icons/labFlask-invert.png b/resources/lib/ooui/themes/wikimediaui/images/icons/labFlask-invert.png new file mode 100644 index 0000000000..89d2d3db79 Binary files /dev/null and b/resources/lib/ooui/themes/wikimediaui/images/icons/labFlask-invert.png differ diff --git a/resources/lib/ooui/themes/wikimediaui/images/icons/labFlask-invert.svg b/resources/lib/ooui/themes/wikimediaui/images/icons/labFlask-invert.svg new file mode 100644 index 0000000000..bfb66da0d0 --- /dev/null +++ b/resources/lib/ooui/themes/wikimediaui/images/icons/labFlask-invert.svg @@ -0,0 +1,7 @@ + + + + laboratory flask + + + diff --git a/resources/lib/ooui/themes/wikimediaui/images/icons/labFlask-progressive.png b/resources/lib/ooui/themes/wikimediaui/images/icons/labFlask-progressive.png new file mode 100644 index 0000000000..78736aca78 Binary files /dev/null and b/resources/lib/ooui/themes/wikimediaui/images/icons/labFlask-progressive.png differ diff --git a/resources/lib/ooui/themes/wikimediaui/images/icons/labFlask-progressive.svg b/resources/lib/ooui/themes/wikimediaui/images/icons/labFlask-progressive.svg new file mode 100644 index 0000000000..1db0d6bd11 --- /dev/null +++ b/resources/lib/ooui/themes/wikimediaui/images/icons/labFlask-progressive.svg @@ -0,0 +1,7 @@ + + + + laboratory flask + + + diff --git a/resources/lib/ooui/themes/wikimediaui/images/icons/labFlask.png b/resources/lib/ooui/themes/wikimediaui/images/icons/labFlask.png new file mode 100644 index 0000000000..63a1a80b27 Binary files /dev/null and b/resources/lib/ooui/themes/wikimediaui/images/icons/labFlask.png differ diff --git a/resources/lib/ooui/themes/wikimediaui/images/icons/labFlask.svg b/resources/lib/ooui/themes/wikimediaui/images/icons/labFlask.svg new file mode 100644 index 0000000000..c95a51a8bd --- /dev/null +++ b/resources/lib/ooui/themes/wikimediaui/images/icons/labFlask.svg @@ -0,0 +1,7 @@ + + + + laboratory flask + + + diff --git a/resources/lib/ooui/themes/wikimediaui/images/icons/userAvatarOutline-invert.svg b/resources/lib/ooui/themes/wikimediaui/images/icons/userAvatarOutline-invert.svg index 3b5187ded1..268dc3046d 100644 --- a/resources/lib/ooui/themes/wikimediaui/images/icons/userAvatarOutline-invert.svg +++ b/resources/lib/ooui/themes/wikimediaui/images/icons/userAvatarOutline-invert.svg @@ -1,4 +1,4 @@ - + user avatar diff --git a/resources/lib/ooui/themes/wikimediaui/images/icons/userAvatarOutline-progressive.svg b/resources/lib/ooui/themes/wikimediaui/images/icons/userAvatarOutline-progressive.svg index 047a18c79f..681a46815c 100644 --- a/resources/lib/ooui/themes/wikimediaui/images/icons/userAvatarOutline-progressive.svg +++ b/resources/lib/ooui/themes/wikimediaui/images/icons/userAvatarOutline-progressive.svg @@ -1,4 +1,4 @@ - + user avatar diff --git a/resources/lib/ooui/themes/wikimediaui/images/icons/userAvatarOutline.svg b/resources/lib/ooui/themes/wikimediaui/images/icons/userAvatarOutline.svg index 7608cd2eaf..82362357c2 100644 --- a/resources/lib/ooui/themes/wikimediaui/images/icons/userAvatarOutline.svg +++ b/resources/lib/ooui/themes/wikimediaui/images/icons/userAvatarOutline.svg @@ -1,4 +1,4 @@ - + user avatar diff --git a/resources/lib/ooui/themes/wikimediaui/images/icons/userGroup-ltr-invert.png b/resources/lib/ooui/themes/wikimediaui/images/icons/userGroup-ltr-invert.png new file mode 100644 index 0000000000..bc9c1114e3 Binary files /dev/null and b/resources/lib/ooui/themes/wikimediaui/images/icons/userGroup-ltr-invert.png differ diff --git a/resources/lib/ooui/themes/wikimediaui/images/icons/userGroup-ltr-invert.svg b/resources/lib/ooui/themes/wikimediaui/images/icons/userGroup-ltr-invert.svg new file mode 100644 index 0000000000..d05ad381a5 --- /dev/null +++ b/resources/lib/ooui/themes/wikimediaui/images/icons/userGroup-ltr-invert.svg @@ -0,0 +1,7 @@ + + + + user group + + + diff --git a/resources/lib/ooui/themes/wikimediaui/images/icons/userGroup-ltr-progressive.png b/resources/lib/ooui/themes/wikimediaui/images/icons/userGroup-ltr-progressive.png new file mode 100644 index 0000000000..5cd3d1c7b0 Binary files /dev/null and b/resources/lib/ooui/themes/wikimediaui/images/icons/userGroup-ltr-progressive.png differ diff --git a/resources/lib/ooui/themes/wikimediaui/images/icons/userGroup-ltr-progressive.svg b/resources/lib/ooui/themes/wikimediaui/images/icons/userGroup-ltr-progressive.svg new file mode 100644 index 0000000000..71d354a78d --- /dev/null +++ b/resources/lib/ooui/themes/wikimediaui/images/icons/userGroup-ltr-progressive.svg @@ -0,0 +1,7 @@ + + + + user group + + + diff --git a/resources/lib/ooui/themes/wikimediaui/images/icons/userGroup-ltr.png b/resources/lib/ooui/themes/wikimediaui/images/icons/userGroup-ltr.png new file mode 100644 index 0000000000..43c0be222d Binary files /dev/null and b/resources/lib/ooui/themes/wikimediaui/images/icons/userGroup-ltr.png differ diff --git a/resources/lib/ooui/themes/wikimediaui/images/icons/userGroup-ltr.svg b/resources/lib/ooui/themes/wikimediaui/images/icons/userGroup-ltr.svg new file mode 100644 index 0000000000..248d0560f1 --- /dev/null +++ b/resources/lib/ooui/themes/wikimediaui/images/icons/userGroup-ltr.svg @@ -0,0 +1,7 @@ + + + + user group + + + diff --git a/resources/lib/ooui/themes/wikimediaui/images/icons/userGroup-rtl-invert.png b/resources/lib/ooui/themes/wikimediaui/images/icons/userGroup-rtl-invert.png new file mode 100644 index 0000000000..2147e81d8c Binary files /dev/null and b/resources/lib/ooui/themes/wikimediaui/images/icons/userGroup-rtl-invert.png differ diff --git a/resources/lib/ooui/themes/wikimediaui/images/icons/userGroup-rtl-invert.svg b/resources/lib/ooui/themes/wikimediaui/images/icons/userGroup-rtl-invert.svg new file mode 100644 index 0000000000..5604358123 --- /dev/null +++ b/resources/lib/ooui/themes/wikimediaui/images/icons/userGroup-rtl-invert.svg @@ -0,0 +1,7 @@ + + + + user group + + + diff --git a/resources/lib/ooui/themes/wikimediaui/images/icons/userGroup-rtl-progressive.png b/resources/lib/ooui/themes/wikimediaui/images/icons/userGroup-rtl-progressive.png new file mode 100644 index 0000000000..d9082d388c Binary files /dev/null and b/resources/lib/ooui/themes/wikimediaui/images/icons/userGroup-rtl-progressive.png differ diff --git a/resources/lib/ooui/themes/wikimediaui/images/icons/userGroup-rtl-progressive.svg b/resources/lib/ooui/themes/wikimediaui/images/icons/userGroup-rtl-progressive.svg new file mode 100644 index 0000000000..75436e9d19 --- /dev/null +++ b/resources/lib/ooui/themes/wikimediaui/images/icons/userGroup-rtl-progressive.svg @@ -0,0 +1,7 @@ + + + + user group + + + diff --git a/resources/lib/ooui/themes/wikimediaui/images/icons/userGroup-rtl.png b/resources/lib/ooui/themes/wikimediaui/images/icons/userGroup-rtl.png new file mode 100644 index 0000000000..4eedd2e7ab Binary files /dev/null and b/resources/lib/ooui/themes/wikimediaui/images/icons/userGroup-rtl.png differ diff --git a/resources/lib/ooui/themes/wikimediaui/images/icons/userGroup-rtl.svg b/resources/lib/ooui/themes/wikimediaui/images/icons/userGroup-rtl.svg new file mode 100644 index 0000000000..5bd5bf5969 --- /dev/null +++ b/resources/lib/ooui/themes/wikimediaui/images/icons/userGroup-rtl.svg @@ -0,0 +1,7 @@ + + + + user group + + + diff --git a/resources/src/jquery.color/jquery.color.js b/resources/src/jquery.color/jquery.color.js new file mode 100644 index 0000000000..6df02adf5b --- /dev/null +++ b/resources/src/jquery.color/jquery.color.js @@ -0,0 +1,55 @@ +/** + * jQuery Color Animations + * + * @author John Resig, 2007 + * @author Krinkle, 2011 + * Released under the MIT and GPL licenses. + * + * - 2011-01-05: Forked for MediaWiki. See also jQuery.colorUtil plugin + */ +( function () { + + function getColor( elem, attr ) { + var color; + + do { + color = $.css( elem, attr ); + + // Keep going until we find an element that has color, or we hit the body + if ( color !== '' && color !== 'transparent' || elem.nodeName.toLowerCase() === 'body' ) { + break; + } + + attr = 'backgroundColor'; + // eslint-disable-next-line no-cond-assign + } while ( elem = elem.parentNode ); + + return $.colorUtil.getRGB( color ); + } + + // We override the animation for all of these color styles + [ + 'backgroundColor', + 'borderBottomColor', + 'borderLeftColor', + 'borderRightColor', + 'borderTopColor', + 'color', + 'outlineColor' + ].forEach( function ( attr ) { + $.fx.step[ attr ] = function ( fx ) { + if ( !fx.colorInit ) { + fx.start = getColor( fx.elem, attr ); + fx.end = $.colorUtil.getRGB( fx.end ); + fx.colorInit = true; + } + + fx.elem.style[ attr ] = 'rgb(' + [ + Math.max( Math.min( parseInt( ( fx.pos * ( fx.end[ 0 ] - fx.start[ 0 ] ) ) + fx.start[ 0 ], 10 ), 255 ), 0 ), + Math.max( Math.min( parseInt( ( fx.pos * ( fx.end[ 1 ] - fx.start[ 1 ] ) ) + fx.start[ 1 ], 10 ), 255 ), 0 ), + Math.max( Math.min( parseInt( ( fx.pos * ( fx.end[ 2 ] - fx.start[ 2 ] ) ) + fx.start[ 2 ], 10 ), 255 ), 0 ) + ].join( ',' ) + ')'; + }; + } ); + +}() ); diff --git a/resources/src/jquery.color/jquery.colorUtil.js b/resources/src/jquery.color/jquery.colorUtil.js new file mode 100644 index 0000000000..009be1aa73 --- /dev/null +++ b/resources/src/jquery.color/jquery.colorUtil.js @@ -0,0 +1,268 @@ +/*! + * jQuery Color Utilities + * + * Released under the MIT and GPL licenses. + * + * Mostly based on other plugins and functions (linted and optimized a little). + * Sources cited inline. + */ +( function () { + /** + * @class jQuery.colorUtil + * @singleton + */ + $.colorUtil = { + + /** + * Parse CSS color strings looking for color tuples + * + * Based on highlightFade by Blair Mitchelmore + * + * + * @param {Array|string} color + * @return {Array} + */ + getRGB: function ( color ) { + var result; + + // Check if we're already dealing with an array of colors + if ( color && Array.isArray( color ) && color.length === 3 ) { + return color; + } + if ( typeof color !== 'string' ) { + return undefined; + } + + // Look for rgb(num,num,num) + // eslint-disable-next-line no-cond-assign + if ( result = /rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec( color ) ) { + return [ + parseInt( result[ 1 ], 10 ), + parseInt( result[ 2 ], 10 ), + parseInt( result[ 3 ], 10 ) + ]; + } + + // Look for rgb(num%,num%,num%) + // eslint-disable-next-line no-cond-assign + if ( result = /rgb\(\s*([0-9]+(?:\.[0-9]+)?)%\s*,\s*([0-9]+(?:\.[0-9]+)?)%\s*,\s*([0-9]+(?:\.[0-9]+)?)%\s*\)/.exec( color ) ) { + return [ + parseFloat( result[ 1 ] ) * 2.55, + parseFloat( result[ 2 ] ) * 2.55, + parseFloat( result[ 3 ] ) * 2.55 + ]; + } + + // Look for #a0b1c2 + // eslint-disable-next-line no-cond-assign + if ( result = /#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec( color ) ) { + return [ + parseInt( result[ 1 ], 16 ), + parseInt( result[ 2 ], 16 ), + parseInt( result[ 3 ], 16 ) + ]; + } + + // Look for #fff + // eslint-disable-next-line no-cond-assign + if ( result = /#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec( color ) ) { + return [ + parseInt( result[ 1 ] + result[ 1 ], 16 ), + parseInt( result[ 2 ] + result[ 2 ], 16 ), + parseInt( result[ 3 ] + result[ 3 ], 16 ) + ]; + } + + // Look for rgba(0, 0, 0, 0) == transparent in Safari 3 + // eslint-disable-next-line no-cond-assign + if ( result = /rgba\(0, 0, 0, 0\)/.exec( color ) ) { + return $.colorUtil.colors.transparent; + } + + // Otherwise, we're most likely dealing with a named color + return $.colorUtil.colors[ color.trim().toLowerCase() ]; + }, + + /** + * Named color map + * + * Based on Interface by Stefan Petre + * + * + * @property {Object} + */ + colors: { + aqua: [ 0, 255, 255 ], + azure: [ 240, 255, 255 ], + beige: [ 245, 245, 220 ], + black: [ 0, 0, 0 ], + blue: [ 0, 0, 255 ], + brown: [ 165, 42, 42 ], + cyan: [ 0, 255, 255 ], + darkblue: [ 0, 0, 139 ], + darkcyan: [ 0, 139, 139 ], + darkgrey: [ 169, 169, 169 ], + darkgreen: [ 0, 100, 0 ], + darkkhaki: [ 189, 183, 107 ], + darkmagenta: [ 139, 0, 139 ], + darkolivegreen: [ 85, 107, 47 ], + darkorange: [ 255, 140, 0 ], + darkorchid: [ 153, 50, 204 ], + darkred: [ 139, 0, 0 ], + darksalmon: [ 233, 150, 122 ], + darkviolet: [ 148, 0, 211 ], + fuchsia: [ 255, 0, 255 ], + gold: [ 255, 215, 0 ], + green: [ 0, 128, 0 ], + indigo: [ 75, 0, 130 ], + khaki: [ 240, 230, 140 ], + lightblue: [ 173, 216, 230 ], + lightcyan: [ 224, 255, 255 ], + lightgreen: [ 144, 238, 144 ], + lightgrey: [ 211, 211, 211 ], + lightpink: [ 255, 182, 193 ], + lightyellow: [ 255, 255, 224 ], + lime: [ 0, 255, 0 ], + magenta: [ 255, 0, 255 ], + maroon: [ 128, 0, 0 ], + navy: [ 0, 0, 128 ], + olive: [ 128, 128, 0 ], + orange: [ 255, 165, 0 ], + pink: [ 255, 192, 203 ], + purple: [ 128, 0, 128 ], + violet: [ 128, 0, 128 ], + red: [ 255, 0, 0 ], + silver: [ 192, 192, 192 ], + white: [ 255, 255, 255 ], + yellow: [ 255, 255, 0 ], + transparent: [ 255, 255, 255 ] + }, + + /** + * Convert an RGB color value to HSL. + * + * Conversion formula based on + * + * + * Adapted from . + * + * Assumes `r`, `g`, and `b` are contained in the set `[0, 255]` and + * returns `h`, `s`, and `l` in the set `[0, 1]`. + * + * @param {number} r The red color value + * @param {number} g The green color value + * @param {number} b The blue color value + * @return {number[]} The HSL representation + */ + rgbToHsl: function ( r, g, b ) { + var d, h, s, l, min, max; + + r = r / 255; + g = g / 255; + b = b / 255; + + max = Math.max( r, g, b ); + min = Math.min( r, g, b ); + l = ( max + min ) / 2; + + if ( max === min ) { + // achromatic + h = s = 0; + } else { + d = max - min; + s = l > 0.5 ? d / ( 2 - max - min ) : d / ( max + min ); + switch ( max ) { + case r: + h = ( g - b ) / d + ( g < b ? 6 : 0 ); + break; + case g: + h = ( b - r ) / d + 2; + break; + case b: + h = ( r - g ) / d + 4; + break; + } + h /= 6; + } + + return [ h, s, l ]; + }, + + /** + * Convert an HSL color value to RGB. + * + * Conversion formula based on + * + * + * Adapted from . + * + * Assumes `h`, `s`, and `l` are contained in the set `[0, 1]` and + * returns `r`, `g`, and `b` in the set `[0, 255]`. + * + * @param {number} h The hue + * @param {number} s The saturation + * @param {number} l The lightness + * @return {number[]} The RGB representation + */ + hslToRgb: function ( h, s, l ) { + var r, g, b, hue2rgb, q, p; + + if ( s === 0 ) { + r = g = b = l; // achromatic + } else { + hue2rgb = function ( p, q, t ) { + if ( t < 0 ) { + t += 1; + } + if ( t > 1 ) { + t -= 1; + } + if ( t < 1 / 6 ) { + return p + ( q - p ) * 6 * t; + } + if ( t < 1 / 2 ) { + return q; + } + if ( t < 2 / 3 ) { + return p + ( q - p ) * ( 2 / 3 - t ) * 6; + } + return p; + }; + + q = l < 0.5 ? l * ( 1 + s ) : l + s - l * s; + p = 2 * l - q; + r = hue2rgb( p, q, h + 1 / 3 ); + g = hue2rgb( p, q, h ); + b = hue2rgb( p, q, h - 1 / 3 ); + } + + return [ r * 255, g * 255, b * 255 ]; + }, + + /** + * Get a brighter or darker rgb() value string. + * + * Usage: + * + * $.colorUtil.getColorBrightness( 'red', +0.1 ); + * // > "rgb(255,50,50)" + * $.colorUtil.getColorBrightness( 'rgb(200,50,50)', -0.2 ); + * // > "rgb(118,29,29)" + * + * @param {Mixed} currentColor Current value in css + * @param {number} mod Wanted brightness modification between -1 and 1 + * @return {string} Like `'rgb(r,g,b)'` + */ + getColorBrightness: function ( currentColor, mod ) { + var rgbArr = $.colorUtil.getRGB( currentColor ), + hslArr = $.colorUtil.rgbToHsl( rgbArr[ 0 ], rgbArr[ 1 ], rgbArr[ 2 ] ); + rgbArr = $.colorUtil.hslToRgb( hslArr[ 0 ], hslArr[ 1 ], hslArr[ 2 ] + mod ); + + return 'rgb(' + + [ parseInt( rgbArr[ 0 ], 10 ), parseInt( rgbArr[ 1 ], 10 ), parseInt( rgbArr[ 2 ], 10 ) ].join( ',' ) + + ')'; + } + + }; + +}() ); diff --git a/resources/src/jquery/jquery.color.js b/resources/src/jquery/jquery.color.js deleted file mode 100644 index 6df02adf5b..0000000000 --- a/resources/src/jquery/jquery.color.js +++ /dev/null @@ -1,55 +0,0 @@ -/** - * jQuery Color Animations - * - * @author John Resig, 2007 - * @author Krinkle, 2011 - * Released under the MIT and GPL licenses. - * - * - 2011-01-05: Forked for MediaWiki. See also jQuery.colorUtil plugin - */ -( function () { - - function getColor( elem, attr ) { - var color; - - do { - color = $.css( elem, attr ); - - // Keep going until we find an element that has color, or we hit the body - if ( color !== '' && color !== 'transparent' || elem.nodeName.toLowerCase() === 'body' ) { - break; - } - - attr = 'backgroundColor'; - // eslint-disable-next-line no-cond-assign - } while ( elem = elem.parentNode ); - - return $.colorUtil.getRGB( color ); - } - - // We override the animation for all of these color styles - [ - 'backgroundColor', - 'borderBottomColor', - 'borderLeftColor', - 'borderRightColor', - 'borderTopColor', - 'color', - 'outlineColor' - ].forEach( function ( attr ) { - $.fx.step[ attr ] = function ( fx ) { - if ( !fx.colorInit ) { - fx.start = getColor( fx.elem, attr ); - fx.end = $.colorUtil.getRGB( fx.end ); - fx.colorInit = true; - } - - fx.elem.style[ attr ] = 'rgb(' + [ - Math.max( Math.min( parseInt( ( fx.pos * ( fx.end[ 0 ] - fx.start[ 0 ] ) ) + fx.start[ 0 ], 10 ), 255 ), 0 ), - Math.max( Math.min( parseInt( ( fx.pos * ( fx.end[ 1 ] - fx.start[ 1 ] ) ) + fx.start[ 1 ], 10 ), 255 ), 0 ), - Math.max( Math.min( parseInt( ( fx.pos * ( fx.end[ 2 ] - fx.start[ 2 ] ) ) + fx.start[ 2 ], 10 ), 255 ), 0 ) - ].join( ',' ) + ')'; - }; - } ); - -}() ); diff --git a/resources/src/jquery/jquery.colorUtil.js b/resources/src/jquery/jquery.colorUtil.js deleted file mode 100644 index 009be1aa73..0000000000 --- a/resources/src/jquery/jquery.colorUtil.js +++ /dev/null @@ -1,268 +0,0 @@ -/*! - * jQuery Color Utilities - * - * Released under the MIT and GPL licenses. - * - * Mostly based on other plugins and functions (linted and optimized a little). - * Sources cited inline. - */ -( function () { - /** - * @class jQuery.colorUtil - * @singleton - */ - $.colorUtil = { - - /** - * Parse CSS color strings looking for color tuples - * - * Based on highlightFade by Blair Mitchelmore - * - * - * @param {Array|string} color - * @return {Array} - */ - getRGB: function ( color ) { - var result; - - // Check if we're already dealing with an array of colors - if ( color && Array.isArray( color ) && color.length === 3 ) { - return color; - } - if ( typeof color !== 'string' ) { - return undefined; - } - - // Look for rgb(num,num,num) - // eslint-disable-next-line no-cond-assign - if ( result = /rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec( color ) ) { - return [ - parseInt( result[ 1 ], 10 ), - parseInt( result[ 2 ], 10 ), - parseInt( result[ 3 ], 10 ) - ]; - } - - // Look for rgb(num%,num%,num%) - // eslint-disable-next-line no-cond-assign - if ( result = /rgb\(\s*([0-9]+(?:\.[0-9]+)?)%\s*,\s*([0-9]+(?:\.[0-9]+)?)%\s*,\s*([0-9]+(?:\.[0-9]+)?)%\s*\)/.exec( color ) ) { - return [ - parseFloat( result[ 1 ] ) * 2.55, - parseFloat( result[ 2 ] ) * 2.55, - parseFloat( result[ 3 ] ) * 2.55 - ]; - } - - // Look for #a0b1c2 - // eslint-disable-next-line no-cond-assign - if ( result = /#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec( color ) ) { - return [ - parseInt( result[ 1 ], 16 ), - parseInt( result[ 2 ], 16 ), - parseInt( result[ 3 ], 16 ) - ]; - } - - // Look for #fff - // eslint-disable-next-line no-cond-assign - if ( result = /#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec( color ) ) { - return [ - parseInt( result[ 1 ] + result[ 1 ], 16 ), - parseInt( result[ 2 ] + result[ 2 ], 16 ), - parseInt( result[ 3 ] + result[ 3 ], 16 ) - ]; - } - - // Look for rgba(0, 0, 0, 0) == transparent in Safari 3 - // eslint-disable-next-line no-cond-assign - if ( result = /rgba\(0, 0, 0, 0\)/.exec( color ) ) { - return $.colorUtil.colors.transparent; - } - - // Otherwise, we're most likely dealing with a named color - return $.colorUtil.colors[ color.trim().toLowerCase() ]; - }, - - /** - * Named color map - * - * Based on Interface by Stefan Petre - * - * - * @property {Object} - */ - colors: { - aqua: [ 0, 255, 255 ], - azure: [ 240, 255, 255 ], - beige: [ 245, 245, 220 ], - black: [ 0, 0, 0 ], - blue: [ 0, 0, 255 ], - brown: [ 165, 42, 42 ], - cyan: [ 0, 255, 255 ], - darkblue: [ 0, 0, 139 ], - darkcyan: [ 0, 139, 139 ], - darkgrey: [ 169, 169, 169 ], - darkgreen: [ 0, 100, 0 ], - darkkhaki: [ 189, 183, 107 ], - darkmagenta: [ 139, 0, 139 ], - darkolivegreen: [ 85, 107, 47 ], - darkorange: [ 255, 140, 0 ], - darkorchid: [ 153, 50, 204 ], - darkred: [ 139, 0, 0 ], - darksalmon: [ 233, 150, 122 ], - darkviolet: [ 148, 0, 211 ], - fuchsia: [ 255, 0, 255 ], - gold: [ 255, 215, 0 ], - green: [ 0, 128, 0 ], - indigo: [ 75, 0, 130 ], - khaki: [ 240, 230, 140 ], - lightblue: [ 173, 216, 230 ], - lightcyan: [ 224, 255, 255 ], - lightgreen: [ 144, 238, 144 ], - lightgrey: [ 211, 211, 211 ], - lightpink: [ 255, 182, 193 ], - lightyellow: [ 255, 255, 224 ], - lime: [ 0, 255, 0 ], - magenta: [ 255, 0, 255 ], - maroon: [ 128, 0, 0 ], - navy: [ 0, 0, 128 ], - olive: [ 128, 128, 0 ], - orange: [ 255, 165, 0 ], - pink: [ 255, 192, 203 ], - purple: [ 128, 0, 128 ], - violet: [ 128, 0, 128 ], - red: [ 255, 0, 0 ], - silver: [ 192, 192, 192 ], - white: [ 255, 255, 255 ], - yellow: [ 255, 255, 0 ], - transparent: [ 255, 255, 255 ] - }, - - /** - * Convert an RGB color value to HSL. - * - * Conversion formula based on - * - * - * Adapted from . - * - * Assumes `r`, `g`, and `b` are contained in the set `[0, 255]` and - * returns `h`, `s`, and `l` in the set `[0, 1]`. - * - * @param {number} r The red color value - * @param {number} g The green color value - * @param {number} b The blue color value - * @return {number[]} The HSL representation - */ - rgbToHsl: function ( r, g, b ) { - var d, h, s, l, min, max; - - r = r / 255; - g = g / 255; - b = b / 255; - - max = Math.max( r, g, b ); - min = Math.min( r, g, b ); - l = ( max + min ) / 2; - - if ( max === min ) { - // achromatic - h = s = 0; - } else { - d = max - min; - s = l > 0.5 ? d / ( 2 - max - min ) : d / ( max + min ); - switch ( max ) { - case r: - h = ( g - b ) / d + ( g < b ? 6 : 0 ); - break; - case g: - h = ( b - r ) / d + 2; - break; - case b: - h = ( r - g ) / d + 4; - break; - } - h /= 6; - } - - return [ h, s, l ]; - }, - - /** - * Convert an HSL color value to RGB. - * - * Conversion formula based on - * - * - * Adapted from . - * - * Assumes `h`, `s`, and `l` are contained in the set `[0, 1]` and - * returns `r`, `g`, and `b` in the set `[0, 255]`. - * - * @param {number} h The hue - * @param {number} s The saturation - * @param {number} l The lightness - * @return {number[]} The RGB representation - */ - hslToRgb: function ( h, s, l ) { - var r, g, b, hue2rgb, q, p; - - if ( s === 0 ) { - r = g = b = l; // achromatic - } else { - hue2rgb = function ( p, q, t ) { - if ( t < 0 ) { - t += 1; - } - if ( t > 1 ) { - t -= 1; - } - if ( t < 1 / 6 ) { - return p + ( q - p ) * 6 * t; - } - if ( t < 1 / 2 ) { - return q; - } - if ( t < 2 / 3 ) { - return p + ( q - p ) * ( 2 / 3 - t ) * 6; - } - return p; - }; - - q = l < 0.5 ? l * ( 1 + s ) : l + s - l * s; - p = 2 * l - q; - r = hue2rgb( p, q, h + 1 / 3 ); - g = hue2rgb( p, q, h ); - b = hue2rgb( p, q, h - 1 / 3 ); - } - - return [ r * 255, g * 255, b * 255 ]; - }, - - /** - * Get a brighter or darker rgb() value string. - * - * Usage: - * - * $.colorUtil.getColorBrightness( 'red', +0.1 ); - * // > "rgb(255,50,50)" - * $.colorUtil.getColorBrightness( 'rgb(200,50,50)', -0.2 ); - * // > "rgb(118,29,29)" - * - * @param {Mixed} currentColor Current value in css - * @param {number} mod Wanted brightness modification between -1 and 1 - * @return {string} Like `'rgb(r,g,b)'` - */ - getColorBrightness: function ( currentColor, mod ) { - var rgbArr = $.colorUtil.getRGB( currentColor ), - hslArr = $.colorUtil.rgbToHsl( rgbArr[ 0 ], rgbArr[ 1 ], rgbArr[ 2 ] ); - rgbArr = $.colorUtil.hslToRgb( hslArr[ 0 ], hslArr[ 1 ], hslArr[ 2 ] + mod ); - - return 'rgb(' + - [ parseInt( rgbArr[ 0 ], 10 ), parseInt( rgbArr[ 1 ], 10 ), parseInt( rgbArr[ 2 ], 10 ) ].join( ',' ) + - ')'; - } - - }; - -}() ); diff --git a/resources/src/mediawiki.ForeignApi.core.js b/resources/src/mediawiki.ForeignApi.core.js index 4b6313b93c..83ea0ce003 100644 --- a/resources/src/mediawiki.ForeignApi.core.js +++ b/resources/src/mediawiki.ForeignApi.core.js @@ -59,7 +59,6 @@ } }, parameters: { - // Add 'origin' query parameter to all requests. origin: this.getOrigin() } }, @@ -77,17 +76,26 @@ * any). * * @protected - * @return {string} + * @return {string|undefined} */ CoreForeignApi.prototype.getOrigin = function () { - var origin; + var origin, apiUri, apiOrigin; if ( this.anonymous ) { return '*'; } + origin = location.protocol + '//' + location.hostname; if ( location.port ) { origin += ':' + location.port; } + + apiUri = new mw.Uri( this.apiUrl ); + apiOrigin = apiUri.protocol + '://' + apiUri.getAuthority(); + if ( origin === apiOrigin ) { + // requests are not cross-origin, omit parameter + return undefined; + } + return origin; }; @@ -101,10 +109,12 @@ if ( ajaxOptions.type === 'POST' ) { url = ( ajaxOptions && ajaxOptions.url ) || this.defaults.ajax.url; origin = ( parameters && parameters.origin ) || this.defaults.parameters.origin; - url += ( url.indexOf( '?' ) !== -1 ? '&' : '?' ) + - // Depending on server configuration, MediaWiki may forbid periods in URLs, due to an IE 6 - // XSS bug. So let's escape them here. See WebRequest::checkUrlExtension() and T30235. - 'origin=' + encodeURIComponent( origin ).replace( /\./g, '%2E' ); + if ( origin !== undefined ) { + url += ( url.indexOf( '?' ) !== -1 ? '&' : '?' ) + + // Depending on server configuration, MediaWiki may forbid periods in URLs, due to an IE 6 + // XSS bug. So let's escape them here. See WebRequest::checkUrlExtension() and T30235. + 'origin=' + encodeURIComponent( origin ).replace( /\./g, '%2E' ); + } newAjaxOptions = $.extend( {}, ajaxOptions, { url: url } ); } else { newAjaxOptions = ajaxOptions; diff --git a/resources/src/mediawiki.htmlform.checker.js b/resources/src/mediawiki.htmlform.checker.js index 33207d49a7..473635a53e 100644 --- a/resources/src/mediawiki.htmlform.checker.js +++ b/resources/src/mediawiki.htmlform.checker.js @@ -3,14 +3,6 @@ // FIXME: mw.htmlform.Element also sets this to empty object mw.htmlform = {}; - function debounce( delay, callback ) { - var timeout; - return function () { - clearTimeout( timeout ); - timeout = setTimeout( Function.prototype.apply.bind( callback, this, arguments ), delay ); - }; - } - /** * @class mw.htmlform.Checker */ @@ -60,7 +52,7 @@ if ( $extraElements ) { $e = $e.add( $extraElements ); } - $e.on( events, debounce( 1000, this.validate.bind( this ) ) ); + $e.on( events, mw.util.debounce( 1000, this.validate.bind( this ) ) ); return this; }; diff --git a/resources/src/mediawiki.legacy/shared.css b/resources/src/mediawiki.legacy/shared.css index 3b99696e9f..2c88bdc7cd 100644 --- a/resources/src/mediawiki.legacy/shared.css +++ b/resources/src/mediawiki.legacy/shared.css @@ -354,7 +354,7 @@ a.new { font-weight: bold; } -/* Error, warning and success messages */ +/* Error, warning, success and neutral messages */ .error, .warning, .success { @@ -373,41 +373,46 @@ a.new { color: #14866d; } +.messagebox, .errorbox, .warningbox, .successbox { + color: #000; + display: inline-block; + margin-bottom: 1em; border: 1px solid; padding: 0.5em 1em; - margin-bottom: 1em; - display: inline-block; } +.messagebox h2, .errorbox h2, .warningbox h2, .successbox h2 { color: inherit; - font-size: 1em; - font-weight: bold; display: inline; margin: 0 0.5em 0 0; border: 0; + font-size: 1em; + font-weight: bold; +} + +.messagebox { + background-color: #eaecf0; + border-color: #a2a9b1; } .errorbox { background-color: #fee7e6; - color: #000; border-color: #d33; } .warningbox { background-color: #fef6e7; - color: #000; border-color: #fc3; } .successbox { background-color: #d5fdf4; - color: #000; border-color: #14866d; } diff --git a/resources/src/mediawiki.util/util.js b/resources/src/mediawiki.util/util.js index e8823e1249..85216649e0 100644 --- a/resources/src/mediawiki.util/util.js +++ b/resources/src/mediawiki.util/util.js @@ -13,8 +13,7 @@ require( './jquery.accessKeyLabel.js' ); * @return {string} Encoded string */ function rawurlencode( str ) { - str = String( str ); - return encodeURIComponent( str ) + return encodeURIComponent( String( str ) ) .replace( /!/g, '%21' ).replace( /'/g, '%27' ).replace( /\(/g, '%28' ) .replace( /\)/g, '%29' ).replace( /\*/g, '%2A' ).replace( /~/g, '%7E' ); } @@ -59,33 +58,50 @@ util = { rawurlencode: rawurlencode, /** - * Encode string into HTML id compatible form suitable for use in HTML - * Analog to PHP Sanitizer::escapeIdForAttribute() + * Encode a string as CSS id, for use as HTML id attribute value. * - * @since 1.30 + * Analog to `Sanitizer::escapeIdForAttribute()` in PHP. * + * @since 1.30 * @param {string} str String to encode * @return {string} Encoded string */ escapeIdForAttribute: function ( str ) { - var mode = config.FragmentMode[ 0 ]; - - return escapeIdInternal( str, mode ); + return escapeIdInternal( str, config.FragmentMode[ 0 ] ); }, /** - * Encode string into HTML id compatible form suitable for use in links - * Analog to PHP Sanitizer::escapeIdForLink() + * Encode a string as URL fragment, for use as HTML anchor link. * - * @since 1.30 + * Analog to `Sanitizer::escapeIdForLink()` in PHP. * + * @since 1.30 * @param {string} str String to encode * @return {string} Encoded string */ escapeIdForLink: function ( str ) { - var mode = config.FragmentMode[ 0 ]; + return escapeIdInternal( str, config.FragmentMode[ 0 ] ); + }, - return escapeIdInternal( str, mode ); + /** + * Return a wrapper function that is debounced for the given duration. + * + * When it is first called, a timeout is scheduled. If before the timer + * is reached the wrapper is called again, it gets rescheduled for the + * same duration from now until it stops being called. The original function + * is called from the "tail" of such chain, with the last set of arguments. + * + * @since 1.34 + * @param {number} delay Time in milliseconds + * @param {Function} callback + * @return {Function} + */ + debounce: function ( delay, callback ) { + var timeout; + return function () { + clearTimeout( timeout ); + timeout = setTimeout( Function.prototype.apply.bind( callback, this, arguments ), delay ); + }; }, /** @@ -126,16 +142,15 @@ util = { * @return {string} Url of the page with name of `pageName` */ getUrl: function ( pageName, params ) { - var titleFragmentStart, url, query, - fragment = '', + var fragmentIdx, url, query, fragment, title = typeof pageName === 'string' ? pageName : mw.config.get( 'wgPageName' ); // Find any fragment - titleFragmentStart = title.indexOf( '#' ); - if ( titleFragmentStart !== -1 ) { - fragment = title.slice( titleFragmentStart + 1 ); + fragmentIdx = title.indexOf( '#' ); + if ( fragmentIdx !== -1 ) { + fragment = title.slice( fragmentIdx + 1 ); // Exclude the fragment from the page name - title = title.slice( 0, titleFragmentStart ); + title = title.slice( 0, fragmentIdx ); } // Produce query string @@ -152,7 +167,7 @@ util = { } // Append the encoded fragment - if ( fragment.length ) { + if ( fragment && fragment.length ) { url += '#' + util.escapeIdForLink( fragment ); } @@ -160,16 +175,14 @@ util = { }, /** - * Get address to a script in the wiki root. - * For index.php use `mw.config.get( 'wgScript' )`. + * Get URL to a MediaWiki entry point. * * @since 1.18 - * @param {string} str Name of script (e.g. 'api'), defaults to 'index' - * @return {string} Address to script (e.g. '/w/api.php' ) + * @param {string} [str="index"] Name of MW entry point (e.g. 'index' or 'api') + * @return {string} URL to the script file (e.g. '/w/api.php' ) */ wikiScript: function ( str ) { - str = str || 'index'; - if ( str === 'index' ) { + if ( !str || str === 'index' ) { return mw.config.get( 'wgScript' ); } else if ( str === 'load' ) { return config.LoadScript; @@ -195,7 +208,7 @@ util = { */ addCSS: function ( text ) { var s = mw.loader.addStyleTag( text ); - return s.sheet || s.styleSheet || s; + return s.sheet; }, /** @@ -440,15 +453,15 @@ util = { * @return {boolean} */ isIPv4Address: function ( address, allowBlock ) { - var block, RE_IP_BYTE, RE_IP_ADD; + var block, + RE_IP_BYTE = '(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|0?[0-9]?[0-9])', + RE_IP_ADD = '(?:' + RE_IP_BYTE + '\\.){3}' + RE_IP_BYTE; if ( typeof address !== 'string' ) { return false; } block = allowBlock ? '(?:\\/(?:3[0-2]|[12]?\\d))?' : ''; - RE_IP_BYTE = '(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|0?[0-9]?[0-9])'; - RE_IP_ADD = '(?:' + RE_IP_BYTE + '\\.){3}' + RE_IP_BYTE; return ( new RegExp( '^' + RE_IP_ADD + block + '$' ).test( address ) ); }, diff --git a/tests/phpunit/MediaWikiIntegrationTestCase.php b/tests/phpunit/MediaWikiIntegrationTestCase.php index b738312725..ecd5c05b17 100644 --- a/tests/phpunit/MediaWikiIntegrationTestCase.php +++ b/tests/phpunit/MediaWikiIntegrationTestCase.php @@ -1832,11 +1832,16 @@ abstract class MediaWikiIntegrationTestCase extends PHPUnit\Framework\TestCase { 'revision_actor_temp', 'slots', 'content', 'content_models', 'slot_roles', 'change_tag', ]; + $loggingTables = [ + 'logging', 'log_search', 'change_tag', + ]; $coreDBDataTables = array_merge( $userTables, $pageTables ); - // If any of the user or page tables were marked as used, we should clear all of them. + // some groups of tables are connected such that if any is used, all should be cleared + $extraTables = []; if ( array_intersect( $tablesUsed, $userTables ) ) { - $tablesUsed = array_unique( array_merge( $tablesUsed, $userTables ) ); + $extraTables[] = $userTables; + TestUserRegistry::clear(); // Reset $wgUser, which is probably 127.0.0.1, as its loaded data is probably not valid @@ -1846,7 +1851,13 @@ abstract class MediaWikiIntegrationTestCase extends PHPUnit\Framework\TestCase { $wgUser->clearInstanceCache( $wgUser->mFrom ); } if ( array_intersect( $tablesUsed, $pageTables ) ) { - $tablesUsed = array_unique( array_merge( $tablesUsed, $pageTables ) ); + $extraTables[] = $pageTables; + } + if ( array_intersect( $tablesUsed, $loggingTables ) ) { + $extraTables[] = $loggingTables; + } + if ( $extraTables !== [] ) { + $tablesUsed = array_unique( array_merge( $tablesUsed, ...$extraTables ) ); } // Postgres uses mwuser/pagecontent diff --git a/tests/phpunit/data/media/jpeg-xmp-nullchar.jpg b/tests/phpunit/data/media/jpeg-xmp-nullchar.jpg new file mode 100644 index 0000000000..76ae2b486c Binary files /dev/null and b/tests/phpunit/data/media/jpeg-xmp-nullchar.jpg differ diff --git a/tests/phpunit/includes/Revision/RenderedRevisionTest.php b/tests/phpunit/includes/Revision/RenderedRevisionTest.php index 96658678ba..7115515e8a 100644 --- a/tests/phpunit/includes/Revision/RenderedRevisionTest.php +++ b/tests/phpunit/includes/Revision/RenderedRevisionTest.php @@ -4,6 +4,7 @@ namespace MediaWiki\Tests\Revision; use Content; use Language; +use MediaWiki\MediaWikiServices; use MediaWiki\Revision\MutableRevisionRecord; use MediaWiki\Revision\MutableRevisionSlots; use MediaWiki\Revision\RenderedRevision; @@ -122,7 +123,9 @@ class RenderedRevisionTest extends MediaWikiTestCase { $mock->expects( $this->any() ) ->method( 'userCan' ) ->willReturnCallback( function ( $perm, User $user ) use ( $mock ) { - return $user->isAllowed( $perm ); + return MediaWikiServices::getInstance() + ->getPermissionManager() + ->userHasRight( $user, $perm ); } ); return $mock; diff --git a/tests/phpunit/includes/api/ApiRevisionDeleteTest.php b/tests/phpunit/includes/api/ApiRevisionDeleteTest.php index 5dcea65fa7..7dc63fbe9e 100644 --- a/tests/phpunit/includes/api/ApiRevisionDeleteTest.php +++ b/tests/phpunit/includes/api/ApiRevisionDeleteTest.php @@ -1,5 +1,8 @@ assertTrue( $item['texthidden'], 'texthidden' ); $this->assertEquals( $item['id'], $revid ); } + + public function testPartiallyBlockedPage() { + $this->setExpectedApiException( 'apierror-blocked-partial' ); + + $user = static::getTestSysop()->getUser(); + + $block = new DatabaseBlock( [ + 'address' => $user, + 'by' => static::getTestSysop()->getUser()->getId(), + 'sitewide' => false, + ] ); + + $block->setRestrictions( [ + new PageRestriction( 0, Title::newFromText( self::$page )->getArticleID() ) + ] ); + $block->insert(); + + $revid = array_shift( $this->revs ); + + $this->doApiRequest( [ + 'action' => 'revisiondelete', + 'type' => 'revision', + 'target' => self::$page, + 'ids' => $revid, + 'hide' => 'content|user|comment', + 'token' => $user->getEditToken(), + ] ); + } } diff --git a/tests/phpunit/includes/block/BlockManagerTest.php b/tests/phpunit/includes/block/BlockManagerTest.php index d4133b7f93..6a00e6735a 100644 --- a/tests/phpunit/includes/block/BlockManagerTest.php +++ b/tests/phpunit/includes/block/BlockManagerTest.php @@ -54,8 +54,6 @@ class BlockManagerTest extends MediaWikiTestCase { BlockManager::$constructorOptions, MediaWikiServices::getInstance()->getMainConfig() ), - $this->user, - $this->user->getRequest(), MediaWikiServices::getInstance()->getPermissionManager() ]; } diff --git a/tests/phpunit/includes/media/JpegMetadataExtractorTest.php b/tests/phpunit/includes/media/JpegMetadataExtractorTest.php index 6c56510170..4a0a6d0cad 100644 --- a/tests/phpunit/includes/media/JpegMetadataExtractorTest.php +++ b/tests/phpunit/includes/media/JpegMetadataExtractorTest.php @@ -1,7 +1,7 @@ assertEquals( $expected, bin2hex( $res['PSIR'][0] ) ); } + public function testXMPExtractionNullChar() { + $res = JpegMetadataExtractor::segmentSplitter( $this->filePath . 'jpeg-xmp-nullchar.jpg' ); + $expected = file_get_contents( $this->filePath . 'jpeg-xmp-psir.xmp' ); + $this->assertEquals( $expected, $res['XMP'] ); + } + public function testXMPExtractionAltAppId() { $res = JpegMetadataExtractor::segmentSplitter( $this->filePath . 'jpeg-xmp-alt.jpg' ); $expected = file_get_contents( $this->filePath . 'jpeg-xmp-psir.xmp' ); diff --git a/tests/phpunit/includes/preferences/DefaultPreferencesFactoryTest.php b/tests/phpunit/includes/preferences/DefaultPreferencesFactoryTest.php index e7f7067adb..a45944167a 100644 --- a/tests/phpunit/includes/preferences/DefaultPreferencesFactoryTest.php +++ b/tests/phpunit/includes/preferences/DefaultPreferencesFactoryTest.php @@ -2,6 +2,7 @@ use MediaWiki\Auth\AuthManager; use MediaWiki\MediaWikiServices; +use MediaWiki\Permissions\PermissionManager; use MediaWiki\Preferences\DefaultPreferencesFactory; use Wikimedia\TestingAccessWrapper; @@ -49,9 +50,10 @@ class DefaultPreferencesFactoryTest extends \MediaWikiTestCase { /** * Get a basic PreferencesFactory for testing with. + * @param PermissionManager|null $manager * @return DefaultPreferencesFactory */ - protected function getPreferencesFactory() { + protected function getPreferencesFactory( PermissionManager $manager = null ) { $mockNsInfo = $this->createMock( NamespaceInfo::class ); $mockNsInfo->method( 'getValidNamespaces' )->willReturn( [ NS_MAIN, NS_TALK, NS_USER, NS_USER_TALK @@ -59,13 +61,16 @@ class DefaultPreferencesFactoryTest extends \MediaWikiTestCase { $mockNsInfo->expects( $this->never() ) ->method( $this->anythingBut( 'getValidNamespaces', '__destruct' ) ); + $mockPermissionManager = $manager ?? $this->createMock( PermissionManager::class ); + return new DefaultPreferencesFactory( new LoggedServiceOptions( self::$serviceOptionsAccessLog, DefaultPreferencesFactory::$constructorOptions, $this->config ), new Language(), AuthManager::singleton(), MediaWikiServices::getInstance()->getLinkRenderer(), - $mockNsInfo + $mockNsInfo, + $mockPermissionManager ); } @@ -88,7 +93,9 @@ class DefaultPreferencesFactoryTest extends \MediaWikiTestCase { * @dataProvider emailAuthenticationProvider */ public function testEmailAuthentication( $user, $cssClass ) { - $prefs = $this->getPreferencesFactory()->getFormDescriptor( $user, $this->context ); + $pm = $this->createMock( PermissionManager::class ); + $pm->method( 'userHasRight' )->willReturn( true ); + $prefs = $this->getPreferencesFactory( $pm )->getFormDescriptor( $user, $this->context ); $this->assertArrayHasKey( 'cssclass', $prefs['emailauthentication'] ); $this->assertEquals( $cssClass, $prefs['emailauthentication']['cssclass'] ); } @@ -100,16 +107,18 @@ class DefaultPreferencesFactoryTest extends \MediaWikiTestCase { $userMock = $this->getMockBuilder( User::class ) ->disableOriginalConstructor() ->getMock(); - $userMock->method( 'isAllowed' ) - ->willReturn( false ); $userMock->method( 'getEffectiveGroups' ) ->willReturn( [] ); $userMock->method( 'getGroupMemberships' ) ->willReturn( [] ); $userMock->method( 'getOptions' ) ->willReturn( [ 'test' => 'yes' ] ); - - $prefs = $this->getPreferencesFactory()->getFormDescriptor( $userMock, $this->context ); + $pm = $this->createMock( PermissionManager::class ); + $pm->method( 'userHasRight' ) + ->will( $this->returnValueMap( [ + [ $userMock, 'editmyoptions', true ] + ] ) ); + $prefs = $this->getPreferencesFactory( $pm )->getFormDescriptor( $userMock, $this->context ); $this->assertArrayNotHasKey( 'showrollbackconfirmation', $prefs ); } @@ -120,16 +129,19 @@ class DefaultPreferencesFactoryTest extends \MediaWikiTestCase { $userMock = $this->getMockBuilder( User::class ) ->disableOriginalConstructor() ->getMock(); - $userMock->method( 'isAllowed' ) - ->willReturn( true ); $userMock->method( 'getEffectiveGroups' ) ->willReturn( [] ); $userMock->method( 'getGroupMemberships' ) ->willReturn( [] ); $userMock->method( 'getOptions' ) ->willReturn( [ 'test' => 'yes' ] ); - - $prefs = $this->getPreferencesFactory()->getFormDescriptor( $userMock, $this->context ); + $pm = $this->createMock( PermissionManager::class ); + $pm->method( 'userHasRight' ) + ->will( $this->returnValueMap( [ + [ $userMock, 'editmyoptions', true ], + [ $userMock, 'rollback', true ] + ] ) ); + $prefs = $this->getPreferencesFactory( $pm )->getFormDescriptor( $userMock, $this->context ); $this->assertArrayHasKey( 'showrollbackconfirmation', $prefs ); $this->assertEquals( 'rendering/advancedrendering', @@ -181,10 +193,6 @@ class DefaultPreferencesFactoryTest extends \MediaWikiTestCase { ->getMock(); $userMock->method( 'getOptions' ) ->willReturn( $oldOptions ); - $userMock->method( 'isAllowedAny' ) - ->willReturn( true ); - $userMock->method( 'isAllowed' ) - ->willReturn( true ); $userMock->expects( $this->exactly( 2 ) ) ->method( 'setOption' ) @@ -193,18 +201,25 @@ class DefaultPreferencesFactoryTest extends \MediaWikiTestCase { [ $this->equalTo( 'option' ), $this->equalTo( $newOptions[ 'option' ] ) ] ); - $form->expects( $this->any() ) - ->method( 'getModifiedUser' ) + $form->method( 'getModifiedUser' ) ->willReturn( $userMock ); - $form->expects( $this->any() ) - ->method( 'getContext' ) + $form->method( 'getContext' ) ->willReturn( $this->context ); - $form->expects( $this->any() ) - ->method( 'getConfig' ) + $form->method( 'getConfig' ) ->willReturn( $configMock ); + $pm = $this->createMock( PermissionManager::class ); + $pm->method( 'userHasAnyRight' ) + ->will( $this->returnValueMap( [ + [ $userMock, 'editmyprivateinfo', 'editmyoptions', true ] + ] ) ); + $pm->method( 'userHasRight' ) + ->will( $this->returnValueMap( [ + [ $userMock, 'editmyoptions', true ] + ] ) ); + $this->setTemporaryHook( 'PreferencesFormPreSave', function ( $formData, $form, $user, &$result, $oldUserOptions ) use ( $newOptions, $oldOptions, $userMock ) { @@ -220,7 +235,7 @@ class DefaultPreferencesFactoryTest extends \MediaWikiTestCase { ); /** @var DefaultPreferencesFactory $factory */ - $factory = TestingAccessWrapper::newFromObject( $this->getPreferencesFactory() ); + $factory = TestingAccessWrapper::newFromObject( $this->getPreferencesFactory( $pm ) ); $factory->saveFormData( $newOptions, $form, [] ); } @@ -233,7 +248,14 @@ class DefaultPreferencesFactoryTest extends \MediaWikiTestCase { // Test a string with leading zeros (i.e. not octal) and spaces. $this->context->getRequest()->setVal( 'wprclimit', ' 0012 ' ); $user = new User; - $form = $this->getPreferencesFactory()->getForm( $user, $this->context ); + $pm = $this->createMock( PermissionManager::class ); + $pm->method( 'userHasAnyRight' ) + ->willReturn( true ); + $pm->method( 'userHasRight' ) + ->will( $this->returnValueMap( [ + [ $user, 'editmyoptions', true ] + ] ) ); + $form = $this->getPreferencesFactory( $pm )->getForm( $user, $this->context ); $form->show(); $form->trySubmit(); $this->assertEquals( 12, $user->getOption( 'rclimit' ) ); diff --git a/tests/phpunit/includes/session/SessionManagerTest.php b/tests/phpunit/includes/session/SessionManagerTest.php index cd0867d2ef..b2f525d741 100644 --- a/tests/phpunit/includes/session/SessionManagerTest.php +++ b/tests/phpunit/includes/session/SessionManagerTest.php @@ -259,14 +259,14 @@ class SessionManagerTest extends MediaWikiTestCase { try { $manager->getSessionForRequest( $request ); $this->fail( 'Expcected exception not thrown' ); - } catch ( \OverflowException $ex ) { + } catch ( SessionOverflowException $ex ) { $this->assertStringStartsWith( 'Multiple sessions for this request tied for top priority: ', $ex->getMessage() ); - $this->assertCount( 2, $ex->sessionInfos ); - $this->assertContains( $request->info1, $ex->sessionInfos ); - $this->assertContains( $request->info2, $ex->sessionInfos ); + $this->assertCount( 2, $ex->getSessionInfos() ); + $this->assertContains( $request->info1, $ex->getSessionInfos() ); + $this->assertContains( $request->info2, $ex->getSessionInfos() ); } $this->assertFalse( $request->unpersist1 ); $this->assertFalse( $request->unpersist2 ); diff --git a/tests/phpunit/includes/specials/SpecialBlankPageTest.php b/tests/phpunit/includes/specials/SpecialBlankPageTest.php index 879acfece1..5435afa36e 100644 --- a/tests/phpunit/includes/specials/SpecialBlankPageTest.php +++ b/tests/phpunit/includes/specials/SpecialBlankPageTest.php @@ -8,6 +8,11 @@ */ class SpecialBlankPageTest extends SpecialPageTestBase { + protected function setUp() { + parent::setUp(); + $this->setUserLang( 'qqx' ); + } + /** * Returns a new instance of the special page under test. * @@ -19,7 +24,7 @@ class SpecialBlankPageTest extends SpecialPageTestBase { public function testHasWikiMsg() { list( $html, ) = $this->executeSpecialPage(); - $this->assertContains( wfMessage( 'intentionallyblankpage' )->text(), $html ); + $this->assertContains( '(intentionallyblankpage)', $html ); } } diff --git a/tests/phpunit/includes/user/LocalIdLookupTest.php b/tests/phpunit/includes/user/LocalIdLookupTest.php index e38d77b72b..0e4674455c 100644 --- a/tests/phpunit/includes/user/LocalIdLookupTest.php +++ b/tests/phpunit/includes/user/LocalIdLookupTest.php @@ -1,6 +1,7 @@ getPermissionManager(); $user1 = $this->getLookupUser(); $user2 = User::newFromName( 'UTLocalIdLookup2' ); - $this->assertTrue( $user1->isAllowed( 'hideuser' ), 'sanity check' ); - $this->assertFalse( $user2->isAllowed( 'hideuser' ), 'sanity check' ); + $this->assertTrue( $permissionManager->userHasRight( $user1, 'hideuser' ), 'sanity check' ); + $this->assertFalse( $permissionManager->userHasRight( $user2, 'hideuser' ), 'sanity check' ); $this->assertSame( [], $lookup->lookupCentralIds( [] ) ); @@ -76,11 +77,12 @@ class LocalIdLookupTest extends MediaWikiTestCase { public function testLookupUserNames() { $lookup = new LocalIdLookup(); + $permissionManager = MediaWikiServices::getInstance()->getPermissionManager(); $user1 = $this->getLookupUser(); $user2 = User::newFromName( 'UTLocalIdLookup2' ); - $this->assertTrue( $user1->isAllowed( 'hideuser' ), 'sanity check' ); - $this->assertFalse( $user2->isAllowed( 'hideuser' ), 'sanity check' ); + $this->assertTrue( $permissionManager->userHasRight( $user1, 'hideuser' ), 'sanity check' ); + $this->assertFalse( $permissionManager->userHasRight( $user2, 'hideuser' ), 'sanity check' ); $this->assertSame( [], $lookup->lookupUserNames( [] ) ); diff --git a/tests/phpunit/includes/user/PasswordResetTest.php b/tests/phpunit/includes/user/PasswordResetTest.php index b0c0fec6b2..4a7aa05b14 100644 --- a/tests/phpunit/includes/user/PasswordResetTest.php +++ b/tests/phpunit/includes/user/PasswordResetTest.php @@ -4,6 +4,7 @@ use MediaWiki\Auth\AuthManager; use MediaWiki\Block\DatabaseBlock; use MediaWiki\Block\CompositeBlock; use MediaWiki\Block\SystemBlock; +use MediaWiki\Permissions\PermissionManager; /** * @covers PasswordReset @@ -30,16 +31,19 @@ class PasswordResetTest extends MediaWikiTestCase { $user->expects( $this->any() )->method( 'getName' )->willReturn( 'Foo' ); $user->expects( $this->any() )->method( 'getBlock' )->willReturn( $block ); $user->expects( $this->any() )->method( 'getGlobalBlock' )->willReturn( $globalBlock ); - $user->expects( $this->any() )->method( 'isAllowed' ) - ->will( $this->returnCallback( function ( $perm ) use ( $canEditPrivate ) { - if ( $perm === 'editmyprivateinfo' ) { - return $canEditPrivate; - } else { - $this->fail( 'Unexpected permission check' ); - } - } ) ); - $passwordReset = new PasswordReset( $config, $authManager ); + $permissionManager = $this->getMockBuilder( PermissionManager::class ) + ->disableOriginalConstructor() + ->getMock(); + $permissionManager->method( 'userHasRight' ) + ->with( $user, 'editmyprivateinfo' ) + ->willReturn( $canEditPrivate ); + + $passwordReset = new PasswordReset( + $config, + $authManager, + $permissionManager + ); $this->assertSame( $isAllowed, $passwordReset->isAllowed( $user )->isGood() ); } @@ -204,9 +208,16 @@ class PasswordResetTest extends MediaWikiTestCase { $request->setIP( '1.2.3.4' ); $performingUser = $this->getMockBuilder( User::class )->getMock(); $performingUser->expects( $this->any() )->method( 'getRequest' )->willReturn( $request ); - $performingUser->expects( $this->any() )->method( 'isAllowed' )->willReturn( true ); $performingUser->expects( $this->any() )->method( 'getName' )->willReturn( 'Performer' ); + $permissionManager = $this->getMockBuilder( PermissionManager::class ) + ->disableOriginalConstructor() + ->getMock(); + $permissionManager->expects( $this->once() ) + ->method( 'userHasRight' ) + ->with( $performingUser, 'editmyprivateinfo' ) + ->willReturn( true ); + $targetUser1 = $this->getMockBuilder( User::class )->getMock(); $targetUser2 = $this->getMockBuilder( User::class )->getMock(); $targetUser1->expects( $this->any() )->method( 'getName' )->willReturn( 'User1' ); @@ -217,7 +228,8 @@ class PasswordResetTest extends MediaWikiTestCase { $targetUser2->expects( $this->any() )->method( 'getEmail' )->willReturn( 'foo@bar.baz' ); $passwordReset = $this->getMockBuilder( PasswordReset::class ) - ->setMethods( [ 'getUsersByEmail' ] )->setConstructorArgs( [ $config, $authManager ] ) + ->setConstructorArgs( [ $config, $authManager, $permissionManager ] ) + ->setMethods( [ 'getUsersByEmail' ] ) ->getMock(); $passwordReset->expects( $this->any() )->method( 'getUsersByEmail' )->with( 'foo@bar.baz' ) ->willReturn( [ $targetUser1, $targetUser2 ] ); diff --git a/tests/phpunit/includes/user/UserGroupMembershipTest.php b/tests/phpunit/includes/user/UserGroupMembershipTest.php index 4862747b4f..6f575789f5 100644 --- a/tests/phpunit/includes/user/UserGroupMembershipTest.php +++ b/tests/phpunit/includes/user/UserGroupMembershipTest.php @@ -1,5 +1,7 @@ clearInstanceCache(); $this->assertContains( 'unittesters', $user->getGroups() ); $this->assertArrayHasKey( 'unittesters', $user->getGroupMemberships() ); - $this->assertTrue( $user->isAllowed( 'runtest' ) ); + $this->assertTrue( MediaWikiServices::getInstance() + ->getPermissionManager() + ->userHasRight( $user, 'runtest' ) ); // try updating without allowUpdate. Should fail $ugm = new UserGroupMembership( $user->getId(), 'unittesters', $this->expiryTime ); @@ -72,7 +76,9 @@ class UserGroupMembershipTest extends MediaWikiTestCase { $user->clearInstanceCache(); $this->assertContains( 'unittesters', $user->getGroups() ); $this->assertArrayHasKey( 'unittesters', $user->getGroupMemberships() ); - $this->assertTrue( $user->isAllowed( 'runtest' ) ); + $this->assertTrue( MediaWikiServices::getInstance() + ->getPermissionManager() + ->userHasRight( $user, 'runtest' ) ); // try removing the group $ugm->delete(); @@ -81,7 +87,9 @@ class UserGroupMembershipTest extends MediaWikiTestCase { $this->logicalNot( $this->contains( 'unittesters' ) ) ); $this->assertThat( $user->getGroupMemberships(), $this->logicalNot( $this->arrayHasKey( 'unittesters' ) ) ); - $this->assertFalse( $user->isAllowed( 'runtest' ) ); + $this->assertFalse( MediaWikiServices::getInstance() + ->getPermissionManager() + ->userHasRight( $user, 'runtest' ) ); // check that the user group is now in user_former_groups $this->assertContains( 'unittesters', $user->getFormerGroups() ); diff --git a/tests/phpunit/includes/user/UserTest.php b/tests/phpunit/includes/user/UserTest.php index 3005ae9b2e..2a4ba4bc06 100644 --- a/tests/phpunit/includes/user/UserTest.php +++ b/tests/phpunit/includes/user/UserTest.php @@ -1488,10 +1488,6 @@ class UserTest extends MediaWikiTestCase { // logged in users should be inmune to cookie block of type ip/range $this->assertNull( $user->getBlock() ); - // cookie is being cleared - $cookies = $request->response()->getCookies(); - $this->assertEquals( '', $cookies['wikiBlockID']['value'] ); - // clean up $block->delete(); } diff --git a/tests/phpunit/maintenance/MWDoxygenFilterTest.php b/tests/phpunit/maintenance/MWDoxygenFilterTest.php index 22b5938daa..edb7618ea3 100644 --- a/tests/phpunit/maintenance/MWDoxygenFilterTest.php +++ b/tests/phpunit/maintenance/MWDoxygenFilterTest.php @@ -1,7 +1,7 @@ [ 'jquery.color', - 'jquery.colorUtil', 'jquery.getAttrs', 'jquery.highlightText', 'jquery.lengthLimit', diff --git a/tests/qunit/suites/resources/mediawiki.api/mediawiki.ForeignApi.test.js b/tests/qunit/suites/resources/mediawiki.api/mediawiki.ForeignApi.test.js index 541c61072d..22a3a4b436 100644 --- a/tests/qunit/suites/resources/mediawiki.api/mediawiki.ForeignApi.test.js +++ b/tests/qunit/suites/resources/mediawiki.api/mediawiki.ForeignApi.test.js @@ -29,4 +29,29 @@ return api.post( {} ); } ); + QUnit.test( 'origin is not included in same-origin GET requests', function ( assert ) { + var apiUrl = location.protocol + '//' + location.host + '/w/api.php', + api = new mw.ForeignApi( apiUrl ); + + this.server.respond( function ( request ) { + assert.strictEqual( request.url.match( /origin=.*?(?:&|$)/ ), null, 'origin is not included in GET requests' ); + request.respond( 200, { 'Content-Type': 'application/json' }, '[]' ); + } ); + + return api.get( {} ); + } ); + + QUnit.test( 'origin is not included in same-origin POST requests', function ( assert ) { + var apiUrl = location.protocol + '//' + location.host + '/w/api.php', + api = new mw.ForeignApi( apiUrl ); + + this.server.respond( function ( request ) { + assert.strictEqual( request.requestBody.match( /origin=.*?(?:&|$)/ ), null, 'origin is not included in POST request body' ); + assert.strictEqual( request.url.match( /origin=.*?(?:&|$)/ ), null, 'origin is not included in POST request URL, either' ); + request.respond( 200, { 'Content-Type': 'application/json' }, '[]' ); + } ); + + return api.post( {} ); + } ); + }() ); diff --git a/tests/qunit/suites/resources/mediawiki/mediawiki.util.test.js b/tests/qunit/suites/resources/mediawiki/mediawiki.util.test.js index 4f61abd186..a05b50b462 100644 --- a/tests/qunit/suites/resources/mediawiki/mediawiki.util.test.js +++ b/tests/qunit/suites/resources/mediawiki/mediawiki.util.test.js @@ -474,4 +474,27 @@ assert.strictEqual( mw.util.escapeRegExp( normal ), normal, 'Alphanumerals are left alone' ); } ); + + QUnit.test( 'debounce', function ( assert ) { + var fn, + q = [], + done = assert.async(); + + fn = mw.util.debounce( 0, function ( data ) { + q.push( data ); + } ); + + fn( 1 ); + fn( 2 ); + fn( 3 ); + + setTimeout( function () { + assert.deepEqual( + q, + [ 3 ], + 'Last one ran' + ); + done(); + } ); + } ); }() );