Merge "Introduce new schema flags and use them in RevisionStore."
authorjenkins-bot <jenkins-bot@gerrit.wikimedia.org>
Fri, 6 Jul 2018 17:53:44 +0000 (17:53 +0000)
committerGerrit Code Review <gerrit@wikimedia.org>
Fri, 6 Jul 2018 17:53:44 +0000 (17:53 +0000)
121 files changed:
.travis.yml
RELEASE-NOTES-1.32
includes/Block.php
includes/DefaultSettings.php
includes/EditPage.php
includes/GlobalFunctions.php
includes/MWNamespace.php
includes/MediaWikiServices.php
includes/MovePage.php
includes/OutputPage.php
includes/ServiceWiring.php
includes/Storage/DerivedPageDataUpdater.php
includes/Storage/PageUpdater.php
includes/Storage/RevisionStore.php
includes/api/ApiBase.php
includes/api/i18n/nl.json
includes/api/i18n/uk.json
includes/api/i18n/zh-hant.json
includes/cache/MessageCache.php
includes/db/CloneDatabase.php
includes/deferred/LinksUpdate.php
includes/diff/DifferenceEngine.php
includes/filerepo/file/ArchivedFile.php
includes/filerepo/file/LocalFile.php
includes/filerepo/file/OldLocalFile.php
includes/installer/i18n/uk.json
includes/libs/MapCacheLRU.php
includes/libs/ProcessCacheLRU.php
includes/libs/objectcache/MultiWriteBagOStuff.php
includes/libs/objectcache/RESTBagOStuff.php
includes/libs/rdbms/database/Database.php
includes/libs/rdbms/database/DatabaseSqlite.php
includes/libs/rdbms/loadbalancer/ILoadBalancer.php
includes/logging/LogEventsList.php
includes/logging/LogPager.php
includes/page/WikiPage.php
includes/resourceloader/ResourceLoader.php
includes/search/SearchMssql.php
includes/session/SessionProviderInterface.php
includes/shell/Shell.php
includes/specials/pagers/DeletedContribsPager.php
languages/Language.php
languages/data/Names.php
languages/i18n/ace.json
languages/i18n/ar.json
languages/i18n/ast.json
languages/i18n/be-tarask.json
languages/i18n/be.json
languages/i18n/bs.json
languages/i18n/ca.json
languages/i18n/ce.json
languages/i18n/ckb.json
languages/i18n/et.json
languages/i18n/eu.json
languages/i18n/fa.json
languages/i18n/frr.json
languages/i18n/fy.json
languages/i18n/he.json
languages/i18n/hr.json
languages/i18n/hu.json
languages/i18n/ia.json
languages/i18n/io.json
languages/i18n/is.json
languages/i18n/ja.json
languages/i18n/mg.json
languages/i18n/mni.json
languages/i18n/my.json
languages/i18n/nan.json
languages/i18n/nb.json
languages/i18n/nl.json
languages/i18n/nn.json
languages/i18n/pnb.json
languages/i18n/ps.json
languages/i18n/pt-br.json
languages/i18n/pt.json
languages/i18n/qqq.json
languages/i18n/qu.json
languages/i18n/ru.json
languages/i18n/sat.json
languages/i18n/skr-arab.json
languages/i18n/sr-ec.json
languages/i18n/sr-el.json
languages/i18n/te.json
languages/i18n/uk.json
languages/i18n/ur.json
languages/i18n/wa.json
languages/i18n/zh-hant.json
languages/messages/MessagesMni.php [new file with mode: 0644]
languages/messages/MessagesSa.php
maintenance/Maintenance.php
maintenance/categoryChangesAsRdf.php
maintenance/populateChangeTagDef.php
maintenance/storage/recompressTracked.php
maintenance/updateCollation.php
resources/Resources.php
resources/src/mediawiki.ForeignStructuredUpload.BookletLayout/BookletLayout.js
resources/src/mediawiki.Upload.BookletLayout/BookletLayout.css
resources/src/mediawiki.rcfilters/dm/mw.rcfilters.dm.ItemModel.js
resources/src/mediawiki.rcfilters/styles/mw.rcfilters.less
resources/src/mediawiki.rcfilters/styles/mw.rcfilters.ui.ChangesListWrapperWidget.highlightCircles.seenunseen.less
resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.FilterTagMultiselectWidget.js
resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.MenuSelectWidget.js
resources/src/mediawiki.special.changeslist.css
resources/src/mediawiki.special.preferences.styles.ooui.css [deleted file]
resources/src/mediawiki.special.preferences.styles.ooui.less [new file with mode: 0644]
resources/src/mediawiki.widgets/mw.widgets.TitleWidget.js
tests/integration/includes/shell/FirejailCommandTest.php
tests/parser/parserTests.txt
tests/phpunit/MediaWikiTestCase.php
tests/phpunit/includes/MWNamespaceTest.php
tests/phpunit/includes/MediaWikiServicesTest.php
tests/phpunit/includes/Storage/McrWriteBothRevisionStoreDbTest.php
tests/phpunit/includes/Storage/NoContentModelRevisionStoreDbTest.php
tests/phpunit/includes/Storage/PreMcrRevisionStoreDbTest.php
tests/phpunit/includes/db/LoadBalancerTest.php
tests/phpunit/includes/libs/MapCacheLRUTest.php
tests/phpunit/includes/libs/ProcessCacheLRUTest.php
tests/phpunit/includes/libs/objectcache/MultiWriteBagOStuffTest.php
tests/phpunit/includes/libs/rdbms/database/DatabaseTest.php
tests/phpunit/includes/page/WikiPageDbTestBase.php
tests/selenium/wdio-mediawiki/Util.js

index e15fc55..2fc6d64 100644 (file)
@@ -38,8 +38,11 @@ matrix:
     - env: dbtype=mysql dbuser=root
       php: hhvm-3.18
   allow_failures:
-    - php: hhvm-3.24
+    - php: 7.2
+    - env: dbtype=postgres dbuser=travis
+    - php: hhvm-3.18
     - php: hhvm-3.21
+    - php: hhvm-3.24
 
 services:
   - mysql
@@ -80,7 +83,8 @@ notifications:
   email: false
   irc:
     channels:
-      - "chat.freenode.net#mediawiki-feed"
+      - "chat.freenode.net#wikimedia-dev"
+    template:
+      - "%{repository}#%{build_number} (%{branch} - %{commit} %{author}): %{message} - %{build_url}"
     on_success: change
-    on_failure: change
-    skip_join: true
+    on_failure: always
index 5282236..c41e5b5 100644 (file)
@@ -10,6 +10,7 @@ production.
   have been removed.
 * The $wgUseAjax setting, deprecated in 1.31, is now ignored.
 * The $wgSiteSupportPage setting, unused since 1.5, was removed.
+* The $wgBrowserBlacklist setting, deprecated in 1.30, was removed.
 * The default quality of JPEG thumbnails generated by GD was reduced from 95 to
   80. The quality of JPEG thumbnails is now configurable through the new setting
   $wgJpegQuality (default 80). This aligns the quality to what ImageMagick uses.
@@ -97,6 +98,7 @@ because of Phabricator reports.
 * (T194047) Added language support for Shawiya, Latin script (shy-latn).
 * (T195940) Added language support for Batak Mandailing (btm).
 * (T137491) Added language support for Standard Moroccan Amazigh (zgh).
+* (T198132) Added language support for Manipuri (mni).
 
 === Breaking changes in 1.32 ===
 * $wgRequestTime, deprecated in 1.25, was removed. Use
@@ -133,6 +135,7 @@ because of Phabricator reports.
 * The jquery.footHovzer module, for mediawiki.debug, was removed.
 * The es5-shim module, empty and deprecated since 1.29, was removed.
 * the dom-level2-shim module, empty and deprecated since 1.29, was removed.
+* the json module, empty and deprecated since 1.29, was removed.
 * The mediawiki.widgets.visibleByteLimit module alias, deprecated in 1.32, was
   removed. Use mediawiki.widgets.visibleLengthLimit instead.
 * The jquery.farbtastic module, unused since 1.18, was removed.
@@ -169,6 +172,9 @@ because of Phabricator reports.
   use 'EditPageGetCheckboxesDefinition' instead.
 * Linker::getLinkColour() and DummyLinker::getLinkColour(), deprecated since
   1.28, were removed. LinkRenderer::getLinkClasses() should be used instead.
+* Wikimedia\Rdbms\LoadBalancer::getLaggedSlaveMode(), deprecated in 1.28, has
+  been removed. Use Wikimedia\Rdbms\LoadBalancer::getLaggedReplicaMode()
+  instead.
 * mw.widgets.CategoryMultiselectWidget now uses TagMultiselectWidget instead of
   CapsuleMultiselectWidget. The following methods may no longer be used:
   * setItemsFromData: Use setValue instead
@@ -225,6 +231,7 @@ because of Phabricator reports.
 * The 'jquery.hidpi' module (polyfill for IMG srcset) is deprecated.
 * ResourceLoaderStartUpModule::getStartupModules() and ::getLegacyModules()
   are deprecated. These concepts are obsolete and have no replacement.
+* String type for $lang of DifferenceEngine::setTextLanguage is deprecated.
 
 === Other changes in 1.32 ===
 * …
index 9567b06..a7b8035 100644 (file)
@@ -224,7 +224,7 @@ class Block {
                        'ipb_address',
                        'ipb_by',
                        'ipb_by_text',
-                       'ipb_by_actor' => $wgActorTableSchemaMigrationStage > MIGRATION_OLD ? 'ipb_by_actor' : null,
+                       'ipb_by_actor' => $wgActorTableSchemaMigrationStage > MIGRATION_OLD ? 'ipb_by_actor' : 'NULL',
                        'ipb_timestamp',
                        'ipb_auto',
                        'ipb_anon_only',
index e10561c..f3bc9cc 100644 (file)
@@ -3003,11 +3003,6 @@ $wgAllUnicodeFixes = false;
  */
 $wgLegacyEncoding = false;
 
-/**
- * @deprecated since 1.30, does nothing
- */
-$wgBrowserBlackList = [];
-
 /**
  * If set to true, the MediaWiki 1.4 to 1.5 schema conversion will
  * create stub reference rows in the text table instead of copying
@@ -7892,7 +7887,7 @@ $wgNewUserLog = true;
  * Maintain a log of page creations at Special:Log/create?
  * @since 1.32
  */
-$wgPageCreationLog = false;
+$wgPageCreationLog = true;
 
 /** @} */ # end logging }
 
index 9a8a4a6..de89ab4 100644 (file)
@@ -948,12 +948,7 @@ class EditPage {
                        } else {
                                // If we receive the last parameter of the request, we can fairly
                                // claim the POST request has not been truncated.
-
-                               // TODO: softened the check for cutover.  Once we determine
-                               // that it is safe, we should complete the transition by
-                               // removing the "edittime" clause.
-                               $this->incompleteForm = ( !$request->getVal( 'wpUltimateParam' )
-                                       && is_null( $this->edittime ) );
+                               $this->incompleteForm = !$request->getVal( 'wpUltimateParam' );
                        }
                        if ( $this->incompleteForm ) {
                                # If the form is incomplete, force to preview.
index d9996f4..d0229bc 100644 (file)
@@ -31,6 +31,7 @@ use MediaWiki\MediaWikiServices;
 use MediaWiki\Shell\Shell;
 use Wikimedia\ScopedCallback;
 use Wikimedia\Rdbms\DBReplicationWaitError;
+use Wikimedia\WrappedString;
 
 /**
  * Load an extension
@@ -3103,6 +3104,7 @@ function wfShorthandToInteger( $string = '', $default = -1 ) {
  * @return string The language code which complying with BCP 47 standards.
  */
 function wfBCP47( $code ) {
+       wfDeprecated( __METHOD__, '1.31' );
        return LanguageCode::bcp47( $code );
 }
 
index 73fdd82..1df5d51 100644 (file)
@@ -540,4 +540,26 @@ class MWNamespace {
 
                return $usableLevels;
        }
+
+       /**
+        * Returns the link type to be used for categories.
+        *
+        * This determines which section of a category page titles
+        * in the namespace will appear within.
+        *
+        * @since 1.32
+        * @param int $index Namespace index
+        * @return string One of 'subcat', 'file', 'page'
+        */
+       public static function getCategoryLinkType( $index ) {
+               self::isMethodValidFor( $index, __METHOD__ );
+
+               if ( $index == NS_CATEGORY ) {
+                       return 'subcat';
+               } elseif ( $index == NS_FILE ) {
+                       return 'file';
+               } else {
+                       return 'page';
+               }
+       }
 }
index ac15574..a756d50 100644 (file)
@@ -21,6 +21,8 @@ use MediaWiki\Storage\NameTableStore;
 use MediaWiki\Storage\RevisionFactory;
 use MediaWiki\Storage\RevisionLookup;
 use MediaWiki\Storage\RevisionStore;
+use OldRevisionImporter;
+use UploadRevisionImporter;
 use Wikimedia\Rdbms\LBFactory;
 use LinkCache;
 use Wikimedia\Rdbms\LoadBalancer;
@@ -464,6 +466,14 @@ class MediaWikiServices extends ServiceContainer {
                return $this->getService( 'StatsdDataFactory' );
        }
 
+       /**
+        * @since 1.32
+        * @return IBufferingStatsdDataFactory
+        */
+       public function getPerDbNameStatsdDataFactory() {
+               return $this->getService( 'PerDbNameStatsdDataFactory' );
+       }
+
        /**
         * @since 1.27
         * @return EventRelayerGroup
@@ -829,6 +839,22 @@ class MediaWikiServices extends ServiceContainer {
                return $this->getService( 'ActorMigration' );
        }
 
+       /**
+        * @since 1.32
+        * @return UploadRevisionImporter
+        */
+       public function getUploadRevisionImporter() {
+               return $this->getService( 'UploadRevisionImporter' );
+       }
+
+       /**
+        * @since 1.32
+        * @return OldRevisionImporter
+        */
+       public function getOldRevisionImporter() {
+               return $this->getService( 'OldRevisionImporter' );
+       }
+
        ///////////////////////////////////////////////////////////////////////////
        // NOTE: When adding a service getter here, don't forget to add a test
        // case for it in MediaWikiServicesTest::provideGetters() and in
index 614ea7d..ec44b6e 100644 (file)
@@ -280,13 +280,7 @@ class MovePage {
                        [ 'cl_from' => $pageid ],
                        __METHOD__
                );
-               if ( $this->newTitle->getNamespace() == NS_CATEGORY ) {
-                       $type = 'subcat';
-               } elseif ( $this->newTitle->getNamespace() == NS_FILE ) {
-                       $type = 'file';
-               } else {
-                       $type = 'page';
-               }
+               $type = MWNamespace::getCategoryLinkType( $this->newTitle->getNamespace() );
                foreach ( $prefixes as $prefixRow ) {
                        $prefix = $prefixRow->cl_sortkey_prefix;
                        $catTo = $prefixRow->cl_to;
index 0b2ba40..4ce49fd 100644 (file)
@@ -24,6 +24,7 @@ use MediaWiki\Linker\LinkTarget;
 use MediaWiki\Logger\LoggerFactory;
 use MediaWiki\MediaWikiServices;
 use MediaWiki\Session\SessionManager;
+use Wikimedia\Rdbms\IResultWrapper;
 use Wikimedia\RelPath;
 use Wikimedia\WrappedString;
 use Wikimedia\WrappedStringList;
@@ -1337,7 +1338,7 @@ class OutputPage extends ContextSource {
 
        /**
         * @param array $categories
-        * @return bool|ResultWrapper
+        * @return bool|IResultWrapper
         */
        protected function addCategoryLinksToLBAndGetResult( array $categories ) {
                # Add the links to a LinkBatch
index 425b789..6da537d 100644 (file)
@@ -128,6 +128,14 @@ return [
                );
        },
 
+       'PerDbNameStatsdDataFactory' => function ( MediaWikiServices $services ) {
+               $config = $services->getMainConfig();
+               $wiki = $config->get( 'DBname' );
+               return new BufferingStatsdDataFactory(
+                       rtrim( $services->getMainConfig()->get( 'StatsdMetricPrefix' ), '.' ) . $wiki
+               );
+       },
+
        'EventRelayerGroup' => function ( MediaWikiServices $services ) {
                return new EventRelayerGroup( $services->getMainConfig()->get( 'EventRelayerConfig' ) );
        },
index cc72754..8da812a 100644 (file)
@@ -1310,7 +1310,7 @@ class DerivedPageDataUpdater implements IDBAccessObject {
                                        // stale data from REPEATABLE-READ snapshots.
                                        // HACK: But don't use a fresh connection in unit tests, since it would not have
                                        // the fake tables. This should be handled by the LoadBalancer!
-                                       $flags = defined( 'MW_PHPUNIT_TEST' ) ? 0 : $lb::CONN_TRX_AUTO;
+                                       $flags = defined( 'MW_PHPUNIT_TEST' ) ? 0 : $lb::CONN_TRX_AUTOCOMMIT;
                                        $db = $lb->getConnectionRef( $dbIndex, [], $this->getWikiId(), $flags );
 
                                        return 1 + (int)$db->selectField(
index 7900210..2376d16 100644 (file)
@@ -45,6 +45,7 @@ use User;
 use Wikimedia\Assert\Assert;
 use Wikimedia\Rdbms\DBConnRef;
 use Wikimedia\Rdbms\DBUnexpectedError;
+use Wikimedia\Rdbms\IDatabase;
 use Wikimedia\Rdbms\LoadBalancer;
 use WikiPage;
 
@@ -639,7 +640,7 @@ class PageUpdater {
                // NOTE: This grabs the parent revision as the CAS token, if grabParentRevision
                // wasn't called yet. If the page is modified by another process before we are done with
                // it, this method must fail (with status 'edit-conflict')!
-               // NOTE: The parent revision may be different from $this->baseRevisionId.
+               // NOTE: The parent revision may be different from $this->originalRevisionId.
                $this->grabParentRevision();
                $flags = $this->checkFlags( $flags );
 
@@ -922,7 +923,6 @@ class PageUpdater {
 
                // XXX: we may want a flag that allows a null revision to be forced!
                $changed = $this->derivedDataUpdater->isChange();
-               $mainContent = $newRevisionRecord->getContent( 'main' );
 
                $dbw = $this->getDBConnectionRef( DB_MASTER );
 
@@ -991,22 +991,19 @@ class PageUpdater {
                        $user->incEditCount();
 
                        $dbw->endAtomic( __METHOD__ );
-               } else {
-                       // T34948: revision ID must be set to page {{REVISIONID}} and
-                       // related variables correctly. Likewise for {{REVISIONUSER}} (T135261).
-                       // Since we don't insert a new revision into the database, the least
-                       // error-prone way is to reuse given old revision.
-                       $newRevisionRecord = $oldRev;
-                       $newLegacyRevision = new Revision( $newRevisionRecord );
-               }
 
-               if ( $changed ) {
                        // Return the new revision to the caller
                        $status->value['revision-record'] = $newRevisionRecord;
 
                        // TODO: globally replace usages of 'revision' with getNewRevision()
                        $status->value['revision'] = $newLegacyRevision;
                } else {
+                       // T34948: revision ID must be set to page {{REVISIONID}} and
+                       // related variables correctly. Likewise for {{REVISIONUSER}} (T135261).
+                       // Since we don't insert a new revision into the database, the least
+                       // error-prone way is to reuse given old revision.
+                       $newRevisionRecord = $oldRev;
+
                        $status->warning( 'edit-no-change' );
                        // Update page_touched as updateRevisionOn() was not called.
                        // Other cache updates are managed in WikiPage::onArticleEdit()
@@ -1021,30 +1018,15 @@ class PageUpdater {
                // importantly, before the parser cache has been updated. This would cause the
                // content to be parsed a second time, or may cause stale content to be shown.
                DeferredUpdates::addUpdate(
-                       new AtomicSectionUpdate(
+                       $this->getAtomicSectionUpdate(
                                $dbw,
-                               __METHOD__,
-                               function () use (
-                                       $wikiPage, $newRevisionRecord, $newLegacyRevision, $user, $mainContent,
-                                       $summary, $flags, $changed, $status
-                               ) {
-                                       // Update links tables, site stats, etc.
-                                       $this->derivedDataUpdater->prepareUpdate(
-                                               $newRevisionRecord,
-                                               [
-                                                       'changed' => $changed,
-                                               ]
-                                       );
-                                       $this->derivedDataUpdater->doUpdates();
-
-                                       // Trigger post-save hook
-                                       // TODO: replace legacy hook!
-                                       // TODO: avoid pass-by-reference, see T193950
-                                       $params = [ &$wikiPage, &$user, $mainContent, $summary->text, $flags & EDIT_MINOR,
-                                               null, null, &$flags, $newLegacyRevision, &$status, $this->getOriginalRevisionId(),
-                                               $this->undidRevId ];
-                                       Hooks::run( 'PageContentSaveComplete', $params );
-                               }
+                               $wikiPage,
+                               $newRevisionRecord,
+                               $user,
+                               $summary,
+                               $flags,
+                               $status,
+                               [ 'changed' => $changed, ]
                        ),
                        DeferredUpdates::PRESEND
                );
@@ -1162,47 +1144,65 @@ class PageUpdater {
                $status->value['revision'] = $newLegacyRevision;
                $status->value['revision-record'] = $newRevisionRecord;
 
-               // XXX: make sure we are not loading the Content from the DB
-               $mainContent = $newRevisionRecord->getContent( 'main' );
-
                // Do secondary updates once the main changes have been committed...
                DeferredUpdates::addUpdate(
-                       new AtomicSectionUpdate(
+                       $this->getAtomicSectionUpdate(
                                $dbw,
-                               __METHOD__,
-                               function () use (
-                                       $wikiPage,
-                                       $newRevisionRecord,
-                                       $newLegacyRevision,
-                                       $user,
-                                       $mainContent,
-                                       $summary,
-                                       $flags,
-                                       $status
-                               ) {
-                                       // Update links, etc.
-                                       $this->derivedDataUpdater->prepareUpdate(
-                                               $newRevisionRecord,
-                                               [ 'created' => true ]
-                                       );
-                                       $this->derivedDataUpdater->doUpdates();
+                               $wikiPage,
+                               $newRevisionRecord,
+                               $user,
+                               $summary,
+                               $flags,
+                               $status,
+                               [ 'created' => true ]
+                       ),
+                       DeferredUpdates::PRESEND
+               );
 
+               return $status;
+       }
+
+       private function getAtomicSectionUpdate(
+               IDatabase $dbw,
+               WikiPage $wikiPage,
+               RevisionRecord $newRevisionRecord,
+               User $user,
+               CommentStoreComment $summary,
+               $flags,
+               Status $status,
+               $hints = []
+       ) {
+               return new AtomicSectionUpdate(
+                       $dbw,
+                       __METHOD__,
+                       function () use (
+                               $wikiPage, $newRevisionRecord, $user,
+                               $summary, $flags, $status, $hints
+                       ) {
+                               $newLegacyRevision = new Revision( $newRevisionRecord );
+                               $mainContent = $newRevisionRecord->getContent( 'main', RevisionRecord::RAW );
+
+                               // Update links tables, site stats, etc.
+                               $this->derivedDataUpdater->prepareUpdate( $newRevisionRecord, $hints );
+                               $this->derivedDataUpdater->doUpdates();
+
+                               // TODO: replace legacy hook!
+                               // TODO: avoid pass-by-reference, see T193950
+
+                               if ( $hints['created'] ?? false ) {
                                        // Trigger post-create hook
-                                       // TODO: replace legacy hook!
-                                       // TODO: avoid pass-by-reference, see T193950
                                        $params = [ &$wikiPage, &$user, $mainContent, $summary->text,
                                                $flags & EDIT_MINOR, null, null, &$flags, $newLegacyRevision ];
                                        Hooks::run( 'PageContentInsertComplete', $params );
-                                       // Trigger post-save hook
-                                       // TODO: replace legacy hook!
-                                       $params = array_merge( $params, [ &$status, $this->getOriginalRevisionId(), 0 ] );
-                                       Hooks::run( 'PageContentSaveComplete', $params );
                                }
-                       ),
-                       DeferredUpdates::PRESEND
-               );
 
-               return $status;
+                               // Trigger post-save hook
+                               $params = [ &$wikiPage, &$user, $mainContent, $summary->text,
+                                               $flags & EDIT_MINOR, null, null, &$flags, $newLegacyRevision,
+                                               &$status, $this->getOriginalRevisionId(), $this->undidRevId ];
+                               Hooks::run( 'PageContentSaveComplete', $params );
+                       }
+               );
        }
 
 }
index 07329c9..119af1d 100644 (file)
@@ -83,6 +83,7 @@ class RevisionStore
 
        /**
         * @var boolean
+        * @see $wgContentHandlerUseDB
         */
        private $contentHandlerUseDB = true;
 
@@ -220,6 +221,7 @@ class RevisionStore
        }
 
        /**
+        * @see $wgContentHandlerUseDB
         * @param bool $contentHandlerUseDB
         * @throws MWException
         */
index 98aa554..943ee22 100644 (file)
@@ -2675,16 +2675,14 @@ abstract class ApiBase extends ContextSource {
         * @deprecated since 1.25
         */
        public function profileIn() {
-               // No wfDeprecated() yet because extensions call this and might need to
-               // keep doing so for BC.
+               wfDeprecated( __METHOD__, '1.25' );
        }
 
        /**
         * @deprecated since 1.25
         */
        public function profileOut() {
-               // No wfDeprecated() yet because extensions call this and might need to
-               // keep doing so for BC.
+               wfDeprecated( __METHOD__, '1.25' );
        }
 
        /**
index 271e36c..d7735f6 100644 (file)
        "apihelp-protect-example-protect": "Een pagina beveiligen.",
        "apihelp-purge-param-forcelinkupdate": "Werk de koppelingstabellen bij.",
        "apihelp-purge-param-forcerecursivelinkupdate": "Werk de koppelingentabel bij, en werk de koppelingstabellen bij voor alle pagina's die deze pagina als sjabloon gebruiken.",
+       "apihelp-query+allcategories-summary": "Alle categorieën doorlopen.",
        "apihelp-query+allcategories-param-dir": "Richting om in te sorteren.",
        "apihelp-query+allcategories-param-limit": "Hoeveel categorieën te tonen.",
        "apihelp-query+allcategories-paramvalue-prop-size": "Voegt het aantal pagina's in de categorie toe.",
        "apihelp-query+allpages-param-limit": "Het totaal aantal pagina's dat getoont moeten worden.",
        "apihelp-query+allredirects-summary": "Toon alle doorverwijzingen naar een naamruimte.",
        "apihelp-query+allredirects-paramvalue-prop-title": "Voegt de titel van de doorverwijzing toe.",
+       "apihelp-query+allredirects-param-limit": "Hoeveel items er in totaal moeten worden getoond.",
        "apihelp-query+allrevisions-summary": "Toon alle versies.",
+       "apihelp-query+allrevisions-param-namespace": "Alleen pagina's in deze naamruimte weergeven.",
        "apihelp-query+allrevisions-example-user": "Toon de laatste 50 bijdragen van gebruiker <kbd>Example</kbd>.",
        "apihelp-query+mystashedfiles-paramvalue-prop-type": "Vraag het MIME- en mediatype van het bestand op.",
        "apihelp-query+mystashedfiles-param-limit": "Hoeveel bestanden te tonen.",
        "apihelp-query+alltransclusions-param-namespace": "De door te lopen naamruimte.",
+       "apihelp-query+alltransclusions-param-limit": "Hoeveel items er in totaal moeten worden getoond.",
        "apihelp-query+allusers-param-dir": "Richting om in te sorteren.",
        "apihelp-query+allusers-param-excludegroup": "Sluit gebruikers in de gegeven groepen uit.",
        "apihelp-query+allusers-paramvalue-prop-blockinfo": "Voegt informatie over een actuele blokkade van de gebruiker toe.",
        "apihelp-query+categorymembers-param-dir": "Richting om in te sorteren.",
        "apihelp-query+categorymembers-example-simple": "Toon de eerste 10 pagina's in <kbd>Category:Physics</kbd>.",
        "apihelp-query+deletedrevisions-param-tag": "Alleen revisies met dit label weergeven.",
+       "apihelp-query+deletedrevs-paraminfo-modes": "{{PLURAL:$1|Modus|Modi}}: $2",
        "apihelp-query+deletedrevs-param-tag": "Alleen revisies met dit label weergeven.",
        "apihelp-query+embeddedin-param-namespace": "De door te lopen naamruimte.",
+       "apihelp-query+filearchive-example-simple": "Toon een lijst met alle verwijderde bestanden.",
        "apihelp-query+fileusage-paramvalue-prop-pageid": "Pagina-ID van elke pagina.",
        "apihelp-query+fileusage-paramvalue-prop-title": "Titel van elke pagina.",
+       "apihelp-query+imageinfo-paramvalue-prop-mediatype": "Voegt het mediatype van het bestand toe.",
        "apihelp-query+imageusage-param-namespace": "De door te lopen naamruimte.",
        "apihelp-query+imageusage-example-simple": "Toon pagina's die [[:File:Albert Einstein Head.jpg]] gebruiken.",
        "apihelp-query+imageusage-example-generator": "Toon informatie over pagina's die [[:File:Albert Einstein Head.jpg]] gebruiken.",
        "apihelp-query+iwbacklinks-param-prefix": "Voorvoegsel voor de interwiki.",
+       "apihelp-query+iwlinks-paramvalue-prop-url": "Voegt de volledige URL toe.",
        "apihelp-query+langbacklinks-example-simple": "Toon de pagina's die verwijzen naar [[:fr:Test]].",
+       "apihelp-query+langlinks-paramvalue-prop-url": "Voegt de volledige URL toe.",
        "apihelp-query+linkshere-paramvalue-prop-pageid": "Pagina-ID van elke pagina.",
        "apihelp-query+linkshere-paramvalue-prop-title": "Titel van elke pagina.",
        "apihelp-query+linkshere-param-namespace": "Toon alleen pagina's in deze naamruimten.",
index 59616c0..3039ef4 100644 (file)
@@ -16,7 +16,7 @@
                        "Choomaq"
                ]
        },
-       "apihelp-main-extended-description": "<div class=\"hlist plainlinks api-main-links\">\n* [[mw:Special:MyLanguage/API:Main_page|Документація]]\n* [[mw:Special:MyLanguage/API:FAQ|ЧаПи]]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api Список розсилки]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api-announce Оголошення API]\n* [https://phabricator.wikimedia.org/maniphest/query/GebfyV4uCaLd/#R Баґи і запити]\n</div>\n<strong>Статус:</strong> Усі функції, вказані на цій сторінці, мають працювати, але API далі перебуває в активній розробці і може змінитися у будь-який момент. Підпишіться на [https://lists.wikimedia.org/pipermail/mediawiki-api-announce/ список розсилки mediawiki-api-announce], щоб помічати оновлення.\n\n<strong>Хибні запити:</strong> Коли до API надсилаються хибні запити, буде відіслано HTTP-шапку з ключем «MediaWiki-API-Error», а тоді і значення шапки, і код помилки, надіслані назад, будуть встановлені з тим же значенням. Більше інформації див. на [[mw:Special:MyLanguage/API:Errors_and_warnings|API: Errors and warnings]].\n\n<strong>Тестування:</strong> Для зручності тестування запитів API, див. [[Special:ApiSandbox]].",
+       "apihelp-main-extended-description": "<div class=\"hlist plainlinks api-main-links\">\n* [[mw:Special:MyLanguage/API:Main_page|Документація]]\n* [[mw:Special:MyLanguage/API:FAQ|ЧаПи]]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api Список розсилки]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api-announce Оголошення API]\n* [https://phabricator.wikimedia.org/maniphest/query/GebfyV4uCaLd/#R Баґи і запити]\n</div>\n<strong>Статус:</strong> Усі функції, вказані на цій сторінці, мають працювати, але API далі перебуває в активній розробці і може змінитися у будь-який момент. Підпишіться на [https://lists.wikimedia.org/pipermail/mediawiki-api-announce/ список розсилки mediawiki-api-announce], щоб помічати оновлення.\n\n<strong>Хибні запити:</strong> Коли до API надсилаються хибні запити, буде відіслано HTTP-шапку з ключем «MediaWiki-API-Error», а тоді і значення шапки, і код помилки, надіслані назад, будуть встановлені з тим же значенням. Більше інформації див. на сторінці [[mw:Special:MyLanguage/API:Errors_and_warnings|API: Помилки й попередження]].\n\n<p class=\"mw-apisandbox-link\"><strong>Тестування:</strong> Для зручності тестування запитів API, див. [[Special:ApiSandbox]].</p>",
        "apihelp-main-param-action": "Яку дію виконати.",
        "apihelp-main-param-format": "Формат виводу.",
        "apihelp-main-param-maxlag": "Максимальна затримка може використовуватися, коли MediaWiki інстальовано на реплікований кластер бази даних. Щоб зберегти дії, які спричиняють більшу затримку реплікації, цей параметр може змусити клієнт почекати, поки затримка реплікації не буде меншою за вказане значення. У випадку непомірної затримки, видається код помилки <samp>maxlag</samp> з повідомленням на зразок <samp>Очікування на $host: $lag секунд(и) затримки</samp>.<br />Див. [[mw:Special:MyLanguage/Manual:Maxlag_parameter|Manual: Maxlag parameter]] для детальнішої інформації.",
@@ -67,6 +67,7 @@
        "apihelp-compare-param-fromid": "Перший ID сторінки для порівняння.",
        "apihelp-compare-param-fromrev": "Перша версія для порівняння.",
        "apihelp-compare-param-fromtext": "Використати цей текст замість контенту версії, вказаної через <var>fromtitle</var>, <var>fromid</var> або <var>fromrev</var>.",
+       "apihelp-compare-param-fromsection": "Використовувати лише вказану секцію із заданого вмісту «from».",
        "apihelp-compare-param-frompst": "Зробити трансформацію перед збереженням на <var>fromtext</var>.",
        "apihelp-compare-param-fromcontentmodel": "Контентна модель <var>fromtext</var>. Якщо не вказано, буде використано припущення на основі інших параметрів.",
        "apihelp-compare-param-fromcontentformat": "Формат серіалізації контенту <var>fromtext</var>.",
@@ -75,6 +76,7 @@
        "apihelp-compare-param-torev": "Друга версія для порівняння.",
        "apihelp-compare-param-torelative": "Використати версію, яка стосується версії, визначеної через <var>fromtitle</var>, <var>fromid</var> або <var>fromrev</var>. Усі інші опції 'to' буде проігноровано.",
        "apihelp-compare-param-totext": "Використати цей текст замість контенту версії, вказаної через <var>totitle</var>, <var>toid</var> або <var>torev</var>.",
+       "apihelp-compare-param-tosection": "Використовувати лише вказану секцію із заданого вмісту «to».",
        "apihelp-compare-param-topst": "Виконати трансформацію перед збереженням на <var>totext</var>.",
        "apihelp-compare-param-tocontentmodel": "Контентна модель <var>totext</var>. Якщо не вказано, буде використано припущення на основі інших параметрів.",
        "apihelp-compare-param-tocontentformat": "Формат серіалізації контенту <var>totext</var>.",
        "apihelp-import-extended-description": "Зважте, що HTTP POST має бути виконано як завантаження файлу (тобто з використанням даних різних частин/форм) під час надсилання файлу для параметра <var>xml</var>.",
        "apihelp-import-param-summary": "Підсумок імпорту записів журналу.",
        "apihelp-import-param-xml": "Завантажено XML-файл.",
+       "apihelp-import-param-interwikiprefix": "Для завантажених імпортів: префікс інтервікі, який слід додавати до невідомих імен користувачів (а також відомих користувачів, якщо задано <var>$1assignknownusers</var>).",
+       "apihelp-import-param-assignknownusers": "Прив'язувати редагування до локальних користувачів, якщо користувач із таким іменем існує локально.",
        "apihelp-import-param-interwikisource": "Для інтервікі-імпорту: вікі, з якої імпортувати.",
        "apihelp-import-param-interwikipage": "Для інтервікі-імпорту: сторінки для імпорту.",
        "apihelp-import-param-fullhistory": "Для інтервікі-імпорту: імпортувати повну історію, не лише поточну версію.",
        "apihelp-opensearch-summary": "Шукати у вікі з використанням протоколу OpenSearch.",
        "apihelp-opensearch-param-search": "Рядок пошуку.",
        "apihelp-opensearch-param-limit": "Максимальна кількість результатів для виведення.",
-       "apihelp-opensearch-param-namespace": "Простори назв, у яких шукати.",
+       "apihelp-opensearch-param-namespace": "Простори назв, у яких шукати. Ігнорується, якщо <var>$1search</var> починається з валідного префікса простору назв.",
        "apihelp-opensearch-param-suggest": "Нічого не робити, якщо <var>[[mw:Special:MyLanguage/Manual:$wgEnableOpenSearchSuggest|$wgEnableOpenSearchSuggest]]</var> хибний.",
        "apihelp-opensearch-param-redirects": "Як обробляти перенаправлення:\n;return:Видати саме перенаправлення.\n;resolve:Видати цільову сторінку. Може видати менше, ніж $1limit результат{{PLURAL:$1limit||и|ів}}.\nЗ історичних причин, за замовчуванням стоїть «return» для $1format=json і «resolve» — для інших форматів.",
        "apihelp-opensearch-param-format": "Формат виводу.",
        "apihelp-parse-param-disablepp": "Використати натомість <var>$1disablelimitreport</var>.",
        "apihelp-parse-param-disableeditsection": "Пропустити посилання на редагування розділів на виході аналізу.",
        "apihelp-parse-param-disabletidy": "Не запускайте очищення HTML (e.g. tidy) на виході аналізу.",
+       "apihelp-parse-param-disablestylededuplication": "Не усувайте дублікати вбудованих таблиць стилів на виході парсера.",
        "apihelp-parse-param-generatexml": "Генерувати синтаксичне дерево XML (передбачає модель вмісту <code>$1</code>; замінено на <kbd>$2prop=parsetree</kbd>).",
        "apihelp-parse-param-preview": "Аналізувати у режимі попереднього перегляду.",
        "apihelp-parse-param-sectionpreview": "Аналізувати у режимі попереднього перегляду розділу (також вмикає попередній перегляд).",
        "apihelp-query+filearchive-param-dir": "Напрямок, у якому перелічити.",
        "apihelp-query+filearchive-param-sha1": "SHA1-хеш зображення. Перевизначає $1sha1base36.",
        "apihelp-query+filearchive-param-sha1base36": "SHA1-хеш зображення у base 36 (використано в MediaWiki).",
+       "apihelp-query+filearchive-param-prop": "Інформацію про яке зображення слід отримати:",
        "apihelp-query+filearchive-paramvalue-prop-sha1": "Додає хеш SHA-1 до зображення.",
        "apihelp-query+filearchive-paramvalue-prop-timestamp": "Додає часову мітку завантаженої версії.",
        "apihelp-query+filearchive-paramvalue-prop-user": "Додає користувача, який завантажив версію зображення.",
        "apihelp-query+filearchive-paramvalue-prop-archivename": "Додає до імені версію архіву для неостаточного варіанту файлу.",
        "apihelp-query+filearchive-example-simple": "Показати список усіх вилучених файлів.",
        "apihelp-query+filerepoinfo-summary": "Видати мета-інформацію про репозиторії зображень, налаштовані на вікі.",
-       "apihelp-query+filerepoinfo-param-prop": "Які властивості репозиторію отримати (на деяких вікі може бути більше):\n;apiurl:URL до репозиторію API — корисне для отримання інформації про зображення з хосту.\n;name:Ключ репозиторію — використано в e.g. <var>[[mw:Special:MyLanguage/Manual:$wgForeignFileRepos|$wgForeignFileRepos]]</var> і значення [[Special:ApiHelp/query+imageinfo|imageinfo]].\n;displayname:Людиночита назва репозиторію вікі.\n;rooturl:Корінний URL для шляху зображення.\n;local:Чи репозиторій локальний, чи ні.",
+       "apihelp-query+filerepoinfo-param-prop": "Які властивості репозиторію отримати (доступні властивості можуть варіюватися в інших вікі).",
+       "apihelp-query+filerepoinfo-paramvalue-prop-apiurl": "URL-адреса API репозиторію — корисно для отримання інформації про зображення від хоста.",
+       "apihelp-query+filerepoinfo-paramvalue-prop-articlepath": "<var>[[mw:Special:MyLanguage/Manual:$wgArticlePath|$wgArticlePath]]</var> вікі-сайту репозиторію, або еквівалент.",
+       "apihelp-query+filerepoinfo-paramvalue-prop-canUpload": "Чи можна завантажувати файли в цей репозиторій, напр., через CORS та спільну автентифікацію.",
+       "apihelp-query+filerepoinfo-paramvalue-prop-displayname": "Назва вікі-сайту репозиторію, читабельна для людини.",
        "apihelp-query+filerepoinfo-example-simple": "Отримати інформацію про репозиторії файлів.",
        "apihelp-query+fileusage-summary": "Знайти всі сторінки, що використовують дані файли.",
        "apihelp-query+fileusage-param-prop": "Які властивості отримати:",
index 30a685b..ac7a7b5 100644 (file)
@@ -29,7 +29,7 @@
        "apihelp-main-param-servedby": "在結果中包括提出請求的主機名。",
        "apihelp-main-param-curtimestamp": "在結果中包括目前的時間戳。",
        "apihelp-main-param-responselanginfo": "在結果中包括<var>uselang</var>和<var>errorlang</var>所用的語言。",
-       "apihelp-block-summary": "封鎖用戶。",
+       "apihelp-block-summary": "封鎖使用者。",
        "apihelp-block-param-user": "要封鎖的使用者名稱、IP 位址或 IP 範圍。不能與 <var>$1userid</var> 一起使用",
        "apihelp-block-param-reason": "封鎖原因。",
        "apihelp-block-param-anononly": "僅封鎖匿名使用者 (禁止這個 IP 位址的匿名使用者編輯)。",
@@ -60,7 +60,7 @@
        "apihelp-compare-param-torev": "要比對的第二個修訂。",
        "apihelp-compare-example-1": "建立修訂 1 與 1 的差異檔",
        "apihelp-createaccount-summary": "建立新使用者帳號。",
-       "apihelp-createaccount-param-name": "用戶名。",
+       "apihelp-createaccount-param-name": "使用者名稱。",
        "apihelp-createaccount-param-password": "密碼 (若有設定 <var>$1mailpassword</var> 則可略過)。",
        "apihelp-createaccount-param-domain": "外部身分核對使用的網域 (可有可無)。",
        "apihelp-createaccount-param-token": "在第一次請求時已取得的帳號建立金鑰。",
        "apihelp-import-param-namespace": "匯入至此命名空間。無法與 <var>$1rootpage</var> 一起使用。",
        "apihelp-import-param-rootpage": "匯入作為此頁面的子頁面。無法與 <var>$1namespace</var> 一起使用。",
        "apihelp-login-summary": "登入並取得身分核對 cookies",
-       "apihelp-login-param-name": "用戶名。",
+       "apihelp-login-param-name": "使用者名稱。",
        "apihelp-login-param-password": "密碼。",
        "apihelp-login-param-domain": "網域名稱(可有可無)。",
        "apihelp-login-example-login": "登入",
        "apihelp-unblock-example-id": "解除封銷 ID #<kbd>105</kbd>。",
        "apihelp-undelete-param-reason": "還原的原因。",
        "apihelp-userrights-summary": "變更一位使用者的群組成員。",
-       "apihelp-userrights-param-user": "用戶名。",
-       "apihelp-userrights-param-userid": "用戶ID。",
+       "apihelp-userrights-param-user": "使用者名稱。",
+       "apihelp-userrights-param-userid": "使用者ID。",
        "apihelp-userrights-param-add": "加入使用者至這些群組;若已是成員,則更新失效時間。",
        "apihelp-userrights-param-remove": "從這些群組移除使用者。",
        "apihelp-userrights-param-reason": "變更的原因。",
index 0854a43..93959db 100644 (file)
@@ -46,14 +46,11 @@ class MessageCache {
        const LOCK_TTL = 30;
 
        /**
-        * Process local cache of loaded messages that are defined in
-        * MediaWiki namespace. First array level is a language code,
-        * second level is message key and the values are either message
-        * content prefixed with space, or !NONEXISTENT for negative
-        * caching.
-        * @var array $mCache
+        * Process cache of loaded messages that are defined in MediaWiki namespace
+        *
+        * @var MapCacheLRU Map of (language code => key => " <MESSAGE>" or "!TOO BIG")
         */
-       protected $mCache;
+       protected $cache;
 
        /**
         * @var bool[] Map of (language code => boolean)
@@ -80,12 +77,6 @@ class MessageCache {
        /** @var Parser */
        protected $mParser;
 
-       /**
-        * Variable for tracking which variables are already loaded
-        * @var array $mLoadedLanguages
-        */
-       protected $mLoadedLanguages = [];
-
        /**
         * @var bool $mInParser
         */
@@ -174,6 +165,8 @@ class MessageCache {
                $this->clusterCache = $clusterCache;
                $this->srvCache = $serverCache;
 
+               $this->cache = new MapCacheLRU( 5 ); // limit size for sanity
+
                $this->mDisable = !$useDB;
                $this->mExpiry = $expiry;
        }
@@ -247,7 +240,7 @@ class MessageCache {
         *
         * @param string $code Language to which load messages
         * @param int $mode Use MessageCache::FOR_UPDATE to skip process cache [optional]
-        * @throws MWException
+        * @throws InvalidArgumentException
         * @return bool
         */
        protected function load( $code, $mode = null ) {
@@ -256,7 +249,7 @@ class MessageCache {
                }
 
                # Don't do double loading...
-               if ( isset( $this->mLoadedLanguages[$code] ) && $mode != self::FOR_UPDATE ) {
+               if ( $this->cache->has( $code ) && $mode != self::FOR_UPDATE ) {
                        return true;
                }
 
@@ -296,8 +289,8 @@ class MessageCache {
                        $staleCache = $cache;
                } else {
                        $where[] = 'got from local cache';
+                       $this->cache->set( $code, $cache );
                        $success = true;
-                       $this->mCache[$code] = $cache;
                }
 
                if ( !$success ) {
@@ -326,7 +319,7 @@ class MessageCache {
                                                $staleCache = $cache;
                                        } else {
                                                $where[] = 'got from global cache';
-                                               $this->mCache[$code] = $cache;
+                                               $this->cache->set( $code, $cache );
                                                $this->saveToCaches( $cache, 'local-only', $code );
                                                $success = true;
                                        }
@@ -347,7 +340,7 @@ class MessageCache {
                                } elseif ( $staleCache ) {
                                        # Use the stale cache while some other thread constructs the new one
                                        $where[] = 'using stale cache';
-                                       $this->mCache[$code] = $staleCache;
+                                       $this->cache->set( $code, $staleCache );
                                        $success = true;
                                        break;
                                } elseif ( $failedAttempts > 0 ) {
@@ -371,13 +364,14 @@ class MessageCache {
                if ( !$success ) {
                        $where[] = 'loading FAILED - cache is disabled';
                        $this->mDisable = true;
-                       $this->mCache = false;
+                       $this->cache->set( $code, null );
                        wfDebugLog( 'MessageCacheError', __METHOD__ . ": Failed to load $code\n" );
                        # This used to throw an exception, but that led to nasty side effects like
                        # the whole wiki being instantly down if the memcached server died
-               } else {
-                       # All good, just record the success
-                       $this->mLoadedLanguages[$code] = true;
+               }
+
+               if ( !$this->cache->has( $code ) ) { // sanity
+                       throw new LogicException( "Process cache for '$code' should be set by now." );
                }
 
                $info = implode( ', ', $where );
@@ -417,7 +411,7 @@ class MessageCache {
                }
 
                $cache = $this->loadFromDB( $code, $mode );
-               $this->mCache[$code] = $cache;
+               $this->cache->set( $code, $cache );
                $saveSuccess = $this->saveToCaches( $cache, 'all', $code );
 
                if ( !$saveSuccess ) {
@@ -473,10 +467,10 @@ class MessageCache {
 
                $mostused = [];
                if ( $wgAdaptiveMessageCache && $code !== $wgLanguageCode ) {
-                       if ( !isset( $this->mCache[$wgLanguageCode] ) ) {
+                       if ( !$this->cache->has( $wgLanguageCode ) ) {
                                $this->load( $wgLanguageCode );
                        }
-                       $mostused = array_keys( $this->mCache[$wgLanguageCode] );
+                       $mostused = array_keys( $this->cache->get( $wgLanguageCode ) );
                        foreach ( $mostused as $key => $value ) {
                                $mostused[$key] = "$value/$code";
                        }
@@ -578,10 +572,10 @@ class MessageCache {
                // (a) Update the process cache with the new message text
                if ( $text === false ) {
                        // Page deleted
-                       $this->mCache[$code][$title] = '!NONEXISTENT';
+                       $this->cache->setField( $code, $title, '!NONEXISTENT' );
                } else {
                        // Ignore $wgMaxMsgCacheEntrySize so the process cache is up to date
-                       $this->mCache[$code][$title] = ' ' . $text;
+                       $this->cache->setField( $code, $title, ' ' . $text );
                }
 
                // (b) Update the shared caches in a deferred update with a fresh DB snapshot
@@ -600,24 +594,27 @@ class MessageCache {
                                }
                                // Load the messages from the master DB to avoid race conditions
                                $cache = $this->loadFromDB( $code, self::FOR_UPDATE );
-                               $this->mCache[$code] = $cache;
-                               // Load the process cache values and set the per-title cache keys
+                               // Check if an individual cache key should exist and update cache accordingly
                                $page = WikiPage::factory( Title::makeTitle( NS_MEDIAWIKI, $title ) );
                                $page->loadPageData( $page::READ_LATEST );
                                $text = $this->getMessageTextFromContent( $page->getContent() );
-                               // Check if an individual cache key should exist and update cache accordingly
                                if ( is_string( $text ) && strlen( $text ) > $wgMaxMsgCacheEntrySize ) {
-                                       $titleKey = $this->bigMessageCacheKey( $this->mCache[$code]['HASH'], $title );
-                                       $this->wanCache->set( $titleKey, ' ' . $text, $this->mExpiry );
+                                       $this->wanCache->set(
+                                               $this->bigMessageCacheKey( $cache['HASH'], $title ),
+                                               ' ' . $text,
+                                               $this->mExpiry
+                                       );
                                }
                                // Mark this cache as definitely being "latest" (non-volatile) so
-                               // load() calls do try to refresh the cache with replica DB data
-                               $this->mCache[$code]['LATEST'] = time();
+                               // load() calls do not try to refresh the cache with replica DB data
+                               $cache['LATEST'] = time();
+                               // Update the process cache
+                               $this->cache->set( $code, $cache );
                                // Pre-emptively update the local datacenter cache so things like edit filter and
                                // blacklist changes are reflected immediately; these often use MediaWiki: pages.
                                // The datacenter handling replace() calls should be the same one handling edits
                                // as they require HTTP POST.
-                               $this->saveToCaches( $this->mCache[$code], 'all', $code );
+                               $this->saveToCaches( $cache, 'all', $code );
                                // Release the lock now that the cache is saved
                                ScopedCallback::consume( $scopedLock );
 
@@ -971,8 +968,8 @@ class MessageCache {
        public function getMsgFromNamespace( $title, $code ) {
                $this->load( $code );
 
-               if ( isset( $this->mCache[$code][$title] ) ) {
-                       $entry = $this->mCache[$code][$title];
+               if ( $this->cache->hasField( $code, $title ) ) {
+                       $entry = $this->cache->getField( $code, $title );
                        if ( substr( $entry, 0, 1 ) === ' ' ) {
                                // The message exists and is not '!TOO BIG'
                                return (string)substr( $entry, 1 );
@@ -984,40 +981,40 @@ class MessageCache {
                        $message = false;
                        Hooks::run( 'MessagesPreLoad', [ $title, &$message, $code ] );
                        if ( $message !== false ) {
-                               $this->mCache[$code][$title] = ' ' . $message;
+                               $this->cache->setField( $code, $title, ' ' . $message );
                        } else {
-                               $this->mCache[$code][$title] = '!NONEXISTENT';
+                               $this->cache->setField( $code, $title, '!NONEXISTENT' );
                        }
 
                        return $message;
                }
 
                // Individual message cache key
-               $titleKey = $this->bigMessageCacheKey( $this->mCache[$code]['HASH'], $title );
+               $bigKey = $this->bigMessageCacheKey( $this->cache->getField( $code, 'HASH' ), $title );
 
                if ( $this->mCacheVolatile[$code] ) {
                        $entry = false;
                        // Make sure that individual keys respect the WAN cache holdoff period too
                        LoggerFactory::getInstance( 'MessageCache' )->debug(
                                __METHOD__ . ': loading volatile key \'{titleKey}\'',
-                               [ 'titleKey' => $titleKey, 'code' => $code ] );
+                               [ 'titleKey' => $bigKey, 'code' => $code ] );
                } else {
                        // Try the individual message cache
-                       $entry = $this->wanCache->get( $titleKey );
+                       $entry = $this->wanCache->get( $bigKey );
                }
 
                if ( $entry !== false ) {
                        if ( substr( $entry, 0, 1 ) === ' ' ) {
-                               $this->mCache[$code][$title] = $entry;
+                               $this->cache->setField( $code, $title, $entry );
                                // The message exists, so make sure a string is returned
                                return (string)substr( $entry, 1 );
                        } elseif ( $entry === '!NONEXISTENT' ) {
-                               $this->mCache[$code][$title] = '!NONEXISTENT';
+                               $this->cache->setField( $code, $title, '!NONEXISTENT' );
 
                                return false;
                        } else {
                                // Corrupt/obsolete entry, delete it
-                               $this->wanCache->delete( $titleKey );
+                               $this->wanCache->delete( $bigKey );
                        }
                }
 
@@ -1040,14 +1037,14 @@ class MessageCache {
                        if ( $content ) {
                                $message = $this->getMessageTextFromContent( $content );
                                if ( is_string( $message ) ) {
-                                       $this->mCache[$code][$title] = ' ' . $message;
-                                       $this->wanCache->set( $titleKey, ' ' . $message, $this->mExpiry, $cacheOpts );
+                                       $this->cache->setField( $code, $title, ' ' . $message );
+                                       $this->wanCache->set( $bigKey, ' ' . $message, $this->mExpiry, $cacheOpts );
                                }
                        } else {
                                // A possibly temporary loading failure
                                LoggerFactory::getInstance( 'MessageCache' )->warning(
                                        __METHOD__ . ': failed to load message page text for \'{titleKey}\'',
-                                       [ 'titleKey' => $titleKey, 'code' => $code ] );
+                                       [ 'titleKey' => $bigKey, 'code' => $code ] );
                                $message = null; // no negative caching
                        }
                } else {
@@ -1056,8 +1053,8 @@ class MessageCache {
 
                if ( $message === false ) {
                        // Negative caching in case a "too big" message is no longer available (deleted)
-                       $this->mCache[$code][$title] = '!NONEXISTENT';
-                       $this->wanCache->set( $titleKey, '!NONEXISTENT', $this->mExpiry, $cacheOpts );
+                       $this->cache->setField( $code, $title, '!NONEXISTENT' );
+                       $this->wanCache->set( $bigKey, '!NONEXISTENT', $this->mExpiry, $cacheOpts );
                }
 
                return $message;
@@ -1192,13 +1189,12 @@ class MessageCache {
         *
         * Mainly used after a mass rebuild
         */
-       function clear() {
+       public function clear() {
                $langs = Language::fetchLanguageNames( null, 'mw' );
                foreach ( array_keys( $langs ) as $code ) {
                        $this->wanCache->touchCheckKey( $this->getCheckKey( $code ) );
                }
-
-               $this->mLoadedLanguages = [];
+               $this->cache->clear();
        }
 
        /**
@@ -1235,12 +1231,12 @@ class MessageCache {
                global $wgContLang;
 
                $this->load( $code );
-               if ( !isset( $this->mCache[$code] ) ) {
+               if ( !$this->cache->has( $code ) ) {
                        // Apparently load() failed
                        return null;
                }
                // Remove administrative keys
-               $cache = $this->mCache[$code];
+               $cache = $this->cache->get( $code );
                unset( $cache['VERSION'] );
                unset( $cache['EXPIRY'] );
                unset( $cache['EXCESSIVE'] );
index edb54ae..64c33df 100644 (file)
@@ -82,10 +82,10 @@ class CloneDatabase {
                        # works correctly across DB engines, we need to change the pre-
                        # fix back and forth so tableName() works right.
 
-                       self::changePrefix( $this->oldTablePrefix );
+                       $this->db->tablePrefix( $this->oldTablePrefix );
                        $oldTableName = $this->db->tableName( $tbl, 'raw' );
 
-                       self::changePrefix( $this->newTablePrefix );
+                       $this->db->tablePrefix( $this->newTablePrefix );
                        $newTableName = $this->db->tableName( $tbl, 'raw' );
 
                        // Postgres: Temp tables are automatically deleted upon end of session
@@ -116,12 +116,12 @@ class CloneDatabase {
         */
        public function destroy( $dropTables = false ) {
                if ( $dropTables ) {
-                       self::changePrefix( $this->newTablePrefix );
+                       $this->db->tablePrefix( $this->newTablePrefix );
                        foreach ( $this->tablesToClone as $tbl ) {
                                $this->db->dropTable( $tbl );
                        }
                }
-               self::changePrefix( $this->oldTablePrefix );
+               $this->db->tablePrefix( $this->oldTablePrefix );
        }
 
        /**
index 398df01..5c82f09 100644 (file)
@@ -593,13 +593,7 @@ class LinksUpdate extends DataUpdate implements EnqueueableDataUpdate {
                        $nt = Title::makeTitleSafe( NS_CATEGORY, $name );
                        $wgContLang->findVariantLink( $name, $nt, true );
 
-                       if ( $this->mTitle->getNamespace() == NS_CATEGORY ) {
-                               $type = 'subcat';
-                       } elseif ( $this->mTitle->getNamespace() == NS_FILE ) {
-                               $type = 'file';
-                       } else {
-                               $type = 'page';
-                       }
+                       $type = MWNamespace::getCategoryLinkType( $this->mTitle->getNamespace() );
 
                        # Treat custom sortkeys as a prefix, so that if multiple
                        # things are forced to sort as '*' or something, they'll
index ff07fe7..a77dab8 100644 (file)
@@ -132,6 +132,8 @@ class DifferenceEngine extends ContextSource {
        }
 
        /**
+        * Get the language of the difference engine, defaults to page content language
+        *
         * @return Language
         */
        public function getDiffLang() {
@@ -1343,11 +1345,14 @@ class DifferenceEngine extends ContextSource {
 
        /**
         * Set the language in which the diff text is written
-        * (Defaults to page content language).
-        * @param Language|string $lang
+        *
+        * @param Language $lang
         * @since 1.19
         */
        public function setTextLanguage( $lang ) {
+               if ( !$lang instanceof Language ) {
+                       wfDeprecated( __METHOD__ . ' with other type than Language for $lang', '1.32' );
+               }
                $this->mDiffLang = wfGetLangObj( $lang );
        }
 
index 65e4345..5589c68 100644 (file)
@@ -248,7 +248,7 @@ class ArchivedFile {
                        'fa_minor_mime',
                        'fa_user',
                        'fa_user_text',
-                       'fa_actor' => $wgActorTableSchemaMigrationStage > MIGRATION_OLD ? 'fa_actor' : null,
+                       'fa_actor' => $wgActorTableSchemaMigrationStage > MIGRATION_OLD ? 'fa_actor' : 'NULL',
                        'fa_timestamp',
                        'fa_deleted',
                        'fa_deleted_timestamp', /* Used by LocalFileRestoreBatch */
index e86f292..7206dce 100644 (file)
@@ -223,7 +223,7 @@ class LocalFile extends File {
                        'img_minor_mime',
                        'img_user',
                        'img_user_text',
-                       'img_actor' => $wgActorTableSchemaMigrationStage > MIGRATION_OLD ? 'img_actor' : null,
+                       'img_actor' => $wgActorTableSchemaMigrationStage > MIGRATION_OLD ? 'img_actor' : 'NULL',
                        'img_timestamp',
                        'img_sha1',
                ] + MediaWikiServices::getInstance()->getCommentStore()->getFields( 'img_description' );
index aa434d0..b5c44f2 100644 (file)
@@ -138,7 +138,7 @@ class OldLocalFile extends LocalFile {
                        'oi_minor_mime',
                        'oi_user',
                        'oi_user_text',
-                       'oi_actor' => $wgActorTableSchemaMigrationStage > MIGRATION_OLD ? 'oi_actor' : null,
+                       'oi_actor' => $wgActorTableSchemaMigrationStage > MIGRATION_OLD ? 'oi_actor' : 'NULL',
                        'oi_timestamp',
                        'oi_deleted',
                        'oi_sha1',
index a40bf1b..df5aad0 100644 (file)
        "config-license-help": "Чимало загальнодоступних вікі публікують увесь свій вміст під [https://freedomdefined.org/Definition вільною ліцензією]. Це розвиває відчуття спільної власності і заохочує довготривалу участь. У загальному випадку для приватної чи корпоративної вікі у цьому немає необхідності.\n\nЯкщо Ви хочете мати змогу використовувати текст з Вікіпедії і дати Вікіпедії змогу використовувати текст, скопійований з Вашої вікі, вам необхідно обрати <strong>{{int:config-license-cc-by-sa}}</strong>.\n\nРаніше Вікіпедія використовувала GNU Free Documentation License.\nGFDL — допустима ліцензія, але у ній важко розібратися, а контент під GFDL важко використовувати повторно.",
        "config-email-settings": "Налаштування електронної пошти",
        "config-enable-email": "Увімкнути вихідну електронну пошту",
-       "config-enable-email-help": "Якщо Ви хочете, що електронна пошта працювала, необхідно виставити коректні [Config-dbsupport-oracle/manual/en/mail.configuration.php налаштування пошти у PHP].\nЯкщо Вам не потрібні жодні можливості електронної пошти у вікі, можете тут їх відключити.",
+       "config-enable-email-help": "Якщо Ви хочете, що електронна пошта працювала, необхідно виставити коректні [Config-dbsupport-oracle/manual/en/mail.configuration.php налаштування пошти у PHP].\nЯкщо Вам не потрібні жодні можливості електронної пошти у вікі, можете тут їх відімкнути.",
        "config-email-user": "Увімкнути електронну пошту користувач-користувачеві",
        "config-email-user-help": "Дозволити усім користувачам надсилати один одному електронну пошту, якщо вони увімкнули цю можливість у своїх налаштуваннях.",
        "config-email-usertalk": "Увімкнути сповіщення про повідомлення на сторінці обговорення користувача",
        "config-nofile": "Файл \"$1\" не знайдено. Його видалено?",
        "config-extension-link": "Чи знаєте ви, що ваше вікі підтримує [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Extensions розширення]?\n\nВи можете переглядати [https://www.mediawiki.org/wiki/Special:MyLanguage/Category:Extensions_by_category розширення по категорії] або в [https://www.mediawiki.org/wiki/Extension_Matrix матрицю розширень] щоб побачити повний список розширень.",
        "config-skins-screenshots": "$1 (скріншоти: $2)",
+       "config-extensions-requires": "$1 (вимагає $2)",
        "config-screenshot": "скріншот",
        "mainpagetext": "<strong>Програмне забезпечення «MediaWiki» встановлено.</strong>",
        "mainpagedocfooter": "Інформацію про роботу з цією вікі можна знайти на сторінці [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Contents Довідка:Вміст].\n\n== Деякі корисні ресурси ==\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Configuration_settings Список налаштувань];\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ Часті питання з приводу MediaWiki];\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce Розсилка повідомлень про появу нових версій MediaWiki];\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Localisation#Translation_resources Локалізувати MediaWiki своєю мовою]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Combating_spam Дізнатися, як боротися зі спамом у своїй вікі]"
index 553315f..bca8c05 100644 (file)
@@ -25,27 +25,47 @@ use Wikimedia\Assert\Assert;
 /**
  * Handles a simple LRU key/value map with a maximum number of entries
  *
- * Use ProcessCacheLRU if hierarchical purging is needed or objects can become stale
+ * The last-modification timestamp of entries is internally tracked so that callers can
+ * specify the maximum acceptable age of entries in calls to the has() method. As a convenience,
+ * the hasField(), getField(), and setField() methods can be used for entries that are field/value
+ * maps themselves; such fields will have their own internally tracked last-modification timestamp.
  *
  * @see ProcessCacheLRU
  * @ingroup Cache
  * @since 1.23
  */
-class MapCacheLRU {
-       /** @var array */
-       protected $cache = []; // (key => value)
+class MapCacheLRU implements IExpiringStore, Serializable {
+       /** @var array Map of (key => value) */
+       private $cache = [];
+       /** @var array Map of (key => (UNIX timestamp, (field => UNIX timestamp))) */
+       private $timestamps = [];
+       /** @var float Default entry timestamp if not specified */
+       private $epoch;
 
-       protected $maxCacheKeys; // integer; max entries
+       /** @var int Max number of entries */
+       private $maxCacheKeys;
+
+       /** @var float|null */
+       private $wallClockOverride;
+
+       const RANK_TOP = 1.0;
+
+       /** @var int Array key that holds the entry's main timestamp (flat key use) */
+       const SIMPLE = 0;
+       /** @var int Array key that holds the entry's field timestamps (nested key use) */
+       const FIELDS = 1;
 
        /**
-        * @param int $maxKeys Maximum number of entries allowed (min 1).
-        * @throws Exception When $maxCacheKeys is not an int or not above zero.
+        * @param int $maxKeys Maximum number of entries allowed (min 1)
+        * @throws Exception When $maxKeys is not an int or not above zero
         */
        public function __construct( $maxKeys ) {
                Assert::parameterType( 'integer', $maxKeys, '$maxKeys' );
                Assert::parameter( $maxKeys > 0, '$maxKeys', 'must be above zero' );
 
                $this->maxCacheKeys = $maxKeys;
+               // Use the current time as the default "as of" timesamp of entries
+               $this->epoch = $this->getCurrentTime();
        }
 
        /**
@@ -86,13 +106,14 @@ class MapCacheLRU {
         * @param float $rank Bottom fraction of the list where keys start off [Default: 1.0]
         * @return void
         */
-       public function set( $key, $value, $rank = 1.0 ) {
+       public function set( $key, $value, $rank = self::RANK_TOP ) {
                if ( $this->has( $key ) ) {
                        $this->ping( $key );
                } elseif ( count( $this->cache ) >= $this->maxCacheKeys ) {
                        reset( $this->cache );
                        $evictKey = key( $this->cache );
                        unset( $this->cache[$evictKey] );
+                       unset( $this->timestamps[$evictKey] );
                }
 
                if ( $rank < 1.0 && $rank > 0 ) {
@@ -103,20 +124,31 @@ class MapCacheLRU {
                } else {
                        $this->cache[$key] = $value;
                }
+
+               $this->timestamps[$key] = [
+                       self::SIMPLE => $this->getCurrentTime(),
+                       self::FIELDS => []
+               ];
        }
 
        /**
         * Check if a key exists
         *
         * @param string $key
+        * @param float $maxAge Ignore items older than this many seconds (since 1.32)
         * @return bool
         */
-       public function has( $key ) {
+       public function has( $key, $maxAge = 0.0 ) {
                if ( !is_int( $key ) && !is_string( $key ) ) {
                        throw new UnexpectedValueException(
                                __METHOD__ . ' called with invalid key. Must be string or integer.' );
                }
-               return array_key_exists( $key, $this->cache );
+
+               if ( !array_key_exists( $key, $this->cache ) ) {
+                       return false;
+               }
+
+               return ( $maxAge <= 0 || $this->getAge( $key ) <= $maxAge );
        }
 
        /**
@@ -137,6 +169,46 @@ class MapCacheLRU {
                return $this->cache[$key];
        }
 
+       /**
+        * @param string|int $key
+        * @param string|int $field
+        * @param mixed $value
+        * @param float $initRank
+        */
+       public function setField( $key, $field, $value, $initRank = self::RANK_TOP ) {
+               if ( $this->has( $key ) ) {
+                       $this->ping( $key );
+               } else {
+                       $this->set( $key, [], $initRank );
+               }
+
+               if ( !is_array( $this->cache[$key] ) ) {
+                       throw new UnexpectedValueException( "The value of '$key' is not an array." );
+               }
+
+               $this->cache[$key][$field] = $value;
+               $this->timestamps[$key][self::FIELDS][$field] = $this->getCurrentTime();
+       }
+
+       /**
+        * @param string|int $key
+        * @param string|int $field
+        * @param float $maxAge
+        * @return bool
+        */
+       public function hasField( $key, $field, $maxAge = 0.0 ) {
+               $value = $this->get( $key );
+               if ( !is_array( $value ) || !array_key_exists( $field, $value ) ) {
+                       return false;
+               }
+
+               return ( $maxAge <= 0 || $this->getAge( $key, $field ) <= $maxAge );
+       }
+
+       public function getField( $key, $field ) {
+               return $this->get( $key )[$field] ?? null;
+       }
+
        /**
         * @return array
         * @since 1.25
@@ -154,10 +226,13 @@ class MapCacheLRU {
         * @param string $key
         * @param callable $callback Callback that will produce the value
         * @param float $rank Bottom fraction of the list where keys start off [Default: 1.0]
+        * @param float $maxAge Ignore items older than this many seconds [Default: 0.0] (since 1.32)
         * @return mixed The cached value if found or the result of $callback otherwise
         */
-       public function getWithSetCallback( $key, callable $callback, $rank = 1.0 ) {
-               if ( $this->has( $key ) ) {
+       public function getWithSetCallback(
+               $key, callable $callback, $rank = self::RANK_TOP, $maxAge = 0.0
+       ) {
+               if ( $this->has( $key, $maxAge ) ) {
                        $value = $this->get( $key );
                } else {
                        $value = call_user_func( $callback );
@@ -178,21 +253,99 @@ class MapCacheLRU {
        public function clear( $keys = null ) {
                if ( $keys === null ) {
                        $this->cache = [];
+                       $this->timestamps = [];
                } else {
                        foreach ( (array)$keys as $key ) {
                                unset( $this->cache[$key] );
+                               unset( $this->timestamps[$key] );
                        }
                }
        }
 
+       /**
+        * Get the maximum number of keys allowed
+        *
+        * @return int
+        * @since 1.32
+        */
+       public function getMaxSize() {
+               return $this->maxCacheKeys;
+       }
+
+       /**
+        * Resize the maximum number of cache entries, removing older entries as needed
+        *
+        * @param int $maxKeys Maximum number of entries allowed (min 1)
+        * @return void
+        * @throws Exception When $maxKeys is not an int or not above zero
+        * @since 1.32
+        */
+       public function setMaxSize( $maxKeys ) {
+               Assert::parameterType( 'integer', $maxKeys, '$maxKeys' );
+               Assert::parameter( $maxKeys > 0, '$maxKeys', 'must be above zero' );
+
+               $this->maxCacheKeys = $maxKeys;
+               while ( count( $this->cache ) > $this->maxCacheKeys ) {
+                       reset( $this->cache );
+                       $evictKey = key( $this->cache );
+                       unset( $this->cache[$evictKey] );
+                       unset( $this->timestamps[$evictKey] );
+               }
+       }
+
        /**
         * Push an entry to the top of the cache
         *
         * @param string $key
         */
-       protected function ping( $key ) {
+       private function ping( $key ) {
                $item = $this->cache[$key];
                unset( $this->cache[$key] );
                $this->cache[$key] = $item;
        }
+
+       /**
+        * @param string|int $key
+        * @param string|int|null $field [optional]
+        * @return float UNIX timestamp; the age of the given entry or entry field
+        */
+       private function getAge( $key, $field = null ) {
+               if ( $field !== null ) {
+                       $mtime = $this->timestamps[$key][self::FIELDS][$field] ?? $this->epoch;
+               } else {
+                       $mtime = $this->timestamps[$key][self::SIMPLE] ?? $this->epoch;
+               }
+
+               return ( $this->getCurrentTime() - $mtime );
+       }
+
+       public function serialize() {
+               return serialize( [
+                       'entries' => $this->cache,
+                       'timestamps' => $this->timestamps
+               ] );
+       }
+
+       public function unserialize( $serialized ) {
+               $data = unserialize( $serialized );
+               $this->cache = $data['entries'] ?? [];
+               $this->timestamps = $data['timestamps'] ?? [];
+               $this->epoch = $this->getCurrentTime();
+       }
+
+       /**
+        * @return float UNIX timestamp
+        * @codeCoverageIgnore
+        */
+       protected function getCurrentTime() {
+               return $this->wallClockOverride ?: microtime( true );
+       }
+
+       /**
+        * @param float|null &$time Mock UNIX timestamp for testing
+        * @codeCoverageIgnore
+        */
+       public function setMockTime( &$time ) {
+               $this->wallClockOverride =& $time;
+       }
 }
index b374259..eb32d98 100644 (file)
@@ -20,7 +20,6 @@
  * @file
  * @ingroup Cache
  */
-use Wikimedia\Assert\Assert;
 
 /**
  * Class for process caching individual properties of expiring items
@@ -28,22 +27,18 @@ use Wikimedia\Assert\Assert;
  * When the key for an entire item is deleted, all properties for it are deleted
  *
  * @ingroup Cache
+ * @deprecated Since 1.32 Use MapCacheLRU instead
  */
 class ProcessCacheLRU {
-       /** @var array */
-       protected $cache = []; // (key => prop => value)
-
-       /** @var array */
-       protected $cacheTimes = []; // (key => prop => UNIX timestamp)
-
-       protected $maxCacheKeys; // integer; max entries
+       /** @var MapCacheLRU */
+       protected $cache;
 
        /**
         * @param int $maxKeys Maximum number of entries allowed (min 1).
         * @throws UnexpectedValueException When $maxCacheKeys is not an int or =< 0.
         */
        public function __construct( $maxKeys ) {
-               $this->resize( $maxKeys );
+               $this->cache = new MapCacheLRU( $maxKeys );
        }
 
        /**
@@ -57,16 +52,7 @@ class ProcessCacheLRU {
         * @return void
         */
        public function set( $key, $prop, $value ) {
-               if ( isset( $this->cache[$key] ) ) {
-                       $this->ping( $key );
-               } elseif ( count( $this->cache ) >= $this->maxCacheKeys ) {
-                       reset( $this->cache );
-                       $evictKey = key( $this->cache );
-                       unset( $this->cache[$evictKey] );
-                       unset( $this->cacheTimes[$evictKey] );
-               }
-               $this->cache[$key][$prop] = $value;
-               $this->cacheTimes[$key][$prop] = microtime( true );
+               $this->cache->setField( $key, $prop, $value );
        }
 
        /**
@@ -78,13 +64,7 @@ class ProcessCacheLRU {
         * @return bool
         */
        public function has( $key, $prop, $maxAge = 0.0 ) {
-               if ( isset( $this->cache[$key][$prop] ) ) {
-                       return ( $maxAge <= 0 ||
-                               ( microtime( true ) - $this->cacheTimes[$key][$prop] ) <= $maxAge
-                       );
-               }
-
-               return false;
+               return $this->cache->hasField( $key, $prop, $maxAge );
        }
 
        /**
@@ -97,11 +77,7 @@ class ProcessCacheLRU {
         * @return mixed
         */
        public function get( $key, $prop ) {
-               if ( !isset( $this->cache[$key][$prop] ) ) {
-                       return null;
-               }
-               $this->ping( $key );
-               return $this->cache[$key][$prop];
+               return $this->cache->getField( $key, $prop );
        }
 
        /**
@@ -111,15 +87,7 @@ class ProcessCacheLRU {
         * @return void
         */
        public function clear( $keys = null ) {
-               if ( $keys === null ) {
-                       $this->cache = [];
-                       $this->cacheTimes = [];
-               } else {
-                       foreach ( (array)$keys as $key ) {
-                               unset( $this->cache[$key] );
-                               unset( $this->cacheTimes[$key] );
-                       }
-               }
+               $this->cache->clear( $keys );
        }
 
        /**
@@ -130,27 +98,7 @@ class ProcessCacheLRU {
         * @throws UnexpectedValueException
         */
        public function resize( $maxKeys ) {
-               Assert::parameterType( 'integer', $maxKeys, '$maxKeys' );
-               Assert::parameter( $maxKeys > 0, '$maxKeys', 'must be above zero' );
-
-               $this->maxCacheKeys = $maxKeys;
-               while ( count( $this->cache ) > $this->maxCacheKeys ) {
-                       reset( $this->cache );
-                       $evictKey = key( $this->cache );
-                       unset( $this->cache[$evictKey] );
-                       unset( $this->cacheTimes[$evictKey] );
-               }
-       }
-
-       /**
-        * Push an entry to the top of the cache
-        *
-        * @param string $key
-        */
-       protected function ping( $key ) {
-               $item = $this->cache[$key];
-               unset( $this->cache[$key] );
-               $this->cache[$key] = $item;
+               $this->cache->setMaxSize( $maxKeys );
        }
 
        /**
@@ -158,6 +106,6 @@ class ProcessCacheLRU {
         * @return int
         */
        public function getSize() {
-               return $this->maxCacheKeys;
+               return $this->cache->getMaxSize();
        }
 }
index edd5fbc..fd45024 100644 (file)
@@ -34,9 +34,8 @@ class MultiWriteBagOStuff extends BagOStuff {
        protected $caches;
        /** @var bool Use async secondary writes */
        protected $asyncWrites = false;
-
-       /** Idiom for "write to all backends" */
-       const ALL = INF;
+       /** @var int[] List of all backing cache indexes */
+       protected $cacheIndexes = [];
 
        const UPGRADE_TTL = 3600; // TTL when a key is copied to a higher cache tier
 
@@ -91,6 +90,8 @@ class MultiWriteBagOStuff extends BagOStuff {
                        $params['replication'] === 'async' &&
                        is_callable( $this->asyncHandler )
                );
+
+               $this->cacheIndexes = array_keys( $this->caches );
        }
 
        public function setDebug( $debug ) {
@@ -107,21 +108,24 @@ class MultiWriteBagOStuff extends BagOStuff {
                        return $this->caches[0]->get( $key, $flags );
                }
 
-               $misses = 0; // number backends checked
                $value = false;
-               foreach ( $this->caches as $cache ) {
+               $missIndexes = []; // backends checked
+               foreach ( $this->caches as $i => $cache ) {
                        $value = $cache->get( $key, $flags );
                        if ( $value !== false ) {
                                break;
                        }
-                       ++$misses;
+                       $missIndexes[] = $i;
                }
 
                if ( $value !== false
-                       && $misses > 0
+                       && $missIndexes
                        && ( $flags & self::READ_VERIFIED ) == self::READ_VERIFIED
                ) {
-                       $this->doWrite( $misses, $this->asyncWrites, 'set', $key, $value, self::UPGRADE_TTL );
+                       // Backfill the value to the lower (and often larger) cache tiers
+                       $this->doWrite(
+                               $missIndexes, $this->asyncWrites, 'set', $key, $value, self::UPGRADE_TTL
+                       );
                }
 
                return $value;
@@ -132,23 +136,39 @@ class MultiWriteBagOStuff extends BagOStuff {
                        ? false
                        : $this->asyncWrites;
 
-               return $this->doWrite( self::ALL, $asyncWrites, 'set', $key, $value, $exptime );
+               return $this->doWrite( $this->cacheIndexes, $asyncWrites, 'set', $key, $value, $exptime );
        }
 
        public function delete( $key ) {
-               return $this->doWrite( self::ALL, $this->asyncWrites, 'delete', $key );
+               return $this->doWrite( $this->cacheIndexes, $this->asyncWrites, 'delete', $key );
        }
 
        public function add( $key, $value, $exptime = 0 ) {
-               return $this->doWrite( self::ALL, $this->asyncWrites, 'add', $key, $value, $exptime );
+               // Try the write to the top-tier cache
+               $ok = $this->doWrite( [ 0 ], $this->asyncWrites, 'add', $key, $value, $exptime );
+               if ( $ok ) {
+                       // Relay the add() using set() if it succeeded. This is meant to handle certain
+                       // migration scenarios where the same store might get written to twice for certain
+                       // keys. In that case, it does not make sense to return false due to "self-conflicts".
+                       return $this->doWrite(
+                               array_slice( $this->cacheIndexes, 1 ),
+                               $this->asyncWrites,
+                               'set',
+                               $key,
+                               $value,
+                               $exptime
+                       );
+               }
+
+               return false;
        }
 
        public function incr( $key, $value = 1 ) {
-               return $this->doWrite( self::ALL, $this->asyncWrites, 'incr', $key, $value );
+               return $this->doWrite( $this->cacheIndexes, $this->asyncWrites, 'incr', $key, $value );
        }
 
        public function decr( $key, $value = 1 ) {
-               return $this->doWrite( self::ALL, $this->asyncWrites, 'decr', $key, $value );
+               return $this->doWrite( $this->cacheIndexes, $this->asyncWrites, 'decr', $key, $value );
        }
 
        public function lock( $key, $timeout = 6, $expiry = 6, $rclass = '' ) {
@@ -170,29 +190,26 @@ class MultiWriteBagOStuff extends BagOStuff {
        }
 
        /**
-        * Apply a write method to the first $count backing caches
+        * Apply a write method to the backing caches specified by $indexes (in order)
         *
-        * @param int $count
+        * @param int[] $indexes List of backing cache indexes
         * @param bool $asyncWrites
         * @param string $method
         * @param mixed $args,...
         * @return bool
         */
-       protected function doWrite( $count, $asyncWrites, $method /*, ... */ ) {
+       protected function doWrite( $indexes, $asyncWrites, $method /*, ... */ ) {
                $ret = true;
                $args = array_slice( func_get_args(), 3 );
 
-               if ( $count > 1 && $asyncWrites ) {
+               if ( count( $indexes ) > 1 && $asyncWrites ) {
                        // Deep-clone $args to prevent misbehavior when something writes an
                        // object to the BagOStuff then modifies it afterwards, e.g. T168040.
                        $args = unserialize( serialize( $args ) );
                }
 
-               foreach ( $this->caches as $i => $cache ) {
-                       if ( $i >= $count ) {
-                               break; // ignore the lower tiers
-                       }
-
+               foreach ( $indexes as $i ) {
+                       $cache = $this->caches[$i];
                        if ( $i == 0 || !$asyncWrites ) {
                                // First store or in sync mode: write now and get result
                                if ( !$cache->$method( ...$args ) ) {
index d3aa9f5..fc3d575 100644 (file)
@@ -1,5 +1,7 @@
 <?php
 
+use Psr\Log\LoggerInterface;
+
 /**
  * Interface to key-value storage behind an HTTP server.
  *
  * @endcode
  */
 class RESTBagOStuff extends BagOStuff {
+       /**
+        * Default connection timeout in seconds. The kernel retransmits the SYN
+        * packet after 1 second, so 1.2 seconds allows for 1 retransmit without
+        * permanent failure.
+        */
+       const DEFAULT_CONN_TIMEOUT = 1.2;
+
+       /**
+        * Default request timeout
+        */
+       const DEFAULT_REQ_TIMEOUT = 3.0;
 
        /**
         * @var MultiHttpClient
@@ -43,18 +56,34 @@ class RESTBagOStuff extends BagOStuff {
                if ( empty( $params['url'] ) ) {
                        throw new InvalidArgumentException( 'URL parameter is required' );
                }
-               parent::__construct( $params );
                if ( empty( $params['client'] ) ) {
-                       $this->client = new MultiHttpClient( [] );
+                       // Pass through some params to the HTTP client.
+                       $clientParams = [
+                               'connTimeout' => $params['connTimeout'] ?? self::DEFAULT_CONN_TIMEOUT,
+                               'reqTimeout' => $params['reqTimeout'] ?? self::DEFAULT_REQ_TIMEOUT,
+                       ];
+                       foreach ( [ 'caBundlePath', 'proxy' ] as $key ) {
+                               if ( isset( $params[$key] ) ) {
+                                       $clientParams[$key] = $params[$key];
+                               }
+                       }
+                       $this->client = new MultiHttpClient( $clientParams );
                } else {
                        $this->client = $params['client'];
                }
+               // The parent constructor calls setLogger() which sets the logger in $this->client
+               parent::__construct( $params );
                // Make sure URL ends with /
                $this->url = rtrim( $params['url'], '/' ) . '/';
                // Default config, R+W > N; no locks on reads though; writes go straight to state-machine
                $this->attrMap[self::ATTR_SYNCWRITES] = self::QOS_SYNCWRITES_QC;
        }
 
+       public function setLogger( LoggerInterface $logger ) {
+               parent::setLogger( $logger );
+               $this->client->setLogger( $logger );
+       }
+
        /**
         * @param string $key
         * @param int $flags Bitfield of BagOStuff::READ_* constants [optional]
@@ -111,7 +140,7 @@ class RESTBagOStuff extends BagOStuff {
                        'body' => serialize( $value )
                ];
                list( $rcode, $rdesc, $rhdrs, $rbody, $rerr ) = $this->client->run( $req );
-               if ( $rcode === 200 || $rcode === 201 ) {
+               if ( $rcode === 200 || $rcode === 201 || $rcode === 204 ) {
                        return true;
                }
                return $this->handleError( "Failed to store $key", $rcode, $rerr );
@@ -129,7 +158,7 @@ class RESTBagOStuff extends BagOStuff {
                        'url' => $this->url . rawurlencode( $key ),
                ];
                list( $rcode, $rdesc, $rhdrs, $rbody, $rerr ) = $this->client->run( $req );
-               if ( $rcode === 200 || $rcode === 204 || $rcode === 205 ) {
+               if ( in_array( $rcode, [ 200, 204, 205, 404, 410 ] ) ) {
                        return true;
                }
                return $this->handleError( "Failed to delete $key", $rcode, $rerr );
index 57e5907..3054156 100644 (file)
@@ -1925,18 +1925,7 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                }
        }
 
-       public function tableExists( $table, $fname = __METHOD__ ) {
-               $tableRaw = $this->tableName( $table, 'raw' );
-               if ( isset( $this->sessionTempTables[$tableRaw] ) ) {
-                       return true; // already known to exist
-               }
-
-               $table = $this->tableName( $table );
-               $ignoreErrors = true;
-               $res = $this->query( "SELECT 1 FROM $table LIMIT 1", $fname, $ignoreErrors );
-
-               return (bool)$res;
-       }
+       abstract public function tableExists( $table, $fname = __METHOD__ );
 
        public function indexUnique( $table, $index ) {
                $indexInfo = $this->indexInfo( $table, $index );
index 4b925e6..d86c5ce 100644 (file)
@@ -519,6 +519,19 @@ class DatabaseSqlite extends Database {
                return $this->lastAffectedRowCount;
        }
 
+       function tableExists( $table, $fname = __METHOD__ ) {
+               $tableRaw = $this->tableName( $table, 'raw' );
+               if ( isset( $this->sessionTempTables[$tableRaw] ) ) {
+                       return true; // already known to exist
+               }
+
+               $encTable = $this->addQuotes( $tableRaw );
+               $res = $this->query(
+                       "SELECT 1 FROM sqlite_master WHERE type='table' AND name=$encTable" );
+
+               return $res->numRows() ? true : false;
+       }
+
        /**
         * Returns information about an index
         * Returns false if the index does not exist
index 04a553c..4eaa4e8 100644 (file)
@@ -86,8 +86,6 @@ interface ILoadBalancer {
 
        /** @var int DB handle should have DBO_TRX disabled and the caller will leave it as such */
        const CONN_TRX_AUTOCOMMIT = 1;
-       /** @var int Alias for CONN_TRX_AUTOCOMMIT for b/c; deprecated since 1.31 */
-       const CONN_TRX_AUTO = 1;
 
        /** @var string Manager of ILoadBalancer instances is running post-commit callbacks */
        const STAGE_POSTCOMMIT_CALLBACKS = 'stage-postcommit-callbacks';
index 911a8cc..7b8ffef 100644 (file)
@@ -177,7 +177,7 @@ class LogEventsList extends ContextSource {
                        $query = $this->getDefaultQuery();
                        $queryKey = "hide_{$type}_log";
 
-                       $hideVal = 1 - intval( $val );
+                       $hideVal = $val ? 0 : 1;
                        $query[$queryKey] = $hideVal;
 
                        $link = $linkRenderer->makeKnownLink(
index 84653b1..6b177ae 100644 (file)
@@ -105,7 +105,7 @@ class LogPager extends ReverseChronologicalPager {
                        return $filters;
                }
                foreach ( $wgFilterLogTypes as $type => $default ) {
-                       $hide = $this->getRequest()->getInt( "hide_{$type}_log", $default );
+                       $hide = $this->getRequest()->getBool( "hide_{$type}_log", $default );
 
                        $filters[$type] = $hide;
                        if ( $hide ) {
index fa56ab0..754b0fb 100644 (file)
@@ -1935,7 +1935,7 @@ class WikiPage implements Page, IDBAccessObject {
                $updater = $this->getDerivedDataUpdater( $user, $revision, $slots );
 
                if ( !$updater->isUpdatePrepared() ) {
-                       $updater->prepareContent( $user, $slots, [], $useCache );
+                       $updater->prepareContent( $user, $slots, $useCache );
 
                        if ( $revision ) {
                                $updater->prepareUpdate( $revision );
@@ -2527,17 +2527,9 @@ class WikiPage implements Page, IDBAccessObject {
                // Note array_intersect() preserves keys from the first arg, and we're
                // assuming $revQuery has `revision` primary and isn't using subtables
                // for anything we care about.
-               $tablesFlat = [];
-               array_walk_recursive(
-                       $revQuery['tables'],
-                       function ( $a ) use ( &$tablesFlat ) {
-                               $tablesFlat[] = $a;
-                       }
-               );
-
                $res = $dbw->select(
                        array_intersect(
-                               $tablesFlat,
+                               $revQuery['tables'],
                                [ 'revision', 'revision_comment_temp', 'revision_actor_temp' ]
                        ),
                        '1',
@@ -2977,9 +2969,16 @@ class WikiPage implements Page, IDBAccessObject {
                }
 
                $updater->setOriginalRevisionId( $target->getId() );
-               $updater->setUndidRevisionId( $current->getId() );
+               // Do not call setUndidRevisionId(), that causes an extra "mw-undo" tag to be added (T190374)
                $updater->addTags( $tags );
 
+               // 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.
+               if ( $wgUseRCPatrol && $this->getTitle()->userCan( 'autopatrol', $guser ) ) {
+                       $updater->setRcPatrolStatus( RecentChange::PRC_AUTOPATROLLED );
+               }
+
                // Actually store the rollback
                $rev = $updater->saveRevision(
                        CommentStoreComment::newUnsavedComment( $summary ),
@@ -3269,16 +3268,13 @@ class WikiPage implements Page, IDBAccessObject {
         */
        public function updateCategoryCounts( array $added, array $deleted, $id = 0 ) {
                $id = $id ?: $this->getId();
-               $ns = $this->getTitle()->getNamespace();
+               $type = MWNamespace::getCategoryLinkType( $this->getTitle()->getNamespace() );
 
                $addFields = [ 'cat_pages = cat_pages + 1' ];
                $removeFields = [ 'cat_pages = cat_pages - 1' ];
-               if ( $ns == NS_CATEGORY ) {
-                       $addFields[] = 'cat_subcats = cat_subcats + 1';
-                       $removeFields[] = 'cat_subcats = cat_subcats - 1';
-               } elseif ( $ns == NS_FILE ) {
-                       $addFields[] = 'cat_files = cat_files + 1';
-                       $removeFields[] = 'cat_files = cat_files - 1';
+               if ( $type !== 'page' ) {
+                       $addFields[] = "cat_{$type}s = cat_{$type}s + 1";
+                       $removeFields[] = "cat_{$type}s = cat_{$type}s - 1";
                }
 
                $dbw = wfGetDB( DB_MASTER );
@@ -3310,8 +3306,8 @@ class WikiPage implements Page, IDBAccessObject {
                                        $insertRows[] = [
                                                'cat_title'   => $cat,
                                                'cat_pages'   => 1,
-                                               'cat_subcats' => ( $ns == NS_CATEGORY ) ? 1 : 0,
-                                               'cat_files'   => ( $ns == NS_FILE ) ? 1 : 0,
+                                               'cat_subcats' => ( $type === 'subcat' ) ? 1 : 0,
+                                               'cat_files'   => ( $type === 'file' ) ? 1 : 0,
                                        ];
                                }
                                $dbw->upsert(
index 43f294b..80eb598 100644 (file)
@@ -570,8 +570,7 @@ class ResourceLoader implements LoggerAwareInterface {
        }
 
        /**
-        * Return whether the definition of a module corresponds to a simple ResourceLoaderFileModule
-        * or one of its subclasses.
+        * Whether the module is a ResourceLoaderFileModule (including subclasses).
         *
         * @param string $name Module name
         * @return bool
@@ -584,14 +583,13 @@ class ResourceLoader implements LoggerAwareInterface {
                if ( isset( $info['object'] ) ) {
                        return false;
                }
-               if (
-                       isset( $info['class'] ) &&
-                       $info['class'] !== ResourceLoaderFileModule::class &&
-                       !is_subclass_of( $info['class'], ResourceLoaderFileModule::class )
-               ) {
-                       return false;
-               }
-               return true;
+               return (
+                       // The implied default for 'class' is ResourceLoaderFileModule
+                       !isset( $info['class'] ) ||
+                       // Explicit default
+                       $info['class'] === ResourceLoaderFileModule::class ||
+                       is_subclass_of( $info['class'], ResourceLoaderFileModule::class )
+               );
        }
 
        /**
index 43bd3be..30ac92d 100644 (file)
@@ -21,6 +21,8 @@
  * @ingroup Search
  */
 
+use Wikimedia\Rdbms\IResultWrapper;
+
 /**
  * Search engine hook base class for Mssql (ConText).
  * @ingroup Search
@@ -168,7 +170,7 @@ class SearchMssql extends SearchDatabase {
         * @param int $id
         * @param string $title
         * @param string $text
-        * @return bool|ResultWrapper
+        * @return bool|IResultWrapper
         */
        function update( $id, $title, $text ) {
                // We store the column data as UTF-8 byte order marked binary stream
@@ -191,7 +193,7 @@ class SearchMssql extends SearchDatabase {
         *
         * @param int $id
         * @param string $title
-        * @return bool|ResultWrapper
+        * @return bool|IResultWrapper
         */
        function updateTitle( $id, $title ) {
                $table = $this->db->tableName( 'searchindex' );
index 02ae23d..896e62f 100644 (file)
@@ -24,6 +24,7 @@
 namespace MediaWiki\Session;
 
 use Language;
+use Message;
 
 /**
  * This exists to make IDEs happy, so they don't see the
index ee9f1eb..0ddc443 100644 (file)
@@ -110,6 +110,7 @@ class Shell {
        /**
         * Returns a new instance of Command class
         *
+        * @note You should check Shell::isDisabled() before calling this
         * @param string|string[] ...$commands String or array of strings representing the command to
         * be executed, each value will be escaped.
         *   Example:   [ 'convert', '-font', 'font name' ] would produce "'convert' '-font' 'font name'"
@@ -223,6 +224,7 @@ class Shell {
         * Note that $parameters should be a flat array and an option with an argument
         * should consist of two consecutive items in the array (do not use "--option value").
         *
+        * @note You should check Shell::isDisabled() before calling this
         * @param string $script MediaWiki CLI script with full path
         * @param string[] $parameters Arguments and options to the script
         * @param array $options Associative array of options:
index b5ced13..f261b72 100644 (file)
@@ -23,6 +23,7 @@
  * @ingroup Pager
  */
 use MediaWiki\MediaWikiServices;
+use Wikimedia\Rdbms\IDatabase;
 use Wikimedia\Rdbms\IResultWrapper;
 use Wikimedia\Rdbms\FakeResultWrapper;
 
index 1623c36..28469ef 100644 (file)
@@ -220,7 +220,8 @@ class Language {
 
                // Check if there is a language class for the code
                $class = self::classFromCode( $code, $fallback );
-               if ( class_exists( $class ) ) {
+               // LanguageCode does not inherit Language
+               if ( class_exists( $class ) && is_a( $class, 'Language', true ) ) {
                        $lang = new $class;
                        return $lang;
                }
index 97ff012..277bd02 100644 (file)
@@ -297,6 +297,7 @@ class Names {
                'mk' => 'македонски', # Macedonian
                'ml' => 'മലയാളം', # Malayalam
                'mn' => 'монгол', # Halh Mongolian (Cyrillic) (ISO 639-3: khk)
+               'mni' => 'মেইতেই লোন্', # Manipuri/Meitei
                'mo' => 'молдовеняскэ', # Moldovan, deprecated
                'mr' => 'मराठी', # Marathi
                'mrj' => 'кырык мары', # Hill Mari
index 605025c..5cdcfaf 100644 (file)
        "tooltip-ca-nstab-special": "Nyoë nakeuh miëng kusuih, ngön h’an jeuët geuandam.",
        "tooltip-ca-nstab-project": "Eu laman buët",
        "tooltip-ca-nstab-image": "Eu miëng beureukaih",
+       "tooltip-ca-nstab-mediawiki": "Eu peusan sistem",
        "tooltip-ca-nstab-template": "Eu seunaleuëk",
        "tooltip-ca-nstab-help": "Eu laman beunantu",
        "tooltip-ca-nstab-category": "Eu miëng kawan",
        "logentry-delete-delete": "$1 {{GENDER:$2|geusampôh}} miëng $3",
        "logentry-move-move": "$1 {{GENDER:$2|geupinah}} mieng $3 u $4",
        "logentry-move-move-noredirect": "$1 {{GENDER:$2|geupinah}} mieng $3 u $4 hana geubôh peuninah",
+       "logentry-move-move_redir": "$1 {{GENDER:$2|geupinah}} mieng $3 u $4 ateueh mieng peuninah",
        "logentry-patrol-patrol-auto": "$1 otomatis {{GENDER:$2|geutanda}} revisi $4 nibak mieng $3 nyang geukawai",
        "logentry-newusers-create": "$1 {{GENDER:$2|geupeugöt}} akun ureuëng ngui",
        "logentry-upload-upload": "$1 {{GENDER:$2|geupasoe}} $3",
index 0344828..651c3f4 100644 (file)
        "converter-manual-rule-error": "خطأ تم اكتشافه في قاعدة تحويل اللغة اليدوية",
        "undo-success": "يمكن استرجاع التعديل.\nتحقق من المقارنة بالأسفل للتأكد من أن هذا هو ما تريد أن تفعله، ثم احفظ التغييرات بالأسفل للانتهاء من استرجاع التعديل.",
        "undo-failure": "لم يمكن استرجاع التعديل بسبب تعديلات متعارضة تمت على الصفحة.",
+       "undo-main-slot-only": "لا يمكن التراجع عن التعديل لأنه ينطوي على محتوى خارج الفتحة الرئيسية.",
        "undo-norev": "فشل في الرجوع عن التعديل حيث أنه غير موجود أو تم حذفه.",
        "undo-nochange": "التعديل يبدو أنه قد تم الترجع عنه بالفعل.",
        "undo-summary": "الرجوع عن التعديل $1 بواسطة [[Special:Contributions/$2|$2]] ([[User talk:$2|نقاش]])",
index 4f4aa01..8f248ce 100644 (file)
        "welcomecreation-msg": "Creóse la to cuenta.\nNun t'escaezas de camudar les tos [[Special:Preferences|preferencies de {{SITENAME}}]].",
        "yourname": "Nome d'usuariu:",
        "userlogin-yourname": "Nome d'usuariu",
-       "userlogin-yourname-ph": "Escriba'l so nome d'usuariu",
-       "createacct-another-username-ph": "Escriba'l nome d'usuariu",
+       "userlogin-yourname-ph": "Escribe'l to nome d'usuariu",
+       "createacct-another-username-ph": "Escribe'l nome d'usuariu",
        "yourpassword": "Contraseña:",
        "userlogin-yourpassword": "Contraseña",
-       "userlogin-yourpassword-ph": "Escriba la so contraseña",
-       "createacct-yourpassword-ph": "Escriba una contraseña",
+       "userlogin-yourpassword-ph": "Escribe la contraseña",
+       "createacct-yourpassword-ph": "Escribe una contraseña",
        "yourpasswordagain": "Escribi otra vuelta la contraseña:",
        "createacct-yourpasswordagain": "Confirmar la contraseña",
-       "createacct-yourpasswordagain-ph": "Escriba nuevamente la contraseña",
+       "createacct-yourpasswordagain-ph": "Escribe nuevamente la contraseña",
        "userlogin-remembermypassword": "Caltener abierta la sesión",
        "userlogin-signwithsecure": "Usar una conexón segura",
        "cannotlogin-title": "Nun pudo aniciase sesión",
        "logout": "Salir",
        "userlogout": "Salir",
        "notloggedin": "Nun aniciasti sesión",
-       "userlogin-noaccount": "¿Nun tien una cuenta?",
+       "userlogin-noaccount": "¿Nun tienes una cuenta?",
        "userlogin-joinproject": "Xunise a {{SITENAME}}",
        "createaccount": "Crear una cuenta",
-       "userlogin-resetpassword-link": "¿Escaeció la contraseña?",
+       "userlogin-resetpassword-link": "¿Escaecisti la contraseña?",
        "userlogin-helplink2": "Ayuda del aniciu de sesión",
        "userlogin-loggedin": "Yá anició sesión como {{GENDER:$1|$1}}.\nUtilice'l formulariu de más abaxo p'aniciar sesión como otru usuariu.",
        "userlogin-reauth": "Tienes d'aniciar sesión de nueves pa comprobar que yes {{GENDER:$1|$1}}.",
        "userlogin-createanother": "Crear otra cuenta",
        "createacct-emailrequired": "Direición de corréu electrónicu",
        "createacct-emailoptional": "Direición de corréu electrónicu (opcional)",
-       "createacct-email-ph": "Escriba la so direición de corréu electrónicu",
-       "createacct-another-email-ph": "Escriba la direición de corréu electrónicu",
+       "createacct-email-ph": "Escribe la to direición de corréu electrónicu",
+       "createacct-another-email-ph": "Escribe la direición de corréu electrónicu",
        "createaccountmail": "Usar una contraseña al debalu temporal y unviala a la direición de corréu electrónicu conseñada",
        "createaccountmail-help": "Pue usase pa crear una cuenta pa otra persona ensin saber la contraseña.",
        "createacct-realname": "Nome real (opcional)",
        "createacct-reason": "Motivu",
-       "createacct-reason-ph": "Por qué quier crear otra cuenta",
+       "createacct-reason-ph": "Por qué vas crear otra cuenta",
        "createacct-reason-help": "Mensaxe que s'amuesa nel rexistru de creación de cuentes",
        "createacct-submit": "Crear la cuenta",
        "createacct-another-submit": "Crear una cuenta",
        "createacct-continue-submit": "Siguir cola creación de la cuenta",
        "createacct-another-continue-submit": "Siguir cola creación de la cuenta",
-       "createacct-benefit-heading": "{{SITENAME}} failu xente como vusté.",
+       "createacct-benefit-heading": "Persones como tu son les que construyen {{SITENAME}}.",
        "createacct-benefit-body1": "{{PLURAL:$1|edición|ediciones}}",
        "createacct-benefit-body2": "{{PLURAL:$1|páxina|páxines}}",
        "createacct-benefit-body3": "{{PLURAL:$1|collaborador|collaboradores}} de recién",
        "userexists": "El nome d'usuariu conseñáu yá ta usándose.\nPor favor escueyi un nome diferente.",
        "loginerror": "Error d'aniciu de sesión",
        "createacct-error": "Error de creación de cuenta",
-       "createaccounterror": "Nun se pudo crear la cuenta: $1",
+       "createaccounterror": "Nun pudo crease la cuenta: $1",
        "nocookiesnew": "La cuenta d'usuariu ta creada, pero nun aniciasti sesión.\n{{SITENAME}} usa «cookies» pa identificar a los usuarios.\nTienes les «cookies» desactivaes.\nPor favor actívales y anicia sesión col nuevu nome d'usuariu y contraseña.",
-       "nocookieslogin": "{{SITENAME}} usa «cookies» pa identificar a los usuarios.\nTien les «cookies» desactivaes.\nPor favor activeles y vuelva a intentalo.",
-       "nocookiesfornew": "La cuenta nun se creó porque nun pudimos confirmar l'orixe.\nComprueba que tienes activaes les «cookies», recarga esta páxina y vuelvi a intentalo.",
+       "nocookieslogin": "{{SITENAME}} usa «cookies» pa identificar a los usuarios.\nTien les «cookies» desactivaes.\nPor favor actívales y tenta otra vuelta.",
+       "nocookiesfornew": "La cuenta nun se creó porque nun pudimos confirmar l'orixe.\nComprueba que tienes activaes les «cookies», recarga esta páxina y tenta otra vuelta.",
        "createacct-loginerror": "La cuenta creóse correchamente, pero nun pudo aniciase sesión automáticamente. Sigui col [[Special:UserLogin|accesu manual]].",
        "noname": "Nun conseñasti un nome d'usuariu válidu.",
        "loginsuccesstitle": "Identificáu",
        "nouserspecified": "Has d'especificar un nome d'usuariu.",
        "login-userblocked": "Esti usuariu ta bloquiáu. Nun se permite l'aniciu de sesión.",
        "wrongpassword": "Escribisti un nome d'usuariu o contraseña incorreutu.\nTenta otra vuelta.",
-       "wrongpasswordempty": "La contraseña taba en blanco.\nVuelvi a intentalo.",
+       "wrongpasswordempty": "La contraseña taba en blancu.\nTenta otra vuelta.",
        "passwordtooshort": "Les contraseñes han de tener polo menos {{PLURAL:$1|1 caráuter|$1 caráuteres}}.",
        "passwordtoolong": "Les contraseñes nun puen ser mayores de {{PLURAL:$1|1 caráuter|$1 caráuteres}}.",
        "passwordtoopopular": "Les contraseñes más escoyíes de vezu nun pueden usase. Escueye una contraseña más difícil d'aldovinar.",
        "throttled-mailpassword": "Yá s'unvió un corréu de reaniciu la clave {{PLURAL:$1|na postrer hora|nes postreres $1 hores}}.\nPa evitar abusos, namái s'unviará un corréu de reaniciu cada {{PLURAL:$1|hora|$1 hores}}.",
        "mailerror": "Fallu al unviar el corréu: $1",
        "acct_creation_throttle_hit": "Los visitantes d'esta wiki qu'usen la to direición IP yá crearon {{PLURAL:$1|1 cuenta|$1 cuentes}} nel periodu de $2, que ye'l máximu almitíu nesi tiempu.\nPoro, los visitantes qu'usen esta direición IP nun pueden crear más cuentes pol momentu.",
-       "emailauthenticated": "La so direición de corréu electrónicu confirmóse'l $2 a les $3.",
-       "emailnotauthenticated": "La so direición de corréu electrónicu inda nun se confirmó.\nNun s'unviará corréu pa nenguna de les funciones siguientes.",
+       "emailauthenticated": "La direición de corréu electrónicu confirmóse'l $2 a les $3.",
+       "emailnotauthenticated": "La direición de corréu electrónicu inda nun se confirmó.\nNun s'unviará corréu pa nenguna de les funciones siguientes.",
        "noemailprefs": "Conseña una direición de corréu electrónicu nes tos preferencies pa que funcionen eses carauterístiques.",
        "emailconfirmlink": "Confirmar la direición de corréu electrónicu",
        "invalidemailaddress": "La direición de corréu electrónicu nun pue aceutase yá que paez tener un formatu inválidu.\nPor favor conseña una direición con formatu afayadizu o dexa baleru'l campu.",
        "pt-createaccount": "Crear una cuenta",
        "pt-userlogout": "Salir",
        "php-mail-error-unknown": "Fallu desconocíu na función mail() de PHP.",
-       "user-mail-no-addy": "Intentasti unviar un corréu electrónicu ensin direición de corréu.",
-       "user-mail-no-body": "Trató d'unviar un corréu electrónicu con un cuerpu baleru o curtiu enforma.",
+       "user-mail-no-addy": "Tentasti unviar un corréu electrónicu ensin direición de corréu.",
+       "user-mail-no-body": "Tentasti unviar un corréu electrónicu col cuerpu vaciu o curtiu enforma.",
        "changepassword": "Camudar la contraseña",
-       "resetpass_announce": "P'acabar d'aniciar sesión, tien de definir equí una contraseña nueva.",
+       "resetpass_announce": "P'acabar d'aniciar sesión, tienes de configurar una contraseña nueva.",
        "resetpass_text": "<!-- Amestar testu equí -->",
        "resetpass_header": "Camudar la contraseña de la cuenta",
        "oldpassword": "Contraseña antigua:",
        "retypenew": "Vuelvi a escribir la contraseña nueva:",
        "resetpass_submit": "Configurar la contraseña y aniciar sesión",
        "changepassword-success": "Camudóse la contraseña.",
-       "changepassword-throttled": "Ficisti demasiaos intentos d'aniciu de sesión recientes.\nPor favor espera $1 enantes d'intentalo otra vuelta.",
+       "changepassword-throttled": "Ficisti demasiaos intentos d'aniciar sesión de recien.\nPor favor espera $1 enantes de tentar otra vuelta.",
        "botpasswords": "Contraseñes de bots",
        "botpasswords-summary": "Les <em>contraseñes de bot</em> permiten l'accesu a una cuenta d'usuariu por aciu de la API sin usar les credenciales d'accesu de la cuenta principal. Los permisos d'usuariu disponibles al aniciar sesión con una contraseña de bot puen tar torgaos.\n\nSi nun sabes pa qué val esto, probablemente nun tendríes d'usalo. Naide tendría de pidite nunca que xeneres una d'estes y que-y la deas.",
        "botpasswords-disabled": "Les contraseñes de bot tán desactivaes.",
        "botpasswords-label-delete": "Desaniciar",
        "botpasswords-label-resetpassword": "Reestablecer la contraseña",
        "botpasswords-label-grants": "Permisos aplicables:",
-       "botpasswords-help-grants": "Los permisos dan accesu a los permisos d'usuariu que yá tenga la cuenta. Activar un permisu equí nun da accesu a nengún permisu que la to cuenta nun tenga d'otra miente. Mira la [[Special:ListGrants|tabla de permisos]] pa más información.",
+       "botpasswords-help-grants": "Los permisos dan accesu a los permisos d'usuariu que yá tengas na cuenta. Activar un permisu equí nun da accesu a nengún permisu que la to cuenta nun tenga d'otra miente. Mira la [[Special:ListGrants|tabla de permisos]] pa más información.",
        "botpasswords-label-grants-column": "Permitío",
        "botpasswords-bad-appid": "El nome del bot \"$1\" nun ye válidu.",
        "botpasswords-insert-failed": "Nun pudo amestase'l nome de bot «$1». ¿Taba añadíu yá?",
        "resetpass-temp-emailed": "Anició sesión con un códigu temporal unviáu per corréu electrónicu.\nPa completar l'aniciu de sesión, tien de definir una nueva contraseña equí:",
        "resetpass-temp-password": "Contraseña temporal:",
        "resetpass-abort-generic": "Una estensión encaboxó'l cambiu de la contraseña.",
-       "resetpass-expired": "La so contraseña caducó. Defina una nueva contraseña p'aniciar sesión.",
+       "resetpass-expired": "La to contraseña caducó. Configura una nueva contraseña p'aniciar sesión.",
        "resetpass-expired-soft": "La contraseña caducó y precisa cambiase. Escueye agora una contraseña nueva, o pulsia «{{int:authprovider-resetpass-skip-label}}» pa cambiala sero.",
        "resetpass-validity-soft": "La contraseña nun ye válida: $1\n\nEscueye agora una contraseña nueva, o pulsia «{{int:authprovider-resetpass-skip-label}}» pa cambiala sero.",
        "passwordreset": "Reaniciar contraseña",
-       "passwordreset-text-one": "Complete esti formulariu pa reaniciar la contraseña.",
-       "passwordreset-text-many": "{{PLURAL:$1|Rellene unu de los campos pa recibir una contraseña temporal per corréu.}}",
+       "passwordreset-text-one": "Completa esti formulariu pa recibir per corréu una contraseña temporal.",
+       "passwordreset-text-many": "{{PLURAL:$1|Rellena unu de los campos pa recibir una contraseña temporal per corréu.}}",
        "passwordreset-disabled": "Los reanicios de contraseña tán desactivaos nesta wiki.",
        "passwordreset-emaildisabled": "Les funciones de corréu electrónicu tan desactivaes nesta wiki.",
        "passwordreset-username": "Nome d'usuariu:",
        "passwordreset-domain": "Dominiu:",
        "passwordreset-email": "Direición de corréu electrónicu:",
        "passwordreset-emailtitle": "Detalles de la cuenta en {{SITENAME}}",
-       "passwordreset-emailtext-ip": "Dalguién (seique vusté, dende la direición IP $1)solicitó'l reaniciu de la so contraseña de {{SITENAME}} ($4).\n{{PLURAL:$3|La cuenta d'usuariu siguiente ta asociada|Les cuentes d'usuariu siguientes tán asociaes}}\na esta direición de corréu electrónicu:\n\n$2\n\n{{PLURAL:$3|Esta contraseña provisional caduca|Estes contraseñes provisionales caduquen}} {{PLURAL:$5|nun día|en $5 díes}}.\nTendría d'aniciar sesión y escoyer una contraseña nueva agora. Si esta solicitú la fizo otra persona,\no si recordó la clave orixinal y yá nun quier camudala, pue escaecer esti mensaxe y siguir\nusando la contraseña antigua.",
-       "passwordreset-emailtext-user": "L'usuariu $1 de {{SITENAME}} solicitó un reaniciu de la so contraseña de {{SITENAME}} ($4). {{PLURAL:$3|La cuenta d'usuariu siguiente ta asociada|Les cuentes d'usuariu siguientes tán asociaes}} con esta direición de corréu electrónicu:\n\n$2\n\n{{PLURAL:$3|Esta contraseña provisional caduca|Estes contraseñes provisionales caduquen}} {{PLURAL:$5|nun día|en $5 díes}}.\nTendría d'aniciar sesión y escoyer una contraseña nueva agora. Si esta solicitú la fizo otra persona, o si recordó la clave orixinal y yá nun quier camudala, pue escaecer esti mensaxe y siguir usando la contraseña antigua.",
+       "passwordreset-emailtext-ip": "Dalguién (seique tu, dende la direición IP $1)solicitó'l reaniciu de la contraseña de {{SITENAME}} ($4).\n{{PLURAL:$3|La cuenta d'usuariu siguiente ta asociada|Les cuentes d'usuariu siguientes tán asociaes}}\na esta direición de corréu electrónicu:\n\n$2\n\n{{PLURAL:$3|Esta contraseña provisional caduca|Estes contraseñes provisionales caduquen}} {{PLURAL:$5|nun día|en $5 díes}}.\nTendríes d'aniciar sesión y escoyer una contraseña nueva agora. Si esta solicitú ye d'otra persona,\no si recordasti la clave orixinal y yá nun quies camudala, inora esti mensaxe y sigue\nusando la contraseña antigua.",
+       "passwordreset-emailtext-user": "L'usuariu $1 de {{SITENAME}} solicitó un reaniciu de la contraseña de {{SITENAME}} ($4). {{PLURAL:$3|La cuenta d'usuariu siguiente ta asociada|Les cuentes d'usuariu siguientes tán asociaes}} con esta direición de corréu electrónicu:\n\n$2\n\n{{PLURAL:$3|Esta contraseña provisional caduca|Estes contraseñes provisionales caduquen}} {{PLURAL:$5|nun día|en $5 díes}}.\nTendríes d'aniciar sesión y escoyer una contraseña nueva agora. Si esta solicitú ye d'otra persona, o si recordasti la clave orixinal y yá nun quies camudala, pues inorar esti mensaxe y siguir usando la contraseña antigua.",
        "passwordreset-emailelement": "Nome d'usuariu: \n$1\n\nContraseña temporal: \n$2",
        "passwordreset-emailsentemail": "Si esta direición de corréu electrónicu ta asociada cola to cuenta, unviaráse un corréu pa reaniciar la contraseña.",
        "passwordreset-emailsentusername": "Si hai una direición de corréu electrónicu asociada con esti nome d'usuariu, unviaráse un corréu electrónicu pa reaniciar la contraseña.",
index 15e292d..ae9c950 100644 (file)
        "fileexists": "Файл з такой назвай ужо існуе. Калі ласка, праверце <strong>[[:$1]]</strong>, калі {{GENDER:|вы}} ня ўпэўненыя, што жадаеце яго замяніць.\n[[$1|thumb]]",
        "filepageexists": "Старонка апісаньня для гэтага файлу ўжо існуе як <strong>[[:$1]]</strong>, але файлу з такой назвай няма.\nАпісаньне якое вы дадалі ня зьявіцца на старонцы апісаньня.\nКаб яно там зьявілася, вам трэба рэдагаваць яе самастойна.\n[[$1|thumb]]",
        "fileexists-extension": "Файл з падобнай назвай ужо існуе: [[$2|thumb]]\n* Назва загружанага файла: <strong>[[:$1]]</strong>\n* Назва існуючага файла: <strong>[[:$2]]</strong>\nМагчыма, вы жадаеце выкарыстаць адрозную назву?",
-       "fileexists-thumbnail-yes": "Верагодна файл зьяўляецца паменшанай копіяй ''(мініятурай)''. [[$1|thumb]]\nКалі ласка, праверце файл <strong>[[:$1]]</strong>.\nКалі правераны файл зьяўляецца той жа выявай, то загрузка мініятуры ня мае сэнсу.",
-       "file-thumbnail-no": "Назва файла пачынаецца з <strong>$1</strong>.\nВерагодна гэта паменшаная копія выявы ''(мініятура)''.\nКалі Вы маеце гэтую выяву ў поўным памеры, загрузіце яе, альбо зьмяніце назву файла.",
+       "fileexists-thumbnail-yes": "Верагодна, файл зьяўляецца паменшанай копіяй (<em>мініятурай</em>).\n[[$1|thumb]]\nКалі ласка, праверце файл <strong>[[:$1]]</strong>.\nКалі правераны файл зьяўляецца той жа выявай, то загрузка дадатковай мініятуры ня мае сэнсу.",
+       "file-thumbnail-no": "Назва файлу пачынаецца з <strong>$1</strong>.\nВерагодна, гэта паменшаная копія выявы (<em>мініятура</em>).\nКалі вы маеце гэтую выяву ў поўным памеры, загрузіце яе, альбо зьмяніце назву файлу.",
        "fileexists-forbidden": "Файл з такой назвай ужо існуе і ня можа быць перапісаны.\nКалі ласка, вярніцеся назад і загрузіце гэты файл з новай назвай. [[File:$1|thumb|center|$1]]",
-       "fileexists-shared-forbidden": "Файл Ð· Ñ\82акой Ð½Ð°Ð·Ð²Ð°Ð¹ Ñ\83жо Ñ\96Ñ\81нÑ\83е Ñ\9e Ð°Ð³Ñ\83лÑ\8cнÑ\8bм Ñ\81Ñ\85овÑ\96Ñ\88Ñ\87Ñ\8b Ñ\84айлаÑ\9e.\nÐ\9aалÑ\96 Ð\92Ñ\8b Ð¶Ð°Ð´Ð°ÐµÑ\86е Ð·Ð°Ð³Ñ\80Ñ\83зÑ\96Ñ\86Ñ\8c Ð\92аÑ\88 Ñ\84айл, Ð²Ñ\8fÑ\80нÑ\96Ñ\86еÑ\81Ñ\8f Ð½Ð°Ð·Ð°Ð´ Ñ\96 Ð·Ð°Ð³Ñ\80Ñ\83зÑ\96Ñ\86е Ð³Ñ\8dÑ\82Ñ\8b Ñ\84айл Ð· Ð½Ð¾Ð²Ð°Ð¹ Ð½Ð°Ð·Ð²Ð°Ð¹. [[File:$1|thumb|center|$1]]",
+       "fileexists-shared-forbidden": "Файл Ð· Ñ\82акой Ð½Ð°Ð·Ð²Ð°Ð¹ Ñ\83жо Ñ\96Ñ\81нÑ\83е Ñ\9e Ð°Ð³Ñ\83лÑ\8cнÑ\8bм Ñ\81Ñ\85овÑ\96Ñ\88Ñ\87Ñ\8b Ñ\84айлаÑ\9e.\nÐ\9aалÑ\96 Ð²Ñ\8b Ð¶Ð°Ð´Ð°ÐµÑ\86е Ð·Ð°Ð³Ñ\80Ñ\83зÑ\96Ñ\86Ñ\8c Ð²Ð°Ñ\88 Ñ\84айл, Ð²Ñ\8fÑ\80нÑ\96Ñ\86еÑ\81Ñ\8f Ð½Ð°Ð·Ð°Ð´ Ñ\96 Ð·Ð°Ð³Ñ\80Ñ\83зÑ\96Ñ\86е Ð³Ñ\8dÑ\82Ñ\8b Ñ\84айл Ð· Ð½Ð¾Ð²Ð°Ð¹ Ð½Ð°Ð·Ð²Ð°Ð¹.\n[[File:$1|thumb|center|$1]]",
        "fileexists-no-change": "Гэтая загрузка зьяўляецца дакладнай копіяй цяперашняй вэрсіі <strong>[[:$1]]</strong>.",
        "fileexists-duplicate-version": "Гэтая загрузка зьяўляецца дакладнай копіяй {{PLURAL:$2|1=старой вэрсіі|старых вэрсіяў}} файлу <strong>[[:$1]]</strong>.",
        "file-exists-duplicate": "Гэты файл дублюе {{PLURAL:$1|1=наступны файл|наступныя файлы}}:",
-       "file-deleted-duplicate": "Ð\9fадобнÑ\8b Ñ\84айл ([[:$1]]) Ñ\83жо Ð²Ñ\8bдалÑ\8fÑ\9eÑ\81Ñ\8f. Ð\9aалÑ\96 Ð»Ð°Ñ\81ка, Ð¿Ð°Ð³Ð»Ñ\8fдзÑ\96Ñ\86е Ð³Ñ\96Ñ\81Ñ\82оÑ\80Ñ\8bÑ\8e Ð²Ñ\8bдаленÑ\8cнÑ\8fÑ\9e Ð³Ñ\8dÑ\82ага Ñ\84айла перад яго паўторнай загрузкай.",
+       "file-deleted-duplicate": "Ð\86дÑ\8dнÑ\82Ñ\8bÑ\87нÑ\8b Ñ\84айл ([[:$1]]) Ñ\83жо Ñ\80аней Ð²Ñ\8bдалÑ\8fÑ\9eÑ\81Ñ\8f. Ð\92ам Ñ\82Ñ\80Ñ\8dба Ð¿Ð°Ð³Ð»Ñ\8fдзеÑ\86Ñ\8c Ð³Ñ\96Ñ\81Ñ\82оÑ\80Ñ\8bÑ\8e Ð²Ñ\8bдаленÑ\8cнÑ\8fÑ\9e Ð³Ñ\8dÑ\82ага Ñ\84айлÑ\83 перад яго паўторнай загрузкай.",
        "file-deleted-duplicate-notitle": "Файл, ідэнтычны гэтаму файлу, раней ужо быў выдалены, а назва файла была забароненая.\nВам трэба зьвярнуцца да некага з правамі прагляду зьвестак забароненых файлаў, каб прааналізаваць сытуацыю перад тым, як загружаць файл ізноў.",
        "uploadwarning": "Папярэджаньне",
        "uploadwarning-text": "Калі ласка, зьмяніце апісаньне файла ніжэй і паспрабуйце ізноў.",
index 44f4040..2277444 100644 (file)
        "thu": "Чц",
        "fri": "Пт",
        "sat": "Сб",
-       "january": "cтудзень",
+       "january": "студзень",
        "february": "люты",
        "march": "сакавік",
        "april": "красавік",
index a5250de..c3f575a 100644 (file)
        "dellogpage": "Zapisnik brisanja",
        "dellogpagetext": "Ispod je spisak nedavno obrisanih stavki.",
        "deletionlog": "zapisnik brisanja",
+       "log-name-create": "Zapisnik stvaranja stranica",
+       "log-description-create": "Ispod je spisak najnovije stvorenih stranica.",
+       "logentry-create-create": "$1 {{GENDER:$2|stvorio je|stvorila je}} stranicu $3",
        "reverted": "Vraćeno na raniju verziju",
        "deletecomment": "Razlog:",
        "deleteotherreason": "Drugi/dodatni razlog:",
index 2ea950d..ee7435f 100644 (file)
        "confirm-unwatch-top": "Voleu treure aquesta pàgina de la llista de seguiment?",
        "confirm-rollback-button": "D'acord",
        "confirm-rollback-top": "Voleu revertir les modificacions a la pàgina?",
+       "colon-separator": ":&#32;",
        "quotation-marks": "«$1»",
        "imgmultipageprev": "← pàgina anterior",
        "imgmultipagenext": "pàgina següent →",
index 0f2f3fc..ec13f39 100644 (file)
        "timezoneregion-indian": "Индин океан",
        "timezoneregion-pacific": "Тийна океан",
        "allowemail": "Магийта декъашхошна хьайга электронан поштехула кехат кхехьийта",
+       "email-allow-new-users-label": "Магийта керла декъашхошна хьайга электронан поштехула кехат кхехьийта",
        "email-blacklist-label": "ХӀокху декъашхошна электронан пошт соьга яийта бехкам-бе:",
        "prefs-searchoptions": "Лахар",
        "prefs-namespaces": "ЦӀерийн меттигаш",
        "rcfilters-other-review-tools": "Талларан кхин гӀирсаш",
        "rcfilters-group-results-by-page": "Карийнарш, агӀонгахь тобанаш ян",
        "rcfilters-activefilters": "Жигара литтарш",
+       "rcfilters-activefilters-hide": "Къайла",
+       "rcfilters-activefilters-show": "Гайта",
+       "rcfilters-activefilters-hide-tooltip": "Къайладаха жигара литтарш",
+       "rcfilters-activefilters-show-tooltip": "Гайта жигара литтарш",
        "rcfilters-advancedfilters": "Шуьйра литтарш",
        "rcfilters-limit-title": "Гойту хийцамаш",
        "rcfilters-limit-and-date-label": "$1 {{PLURAL:$1|хийцам}}, $2",
        "special-characters-group-greek": "Грекийн",
        "special-characters-group-greekextended": "Грекийн алсам",
        "special-characters-group-cyrillic": "Кирилан",
-       "special-characters-group-arabic": "Ӏарбийн",
+       "special-characters-group-arabic": "Ó\80аÑ\8cÑ\80бийн",
        "special-characters-group-arabicextended": "Ӏаьрбийн алсам",
        "special-characters-group-persian": "Пхьарсхойн",
        "special-characters-group-hebrew": "Жуьгтийн",
        "credentialsform-provider": "ДӀаяздарийн тайпа:",
        "credentialsform-account": "Декъашхочун цӀе:",
        "userjsispublic": "Тергам бе: JavaScript бухара агӀонаш чохь къайлаха хаамаш хийла ца беза, уьш массо декъашхойн тӀекхочуш йолу дера.",
-       "usercssispublic": "Тергам бе: CSS бухара агӀонаш чохь къайлаха хаамаш хийла ца беза, уьш массо декъашхойн тӀекхочуш йолу дера."
+       "usercssispublic": "Тергам бе: CSS бухара агӀонаш чохь къайлаха хаамаш хийла ца беза, уьш массо декъашхойн тӀекхочуш йолу дера.",
+       "passwordpolicies": "Паролийн политика",
+       "passwordpolicies-summary": "ХӀокху агӀонгахь гойту декъашхойн паролашна болу бехкам. Декъашхойн юкъабогӀуш болу бакъонийн тобанашка хьажжина бу бехкам.",
+       "passwordpolicies-policy-minimalpasswordlength": "Пароль $1 {{PLURAL:$1|символал}} еха хила еза",
+       "passwordpolicies-policy-passwordcannotmatchusername": "Пароль декъашхочун цӀерах тера хила ца еза",
+       "passwordpolicies-policy-passwordcannotmatchblacklist": "Пароль Ӏаьржачу могӀаман юкъахь йолучарех тера хила ца еза",
+       "passwordpolicies-policy-maximalpasswordlength": "Пароль $1 {{PLURAL:$1|символал}} йоца хила ца еза",
+       "passwordpolicies-policy-passwordcannotbepopular": "Пароль дукха {{PLURAL:$1|лелош йолчарех хила ца еза}}"
 }
index ef417f5..53337d1 100644 (file)
        "rcfilters-advancedfilters": "پاڵوێنە پێشکەوتووەکان",
        "rcfilters-limit-title": "ئەنجام بۆ نیشاندان",
        "rcfilters-limit-and-date-label": "$1 گۆڕانکاری، $2",
+       "rcfilters-date-popup-title": "ماوە بۆ گەڕان",
+       "rcfilters-days-title": "ڕۆژ",
+       "rcfilters-hours-title": "کاتژمێر",
        "rcfilters-days-show-days": "$1 {{PLURAL:$1|ڕۆژ}}",
        "rcfilters-quickfilters": "پاڵوێنە پاشەکەوتکراوەکان",
        "rcfilters-quickfilters-placeholder-title": "ھیچ پاڵوێنەیەک پاشەکەوت نەکراوە",
        "rcfilters-view-tags-help-icon-tooltip": "زیاتر بزانە لەسەر دەستکارییە تاگکراوەکان",
        "rcfilters-liveupdates-button": "نوێکردنەوەی زیندوو",
        "rcnotefrom": "ژێرەوە {{PLURAL:$5|گۆڕانکارییەکەیە|گۆڕانکارییەکانە}} لە <strong>$3، $4</strong>ەوە (ھەتا <strong>$1</strong> نیشان دراوە).",
+       "rclistfromreset": "گەڕاندنەوەی ھەڵبژاردەی بەروار",
        "rclistfrom": "گۆڕانکارییە نوێکان نیشان بدە بە دەستپێکردن لە $3 $2",
        "rcshowhideminor": "دەستکارییە بچووکەکان $1",
        "rcshowhideminor-show": "نیشان بدە",
        "special-characters-group-gujarati": "گوجەراتی",
        "special-characters-group-thai": "تایلەندی",
        "special-characters-group-khmer": "خمێری",
+       "mw-widgets-dateinput-no-date": "ڕێکەوت ھەڵنەبژێردراوە",
        "mw-widgets-usersmultiselect-placeholder": "زیادکردن...",
+       "date-range-from": "لە ڕێکەوتی:",
+       "date-range-to": "بۆ ڕێکەوتی:",
        "log-action-filter-block": "جۆری بلۆک:",
        "log-action-filter-contentmodel": "جۆری گۆڕینی مۆدێلی ناوەڕۆک:",
        "log-action-filter-all": "ھەموو",
index 2e8bf97..ca35efc 100644 (file)
        "rcfilters-other-review-tools": "Muud ülevaatusriistad",
        "rcfilters-group-results-by-page": "Rühmita tulemused lehekülje kaupa",
        "rcfilters-activefilters": "Aktiivsed filtrid",
+       "rcfilters-activefilters-hide": "Peida",
+       "rcfilters-activefilters-show": "Näita",
+       "rcfilters-activefilters-hide-tooltip": "Peida aktiivsete filtrite ala",
+       "rcfilters-activefilters-show-tooltip": "Kuva aktiivsete filtrite ala",
        "rcfilters-advancedfilters": "Täpsemad filtrid",
        "rcfilters-limit-title": "Näita nii mitut tulemust",
        "rcfilters-limit-and-date-label": "$1 {{PLURAL:$1|muudatus|muudatust}}, $2",
        "rcfilters-highlighted-filters-list": "Esile tõstetud: $1",
        "rcfilters-quickfilters": "Salvestatud filtrid",
        "rcfilters-quickfilters-placeholder-title": "Filtreid pole veel salvestatud",
-       "rcfilters-quickfilters-placeholder-description": "Et filtri sätted salvestada ja et neid hiljem uuesti kasutada, klõpsa alloleva aktiivsete filtrite loendi juures järjehoidjaikooni.",
+       "rcfilters-quickfilters-placeholder-description": "Filtri sätete salvestamiseks (et neid hiljem uuesti kasutada) klõpsa alloleva aktiivsete filtrite loendi juures järjehoidjaikooni.",
        "rcfilters-savedqueries-defaultlabel": "Salvestatud filtrid",
        "rcfilters-savedqueries-rename": "Nimeta ümber",
        "rcfilters-savedqueries-setdefault": "Määra vaikefiltriteks",
        "rcfilters-restore-default-filters": "Taasta vaikefiltrid",
        "rcfilters-clear-all-filters": "Eemalda kõik filtrid",
        "rcfilters-show-new-changes": "Vaata uusimaid muudatusi",
-       "rcfilters-search-placeholder": "Filtri muudatusi (kasuta menüüd või otsi filtri nime)",
+       "rcfilters-search-placeholder": "Filtreeri muudatusi (kasuta menüüd või tipi filtri nimi)",
        "rcfilters-invalid-filter": "Vigane filter",
        "rcfilters-empty-filter": "Aktiivsed filtrid puuduvad. Näidatakse kogu kaastööd.",
        "rcfilters-filterlist-title": "Filtrid",
index c93d35d..88d39dd 100644 (file)
        "grant-createaccount": "Kontuak sortu",
        "grant-createeditmovepage": "Orrialdeak sortu, aldatu eta mugitu",
        "grant-delete": "Ezabatu orriak, berrikuspenak eta sarrerak",
-       "grant-editinterface": "MediaWiki izen eremua eta CSS/JavaScript erabiltzailea aldatu",
+       "grant-editinterface": "MediaWiki izen eremua eta CSS/JSON/JavaScript erabiltzailea aldatu",
        "grant-editmycssjs": "Zure CSS/JSON/JavaScript erabiltzailea aldatu",
        "grant-editmyoptions": "Aldatu zure hobespenak",
        "grant-editmywatchlist": "Zure jarraipen zerrenda aldatu",
        "apisandbox-dynamic-parameters-add-label": "Gehitu parametroa:",
        "apisandbox-dynamic-parameters-add-placeholder": "Parametroaren izena",
        "apisandbox-dynamic-error-exists": "$1 parametro izena dagoeneko existitzen da",
+       "apisandbox-templated-parameter-reason": "[[Special:ApiHelp/main#main/templatedparams|templated parameter]] Hau $2-(a)ren {{PLURAL:$1|balio $1-ean|$1 baliotan}} oinarrituta dago eskainita.",
        "apisandbox-deprecated-parameters": "Aurretiaz zehaztutako parametroak",
        "apisandbox-fetch-token": "Token-a automatikoki bete",
        "apisandbox-add-multi": "Gehitu",
        "deletionlog": "ezabaketa erregistroa",
        "log-name-create": "Orri sorkuntzaren erregistroa",
        "log-description-create": "Azpian, sortutako azken orrien zerrenda ageri da.",
+       "logentry-create-create": "$1 {{GENDER:$2|erabiltzaileak}} $3 orria sortu du",
        "reverted": "Lehenagoko berrikuspen batera itzuli da",
        "deletecomment": "Arrazoia:",
        "deleteotherreason": "Arrazoi gehigarria:",
        "rollback-success": "{{GENDER:$3|$1}}; wikilariaren aldaketak deseginda,\nedukia {{GENDER:$4|$2}} wikilariaren azken bertsiora itzuli da.",
        "rollback-success-notify": "$1k leheneratutako aldaketal;\nazkenengo berrikusketara aldatu da berriz $2ren eskutik. [$3 Erakutsi aldaketak]",
        "sessionfailure-title": "Saio-akatsa",
-       "sessionfailure": "Badirudi saioarekin arazoren bat dagoela; bandalismoak saihesteko ekintza hau ezeztatu egin da. Mesedez, nabigatzaileko \"atzera\" botoian klik egin, hona ekarri zaituen orrialde hori berriz kargatu, eta saiatu berriz.",
+       "sessionfailure": "Badirudi saioarekin arazoren bat dagoela; ekintza hau ezeztatua izan da, saio bahiketa saihesteko neurri bezala. Mesedez, nabigatzaileko \"atzera\" botoian klik egin, hona ekarri zaituen orrialde hori berriz kargatu, eta saiatu berriz.",
        "changecontentmodel": "Aldatu orri bateko eduki eredua",
        "changecontentmodel-legend": "Aldatu eduki eredua",
        "changecontentmodel-title-label": "Orriaren izenburua",
        "fix-double-redirects": "Eguneratu jatorrizko izenburura zuzendutako birbideratze guztiak",
        "move-leave-redirect": "Utzi atzean birbideratzea",
        "protectedpagemovewarning": "'''Oharra:''' Orrialde hau babestua izan da, beraz administratzaile eskumenak dituztenek alda dezakete bakarrik.\nAzken erregistroko sarrera ematen da azpian erreferentzia gisa:",
-       "semiprotectedpagemovewarning": "'''Oharra:''' Orrialde hau blokeatu dute, izena emanda duten erabiltzaileek soilik mugitu ahal dezaten. Erregistroko azken sarrera erakusten da jarraian erreferentzia gisa:",
+       "semiprotectedpagemovewarning": "<strong>Oharra:</strong> Orrialde hau blokeatu dute, izena emanda duten erabiltzaileek soilik mugitu ahal dezaten. Erregistroko azken sarrera jarraian erakusten da erreferentzia gisa:",
        "move-over-sharedrepo": "[[:$1]] datu-base partekatu batean existitzen da. Izenburu honetara fitxategi bat mugitzean partekatutako fitxategia gainezarriko du.",
        "file-exists-sharedrepo": "Aukeratutako artxibo izena jadanik partekatutako biltegi batean erabiltzen ari da. Aukeratu beste izen bat mesedez.",
        "export": "Orrialdeak esportatu",
        "thumbnail_dest_directory": "Ezinezkoa izan da helburu direktorioa sortu",
        "thumbnail_image-type": "Irudi mota ez babestua",
        "thumbnail_gd-library": "GD liburutegiaren konfigurazio osagabea: $1 funtzioa falta da",
+       "thumbnail_image-size-zero": "Irudi fitxategiaren tamaina zero dela dirudi.",
        "thumbnail_image-missing": "Fitxategirik ez dagoela dirudi: $1",
        "thumbnail_image-failure-limit": "Koadro txikiak sortzeko saiakera galduak ($1 edo gehiago) gehiegi izan dira. Saiatu berriz geroago mesedez.",
        "import": "Orrialdeak inportatu",
        "tooltip-preferences-save": "Hobespenak gorde",
        "tooltip-summary": "Laburpen labur bat sar ezazu",
        "common.css": "/** Hemen idatzitako CSS kodeak itxura guztietan izango du eragina */",
+       "common.json": "/* Hemen idatzitako JSON oro erabiltzaile guztiek edozein orrialde irekitzerakoan kargatuko da. */",
        "common.js": "/* Hemen idatzitako JavaScript kode oro erabiltzaile guztiek edozein orrialde irekitzerakoan kargatuko da. */",
        "anonymous": "{{SITENAME}}(e)ko lankide {{PLURAL:$1|anonimoa|anonimoak}}",
        "siteuser": "{{SITENAME}}(e)ko $1 erabiltzailea",
        "watchlistedit-clear-titles": "Izenburuak:",
        "watchlistedit-clear-submit": "Garbitu jarraipen zerrenda (Behin betiko da!)",
        "watchlistedit-clear-done": "Zure jarraipen-zerrenda garbitu da.",
+       "watchlistedit-clear-jobqueue": "Jarraipen zerrenda garbitzen ari da. Prozesu honen denbora apur bat luza daiteke!",
        "watchlistedit-clear-removed": "{{PLURAL:$1|Izenburu 1 kendu da|$1 izenburu kendu dira}}:",
        "watchlistedit-too-many": " Orrialde gehiegi, hemen erakusteko.",
        "watchlisttools-clear": "Garbitu jarraipen-zerrenda",
        "limitreport-expansiondepth": "Gehienezko espantsio sakonera",
        "limitreport-expensivefunctioncount": "Parser funtzio kontaketa garestia",
        "limitreport-unstrip-depth": "Unstrip errekurtsio sakona",
+       "limitreport-unstrip-size-value": "{{PLURAL:$2|byte $1/$2|$1/$2 byte}}",
        "expandtemplates": "Txantiloi ordezkatzailea",
        "expand_templates_intro": "Orri berezi honek wiki-testua hartu eta txantiloi guztiak modu errekurtsiboan zabaltzen ditu.\nOnartutako funtzio sintaktikoak ere ordezkatzen ditu, hala nola\n<code><nowiki>{{</nowiki>#language:…}}</code>; eta aldagaiak ere, hala nola\n<code><nowiki>{{</nowiki>CURRENTDAY}}</code>.\nIzan ere, kortxete bikoitzen arteko ia edozer zabaltzen du.",
        "expand_templates_title": "Izenburua ({{FULLPAGENAME}} ordezkatzeko, eta abar):",
        "unlinkaccounts-success": "Kontua desestekatu da.",
        "authenticationdatachange-ignored": "Autentifikazio datuen aldaketa ez da kudeatu. Beharbada ez da hornitzailerik konfiguratu?",
        "userjsispublic": "Kontutan izan mesedez: JavaScript azpiorriek ez lukete datu konfidentzialik eraman behar, beste erabiltzaileek ikusi ahal dituztelako.",
+       "userjsonispublic": "Gogoratu: JSON azpiorriek ez dute datu konfidentzialik eduki behar, beste erabiltzaile batzuek ikus ditzaketelako.",
        "usercssispublic": "Kontutan izan mesedez: CSS azpiorriek ez lukete datu konfidentzialik eraman behar, beste erabiltzaileek ikusi ahal dituztelako.",
        "restrictionsfield-badip": "Baliogabeko IP helbide edo eremua: $1",
        "restrictionsfield-label": "Onartutako IP eremuak:",
        "passwordpolicies-policy-minimalpasswordlength": "Pasahitzak gutxienez {{PLURAL:$1|kraktere $1eko|$1 karaktereko}} luzera izan behar du",
        "passwordpolicies-policy-minimumpasswordlengthtologin": "Pasahitzak gutxienez {{PLURAL:$1|kraktere $1eko|$1 karaktereko}} luzera izan behar du saioa hasi ahal izateko",
        "passwordpolicies-policy-passwordcannotmatchusername": "Pasahitza ezin da erabiltzaile izenaren berdina izan",
-       "passwordpolicies-policy-passwordcannotmatchblacklist": "Pasahitza ezin da zerrenda beltzean zehaztutakoren bat izan"
+       "passwordpolicies-policy-passwordcannotmatchblacklist": "Pasahitza ezin da zerrenda beltzean zehaztutakoren bat izan",
+       "passwordpolicies-policy-maximalpasswordlength": "Pasahitza ezin da {{PLURAL:$1|karaktere $1|$1 karaktere}} baino luzeagoa izan",
+       "passwordpolicies-policy-passwordcannotbepopular": "Pasahitza ezin da {{PLURAL:$1|pasahitz erabiliena izan|$1 pasahitz erabilienen zerrendan egon}}"
 }
index 0d44d82..f27a9cd 100644 (file)
@@ -65,7 +65,8 @@
                        "Alp Er Tunqa",
                        "Baloch Khan",
                        "Fitoschido",
-                       "Alireza Ivaz"
+                       "Alireza Ivaz",
+                       "Iriman"
                ]
        },
        "tog-underline": "خط کشیدن زیر پیوندها:",
        "filehist-dimensions": "ابعاد",
        "filehist-filesize": "اندازهٔ پرونده",
        "filehist-comment": "توضیح",
-       "imagelinks": "به‌کاررفتن پرونده",
+       "imagelinks": "کاربرد پرونده",
        "linkstoimage": "{{PLURAL:$1|صفحهٔ|صفحه‌های}} زیر به این تصویر پیوند {{PLURAL:$1|دارد|دارند}}:",
        "linkstoimage-more": "بیش از $1 صفحه به این پرونده پیوند {{PLURAL:$1|دارد|دارند}}.\nفهرست زیر تنها {{PLURAL:$1|اولین پیوند|اولین $1 پیوند}} به این صفحه را نشان می‌دهد.\n[[Special:WhatLinksHere/$2|فهرست کامل]] نیز موجود است.",
        "nolinkstoimage": "این پرونده در هیچ صفحه‌ای به کار نرفته‌است.",
index 2d03e12..b69d49c 100644 (file)
@@ -12,7 +12,8 @@
                        "Macofe",
                        "Matma Rex",
                        "Nemo bis",
-                       "Fitoschido"
+                       "Fitoschido",
+                       "Tacsipacsi"
                ]
        },
        "tog-underline": "Ferwisangen onerstrik:",
        "category_header": "Sidjen uun kategorii \"$1\"",
        "subcategories": "Onerkategoriin",
        "category-media-header": "Meedien uun kategorii \"$1\"",
-       "category-empty": "\"Uun detdiar kategorii san uun uugenblak nian sidjen of meedien.\"",
+       "category-empty": "<em>Uun detdiar kategorii san uun uugenblak nian sidjen of meedien.</em>",
        "hidden-categories": "{{PLURAL:$1|Ferbürgen kategorii|Ferbürgen kategoriin}}",
        "hidden-category-category": "Ferbürgen kategoriin",
        "category-subcat-count": "{{PLURAL:$2|Detdiar kategorii hää ian onerkategorii.|Uun detdiar kategorii {{PLURAL:$1|stäänt ian onerkategorii|stun $1 onerkategoriin}} faan $2 uun't gehial.}}",
index d63d371..79e62fe 100644 (file)
        "nav-login-createaccount": "Oanmelde",
        "logout": "Ofmelde",
        "userlogout": "Ofmelde",
-       "notloggedin": "Net oanmelde",
+       "notloggedin": "Net oanmeld",
        "userlogin-noaccount": "Hasto gjin akkount?",
        "userlogin-joinproject": "Meidwaan {{SITENAME}}",
        "createaccount": "Registrearje",
        "upload": "Bied triem oan",
        "uploadbtn": "Bied triem oan",
        "reuploaddesc": "Werom nei oanbied-side.",
-       "uploadnologin": "Net oanmelde",
+       "uploadnologin": "Net oanmeld",
        "uploadnologintext": "Jo moatte [[Special:UserLogin|oanmeld]] wêze om in triem oanbiede te kinnen.",
        "upload_directory_missing": "De heechlaadmap ($1) is der net en koe net oanmakke wurde troch de webserver.",
        "upload_directory_read_only": "De webserver kin net skriuwe yn de oanbiedpad ($1).",
index 8e925ca..7c25725 100644 (file)
        "confirm-unwatch-button": "אישור",
        "confirm-unwatch-top": "להסיר את הדף הזה מרשימת המעקב שלך?",
        "confirm-rollback-button": "אישור",
-       "confirm-rollback-top": "×\9cש×\97×\96ר ×\90ת ×\94ש×\99× ×\95×\99×\99×\9d ×\9c×\93×£ ×\94זה?",
+       "confirm-rollback-top": "×\9cש×\97×\96ר ×\90ת ×\94ער×\99×\9b×\95ת ×\91×\93×£ זה?",
        "quotation-marks": "\"$1\"",
        "imgmultipageprev": "→ לדף הקודם",
        "imgmultipagenext": "לדף הבא ←",
        "watchlisttools-raw": "עריכת רשימת המעקב הגולמית",
        "iranian-calendar-m1": "פרורדין",
        "iranian-calendar-m2": "ארדיבהשת",
-       "iranian-calendar-m3": "ח׳רדאד",
+       "iranian-calendar-m3": "ח'רדאד",
        "iranian-calendar-m4": "תיר",
        "iranian-calendar-m5": "מרדאד",
        "iranian-calendar-m6": "שהריור",
        "iranian-calendar-m7": "מהר",
        "iranian-calendar-m8": "אבאן",
-       "iranian-calendar-m9": "אד׳ר",
+       "iranian-calendar-m9": "אד'ר",
        "iranian-calendar-m10": "די",
        "iranian-calendar-m11": "בהמן",
        "iranian-calendar-m12": "אספנד",
index 55eba4d..2eeb713 100644 (file)
        "rcfilters-other-review-tools": "Ostali alati za pregledavanje:",
        "rcfilters-group-results-by-page": "Grupiranje rezultata po stranici",
        "rcfilters-activefilters": "Aktivni filtri",
+       "rcfilters-activefilters-hide": "Skrij",
+       "rcfilters-activefilters-show": "Pokaži",
        "rcfilters-advancedfilters": "Napredni filtri",
        "rcfilters-limit-title": "Rezultata za prikaz",
        "rcfilters-limit-and-date-label": "{{PLURAL:$1|$1 izmjena|$1 izmjene|$1 izmjena}}, $2",
index 6bd9201..9264fbb 100644 (file)
        "rcfilters-activefilters": "Aktív szűrők",
        "rcfilters-activefilters-hide": "Elrejt",
        "rcfilters-activefilters-show": "Mutat",
+       "rcfilters-activefilters-hide-tooltip": "Aktív szűrők dobozának elrejtése",
+       "rcfilters-activefilters-show-tooltip": "Aktív szűrők dobozának megjelenítése",
        "rcfilters-advancedfilters": "Haladó szűrők",
        "rcfilters-limit-title": "Megjelenítendő találatok száma",
        "rcfilters-limit-and-date-label": "$1 változtatás, $2",
index f632abc..5c9ac57 100644 (file)
        "resetpass-submit-loggedin": "Cambiar contrasigno",
        "resetpass-submit-cancel": "Cancellar",
        "resetpass-wrong-oldpass": "Le contrasigno temporari o actual es invalide.\nEs possibile que tu ha ja cambiate tu contrasigno o requestate un nove contrasigno temporari.",
-       "resetpass-recycled": "Redefini tu contrasigno a un differente del actual, per favor.",
+       "resetpass-recycled": "Cambia tu contrasigno a un differente del actual, per favor.",
        "resetpass-temp-emailed": "Tu ha aperite session con un codice temporari que tu recipeva in e-mail.\nPro completar le accesso, tu debe definir un nove contrasigno hic:",
        "resetpass-temp-password": "Contrasigno temporari:",
        "resetpass-abort-generic": "Le cambio del contrasigno ha essite abortate per un extension.",
        "resetpass-expired": "Le contrasigno ha expirate. Per favor defini un nove contrasigno pro aperir session.",
-       "resetpass-expired-soft": "Le contrasigno ha expirate e debe esser redefinite. Per favor elige un nove contrasigno ora, o clicca sur \"{{int:authprovider-resetpass-skip-label}}\" pro redefinir lo plus tarde.",
-       "resetpass-validity-soft": "Le contrasigno non es valide: $1\n\nPer favor elige un nove contrasigno ora, o clicca sur \"{{int:authprovider-resetpass-skip-label}}\" pro redefinir lo plus tarde.",
+       "resetpass-expired-soft": "Le contrasigno ha expirate e debe esser cambiate. Per favor, elige un nove contrasigno ora, o clicca sur \"{{int:authprovider-resetpass-skip-label}}\" pro cambiar lo plus tarde.",
+       "resetpass-validity-soft": "Le contrasigno non es valide: $1\n\nPer favor, elige un nove contrasigno ora, o clicca sur \"{{int:authprovider-resetpass-skip-label}}\" pro cambiar lo plus tarde.",
        "passwordreset": "Reinitialisar contrasigno",
        "passwordreset-text-one": "Completa iste formulario pro reinitialisar tu contrasigno.",
        "passwordreset-text-many": "{{PLURAL:$1|Completa un de iste campos pro reciper un contrasigno temporari in e-mail.}}",
        "converter-manual-rule-error": "Error detegite in le regula manual de conversion de lingua",
        "undo-success": "Le modification pote esser disfacite.\nPer favor controla le comparation infra pro verificar que tu vole facer isto, e postea salveguarda le modificationes infra pro assi disfacer le modification.",
        "undo-failure": "Le modification non poteva esser annullate a causa de conflicto con modificationes intermedie.",
+       "undo-main-slot-only": "Le modification non poteva esser disfacite perque illo implica contento foras del cannellatura principal.",
        "undo-norev": "Impossibile annullar le modification proque illo non existe o esseva delite.",
        "undo-nochange": "Pare que iste modification ha jam essite disfacite.",
        "undo-summary": "Annullava le version $1 per [[Special:Contributions/$2|$2]] ([[User talk:$2|Discussion]] | [[Special:Contributions/$2|{{MediaWiki:Contribslink}}]])",
        "rcfilters-other-review-tools": "Altere instrumentos de revision",
        "rcfilters-group-results-by-page": "Gruppar resultatos per pagina",
        "rcfilters-activefilters": "Filtros active",
+       "rcfilters-activefilters-hide": "Celar",
+       "rcfilters-activefilters-show": "Monstrar",
+       "rcfilters-activefilters-hide-tooltip": "Celar le area de filtros active",
+       "rcfilters-activefilters-show-tooltip": "Monstrar le area de filtros active",
        "rcfilters-advancedfilters": "Filtros avantiate",
        "rcfilters-limit-title": "Resultatos a monstrar",
        "rcfilters-limit-and-date-label": "$1 modification{{PLURAL:$1||es}}, $2",
        "rcfilters-savedqueries-rename": "Renominar",
        "rcfilters-savedqueries-setdefault": "Predefinir",
        "rcfilters-savedqueries-unsetdefault": "Remover predefinition",
-       "rcfilters-savedqueries-remove": "Remover",
+       "rcfilters-savedqueries-remove": "Deler",
        "rcfilters-savedqueries-new-name-label": "Nomine",
        "rcfilters-savedqueries-new-name-placeholder": "Describe le proposito del filtro",
        "rcfilters-savedqueries-apply-label": "Crear filtro",
        "rcfilters-empty-filter": "Nulle filtro active. Tote le contributiones es monstrate.",
        "rcfilters-filterlist-title": "Filtros",
        "rcfilters-filterlist-whatsthis": "Como functiona istes?",
-       "rcfilters-filterlist-feedbacklink": "Da nos tu opinion sur iste (nove) instrumentos de filtrage",
+       "rcfilters-filterlist-feedbacklink": "Da nos tu opinion sur iste instrumentos de filtrage",
        "rcfilters-highlightbutton-title": "Colorar le resultatos",
        "rcfilters-highlightmenu-title": "Selige un color",
        "rcfilters-highlightmenu-help": "Selige un color pro illuminar iste proprietate",
index 7f27e4a..b095455 100644 (file)
        "rcfilters-days-show-hours": "$1 {{PLURAL:$1|horo|hori}}",
        "rcfilters-quickfilters": "Konservita filtrili",
        "rcfilters-quickfilters-placeholder-title": "Nula filtrilo konservesis til nun",
+       "rcfilters-quickfilters-placeholder-description": "Por konservar vua ajusto di filtrili ed uzar li pose, kliktez en la marko-rubando ikono en la buxo adinfre, ube l'agiva filtrili montresas.",
        "rcfilters-savedqueries-defaultlabel": "Konservita filtrili",
+       "rcfilters-clear-all-filters": "Efacar omna filtrili",
        "rcfilters-show-new-changes": "Videz la maxim recenta chanji",
        "rcfilters-search-placeholder": "Filtrar la modifikuri (uzez la menuo o serchez segun la nomo dil filtrilo)",
        "rcfilters-filterlist-feedbacklink": "Dicez a ni quon vu pensas pri la filtrili",
        "protectexpiry": "Expiras:",
        "protect_expiry_invalid": "Expirotempo es ne-valida.",
        "protect_expiry_old": "Expirotempo es in pasinta.",
+       "protect-cascadeon": "Ica pagino esas nune protektita, pro ke existas kopio de ol en {{PLURAL:$1|pagino qua|pagini qui}} protektesas \"seriale\" (cascade protection).\nModifiki en la nivelo di protektado por ica pagino ne modifikos la \"protekto seriala\".",
        "protect-default": "Permisar omna uzanti",
        "protect-fallback": "Permisez nur uzeri kun permiso \"$1\"",
        "protect-level-autoconfirmed": "Permisar nur uzeri automatale konfirmata",
index 3aa9d6f..6d5ce82 100644 (file)
        "customcssprotected": "Þú hefur ekki leyfi að breyta þessari CSS-umbrotsíðu, því hún hefur notandastillingar annars notanda.",
        "customjsprotected": "Þú hefur ekki leyfi til að breyta þessari JavaScript síðu, því hún hefur notandastillingar annars notanda.",
        "mycustomcssprotected": "Þú hefur ekki leyfi til þess að breyta þessari CSS-síðu.",
+       "mycustomjsonprotected": "Þú hefur ekki heimild til að breyta þessari JSON-síðu.",
        "mycustomjsprotected": "Þú hefur ekki leyfi til þess að breyta þessari JavaScript-síðu.",
        "myprivateinfoprotected": "Þú ert ekki með réttindi til að breyta einkaupplýsingunum þínum.",
        "mypreferencesprotected": "Þú ert ekki með réttindi til að breyta kjörstillingunum þínum.",
        "wrongpasswordempty": "Lykilorðsreiturinn var auður. Reyndu aftur.",
        "passwordtooshort": "Lykilorð skal vera að minnsta kosti $1 {{PLURAL:$1|stafur|stafir}}.",
        "passwordtoolong": "Lykilorð geta ekki verið lengri en $1 {{PLURAL:$1|stafur|stafir}}.",
-       "passwordtoopopular": "Ekki má nota algeng lykilorð. Veldu eitthvað alveg sérstakt lykilorð.",
+       "passwordtoopopular": "Ekki má nota títt valin lykilorð. Vinsamlegast velja lykilorð sem erfiðara er að giska á.",
        "password-name-match": "Þarf að lykilorð þitt sé öðruvísi notandanafni þínu",
        "password-login-forbidden": "Notkun þessa notandanafns og lykilorðs er ekki leyfileg.",
        "mailmypassword": "Endurstilla lykilorð",
        "botpasswords-existing": "Fyrirliggjandi lykilorð vélmenna",
        "botpasswords-createnew": "Búa til nýtt lykilorð vélmennis",
        "botpasswords-editexisting": "Breyta fyrirliggjandi lykilorði vélmennis",
+       "botpasswords-label-needsreset": "(lykilorð þarf að endurstilla)",
        "botpasswords-label-appid": "Heiti vélmennis:",
        "botpasswords-label-create": "Búa til",
        "botpasswords-label-update": "Uppfæra",
        "savechanges": "Vista breytingar",
        "publishpage": "Gefa út síðu",
        "publishchanges": "Gefa út breytingar",
+       "savearticle-start": "Vista síðu…",
+       "savechanges-start": "Vista breytingar…",
+       "publishpage-start": "Birta síðu...",
+       "publishchanges-start": "Gefa út breytingar...",
        "preview": "Forskoða",
        "showpreview": "Forskoða",
        "showdiff": "Sýna breytingar",
        "anoneditwarning": "<strong>Viðvörun:</strong> Þú ert ekki innskráð(ur). Vistfang þitt verður sýnt opinberlega ef þú gerir einhverjar breytingar. Ef þú <strong>[$1 skráir þig inn]</strong> eða <strong>[$2 stofnar aðgang]</strong> munu breytingarnar þínar vera tengdar við notandanafn þitt, ásamt öðrum kostum.",
        "anonpreviewwarning": "<em>Þú ert ekki skráð(ur) inn. Vistfang þitt skráist í breytingaskrá síðunnar.</em>",
        "missingsummary": "'''Áminning:''' Þú hefur ekki skrifað breytingarágrip.\nEf þú smellir á Vista aftur, verður breyting þín vistuð án þess.",
+       "selfredirect": "<strong>Viðvörun:</strong> Þú ert að vísa þessa síðu á sjálfa sig.\nÞað kann að vera að þú hafir valið vitlausa marksíðu fyrir tilvísunina eða að þú sért að breyta vitlausri síðu.\nEf þú smellir aftur á „$1“ verður tilvísunin samt búin til.",
        "missingcommenttext": "Gerðu svo vel og skrifaðu athugasemd.",
        "missingcommentheader": "<strong>Áminning:</strong> Þú hefur ekki gefið upp umræðuefni.\nEf þú smellir á \"$1\" aftur, verður breyting þín vistuð án þess.",
        "summary-preview": "Forskoða breytingarágrip:",
        "subject-preview": "Forskoðun viðfangsefnis:",
        "previewerrortext": "Óvænt villa kom upp þegar reynt var að forskoða breytingarnar þínar.",
        "blockedtitle": "Notandi er bannaður",
-       "blockedtext": "'''Notandanafn þitt eða vistfang hefur verið bannað.'''\n\nBannið var sett af $1.\nÁstæðan er eftirfarandi: ''$2''.\n\n* Bannið hófst: $8\n* Banninu lýkur: $6\n* Sá sem banna átti: $7\n\nÞú getur haft samband við $1 eða annan [[{{MediaWiki:Grouppage-sysop}}|stjórnanda]] til að ræða bannið.\nÞú getur ekki notað „Senda þessum notanda tölvupóst“ aðgerðina nema gilt netfang sé skráð í [[Special:Preferences|kjörstillingum þínum]] og að þér hafi ekki verið óheimilað það.\nNúverandi vistfang þitt er $3, og bannnúmerið er #$5.\nHafðu með allar þessar upplýsingar hér fyrir ofan í fyrirspurnum þínum.",
-       "autoblockedtext": "Vistfang þitt hefur verið sjálfvirkt bannað því það var notað af öðrum notanda, sem var bannaður af $1.\nÁstæðan er eftirfarandi:\n\n:''$2''\n\n* Bannið hófst: $8\n* Banninu lýkur: $6\n* Sá sem banna átti: $7\n\nÞú getur haft samband við $1 eða annan [[{{MediaWiki:Grouppage-sysop}}|stjórnanda]] til að ræða bannið.\n\nAthugaðu að þú getur ekki notað „Senda þessum notanda tölvupóst“ aðgerðina nema gilt netfang sé skráð í [[Special:Preferences|kjörstillingum þínum]] og að þér hafi ekki verið óheimilað það.\n\nNúverandi vistfang þitt er $3, og bannnúmerið er #$5.\nHafðu með allar þessar upplýsingar hér fyrir ofan í fyrirspurnum þínum.",
+       "blockedtext": "<strong>Þitt notandanafn eða vistfang hefur verið bannað.</strong>\n\nBannið var sett af $1.\nÁstæðan er eftirfarandi: <em>$2</em>.\n\n* Bannið hófst: $8\n* Banninu lýkur: $6\n* Sá sem banna átti: $7\n\nÞú getur haft samband við $1 eða annan [[{{MediaWiki:Grouppage-sysop}}|stjórnanda]] til að ræða bannið.\nÞú getur ekki notað „Senda þessum notanda tölvupóst“ aðgerðina nema gilt netfang sé skráð í [[Special:Preferences|kjörstillingum þínum]] og að þér hafi ekki verið óheimilað það.\nNúverandi vistfang þitt er $3, og bannnúmerið er #$5.\nHafðu með allar þessar upplýsingar hér fyrir ofan í fyrirspurnum þínum.",
+       "autoblockedtext": "Vistfang þitt hefur verið sjálfvirkt bannað því það var notað af öðrum notanda, sem var bannaður af $1.\nÁstæðan er eftirfarandi:\n\n:<em>$2</em>\n\n* Bannið hófst: $8\n* Banninu lýkur: $6\n* Sá sem banna átti: $7\n\nÞú getur haft samband við $1 eða annan [[{{MediaWiki:Grouppage-sysop}}|stjórnanda]] til að ræða bannið.\n\nAthugaðu að þú getur ekki notað „Senda þessum notanda tölvupóst“ aðgerðina nema gilt netfang sé skráð í [[Special:Preferences|kjörstillingum þínum]] og að þér hafi ekki verið óheimilað það.\n\nNúverandi vistfang þitt er $3, og bannnúmerið er #$5.\nHafðu með allar þessar upplýsingar hér fyrir ofan í fyrirspurnum þínum.",
        "systemblockedtext": "Notandanafnið þitt eða IP-vistfangið hafa verið útilokuð sjálfvirkt af MediaWiki.\nUppgefin ástæða er:\n\n:<em>$2</em>\n\n* Upphaf útilokunar: $8\n* Útilokun rennur út: $6\n* Sá sem átti að útiloka: $7\n\nNúverandi IP-vistfang þitt er$3.\nHafðu allar þessar upplýsingar með í öllum þeim fyrirspurnum sem þú gætir gert vegna þessa.",
        "blockednoreason": "engin ástæða gefin",
        "whitelistedittext": "Þú þarft að $1 þig til að breyta síðum.",
        "blocked-notice-logextract": "Þessi notandi er í banni.\nSíðasta færsla notandans úr bannskrá er birt hér fyrir neðan til skýringar:",
        "clearyourcache": "<strong>Athugaðu:</strong> Eftir vistun kann að vera að þú þurfir að komast hjá skyndiminni vafrans þíns til að sjá breytingarnar.\n* <strong>Firefox / Safari:</strong> Haltu <em>Shift</em> samtímis og þú smellir á <em>Endurhlaða (Reload)</em>, eða ýttu á annaðhvort <em>Ctrl-F5</em> eða <em>Ctrl-R</em> (<em>⌘-R</em> á Mac)\n* <strong>Google Chrome:</strong> Ýttu á <em>Ctrl-Shift-R </em>(<em>⌘-Shift-R</em> á Mac)\n* <strong>Internet Explorer:</strong> Haltu <em>Ctrl</em> samtímis og þú smellir á <em>Endurnýja (Refresh)</em>, eða ýttu á <em>Ctrl-F5</em>\n* <strong>Opera:</strong> Farðu í <em>Verkfæri (Tools) → Stillingar (Preferences)</em> og svo <em>Friðhelgi og öryggi (Privacy & security) → Hreinsa vafragögn (Clear browsing data) → Myndir og skrár í skyndiminni (Chached images and files)</em>",
        "usercssyoucanpreview": "'''Ath:''' Hægt er að nota „{{int:showpreview}}“ hnappinn til að prófa CSS-kóða áður en hann er vistaður.",
+       "userjsonyoucanpreview": "<strong>Ath.:</strong> Hægt er að nota hnappinn „{{int:showpreview}}“ til að prófa JSON-kóða áður en hann er vistaður.",
        "userjsyoucanpreview": "'''Ath:''' Hægt er að nota \"{{int:showpreview}}\" hnappinn til að prófa JavaScript-kóða áður en hann er vistaður.",
        "usercsspreview": "'''Mundu að þú ert aðeins að forskoða CSS-kóðann þinn.'''\n'''Hann hefur ekki enn verið vistaður!'''",
        "userjspreview": "'''Mundu að þú ert aðeins að prófa/forskoða JavaScript-kóðann þinn.'''\n'''Hann hefur ekki enn verið vistaður!'''",
        "rcfilters-other-review-tools": "Önnur rýniverkfæri",
        "rcfilters-group-results-by-page": "Flokka niðurstöður eftir síðum",
        "rcfilters-activefilters": "Virkar síur",
+       "rcfilters-activefilters-hide": "Fela",
+       "rcfilters-activefilters-show": "Sýna",
        "rcfilters-advancedfilters": "Ítarlegar síur",
        "rcfilters-limit-title": "Breytingar sem á að birta",
        "rcfilters-limit-and-date-label": "$1 {{PLURAL:$1|breyting|breytingar}}, $2",
        "rcfilters-savedqueries-rename": "Endurnefna",
        "rcfilters-savedqueries-setdefault": "Setja sem sjálfgefið",
        "rcfilters-savedqueries-unsetdefault": "Fjarlægja sjálfgefið",
-       "rcfilters-savedqueries-remove": "Fjarlægja",
+       "rcfilters-savedqueries-remove": "Eyða",
        "rcfilters-savedqueries-new-name-label": "Heiti",
        "rcfilters-savedqueries-new-name-placeholder": "Lýstu markmiði síunnar",
        "rcfilters-savedqueries-apply-label": "Búa til síu",
        "deadendpages": "Botnlangar",
        "deadendpagestext": "Eftirfarandi síður tengjast ekki við aðrar síður á {{SITENAME}}.",
        "protectedpages": "Verndaðar síður",
+       "protectedpages-filters": "Síur:",
        "protectedpages-indef": "Aðeins óendanlegar verndanir",
        "protectedpages-summary": "Þessi skrá sýnir lista yfir síður sem eru til og eru verndaðar í auknablikinu. Til að sjá lista yfir titla sem eru verndaðir gegn stofnun þeirra, sjáðu [[{{#special:ProtectedTitles}}|{{int:protectedtitles}}]].",
        "protectedpages-cascade": "Keðjuverndun eingöngu",
        "apisandbox-dynamic-parameters-add-label": "Bæta við viðfangi:",
        "apisandbox-dynamic-parameters-add-placeholder": "Heiti viðfangs",
        "apisandbox-deprecated-parameters": "Úrelt viðföng",
+       "apisandbox-add-multi": "Bæta við",
        "apisandbox-submit-invalid-fields-title": "Sumir reitir eru ógildir",
        "apisandbox-results": "Niðurstöður",
+       "apisandbox-sending-request": "Sendir API-beiðni...",
        "apisandbox-request-url-label": "Slóð á beiðni:",
        "apisandbox-request-format-json-label": "JSON",
        "apisandbox-request-json-label": "JSON beiðni:",
        "revertpage": "Tók aftur breytingar [[Special:Contributions/$2|$2]] ([[User talk:$2|spjall]]), breytt til síðustu útgáfu [[User:$1|$1]]",
        "revertpage-nouser": "Tók aftur breytingar falins notanda til síðustu útgáfu {{GENDER:$1|[[User:$1|$1]]}}",
        "rollback-success": "Tók til baka breytingar eftir {{GENDER:$3|$1}};\nsetti yfir á síðustu útgáfu eftir {{GENDER:$4|$2}}.",
+       "rollback-success-notify": "Tók aftur breytingar $1;\nbreytti í síðustu útgafu $2. [$3 Sýna breytingar]",
        "sessionfailure-title": "Mistök í setu",
        "sessionfailure": "Líklega er vandamál með innskráningarsetuna þína;\nhætt hefur verið við þessa aðgerð sem vörn gegn mögulegu samskiptaráni setunar.\nReyndu að senda upplýsingarnar aftur inn.",
+       "changecontentmodel": "Breyta efnislíkani síðu",
+       "changecontentmodel-legend": "Breyta efnislíkani",
        "changecontentmodel-title-label": "Titill síðu",
+       "changecontentmodel-model-label": "Nýtt efnislíkan",
        "changecontentmodel-reason-label": "Ástæða:",
        "changecontentmodel-submit": "Breyta",
+       "changecontentmodel-success-title": "Efnislíkaninu var breytt",
        "logentry-contentmodel-change-revertlink": "taka aftur",
        "logentry-contentmodel-change-revert": "taka aftur",
        "protectlogpage": "Verndunarskrá",
        "unblocked-id": "Bann $1 hefur verið fjarlægt",
        "unblocked-ip": "[[Special:Contributions/$1|$1]] hefur verið afbannaður.",
        "blocklist": "Bannaðir notendur og vistföng",
+       "autoblocklist": "Sjálfvirk bönn",
        "autoblocklist-submit": "Leita",
+       "autoblocklist-legend": "Sýna sjálfvirk bönn",
+       "autoblocklist-total-autoblocks": "Samanlagður fjöldi sjálfvirkra banna: $1",
+       "autoblocklist-empty": "Listinn yfir sjálfvirk bönn er tómur.",
+       "autoblocklist-otherblocks": "{{PLURAL:$1|Annað sjálfvirkt bann|Önnur sjálfvirk bönn}}",
        "ipblocklist": "Bannaðir notendur og vistföng",
        "ipblocklist-legend": "Finna bannaðan notanda",
        "blocklist-userblocks": "Fela notendabönn",
        "tooltip-ca-nstab-help": "Sýna hjálparsíðuna",
        "tooltip-ca-nstab-category": "Sýna efnisflokkasíðuna",
        "tooltip-minoredit": "Merkja þessa breytingu sem minniháttar",
-       "tooltip-save": "Vista breytingarnar",
-       "tooltip-publish": "Gefa út breytingarnar þínar",
+       "tooltip-save": "Vista breytingar þínar",
+       "tooltip-publish": "Gefa út breytingar þínar",
        "tooltip-preview": "Forskoða breytingarnar þínar. Gerðu þetta áður en þú vistar.",
        "tooltip-diff": "Sýna hvaða breytingar þú gerðir á textanum.",
        "tooltip-compareselectedversions": "Sjá breytingarnar á þessari grein á milli útgáfanna sem þú valdir.",
        "version-specialpages": "Kerfissíður",
        "version-parserhooks": "Tengikrókar þáttara (parser hooks)",
        "version-variables": "Breytur",
+       "version-editors": "Ritstjórar",
        "version-antispam": "Varnir gegn amasendingum",
        "version-api": "API",
        "version-other": "Aðrar",
        "tag-mw-new-redirect": "Ný endurbeining",
        "tag-mw-removed-redirect": "Fjarlægði endurbeiningu",
        "tag-mw-replace": "Skipt út",
+       "tag-mw-rollback": "Afturköllun",
        "tag-mw-undo": "Afturkalla",
        "tags-title": "Merki",
        "tags-intro": "Þessi síða sýnir merkin sem hugbúnaðurinn gæti merkt breytingar með, og hvað þau þýða.",
index 0d59119..082ed36 100644 (file)
        "revdelete-text-file": "削除されたファイルの版はファイルの履歴に表示されつづけますが、一般の利用者はその内容の一部を閲覧できなくなります。",
        "logdelete-text": "削除された記録項目は記録に表示され続けますが、一般の利用者はその内容の一部を閲覧できなくなります。",
        "revdelete-text-others": "追加の制限を設定しない限り、他の管理者は非表示コンテンツにまだアクセスすることも復元することもできます。",
-       "revdelete-confirm": "ã\81\93ã\81®æ\93\8dä½\9cã\82\92è¡\8cã\81\8aã\81\86ã\81¨ã\81\97ã\81¦ã\81\84ã\82\8bã\81\93ã\81¨ã\80\81ã\81\9dã\81®結果を理解していること、[[{{MediaWiki:Policy-url}}|方針]]に従っていること、を確認してください。",
+       "revdelete-confirm": "ã\81\93ã\81®æ\93\8dä½\9cã\81«ã\82\88ã\82\8aç\94\9fã\81\98ã\82\8b結果を理解していること、[[{{MediaWiki:Policy-url}}|方針]]に従っていること、を確認してください。",
        "revdelete-suppress-text": "秘匿は、<strong>以下の場合に限って</strong>使用すべきです:\n* 名誉毀損のおそれがある記述\n* 非公開個人情報\n*: <em>自宅の住所、電話番号、個人を識別できる公的な番号など</em>",
        "revdelete-legend": "閲覧レベル制限を設定",
        "revdelete-hide-text": "版の本文",
        "dellogpage": "削除記録",
        "dellogpagetext": "以下は最近の削除と復元の一覧です。",
        "deletionlog": "削除記録",
+       "log-name-create": "ページ作成記録",
+       "log-description-create": "以下はページ作成の最近の記録です。",
        "logentry-create-create": "$1 がページ「$3」を{{GENDER:$2|作成しました}}",
        "reverted": "以前の版への差し戻し",
        "deletecomment": "理由:",
index 6337ea4..95adaf8 100644 (file)
        "cascadeprotected": "Ankehitriny dia voaaro ity pejy ity satria misy pejy voaaro {{PLURAL:$1|iray|$1}} mampiasa ity pejy ity. Io pejy io dia mampiasa ny fiarovana \"mirihana\":\n\n$2",
        "namespaceprotected": "Tsy manana alalàna manova ny toeran'anarana « '''$1''' » ianao.",
        "customcssprotected": "Tsy afaka manova ity pejy CSS ity ianao satria misy ny safidy manokan'ny mpikambana hafa.",
+       "customjsonprotected": "Tsy manana alalalana manova ity pejy JSON ity ianao satria misy ny safidin'olon-kafa izy ity.",
        "customjsprotected": "Tsy afaka manova ity pejy JavaScript ity inaao satria misy ny safidin'ny mpikambana hafa.",
        "mycustomcssprotected": "Tsy manana ny alalana ahafahana manova ity pejy CSS ity ianao.",
+       "mycustomjsonprotected": "Tsy manana alalana manova ity pejy JSON ity ianao.",
        "mycustomjsprotected": "Tsy manana ny alalana ahafahana manova ity pejy JavaScript ity ianao.",
        "myprivateinfoprotected": "Tsy manana alalana ahafahana manova ny fampahalalana tsy sarababem-bahoakanao ianao.",
        "mypreferencesprotected": "Tsy manana alalana ahafahana manova ny safidinao ianao.",
        "changepassword-success": "Voaova soa aman-tsara ny tenimiafinao!",
        "changepassword-throttled": "Betsaka loatra ny andram-pidirana nataonao.\nAndraso $1 aloha ny mamerina.",
        "botpasswords": "Tenimiafin-drôbô",
+       "botpasswords-summary": "Ny <em>Tenimiafina rôbô</em> dia manome alalana ny mampiasa ny kaontim-pikambana iray amin'ny alalana API ka tsy mila mampiasa ny tenimiafin'ny mpikambana. Ny zom-pikambana ananana rehefa tafiditra amin'ny alalana tenimiafina rôbô dia mety ho voafetra.\n\nRaha tsy fantatrao ny antony hanaovanao izany dia tsy tokony hanao izany ianao. Tsy tokony hisy ny olona hangataka anao hamoaka iray amin'itony ary hanome azy.",
        "botpasswords-disabled": "Tsy ampiasaina ny tenimiafin-drôbô.",
+       "botpasswords-no-central-id": "Raha hampiasa tenimiafina rôbô dia tsy maintsy tafiditra anaty kaonty iombonan-tsehatra ianao.",
        "botpasswords-existing": "Tenimiafin-drôbô efa misy",
        "botpasswords-createnew": "Hamorona tenimiafina rôbô vaovao",
        "botpasswords-editexisting": "Hanova tenimiafina rôbô efa misy",
+       "botpasswords-label-needsreset": "(mila famerenana ny tenimiafina)",
        "botpasswords-label-appid": "Anarana rôbô:",
        "botpasswords-label-create": "Foronina",
        "botpasswords-label-update": "Vaozina",
        "savechanges": "Hitahiry ny fiovana",
        "publishpage": "Hamoaka pejy",
        "publishchanges": "Hamoaka ny fiovana",
+       "savearticle-start": "Hitahiry pejy...",
+       "savechanges-start": "Mitahiry ny fiovana...",
+       "publishpage-start": "Hamoaka ny pejy...",
+       "publishchanges-start": "Hamoaka ny fiovana...",
        "preview": "Topi-maso",
        "showpreview": "Asehoy aloha",
        "showdiff": "Asehoy ny fiovana",
        "anoneditwarning": "<strong>Fampitandremana :</strong> Tsy niditra tamin'ny kaontinao ianao. Ho hitan'ny vahoaka ny adiresy IP-nao raha manova inona na inona ianao. Raha <strong>[$1 miditra amin'ny kaontinao]</strong> ianao dia ho anisan'ny tombontsoa anananao ny fanaovana ny fiovana amin'ny solonanaranao.",
        "anonpreviewwarning": "''Tsy niditra ianao. Hampitahiry ny adiresy IP anao ao amin'ny tantaram-panovan'ity pejy ity ny fitehirizana ny fanovana.''",
        "missingsummary": "'''Hafatra fampantsiahivana''' : tsy mbola nanome ny ambangovangom-panovanao ianao.\nRaha mbola tsindriano fanindroany eo amin'ny bokotra $1, ho voatahiry tsy fanambarana ny fanovanao.",
-       "missingcommenttext": "Ampidiro ny ambangovangony azafady.",
+       "missingcommenttext": "Mampidira ambangovangony azafady.",
        "missingcommentheader": "<strong>Fampatsiahivana: </strong> Tsy nampiditra lohahevitra ho an'ity hafatra ity ianao. Raha tsindrianao fanindroany \"$1\" dia ho tehirizina tsy misy lohahevitra ny hafatrao.",
        "summary-preview": "Topi-mason'ny ambangovangom-panovana :",
        "subject-preview": "Topi-mason-dohahevitra:",
index d6033e1..81cfbe9 100644 (file)
        "badtitletext": "The requested page title was invalid, empty, or an incorrectly linked inter-language or inter-wiki title.\nIt may contain one or more characters that cannot be used in titles.",
        "title-invalid-empty": "The requested page title is empty or contains only the name of a namespace.",
        "title-invalid-utf8": "The requested page title contains an invalid UTF-8 sequence.",
+       "title-invalid-interwiki": "ꯍꯪꯒꯠꯆꯔꯤꯕꯥ ꯂꯥꯃꯥꯏꯁꯤꯒꯤ ꯃꯃꯤꯡ ꯁꯤ ꯋꯤꯀꯤ ꯒꯥ ꯃꯔꯤ ꯂꯩꯅꯕꯥ ꯁꯝꯅꯐꯝ ꯌꯥꯑꯣ ꯏ ꯃꯗꯨꯗꯤ ꯃꯃꯤꯡ ꯑꯣꯏꯅꯥ ꯁꯤꯖꯤꯟꯅꯕꯥ ꯌꯥꯗꯕꯥ",
        "viewsource": "ꯍꯧꯔꯛꯐꯝ ꯎꯨꯇꯂꯨ",
+       "viewsource-title": "$1 ꯒꯤ ꯍꯧꯔꯛꯐꯝ ꯎꯨꯠꯂꯨ",
+       "viewsourcetext": "ꯅꯪꯅꯥ ꯌꯦꯡꯕꯥ ꯌꯥꯒꯅꯤ ꯑꯃꯗꯤ ꯃꯁꯤꯒꯤ ꯂꯥꯃꯥꯏꯁꯤꯒꯤ ꯍꯧꯔꯛꯐꯝ ꯁꯤꯟꯇꯣꯛ ꯎ",
+       "mycustomjsonprotected": "ꯅꯪꯅꯥ ꯃꯁꯤ json ꯂꯥꯃꯥꯏꯁꯤ ꯁꯦꯝꯒꯠꯅꯕꯥ ꯑꯌꯥꯕꯥ ꯄꯤꯗꯦ",
+       "mycustomjsprotected": "JavaScript ꯂꯥꯃꯥꯏꯁꯤ ꯅꯪꯅꯥ ꯁꯦꯝꯒꯠꯅꯕꯒꯤ ꯑꯌꯥꯕꯥ ꯄꯤꯗꯦ",
+       "myprivateinfoprotected": "ꯅꯪꯅꯥ ꯅꯪꯒꯤ ꯑꯔꯣꯟꯕꯥ ꯑꯀꯨꯞꯄ ꯋꯥꯔꯣꯜ ꯂꯧꯐꯝ ꯁꯤ ꯁꯦꯝꯒꯠꯅꯕꯒꯤ ꯑꯌꯥꯕꯥ ꯄꯤꯗꯦ",
+       "mypreferencesprotected": "ꯅꯪꯅꯥ ꯅꯪꯒꯤ ꯄꯔꯤꯐꯔꯦꯟꯁ ꯁꯤ ꯁꯦꯝꯒꯠꯅꯕꯒꯤ ꯑꯌꯥꯕꯥ ꯄꯤꯗꯦ",
+       "ns-specialprotected": "ꯑꯈꯟꯅꯕꯥ ꯂꯥꯃꯥꯏꯅꯤ ꯁꯦꯝꯗꯣꯛꯄꯥ ꯌꯥꯗꯦ",
+       "titleprotected": "ꯃꯁꯤꯒꯤ ꯃꯃꯤꯡ ꯁꯤ ꯉꯥꯛꯊꯣꯛꯂꯦ ꯁꯥꯒꯠꯂꯛꯄꯗꯥ [[User:$1|$1]].\nThe reason given is <em>$2</em>.",
+       "filereadonlyerror": "Unable to modify the file \"$1\" because the file repository \"$2\" is in read-only mode.\n\nThe system administrator who locked it offered this explanation: \"$3\".",
+       "invalidtitle-knownnamespace": "Invalid title with namespace \"$2\" and text \"$3\"",
+       "invalidtitle-unknownnamespace": "Invalid title with unknown namespace number $1 and text \"$2\"",
+       "exception-nologin": "ꯂꯦꯒ ꯏꯟ ꯇꯧꯗꯦ",
+       "exception-nologin-text": "ꯆꯥꯟꯕꯤꯗꯨꯅꯥ ꯂꯣꯒ ꯏꯟ ꯇꯧꯁꯤꯟꯂꯨ ꯃꯁꯤꯒꯤ ꯂꯥꯃꯥꯏꯁꯤꯗꯥ ꯆꯪꯁꯤꯟꯅꯕꯥ ꯅꯠꯇꯔꯒꯥ ꯃꯊꯧ ꯄꯥꯡꯊꯣꯛꯅꯕꯥ",
+       "exception-nologin-text-manual": "Please $1 to be able to access this page or action.",
+       "virus-badscanner": "ꯑꯐꯠꯇꯕꯥ ꯀꯟꯐꯤꯒꯨꯔꯦꯁꯟ: Unknown virus scanner: <em>$1</em>",
+       "virus-scanfailed": "ꯁꯦꯡꯗꯣꯛꯄꯥ ꯃꯥꯏꯄꯥꯛꯇꯔꯦ (code $1)",
+       "virus-unknownscanner": "ꯁꯛꯈꯪꯗꯕꯥ ꯑꯦꯟꯇꯤ ꯕꯥꯏꯔꯨꯁ",
+       "logouttext": "<strong>You are now logged out.</strong>\n\nNote that some pages may continue to be displayed as if you were still logged in, until you clear your browser cache.",
+       "cannotlogoutnow-title": "ꯍꯧꯖꯤꯛ ꯂꯣꯒ out ꯇꯧꯕꯥ ꯌꯥꯗꯦ",
+       "cannotlogoutnow-text": "$1 ꯁꯤꯖꯤꯟꯅꯔꯤꯉꯩꯗꯥ ꯂꯣꯒꯒꯤꯡ out ꯁꯤ ꯑꯣꯏꯊꯣꯛꯇꯦ",
+       "welcomeuser": "$1ꯂꯦꯡꯁꯤꯟꯕꯤꯔꯛꯁꯤ",
+       "welcomecreation-msg": "ꯅꯪꯒꯤ ꯑꯦꯀꯥꯎꯟꯇ ꯁꯤ ꯁꯥꯈꯔꯦ\nꯅꯪꯒꯤ ꯑꯄꯥꯝꯕꯒꯤ ꯃꯇꯨꯡ ꯏꯟꯅꯥ ꯍꯣꯡꯗꯣꯛꯄꯥ ꯌꯥꯔꯦ ꯅꯪꯅꯥ {{SITENAME}} [[Special:Preferences|preferences]] ꯅꯪꯒꯤ ꯑꯄꯥꯝꯕꯒꯤ ꯃꯇꯨꯡꯏꯟꯅꯥ.",
+       "yourname": "ꯁꯤꯖꯤꯟꯅꯔꯤꯕꯥ ꯃꯃꯤꯡ",
        "userlogin-yourname": "Username",
        "userlogin-yourname-ph": "Enter your username",
+       "createacct-another-username-ph": "ꯁꯤꯖꯤꯟꯅꯔꯤꯕꯥ ꯃꯃꯤꯡ ꯗꯨ ꯏꯁꯤꯟꯂꯣ",
+       "yourpassword": "ꯆꯪꯁꯤꯟꯅꯕꯥ ꯋꯥꯍꯩ",
        "userlogin-yourpassword": "ꯆꯪꯁꯤꯟꯅꯕꯥ ꯋꯥꯍꯩ",
+       "userlogin-yourpassword-ph": "ꯄꯥꯁꯋ꯭ꯇ ꯏꯔꯛ ꯎ",
        "createacct-yourpassword-ph": "ꯄꯥꯁꯋ꯭ꯇ ꯏꯔꯛ ꯎ",
+       "yourpasswordagain": "ꯑꯃꯨꯛꯍꯟꯅꯥ ꯄꯥꯁꯋꯔꯇ ꯅꯝꯃꯨ",
        "createacct-yourpasswordagain": "Confirm password",
        "createacct-yourpasswordagain-ph": "ꯑꯃꯨꯛ ꯍꯟꯅꯥ ꯄꯥꯁꯋ꯭ꯇ ꯏꯌꯨ",
+       "userlogin-remembermypassword": "ꯑꯩꯕꯨ ꯑꯗꯨꯝ ꯂꯣꯒ ꯏꯟ ꯇꯧꯍꯟꯂꯨ",
+       "userlogin-signwithsecure": "ꯁꯣꯏꯔꯣꯏꯗꯕꯥ ꯁꯝꯅꯕꯥ  ꯁꯤꯖꯤꯟ ꯅꯧ",
+       "cannotlogin-title": "ꯂꯣꯒ ꯏꯟ ꯌꯥꯗꯦ",
+       "cannotlogin-text": "ꯂꯣꯒ ꯏꯟ ꯁꯤ ꯑꯣꯏꯊꯣꯛꯇꯦ",
+       "cannotloginnow-title": "ꯍꯧꯖꯤꯛ ꯂꯣꯒ ꯏꯟ ꯇꯧꯕꯥ ꯌꯥꯗꯦ",
+       "cannotloginnow-text": "$1 ꯁꯤꯖꯤꯟꯅꯔꯤꯉꯩꯗꯥ ꯂꯣꯒꯒꯤꯡ ꯏꯟ ꯁꯤ ꯑꯣꯏꯊꯣꯛꯇꯦ",
+       "cannotcreateaccount-title": "ꯑꯦꯀꯥꯎꯟ ꯁꯥꯕꯥ ꯌꯥꯗꯦ",
+       "cannotcreateaccount-text": "ꯍꯦꯛꯇꯥ ꯑꯣꯀꯥꯎꯅ ꯁꯥꯕꯥ ꯁꯤ ꯃꯁꯤꯒꯤ ꯋꯤꯀꯤ ꯁꯤ ꯗ ꯌꯥꯍꯟꯗꯦ",
+       "yourdomainname": "ꯅꯪꯒꯤ ꯗꯣꯃꯦꯟ",
+       "password-change-forbidden": "ꯅꯪꯅꯥ ꯃꯁꯤꯒꯤ ꯋꯤꯀꯤ ꯁꯤꯗꯥ ꯄꯥꯁꯋꯔꯇ ꯍꯣꯡꯕꯥ ꯌꯥꯔꯣꯏ",
+       "externaldberror": "There was either an authentication database error or you are not allowed to update your external account.",
        "login": "Chang Sinba",
+       "login-security": "ꯅꯪꯒꯤ ꯁꯛꯑꯣꯡ ꯈꯟꯗꯣꯛꯄꯥ",
+       "nav-login-createaccount": "ꯂꯣꯒ ꯏꯟ/ꯑꯦꯀꯥꯎꯟ ꯁꯥꯕꯥ",
+       "logout": "Log out",
+       "userlogout": "ꯂꯣꯒ ꯑꯧꯇ",
+       "notloggedin": "ꯂꯦꯒ ꯏꯟ ꯇꯧꯗꯦ",
+       "userlogin-noaccount": "ꯑꯦꯀꯥꯎꯟ ꯂꯩꯇꯕꯔꯥ",
+       "userlogin-joinproject": "ꯌꯥꯎꯕꯥ {{ꯃꯃꯤꯡ ꯏꯐꯝ}}",
        "createaccount": "ꯑꯩꯒꯤ ꯑꯣꯏꯕꯥ ꯑꯃꯥ ꯁꯦꯝꯕꯥ",
+       "userlogin-resetpassword-link": "ꯄꯥꯁꯋꯔꯇ ꯀꯥꯎꯈꯔꯕꯥ",
+       "userlogin-helplink2": "ꯂꯣꯒꯒꯤꯡ ꯇꯧꯗꯨꯅꯥ ꯃꯇꯦꯡ ꯄꯥꯡ ꯎ",
+       "userlogin-loggedin": "You are already logged in as {{GENDER:$1|$1}}.\nUse the form below to log in as another user.",
+       "userlogin-reauth": "You must log in again to verify that you are {{GENDER:$1|$1}}.",
+       "userlogin-createanother": "ꯅꯪꯒꯤ ꯑꯇꯣꯞꯄꯥ ꯑꯦꯀꯥꯎꯟꯇ ꯁꯦꯝꯕꯥ",
+       "createacct-emailrequired": "ꯏꯃꯦꯜ ꯂꯥꯐꯝ",
        "createacct-emailoptional": "Email address (ꯑꯇꯣꯞꯄꯥ ꯱)",
        "createacct-email-ph": "Enter your email address",
+       "createacct-another-email-ph": "Enter your email address",
+       "createaccountmail": "Use a temporary random password and send it to the specified email address",
+       "createaccountmail-help": "ꯄꯥꯁꯋꯔꯇ ꯈꯪꯗꯅꯥ ꯑꯇꯣꯞꯄꯒꯤ ꯑꯦꯀꯥꯎꯟ ꯁꯥꯕꯗꯥ ꯁꯤꯖꯤꯟꯅꯕꯥ ꯌꯥꯏ",
+       "createacct-realname": "ꯑꯆꯨꯝꯕꯥ ꯃꯃꯤꯡ(ꯑꯇꯣꯞꯄꯥ ꯱)",
+       "createacct-reason": "ꯃꯔꯝ",
+       "createacct-reason-ph": "ꯅꯪꯅꯥ ꯀꯔꯤꯒꯤ ꯑꯇꯣꯞꯄꯥ ꯑꯦꯀꯥꯎꯟ ꯁꯥꯔꯤꯅꯣ",
+       "createacct-reason-help": "ꯄꯥꯎꯖꯦꯜꯁꯤ ꯑꯦꯀꯥꯎꯟ ꯁꯦꯝꯕꯥ ꯂꯣꯒ ꯇꯥ ꯎꯨꯠꯂꯦ",
        "createacct-submit": "ꯅꯪꯒꯤ ꯑꯦꯀꯥꯎꯟꯇ ꯁꯦꯝꯕꯥ",
+       "createacct-another-submit": "ꯑꯩꯒꯤ ꯑꯣꯏꯕꯥ ꯑꯃꯥ ꯁꯦꯝꯕꯥ",
+       "createacct-continue-submit": "ꯃꯈꯥ ꯆꯠꯊꯧ ꯑꯦꯀꯥꯎꯟ ꯁꯦꯝꯕꯗꯨ",
+       "createacct-another-continue-submit": "ꯃꯈꯥ ꯆꯠꯊꯧ ꯑꯦꯀꯥꯎꯟ ꯁꯦꯝꯕꯗꯨ",
        "createacct-benefit-heading": "{{SITENAME}} ꯁꯤ ꯅꯪꯒꯥ ꯃꯥꯟꯅꯕꯥ ꯃꯤꯑꯣꯏꯁꯤꯡꯅꯥ ꯁꯦꯝꯕꯅꯤ",
        "createacct-benefit-body1": "{{PLURAL:$1|edit|edits}}",
        "createacct-benefit-body2": "{{PLURAL:$1|page|pages}}",
        "createacct-benefit-body3": "ꯍꯧꯖꯤꯛꯀꯤ {{PLURAL:$1|contributor|contributors}}",
+       "badretype": "ꯅꯪꯅꯥ ꯏꯔꯤꯕꯥ ꯄꯥꯡꯋꯔꯇ ꯁꯤ ꯆꯥꯟꯅꯗꯔꯦ",
+       "usernameinprogress": "ꯉꯍꯥꯛꯇꯪ ꯉꯥꯏꯕꯤꯈꯣ ꯃꯁꯤꯒꯤ ꯁꯤꯖꯤꯟꯅꯔꯤꯕꯥ ꯃꯃꯤꯡ ꯁꯤ ꯒꯤ ꯑꯦꯀꯥꯎꯟ ꯁꯦꯝꯕꯗꯥ ꯈꯨꯃꯥꯡ ꯆꯥꯎꯁꯤꯟꯂꯦ",
+       "createacct-error": "ꯑꯀꯥꯎꯟ ꯁꯦꯝꯕꯗꯥ ꯑꯁꯣꯏꯕꯥ ꯂꯩꯔꯦ",
+       "createaccounterror": "$1 ꯑꯦꯀꯥꯎꯟ ꯁꯥꯕꯥ ꯌꯥꯗꯔꯦ",
+       "nocookiesnew": "The user account was created, but you are not logged in.\n{{SITENAME}} uses cookies to log in users.\nYou have cookies disabled.\nPlease enable them, then log in with your new username and password.",
+       "nocookieslogin": "{{SITENAME}} uses cookies to log in users.\nYou have cookies disabled.\nPlease enable them and try again.",
+       "loginsuccesstitle": "ꯂꯣꯒ ꯏꯟ",
+       "login-userblocked": "ꯃꯁꯤꯒꯤ ꯁꯤꯖꯤꯟꯅꯔꯤꯕꯥꯁꯤ ꯊꯤꯡꯖꯤꯟꯈꯔꯦ? ꯂꯣꯒ ꯏꯟ ꯌꯥꯔꯥꯔꯣꯏ",
+       "passwordtooshort": "ꯄꯥꯁꯋꯔꯇ ꯁꯤ ꯌꯥꯝꯗꯔꯕꯗꯥ ꯃꯁꯤ ꯈꯔꯥꯁꯤ ꯌꯥꯎꯒꯗꯕꯅꯤ {{PLURAL:$1|1 character|$1 characters}}.",
+       "mailmypassword": "ꯄꯥꯁꯋ꯭ꯇ ꯁꯦꯝꯗꯣꯛꯄꯥ",
+       "passwordremindertitle": " {{SITENAME}} ꯁꯤꯒꯤ ꯑꯅꯧꯕꯥ ꯉꯥꯏꯍꯥꯛꯀꯤ ꯑꯣꯏꯕꯥ ꯄꯥꯁꯋꯔꯇ",
+       "passwordremindertext": "Someone (from IP address $1) requested a new\npassword for {{SITENAME}} ($4). A temporary password for user\n\"$2\" has been created and was set to \"$3\". If this was your\nintent, you will need to log in and choose a new password now.\nYour temporary password will expire in {{PLURAL:$5|one day|$5 days}}.\n\nIf someone else made this request, or if you have remembered your password,\nand you no longer wish to change it, you may ignore this message and\ncontinue using your old password.",
+       "emailconfirmlink": "ꯅꯪꯒꯤ ꯏꯃꯦꯜ ꯑꯦꯗꯔꯦꯁ ꯌꯥꯕꯔꯥ ꯌꯦꯡ ꯎ",
+       "accountcreated": "ꯑꯦꯀꯥꯎꯟ ꯁꯥꯈꯔꯦ",
        "loginlanguagelabel": "$1 ꯂꯣꯟ",
        "pt-login": "Chang Sinba",
+       "pt-login-button": "Chang Sinba",
+       "pt-login-continue-button": "ꯂꯣꯘ ꯏꯟ ꯃꯈꯥ ꯆꯠꯊꯧ",
        "pt-createaccount": "ꯑꯩꯒꯤ ꯑꯣꯏꯕꯥ ꯑꯃꯥ ꯁꯦꯝꯕꯥ",
        "pt-userlogout": "Log out",
+       "changepassword": "ꯄꯥꯁꯋ꯭ꯔꯇ ꯍꯣꯡꯗꯣꯛꯄꯥ",
+       "oldpassword": "ꯑꯔꯤꯕꯥ ꯄꯥꯁꯋꯔꯇ",
+       "newpassword": "ꯑꯅꯧꯕꯥ ꯄꯥꯁꯋꯔꯇ",
+       "retypenew": "ꯑꯃꯨꯛꯍꯟꯅꯥ ꯑꯅꯧꯕꯥ  ꯄꯥꯁꯋꯔꯇ ꯅꯝꯃꯨ",
+       "resetpass_submit": "ꯄꯥꯁꯋꯔꯇ ꯁꯦꯝꯃꯨ ꯱ꯗꯤ ꯂꯣꯒ ꯏꯟ",
+       "changepassword-success": "ꯅꯪꯒꯤ ꯄꯥꯁꯋꯔꯇ ꯁꯤ ꯍꯣꯡꯗꯣꯛꯈꯔꯦ",
+       "changepassword-throttled": "You have made too many recent login attempts.\nPlease wait $1 before trying again.",
+       "botpasswords": "ꯕꯣꯇ ꯄꯥꯁꯋꯔꯇ",
+       "botpasswords-summary": "<em>Bot passwords</em> allow access to a user account via the API without using the account's main login credentials. The user rights available when logged in with a bot password may be restricted.\n\nIf you don't know why you might want to do this, you should probably not do it. No one should ever ask you to generate one of these and give it to them.",
+       "botpasswords-disabled": "ꯕꯣꯇ ꯄꯥꯁꯋꯔꯇ ꯌꯥꯉꯟꯗꯕꯥ",
+       "botpasswords-label-create": "ꯁꯥꯕꯥ",
+       "botpasswords-label-update": "ꯅꯧꯊꯣꯛꯍꯟꯕꯥ",
+       "botpasswords-label-cancel": "ꯀꯛꯊꯠꯄꯥ",
+       "botpasswords-label-delete": "ꯃꯥꯡꯍꯟꯕꯥ",
+       "botpasswords-label-resetpassword": "ꯄꯥꯁꯋ꯭ꯇ ꯑꯃꯨꯛ ꯍꯟꯅꯥ ꯁꯦꯝꯗꯣꯛꯄꯥ",
+       "botpasswords-label-grants": "ꯆꯥꯟꯅꯕꯥ ꯌꯥꯕꯥ ꯑꯌꯥꯕ",
+       "botpasswords-help-grants": "Grants allow access to rights already held by your user account. Enabling a grant here does not provide access to any rights that your user account would not otherwise have. See the [[Special:ListGrants|table of grants]] for more information.",
+       "botpasswords-created-title": "ꯕꯣꯠ ꯄꯥꯁꯋ꯭ꯔꯇ ꯁꯥꯈꯔꯦ",
+       "botpasswords-deleted-title": "ꯕꯣꯠ ꯄꯥꯁꯋ꯭ꯔꯇ ꯀꯛꯊꯠꯈꯔꯦ",
+       "resetpass_forbidden": "ꯄꯥꯁꯋ꯭ꯔꯇ ꯍꯣꯡꯗꯣꯧꯄꯥ ꯌꯥꯔꯣꯏ",
+       "resetpass_forbidden-reason": "$1 ꯄꯥꯁꯋ꯭ꯔꯇ ꯍꯣꯡꯗꯣꯧꯄꯥ ꯌꯥꯔꯣꯏ",
+       "resetpass-no-info": "ꯃꯁꯤꯒꯤ ꯂꯥꯃꯥꯏꯁꯤ ꯍꯦꯧꯇꯥ ꯌꯧꯅꯕꯥ ꯅꯪ ꯁꯣꯏꯗꯅꯥ ꯂꯣꯒ ꯏꯟ ꯇꯧꯒꯗꯕꯅꯤ",
+       "resetpass-submit-loggedin": "ꯄꯥꯁꯋ꯭ꯔꯇ ꯍꯣꯡꯗꯣꯛꯄꯥ",
+       "resetpass-submit-cancel": "ꯀꯛꯊꯠꯄꯥ",
+       "resetpass-wrong-oldpass": "ꯃꯇꯝ ꯈꯔꯥꯒꯤ ꯑꯣꯏꯅꯥ ꯀꯔꯤꯝꯇꯥ ꯌꯥꯎꯗꯦ  ꯅꯠꯇꯔꯒꯥ ꯍꯧꯖꯤꯧꯀꯤ ꯄꯥꯁꯋ꯭ꯔꯇ꯫\nꯅꯪꯅꯥ ꯄꯥꯁꯋꯑꯔꯇ ꯍꯥꯟꯅꯗꯒꯤ ꯍꯣꯡꯂꯝꯂꯅꯤ ꯅꯠꯇꯔꯒꯥ ꯍꯪꯒꯠꯂꯨ ꯉꯥꯏꯍꯥꯛꯀꯤ ꯑꯣꯏꯕꯥ ꯄꯥꯁꯋ꯭ꯔꯇ",
+       "resetpass-temp-password": "ꯉꯩꯍꯥꯛꯀꯤ ꯑꯣꯏꯕꯥ ꯄꯥꯁꯋ꯭ꯔꯇ",
+       "passwordreset": "ꯄꯥꯁꯋ꯭ꯇ ꯁꯦꯝꯗꯣꯛꯄꯥ",
+       "passwordreset-username": "ꯁꯤꯖꯤꯟꯅꯔꯤꯕꯥ ꯃꯃꯤꯡ",
+       "passwordreset-domain": "ꯗꯣꯃꯦꯟ",
+       "passwordreset-email": "ꯏꯃꯦꯜ ꯂꯥꯐꯝ",
+       "passwordreset-emailtitle": "{{SITENAME}} ꯑꯀꯨꯞꯄꯥ ꯃꯔꯣꯜ",
+       "passwordreset-emailtext-ip": "Someone (probably you, from IP address $1) requested a reset of your\npassword for {{SITENAME}} ($4). The following user {{PLURAL:$3|account is|accounts are}}\nassociated with this email address:\n\n$2\n\n{{PLURAL:$3|This temporary password|These temporary passwords}} will expire in {{PLURAL:$5|one day|$5 days}}.\nYou should log in and choose a new password now. If someone else made this\nrequest, or if you have remembered your original password, and you no longer\nwish to change it, you may ignore this message and continue using your old\npassword.",
+       "passwordreset-emailtext-user": "User $1 on {{SITENAME}} requested a reset of your password for {{SITENAME}}\n($4). The following user {{PLURAL:$3|account is|accounts are}} associated with this email address:\n\n$2\n\n{{PLURAL:$3|This temporary password|These temporary passwords}} will expire in {{PLURAL:$5|one day|$5 days}}.\nYou should log in and choose a new password now. If someone else made this\nrequest, or if you have remembered your original password, and you no longer\nwish to change it, you may ignore this message and continue using your old\npassword.",
+       "passwordreset-emailelement": "$1 ꯁꯤꯖꯤꯟꯅꯔꯤꯕꯥ\n$2 ꯉꯩꯍꯥꯛꯀꯤ ꯑꯣꯏꯕꯥ ꯄꯥꯁꯋꯔꯇ",
+       "changeemail-none": "ꯑꯃꯥꯇꯥ ꯅꯠꯇꯦ",
+       "changeemail-password": "ꯅꯪꯒꯤ {{SITENAME}} ꯄꯥꯁꯋ꯭ꯔꯇ:",
+       "changeemail-submit": "ꯏ-ꯃꯦꯜ ꯍꯣꯡꯕꯥ",
        "bold_sample": "ꯆꯥꯎꯅꯥ ꯏꯕꯥ",
        "bold_tip": "ꯆꯥꯎꯅꯥ ꯏꯕꯥ",
        "italic_sample": "ꯋꯥꯔꯦꯡ ꯐꯆꯅꯥ ꯏꯕꯥ",
        "sig_tip": "ꯃꯇꯝꯒꯤ ꯏꯁꯇꯥꯝꯒꯥ ꯂꯣꯏꯟꯅꯥ ꯅꯪꯒꯤ ꯈꯨꯇꯌꯦꯛ",
        "hr_tip": "ꯐꯩꯅꯥ ꯆꯤꯡꯕꯥ ꯂꯥ ꯏ (ꯃꯔꯤꯛ ꯃꯔꯤꯛ ꯑꯣꯏꯅꯥ ꯁꯤꯖꯤꯟꯅꯧ)",
        "summary": "ꯑꯇꯦꯟꯕꯥ ꯁꯟꯗꯣꯛꯅꯥ ꯇꯥꯛꯄꯥ",
+       "subject": "ꯍꯤꯔꯝ",
        "minoredit": "ꯃꯁꯤ ꯑꯄꯤꯛꯄꯥ ꯁꯦꯝꯒꯠꯄꯅꯤ",
        "watchthis": "ꯃꯁꯤꯒꯤ ꯂꯥꯃꯥꯏꯁꯤ ꯌꯦꯡꯉꯨ",
        "savearticle": "ꯂꯥꯃꯥꯏ ꯇꯨꯪꯁꯤꯟꯕꯥ",
+       "savechanges": "ꯑꯍꯣꯡꯕꯗꯨ ꯇꯨꯪꯁꯤꯟꯂꯨ",
+       "publishpage": "ꯂꯥꯃꯥꯏ ꯐꯣꯡꯗꯣꯛ ꯎ",
+       "publishchanges": "ꯑꯍꯣꯡꯕꯁꯤꯡꯗꯨ ꯐꯣꯡꯗꯣꯛ ꯎ",
+       "savearticle-start": "ꯂꯥꯃꯥꯏ ꯁꯤ ꯇꯨꯡꯁꯤꯜꯂꯨ",
+       "savechanges-start": "ꯑꯍꯣꯡꯕꯁꯤꯡꯗꯨ ꯇꯨꯪꯁꯤꯟꯂꯨ",
+       "publishpage-start": "ꯂꯥꯃꯥꯏ ꯐꯣꯡꯗꯣꯛ ꯎ",
+       "publishchanges-start": "ꯑꯍꯣꯡꯕꯁꯤꯡꯗꯨ ꯐꯣꯡꯗꯣꯛ ꯎ",
+       "preview": "ꯃꯥꯃꯥꯡꯒꯤ",
        "showpreview": "ꯍꯥꯟꯅꯒꯤꯗꯨ ꯎꯨꯇꯂꯨ",
        "showdiff": "ꯑꯍꯣꯡꯕꯗꯨ ꯎꯨꯇꯂꯨ",
+       "blankarticle": "<strong>Warning:</strong> The page you are creating is blank.\nIf you click \"$1\" again, the page will be created without any content.",
        "anoneditwarning": "<strong>Warning:</strong> You are not logged in. Your IP address will be publicly visible if you make any edits. If you <strong>[$1 log in]</strong> or <strong>[$2 create an account]</strong>, your edits will be attributed to your username, along with other benefits.",
        "loginreqlink": "Chang Sinba",
+       "accmailtitle": "ꯄꯥꯁꯋ꯭ꯔꯇ ꯊꯥꯕ",
+       "newarticle": "ꯑꯅꯧꯕꯥ",
+       "newarticletext": "You have followed a link to a page that does not exist yet.\nTo create the page, start typing in the box below (see the [$1 help page] for more info).\nIf you are here by mistake, click your browser's <strong>back</strong> button.",
+       "anontalkpagetext": "----\n<em>This is the discussion page for an anonymous user who has not created an account yet, or who does not use it.</em>\nWe therefore have to use the numerical IP address to identify him/her.\nSuch an IP address can be shared by several users.\nIf you are an anonymous user and feel that irrelevant comments have been directed at you, please [[Special:CreateAccount|create an account]] or [[Special:UserLogin|log in]] to avoid future confusion with other anonymous users.",
        "noarticletext": "There is currently no text in this page.\nYou can [[Special:Search/{{PAGENAME}}|search for this page title]] in other pages,\n<span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} search the related logs],\nor [{{fullurl:{{FULLPAGENAME}}|action=edit}} create this page]</span>.",
        "noarticletext-nopermission": "There is currently no text in this page.\nYou can [[Special:Search/{{PAGENAME}}|search for this page title]] in other pages, or <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} search the related logs]</span>, but you do not have permission to create this page.",
+       "missing-revision": "The revision #$1 of the page named \"{{FULLPAGENAME}}\" does not exist.\n\nThis is usually caused by following an outdated history link to a page that has been deleted.\nDetails can be found in the [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} deletion log].",
+       "continue-editing": "ꯁꯦꯝꯒꯠꯄꯒꯤ ꯃꯐꯝꯗꯨꯗꯥ ꯆꯠꯂꯨ",
+       "editing": "$1 ꯁꯦꯝꯒꯠꯂꯤ",
        "creating": "Creating $1",
        "editingsection": "Editing $1 (section)",
+       "yourtext": "ꯅꯪꯒꯤ ꯇꯦꯀꯁ",
+       "yourdiff": "ꯈꯦꯠꯅꯕꯥ ꯁꯤꯡ",
+       "copyrightwarning": "Please note that all contributions to {{SITENAME}} are considered to be released under the $2 (see $1 for details).\nIf you do not want your writing to be edited mercilessly and redistributed at will, then do not submit it here.<br />\nYou are also promising us that you wrote this yourself, or copied it from a public domain or similar free resource.\n<strong>Do not submit copyrighted work without permission!</strong>",
+       "templatesused": "{{PLURAL:$1|Template|Templates}} used on this page:",
        "template-protected": "ꯉꯥꯛꯊꯣꯛꯂꯕꯥ",
        "template-semiprotected": "ꯇꯪꯈꯥꯏ ꯉꯥꯛꯊꯣꯛꯂꯕꯥ",
+       "hiddencategories": "This page is a member of {{PLURAL:$1|1 hidden category|$1 hidden categories}}:",
+       "permissionserrors": "ꯑꯌꯥꯕꯥꯗꯨ ꯁꯣꯏꯔꯦ",
+       "permissionserrorstext-withaction": "You do not have permission to $2, for the following {{PLURAL:$1|reason|reasons}}:",
+       "moveddeleted-notice": "ꯃꯁꯤꯒꯤ ꯂꯥꯃꯥꯏꯁꯤ ꯀꯛꯊꯠꯈꯔꯦ. \nꯀꯛꯊꯠꯄꯥ, ꯉꯥꯛꯊꯣꯛꯄꯥ ꯑꯃꯗꯤ ꯂꯣꯒ ꯂꯦꯡꯍꯟꯕꯥ ꯂꯥꯃꯥꯏꯒꯤꯗꯃꯛ ꯇꯨ ꯃꯈꯥꯒꯤ ꯁꯤꯗꯥ ꯔꯤꯐꯔꯦꯟꯁ ꯎꯨꯠꯂꯦ",
+       "edit-conflict": "ꯁ‍ꯦꯝꯒꯠꯐꯝꯒꯤ ꯈꯠꯅ ꯆꯩꯅꯕꯥ",
+       "content-json-empty-object": "ꯑꯍꯥꯡꯕꯥ ꯄꯣꯠꯁꯛ",
+       "viewpagelogs": "ꯃꯁꯤꯒꯤ ꯂꯥꯃꯥꯏꯁꯤꯒꯤ ꯅꯧꯅ ꯆꯪꯉꯨ",
+       "currentrev-asof": "$1 ꯒꯤ ꯅꯧꯅꯥ ꯑꯃꯨꯛꯍꯟꯅꯥ ꯌꯦꯡꯕꯥ ꯃꯤꯠꯌꯦꯡ",
        "revisionasof": "Revision as of $1",
+       "revision-info": "Revision as of $1 by {{GENDER:$6|$2}}$7",
        "previousrevision": "ꯑꯔꯤꯕꯥ ꯑꯃꯨꯛ ꯍꯟꯅꯥ ꯌꯦꯡꯕꯥ",
+       "nextrevision": "ꯑꯅꯧꯕꯥ ꯑꯃꯨꯛꯍꯟꯅꯥ ꯌꯦꯡꯕꯥ",
+       "currentrevisionlink": "ꯈꯋꯥꯏꯗꯒꯤ ꯅꯧꯅꯥ ꯑꯃꯨꯛ ꯌꯦꯡꯕꯥ",
        "cur": "ꯍꯧ",
        "last": "ꯃꯥꯃꯥꯡꯒꯤ",
+       "page_first": "ꯑꯍꯥꯟꯕ",
+       "page_last": "ꯑꯔꯣꯏꯕ",
+       "histlegend": "Diff selection: Mark the radio boxes of the revisions to compare and hit enter or the button at the bottom.<br />\nLegend: <strong>({{int:cur}})</strong> = difference with latest revision, <strong>({{int:last}})</strong> = difference with preceding revision, <strong>{{int:minoreditletter}}</strong> = minor edit.",
+       "history-fieldset-title": "ꯊꯤꯋꯨ ꯑꯃꯨꯛ ꯍꯝꯁꯟꯅꯥ ꯌꯦꯡꯅꯕꯥ",
+       "histfirst": "ꯈꯋꯥꯏꯗꯒꯤ ꯑꯔꯤꯕꯥ",
+       "histlast": "ꯑꯅꯧꯕꯥ",
        "rev-delundel": "ꯑꯍꯣꯡꯕꯥ ꯎꯍꯟꯂꯤꯕꯥ",
+       "revdelete-show-file-submit": "ꯍꯣꯏ",
+       "revdelete-radio-unset": "ꯎꯍꯟꯕ",
+       "history-title": "Revision history of \"$1\"",
        "difference-title": "$1 ꯒꯤ ꯑꯃꯨꯛꯍꯟꯕꯥ ꯈꯦꯠꯅꯕꯥꯒꯤ ꯃꯔꯛ",
        "lineno": "ꯂꯥ ꯏ $1",
        "editundo": "ꯇꯧꯒꯅꯨ",
        "searchresults-title": "Search results for \"$1\"",
        "prevn": "ꯍꯥꯟꯅꯒꯤ {{PLURAL:$1|$1}}",
        "nextn": "ꯃꯥꯊꯪ{{PLURAL:$1|$1}}",
+       "prevn-title": "ꯃꯃꯥꯡꯒꯤ $1 {{PLURAL:$1|result|results}}",
        "nextn-title": "Next $1 {{PLURAL:$1|result|results}}",
        "shown-title": "Show $1 {{PLURAL:$1|result|results}} per page",
        "viewprevnext": "ꯎꯨꯇꯂꯨ ($1 {{int:pipe-separator}} $2) ($3)",
        "search-result-size": "$1 ({{PLURAL:$2|1 word|$2 words}})",
        "search-redirect": "(redirect from $1)",
        "search-section": "(section $1)",
+       "search-suggest": "$1 ꯁꯤꯔꯥ ꯅꯪꯅꯥ ꯍꯥꯏꯅꯤꯡꯂꯤꯕꯥꯁꯤ",
        "searchall": "ꯄꯨꯂꯞ",
        "search-showingresults": "{{PLURAL:$4|Result <strong>$1</strong> of <strong>$3</strong>|Results <strong>$1 – $2</strong> of <strong>$3</strong>}}",
        "search-nonefound": "ꯃꯁꯤꯒꯤ ꯐꯣꯜꯁꯤꯒꯥ ꯆꯥꯟꯅꯕꯥ ꯂꯩꯇꯦ",
        "mypreferences": "Preferences",
        "right-writeapi": "API sijinaduna eba",
        "newuserlogpage": "User creation log",
+       "action-edit": "ꯃꯁꯤꯒꯤ ꯂꯥꯃꯥꯏꯁꯤ ꯁꯦꯝꯒꯠꯂꯨ",
        "enhancedrc-history": "ꯄꯨꯋꯥꯔꯤ",
        "recentchanges": "ꯍꯧꯖꯤꯛꯀꯤ ꯑꯣꯏꯕꯥ ꯑꯍꯣꯡꯕꯁꯤꯡ",
        "recentchanges-legend": "ꯍꯧꯖꯤꯛꯀꯤ ꯑꯣꯏꯕꯥ ꯑꯍꯣꯡꯕꯥ ꯈꯟꯐꯝꯁꯤꯡ",
        "recentchanges-summary": "ꯋꯤꯀꯤꯄꯦꯗꯤꯌꯥ ꯂꯃꯥꯏꯒꯤ ꯍꯧꯖꯤꯛꯀꯤ ꯑꯣꯏꯕꯥ ꯑꯍꯣꯡꯕꯒꯤ ꯃꯐꯝ ꯇꯥꯛꯄꯥ",
+       "recentchanges-noresult": "ꯑꯍꯣꯡꯕꯥ ꯂꯩꯍꯟꯒꯅꯨ ꯑꯩꯈꯣꯏꯅꯥ ꯄꯤꯔꯤꯕꯥ ꯃꯇꯝ ꯁꯤꯗꯥ ꯆꯥꯟꯅꯕꯥ ꯱ ꯌꯥꯎꯗꯔꯤꯐꯥꯎ",
        "recentchanges-label-newpage": "ꯃꯁꯤꯒꯤ ꯁꯦꯝꯒꯠꯄꯁꯤꯅꯥ ꯑꯅꯧꯕꯥ ꯂꯥꯃꯥꯏ ꯱ ꯁꯥꯔꯦ",
        "recentchanges-label-minor": "ꯃꯁꯤ ꯑꯄꯤꯛꯄꯥ ꯁꯦꯝꯒꯠꯄꯅꯤ",
        "recentchanges-label-bot": "ꯃꯁꯤꯒꯤ ꯁꯦꯝꯒꯠꯄꯁꯤ ꯕ ꯅꯥ ꯄꯥꯡꯊꯣꯛꯄꯅꯤ",
        "recentchanges-label-plusminus": "ꯕꯥꯏꯠꯀꯤ ꯑꯍꯣꯡꯕꯒꯤ ꯃꯇꯪ ꯏꯟꯅꯥ ꯂꯥꯃꯥꯏꯁꯤꯒꯤ ꯑꯆꯧꯕꯥ ꯂꯦꯞꯄꯤ",
        "recentchanges-legend-heading": "<ꯑꯀꯟꯕꯥ>ꯊꯥꯏꯅꯗꯒꯤ</ꯑꯀꯟꯕꯥ>",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (also see [[Special:NewPages|list of new pages]])",
+       "rcnotefrom": "Below {{PLURAL:$5|is the change|are the changes}} since <strong>$3, $4</strong> (up to <strong>$1</strong> shown).",
        "rclistfrom": "$2$3 ꯁꯤꯗꯒꯤ ꯍꯧꯔꯒꯥ ꯑꯅꯧꯕꯥ ꯑꯍꯣꯡꯕꯗꯨ ꯎꯨꯇꯂꯨ",
        "rcshowhideminor": "$1 ꯄꯤꯛꯅꯥ ꯁꯦꯝꯒꯠꯄꯥ",
+       "rcshowhideminor-show": "ꯎꯨꯇꯄꯥ",
        "rcshowhideminor-hide": "ꯂꯣꯇꯄꯥ",
        "rcshowhidebots": "$1 bots",
        "rcshowhidebots-show": "ꯎꯨꯇꯄꯥ",
+       "rcshowhidebots-hide": "ꯂꯣꯇꯄꯥ",
        "rcshowhideliu": "ꯃꯃꯤꯡ ꯆꯟꯂꯕꯥ ꯄꯥꯏꯔꯤꯕꯥ $1",
+       "rcshowhideliu-show": "ꯎꯨꯇꯄꯥ",
        "rcshowhideliu-hide": "ꯂꯣꯇꯄꯥ",
        "rcshowhideanons": "$1 ꯃꯁꯛ ꯃꯥꯅꯥꯗꯕꯥ ꯄꯥꯏꯔꯤꯕꯥ ꯃꯤ",
+       "rcshowhideanons-show": "ꯎꯨꯇꯄꯥ",
        "rcshowhideanons-hide": "ꯂꯣꯇꯄꯥ",
        "rcshowhidemine": "$1 ꯑꯩꯅꯥ ꯁꯦꯝꯒꯠꯄꯁꯤꯡ",
+       "rcshowhidemine-show": "ꯎꯨꯇꯄꯥ",
        "rcshowhidemine-hide": "ꯂꯣꯇꯄꯥ",
        "rclinks": "$1 ꯒꯤ ꯑꯔꯣꯏꯕꯥ ꯑꯍꯣꯡꯕꯥꯗꯎ ꯎꯨꯇꯂꯎ $2 ꯃꯅꯨꯡꯗꯥ",
        "diff": "ꯈꯦꯠ",
        "upload": "ꯐꯥꯏꯜ ꯊꯥꯒꯠꯂꯨ",
        "filedesc": "ꯑꯇꯦꯟꯕꯥ ꯁꯟꯗꯣꯛꯅꯥ ꯇꯥꯛꯄꯥ",
        "license-header": "ꯑꯌꯥꯕꯥ",
+       "imgfile": "ꯈꯣꯝꯖꯤꯟꯗꯨꯅꯥ ꯍꯥꯞꯐꯝ",
        "file-anchor-link": "ꯈꯣꯝꯖꯤꯟꯗꯨꯅꯥ ꯍꯥꯞꯐꯝ",
        "filehist": "ꯐꯥꯏꯜꯒꯤ ꯄꯨꯋꯥꯔꯤ",
        "filehist-help": "Cheichat/Matamda nammmu matam aduda file adu ooonaba",
+       "filehist-revert": "ꯑꯃꯨꯛ ꯍꯟꯂꯟꯕꯥ",
        "filehist-current": "Houjikki",
        "filehist-datetime": "ꯆꯩꯆꯠ/ꯃꯇꯝ",
        "filehist-thumb": "Khutpina namba",
        "upload-disallowed-here": "ꯃꯁꯤꯒꯤ ꯐꯥꯏꯜꯁꯤ ꯅꯪꯅꯥ ꯑꯃꯨꯛ ꯍꯟꯅꯥ ꯏꯕꯥ ꯌꯥꯔꯣꯏ",
        "randompage": "ꯆꯥꯡ ꯅꯥꯏꯗꯕꯥ ꯂꯥꯃꯥꯏ",
        "nbytes": "$1 {{PLURAL:$1|byte|bytes}}",
+       "nmembers": "$1 {{PLURAL:$1|member|members}}",
        "newpages": "ꯑꯅꯧꯕꯥ ꯂꯥꯃꯥꯏꯁꯤꯡ",
+       "move": "ꯂꯦꯡꯍꯟꯕꯥ",
+       "pager-newer-n": "{{PLURAL:$1|newer 1|newer $1}}",
+       "pager-older-n": "{{PLURAL:$1|older 1|older $1}}",
        "booksources": "ꯂꯥꯏꯔꯤꯛꯀꯤ ꯍꯧꯔꯛꯐꯝ",
+       "booksources-search-legend": "ꯂꯥꯏꯔꯤꯛꯀꯤ ꯍꯧꯔꯛꯐꯝ ꯊꯤꯕꯥ",
+       "booksources-search": "ꯊꯤꯕꯥ",
        "log": "ꯆꯪꯕꯥ",
+       "allpages": "ꯂꯥꯃꯥꯏ ꯂꯣꯏꯅꯥ",
+       "allarticles": "ꯂꯥꯃꯥꯏ ꯂꯣꯏꯅꯥ",
        "allpagessubmit": "ꯆꯠꯂꯨ",
+       "categories": "ꯃꯊꯪ ꯃꯅꯥꯎ ꯈꯥꯏꯗꯣꯛꯄꯥ",
        "mywatchlist": "Watchlist",
        "watch": "ꯌꯦꯡꯕꯥ",
+       "dellogpage": "ꯀꯛꯊꯠꯄꯥꯒꯤ ꯂꯣꯒ",
        "rollbacklink": "ꯑꯃꯨꯛ ꯍꯟꯍꯟꯕꯥ",
+       "rollbacklinkcount": "rollback $1 {{PLURAL:$1|edit|edits}}",
+       "protectlogpage": "ꯂꯣꯒ ꯉꯥꯛꯊꯣꯛꯄꯥ",
+       "restriction-edit": "ꯁꯦꯝꯒꯠꯄꯥ",
+       "restriction-move": "ꯂꯦꯡꯍꯟꯕꯥ",
        "namespace": "ꯃꯥꯃꯤꯡꯒꯤ ꯃꯐꯝ",
        "invert": "Khanlibadu Makoktagi lak hanba",
        "tooltip-invert": "Akhannaba maming gi manungda page tungi ahongba lotnaba oopu du yeng ngoo",
        "contributions": "{{GENDER:$1|User}} ꯈꯣꯝꯒꯠꯂꯛꯄꯁꯤꯡ",
        "mycontris": "ꯈꯣꯝꯒꯠꯂꯛꯂꯤꯕꯁꯤꯡ",
        "anoncontribs": "ꯈꯣꯝꯒꯠꯂꯛꯂꯤꯕꯁꯤꯡ",
+       "uctop": "ꯍꯧꯖꯤꯛ",
        "month": "ꯃꯗꯨꯒꯤ ꯊꯥꯗꯒꯤ (ꯑꯃꯗꯤ ꯅꯧꯔꯤꯕꯥ)",
        "year": "ꯃꯗꯨꯒꯤ ꯆꯥꯍꯤꯗꯒꯤ (ꯑꯃꯗꯤ ꯅꯧꯔꯤꯕꯥ)",
+       "sp-contributions-talk": "ꯉꯥꯡꯐꯝ",
+       "sp-contributions-submit": "ꯊꯤꯕꯥ",
        "whatlinkshere": "ꯃꯁꯤꯗꯥ ꯀꯔꯤ ꯁꯝꯃꯤ",
        "whatlinkshere-title": "$1 ꯒꯥ ꯃꯔꯤ ꯂꯩꯅꯕꯥ ꯁꯝꯅꯐꯝ",
        "whatlinkshere-page": "ꯂꯥꯃꯥꯏ",
        "tooltip-ca-nstab-main": "ꯂꯃꯥꯏꯁꯤꯒꯤ ꯑꯌꯥꯎꯕꯁꯤꯡꯗꯨ ꯎꯨꯇꯂꯨ",
        "tooltip-ca-nstab-user": "ꯁꯤꯖꯤꯟꯅꯔꯤꯕꯥ ꯂꯥꯃꯥꯏꯁꯤ ꯌꯦꯡꯕꯥ",
        "tooltip-ca-nstab-special": "ꯃꯁꯤ ꯑꯈꯟꯅꯕꯥ ꯂꯥꯃꯥꯏꯅꯤ, ꯁꯦꯝꯒꯠꯄꯥ ꯌꯥꯔꯣꯏ",
+       "tooltip-ca-nstab-project": "ꯂꯃꯥꯏꯁꯤꯒꯤ ꯇꯧꯒꯗꯥ ꯊꯧꯔꯥꯡꯗꯨ ꯎꯨꯇꯂꯨ",
        "tooltip-ca-nstab-image": "File lamai du ootlu",
        "tooltip-ca-nstab-template": "ꯇꯦꯝꯄꯂꯦꯠ ꯇꯨ ꯎꯨꯠꯂꯨ",
        "tooltip-ca-nstab-category": "Macahkhaiba lamai sure oootlooo",
        "tooltip-save": "ꯅꯪꯒꯤ ꯑꯍꯣꯡꯕꯗꯨ ꯇꯨꯡꯁꯤꯟꯂꯨ",
        "tooltip-preview": "ꯅꯪꯒꯤ ꯑꯍꯣꯡꯕꯗꯨ ꯑꯃꯨꯛ ꯍꯟꯅꯥ ꯎꯠꯂꯨ. ꯆꯥꯟꯕꯤꯗꯨꯅꯥ ꯃꯁꯤ ꯍꯥꯟꯅꯥ ꯁꯤꯖꯤꯅꯧ ꯇꯪꯁꯤꯟꯗ꯭ꯔꯤꯉꯧꯗꯥ",
        "tooltip-diff": "ꯅꯪꯅꯥ ꯏꯔꯤꯕꯥ ꯄꯥꯔꯦꯡꯗꯨꯗꯥ ꯑꯍꯣꯡꯕꯥ ꯎꯠꯂꯨ",
+       "tooltip-compareselectedversions": "See the differences between the two selected revisions of this page",
        "tooltip-rollback": "ꯑꯔꯣꯏꯕꯥ ꯈꯣꯝꯒꯠꯛꯂꯤꯕꯥꯁꯤꯡꯒꯤ ꯁꯦꯝꯒꯠꯄꯁꯤꯡ ꯗꯨꯒꯤ ꯂꯥꯃꯥꯏ ꯑꯃꯨꯛ ꯅꯝꯕꯗꯥ ꯂꯥꯛꯍꯟꯂꯨ ꯍꯥꯟꯅꯒꯤ ꯃꯐꯝꯗꯨꯗꯥ",
        "tooltip-undo": "\"Undo\" reverts this edit and opens the edit form in preview mode. It allows adding a reason in the summary.",
        "tooltip-summary": "ꯑꯇꯦꯟꯕꯥ ꯀꯨꯞꯅꯥ ꯁꯟꯗꯣꯛꯅꯩ ꯇꯥꯛꯄꯥ ꯏꯌꯨ",
        "simpleantispam-label": "Anti-spam check.\nDo <strong>not</strong> fill this in!",
+       "pageinfo-header-edits": "ꯄꯨꯋꯥꯔꯤ ꯁꯦꯝꯒꯠꯄ",
+       "pageinfo-header-restrictions": "ꯉꯥꯛꯊꯣꯛꯂꯕꯥ ꯂꯥꯃꯥꯏ",
        "pageinfo-robot-noindex": "ꯌꯥꯍꯟꯗꯕꯥ",
        "pageinfo-subpages-name": "ꯂꯥꯃꯥꯏꯁꯤ ꯒꯤ ꯃꯅꯨꯡ ꯆꯟꯕꯥ ꯀꯨꯞꯊꯕꯥ ꯂꯥꯃꯥꯏꯁꯤꯡ",
        "pageinfo-subpages-value": "$1 ($2 {{PLURAL:$2|redirect|redirects}}; $3 {{PLURAL:$3|non-redirect|non-redirects}})",
+       "pageinfo-firstuser": "ꯂꯥꯃꯥꯏ ꯁꯥꯔꯤꯕ ꯃꯤꯑꯣꯏꯁꯤꯡ",
+       "pageinfo-firsttime": "ꯂꯥꯃꯥꯏ ꯁꯥꯈꯤꯕꯒꯤ ꯆꯩꯆꯠ",
+       "pageinfo-lastuser": "ꯈꯋꯥꯏꯗꯒꯤ ꯅꯧꯕ ꯁꯦꯝꯒꯠꯂꯛꯂꯤꯕꯁꯤꯡ",
+       "pageinfo-lasttime": "ꯅꯧꯔꯤꯕ ꯁꯦꯝꯒꯠꯄꯒꯤ ꯆꯩꯆꯠ",
+       "pageinfo-edits": "ꯑꯄꯨꯟꯕ ꯁꯦꯝꯒꯠꯄꯒꯤ ꯃꯁꯤꯡ",
+       "pageinfo-authors": "ꯑꯄꯨꯟꯕ ꯑꯈꯟꯅꯕ ꯑꯌꯤꯕꯁꯤꯡꯒꯤ ꯃꯁꯤꯡ",
        "pageinfo-magic-words": "Magic {{PLURAL:$1|word|words}} ($1)",
        "pageinfo-toolboxlink": "ꯂꯥꯃꯥꯏꯒꯤ ꯃꯇꯥꯡꯗꯥ",
+       "pageinfo-contentpage-yes": "ꯍꯣꯏ",
        "previousdiff": "ꯑꯔꯤꯕꯥ ꯁꯦꯝꯒꯠꯂꯛꯐꯝ",
+       "nextdiff": "ꯑꯅꯧꯕꯥ ꯁꯦꯝꯗꯠꯄ",
        "file-info-size": "$1 × $2 pixels, file size: $3, MIME type: $4",
        "file-nohires": "ꯃꯁꯤꯗꯒꯤ ꯍꯦꯟꯅꯥ ꯁꯦꯡꯕꯥ ꯂꯩꯇꯔꯦ",
        "svg-long-desc": "SVG file, nominally $1 × $2 pixels, file size: $3",
        "namespacesall": "Pullap",
        "monthsall": "ꯄꯨꯂꯞ",
        "signature": "[[{{ns:user}}:$1|$2]] ([[{{ns:user_talk}}:$1|talk]])",
+       "redirect-submit": "ꯆꯠꯂꯨ",
+       "redirect-value": "ꯃꯔꯨꯑꯣꯏꯕꯥ",
        "specialpages": "MediaWiki:Bs-wikiadmin-mediawiki-akhannaba-lamai-text/mni",
        "tag-filter": "[[Special:Tags|Tag]] filter:",
        "tag-list-wrapper": "([[Special:Tags|{{PLURAL:$1|Tag|Tags}}]]: $2)",
+       "tags-active-yes": "ꯍꯣꯏ",
+       "tags-active-no": "ꯅꯠꯇꯦ",
        "logentry-delete-delete": "$1 {{GENDER:$2|deleted}} page $3",
+       "logentry-move-move": "$1 {{GENDER:$2|moved}} page $3 to $4",
        "logentry-newusers-create": "User account $1 was {{GENDER:$2|created}}",
+       "logentry-upload-upload": "$1 {{GENDER:$2|uploaded}} $3",
        "searchsuggest-search": "ꯊꯤꯔꯣ ꯃꯐꯝꯗꯨꯒꯤ ꯃꯃꯤꯡ"
 }
index c3fc175..e73006f 100644 (file)
        "rev-deleted-user": "(အသုံးပြုသူအမည် ဖယ်ရှားပြီး)",
        "rev-deleted-event": "(အသေးစိတ် မှတ်တမ်း ဖယ်ရှားပြီးပြီ)",
        "rev-deleted-text-permission": "ဤစာမျက်နှာ ရာဇဝင်များသည် <strong>ဖျက်ထားပြီး</strong>ဖြစ်သည်။\nအသေးစိတ်များကို [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} ဖျက်ထားသည့် မှတ်တမ်း]တွင် တွေ့ရှိနိုင်ပါသည်။",
+       "rev-deleted-unhide-diff": "ဤမူကွဲ၏ တည်းဖြတ်မူတစ်ခုအား <strong>ဖျက်ထားသည်</strong>။\nအသေးစိတ်ကို [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} ဖျက်ထားသည့် မှတ်တမ်း]တွင် တွေ့ရှိနိုင်သည်။\nသင့်အနေဖြင့် ဆန္ဒရှိပါက [$1 ဤမူကွဲ]ကို ဆက်လက် ကြည့်ရှုနိုင်သည်။",
+       "rev-deleted-diff-view": "ဤမူကွဲ၏ တည်းဖြတ်မူတစ်ခုအား <strong>ဖျက်ထားသည်</strong>။\nဤမူကွဲကို ကြည့်ရှုနိုင်ပြီး အသေးစိတ်ကို [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} ဖျက်ထားသည့် မှတ်တမ်း]တွင် တွေ့ရှိနိုင်သည်။",
        "rev-delundel": "အမြင်ပုံစံ ပြောင်းလဲရန်",
        "rev-showdeleted": "ပြ",
        "revisiondelete": "မူများကို ဖျက်ရန်/မဖျက်တော့ရန်",
index c058b77..512e4ae 100644 (file)
        "sp-contributions-userrights": "{{GENDER:$1|iōng-chiá}} khoân-hān koán-lí",
        "sp-contributions-search": "Chhoē chhut kòng-hiàn",
        "sp-contributions-username": "IP Chū-chí a̍h iōng-chiá miâ:",
+       "sp-contributions-newonly": "Taⁿ piáu-sū chhòng-kiàn ia̍h-bīn ê pian-chi̍p",
+       "sp-contributions-hideminor": "Am-khàm sè-hāng pian-chi̍p",
        "sp-contributions-submit": "Chhoē",
        "whatlinkshere": "Tó-ūi liân kàu chia",
        "whatlinkshere-title": "Liân khì \"$1\" ê ia̍h-bīn",
        "specialpages": "Te̍k-sû-ia̍h",
        "tag-filter": "[[Special:Tags|Piau-chhiam]] chhoē mi̍h:",
        "tag-list-wrapper": "([[Special:Tags|{{PLURAL:$1|piau-chhiam}}]]: $2)",
+       "tag-mw-new-redirect": "Sin choán-ia̍h",
        "logentry-move-move": "$1 {{GENDER:$2|sóa}} $3 chit ia̍h khì $4",
        "logentry-move-move_redir": "$1 iōng choán-ia̍h {{GENDER:$2|sóa}} ia̍h-bīn $3 kòe $4",
        "logentry-newusers-create": "已經{{GENDER:$2|開好}}用者口座 $1",
        "expand_templates_input": "Su-ji̍p bûn-jī:",
        "expand_templates_output": "Kiat-kó:",
        "expand_templates_remove_comments": "Comments the̍h tiāu",
+       "mw-widgets-dateinput-no-date": "Ji̍t-kî iáu-bōe soán",
        "mw-widgets-mediasearch-input-placeholder": "搜揣媒體",
        "date-range-from": "Khai-sí ji̍t-chí:",
        "date-range-to": "Kiat-sok ji̍t-chí:"
index 80d38b6..17886a4 100644 (file)
        "resetpass-submit-loggedin": "Endre passord",
        "resetpass-submit-cancel": "Avbryt",
        "resetpass-wrong-oldpass": "Ugyldig midlertidig eller aktivt passord.\nDet kan tenkes at allerede har gjennomført et vellykket bytte av passord, eller bedt om et nytt midlertidig passord.",
-       "resetpass-recycled": "Vær vennlig å endre passordet til noe annen enn gjeldende passord.",
+       "resetpass-recycled": "Endre passordet ditt til noe annet enn det nåværende passordet.",
        "resetpass-temp-emailed": "Du logget inn med en midlertidig kode sendt på e-post.\nFor å avslutte innloggingen må du angi et nytt passord her:",
        "resetpass-temp-password": "Midlertidig passord:",
        "resetpass-abort-generic": "Endring av passord har blitt avbrutt av en utvidelse.",
        "resetpass-expired": "Passordet ditt har utløpt. Vær vennlig å angi et nytt passord for å logge inn.",
        "resetpass-expired-soft": "Passordet ditt har utløpt og må endres. Vær vennlig å angi et nytt passord, eller klikk \"{{int:authprovider-resetpass-skip-label}}\" for å endre det senere.",
-       "resetpass-validity-soft": "Ditt passord er ikke gyldig: $1",
+       "resetpass-validity-soft": "Passordet ditt er ikke gyldig: $1\n\nVelg et nytt passord nå, eller klikk på «{{int:authprovider-resetpass-skip-label}}» for å endre det seinere.",
        "passwordreset": "Tilbakestilling av passord",
        "passwordreset-text-one": "Fyll ut skjemaet for å tilbakestille passordet",
        "passwordreset-text-many": "{{PLURAL:$1|Fyll inn ett av datafeltene for å tilbakestille passordet ditt via epost.}}",
        "previewerrortext": "En feil oppsto mens dine endringer skulle forhåndsvises.",
        "blockedtitle": "Brukeren er blokkert",
        "blockedtext": "<strong>Ditt brukernavn eller din IP-adresse har blitt blokkert.</strong>\n\nBlokkeringen ble utført av $1. Grunnen som ble oppgitt var <em>$2</em>.\n\n* Blokkeringen begynte:  $8\n* Blokkeringen opphører: $6\n* Blokkeringen ment for: $7\n\nDu kan kontakte $1 eller en annen [[{{MediaWiki:Grouppage-sysop}}|administrator]] for å diskutere blokkeringen.\nDu kan ikke bruke \"{{int:emailuser}}\"-funksjonen med mindre du har oppgitt en gyldig e-postadresse i [[Special:Preferences|innstillingene dine]] og du ikke har blitt blokkert fra å sende e-post.\nDin nåværende IP-adresse er $3, og blokkerings-ID-en er #$5.\nVennligst ta med all denne informasjonen ved henvendelser.",
-       "autoblockedtext": "Din IP-adresse har blitt automatisk blokkert fordi den ble brukt av en annen bruker som ble blokkert av $1.\nDen oppgitte grunnen var:\n\n:'''$2'''\n\n* Blokkeringen begynte: $8\n* Blokkeringen utgår: $6\n* Blokkeringen er ment for: $7\n\nDu kan kontakte $1 eller en av de andre [[{{MediaWiki:Grouppage-sysop}}|administratorene]] for å diskutere blokkeringen.\n\nMerk at du ikke kan bruke «E-post til denne brukeren»-funksjonen med mindre du har registrert en gyldig e-postadresse i [[Special:Preferences|innstillingene dine]].\n\nDin IP-adresse er $3, og blokkerings-ID-en er #$5.\nVennligst ta med all denne informasjonen ved henvendelser.",
+       "autoblockedtext": "Din IP-adresse har blitt automatisk blokkert fordi den ble brukt av en annen bruker som ble blokkert av $1.\nDen oppgitte grunnen var:\n\n:'''$2'''\n\n* Blokkeringen begynte: $8\n* Blokkeringen utgår: $6\n* Blokkeringen er ment for: $7\n\nDu kan kontakte $1 eller en av de andre [[{{MediaWiki:Grouppage-sysop}}|administratorene]] for å diskutere blokkeringen.\n\nMerk at du ikke kan bruke «{{int:emailuser}}»-funksjonen med mindre du har registrert en gyldig e-postadresse i [[Special:Preferences|innstillingene dine]].\n\nDin IP-adresse er $3, og blokkerings-ID-en er #$5.\nVennligst ta med all denne informasjonen ved henvendelser.",
        "systemblockedtext": "Ditt brukernavn eller IP-adresse har blitt blokkert automatisk av MediaWiki.\n\nBlokkeringen grunnes:\n\n:<em>$2</em>\n\n* Blokkeringen startet: $8\n* Blokkeringen gjelder til: $6\n* Blokkeringen er ment for: $7\n\nDin nåværende IP-adresse er $3.\nVennligst inkluder informasjonen over i alle spørsmål du spør angående dette.",
        "blockednoreason": "ingen grunn gitt",
        "whitelistedittext": "Du må $1 for å redigere artikler.",
        "converter-manual-rule-error": "En feil ble oppdaget i en manuell språkkonverteringsregel",
        "undo-success": "Redigeringen kan omgjøres. Sjekk sammenligningen under for å bekrefte at du vil gjøre dette, og lagre endringene for å fullføre omgjøringen.",
        "undo-failure": "Redigeringen kunne ikke omgjøres på grunn av konflikterende etterfølgende redigeringer.",
+       "undo-main-slot-only": "Redigeringen kunne ikke omgjøres fordi den involverer innhold utenfor hovedspalten.",
        "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]])",
        "rcfilters-other-review-tools": "Andre gjennomgangsverktøy",
        "rcfilters-group-results-by-page": "Grupper resultater etter side",
        "rcfilters-activefilters": "Aktive filtre",
+       "rcfilters-activefilters-hide": "Skjul",
+       "rcfilters-activefilters-show": "Vis",
+       "rcfilters-activefilters-hide-tooltip": "Skjul området for aktive filtre",
+       "rcfilters-activefilters-show-tooltip": "Vis området for aktive filtre",
        "rcfilters-advancedfilters": "Avanserte filtre",
        "rcfilters-limit-title": "Antall resultater som skal vises",
        "rcfilters-limit-and-date-label": "$1 {{PLURAL:$1|endring|endringer}}, $2",
        "rcfilters-savedqueries-rename": "Gi nytt navn",
        "rcfilters-savedqueries-setdefault": "Sett som standard",
        "rcfilters-savedqueries-unsetdefault": "Fjern som standard",
-       "rcfilters-savedqueries-remove": "Fjern",
+       "rcfilters-savedqueries-remove": "Slett",
        "rcfilters-savedqueries-new-name-label": "Navn",
        "rcfilters-savedqueries-new-name-placeholder": "Beskriv formålet til filteret",
        "rcfilters-savedqueries-apply-label": "Opprett filter",
        "rcfilters-empty-filter": "Ingen aktive filtre. Alle bidrag vises.",
        "rcfilters-filterlist-title": "Filtre",
        "rcfilters-filterlist-whatsthis": "Hvordan virker dette?",
-       "rcfilters-filterlist-feedbacklink": "Gi tilbakemelding på disse (nye) filterverktøyene",
+       "rcfilters-filterlist-feedbacklink": "Gi tilbakemelding på disse filterverktøyene",
        "rcfilters-highlightbutton-title": "Marker resultater",
        "rcfilters-highlightmenu-title": "Velg en farge",
        "rcfilters-highlightmenu-help": "Velg en farge for å merke denne egenskapen",
index ea57228..6adf737 100644 (file)
        "expansion-depth-exceeded-warning": "De pagina bevat te veel sjablonen",
        "parser-unstrip-loop-warning": "Er is een \"unstrip\"-lus gedetecteerd",
        "unstrip-depth-warning": "De recursielimiet ($1) voor \"unstrip\" is overschreden",
+       "unstrip-depth-category": "Pagina's waar de \"unstrip\" dieptelimiet is overschreden.",
+       "unstrip-size-warning": "De groottelimiet ($1) voor \"unstrip\" is overschreden",
+       "unstrip-size-category": "Pagina's waar de \"unstrip\" groottelimiet is overschreden",
        "converter-manual-rule-error": "Er is een fout gedetecteerd in een handmatig toegevoegde taalconversieregel.",
        "undo-success": "Deze bewerking kan ongedaan gemaakt worden.\nHieronder staat de tekst waarin de wijziging ongedaan is gemaakt.\nControleer voor het opslaan of het resultaat gewenst is.",
        "undo-failure": "De wijziging kan niet ongedaan gemaakt worden vanwege andere strijdige wijzigingen.",
        "version-poweredby-others": "anderen",
        "version-poweredby-translators": "translatewiki.net-vertalers",
        "version-credits-summary": "We erkennen graag de volgende personen voor hun bijdrage aan [[Special:Version|MediaWiki]].",
-       "version-license-info": "MediaWiki is vrije software; u kunt MediaWiki verspreiden en/of aanpassen onder de voorwaarden van de GNU General Public License zoals gepubliceerd door de Free Software Foundation; ofwel versie 2 van de Licentie, of - naar uw wens - enige latere versie.\n\nMediaWiki wordt verspreid in de hoop dat het nuttig is, maar <em>ZONDER ENIGE GARANTIE</em>; zonder zelfs de impliciete garantie van <strong>VERKOOPBAARHEID</strong> of <string>GESCHIKTHEID VOOR ENIG DOEL IN HET BIJZONDER</strong>. Zie de GNU General Public License voor meer informatie.\n\nSamen met dit programma hoort u een [{{SERVER}}{{SCRIPTPATH}}/COPYING kopie van de GNU General Public License] te hebben ontvangen; zo niet, schrijf dan naar de Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA of [//www.gnu.org/licenses/old-licenses/gpl-2.0.html lees de licentie online].",
+       "version-license-info": "MediaWiki is vrije software; u kunt MediaWiki verspreiden en/of aanpassen onder de voorwaarden van de GNU General Public License zoals gepubliceerd door de Free Software Foundation; ofwel versie 2 van de Licentie, of - naar uw wens - enige latere versie.\n\nMediaWiki wordt verspreid in de hoop dat het nuttig is, maar <em>ZONDER ENIGE GARANTIE</em>; zonder zelfs de impliciete garantie van <strong>VERKOOPBAARHEID</strong> of <strong>GESCHIKTHEID VOOR ENIG DOEL IN HET BIJZONDER</strong>. Zie de GNU General Public License voor meer informatie.\n\nSamen met dit programma hoort u een [{{SERVER}}{{SCRIPTPATH}}/COPYING kopie van de GNU General Public License] te hebben ontvangen; zo niet, schrijf dan naar de Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA of [//www.gnu.org/licenses/old-licenses/gpl-2.0.html lees de licentie online].",
        "version-software": "Geïnstalleerde software",
        "version-software-product": "Product",
        "version-software-version": "Versie",
        "limitreport-cputime-value": "$1 {{PLURAL:$1|seconde|seconden}}",
        "limitreport-walltime": "Werkelijk tijdsgebruik",
        "limitreport-walltime-value": "$1 {{PLURAL:$1|seconde|seconden}}",
-       "limitreport-ppvisitednodes": "Aantal nodes bekeken tijdens de voorverwerking:",
-       "limitreport-ppgeneratednodes": "Aantal nodes aangemaakt tijdens de voorverwerking:",
+       "limitreport-ppvisitednodes": "Aantal nodes bekeken tijdens de voorverwerking",
+       "limitreport-ppgeneratednodes": "Aantal nodes aangemaakt tijdens de voorverwerking",
        "limitreport-postexpandincludesize": "Inclusiegrootte na uitbreiden",
        "limitreport-postexpandincludesize-value": "$1/$2 {{PLURAL:$2|byte|bytes}}",
        "limitreport-templateargumentsize": "Grootte sjabloonparameters",
        "limitreport-templateargumentsize-value": "$1 / $2 {{PLURAL:$2|byte|bytes}}",
        "limitreport-expansiondepth": "Hoogste uitbreidingsdiepte",
        "limitreport-expensivefunctioncount": "Aantal kostbare parserfuncties",
+       "limitreport-unstrip-depth": "\"Unstrip\" recursiediepte",
+       "limitreport-unstrip-size": "\"Unstrip\" grootte na uitbreiden",
        "limitreport-unstrip-size-value": "$1/$2 {{PLURAL:$2|byte|bytes}}",
        "expandtemplates": "Sjablonen substitueren",
        "expand_templates_intro": "Deze speciale pagina leest de opgegeven wikitekst in en substitueert recursief alle sjablonen in de wikitekst.\nHet substitueert ook alle parserfuncties zoals\n<code><nowiki>{{</nowiki>#language:…}}</code> en\nvariabelen als <code><nowiki>{{</nowiki>CURRENTDAY}}</code>.\nVrijwel alles tussen dubbele accolades wordt gesubstitueerd.",
index f51ac71..be98c41 100644 (file)
        "prefs-diffs": "Skilnader",
        "prefs-help-prefershttps": "Denne innstillinga vil verta verksam neste gongen du loggar inn.",
        "userrights": "Administrering av brukartilgang",
-       "userrights-lookup-user": "Administrer brukargrupper",
+       "userrights-lookup-user": "Vel ein brukar",
        "userrights-user-editname": "Skriv inn brukarnamn:",
-       "editusergroup": "Endre brukargrupper",
+       "editusergroup": "Last inn brukargrupper",
        "editinguser": "Endrar brukarrettane til brukaren '''[[User:$1|$1]]''' $2",
+       "viewinguserrights": "Viser brukarrettane til {{GENDER:$1|brukaren}} <strong>[[User:$1|$1]]</strong> $2",
        "userrights-editusergroup": "Endre brukargrupper",
+       "userrights-viewusergroup": "Sjå {{GENDER:$1|brukargrupper}}",
        "saveusergroups": "Lagre brukargrupper",
        "userrights-groupsmember": "Medlem av:",
        "userrights-groupsmember-auto": "Implisitt medlem av:",
        "right-siteadmin": "Låse og låse opp databasen",
        "right-override-export-depth": "Eksporter sider inkludert lenkte sider til ei djupn på 5",
        "right-sendemail": "Senda e-post til andre brukarar",
+       "grant-group-page-interaction": "Verka inn på sider",
        "grant-group-high-volume": "Utføra høgvolumaktivitet",
+       "grant-group-administration": "Utføra administrative handlingar",
        "grant-blockusers": "Blokkera og avblokkera brukarar",
        "grant-createaccount": "Oppretta kontoar",
        "grant-createeditmovepage": "Oppretta, endra og flytta sider",
        "grant-delete": "Sletta sider, versjonar og loggoppføringar",
        "grant-editinterface": "Gjera endringar i MediaWiki-namnerommet og i CSS/JavaScript for brukarkontoen",
+       "grant-editpage": "Endra oppretta sider",
        "grant-highvolume": "Høgvolumendring",
        "grant-protect": "Verna og avverna sider",
+       "grant-rollback": "Rulla attende endringar på sider",
        "grant-sendemail": "Senda e-post til andre brukarar",
        "grant-uploadeditmovefile": "Lasta opp, byta ut og flytta filer",
        "grant-uploadfile": "Lasta opp nye filer",
        "rcfilters-legend-heading": "<strong>Liste over forkortingar:</strong>",
        "rcfilters-group-results-by-page": "Grupper resultat etter side",
        "rcfilters-activefilters": "Aktive filter",
+       "rcfilters-activefilters-hide": "Gøym",
+       "rcfilters-activefilters-show": "Vis",
+       "rcfilters-activefilters-hide-tooltip": "Gøym området for aktive filter",
+       "rcfilters-activefilters-show-tooltip": "Vis området for aktive filter",
        "rcfilters-advancedfilters": "Avanserte filter",
-       "rcfilters-limit-title": "Tal endringar som skal visast",
+       "rcfilters-limit-title": "Resultat som skal visast",
        "rcfilters-limit-and-date-label": "{{PLURAL:$1|éi endring|$1 endringar}}, $2",
        "rcfilters-date-popup-title": "Søk i tidsperioden",
        "rcfilters-days-title": "Dei siste dagane",
        "booksources-search": "Søk",
        "booksources-text": "Nedanfor finn du ei liste over lenkjer til andre nettstader som sel nye og brukte bøker, og desse kan ha meir informasjon om bøker du leitar etter:",
        "booksources-invalid-isbn": "Det oppgjevne ISBN-nummeret er ugyldig; sjekk med kjelda di om du har oppgjeve det rett.",
+       "magiclink-tracking-rfc": "Sider som nyttar magiske RFC-lenkjer",
+       "magiclink-tracking-pmid": "Sider som nyttar magiske PMID-lenkjer‎",
+       "magiclink-tracking-isbn": "Sider som nyttar magiske ISBN-lenkjer",
        "specialloguserlabel": "Utøvar:",
        "speciallogtitlelabel": "Mål (tittel eller {{ns:user}}:brukarnamn for brukar):",
        "log": "Loggar",
        "trackingcategories-msg": "Sporingskategori",
        "trackingcategories-name": "Meldingsnamn",
        "trackingcategories-desc": "Inkluderingsgrunnlag",
+       "restricted-displaytitle-ignored": "Sider med ignorerte visingstitlar",
+       "restricted-displaytitle-ignored-desc": "Ein <code><nowiki>{{DISPLAYTITLE}}</nowiki></code>-funksjon på denne sida  er sett bort ifrå av di argumentet ikkje svarar til den faktiske tittelen til sida.",
        "noindex-category-desc": "Sida vert ikkje indeksert av robotar av di ho inneheld trylleordet <code><nowiki>__NOINDEX__</nowiki></code> og er i eit namnerom der dette flagget er tillate.",
        "trackingcategories-nodesc": "Inga skilding er tilgjengeleg.",
        "trackingcategories-disabled": "Kategorien er avslegen",
        "editcomment": "Samandraget for endringa var: <em>$1</em>.",
        "revertpage": "Attenderulla endring gjord av [[Special:Contributions/$2|$2]] ([[User talk:$2|diskusjon]]) til siste versjonen av [[User:$1|$1]]",
        "revertpage-nouser": "Attenderulla endring gjord av ein løynd brukar til siste versjonen av {{GENDER:$1|[[User:$1|$1]]}}",
-       "rollback-success": "Rulla attende endringane av $1, attende til siste versjonen av $2.",
+       "rollback-success": "Rulla attende endringane av {{GENDER:$3|$1}}, attende til siste versjonen av {{GENDER:$4|$2}}.",
        "sessionfailure-title": "Feil med omgangen.",
        "sessionfailure": "Det ser ut til å vera eit problem med innloggingsøkta di. Handlinga er vorten avbroten for å vera føre var mot kidnapping av økta. Bruk attendeknappen i nettlesaren din og prøv om att.",
        "changecontentmodel": "Endra innhaldsmodellen til ei side",
        "exif-model": "Kameramodell",
        "exif-software": "Programvare brukt",
        "exif-artist": "Skapar",
-       "exif-copyright": "Opphavsrettsleg eigar",
+       "exif-copyright": "Opphavsrettshaldar",
        "exif-exifversion": "Exif-versjon",
        "exif-flashpixversion": "Støtta Flashpix-versjon",
        "exif-colorspace": "Fargerom",
        "watchlisttools-raw": "Endre på overvakingslista i råformat",
        "signature": "[[{{ns:user}}:$1|$2]] ([[{{ns:user_talk}}:$1|diskusjon]])",
        "duplicate-defaultsort": "Åtvaring: Standardsorteringa «$2» tar over for den tidlegare sorteringa «$1».",
+       "restricted-displaytitle": "<strong>Åtvaring:</strong> Visingstittelen «$1» vart sett bort frå sidan han ikkje svarar til den faktiske tittelen til sida.",
        "version": "Versjon",
        "version-extensions": "Installerte utvidingar",
        "version-skins": "Installerte drakter",
index 989c83b..9fba0d5 100644 (file)
        "virus-scanfailed": "کھوج نا ہوسکی (کوڈ $1)",
        "virus-unknownscanner": "اندیکھا اینٹیوائرس:",
        "logouttext": "'''تسی لاگ آؤٹ ہوگۓ او.'''\nتسی   {{SITENAME}} نوں گمنامی چ ورت سکدے او یا تسی <span class='plainlinks'>[$1 لاگ ان دوبارہ]</span> ہوجاؤ اوسے ناں توں یا وکھرے ورتن والے توں۔ اے گل چیتے رکھنا جے کج صفیاں تے تسی لاگ ان دسے جاؤگے جدوں تک تسی اپنے براؤزر دے کاشے نوں صاف ناں کرلو۔\nYou can continue to use {{SITENAME}} anonymously, or you can <span class='plainlinks'>[$1 log in again]</span> as the same or as a different user.\nNote that some pages may continue to be displayed as if you were still logged in, until you clear your browser cache.",
+       "welcomeuser": "جی آیاں نوں، $1!",
        "yourname": "ورتن والہ:",
        "userlogin-yourname": "ورتن ناں",
        "userlogin-yourname-ph": "اپنا ورتن ناں لکھو",
index 7802628..ad46b4d 100644 (file)
        "rcfilters-savedqueries-apply-and-setdefault-label": "د فرض په ډول د فيلټر جوړول",
        "rcfilters-savedqueries-cancel-label": "ناگارل",
        "rcfilters-savedqueries-add-new-title": "د امستنې اوسنۍ فيلټر خوندي کړي",
+       "rcfilters-restore-default-filters": "د ډيفاولټ فلټرونه بیا تازه کول",
        "rcfilters-search-placeholder": "د فلټر بدلونونه (د مینو کارول یا د فلټر نوم لټونه)",
        "rcfilters-invalid-filter": "غلط فلټر",
        "rcfilters-empty-filter": "هيڅ فعال فلټر نشته. ټولي سمونې ښکاره شوي.",
        "undeletepagetitle": "'''د [[:$1|$1]] ړنگې شوې بڼې په لاندې توگه دي'''.",
        "viewdeletedpage": "ړنگ شوي مخونه کتل",
        "undelete-fieldset-title": "بڼې بيازېرمل",
+       "undeleteextrahelp": "د ټول مخ د معلوماتو د بيا کتنې لپاره د '''''{{int:undeletebtn}}''''' پر\nبټن کښي کاږي، او ددي ترمخه چي د '''''{{int:undeletebtn}}''''' پر مخ ګوته يا موس بټن کښي کاږي نو لږ فکر پر وکړي.",
        "undeleterevisions": "$1 {{PLURAL:$1|بڼه|بڼې}} خونديځ کې {{PLURAL:$1|ورگډ شو|ورگډ شول}}",
        "undeletehistory": "که تاسې همدا مخ بيازېرمه کوۍ، نو ټولې بڼې به يې پېښليک کې زېرمه شي.\nکه چېرته د ړنگېدو وروسته په همدې نوم يو بل نوی مخ جوړ شوی وي، نو زېرمه شوې بڼې به يې په پخواني پېښليک کې ښکاره شي.",
+       "undeleterevdel": "ړنګيدنه بيرته راګرځول به د مخ په پيښنليک کي نشي ښکاره، او تاسو که ليکنه ړنګه کړي نو د کارنانو سمونې به بيا هم پرځای پاته وي. \nپه دا ډول پيښو کې تاسو بايد د کارنانو سمونې پټې يا ړنګې کړي.",
+       "undelete-revision": "د $1 ړنګه شوي بڼه (چې د $4 نيټې په $5 بجو) د $3 لخوا داسې جوړه شوي وه:",
        "undelete-nodiff": "کومې پخوانۍ بڼې و نه موندل شوې.",
        "undeletebtn": "بيازېرمل",
        "undeletelink": "کتل/بيازېرمل",
index 120b542..23b2f66 100644 (file)
        "removedwatchtext-short": "A página \"$1\" foi removida de sua lista de páginas vigiadas.",
        "watch": "Vigiar",
        "watchthispage": "Vigiar esta página",
-       "unwatch": "Desinteressar-se",
+       "unwatch": "Deixar de vigiar",
        "unwatchthispage": "Parar de vigiar esta página",
        "notanarticle": "Não é uma página de conteúdo",
        "notvisiblerev": "Edição eliminada",
        "sp-contributions-logs": "registros",
        "sp-contributions-talk": "discussão",
        "sp-contributions-userrights": "{{GENDER:$1|gestão}} dos privilégios",
-       "sp-contributions-blocked-notice": "Este usuário atualmente está bloqueado. O registro de bloqueio mais recente é fornecido abaixo para referência:",
+       "sp-contributions-blocked-notice": "{{GENDER:$1|Este usuário atualmente está bloqueado|Esta usuária atualmente está bloqueada|Este(a) usuário(a) atualmente está bloqueado(a)}}. O registro de bloqueio mais recente é fornecido abaixo para referência:",
        "sp-contributions-blocked-notice-anon": "Este endereço IP encontra-se bloqueado.\nSegue, para referência, a entrada mais recente no registro de bloqueios:",
        "sp-contributions-search": "Navegar pelas contribuições",
        "sp-contributions-username": "Endereço de IP ou usuário(a):",
index db51aa6..0220365 100644 (file)
@@ -77,7 +77,8 @@
                        "RadiX",
                        "MokaAkashiyaPT",
                        "Athena in Wonderland",
-                       "Fitoschido"
+                       "Fitoschido",
+                       "Ldacosta"
                ]
        },
        "tog-underline": "Sublinhar hiperligações:",
        "viewhelppage": "Ver página de ajuda",
        "categorypage": "Ver página de categoria",
        "viewtalkpage": "Ver discussão",
-       "otherlanguages": "Noutras línguas",
+       "otherlanguages": "Em outros idiomas",
        "redirectedfrom": "(Redirecionado de $1)",
        "redirectpagesub": "Página de redirecionamento",
        "redirectto": "Redireciona para:",
        "mostinterwikis": "Páginas com mais hiperligações interwikis",
        "mostrevisions": "Páginas com mais revisões",
        "prefixindex": "Todas as páginas iniciadas por",
-       "prefixindex-namespace": "Todas as páginas com prefixo (domínio $1)",
+       "prefixindex-namespace": "Todas as páginas com prefixo (espaço nominal $1)",
        "prefixindex-submit": "Mostrar",
        "prefixindex-strip": "Remover prefixo",
        "shortpages": "Páginas curtas",
        "nowikiemailtext": "Este utilizador optou por não receber correio eletrónico de outros utilizadores.",
        "emailnotarget": "O nome do destinatário não existe ou é inválido.",
        "emailtarget": "Introduza o nome do destinatário",
-       "emailusername": "Utilizador:",
+       "emailusername": "Nome de Utilizador:",
        "emailusernamesubmit": "Enviar",
        "email-legend": "Enviar uma mensagem a outro utilizador da wiki {{SITENAME}}",
        "emailfrom": "De:",
        "removedwatchtext-short": "A página \"$1\" foi removida das suas páginas vigiadas.",
        "watch": "Vigiar",
        "watchthispage": "Vigiar esta página",
-       "unwatch": "Desinteressar-se",
+       "unwatch": "Deixar de vigiar",
        "unwatchthispage": "Parar de vigiar esta página",
        "notanarticle": "Não é uma página de conteúdo",
        "notvisiblerev": "A última revisão feita por um utilizador diferente foi eliminada",
        "sp-contributions-logs": "registos",
        "sp-contributions-talk": "discussão",
        "sp-contributions-userrights": "{{GENDER:$1|gestão}} dos privilégios",
-       "sp-contributions-blocked-notice": "Este utilizador está bloqueado neste momento.\nPara referência é apresentado abaixo o último registo de bloqueio:",
+       "sp-contributions-blocked-notice": "{{GENDER:$1|Este utilizador está bloqueado|Esta utilizadora está bloqueada}} neste momento.\nPara referência é apresentado abaixo o último registo de bloqueio:",
        "sp-contributions-blocked-notice-anon": "Este endereço IP está bloqueado neste momento.\nPara referência é apresentado abaixo o último registo de bloqueio:",
        "sp-contributions-search": "Pesquisar contribuições",
        "sp-contributions-username": "Endereço IP ou nome de utilizador:",
index 082230f..d9fef83 100644 (file)
        "prefs-editor": "Used in [[Special:Preferences]], tab \"Editing\" ({{int:prefs-editing}}).\n\n{{Identical|Editor}}",
        "prefs-preview": "Used in [[Special:Preferences]], tab \"Editing\".\n{{Identical|Preview}}",
        "prefs-advancedrc": "Used in [[Special:Preferences]], tab \"Recent changes\".\n{{Identical|Advanced options}}",
-       "prefs-opt-out": "Used in [[Special:Preferences]], tab \"Recent changes\".",
+       "prefs-opt-out": "Used in [[Special:Preferences]], tabs \"Recent changes\" and \"Watchlist\".",
        "prefs-advancedrendering": "Used in [[Special:Preferences]], tab \"Appearence\".\n{{Identical|Advanced options}}",
        "prefs-advancedsearchoptions": "Used in [[Special:Preferences]], tab \"Search options\".\n{{Identical|Advanced options}}",
        "prefs-advancedwatchlist": "Used in [[Special:Preferences]], tab \"Watchlist\".\n{{Identical|Advanced options}}",
index 111f637..c858a1a 100644 (file)
        "yourtext": "Qillqasqayki",
        "storedversion": "Hallch'asqa musuqchasqa",
        "editingold": "'''Paqtataq: Kay p'anqap mawk'a hukchasqantam llamk'apuchkanki. Waqaychaptiykiqa, chaymanta aswan musuq hukchasqankuna chinkanqam.'''",
+       "unicode-support-fail": "Wamp'unaykiqa manayá llamk'achinchu sapatuyru (Unicode) nisqata. P'anqakunata llamk'apunapaqqa muchusqa kaptinmi, llamk'apusqaykiqa manam waqaychasqachu.",
        "yourdiff": "Hukchasqaykikuna",
        "copyrightwarning": "Lliw {{SITENAME}}paq llamk'apuykunaqa $2 nisqawanmi uyaychasqa kanqa ($1 p'anqata qhaway). Llamk'asqaykikunata huk runakunap allinchayninta qispilla mast'ariyninta mana munaspaykiqa, ama kayman qillqamuychu.<br />\nTakyachichkankim: Kayqa ñuqap qillqasqaymi icha qispi pukyumanta iskaychamusqaymi, nispa.\n<br />'''Mana saqillasqa kaspaykiqa, ama qillqarimuychu iskaychay hayñi ''(copyright)'' nisqayuq qillqakunata iskaychamuspa!'''",
        "copyrightwarning2": "Lliw {{SITENAME}}paq llamk'apuykunaqa huk ruraqkunap llamk'apunallanmi, hukchanallanmi icha qullunallanmi. Llamk'asqaykikunata huk runakunap allinchayninta qispilla mast'ariyninta mana munaspaykiqa, ama kayman qillqamuychu.<br />\nTakyachichkankim: Kayqa ñuqap qillqasqaymi, ñuqamanmi kapuwan icha qispi pukyumanta iskaychamusqaymi, nispa ($1 p'anqata qhaway).\n<br />'''Mana saqillasqa kaspaykiqa, ama qillqarimuychu iskaychay hayñi ''(copyright)'' nisqayuq qillqakunata iskaychamuspa!'''",
        "recentchanges-label-plusminus": "P'anqap chhikan, kay byte yupaywan wakinchasqa",
        "recentchanges-legend-heading": "<strong>Sut'ichana:</strong>",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} ([[Special:NewPages|musuq p'anqakunatapas]] qhaway)",
+       "rcfilters-other-review-tools": "Huk qhawakipana llamk'anakuna",
+       "rcfilters-activefilters": "Llamk'achkaq ch'illchinakuna",
+       "rcfilters-activefilters-hide": "Pakay",
+       "rcfilters-activefilters-show": "Rikuchiy",
+       "rcfilters-limit-and-date-label": "$1 {{PLURAL:$1|hukchasqa|hukchasqakuna}}, $2",
+       "rcfilters-quickfilters-placeholder-title": "Manaraqmi ima ch'illchina waqaychasqachu",
+       "rcfilters-quickfilters-placeholder-description": "Chillch'ina churasqakunata qhipaqta llamk'achinaypaq waqaychanaykipaqqa, urapi kaq Llamk'achkaq Ch'illchina suyuchapi sananchana rikch'achata ñit'iy.",
+       "rcfilters-savedqueries-defaultlabel": "Waqaychasqa ch'illchinakuna",
+       "rcfilters-search-placeholder": "Hukchasqakunata ch'illchiy (sutisuyuta llamk'achiy icha ch'illchinap sutinta maskay)",
+       "rcfilters-filter-humans-label": "Chiqap runa",
+       "rcfilters-filter-pageedits-label": "P'anqakunapi hukchasqakuna",
+       "rcfilters-filter-newpages-label": "Kamarisqa p'anqakuna",
+       "rcfilters-filter-logactions-label": "Hallch'asqa rurasqakuna",
+       "rcfilters-liveupdates-button": "Tuylla musuqchasqakuna",
+       "rcfilters-liveupdates-button-title-on": "Tuylla musuqchasqakunata thasnuy",
        "rcnotefrom": "Kay qatiqpiqa <strong>$2</strong>-mantapacha (<strong>$1</strong>-kama) hukchasqakunatam rikunki.",
        "rclistfrom": "$3 $2-manta musuq hukchasqakunata rikuchiy",
        "rcshowhideminor": "$1 uchuylla llamk'apusqakunata",
        "wlheader-showupdated": "Qayna watukamusqaykimantapacha hukchasqa p'anqakunataqa '''yanasapa''' nisqapim rikunki.",
        "wlnote": "Kay qatiqpiqa {{PLURAL:$1|qhipaq hukchasqam|'''$1''' qhipaq hukchasqakunam}} qhipaq {{PLURAL:$2|urapim|'''$2''' urakunapim}}, musuqchasqa $3, $4.",
        "wlshowlast": "$1 ura, $2 p'unchaw -mantapacha hukchasqakunata rikuchiy",
+       "watchlist-hide": "Pakay",
        "watchlist-options": "Watiqana sutisuyupaq allinkachinakuna",
        "watching": "Watiqasqakunaman yapaspa...",
        "unwatching": "Watiqasqakunamanta qulluspa...",
index f4cfc79..e52721f 100644 (file)
        "apisandbox": "Песочница API",
        "apisandbox-jsonly": "Для использования API-песочницы требуется JavaScript.",
        "apisandbox-api-disabled": "API отключен на этом сайте.",
-       "apisandbox-intro": "Используйте эту страницу для экспериментов с <strong>MediaWiki API</strong>.\nОбратитесь к [[mw:API:Main page|документации API]] для получения дополнительной информации об использовании API. Например, о том, [https://www.mediawiki.org/wiki/API#A_simple_example как получить содержание Заглавной страницы]. Выберите действие, чтобы увидеть другие примеры.\nОбратите внимание, что, хотя это и песочница, действия, выполненные на этой странице, могут внести изменения в вики.",
+       "apisandbox-intro": "Используйте эту страницу для экспериментов с <strong>MediaWiki API</strong>.\nОбратитесь к документации API ([https://ru.wikipedia.org/w/api.php встроенной] или [[mw:API:Main page|внешней]]) для получения дополнительной информации об использовании API. Например, о том, [https://www.mediawiki.org/wiki/API#A_simple_example как получить содержание Заглавной страницы]. Выберите действие, чтобы увидеть другие примеры.\nОбратите внимание, что, хотя это и песочница, действия, выполненные на этой странице, могут внести изменения в вики.",
        "apisandbox-submit": "Сделать запрос",
        "apisandbox-reset": "Очистить",
        "apisandbox-retry": "Повторить",
index 6af24e5..3d12f42 100644 (file)
        "talk": "ᱜᱟᱞᱢᱟᱨᱟᱣ",
        "views": "ᱧᱮᱞᱚᱜᱚᱜ",
        "toolbox": "ᱦᱟᱹᱛᱭᱟᱹᱨ",
+       "tool-link-userrights": "{{GENDER:$1|ᱵᱮᱵᱷᱟᱨᱤᱭᱟᱹ}} ᱜᱟᱫᱮᱞ ᱵᱚᱫᱚᱞ",
+       "tool-link-userrights-readonly": "{{GENDER:$1|ᱵᱮᱵᱷᱟᱨᱤᱭᱟᱹ}} ᱜᱟᱫᱮᱞ ᱧᱮᱞ",
        "tool-link-emailuser": "ᱤᱢᱮᱞᱟᱭᱢᱮ ᱱᱩᱭ {{GENDER:$1|ᱵᱮᱵᱷᱟᱨᱤᱭᱟᱹ}}",
        "imagepage": "ᱨᱮᱫ ᱥᱟᱦᱴᱟ ᱧᱮᱞᱢᱮ",
        "mediawikipage": "ᱠᱷᱚᱵᱚᱨ ᱥᱟᱦᱴᱟ ᱧᱮᱞᱢᱮ",
        "jumptonavigation": "ᱟᱹᱪᱩᱨᱵᱟᱲᱟ",
        "jumptosearch": "ᱥᱮᱸᱫᱽᱨᱟ",
        "view-pool-error": "Ikạkańmẽ, sarvarre nitoḱ do aḍi cap menaḱa.\nẠḍi aema beoharko noa sakam ńel lạgit́ko kurumuṭueda.\nNãwate noa sakam ńel kurumuṭuy lạgit́te dayakate mit́ghạṛi tạṅgiymẽ.\n$1",
+       "generic-pool-error": "ᱤᱠᱟᱹᱠᱟᱹᱧᱢᱮ, ᱱᱚᱶᱟ ᱥᱚᱨᱵᱷᱚᱨ ᱨᱮ ᱱᱤᱛ ᱟᱹᱰᱤᱜᱟᱱ ᱪᱟᱯ ᱢᱮᱱᱟᱜᱼᱟ ᱾\nᱟᱹᱰᱤ ᱟᱭᱢᱟ ᱵᱮᱵᱷᱟᱨᱤᱭᱟᱹ ᱱᱚᱶᱟ ᱥᱟᱠᱟᱢ ᱧᱮᱞ ᱞᱟᱹᱜᱤᱫ ᱠᱚ ᱨᱤᱠᱟᱹᱭᱮᱫᱼᱟ ᱾\nᱱᱚᱶᱟ ᱥᱟᱠᱟᱢ ᱧᱮᱞ ᱞᱟᱹᱜᱤᱰ ᱱᱟᱥᱮ ᱛᱟᱺᱜᱤ ᱢᱮ ᱾",
        "pool-timeout": "Somoy paromena cạbi lạgit́te tạṅgi hoyoḱkana",
        "pool-queuefull": "Pool queue is full",
        "pool-errorunknown": "ᱵᱟᱝ ᱵᱟᱰᱟᱭ ᱦᱩᱲᱟᱹᱜ",
        "filerenameerror": "\"$1\" ᱨᱮᱫ ᱨᱮᱭᱟᱜ ᱧᱩᱛᱩᱢ ᱵᱚᱫᱚᱞ ᱠᱟᱛᱮ \"$2\" ᱮᱢ ᱵᱟᱝ ᱜᱟᱱᱚᱜ ᱠᱟᱱᱟ᱾",
        "filedeleteerror": "$1 ᱨᱮᱫ ᱫᱚ ᱵᱟᱝ ᱜᱮᱫᱽ ᱜᱤᱰᱤ ᱞᱮᱱᱟ",
        "directorycreateerror": "\"$1\" ᱰᱟᱭᱨᱮᱠᱴᱳᱨᱤ ᱫᱚ ᱵᱟᱝ ᱛᱮᱭᱟᱨᱞᱮᱱᱟ᱾",
+       "directorynotreadableerror": "ᱯᱟᱠᱷᱟ \"$1\" ᱫᱚ ᱯᱟᱲᱦᱟᱣ ᱵᱟᱭ ᱜᱟᱱᱚᱜᱼᱟ ᱾",
        "filenotfound": "\"$1\" ᱨᱮᱫ ᱫᱚ ᱵᱟᱝ ᱧᱟᱢᱞᱮᱱᱟ᱾",
        "unexpected": "ᱵᱟᱝ ᱟᱥᱟᱜ ᱠᱟᱱ ᱢᱟᱹᱱ: \"$1\"=\"$2\".",
        "formerror": "ᱦᱩᱲᱟᱹᱜ: ᱯᱷᱚᱨᱚᱢ ᱫᱚ ᱵᱟᱝ ᱡᱤᱢᱟᱹᱞᱮᱱᱟ᱾",
        "rcfilters-days-show-days": "$1 {{PLURAL:$1|ᱢᱟᱦᱟ|ᱢᱟᱦᱟᱸ}}",
        "rcfilters-days-show-hours": "$1 {{PLURAL:$1|ᱴᱟᱲᱟᱝ|ᱴᱟᱬᱟᱝ}}",
        "rcfilters-savedqueries-rename": "ᱧᱩᱢ-ᱟᱹᱨᱩ",
-       "rcfilters-savedqueries-remove": "á±\9aᱪá±\9aá±\9c",
+       "rcfilters-savedqueries-remove": "á±\9cᱮᱫ á±\9cᱤᱰᱤ",
        "rcfilters-savedqueries-new-name-label": "ᱧᱩᱛᱩᱢ",
        "rcfilters-savedqueries-cancel-label": "ᱵᱟᱹᱜᱤ",
        "rcnotefrom": "ᱞᱟᱛᱟᱨ {{PLURAL:$5|ᱵᱚᱫᱚᱞ|ᱵᱚᱫᱚᱞ ᱠᱚ}} <strong>$3, $4</strong> ᱠᱷᱚᱱ (<strong>$1</strong> ᱦᱟᱹᱵᱤᱡ ᱩᱫᱩᱜ-ᱮᱱᱟ)",
index 7e80c08..f5d84d8 100644 (file)
        "edithelp": "لکھݨ وچ مدد",
        "helppage-top-gethelp": "مدد",
        "mainpage": "وݙا ورقہ",
-       "mainpage-description": "Ù¾Û\81Ù\84ا ورقہ",
+       "mainpage-description": "Ù\88Ý\99ا ورقہ",
        "policy-url": "Project:پالیسی",
        "portal": "بیٹھک",
        "portal-url": "Project:دیوان عام",
        "recentchanges-submit": "ݙیکھاؤ",
        "rcfilters-tag-remove": "ہٹاؤ '$1'",
        "rcfilters-activefilters": "فعال نتارے",
+       "rcfilters-activefilters-hide": "لُکاؤ",
+       "rcfilters-activefilters-show": "ݙِکھاؤ",
        "rcfilters-advancedfilters": "ودھائے نتارے",
        "rcfilters-limit-title": "ݙیکھاوݨ کیتے نتیجے",
        "rcfilters-limit-and-date-label": "$1{{PLURAL:$1|تبدیلی|تبدیلیاں}}، $2",
        "tooltip-search": "ڳولو {{SITENAME}}",
        "tooltip-search-go": "جے ایں عنوان دا ورقہ ہے تاں اتھ ونڄو",
        "tooltip-search-fulltext": "ایں عبارت کوں ورقیاں وچ ڳولو",
-       "tooltip-p-logo": "Ù¾Û\81Ù\84ا ورقہ ݙیکھو",
-       "tooltip-n-mainpage": "Ù¾Û\81Ù\84ا ورقہ ݙیکھو",
+       "tooltip-p-logo": "Ù\88Ý\99ا ورقہ ݙیکھو",
+       "tooltip-n-mainpage": "Ù\88Ý\99ا ورقہ ݙیکھو",
        "tooltip-n-mainpage-description": "پہلے ورقے تے ونڄو",
        "tooltip-n-portal": "ایں مںصوبے بارے، تساں کیا کر سڳدو، ، چیزاں کتھوں ڳولوں",
        "tooltip-n-currentevents": "موجودہ حالات وچ پچھلیاں معلومات ݙیکھو",
index 656f82f..9f8a351 100644 (file)
@@ -49,7 +49,7 @@
        "tog-extendwatchlist": "Прошири списак надгледања за приказ свих измена, не само скорашњих",
        "tog-usenewrc": "Групиши измене по страници у скорашњим изменама и списку надгледања",
        "tog-numberheadings": "Аутоматски нумериши поднаслове",
-       "tog-showtoolbar": "Ð\9fÑ\80икажи Ñ\82Ñ\80акÑ\83 Ñ\81 алаткама за уређивање",
+       "tog-showtoolbar": "ТÑ\80ака Ñ\81а алаткама за уређивање",
        "tog-editondblclick": "Уреди странице двоструким кликом",
        "tog-editsectiononrightclick": "Уређивање одељака десним кликом на њихове наслове",
        "tog-watchcreations": "Додај странице које направим и датотеке које отпремим у мој списак надгледања",
@@ -81,7 +81,7 @@
        "tog-watchlisthidecategorization": "Сакриј категоризацију страница",
        "tog-ccmeonemails": "Пошаљи ми копије имејлова које пошаљем другим корисницима",
        "tog-diffonly": "Не приказуј садржај странице испод разлика",
-       "tog-showhiddencats": "Ð\9fÑ\80икажи Ñ\81кривене категорије",
+       "tog-showhiddencats": "Скривене категорије",
        "tog-norollbackdiff": "Не приказуј разлику након извршеног враћања",
        "tog-useeditwarning": "Упозори ме када напуштам страницу са несачуваним изменама",
        "tog-prefershttps": "Увек користи сигурну везу док сам пријављен.",
        "december-date": "$1. децембар",
        "period-am": "преподне",
        "period-pm": "поподне",
-       "pagecategories": "{{PLURAL:$1|Категорија|Категорије|Категорија}}",
+       "pagecategories": "{{PLURAL:$1|Категорија|Категорије}}",
        "category_header": "Странице у категорији „$1“",
        "subcategories": "Поткатегорије",
        "category-media-header": "Датотеке у категорији „$1“",
        "permalink": "Трајна веза",
        "print": "Штампај",
        "view": "Погледај",
-       "view-foreign": "Ð\92иди на пројекту $1",
+       "view-foreign": "Ð\9fогледаÑ\98 на пројекту $1",
        "edit": "Уреди",
        "edit-local": "Уреди локални опис",
        "create": "Направи",
        "pool-servererror": "Услуга бројача редова није доступна ($1).",
        "poolcounter-usage-error": "Грешка при употреби: $1",
        "aboutsite": "О пројекту {{SITENAME}}",
-       "aboutpage": "Project:О нама",
+       "aboutpage": "Project:О_пројекту_{{SITENAME}}",
        "copyright": "Садржај је доступан под лиценцом $1 осим ако је другачије наведено.",
        "copyrightpage": "{{ns:project}}:Ауторска права",
        "currentevents": "Актуелности",
        "pagetitle-view-mainpage": "{{SITENAME}}",
        "backlinksubtitle": "← $1",
        "retrievedfrom": "Преузето из „$1“",
-       "youhavenewmessages": "Имате $1 ($2).",
+       "youhavenewmessages": "{{PLURAL:$3|Имате}} $1 ($2).",
        "youhavenewmessagesfromusers": "{{PLURAL:$4|Имате}} $1 од {{PLURAL:$3|другог корисника|$3 корисника}} ($2).",
        "youhavenewmessagesmanyusers": "Имате $1 од много корисника ($2).",
        "newmessageslinkplural": "{{PLURAL:$1|нову поруку|нове поруке|нових порука}}",
        "viewsourceold": "изворни кôд",
        "editlink": "уреди",
        "viewsourcelink": "изворни кôд",
-       "editsectionhint": "Уреди одељак „$1“",
+       "editsectionhint": "Уредите одељак „$1“",
        "toc": "Садржај",
        "showtoc": "прикажи",
        "hidetoc": "сакриј",
        "sort-descending": "Поређај опадајуће",
        "sort-ascending": "Поређај растуће",
        "nstab-main": "Страница",
-       "nstab-user": "{{GENDER:{{BASEPAGENAME}}|Корисник|Корисница|Корисник}}",
+       "nstab-user": "Корисничка страница",
        "nstab-media": "Медији",
-       "nstab-special": "Ð\9fоÑ\81ебно",
-       "nstab-project": "Ð\9fÑ\80оÑ\98екаÑ\82",
+       "nstab-special": "Ð\9fоÑ\81ебна Ñ\81Ñ\82Ñ\80аниÑ\86а",
+       "nstab-project": "СÑ\82Ñ\80аниÑ\86а Ð¿Ñ\80оÑ\98екÑ\82а",
        "nstab-image": "Датотека",
        "nstab-mediawiki": "Порука",
        "nstab-template": "Шаблон",
        "virus-badscanner": "Неисправно подешавање: непознати скенер за вирусе: <em>$1</em>",
        "virus-scanfailed": "неуспешно скенирање (код $1)",
        "virus-unknownscanner": "непознати антивирус:",
-       "logouttext": "<strong>Ð\9eдÑ\98авÑ\99ени Ñ\81Ñ\82е.</strong>\n\nÐ\98маÑ\98Ñ\82е Ð½Ð° Ñ\83мÑ\83 Ð´Ð° Ð½ÐµÐºÐµ Ñ\81Ñ\82Ñ\80аниÑ\86е Ð¼Ð¾Ð³Ñ\83 Ð½Ð°Ñ\81Ñ\82авиÑ\82и Ð´Ð° Ñ\81е Ð¿Ñ\80иказÑ\83Ñ\98Ñ\83 ÐºÐ°Ð¾ Ð´Ð° Ñ\81Ñ\82е Ñ\98оÑ\88 Ð¿Ñ\80иÑ\98авÑ\99ени, Ñ\81ве Ð´Ð¾Ðº Ð½Ðµ Ð¾Ñ\87иÑ\81Ñ\82иÑ\82е Ð¿Ñ\80ивÑ\80еменÑ\83 Ð¼ÐµÐ¼Ð¾Ñ\80иÑ\98Ñ\83 Ð\92аÑ\88ег прегледача.",
+       "logouttext": "<strong>Сада Ñ\81Ñ\82е Ð¾Ð´Ñ\98авÑ\99ени.</strong>\n\nÐ\97апамÑ\82иÑ\82е Ð´Ð° Ð½ÐµÐºÐµ Ñ\81Ñ\82Ñ\80аниÑ\86е Ð¼Ð¾Ð³Ñ\83 Ð´Ð° Ð½Ð°Ñ\81Ñ\82аве Ð´Ð° Ñ\81е Ð¿Ñ\80иказÑ\83Ñ\98Ñ\83 ÐºÐ°Ð¾ Ð´Ð° Ñ\81Ñ\82е Ñ\98оÑ\88 Ñ\83век Ð¿Ñ\80иÑ\98авÑ\99ени, Ð´Ð¾Ðº Ð½Ðµ Ð¾Ñ\87иÑ\81Ñ\82иÑ\82е Ð¿Ñ\80ивÑ\80еменÑ\83 Ð¼ÐµÐ¼Ð¾Ñ\80иÑ\98Ñ\83 Ñ\81вог прегледача.",
        "cannotlogoutnow-title": "Одјава тренутно није могућа",
        "cannotlogoutnow-text": "Одјава није могућа током употребе $1.",
        "welcomeuser": "Добро дошли, $1!",
        "userlogin-yourpassword-ph": "Унесите своју лозинку",
        "createacct-yourpassword-ph": "Унесите лозинку",
        "yourpasswordagain": "Поново унеси лозинку:",
-       "createacct-yourpasswordagain": "Потврди лозинку",
+       "createacct-yourpasswordagain": "Потврдите лозинку",
        "createacct-yourpasswordagain-ph": "Унесите лозинку поново",
        "userlogin-remembermypassword": "Остави ме пријављеног/у",
        "userlogin-signwithsecure": "Користите сигурну конекцију",
        "userlogout": "Одјава",
        "notloggedin": "Нисте пријављени",
        "userlogin-noaccount": "Немате налог?",
-       "userlogin-joinproject": "Ð\9eÑ\82воÑ\80иÑ\82е Ð³Ð°",
+       "userlogin-joinproject": "Ð\9fÑ\80идÑ\80Ñ\83жиÑ\82е Ñ\81е Ð¿Ñ\80оÑ\98екÑ\82Ñ\83 {{SITENAME}}",
        "createaccount": "Отвори налог",
        "userlogin-resetpassword-link": "Заборавили сте лозинку?",
        "userlogin-helplink2": "Помоћ при пријављивању",
        "resetpass-submit-cancel": "Откажи",
        "resetpass-wrong-oldpass": "Неисправна привремена или тренутна лозинка.\nМожда сте већ променили лозинку или сте затражили нову привремену лозинку.",
        "resetpass-recycled": "Унели сте садашњу лозинку, да бисте променили лозинку морате унети нову.",
-       "resetpass-temp-emailed": "Пријавили сте се са привременим кодом из имејла.\nДа бисте завршили пријављивање морате поставити нову лозинку овде:",
+       "resetpass-temp-emailed": "Пријавили сте се са привременим кôдом из имејла.\nДа бисте завршили пријављивање морате поставити нову лозинку овде:",
        "resetpass-temp-password": "Привремена лозинка:",
        "resetpass-abort-generic": "Промену лозинке је спречио додатак.",
        "resetpass-expired": "Ваша лозинка је истекла. Поставите нову лозинку да бисте се пријавили.",
        "link_sample": "Наслов везе",
        "link_tip": "Унутрашња веза",
        "extlink_sample": "http://www.example.com/ наслов везе",
-       "extlink_tip": "Спољашња веза (с префиксом http://)",
-       "headline_sample": "ТекÑ\81Ñ\82 Ð½Ð°Ñ\81лова",
-       "headline_tip": "Поднаслов (ниво 2)",
+       "extlink_tip": "Спољашња веза (запамтите префикс http://)",
+       "headline_sample": "Ð\9dаÑ\81лов",
+       "headline_tip": "Поднаслов",
        "nowiki_sample": "Убаците необликован текст овде",
        "nowiki_tip": "Занемари вики обликовање",
        "image_sample": "Пример.jpg",
        "showpreview": "Прикажи претпреглед",
        "showdiff": "Прикажи измене",
        "blankarticle": "<strong>Упозорење:</strong> Страница коју правите је празна.\nАко још једном притиснете „$1”, страница ће бити направљена без икаквог садржаја.",
-       "anoneditwarning": "<strong>УпозоÑ\80еÑ\9aе:</strong> Ð\9dиÑ\81Ñ\82е Ð¿Ñ\80иÑ\98авÑ\99ени. Ð\90ко Ð¾Ð±Ñ\98авиÑ\82е Ñ\81Ñ\82Ñ\80аниÑ\86Ñ\83, Ð\92аÑ\88а IP Ð°Ð´Ñ\80еÑ\81а Ñ\9bе Ð±Ð¸Ñ\82и Ñ\98авно Ð²Ð¸Ð´Ñ\99ива Ñ\83 Ñ\9aеноÑ\98 Ð¸Ñ\81Ñ\82оÑ\80иÑ\98и Ð¸Ð·Ð¼ÐµÐ½Ð° Ð¸ Ð´Ñ\80Ñ\83где. Ð\90ко Ñ\81е <strong>[$1 Ð¿Ñ\80иÑ\98авиÑ\82е]</strong> Ð¸Ð»Ð¸ <strong>[$2 Ð¾Ñ\82воÑ\80иÑ\82е Ð½Ð°Ð»Ð¾Ð³]</strong>, Ð¿Ð¾Ñ\80ед Ð¾Ñ\81Ñ\82алиÑ\85 Ð¿Ð¾Ð³Ð¾Ð´Ð½Ð¾Ñ\81Ñ\82и ÐºÐ¾Ñ\98е Ð´Ð¾Ð±Ð¸Ñ\98аÑ\82е Ð\92аÑ\88е Ð¸Ð·Ð¼ÐµÐ½Ðµ Ñ\9bе Ð±Ð¸Ñ\82и Ð¿Ñ\80ипиÑ\81иване Ð\92аÑ\88ем ÐºÐ¾Ñ\80иÑ\81ниÑ\87ком Ð¸Ð¼ÐµÐ½Ñ\83.",
+       "anoneditwarning": "<strong>УпозоÑ\80еÑ\9aе:</strong> Ð\9dиÑ\81Ñ\82е Ð¿Ñ\80иÑ\98авÑ\99ени. Ð\92аÑ\88а IP Ð°Ð´Ñ\80еÑ\81а Ñ\9bе Ð±Ð¸Ñ\82и Ñ\98авно Ð²Ð¸Ð´Ñ\99ива Ð°ÐºÐ¾ Ð½Ð°Ð¿Ñ\80авиÑ\82е Ð½ÐµÐºÑ\83 Ð¸Ð·Ð¼ÐµÐ½Ñ\83. Ð\90ко Ñ\81е <strong>[$1 Ð¿Ñ\80иÑ\98авиÑ\82е]</strong> Ð¸Ð»Ð¸ <strong>[$2 Ð¾Ñ\82воÑ\80иÑ\82е Ð½Ð°Ð»Ð¾Ð³]</strong>, Ð\92аÑ\88е Ð¸Ð·Ð¼ÐµÐ½Ðµ Ñ\9bе Ð±Ð¸Ñ\82и Ð¿Ñ\80ипиÑ\81иване Ð\92аÑ\88ем ÐºÐ¾Ñ\80иÑ\81ниÑ\87ком Ð¸Ð¼ÐµÐ½Ñ\83, Ð¿Ð¾Ñ\80ед Ð´Ñ\80Ñ\83гиÑ\85 Ð¿Ð¾Ð³Ð¾Ð´Ð½Ð¾Ñ\81Ñ\82и.",
        "anonpreviewwarning": "<em>Нисте пријављени. Ако објавите страницу, Ваша IP адреса ће бити јавно видљива у њеној историји измена и другде.</em>",
        "missingsummary": "<strong>Подсетник:</strong> Нисте унели опис измене.\nАко поново кликнете на „$1”, Ваша измена ће бити сачувана без описа.",
        "selfredirect": "<strong>Упозорење:</strong> Преусмеравате ову страницу на њу саму.\nМожда вам је одредишна страница за преусмерење погрешна или уређујете погрешну страницу.\nАко још једном притиснете „$1”, преусмерење ће свеједно бити направљено.",
        "newarticle": "(нови)",
        "newarticletext": "Дошли сте на страницу која још не постоји.\nДа бисте је направили, почните да куцате у прозор испод овог текста (погледајте [$1 страницу за помоћ]).\nАко сте овде дошли грешком, вратите се на претходну страницу.",
        "anontalkpagetext": "----\n<em>Ово је страница за разговор с анонимним корисником који још нема налог или га не користи.</em>\nЗбог тога морамо да користимо бројчану IP адресу како бисмо га препознали.\nТакву адресу може делити више корисника.\nАко сте анонимни корисник и мислите да су вам упућене примедбе, [[Special:CreateAccount|отворите налог]] или се [[Special:UserLogin|пријавите]] да бисте избегли будућу забуну с осталим анонимним корисницима.",
-       "noarticletext": "Ð\9dа Ð¾Ð²Ð¾Ñ\98 Ñ\81Ñ\82Ñ\80аниÑ\86и Ñ\82Ñ\80енÑ\83Ñ\82но Ð½ÐµÐ¼Ð° Ñ\81адÑ\80жаÑ\98а.\nМожете [[Special:Search/{{PAGENAME}}|потражити овај наслов]] на другим страницама,\n<span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} претражити сродне извештаје] или [{{fullurl:{{FULLPAGENAME}}|action=edit}} направити ову страницу]</span>.",
-       "noarticletext-nopermission": "Ð\9dа Ð¾Ð²Ð¾Ñ\98 Ñ\81Ñ\82Ñ\80аниÑ\86и Ñ\82Ñ\80енÑ\83Ñ\82но Ð½ÐµÐ¼Ð° Ñ\81адÑ\80жаÑ\98а.\nМожете [[Special:Search/{{PAGENAME}}|потражити овај наслов]] на другим страницама или <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} претражити сродне дневнике]</span>, али немате дозволу да направите ову страницу.",
+       "noarticletext": "Ð\9dа Ð¾Ð²Ð¾Ñ\98 Ñ\81Ñ\82Ñ\80аниÑ\86и Ñ\82Ñ\80енÑ\83Ñ\82но Ð½ÐµÐ¼Ð° Ñ\82екÑ\81Ñ\82а.\nМожете [[Special:Search/{{PAGENAME}}|потражити овај наслов]] на другим страницама,\n<span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} претражити сродне извештаје] или [{{fullurl:{{FULLPAGENAME}}|action=edit}} направити ову страницу]</span>.",
+       "noarticletext-nopermission": "Ð\9dа Ð¾Ð²Ð¾Ñ\98 Ñ\81Ñ\82Ñ\80аниÑ\86и Ñ\82Ñ\80енÑ\83Ñ\82но Ð½ÐµÐ¼Ð° Ñ\82екÑ\81Ñ\82а.\nМожете [[Special:Search/{{PAGENAME}}|потражити овај наслов]] на другим страницама или <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} претражити сродне дневнике]</span>, али немате дозволу да направите ову страницу.",
        "missing-revision": "Не могу да пронађем измену бр. $1 на страници под називом „{{FULLPAGENAME}}“.\n\nОво се обично дешава када пратите застарелу везу до странице која је обрисана.\nВише информација можете пронаћи у [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} дневнику брисања].",
        "userpage-userdoesnotexist": "Кориснички налог „<nowiki>$1</nowiki>“ није отворен.\nРазмислите да ли заиста желите да направите/уредите ову страницу.",
        "userpage-userdoesnotexist-view": "Кориснички налог „$1“ није отворен.",
        "viewpagelogs": "Дневници ове странице",
        "nohistory": "Не постоји историја измена ове странице.",
        "currentrev": "Тренутна измена",
-       "currentrev-asof": "Ð\9fоÑ\81ледÑ\9aа измена на датум $2 у $3",
+       "currentrev-asof": "ТÑ\80енÑ\83Ñ\82на измена на датум $2 у $3",
        "revisionasof": "Измена на датум $2 у $3",
        "revision-info": "Измена од $1 од стране {{GENDER:$6|корисника $2|кориснице $2}}$7",
        "previousrevision": "← Старија измена",
        "page_first": "прва",
        "page_last": "последња",
        "histlegend": "Избор разлика: изаберите кутијице измена за упоређивање и притисните ентер или дугме на дну.<br />\nОбјашњење: <strong>({{int:cur}})</strong> = разлика с тренутном изменом, <strong>({{int:last}})</strong> = разлика с претходном изменом, <strong>{{int:minoreditletter}}</strong> = мања измена",
-       "history-fieldset-title": "Преглед измена",
+       "history-fieldset-title": "Претрага измена",
        "history-show-deleted": "Само обрисане измене",
        "histfirst": "најстарије",
        "histlast": "најновије",
        "revertmerge": "растави",
        "mergelogpagetext": "Испод је списак најскоријих спајања историја двеју страница.",
        "history-title": "Историја измена странице „$1“",
-       "difference-title": "$1 — разлика између измена",
+       "difference-title": "Разлика између измена на страници „$1“",
        "difference-title-multipage": "Разлика између страница „$1“ и „$2“",
        "difference-multipage": "(разлике између страница)",
        "lineno": "Ред $1:",
        "next-page": "следећа страница",
        "prevn-title": "$1 {{PLURAL:$1|претходни  резултат|претходна резултата|претходних резултата}}",
        "nextn-title": "$1 {{PLURAL:$1|следећи резултат|следећа резултата|следећих резултата}}",
-       "shown-title": "Прикажи $1 {{PLURAL:$1|резултат|резултата|резултата}} по страници",
+       "shown-title": "Прикажи $1 {{PLURAL:$1|резултат|резултата}} по страници",
        "viewprevnext": "Погледај ($1 {{int:pipe-separator}} $2) ($3).",
        "searchmenu-exists": "<strong>Постоји страница под називом „[[:$1]]”!</strong> {{PLURAL:$2|0=|Такође погледајте друге пронађене резултате претраге.}}",
-       "searchmenu-new": "<strong>Направите страницу „[[:$1]]”!</strong> {{PLURAL:$2|0=|Такође погледајте резултат претраге.|Такође погледајте резултате претраге.}}",
+       "searchmenu-new": "<strong>Направите страницу „[[:$1]]” на овом викију!</strong> {{PLURAL:$2|0=|Такође погледајте страницу пронађену претрагом.|Такође погледајте резултате претраге.}}",
        "searchprofile-articles": "Странице са садржајем",
        "searchprofile-images": "Датотеке",
        "searchprofile-everything": "Све",
        "searchprofile-images-tooltip": "Претражите датотеке",
        "searchprofile-everything-tooltip": "Претражите сав садржај (укључујући странице за разговор)",
        "searchprofile-advanced-tooltip": "Претражите прилагођене именске просторе",
-       "search-result-size": "$1 ({{PLURAL:$2|1 реч|$2 речи|$2 речи}})",
+       "search-result-size": "$1 ({{PLURAL:$2|1 реч|$2 речи}})",
        "search-result-category-size": "{{PLURAL:$1|1 члан|$1 члана|$1 чланова}}, ({{PLURAL:$2|1 поткатегорија|$2 поткатегорије|$2 поткатегорија}}, {{PLURAL:$3|1 датотека|$3 датотеке|$3 датотека}})",
-       "search-redirect": "(преусмерено са $1)",
+       "search-redirect": "(преусмерење са $1)",
        "search-section": "(одељак $1)",
        "search-category": "(категорија $1)",
        "search-file-match": "(подудара се садржај датотеке)",
-       "search-suggest": "Да ли сте мислили на: $1",
+       "search-suggest": "Да ли сте мислили: $1",
        "search-rewritten": "Приказани резултати за $1. Ипак претражи $2.",
        "search-interwiki-caption": "Резултати са сестринских пројеката",
        "search-interwiki-default": "Резултати са $1:",
        "showingresults": "Испод {{PLURAL:$1|је приказан <strong>1</strong> резултат|су приказана <strong>$1</strong> резултата|је приказано <strong>$1</strong> резултата}}, почев од броја <strong>$2</strong>.",
        "showingresultsinrange": "Испод {{PLURAL:$1|је приказан <strong>1</strong> резултат|су приказана <strong>$1</strong> резултата|је приказано <strong>$1</strong> резултата}}, у распону од <strong>$2</strong> до <strong>$3</strong>.",
        "search-showingresults": "{{PLURAL:$4|Резултат <strong>$1</strong> од <strong>$3</strong>|Резултати <strong>$1—$2</strong> од <strong>$3</strong>}}",
-       "search-nonefound": "Ð\9dема Ð¿Ð¾ÐºÐ»Ð°Ð¿Ð°Ñ\9aа.",
+       "search-nonefound": "Ð\9dиÑ\81Ñ\83 Ð¿Ñ\80онаÑ\92ени Ñ\80езÑ\83лÑ\82аÑ\82и ÐºÐ¾Ñ\98и Ð¾Ð´Ð³Ð¾Ð²Ð°Ñ\80аÑ\98Ñ\83 Ñ\83пиÑ\82Ñ\83.",
        "search-nonefound-thiswiki": "Нема резултата на овом сајту који се поклапају са термином претраге.",
        "powersearch-legend": "Напредна претрага",
        "powersearch-ns": "Претрага по именским просторима:",
        "right-bot": "сматрање измена као аутоматски процес",
        "right-nominornewtalk": "непоседовање мањих измена на страницама за разговор отвара прозор за нове поруке",
        "right-apihighlimits": "коришћење виших граница за упите из API-ја",
-       "right-writeapi": "пиÑ\81аÑ\9aе API-ја",
+       "right-writeapi": "могÑ\83Ñ\9bноÑ\81Ñ\82 Ð¿Ð¸Ñ\81аÑ\9aа API-ја",
        "right-delete": "брисање страница",
        "right-bigdelete": "брисање страница с великом историјом",
        "right-deletelogentry": "брисање и враћање одређених ставки у дневнику",
        "recentchanges-network": "Због техничког проблема не могу да учитам резултате. Покушајте да освежите страницу.",
        "recentchanges-notargetpage": "Унесите назив странице како бисте видели сродне измене.",
        "recentchanges-feed-description": "Пратите скорашње измене уз помоћ овог довода.",
-       "recentchanges-label-newpage": "Ð\9dова страница",
+       "recentchanges-label-newpage": "Ð\9eвом Ð¸Ð·Ð¼ÐµÐ½Ð¾Ð¼ Ñ\98е Ð½Ð°Ð¿Ñ\80авÑ\99ена Ð½ова страница",
        "recentchanges-label-minor": "Ово је мања измена",
        "recentchanges-label-bot": "Ову измену је направио бот",
        "recentchanges-label-unpatrolled": "Ова измена још није патролирана",
        "recentchanges-label-plusminus": "Промена величине странице у бајтовима",
        "recentchanges-legend-heading": "<strong>Легенда:</strong>",
-       "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} ([[Special:NewPages|списак нових страница]])",
+       "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (такође погледајте [[Special:NewPages|списак нових страница]])",
+       "recentchanges-legend-plusminus": "(<em>±123</em>)",
        "recentchanges-submit": "Прикажи",
-       "rcfilters-tag-remove": "Уклони филтер „$1”",
+       "rcfilters-tag-remove": "Уклоните филтер „$1“",
        "rcfilters-legend-heading": "<strong>Списак скраћеница:</strong>",
        "rcfilters-other-review-tools": "Друге алатке за преглед",
        "rcfilters-group-results-by-page": "Групиши резултате по страницама",
        "rcfilters-activefilters": "Активни филтери",
        "rcfilters-activefilters-hide": "Сакриј",
        "rcfilters-activefilters-show": "Прикажи",
-       "rcfilters-activefilters-hide-tooltip": "Сакриј подручје активних филтера",
-       "rcfilters-activefilters-show-tooltip": "Прикажи подручје активних филтера",
+       "rcfilters-activefilters-hide-tooltip": "Сакријте подручје активних филтера",
+       "rcfilters-activefilters-show-tooltip": "Прикажите подручје активних филтера",
        "rcfilters-advancedfilters": "Напредни филтери",
        "rcfilters-limit-title": "Број измена за приказ",
        "rcfilters-limit-and-date-label": "$1 {{PLURAL:$1|измена|измене|измена}}, $2",
        "rcfilters-savedqueries-apply-label": "Направи филтер",
        "rcfilters-savedqueries-apply-and-setdefault-label": "Направи подразумевани филтер",
        "rcfilters-savedqueries-cancel-label": "Откажи",
-       "rcfilters-savedqueries-add-new-title": "Сачувај тренутна подешавања филтера",
-       "rcfilters-savedqueries-already-saved": "Ð\9eви Ñ\84илÑ\82еÑ\80и Ñ\81Ñ\83 Ð²ÐµÑ\9b Ñ\81аÑ\87Ñ\83вани. Ð\98змениÑ\82е Ð\92аÑ\88а Ð¿Ð¾Ð´ÐµÑ\88аваÑ\9aа ÐºÐ°ÐºÐ¾ бисте направили нове сачуване филтере.",
+       "rcfilters-savedqueries-add-new-title": "Сачувајте тренутна подешавања филтера",
+       "rcfilters-savedqueries-already-saved": "Ð\9eви Ñ\84илÑ\82еÑ\80и Ñ\81Ñ\83 Ð²ÐµÑ\9b Ñ\81аÑ\87Ñ\83вани. Ð\98змениÑ\82е Ð\92аÑ\88а Ð¿Ð¾Ð´ÐµÑ\88аваÑ\9aа Ð´Ð° бисте направили нове сачуване филтере.",
        "rcfilters-restore-default-filters": "Врати подразумеване филтере",
-       "rcfilters-clear-all-filters": "Уклони све филтере",
+       "rcfilters-clear-all-filters": "Уклоните све филтере",
        "rcfilters-show-new-changes": "Најновије измене",
-       "rcfilters-search-placeholder": "Филтрирај измене (користите мени или претрагу за име филтера)",
+       "rcfilters-search-placeholder": "Филтрирајте измене (користите мени или претрагу за име филтера)",
        "rcfilters-invalid-filter": "Неисправан филтер",
        "rcfilters-empty-filter": "Нема активних филтера. Сви доприноси су приказани.",
        "rcfilters-filterlist-title": "Филтери",
        "rcfilters-filterlist-whatsthis": "Како ово функционише?",
        "rcfilters-filterlist-feedbacklink": "Реците нам шта мислите о овим алаткама за филтрирање",
        "rcfilters-highlightbutton-title": "Истакни резултате",
-       "rcfilters-highlightmenu-title": "Ð\98забеÑ\80иÑ\82е Ð±Ð¾Ñ\98Ñ\83",
+       "rcfilters-highlightmenu-title": "Ð\98збоÑ\80 Ð±Ð¾Ñ\98е",
        "rcfilters-highlightmenu-help": "Изаберите боју да бисте истакнули ово својство",
        "rcfilters-filterlist-noresults": "Нема пронађених филтера",
        "rcfilters-noresults-conflict": "Није пронађен ниједан резултат јер су критеријуми претраге сукобљени",
        "rcfilters-exclude-button-off": "Изостави означено",
        "rcfilters-exclude-button-on": "Изостави одабрано",
        "rcfilters-view-tags": "Означене измене",
-       "rcfilters-view-namespaces-tooltip": "Филтрирај резултате према именском простору",
-       "rcfilters-view-tags-tooltip": "Филтрирај резултате према ознаци измене",
+       "rcfilters-view-namespaces-tooltip": "Филтрирајте резултате према именском простору",
+       "rcfilters-view-tags-tooltip": "Филтрирајте резултате према ознаци измене",
        "rcfilters-view-return-to-default-tooltip": "Повратак на главни мени",
        "rcfilters-view-tags-help-icon-tooltip": "Сазнајте више о означеним изменама",
        "rcfilters-liveupdates-button": "Ажурирај уживо",
-       "rcfilters-liveupdates-button-title-on": "Искључи ажурирања уживо",
-       "rcfilters-liveupdates-button-title-off": "Прикажи нове измене уживо",
+       "rcfilters-liveupdates-button-title-on": "Искључите ажурирања уживо",
+       "rcfilters-liveupdates-button-title-off": "Прикажите нове измене уживо",
        "rcfilters-watchlist-markseen-button": "Означи све измене као погледане",
        "rcfilters-watchlist-edit-watchlist-button": "Промени списак надгледаних страница",
-       "rcfilters-watchlist-showupdated": "Измене на страницама које нисте посетили од када је измена извршена су <strong>подебљане</strong>, са испуњеним ознакама.",
+       "rcfilters-watchlist-showupdated": "Измене страница које нисте посетили од када је измена извршена су <strong>подебљане</strong>, са испуњеним ознакама.",
        "rcfilters-preference-label": "Сакриј побољшану верзију скорашњих измена",
        "rcfilters-preference-help": "Поништава редизајн интерфејса из 2017. и све алатке додате тада и после.",
        "rcfilters-watchlist-preference-label": "Сакриј побољшану верзију списка надгледања",
        "rcfilters-target-page-placeholder": "Унесите име странице (или категорије)",
        "rcnotefrom": "Испод {{PLURAL:$5|је измена|су измене}} од <strong>$3, $4</strong> (до <strong>$1</strong> приказано).",
        "rclistfromreset": "Ресетуј одабир датума",
-       "rclistfrom": "Прикажи нове измене почев од $2, $3",
+       "rclistfrom": "Прикажи нове измене почев од $3 у $2",
        "rcshowhideminor": "$1 мање измене",
        "rcshowhideminor-show": "Прикажи",
        "rcshowhideminor-hide": "Сакриј",
        "recentchangeslinked-feed": "Сродне измене",
        "recentchangeslinked-toolbox": "Сродне измене",
        "recentchangeslinked-title": "Сродне измене са „$1“",
-       "recentchangeslinked-summary": "УнеÑ\81иÑ\82е Ð¸Ð¼Ðµ Ñ\81Ñ\82Ñ\80аниÑ\86е Ð´Ð° Ð±Ð¸Ñ\81Ñ\82е Ð²Ð¸Ð´ÐµÐ»Ð¸ Ð¿Ñ\80омене Ð½Ð° Ñ\81Ñ\82Ñ\80аниÑ\86ама ÐºÐ¾Ñ\98е Ñ\81Ñ\83 Ð¿Ð¾Ð²ÐµÐ·Ð°Ð½Ðµ Ñ\81а Ð¸Ð»Ð¸ Ñ\81а Ñ\82е Ñ\81Ñ\82Ñ\80аниÑ\86е. (Ð\94а Ð±Ð¸Ñ\81Ñ\82е Ð²Ð¸Ð´ÐµÐ»Ð¸ Ñ\87ланове ÐºÐ°Ñ\82егоÑ\80иÑ\98е, Ñ\83неÑ\81иÑ\82е {{ns:category}}:Ð\98ме ÐºÐ°Ñ\82егоÑ\80иÑ\98е). Ð\9fÑ\80омене Ð½Ð° Ñ\81Ñ\82Ñ\80аниÑ\86ама ÐºÐ¾Ñ\98е Ñ\81Ñ\83 на [[Special:Watchlist|Вашем списку надгледања]] су <strong>подебљане</strong>.",
+       "recentchangeslinked-summary": "УнеÑ\81иÑ\82е Ð¸Ð¼Ðµ Ñ\81Ñ\82Ñ\80аниÑ\86е Ð´Ð° Ð±Ð¸Ñ\81Ñ\82е Ð²Ð¸Ð´ÐµÐ»Ð¸ Ð¸Ð·Ð¼ÐµÐ½Ðµ Ñ\81Ñ\82Ñ\80аниÑ\86а ÐºÐ¾Ñ\98е Ñ\81Ñ\83 Ð¿Ð¾Ð²ÐµÐ·Ð°Ð½Ðµ Ñ\81а Ð¸Ð»Ð¸ Ñ\81а Ñ\82е Ñ\81Ñ\82Ñ\80аниÑ\86е. (Ð\94а Ð±Ð¸Ñ\81Ñ\82е Ð²Ð¸Ð´ÐµÐ»Ð¸ Ñ\87ланове ÐºÐ°Ñ\82егоÑ\80иÑ\98е, Ñ\83неÑ\81иÑ\82е {{ns:category}}:Ð\98ме ÐºÐ°Ñ\82егоÑ\80иÑ\98е). Ð\98змене Ñ\81Ñ\82Ñ\80аниÑ\86а на [[Special:Watchlist|Вашем списку надгледања]] су <strong>подебљане</strong>.",
        "recentchangeslinked-page": "Назив странице:",
        "recentchangeslinked-to": "Прикажи измене страница које су повезане с датом страницом",
        "recentchanges-page-added-to-category": "[[:$1]] је додата у категорију",
        "upload-curl-error28": "Отпремање је истекло",
        "upload-curl-error28-text": "Сервер не одговара на упит.\nПроверите да ли сајт ради, мало осачекајте и покушајте поново.\nПробајте касније када буде мање оптерећење.",
        "license": "Лиценца:",
-       "license-header": "Ð\9bиÑ\86енÑ\86а:",
+       "license-header": "Ð\9bиÑ\86енÑ\86иÑ\80аÑ\9aе",
        "nolicense": "Није изабрано",
        "licenses-edit": "Уреди избор лиценци",
        "license-nopreview": "(преглед није доступан)",
        "filehist-revert": "врати",
        "filehist-current": "тренутно",
        "filehist-datetime": "Датум/време",
-       "filehist-thumb": "УмаÑ\9aени Ð¿Ñ\80иказ",
-       "filehist-thumbtext": "УмаÑ\9aени Ð¿Ñ\80иказ Ð·Ð° Ð¸Ð·Ð´Ð°Ñ\9aе Ð¾Ð´ $1",
+       "filehist-thumb": "Ð\9cиниÑ\98аÑ\82Ñ\83Ñ\80а",
+       "filehist-thumbtext": "Ð\9cиниÑ\98аÑ\82Ñ\83Ñ\80а Ð·Ð° Ð²ÐµÑ\80зиÑ\98Ñ\83 Ð½Ð° Ð´Ð°Ð½ $1",
        "filehist-nothumb": "Нема умањеног приказа",
        "filehist-user": "Корисник",
        "filehist-dimensions": "Димензије",
        "apisandbox-multivalue-all-namespaces": "$1 (сви именски простори)",
        "apisandbox-multivalue-all-values": "$1 (све вредности)",
        "booksources": "Штампани извори",
-       "booksources-search-legend": "ТÑ\80ажи ÐºÑ\9aижевне изворе",
+       "booksources-search-legend": "Ð\9fÑ\80еÑ\82Ñ\80ажи Ñ\88Ñ\82ампане изворе",
        "booksources-isbn": "ISBN:",
        "booksources-search": "Претражи",
        "booksources-text": "Испод се налази списак веза ка сајтовима који се баве продајом нових и половних књига, а који би могли имати додатне податке о књигама које тражите:",
        "watchnologin": "Нисте пријављени",
        "addwatch": "Додај на списак надгледања",
        "addedwatchtext": "Страница „[[:$1]]“ и њена страница за разговор је додата на Ваш [[Special:Watchlist|списак надгледања]].",
+       "addedwatchtext-talk": "Страница „[[:$1]]” и њена придружена страница је додата на Ваш [[Special:Watchlist|списак надгледања]]",
        "addedwatchtext-short": "Страница „$1“ је додата на Ваш списак надгледања.",
        "removewatch": "Уклони са списка надгледања",
-       "removedwatchtext": "Страница „[[:$1]]“ и њена страница за разговор је уклоњена с вашег [[Special:Watchlist|списка надгледања]].",
+       "removedwatchtext": "Страница „[[:$1]]“ и њена страница за разговор је уклоњена са Вашег [[Special:Watchlist|списка надгледања]].",
        "removedwatchtext-short": "Страница „$1“ је уклоњена с вашег списка надгледања.",
        "watch": "Надгледај",
        "watchthispage": "Надгледај ову страницу",
        "wlshowhidemine": "моје измене",
        "wlshowhidecategorization": "категоризацију страница",
        "watchlist-options": "Опције списка надгледања",
-       "watching": "Надгледање…",
-       "unwatching": "УклаÑ\9aаÑ\9aе Ñ\81а Ñ\81пиÑ\81ка Ð½Ð°Ð´Ð³Ð»ÐµÐ´Ð°Ñ\9aа...",
+       "watching": "Надгледам…",
+       "unwatching": "Ð\9fÑ\80еÑ\81Ñ\82аÑ\98ем Ð´Ð° Ð½Ð°Ð´Ð³Ð»ÐµÐ´Ð°Ð¼...",
        "watcherrortext": "Дошло је до грешке при промени поставки вашег списка надгледања за „$1“.",
        "enotif_reset": "Означи све странице као посећене",
        "enotif_impersonal_salutation": "{{SITENAME}} корисник",
        "dellogpage": "Дневник брисања",
        "dellogpagetext": "Испод је списак последњих брисања.",
        "deletionlog": "дневник брисања",
+       "logentry-create-create": "$1 је {{GENDER:$2|направио|направила}} страницу $3",
        "reverted": "Враћено на ранију измену",
        "deletecomment": "Разлог:",
        "deleteotherreason": "Други/додатни разлог:",
        "cantrollback": "Не могу да вратим измену.\nПоследњи аутор је уједно и једини.",
        "alreadyrolled": "Враћање последње измене странице [[:$1]] од стране {{GENDER:$2|корисника|кориснице|корисника}} [[User:$2|$2]] ([[User talk:$2|разговор]]{{int:pipe-separator}}[[Special:Contributions/$2|{{int:contribslink}}]]) није успело; неко други је у међувремену изменио или вратио страницу.\n\nПоследњу измену је {{GENDER:$3|направио|направила|направио}} [[User:$3|$3]] ([[User talk:$3|разговор]]{{int:pipe-separator}}[[Special:Contributions/$3|{{int:contribslink}}]]).",
        "editcomment": "Опис измене: <em>$1</em>.",
-       "revertpage": "Враћене измене [[Special:Contribs/$2|$2]] ([[User talk:$2|разговор]]) на последњу измену корисника [[User:$1|$1]]",
+       "revertpage": "Враћене измене {{GENDER:$2|корисника|кориснице}} [[Special:Contribs/$2|$2]] ([[User talk:$2|разговор]]) на последњу измену {{GENDER:$1|корисника|кориснице}} [[User:$1|$1]]",
        "revertpage-nouser": "Измене скривеног корисника су враћене на последњу измену {{GENDER:$1|корисника|кориснице}} [[User:$1|$1]]",
        "rollback-success": "Измене {{GENDER:$1|корисника|кориснице}} {{GENDER:$3|$1}} су враћене на последњу измену {{GENDER:$2|корисника|кориснице}} {{GENDER:$4|$2}}.",
        "rollback-success-notify": "Враћене измене корисника $1;\nвраћено на последњу измену корисника $2. [$3 Прикажи измене]",
        "logentry-contentmodel-change-revert": "врати",
        "protectlogpage": "Дневник заштите",
        "protectlogtext": "Испод је списак заштићених страница.\nПогледајте [[Special:ProtectedPages|списак заштићених страница]] за више детаља.",
-       "protectedarticle": "је заштитио „[[$1]]“",
-       "modifiedarticleprotection": "промењен степен заштите за „[[$1]]“",
+       "protectedarticle": "је {{GENDER:|заштитио|заштитила}} страницу „[[$1]]“",
+       "modifiedarticleprotection": "је {{GENDER:|променио|променила}} степен заштите странице „[[$1]]“",
        "unprotectedarticle": "је скинуо заштиту са странице „[[$1]]“",
        "movedarticleprotection": "је преместио подешавања заштите са „[[$2]]“ на „[[$1]]“",
        "protectedarticle-comment": "{{GENDER:$2|Заштићена}} страница [[$1]]",
        "undelete-show-file-submit": "Да",
        "namespace": "Именски простор:",
        "invert": "Обрни избор",
-       "tooltip-invert": "Ð\9eзнаÑ\87иÑ\82е Ð¾Ð²Ñ\83 ÐºÑ\83Ñ\9bиÑ\86Ñ\83 Ð´Ð° Ð±Ð¸Ñ\81Ñ\82е Ñ\81акÑ\80или Ð¸Ð·Ð¼ÐµÐ½Ðµ Ð½Ð° Ñ\81Ñ\82Ñ\80аниÑ\86ама Ñ\83 Ð¾Ð´абраном именском простору (и повезаним именским просторима, ако је означено)",
-       "tooltip-whatlinkshere-invert": "Означите ову кутију за сакривање веза са страница у изабраном именском простору.",
+       "tooltip-invert": "Ð\9eзнаÑ\87иÑ\82е Ð¾Ð²Ñ\83 ÐºÑ\83Ñ\82иÑ\98Ñ\83Ñ\86Ñ\83 Ð´Ð° Ð±Ð¸Ñ\81Ñ\82е Ñ\81акÑ\80или Ð¸Ð·Ð¼ÐµÐ½Ðµ Ñ\81Ñ\82Ñ\80аниÑ\86а Ñ\83 Ð¸Ð·абраном именском простору (и повезаним именским просторима, ако је означено)",
+       "tooltip-whatlinkshere-invert": "Означите ову кутијицу за сакривање веза са страница у изабраном именском простору.",
        "namespace_association": "Повезани именски простор",
-       "tooltip-namespace_association": "Ð\9eзнаÑ\87иÑ\82е Ð¾Ð²Ñ\83 ÐºÑ\83Ñ\9bиÑ\86Ñ\83 Ð´Ð° Ð±Ð¸Ñ\81Ñ\82е Ñ\83кÑ\99Ñ\83Ñ\87или Ð¸ Ñ\80азговоÑ\80 Ð¸Ð»Ð¸ Ð¸Ð¼ÐµÐ½Ñ\81ки Ð¿Ñ\80оÑ\81Ñ\82оÑ\80 Ñ\82еме ÐºÐ¾Ñ\98а Ñ\98е Ð¿Ð¾Ð²ÐµÐ·Ð°Ð½Ð° Ñ\81 Ð¾Ð´абраним именским простором",
+       "tooltip-namespace_association": "Ð\9eзнаÑ\87иÑ\82е Ð¾Ð²Ñ\83 ÐºÑ\83Ñ\82иÑ\98иÑ\86Ñ\83 Ð´Ð° Ð±Ð¸Ñ\81Ñ\82е Ñ\83кÑ\99Ñ\83Ñ\87или Ð¸ Ñ\80азговоÑ\80 Ð¸Ð»Ð¸ Ð¸Ð¼ÐµÐ½Ñ\81ки Ð¿Ñ\80оÑ\81Ñ\82оÑ\80 Ñ\82еме ÐºÐ¾Ñ\98а Ñ\98е Ð¿Ð¾Ð²ÐµÐ·Ð°Ð½Ð° Ñ\81а Ð¸Ð·абраним именским простором",
        "blanknamespace": "(главни)",
        "contributions": "{{GENDER:$1|Кориснички}} доприноси",
        "contributions-title": "Доприноси {{GENDER:$1|корисника|кориснице}} $1",
        "contribsub2": "За {{GENDER:$3|$1}} ($2)",
        "contributions-userdoesnotexist": "Кориснички налог „$1“ није отворен.",
        "nocontribs": "Нема измена које одговарају наведеним критеријумима.",
-       "uctop": "(последња)",
+       "uctop": "(тренутна)",
        "month": "од месеца (и раније):",
        "year": "од године (и раније):",
        "sp-contributions-newbies": "Прикажи само доприносе нових корисника",
        "whatlinkshere": "Шта води овде",
        "whatlinkshere-title": "Странице које су повезане са „$1”",
        "whatlinkshere-page": "Страница:",
-       "linkshere": "СледеÑ\9bе Ñ\81Ñ\82Ñ\80аниÑ\86е Ð¸Ð¼Ð°Ñ\98Ñ\83 Ð²ÐµÐ·Ñ\83 Ð´Ð¾ <strong>$1</strong>:",
+       "linkshere": "СледеÑ\9bе Ñ\81Ñ\82Ñ\80аниÑ\86е Ð²Ð¾Ð´Ðµ Ð½Ð° <strong>$2</strong>:",
        "nolinkshere": "Ниједна страница није повезана са: <strong>$2</strong>.",
        "nolinkshere-ns": "Ниједна страница не води до '''$2''' у изабраном именском простору.",
        "isredirect": "преусмерење",
        "blocklogpage": "Дневник блокирања",
        "blocklog-showlog": "{{GENDER:$1|Овај корисник је раније блокиран|Ова корисница је раније блокирана}}.\nИсторија блокирања се налази испод:",
        "blocklog-showsuppresslog": "{{GENDER:$1|Овај корисник је раније блокиран и сакривен|Ова корисница је раније блокирана и сакривена}}.\nИсторија сакривања се налази испод:",
-       "blocklogentry": "је блокирао [[$1]] с роком истицања од $2 $3",
-       "reblock-logentry": "{{GENDER:|је променио|је променила|је променио}} подешавања за блокирање {{GENDER:$1|корисника|кориснице|корисника}} [[$1]] с роком истека од $2 ($3)",
+       "blocklogentry": "је блокирао [[$1]] са временом истицања од $2 $3",
+       "reblock-logentry": "{{GENDER:|је променио|је променила}} подешавања за блокирање {{GENDER:$1|корисника|кориснице}} [[$1]] са временом истека од $2 ($3)",
        "blocklogtext": "Ово је дневник блокирања и деблокирања корисника.\nАутоматски блокиране ИП адресе нису наведене.\nТекуће забране и блокирања можете наћи [[Special:BlockList|овде]].",
        "unblocklogentry": "је деблокирао $1",
        "block-log-flags-anononly": "само анонимни корисници",
        "allmessages-language": "Језик:",
        "allmessages-filter-submit": "Иди",
        "allmessages-filter-translate": "Преведи",
-       "thumbnail-more": "Повећај",
+       "thumbnail-more": "Повећајте",
        "filemissing": "Недостаје датотека",
        "thumbnail_error": "Грешка при стварању минијатуре: $1",
        "thumbnail_error_remote": "Порука о грешци из $1:\n$2",
        "tooltip-pt-watchlist": "Списак страница које надгледате",
        "tooltip-pt-mycontris": "Списак {{GENDER:|Ваших}} доприноса",
        "tooltip-pt-anoncontribs": "Списак измена направљених са ове IP адресе",
-       "tooltip-pt-login": "Ð\9fÑ\80епоÑ\80Ñ\83Ñ\87Ñ\83Ñ\98емо Вам да се пријавите, иако то није обавезно",
+       "tooltip-pt-login": "Ð\9fÑ\80едлажемо Вам да се пријавите, иако то није обавезно",
        "tooltip-pt-login-private": "Морате да се пријавите да бисте користили овај Вики",
        "tooltip-pt-logout": "Одјавите се",
-       "tooltip-pt-createaccount": "Ð\9fÑ\80епоÑ\80Ñ\83Ñ\87иÑ\98емо Вам да отворите налог и пријавите се, иако то није обавезно",
+       "tooltip-pt-createaccount": "Ð\9fÑ\80едлажемо Вам да отворите налог и пријавите се, иако то није обавезно",
        "tooltip-ca-talk": "Разговор о страници са садржајем",
        "tooltip-ca-edit": "Уредите ову страницу",
        "tooltip-ca-addsection": "Започните нови одељак",
        "tooltip-ca-delete": "Обришите ову страницу",
        "tooltip-ca-undelete": "Врати измене направљене на овој страници пре него што буде обрисана",
        "tooltip-ca-move": "Премести ову страницу",
-       "tooltip-ca-watch": "Додајте ову страницу на списак надгледања",
-       "tooltip-ca-unwatch": "Уклони ову страницу са списка надгледања",
-       "tooltip-search": "Ð\9fÑ\80еÑ\82Ñ\80ага",
-       "tooltip-search-go": "Идите на страницу с овим именом, ако постоји",
-       "tooltip-search-fulltext": "Претражите странице с овим текстом",
+       "tooltip-ca-watch": "Ð\94одаÑ\98Ñ\82е Ð¾Ð²Ñ\83 Ñ\81Ñ\82Ñ\80аниÑ\86Ñ\83 Ð½Ð° Ñ\81воÑ\98 Ñ\81пиÑ\81ак Ð½Ð°Ð´Ð³Ð»ÐµÐ´Ð°Ñ\9aа",
+       "tooltip-ca-unwatch": "Уклоните ову страницу са списка надгледања",
+       "tooltip-search": "Ð\9fÑ\80еÑ\82Ñ\80ажиÑ\82е Ð¿Ñ\80оÑ\98екаÑ\82 {{SITENAME}}",
+       "tooltip-search-go": "Идите на страницу са тачно овим именом ако постоји",
+       "tooltip-search-fulltext": "Претражите странице са овим текстом",
        "tooltip-p-logo": "Посетите главну страну",
        "tooltip-n-mainpage": "Посетите главну страну",
        "tooltip-n-mainpage-description": "Посетите главну страну",
        "tooltip-n-portal": "О пројекту, шта можете да радите и где да пронађете ствари",
-       "tooltip-n-currentevents": "СазнаÑ\98Ñ\82е Ð²Ð¸Ñ\88е Ð¾ Ñ\82Ñ\80енÑ\83Ñ\82ним Ð´Ð¾Ð³Ð°Ñ\92аÑ\98има",
+       "tooltip-n-currentevents": "Ð\9fÑ\80онаÑ\92иÑ\82е Ð´Ð¾Ð´Ð°Ñ\82не Ð¸Ð½Ñ\84оÑ\80маÑ\86иÑ\98е Ð¾ Ð°ÐºÑ\82Ñ\83елноÑ\81Ñ\82има",
        "tooltip-n-recentchanges": "Списак скорашњих измена на викију",
        "tooltip-n-randompage": "Учитајте случајну страницу",
-       "tooltip-n-help": "Место где можете да се информишете",
-       "tooltip-t-whatlinkshere": "Списак свих страница које воде овде",
-       "tooltip-t-recentchangeslinked": "Скорашње измене на страницама које су повезане с овом страницом",
+       "tooltip-n-help": "Место где можете да научите нешто",
+       "tooltip-t-whatlinkshere": "Списак свих вики страница које воде овде",
+       "tooltip-t-recentchangeslinked": "Скорашње измене страница које су повезане са овом страницом",
        "tooltip-feed-rss": "RSS довод ове странице",
        "tooltip-feed-atom": "Атом довод ове странице",
        "tooltip-t-contributions": "Списак доприноса {{GENDER:$1|овог корисника|ове кориснице|овог корисника}}",
        "tooltip-t-permalink": "Трајна веза ка овој измени странице",
        "tooltip-ca-nstab-main": "Погледајте страницу са садржајем",
        "tooltip-ca-nstab-user": "Погледајте корисничку страницу",
-       "tooltip-ca-nstab-media": "Погледајте мултимедијалну датотеку",
+       "tooltip-ca-nstab-media": "Погледајте медијску страницу",
        "tooltip-ca-nstab-special": "Ово је посебна страница. Не можете је мењати.",
        "tooltip-ca-nstab-project": "Погледајте страницу пројекта",
-       "tooltip-ca-nstab-image": "Прикажи страницу датотеке",
+       "tooltip-ca-nstab-image": "Погледајте страницу датотеке",
        "tooltip-ca-nstab-mediawiki": "Погледајте системску поруку",
        "tooltip-ca-nstab-template": "Погледајте шаблон",
        "tooltip-ca-nstab-help": "Погледајте страницу за помоћ",
-       "tooltip-ca-nstab-category": "Ð\9fогледаÑ\98Ñ\82е Ñ\81Ñ\82Ñ\80аниÑ\86Ñ\83 ÐºÐ°Ñ\82егоÑ\80иÑ\98а",
+       "tooltip-ca-nstab-category": "Ð\9fогледаÑ\98Ñ\82е Ñ\81Ñ\82Ñ\80аниÑ\86Ñ\83 ÐºÐ°Ñ\82егоÑ\80иÑ\98е",
        "tooltip-minoredit": "Означите као мању измену",
        "tooltip-save": "Сачувајте своје измене",
        "tooltip-publish": "Објавите своје измене",
        "tooltip-preview": "Прегледајте своје измене. Користите ово дугме пре чувања.",
-       "tooltip-diff": "Погледајте које измене сте направили на тексту",
+       "tooltip-diff": "Погледајте које измене сте направили у тексту",
        "tooltip-compareselectedversions": "Погледаjте разлике између две изабране измене ове странице.",
        "tooltip-watch": "Додајте ову страницу на свој списак надгледања",
-       "tooltip-watchlistedit-normal-submit": "Уклони наслове",
+       "tooltip-watchlistedit-normal-submit": "Уклоните наслове",
        "tooltip-watchlistedit-raw-submit": "Ажурирај списак",
        "tooltip-recreate": "Поново направите страницу иако је обрисана",
        "tooltip-upload": "Започните отпремање",
-       "tooltip-rollback": "â\80\9eÐ\92Ñ\80аÑ\82иâ\80\9c Ð²Ñ\80аÑ\9bа Ð¸Ð·Ð¼ÐµÐ½Ðµ Ð¿Ð¾Ñ\81ледÑ\9aег ÐºÐ¾Ñ\80иÑ\81ника једним кликом",
-       "tooltip-undo": "Опција „поништи” враћа ову измену и отвара образац за уређивање у претпрегледном моду. Омогућава додавање разлога у опису измене.",
+       "tooltip-rollback": "â\80\9eÐ\92Ñ\80аÑ\82иâ\80\9c Ð²Ñ\80аÑ\9bа Ð¸Ð·Ð¼ÐµÐ½Ðµ Ð¿Ð¾Ñ\81ледÑ\9aег Ð´Ð¾Ð¿Ñ\80иноÑ\81иоÑ\86а Ð¾Ð²Ðµ Ñ\81Ñ\82Ñ\80аниÑ\86е једним кликом",
+       "tooltip-undo": "„Поништи” враћа ову измену и отвара образац за уређивање у претпрегледном моду. Дозвољава додавање разлога у опису измене.",
        "tooltip-preferences-save": "Сачувај подешавања",
        "tooltip-summary": "Унесите кратак опис",
        "interlanguage-link-title": "$1 — $2",
        "spam_blanking": "Све измене садрже везе до $1. Чистим",
        "spam_deleting": "Све измене садрже везе до $1. Бришем",
        "simpleantispam-label": "Анти-спам провера. \n<strong>Не</strong> попуњавај ово унутра!",
-       "pageinfo-title": "Ð\9fодаÑ\86и Ð¾ „$1“",
+       "pageinfo-title": "Ð\98нÑ\84оÑ\80маÑ\86иÑ\98е Ð·Ð° „$1“",
        "pageinfo-not-current": "Нажалост, немогуће је прибавити ове податке за старије измене.",
-       "pageinfo-header-basic": "Ð\9eÑ\81новни Ð¿Ð¾Ð´Ð°Ñ\86и",
+       "pageinfo-header-basic": "Ð\9eÑ\81новне Ð¸Ð½Ñ\84оÑ\80маÑ\86иÑ\98е",
        "pageinfo-header-edits": "Историја измена",
        "pageinfo-header-restrictions": "Заштита странице",
        "pageinfo-header-properties": "Својства странице",
        "pageinfo-robot-noindex": "Није дозвољено",
        "pageinfo-watchers": "Број надгледача странице",
        "pageinfo-visiting-watchers": "Број надгледача странице који су посетили скорашње измене",
-       "pageinfo-few-watchers": "Ð\9cаÑ\9aе Ð¾Ð´ $1 {{PLURAL:$1|пÑ\80аÑ\82иоÑ\86а|пÑ\80аÑ\82иоÑ\86а|пÑ\80аÑ\82илаÑ\86а}}",
+       "pageinfo-few-watchers": "Ð\9cаÑ\9aе Ð¾Ð´ $1 {{PLURAL:$1|надгледаÑ\87а}}",
        "pageinfo-redirects-name": "Број преусмерења на ову страницу",
        "pageinfo-redirects-value": "$1",
-       "pageinfo-subpages-name": "Ð\9fодÑ\81Ñ\82Ñ\80аниÑ\86е ове странице",
+       "pageinfo-subpages-name": "Ð\91Ñ\80оÑ\98 Ð¿Ð¾Ð´Ñ\81Ñ\82Ñ\80аниÑ\86а ове странице",
        "pageinfo-subpages-value": "$1 ($2 {{PLURAL:$2|преусмерење|преусмерења|преусмерења}}; $3 {{PLURAL:$3|непреусмерење|непреусмерења|непреусмерења}})",
        "pageinfo-firstuser": "Аутор странице",
        "pageinfo-firsttime": "Датум стварања странице",
        "pageinfo-hidden-categories": "{{PLURAL:$1|Сакривена категорија|Сакривене категорије}} ($1)",
        "pageinfo-templates": "{{PLURAL:$1|Укључени шаблон|Укључени шаблони}} ($1)",
        "pageinfo-transclusions": "{{PLURAL:$1|Страница|Странице}} укључене у ($1)",
-       "pageinfo-toolboxlink": "Ð\9fодаÑ\86и о страници",
+       "pageinfo-toolboxlink": "Ð\98нÑ\84оÑ\80маÑ\86иÑ\98е о страници",
        "pageinfo-redirectsto": "Преусмерава на",
        "pageinfo-redirectsto-info": "подаци",
        "pageinfo-contentpage": "Рачуна се као страница са садржајем",
        "svg-long-desc": "SVG датотека, номинално $1 × $2 пиксела, величина: $3",
        "svg-long-desc-animated": "Анимирана SVG датотека, номинално: $1 × $2 пиксела, величина: $3",
        "svg-long-error": "Неисправна SVG датотека: $1",
-       "show-big-image": "Ð\9fÑ\83на Ð²ÐµÐ»Ð¸Ñ\87ина",
+       "show-big-image": "Ð\98звоÑ\80на Ð´Ð°Ñ\82оÑ\82ека",
        "show-big-image-preview": "Величина овог приказа: $1.",
        "show-big-image-preview-differ": "Величина $3 прегледа за ову $2 датотеку је $1.",
        "show-big-image-other": "$2 {{PLURAL:$2|друга резолуција|друге резолуције|других резолуција}}: $1.",
        "exif-iimsupplementalcategory": "Допунске категорије",
        "exif-datetimeexpires": "Не користи након",
        "exif-datetimereleased": "Објављено",
-       "exif-originaltransmissionref": "Изворни пренос кода локације",
+       "exif-originaltransmissionref": "Изворни пренос кôда локације",
        "exif-identifier": "Назнака",
        "exif-lens": "Коришћени објектив",
        "exif-serialnumber": "Серијски број камере",
        "monthsall": "све",
        "confirmemail": "Потврда имејл адресе",
        "confirmemail_noemail": "Нисте унели исправну имејл адресу у [[Special:Preferences|подешавањима]].",
-       "confirmemail_text": "{{SITENAME}} захтева да потврдите имејл адресу пре него што почнете да користите могућности имејла.\nКликните на дугме испод за слање поруке на вашу адресу.\nУ поруци ће се налазити веза с потврдним кодом;\nунесите је у прегледач да бисте потврдили да је ваша имејл адреса исправна.",
+       "confirmemail_text": "{{SITENAME}} захтева да потврдите имејл адресу пре него што почнете да користите могућности имејла.\nКликните на дугме испод за слање поруке на вашу адресу.\nУ поруци ће се налазити веза с потврдним кôдом;\nунесите је у прегледач да бисте потврдили да је ваша имејл адреса исправна.",
        "confirmemail_pending": "Потврдни кôд вам је већ послат. Ако сте управо отворили налог, онда вероватно треба да сачекате неколико минута да пристигне, пре него што поново затражите нови кôд.",
        "confirmemail_send": "Пошаљи потврдни кôд",
        "confirmemail_sent": "Потврдна порука је послата.",
        "htmlform-title-not-exists": "$1 не постоји.",
        "htmlform-user-not-exists": "<strong>$1</strong> не постоји.",
        "htmlform-user-not-valid": "<strong>$1</strong> није исправно корисничко име.",
-       "logentry-delete-delete": "$1 је {{GENDER:$2|обрисао|обрисала|обрисао}} страницу $3",
+       "logentry-delete-delete": "$1 је {{GENDER:$2|обрисао|обрисала}} страницу $3",
        "logentry-delete-delete_redir": "$1 је {{GENDER:$2|обрисао|обрисала}} преусмерење $3 преписивањем",
        "logentry-delete-restore": "$1 је {{GENDER:$2|вратио|вратила}} страницу $3 ($4)",
        "logentry-delete-restore-nocount": "$1 је {{GENDER:$2|вратио|вратила}} страницу $3",
        "logentry-newusers-newusers": "$1 је {{GENDER:$2|отворио|отворила}} кориснички налог",
        "logentry-newusers-create": "$1 је {{GENDER:$2|отворио|отворила}} кориснички налог",
        "logentry-newusers-create2": "$1 је {{GENDER:$2|отворио|отворила}} кориснички налог $3",
-       "logentry-newusers-byemail": "$1 Ñ\98е {{GENDER:$2|оÑ\82воÑ\80ио|оÑ\82воÑ\80ила}} кориснички налог $3 и лозинка је послата на имејл",
+       "logentry-newusers-byemail": "$1 Ñ\98е {{GENDER:$2|напÑ\80авио|напÑ\80авила}} кориснички налог $3 и лозинка је послата на имејл",
        "logentry-newusers-autocreate": "Кориснички налог $1 је аутоматски {{GENDER:$2|отворен}}",
        "logentry-protect-move_prot": "$1 је {{GENDER:$2|преместио|преместила}} подешавања заштите са $4 на $3",
        "logentry-protect-unprotect": "$1 je {{GENDER:$2|скинуо|скинула}} заштиту са странице $3",
        "feedback-thanks": "Хвала! Ваша повратна информација је постављена на страницу „[$2 $1]“.",
        "feedback-thanks-title": "Хвала вам!",
        "feedback-useragent": "Кориснички агент:",
-       "searchsuggest-search": "Ð\9fÑ\80еÑ\82Ñ\80ага",
+       "searchsuggest-search": "Ð\9fÑ\80еÑ\82Ñ\80ажиÑ\82е Ð¿Ñ\80оÑ\98екаÑ\82 {{SITENAME}}",
        "searchsuggest-containing": "садржи...",
        "api-error-badtoken": "Унутрашња грешка: неисправан жетон.",
        "api-error-emptypage": "Стварање нових празних страница није дозвољено.",
        "mw-widgets-dateinput-no-date": "Датум није изабран",
        "mw-widgets-dateinput-placeholder-day": "ГГГГ-ММ-ДД",
        "mw-widgets-dateinput-placeholder-month": "ГГГГ-ММ",
-       "mw-widgets-mediasearch-input-placeholder": "Ð\9fÑ\80еÑ\82Ñ\80ага Ð´Ð°Ñ\82оÑ\82ека",
+       "mw-widgets-mediasearch-input-placeholder": "Ð\9fÑ\80еÑ\82Ñ\80ажиÑ\82е Ð´Ð°Ñ\82оÑ\82еке",
        "mw-widgets-mediasearch-noresults": "Нема резултата.",
        "mw-widgets-titleinput-description-new-page": "страница још увек не постоји",
        "mw-widgets-titleinput-description-redirect": "преусмерава на $1",
        "mw-widgets-categoryselector-add-category-placeholder": "Додај категорију...",
-       "mw-widgets-usersmultiselect-placeholder": "Додај још...",
+       "mw-widgets-usersmultiselect-placeholder": "Додајте још...",
        "date-range-from": "Од датума:",
        "date-range-to": "До датума:",
        "sessionprovider-generic": "$1 сесије",
index b1c1bc3..ecc23b6 100644 (file)
        "dellogpage": "Dnevnik brisanja",
        "dellogpagetext": "Ispod je spisak poslednjih brisanja.",
        "deletionlog": "dnevnik brisanja",
+       "logentry-create-create": "$1 {{GENDER:$2|kreirao je|kreirala je}} stranicu $3",
        "reverted": "Vraćeno na raniju izmenu",
        "deletecomment": "Razlog:",
        "deleteotherreason": "Drugi/dodatni razlog:",
index 9b2077c..416a168 100644 (file)
        "customcssprotected": "ఈ CSS పేజీని మార్చేందుకు మీకు అనుమతి లేదు. ఎందుకంటే వేరే వాడుకరి యొక్క వ్యక్తిగత సెట్టింగులు అందులో ఉన్నాయి.",
        "customjsprotected": "ఈ JavaScript పేజీని మార్చేందుకు మీకు అనుమతి లేదు. ఎందుకంటే వేరే వాడుకరి యొక్క వ్యక్తిగత సెట్టింగులు అందులో ఉన్నాయి.",
        "mycustomcssprotected": "ఈ CSS పేజీని సవరించేందుకు మీకు అనుమతి లేదు.",
+       "mycustomjsonprotected": "ఈ JSON పేజీని సవరించేందుకు మీకు అనుమతి లేదు.",
        "mycustomjsprotected": "ఈ జావాస్క్రిప్టు పేజీని సవరించేందుకు మీకు అనుమతి లేదు.",
        "myprivateinfoprotected": "మీ అంతరంగిక సమాచారాన్ని సవరించేందుకు మీకు అనుమతి లేదు.",
        "mypreferencesprotected": "మీ అభీష్టాలను సవరించేందుకు మీకు అనుమతి లేదు.",
        "nosuchusershort": "\"$1\" పేరుతో వాడుకరి ఎవరూ లేరు. పేరు సరి చూసుకోండి.",
        "nouserspecified": "వాడుకరి పేరును తప్పనిసరిగా ఇవ్వాలి.",
        "login-userblocked": "ఈ వాడుకరిని నిరోధించారు. ప్రవేశానికి అనుమతి లేదు.",
-       "wrongpassword": "à°\88 à°¸à°\82à°\95à±\87తపదà°\82 à°¸à°°à±\88నది à°\95ాదà±\81. à°¦à°¯à°\9aà±\87సి à°®à°³à±\8dà°²à±\80 ప్రయత్నించండి.",
+       "wrongpassword": "వాడà±\81à°\95à°°à°¿ à°ªà±\87à°°à±\81 à°²à±\87దా à°¸à°\82à°\95à±\87తపదà°\82 à°¤à°ªà±\8dà°ªà±\81à°\97à°¾ à°\87à°\9aà±\8dà°\9aారà±\81.\nదయà°\9aà±\87సి à°®à°°à±\8bసారి ప్రయత్నించండి.",
        "wrongpasswordempty": "ఖాళీ సంకేతపదం ఇచ్చారు. మళ్ళీ ప్రయత్నించండి.",
        "passwordtooshort": "సంకేతపదం కనీసం {{PLURAL:$1|1 అక్షరం|$1 అక్షరాల}} నిడివి ఉండాలి.",
        "passwordtoolong": "సంకేతపదం పొడవు {{PLURAL:$1|1 అక్షరం|$1 అక్షరాల}} కన్నా ఎక్కువ ఉండకూడదు.",
        "savechanges": "మార్పులను భద్రపరచు",
        "publishpage": "పేజీని ప్రచురించు",
        "publishchanges": "మార్పులను ప్రచురించు",
+       "savearticle-start": "పేజీని భద్రపరచు",
+       "savechanges-start": "మార్పులను భద్రపరచు…",
+       "publishpage-start": "పేజీని ప్రచురించు…",
+       "publishchanges-start": "మార్పులను ప్రచురించు…",
        "preview": "మునుజూపు",
        "showpreview": "మునుజూపు చూపు",
        "showdiff": "తేడాలను చూపించు",
        "anonpreviewwarning": "<em>మీరు లాగినవలేదు. భద్రపరిస్తే ఈ పేజీ యొక్క దిద్దుబాటు చరిత్రలో మీ ఐపీ చిరునామా నమోదవుతుంది.</em>",
        "missingsummary": "<strong>గుర్తు చేస్తున్నాం:</strong> మీరు దిద్దుబాటు సారాంశమేమీ ఇవ్వలేదు. పేజీని మళ్ళీ భద్రపరచమని చెబితే సారాంశమేమీ లేకుండానే దిద్దుబాటును భద్రపరుస్తాం.",
        "selfredirect": "<strong>హెచ్చరిక:</strong> మీరు ఈ పేజీని దానికే దారిమార్పు చేస్తున్నారు. బహుశా మీరు తప్పు దారిమార్పును సూచించి ఉండవచ్చు, లేదా మీరు తప్పుడు పేజీని మారుస్తున్నారు. \nమీరు \"$1\" ను నొక్కితే దారిమార్పు పేజీ ఖచ్చితంగా సృష్టించబడుతుంది.",
-       "missingcommenttext": "à°\95à°¿à°\82à°¦ à°\93 à°µà±\8dయాà°\96à±\8dà°¯ à°°à°¾à°¯ండి.",
+       "missingcommenttext": "à°\92à°\95 à°µà±\8dయాà°\96à±\8dయనà±\81 à°\87à°µà±\8dà°µండి.",
        "missingcommentheader": "<strong>గుర్తు చేస్తున్నాం:</strong> ఈ వ్యాఖ్యకు మీరు విషయం పెట్టలేదు.\n\"$1\"ని మళ్ళీ నొక్కితే, అది లేకుండానే మీ మార్పును భద్రపరుస్తాం.",
        "summary-preview": "దిద్దుబాటు సారాంశం మునుజూపు:",
        "subject-preview": "విషయపు మునుజూపు:",
        "postedit-confirmation-created": "పేజీ సృష్టించబడినది.",
        "postedit-confirmation-restored": "పేజీని పునస్థాపించాం.",
        "postedit-confirmation-saved": "మీ మార్పు భద్రమయ్యింది.",
+       "postedit-confirmation-published": "మీ మార్పు ప్రచురితమయ్యింది.",
        "edit-already-exists": "కొత్త పేజీని సృష్టించలేకపోయాం.\nఅది ఇప్పటికే ఉంది.",
        "defaultmessagetext": "అప్రమేయ సందేశపు పాఠ్యం",
        "content-failed-to-parse": "$1 మోడల్ కొరకు $2 పాఠ్యాన్ని పార్స్ చెయ్యలేకపోయాం: $3",
        "prefs-dateformat": "తేదీ ఆకృతి",
        "prefs-timeoffset": "సమయపు తేడా",
        "prefs-advancedediting": "సాధారణ ఎంపికలు",
+       "prefs-developertools": "డెవలపర్ల పనిముట్లు",
        "prefs-editor": "రచయిత",
        "prefs-preview": "మునుజూపు",
        "prefs-advancedrc": "ఉన్నత ఎంపికలు",
        "rcfilters-other-review-tools": "ఇతర సమీక్షా ఉపకరణాలు",
        "rcfilters-group-results-by-page": "ఫలితాలను పేజీవారీగా గుదిగుచ్చు",
        "rcfilters-activefilters": "సచేతనమైన వడపోతలు",
+       "rcfilters-activefilters-hide": "దాచు",
+       "rcfilters-activefilters-show": "చూపించు",
        "rcfilters-advancedfilters": "ఉన్నత వడపోతలు",
        "rcfilters-limit-title": "చూపించాల్సిన ఫలితాలు",
        "rcfilters-days-title": "ఇటీవలి రోజులు",
        "rcfilters-empty-filter": "చేతనంగా ఉన్న వడపోతకాలేమీ లేవు. మార్పుచేర్పు లన్నిటినీ చూపించాం.",
        "rcfilters-filterlist-title": "వడపోతలు",
        "rcfilters-filterlist-whatsthis": "ఇవి ఎలా పనిచేస్తాయి?",
-       "rcfilters-filterlist-feedbacklink": "ఈ (కొత్త) వడపోత పరికరాలు ఎలా ఉన్నాయో మాకు చెప్పండి",
+       "rcfilters-filterlist-feedbacklink": "ఈ వడపోత పరికరాలు ఎలా ఉన్నాయో మాకు చెప్పండి",
        "rcfilters-highlightbutton-title": "ఫలితాలను హైలైటు చెయ్యి",
        "rcfilters-highlightmenu-title": "ఒక రంగును ఎంచుకోండి",
        "rcfilters-highlightmenu-help": "ఈ లక్షణాన్ని హైలైటు చేసేందుకు ఓ రంగును ఎంచుకోండి",
        "upload-too-many-redirects": "ఆ URLలో చాలా దారిమార్పులు ఉన్నాయి",
        "upload-http-error": "ఒక HTTP పొరపాటు జరిగింది: $1",
        "upload-copy-upload-invalid-domain": "ఈ డొమెయిన్ నుంచి కాపీ ఎక్కింపులు కుదరదు.",
+       "upload-dialog-title": "దస్త్రపు ఎక్కింపు",
        "upload-dialog-button-cancel": "రద్దుచేయి",
        "upload-dialog-button-back": "వెనుకకు",
        "upload-dialog-button-done": "పూర్తయ్యింది",
        "uploadstash-badtoken": "ఆ చర్య విఫలమైంది. బహుశా మీ ఎడిటింగు అనుమతులకు కాలం చెల్లిందేమో. మళ్ళీ ప్రయత్నించండి.",
        "uploadstash-errclear": "ఫైళ్ళ తీసివేత విఫలమైంది.",
        "uploadstash-refresh": "దస్త్రాల జాబిజాను తాజాకరించు",
+       "uploadstash-thumbnail": "నఖచిత్రం చూడండి",
        "invalid-chunk-offset": "చెల్లని చంక్ ఆఫ్‍సెట్",
        "img-auth-accessdenied": "అనుమతిని నిరాకరించారు",
        "img-auth-nopathinfo": "PATH_INFO లేదు.\nమీ సర్వరు ఈ సమాచారాన్ని పంపించేందుకు అనువుగా అమర్చి లేదు.\nఅది CGI ఆధారితమై ఉండొచ్చు. అంచేత img_auth కు అనుకూలంగా లేదు.\nhttps://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Image_Authorization చూడండి.",
        "deadendpages": "అగాధ (డెడ్ఎండ్) పేజీలు",
        "deadendpagestext": "కింది పేజీల నుండి ఈ వికీ లోని ఏ ఇతర పేజీకీ లింకులు లేవు.",
        "protectedpages": "సంరక్షిత పేజీలు",
+       "protectedpages-filters": "వడపోతలు:",
        "protectedpages-indef": "అనంత సంరక్షణ మాత్రమే",
        "protectedpages-summary": "ప్రస్తుతం సంరక్షణలో ఉన్న పేజీల జాబితాను ఈ పేజీ చూపిస్తుంది. అసలు సృష్టించకుండా సంరక్షించబడిన పేజీశీర్షికల కోసం [[{{#special:ProtectedTitles}}|{{int:protectedtitles}}]] చూడండి.",
        "protectedpages-cascade": "కాస్కేడింగు రక్షణలు మాత్రమే",
        "protectedpages-performer": "రక్షించబడే వాడుకరి",
        "protectedpages-params": "సంరక్షణ పరామితులు",
        "protectedpages-reason": "కారణం",
+       "protectedpages-submit": "పేజీలను చూపించు",
        "protectedpages-unknown-timestamp": "తెలియని",
        "protectedpages-unknown-performer": "తెలియని వాడుకరి",
        "protectedtitles": "సంరక్షిత శీర్షికలు",
        "protectedtitles-summary": "యీ పేజీలో ప్రస్తుతం సృష్టించకుండా నిరోధించబడ్డ శీర్ణికలన్నీ పొందుపరచబడ్డాయి. సంరక్షించబడ్ద పేజీలకోసం యిక్కడ చూడండి: [[{{#special:ProtectedPages}}|{{int:protectedpages}}]].",
        "protectedtitlesempty": "ఈ పరామితులతో ప్రస్తుతం శీర్షికలేమీ సరక్షించబడి లేవు.",
+       "protectedtitles-submit": "శీర్షికలను చూపించు",
        "listusers": "వాడుకరుల జాబితా",
        "listusers-editsonly": "మార్పులు చేసిన వాడుకరులను మాత్రమే చూపించు",
        "listusers-creationsort": "చేరిన తేదీ క్రమంలో చూపించు",
        "apisandbox-dynamic-parameters-add-label": "పరామితిని చేర్చు:",
        "apisandbox-dynamic-parameters-add-placeholder": "పరామితి పేరు",
        "apisandbox-dynamic-error-exists": "\"$1\" అనే పరామితి ఇప్పటికే ఉంది.",
+       "apisandbox-add-multi": "చేర్చు",
        "apisandbox-results": "ఫలితాలు",
        "apisandbox-request-url-label": "అభ్యర్థన URL:",
        "apisandbox-request-time": "అభ్యర్ధన సమయం: {{PLURAL:$1|$1 మి.సె.}}",
        "dellogpage": "తొలగింపుల చిట్టా",
        "dellogpagetext": "ఇది ఇటీవలి తుడిచివేతల జాబితా.",
        "deletionlog": "తొలగింపుల చిట్టా",
+       "logentry-create-create": "$3 పేజీని $1 {{GENDER:$2|సృష్టించారు}}",
        "reverted": "పాత కూర్పుకు తీసుకువెళ్ళాం.",
        "deletecomment": "కారణం:",
        "deleteotherreason": "ఇతర/అదనపు కారణం:",
        "newimages-summary": "ఇటీవలే ఎగుమతైన ఫైళ్ళను ఈ ప్రత్యేక పేజీ చూపిస్తుంది.",
        "newimages-legend": "పడపోత",
        "newimages-label": "ఫైలుపేరు (లేదా దానిలోని భాగం):",
+       "newimages-user": "ఐపీ చిరునామా లేదా వాడుకరి పేరు",
+       "newimages-newbies": "కొత్త ఖాతాల రచనలని మాత్రమే చూపించు",
        "newimages-showbots": "బాట్లు చేసిన అప్లోడ్లు చూపించు",
+       "newimages-mediatype": "మాధ్యమ రకం:",
        "noimages": "చూసేందుకు ఏమీ లేదు.",
        "ilsubmit": "వెతుకు",
        "bydate": "తేదీ వారీగ",
        "tag-filter": "[[Special:Tags|ట్యాగుల]] వడపోత:",
        "tag-filter-submit": "వడపోయి",
        "tag-list-wrapper": "([[Special:Tags|{{PLURAL:$1|ట్యాగు|ట్యాగులు}}]]: $2)",
+       "tag-mw-new-redirect": "కొత్త దారిమార్పు",
        "tag-mw-blank": "తుడిచివేత",
        "tag-mw-blank-description": "పేజీని తుడిచివేసే దిద్దుబాట్లు",
        "tags-title": "టాగులు",
        "compare-title-not-exists": "మీరు పేర్కొన్న శీర్షిక లేనే లేదు.",
        "compare-revision-not-exists": "మీరు పేర్కొన్న కూర్పు లేనే లేదు.",
        "diff-form": "తేడాలు",
+       "permanentlink": "స్థిర లంకె",
        "dberr-problems": "క్షమించండి! ఈ సైటు సాంకేతిక సమస్యలని ఎదుర్కొంటుంది.",
        "dberr-again": "కొన్ని నిమిషాలాగి మళ్ళీ ప్రయత్నించండి.",
        "dberr-info": "(డేటాబేసును చేరలేకున్నాం: $1)",
        "limitreport-templateargumentsize-value": "$1/$2 {{PLURAL:$2|బైటు|బైట్లు}}",
        "limitreport-expansiondepth": "గరిష్ట విస్తరణ లోతు",
        "limitreport-expensivefunctioncount": "ఖరీదైన పార్సర్ ఫంక్షన్ల సంఖ్య",
+       "limitreport-unstrip-size-value": "$1/$2 {{PLURAL:$2|బైటు|బైట్లు}}",
        "expandtemplates": "మూసలను విస్తరించు",
        "expand_templates_intro": "ఈ ప్రత్యేక పేజీ మీరిచ్చిన మూసలను పూర్తిగా విస్తరించి, చూపిస్తుంది. ఇది <code><nowiki>{{</nowiki>#language:...}}</code> వంటి పార్సరు ఫంక్షన్లను, <code><nowiki>{{</nowiki>CURRENTDAY}}</code> వంటి చరరాశులను (వేరియబుల్) కూడా విస్తరిస్తుంది. \nనిజానికి ఇది మీసాల బ్రాకెట్లలో ఉన్న ప్రతీదాన్నీ విస్తరిస్తుంది.",
        "expand_templates_title": "{{FULLPAGENAME}} మొదలగు వాటి కొరకు సందర్భ శీర్షిక:",
        "sessionprovider-generic": "$1 సెషన్లు",
        "sessionprovider-mediawiki-session-cookiesessionprovider": "కూకీ-ఆధారిత సెషన్లు",
        "log-action-filter-block": "నిరోధపు రకం:",
+       "log-action-filter-delete": "తొలగింపు రకం:",
+       "log-action-filter-move": "తరలింపు రకం:",
        "log-action-filter-all": "అన్నీ",
        "log-action-filter-managetags-create": "ట్యాగు సృష్టి",
        "log-action-filter-managetags-delete": "ట్యాగు తొలగింపు",
        "log-action-filter-managetags-activate": "ట్యాగు చేతనం",
        "log-action-filter-managetags-deactivate": "ట్యాగు అచేతనం",
+       "log-action-filter-protect-protect": "సంరక్షణ",
+       "log-action-filter-upload-upload": "కొత్త ఎక్కింపు",
        "authmanager-userdoesnotexist": "వాడుకరి ఖాతా \"$1\" నమోదయి లేదు.",
        "authmanager-userlogin-remembermypassword-help": "సెషను ముగిసిన తరువాత కూడా సంకేతపదాన్ని గుర్తుంచుకోమంటారా",
        "authmanager-username-help": "ధ్రువీకరణ కోసం వాడుకరిపేరు.",
        "restrictionsfield-label": "అనుమతించబడ్డ ఐపీ శ్రేణులు:",
        "restrictionsfield-help": "వరుసకొక్క ఐపీ అడ్రసు లేదా CIDR శ్రేణి. ప్రతీ ఒక్కదాన్నీ చేతనం చేసేందుకు, వాడండి:<pre>0.0.0.0/0\n::/0</pre>",
        "revid": "కూర్పు $1",
-       "pageid": "పేజీ ఐడీ $1"
+       "pageid": "పేజీ ఐడీ $1",
+       "pagedata-bad-title": "చెల్లని శీర్షిక: $1.",
+       "passwordpolicies": "సంకేతపదపు విధానాలు",
+       "passwordpolicies-group": "సమూహం",
+       "passwordpolicies-policies": "విధానాలు"
 }
index 6be888c..4dce507 100644 (file)
@@ -76,7 +76,8 @@
                        "Avatar6",
                        "Fitoschido",
                        "Movses",
-                       "Esk78"
+                       "Esk78",
+                       "Vlad5250"
                ]
        },
        "tog-underline": "Підкреслювання посилань:",
        "resetpass-submit-loggedin": "Змінити пароль",
        "resetpass-submit-cancel": "Скасувати",
        "resetpass-wrong-oldpass": "Неправильний тимчасовий або поточний пароль.\nМожливо, Ви вже змінили пароль або зробили запит на новий тимчасовий пароль.",
-       "resetpass-recycled": "Ð\97мÑ\96нÑ\96Ñ\82Ñ\8c Ñ\81вÑ\96й Ð¿Ð°Ñ\80олÑ\8c Ð½Ð° Ñ\89оÑ\81Ñ\8c Ñ\96нÑ\88е, Ð½Ñ\96ж Ð²аш поточний пароль.",
+       "resetpass-recycled": "Ð\97мÑ\96нÑ\96Ñ\82Ñ\8c Ñ\81вÑ\96й Ð¿Ð°Ñ\80олÑ\8c Ð½Ð° Ñ\89оÑ\81Ñ\8c Ñ\96нÑ\88е, Ð½Ñ\96ж Ð\92аш поточний пароль.",
        "resetpass-temp-emailed": "Ви ввійшли, використовуючи тимчасовий пароль, який отримали електронною поштою. \nДля завершення входу в систему необхідно задати новий пароль:",
        "resetpass-temp-password": "Тимчасовий пароль:",
        "resetpass-abort-generic": "Зміну пароля було перервано розширенням.",
        "resetpass-expired": "Термін дії вашого пароля закінчився. Будь ласка, встановіть новий пароль для входу в систему.",
-       "resetpass-expired-soft": "Термін дії вашого пароля закінчився, і тепер він повинен бути змінений. Будь ласка, виберіть новий пароль або натисніть \"{{int:authprovider-resetpass-skip-label}}\", щоб змінити його пізніше.",
-       "resetpass-validity-soft": "Ваш пароль є некоректним: $1\n\nБудь ласка, виберіть новий пароль або натисніть «{{int:authprovider-resetpass-skip-label}}», щоб скинути його пізніше.",
+       "resetpass-expired-soft": "Термін дії вашого пароля закінчився, і тепер він повинен бути змінений. Будь ласка, виберіть новий пароль або натисніть «{{int:authprovider-resetpass-skip-label}}», щоб змінити його пізніше.",
+       "resetpass-validity-soft": "Ваш пароль є некоректним: $1\n\nБудь ласка, виберіть новий пароль або натисніть «{{int:authprovider-resetpass-skip-label}}», щоб змінити його пізніше.",
        "passwordreset": "Скинути пароль",
        "passwordreset-text-one": "Заповніть цю форму, щоб отримати тимчасовий пароль електронною поштою.",
        "passwordreset-text-many": "{{PLURAL:$1|Заповніть одне з полів для отримання тимчасового пароля електронною поштою.}}",
        "converter-manual-rule-error": "Помилка в ручному правилі перетворення мови",
        "undo-success": "Редагування може бути скасовано.\nБудь ласка, перевірте порівняння нижче, щоб впевнитись, що це те, що ви хочете зробити, а потім збережіть зміни, щоб закінчити скасування редагування.",
        "undo-failure": "Неможливо скасувати редагування через несумісність проміжних змін.",
+       "undo-main-slot-only": "Редагування не може бути скасоване, бо воно включає вміст з-за меж основного слоту.",
        "undo-norev": "Редагування не може бути скасоване, бо його не існує або було вилучено.",
        "undo-nochange": "Схоже, редагування вже було скасовано.",
        "undo-summary": "Скасування редагування № $1 користувача [[Special:Contribs/$2|$2]] ([[User talk:$2|обговорення]])",
        "right-browsearchive": "пошук вилучених сторінок",
        "right-undelete": "відновлення сторінок",
        "right-suppressrevision": "перегляд, приховування та відновлення конкретних змін сторінок від будь-якого користувача",
-       "right-viewsuppressed": "Ð\9fеÑ\80еглÑ\8fд Ð·Ð¼Ñ\96н, Ð¿Ñ\80иÑ\85оваих від усіх користувачів",
+       "right-viewsuppressed": "пеÑ\80еглÑ\8fд Ð·Ð¼Ñ\96н, Ð¿Ñ\80иÑ\85ованих від усіх користувачів",
        "right-suppressionlog": "перегляд приватних журналів",
        "right-block": "заборона редагувань для інших дописувачів",
        "right-blockemail": "блокування користувача від надсилання електронної пошти",
        "right-protect": "зміна рівнів захисту та редагування каскадно захищених сторінок",
        "right-editprotected": "редагування сторінок з рівнем захисту «{{int:protect-level-sysop}}»",
        "right-editsemiprotected": "редагування сторінок з рівнем захисту «{{int:protect-level-autoconfirmed}}»",
-       "right-editcontentmodel": "Редагувати модель вмісту сторінки",
+       "right-editcontentmodel": "редагування моделі вмісту сторінки",
        "right-editinterface": "редагування інтерфейсу користувача",
        "right-editusercss": "редагування CSS-файлів інших користувачів",
        "right-edituserjson": "редагування JSON-файлів інших користувачів",
        "action-viewmywatchlist": "перегляд власного списку спостереження",
        "action-viewmyprivateinfo": "перегляд своєї приватної інформації",
        "action-editmyprivateinfo": "редагування своєї приватної інформації",
-       "action-editcontentmodel": "редагувати модель вмісту сторінки",
+       "action-editcontentmodel": "редагування моделі вмісту сторінки",
        "action-managechangetags": "створення та (де)активування міток",
        "action-applychangetags": "додавання міток разом зі змінами",
        "action-changetags": "додавання або вилучення будь-яких міток для певних версій сторінок або записів журналів",
        "rcfilters-other-review-tools": "Інші інструменти перевірки",
        "rcfilters-group-results-by-page": "Групувати результати за сторінкою",
        "rcfilters-activefilters": "Активні фільтри",
+       "rcfilters-activefilters-hide": "Приховати",
+       "rcfilters-activefilters-show": "Показати",
+       "rcfilters-activefilters-hide-tooltip": "Приховати область Активних фільтрів",
+       "rcfilters-activefilters-show-tooltip": "Показати область Активних фільтрів",
        "rcfilters-advancedfilters": "Розширені фільтри",
        "rcfilters-limit-title": "Результати, які треба показати",
        "rcfilters-limit-and-date-label": "$1 {{PLURAL:$1|зміна|зміни|змін}}, $2",
        "rcfilters-empty-filter": "Без фільтрів. Показано всі зміни.",
        "rcfilters-filterlist-title": "Фільтри",
        "rcfilters-filterlist-whatsthis": "Як це працює?",
-       "rcfilters-filterlist-feedbacklink": "Розкажіть нам, що Ви думаєте про ці (нові) інструменти фільтрування",
+       "rcfilters-filterlist-feedbacklink": "Розкажіть нам, що Ви думаєте про ці інструменти фільтрування",
        "rcfilters-highlightbutton-title": "Виділити результати",
        "rcfilters-highlightmenu-title": "Вибрати колір",
        "rcfilters-highlightmenu-help": "Вибрати колір, щоб виділити цю властивість",
        "rcfilters-watchlist-showupdated": "Зміни до сторінок, які Ви не відвідували з моменту здійснення змін, виділені <strong>жирним</strong>, із цілісними маркерами.",
        "rcfilters-preference-label": "Приховати покращену версію Нових редагувань",
        "rcfilters-preference-help": "Скасовує зміну дизайну 2017 року та всі інструменти, додані тоді й пізніше.",
+       "rcfilters-watchlist-preference-label": "Приховати покращену версію Списку спостереження",
+       "rcfilters-watchlist-preference-help": "Відкидає зміну дизайну інтерфейсу 2017 року та всі інструменти додані тоді й пізніше.",
        "rcfilters-filter-showlinkedfrom-label": "Показати зміни на сторінках, на які є посилання з",
        "rcfilters-filter-showlinkedfrom-option-label": "<strong>Сторінки, на які є посилання з</strong> обраної сторінки",
        "rcfilters-filter-showlinkedto-label": "Показати зміни на сторінках, що посилаються сюди",
        "dellogpage": "Журнал вилучень",
        "dellogpagetext": "Нижче наведений список останніх вилучень.",
        "deletionlog": "журнал вилучень",
+       "log-name-create": "Журнал створення сторінок",
+       "log-description-create": "Нижче наведений список останніх створень сторінок.",
+       "logentry-create-create": "$1 {{GENDER:$2|створив|створила}} сторінку $3",
        "reverted": "Повернуто до більш ранньої версії",
        "deletecomment": "Причина:",
        "deleteotherreason": "Інша/додаткова причина:",
index 45a3874..af79df3 100644 (file)
        "recreate-moveddeleted-warn": "''' انتباہ: آپ ایک گزشتہ حذف شدہ صفحہ دوبارہ تخلیق کررہے ہیں. '''\n\nآپ کو اِس بات پر غور کرنا چاہئے کہ آیا اِس صفحہ کی تدوین جاری رکھنا موزوں ہے یا نہیں.\nصفحہ کا نوشتۂ حذف شدگی و منتقلی یہاں سہولت کی خاطر مہیّا کیا جارہا ہے:",
        "moveddeleted-notice": "اس صفحہ کو حذف کر دیا گیا ہے۔\nحوالہ کے لیے ذیل میں اس صفحہ کا نوشتہ حذف شدگی اور نوشتہ منتقلی درج ہے۔",
        "moveddeleted-notice-recent": "معذرت، اس صفحہ کو حال ہی میں حذف کیا گیا ہے (گزشتہ چوبیس گھنٹوں میں)۔\nحوالہ کے لیے ذیل میں اس صفحہ کا نوشتہ حذف اور نوشتہ منتقلی موجود ہے۔",
-       "log-fulllog": "پورا نوشتہ دیکھئے",
+       "log-fulllog": "پورا نوشتہ دیکھیے",
        "edit-hook-aborted": "کسی رکاوٹ کی وجہ سے ترمیم کاری منسوخ کر دی گئی ہے۔\nاور کوئی وضاحت نہیں دی گئی۔",
        "edit-gone-missing": "صفحہ تجدید نہیں کیا جاسکتا.\nلگتا ہے یہ حذف ہوچکا ہے.",
        "edit-conflict": "تنازعۂ تدوین.",
        "prefs-email": "برقی خط کے اختیارات",
        "prefs-rendering": "ظاہریت",
        "saveprefs": "محفوظ",
-       "restoreprefs": "تمام ابتدائی ترتیبات کو بحال کریں",
+       "restoreprefs": "تمام ابتدائی ترتیبات (تمام خانوں میں) کو بحال کریں",
        "prefs-editing": "ترمیم کاری",
        "searchresultshead": "تلاش",
        "stub-threshold": "نامکمل ربط کے فارمیٹ کی حد ($1):",
        "prefs-dateformat": "تاریخ کی ترتیب",
        "prefs-timeoffset": "وقت کی ترتیب",
        "prefs-advancedediting": "اعلی اختیارات",
+       "prefs-developertools": "آلات ترقی دہندہ",
        "prefs-editor": "خانہ ترمیم",
        "prefs-preview": "نمائش",
        "prefs-advancedrc": "اضافی اختیارات",
        "recentchangeslinked-feed": "متعلقہ تبدیلیاں",
        "recentchangeslinked-toolbox": "متعلقہ تبدیلیاں",
        "recentchangeslinked-title": "\"$1\" سے متعلقہ تبدیلیاں",
-       "recentchangeslinked-summary": "یہ ان تبدیلیوں کی فہرست ہے جو حال ہی میں کسی مخصوص صفحہ سے مربوط صفحات (یا مخصوص زمرہ کے اراکین) میں کی گئی ہیں۔\n\n[[Special:Watchlist|آپ کی زیر نظر فہرست]] میں یہ صفحات <strong>جلی</strong نظر آئیں گےـ",
+       "recentchangeslinked-summary": "یہ ان تبدیلیوں کی فہرست ہے جو حال ہی میں کسی مخصوص صفحہ سے مربوط صفحات (یا مخصوص زمرہ کے اراکین) میں کی گئی ہیں۔\n\n[[Special:Watchlist|آپ کی زیر نظر فہرست]] میں یہ صفحات <strong>جلی</strong> نظر آئیں گےـ",
        "recentchangeslinked-page": "صفحہ کا نام:",
        "recentchangeslinked-to": "اس کی بجائے درج کردہ صفحہ سے مربوط صفحات کی تبدیلیاں دکھائیں",
        "recentchanges-page-added-to-category": "[[:$1]] کو زمرہ میں شامل کیا گیا",
index 70ec8d2..dfd60de 100644 (file)
@@ -53,6 +53,7 @@
        "tog-showhiddencats": "Mostrer les categoreyes mucheyes",
        "tog-norollbackdiff": "Èn nén håyner les diferinces après on disfijhaedje",
        "tog-useeditwarning": "M' advierti cwand dji cwite ene pådje k' a des candjmints nén schapés",
+       "tog-prefershttps": "Todi eployî on seur raloyaedje cwand dji so elodjî",
        "underline-always": "Tofer",
        "underline-never": "Måy",
        "underline-default": "Valixhance del pea u do betchteu",
index 54296b1..e34c4f4 100644 (file)
        "group-sysop-member": "{{GENDER:$1|管理員}}",
        "group-bureaucrat-member": "行政員",
        "group-suppress-member": "{{GENDER:$1|監督員}}",
-       "grouppage-user": "{{ns:project}}:用戶",
+       "grouppage-user": "{{ns:project}}:使用者",
        "grouppage-autoconfirmed": "{{ns:project}}:自動確認使用者",
        "grouppage-bot": "{{ns:project}}:機器人",
        "grouppage-sysop": "{{ns:project}}:管理員",
        "right-override-export-depth": "匯出頁面包含連結內容,深度上限為 5 層",
        "right-sendemail": "傳送電子郵件聯絡其他使用者",
        "right-managechangetags": "建立並自資料庫 (取消) 啟用 [[Special:Tags|標籤]]",
-       "right-applychangetags": "連同某個人的變更一起套用[[Special:Tags|標籤]]",
+       "right-applychangetags": "連同自己的變更一起套用[[Special:Tags|標籤]]",
        "right-changetags": "加入與移除任何於各別修訂與日誌項目的[[Special:Tags|標籤]]",
        "right-deletechangetags": "從資料庫刪除 [[Special:Tags|標籤]]",
        "grant-generic": "\"$1\" 權限組合",
        "listfiles_thumb": "縮圖",
        "listfiles_date": "日期",
        "listfiles_name": "名稱",
-       "listfiles_user": "用戶",
+       "listfiles_user": "使用者",
        "listfiles_size": "大小",
        "listfiles_description": "描述",
        "listfiles_count": "版本",
        "filehist-thumb": "縮圖",
        "filehist-thumbtext": "於 $1 版本的縮圖",
        "filehist-nothumb": "沒有縮圖",
-       "filehist-user": "用戶",
+       "filehist-user": "使用者",
        "filehist-dimensions": "尺寸",
        "filehist-filesize": "檔案大小",
        "filehist-comment": "備註",
        "unwatching": "正在停止監視...",
        "watcherrortext": "變更 \"$1\" 的監視清單設定時發生錯誤。",
        "enotif_reset": "標記所有頁面為已檢視",
-       "enotif_impersonal_salutation": "{{SITENAME}}用戶",
+       "enotif_impersonal_salutation": "{{SITENAME}}使用者",
        "enotif_subject_deleted": "{{SITENAME}} $2 已刪除頁面 $1",
        "enotif_subject_created": "{{SITENAME}} $2 已建立頁面 $1",
        "enotif_subject_moved": "{{SITENAME}} $2 已移動頁面 $1",
        "pageinfo-category-pages": "頁面數量",
        "pageinfo-category-subcats": "子分類數量",
        "pageinfo-category-files": "檔案數量",
-       "pageinfo-user-id": "用戶ID",
+       "pageinfo-user-id": "使用者 ID",
        "pageinfo-file-hash": "雜湊值",
        "markaspatrolleddiff": "標記為已巡查",
        "markaspatrolledtext": "標記此頁面為已巡查",
        "redirect-submit": "執行",
        "redirect-lookup": "查詢:",
        "redirect-value": "值:",
-       "redirect-user": "用戶ID",
+       "redirect-user": "使用者ID",
        "redirect-page": "頁面 ID",
        "redirect-revision": "頁面修訂 ID",
        "redirect-file": "檔案名稱",
        "tags-delete-title": "刪除標籤",
        "tags-delete-explanation-initial": "您正要從資料庫刪除標籤 \"$1\"。",
        "tags-delete-explanation-in-use": "標籤會自目前正在使用的{{PLURAL:$2| $2 個修訂或日誌項目| $2 修訂或日誌項目}}中移除。",
-       "tags-delete-explanation-warning": "此動作是 <strong>無法還原的</strong> 且 <strong>無法取消的</strong>,即使是資料庫管理者也無法。 請確認您要刪除的標題。",
+       "tags-delete-explanation-warning": "此動作是<strong>不可逆轉的</strong>且<strong>無法取消的</strong>,即使是資料庫管理員也無法。請確認您要刪除的標籤。",
        "tags-delete-explanation-active": "<strong>標籤 \"$1\" 尚在使用,無法刪除。</strong> 要停止標籤使用,請至套用該標籤的頁面,並於該處將標籤停用。",
        "tags-delete-reason": "原因:",
-       "tags-delete-submit": "無法取消刪除此標籤",
+       "tags-delete-submit": "不可逆轉地刪除此標籤",
        "tags-delete-not-allowed": "無法刪除由擴充套件定義的標籤,除非該擴充套件允許。",
        "tags-delete-not-found": "標籤 \"$1\" 不存在。",
        "tags-delete-too-many-uses": "標籤 \"$1\" 會套用至 $2 筆以上的{{PLURAL:$2|修訂|修訂}},這代表該標籤將無法刪除。",
diff --git a/languages/messages/MessagesMni.php b/languages/messages/MessagesMni.php
new file mode 100644 (file)
index 0000000..1641c2a
--- /dev/null
@@ -0,0 +1,9 @@
+<?php
+/** Manipuri/Meitei (মেইতেই লোন্)
+ *
+ * To improve a translation please visit https://translatewiki.net
+ *
+ * @ingroup Language
+ * @file
+ *
+ */
index aa5fdeb..81a8a14 100644 (file)
@@ -92,92 +92,92 @@ $namespaceAliases = [
 ];
 
 $specialPageAliases = [
-       'Allmessages'               => [ 'सर्वप्रणाली-संदेश' ],
-       'Allpages'                  => [ 'सर्वपृष्टानि' ],
-       'Ancientpages'              => [ 'पूर्वतनपृष्टानि' ],
-       'Blankpage'                 => [ 'रिक्तपृष्ठ' ],
-       'Block'                     => [ 'सदस्यप्रतिबन्ध' ],
-       'Booksources'               => [ 'पुस्तकस्रोत' ],
-       'BrokenRedirects'           => [ 'खण्डीतपुनर्निर्देशन' ],
-       'Categories'                => [ 'वर्गः' ],
-       'ChangePassword'            => [ 'सङ्केतशब्दपुन:प्रयुक्ता' ],
-       'Confirmemail'              => [ 'विपत्रपुष्टिकृते' ],
-       'Contributions'             => [ 'योगदानम्' ],
-       'CreateAccount'             => [ 'सृज्उपयोजकसंज्ञा' ],
-       'Deadendpages'              => [ 'निराग्रपृष्टानि' ],
-       'DeletedContributions'      => [ 'परित्यागितयोगदान' ],
-       'DoubleRedirects'           => [ 'पुनर्निर्देशनद्वंद्व' ],
-       'Emailuser'                 => [ 'विपत्रयोजक' ],
-       'ExpandTemplates'           => [ 'बिंबधरविस्तारकरोसि' ],
-       'Export'                    => [ 'निर्यात' ],
-       'Fewestrevisions'           => [ 'स्वल्पपरिवर्तन' ],
-       'FileDuplicateSearch'       => [ 'अनुकृतसंचिकाशोध' ],
-       'Filepath'                  => [ 'संचिकापथ' ],
-       'Import'                    => [ 'आयात' ],
-       'Invalidateemail'           => [ 'अमान्यविपत्र' ],
-       'BlockList'                 => [ 'प्रतिबन्धसूची' ],
-       'LinkSearch'                => [ 'सम्बन्धन्‌शोध' ],
-       'Listadmins'                => [ 'प्रचालकसूची' ],
-       'Listbots'                  => [ 'स्वयंअनुकृसूची' ],
-       'Listfiles'                 => [ 'चित्रसूची', 'संचिकासूचि' ],
-       'Listgrouprights'           => [ 'गटअधिकारसूची' ],
-       'Listredirects'             => [ 'विचालन्‌सूची' ],
-       'Listusers'                 => [ 'सदस्यासूची' ],
-       'Lockdb'                    => [ 'विदाद्वारंबन्ध्' ],
-       'Log'                       => [ 'अङ्कन' ],
-       'Lonelypages'               => [ 'अकलपृष्टानि' ],
-       'Longpages'                 => [ 'दीर्घपृष्टानि' ],
-       'MergeHistory'              => [ 'इतिहाससंयोग' ],
-       'MIMEsearch'                => [ 'विविधामाप_(माईम)_शोधसि' ],
-       'Mostcategories'            => [ 'अधिकतमवर्ग' ],
-       'Mostimages'                => [ 'अधिकतमसम्भन्दिन्_संचिका' ],
-       'Mostlinked'                => [ 'अधिकतमसम्भन्दिन्_पृष्टानि', 'अधिकतमसम्भन्दिन्' ],
-       'Mostlinkedcategories'      => [ 'अधिकतमसम्भन्दिन्_वर्ग' ],
-       'Mostlinkedtemplates'       => [ 'अधिकतमसम्भन्दिन्_फलकानि' ],
-       'Mostrevisions'             => [ 'अधिकतमपरिवर्तन' ],
-       'Movepage'                  => [ 'पृष्ठस्थानान्तर' ],
-       'Mycontributions'           => [ 'मदीययोगदानम्' ],
-       'Mypage'                    => [ 'मम_पृष्टम्' ],
-       'Mytalk'                    => [ 'मदीयसंवादम्' ],
-       'Newimages'                 => [ 'नूतनसंचिका', 'नूतनचित्रानि' ],
-       'Newpages'                  => [ 'नूतनपृष्टानि' ],
-       'PasswordReset'             => [ 'सङ्केतशब्दपुन:प्रयु्क्ता' ],
+       'Allmessages'               => [ 'सरà¥\8dवसनà¥\8dदà¥\87शाà¤\83', 'सरà¥\8dवपà¥\8dरणालà¥\80-सà¤\82दà¥\87श' ],
+       'Allpages'                  => [ 'सरà¥\8dवपà¥\83षà¥\8dठानि', 'सरà¥\8dवपà¥\83षà¥\8dà¤\9fानि' ],
+       'Ancientpages'              => [ 'पà¥\81रातनपà¥\83षà¥\8dठानि', 'पà¥\82रà¥\8dवतनपà¥\83षà¥\8dà¤\9fानि' ],
+       'Blankpage'                 => [ 'रिक्तपृष्ठानि', 'रिक्तपृष्ठ' ],
+       'Block'                     => [ 'पà¥\8dरतिबनà¥\8dधà¤\83', 'सदसà¥\8dयपà¥\8dरतिबनà¥\8dध' ],
+       'Booksources'               => [ 'पुस्तकस्रोतांसि', 'पुस्तकस्रोत' ],
+       'BrokenRedirects'           => [ 'भà¤\97à¥\8dनानि_à¤\85नà¥\81पà¥\8dरà¥\87षणानि', 'à¤\96णà¥\8dडà¥\80तपà¥\81नरà¥\8dनिरà¥\8dदà¥\87शन' ],
+       'Categories'                => [ 'वरà¥\8dà¤\97ाà¤\83', 'वरà¥\8dà¤\97à¤\83' ],
+       'ChangePassword'            => [ 'à¤\95à¥\82à¤\9fशबà¥\8dदà¤\83_परिवरà¥\8dतà¥\8dयतामà¥\8d', 'सà¤\99à¥\8dà¤\95à¥\87तशबà¥\8dदपà¥\81न:पà¥\8dरयà¥\81à¤\95à¥\8dता' ],
+       'Confirmemail'              => [ 'विपतà¥\8dरà¤\82_पà¥\81षà¥\8dà¤\9fà¥\8dयतामà¥\8d', 'विपतà¥\8dरपà¥\81षà¥\8dà¤\9fिà¤\95à¥\83तà¥\87' ],
+       'Contributions'             => [ 'यà¥\8bà¤\97दानानि', 'यà¥\8bà¤\97दानमà¥\8d' ],
+       'CreateAccount'             => [ 'लà¥\87à¤\96ा_सà¥\83à¤\9cà¥\8dयतामà¥\8d', 'सà¥\83à¤\9cà¥\8dà¤\89पयà¥\8bà¤\9cà¤\95सà¤\82à¤\9cà¥\8dà¤\9eा' ],
+       'Deadendpages'              => [ 'मà¥\83तानि_पà¥\83षà¥\8dठानि', 'निराà¤\97à¥\8dरपà¥\83षà¥\8dà¤\9fानि' ],
+       'DeletedContributions'      => [ 'à¤\85पाà¤\95à¥\83तानि_यà¥\8bà¤\97दानानि', 'परितà¥\8dयाà¤\97ितयà¥\8bà¤\97दान' ],
+       'DoubleRedirects'           => [ 'दà¥\8dवà¥\88धपà¥\81नरà¥\8dनिरà¥\8dदà¥\87शनमà¥\8d', 'पà¥\81नरà¥\8dनिरà¥\8dदà¥\87शनदà¥\8dवà¤\82दà¥\8dव' ],
+       'Emailuser'                 => [ 'विपतà¥\8dरपà¥\8dरयà¥\8bà¤\95à¥\8dता', 'विपतà¥\8dरयà¥\8bà¤\9cà¤\95' ],
+       'ExpandTemplates'           => [ 'फलà¤\95ानि_विसà¥\8dतà¥\80रà¥\8dयनà¥\8dतामà¥\8d', 'बिà¤\82बधरविसà¥\8dतारà¤\95रà¥\8bसि' ],
+       'Export'                    => [ 'निरà¥\8dयापयतà¥\81', 'निरà¥\8dयात' ],
+       'Fewestrevisions'           => [ 'सà¥\8dवलà¥\8dपतमपरिवरà¥\8dतानानि', 'सà¥\8dवलà¥\8dपपरिवरà¥\8dतन' ],
+       'FileDuplicateSearch'       => [ 'समानसà¤\9eà¥\8dà¤\9aिà¤\95ानà¥\8dवà¥\87षणमà¥\8d', 'à¤\85नà¥\81à¤\95à¥\83तसà¤\82à¤\9aिà¤\95ाशà¥\8bध' ],
+       'Filepath'                  => [ 'सà¤\9eà¥\8dà¤\9aिà¤\95ापथà¤\83', 'सà¤\82à¤\9aिà¤\95ापथ' ],
+       'Import'                    => [ 'à¤\86यापयतà¥\81', 'à¤\86यात' ],
+       'Invalidateemail'           => [ 'विपतà¥\8dरà¥\87ऽमानà¥\8dयमà¥\8d', 'à¤\85मानà¥\8dयविपतà¥\8dर' ],
+       'BlockList'                 => [ 'पà¥\8dरतिबनà¥\8dधावलिà¤\83', 'पà¥\8dरतिबनà¥\8dधसà¥\82à¤\9aà¥\80' ],
+       'LinkSearch'                => [ 'परिसनà¥\8dधà¥\87à¤\83_à¤\85नà¥\8dवà¥\87षणमà¥\8d', 'समà¥\8dबनà¥\8dधनà¥\8dâ\80\8cशà¥\8bध' ],
+       'Listadmins'                => [ 'पà¥\8dरबनà¥\8dधà¤\95ावलिà¤\83', 'पà¥\8dरà¤\9aालà¤\95सà¥\82à¤\9aà¥\80' ],
+       'Listbots'                  => [ 'बà¥\89à¤\9fसà¥\82à¤\9aà¥\80', 'सà¥\8dवयà¤\82à¤\85नà¥\81à¤\95à¥\83सà¥\82à¤\9aà¥\80' ],
+       'Listfiles'                 => [ 'सà¤\9eà¥\8dà¤\9aिà¤\95ावलिà¤\83', 'à¤\9aितà¥\8dरसà¥\82à¤\9aà¥\80', 'सà¤\82à¤\9aिà¤\95ासà¥\82à¤\9aि' ],
+       'Listgrouprights'           => [ 'समà¥\82हाधिà¤\95ारावलिà¤\83', 'à¤\97à¤\9fà¤\85धिà¤\95ारसà¥\82à¤\9aà¥\80' ],
+       'Listredirects'             => [ 'à¤\85नà¥\81पà¥\8dरà¥\87षितावलिà¤\83', 'विà¤\9aालनà¥\8dâ\80\8cसà¥\82à¤\9aà¥\80' ],
+       'Listusers'                 => [ 'सदसà¥\8dयावलिà¤\83', 'सदसà¥\8dयासà¥\82à¤\9aà¥\80' ],
+       'Lockdb'                    => [ 'दतà¥\8dताà¤\82शà¤\95à¥\80लनमà¥\8d', 'विदादà¥\8dवारà¤\82बनà¥\8dधà¥\8d' ],
+       'Log'                       => [ 'सà¤\82रà¤\95à¥\8dषितावलिà¤\83', 'à¤\85à¤\99à¥\8dà¤\95न' ],
+       'Lonelypages'               => [ 'à¤\8fà¤\95ाà¤\95िपà¥\83षà¥\8dठानि', 'à¤\85à¤\95लपà¥\83षà¥\8dà¤\9fानि' ],
+       'Longpages'                 => [ 'दà¥\80रà¥\8dà¤\98पà¥\83षà¥\8dठानि', 'दà¥\80रà¥\8dà¤\98पà¥\83षà¥\8dà¤\9fानि' ],
+       'MergeHistory'              => [ 'à¤\87तिहासविलयà¤\83', 'à¤\87तिहाससà¤\82यà¥\8bà¤\97' ],
+       'MIMEsearch'                => [ 'MIME_अन्वेषणम्', 'विविधामाप_(माईम)_शोधसि' ],
+       'Mostcategories'            => [ 'अधिकतमवर्गाः', 'अधिकतमवर्ग' ],
+       'Mostimages'                => [ 'à¤\85धिà¤\95तमसà¤\9eà¥\8dà¤\9aिà¤\95ाà¤\83', 'à¤\85धिà¤\95तमसमà¥\8dभनà¥\8dदिनà¥\8d_सà¤\82à¤\9aिà¤\95ा' ],
+       'Mostlinked'                => [ 'à¤\85धिà¤\95तमपरिसनà¥\8dधितमà¥\8d', 'à¤\85धिà¤\95तमसमà¥\8dभनà¥\8dदिनà¥\8d_पà¥\83षà¥\8dà¤\9fानि', 'à¤\85धिà¤\95तमसमà¥\8dभनà¥\8dदिनà¥\8d' ],
+       'Mostlinkedcategories'      => [ 'à¤\85धिà¤\95तमपरिसनà¥\8dधितवरà¥\8dà¤\97ाà¤\83', 'à¤\85धिà¤\95तमसमà¥\8dभनà¥\8dदिनà¥\8d_वरà¥\8dà¤\97' ],
+       'Mostlinkedtemplates'       => [ 'à¤\85धिà¤\95तमपरिसनà¥\8dधितफलà¤\95ानि', 'à¤\85धिà¤\95तमसमà¥\8dभनà¥\8dदिनà¥\8d_फलà¤\95ानि' ],
+       'Mostrevisions'             => [ 'à¤\85धिà¤\95तमसà¤\82सà¥\8dà¤\95रणानि', 'à¤\85धिà¤\95तमपरिवरà¥\8dतन' ],
+       'Movepage'                  => [ 'पृष्ठस्थानान्तरणम्', 'पृष्ठस्थानान्तर' ],
+       'Mycontributions'           => [ 'मम_यà¥\8bà¤\97दानानि', 'मदà¥\80ययà¥\8bà¤\97दानमà¥\8d' ],
+       'Mypage'                    => [ 'मम_पà¥\83षà¥\8dठमà¥\8d', 'मम_पà¥\83षà¥\8dà¤\9fमà¥\8d' ],
+       'Mytalk'                    => [ 'मम_समà¥\8dभाषणमà¥\8d', 'मदà¥\80यसà¤\82वादमà¥\8d' ],
+       'Newimages'                 => [ 'नवà¥\80नà¤\9aितà¥\8dराणि', 'नà¥\82तनसà¤\82à¤\9aिà¤\95ा', 'नà¥\82तनà¤\9aितà¥\8dरानि' ],
+       'Newpages'                  => [ 'नवà¥\80नपà¥\83षà¥\8dठानि', 'नà¥\82तनपà¥\83षà¥\8dà¤\9fानि' ],
+       'PasswordReset'             => [ 'à¤\95à¥\82à¤\9fशबà¥\8dदसà¥\8dय_पà¥\81नसà¥\8dसà¥\8dथापनमà¥\8d', 'सà¤\99à¥\8dà¤\95à¥\87तशबà¥\8dदपà¥\81न:पà¥\8dरयà¥\81à¥\8dà¤\95à¥\8dता' ],
        'Preferences'               => [ 'इष्टतमानि' ],
-       'Prefixindex'               => [ 'उपसर्गअनुक्रमणी' ],
-       'Protectedpages'            => [ 'सुरक्षितपृष्टानि' ],
-       'Protectedtitles'           => [ 'सुरक्षितशिर्षकम्' ],
-       'Randompage'                => [ 'अविशीष्टपृष्ठम्' ],
-       'RandomInCategory'          => [ 'अविशिष्टवर्ग' ],
-       'Randomredirect'            => [ 'अविशीष्टविचालन्‌' ],
-       'Recentchanges'             => [ 'नवीनतम_परिवर्तन' ],
-       'Recentchangeslinked'       => [ 'नवीनतमसम्भन्दिन_परिवर्त' ],
-       'Revisiondelete'            => [ 'आवृत्तीपरित्याग' ],
-       'Search'                    => [ 'शोध' ],
-       'Shortpages'                => [ 'लघुपृष्टानि' ],
-       'Specialpages'              => [ 'विशेषपृष्टानि' ],
-       'Statistics'                => [ 'सांख्यिकी' ],
-       'Uncategorizedcategories'   => [ 'अवर्गीकृतवर्ग' ],
-       'Uncategorizedimages'       => [ 'अवर्गीकृतसंचिका', 'अवर्गीकृतचित्रानि' ],
-       'Uncategorizedpages'        => [ 'अवर्गीकृतपृष्टानि' ],
+       'Prefixindex'               => [ 'à¤\89पसरà¥\8dà¤\97ानà¥\81à¤\95à¥\8dरमणà¥\80', 'à¤\89पसरà¥\8dà¤\97à¤\85नà¥\81à¤\95à¥\8dरमणà¥\80' ],
+       'Protectedpages'            => [ 'सà¥\81रà¤\95à¥\8dषितपà¥\83षà¥\8dठानि', 'सà¥\81रà¤\95à¥\8dषितपà¥\83षà¥\8dà¤\9fानि' ],
+       'Protectedtitles'           => [ 'सà¥\81रà¤\95à¥\8dषितशà¥\80रà¥\8dषà¤\95ाणि', 'सà¥\81रà¤\95à¥\8dषितशिरà¥\8dषà¤\95मà¥\8d' ],
+       'Randompage'                => [ 'यादà¥\83à¤\9aà¥\8dà¤\9bिà¤\95पà¥\83षà¥\8dठमà¥\8d', 'à¤\85विशà¥\80षà¥\8dà¤\9fपà¥\83षà¥\8dठमà¥\8d' ],
+       'RandomInCategory'          => [ 'वरà¥\8dà¤\97à¥\87_यादà¥\83à¤\9aà¥\8dà¤\9bिà¤\95मà¥\8d', 'à¤\85विशिषà¥\8dà¤\9fवरà¥\8dà¤\97' ],
+       'Randomredirect'            => [ 'यादà¥\83à¤\9aà¥\8dà¤\9bिà¤\95ानà¥\81पà¥\8dरà¥\87षितमà¥\8d', 'à¤\85विशà¥\80षà¥\8dà¤\9fविà¤\9aालनà¥\8dâ\80\8c' ],
+       'Recentchanges'             => [ 'नà¥\82तनपरिवरà¥\8dतनानि', 'नवà¥\80नतम_परिवरà¥\8dतन' ],
+       'Recentchangeslinked'       => [ 'नà¥\82तनपरिवरà¥\8dतनानाà¤\82_परिसनà¥\8dधयà¤\83', 'नवà¥\80नतमसमà¥\8dभनà¥\8dदिन_परिवरà¥\8dत' ],
+       'Revisiondelete'            => [ 'सà¤\82सà¥\8dà¤\95रणापाà¤\95रणमà¥\8d', 'à¤\86वà¥\83तà¥\8dतà¥\80परितà¥\8dयाà¤\97' ],
+       'Search'                    => [ 'à¤\85नà¥\8dवà¥\87षणमà¥\8d', 'शà¥\8bध' ],
+       'Shortpages'                => [ 'लà¤\98à¥\81पà¥\83षà¥\8dठानि', 'लà¤\98à¥\81पà¥\83षà¥\8dà¤\9fानि' ],
+       'Specialpages'              => [ 'विशà¥\87षपà¥\83षà¥\8dठानि', 'विशà¥\87षपà¥\83षà¥\8dà¤\9fानि' ],
+       'Statistics'                => [ 'साà¤\99à¥\8dà¤\96à¥\8dयिà¤\95à¥\80', 'साà¤\82à¤\96à¥\8dयिà¤\95à¥\80' ],
+       'Uncategorizedcategories'   => [ 'अवर्गीकृतवर्गाः', 'अवर्गीकृतवर्ग' ],
+       'Uncategorizedimages'       => [ 'à¤\85वरà¥\8dà¤\97à¥\80à¤\95à¥\83तà¤\9aितà¥\8dराणि', 'à¤\85वरà¥\8dà¤\97à¥\80à¤\95à¥\83तसà¤\82à¤\9aिà¤\95ा', 'à¤\85वरà¥\8dà¤\97à¥\80à¤\95à¥\83तà¤\9aितà¥\8dरानि' ],
+       'Uncategorizedpages'        => [ 'à¤\85वरà¥\8dà¤\97à¥\80à¤\95à¥\83तपà¥\83षà¥\8dठानि', 'à¤\85वरà¥\8dà¤\97à¥\80à¤\95à¥\83तपà¥\83षà¥\8dà¤\9fानि' ],
        'Uncategorizedtemplates'    => [ 'अवर्गीकृतफलकानि' ],
-       'Undelete'                  => [ 'प्रत्यादिश्_परित्याग' ],
-       'Unlockdb'                  => [ 'विवृतविदाद्वारंतालक' ],
-       'Unusedcategories'          => [ 'अप्रयूक्तवर्ग' ],
-       'Unusedimages'              => [ 'अप्रयूक्तसंचिका' ],
-       'Unusedtemplates'           => [ 'अप्रयूक्तबिंबधर' ],
-       'Unwatchedpages'            => [ 'अनिरिक्षीतपृष्ठ' ],
-       'Upload'                    => [ 'भारंन्यस्यति' ],
-       'Userlogin'                 => [ 'सदस्यप्रवेशन' ],
-       'Userlogout'                => [ 'सदस्यबहिर्गमन' ],
-       'Userrights'                => [ 'योजकआधिकार' ],
-       'Version'                   => [ 'आवृत्ती' ],
-       'Wantedcategories'          => [ 'प्रार्थितवर्ग' ],
-       'Wantedfiles'               => [ 'प्रार्थितसंचिका' ],
-       'Wantedpages'               => [ 'प्रार्थितपृष्टानि' ],
-       'Wantedtemplates'           => [ 'प्रार्थितफलकानि' ],
-       'Watchlist'                 => [ 'निरीक्षा_सूची' ],
-       'Whatlinkshere'             => [ 'किमपृष्ठ_सम्बद्धंकरोति' ],
-       'Withoutinterwiki'          => [ 'आन्तरविकिहीन' ],
+       'Undelete'                  => [ 'पà¥\81नसà¥\8dसà¥\8dथापनमà¥\8d', 'पà¥\8dरतà¥\8dयादिशà¥\8d_परितà¥\8dयाà¤\97' ],
+       'Unlockdb'                  => [ 'दतà¥\8dताà¤\82शà¥\8bदà¥\8dà¤\98ाà¤\9fनमà¥\8d', 'विवà¥\83तविदादà¥\8dवारà¤\82तालà¤\95' ],
+       'Unusedcategories'          => [ 'à¤\85पà¥\8dरयà¥\81à¤\95à¥\8dतवरà¥\8dà¤\97ाà¤\83', 'à¤\85पà¥\8dरयà¥\82à¤\95à¥\8dतवरà¥\8dà¤\97' ],
+       'Unusedimages'              => [ 'à¤\85पà¥\8dरयà¥\81à¤\95à¥\8dतà¤\9aितà¥\8dराणि', 'à¤\85पà¥\8dरयà¥\82à¤\95à¥\8dतसà¤\82à¤\9aिà¤\95ा' ],
+       'Unusedtemplates'           => [ 'à¤\85पà¥\8dरयà¥\81à¤\95à¥\8dतफलà¤\95ानि', 'à¤\85पà¥\8dरयà¥\82à¤\95à¥\8dतबिà¤\82बधर' ],
+       'Unwatchedpages'            => [ 'à¤\85निरà¥\80à¤\95à¥\8dषितपà¥\83षà¥\8dठानि', 'à¤\85निरिà¤\95à¥\8dषà¥\80तपà¥\83षà¥\8dठ' ],
+       'Upload'                    => [ 'à¤\89पारà¥\8bपणमà¥\8d', 'भारà¤\82नà¥\8dयसà¥\8dयति' ],
+       'Userlogin'                 => [ 'सदसà¥\8dयपà¥\8dरवà¥\87शà¤\83', 'सदसà¥\8dयपà¥\8dरवà¥\87शन' ],
+       'Userlogout'                => [ 'सदसà¥\8dयनिरà¥\8dà¤\97मनमà¥\8d', 'सदसà¥\8dयबहिरà¥\8dà¤\97मन' ],
+       'Userrights'                => [ 'सदसà¥\8dयाधिà¤\95ाराà¤\83', 'यà¥\8bà¤\9cà¤\95à¤\86धिà¤\95ार' ],
+       'Version'                   => [ 'सà¤\82सà¥\8dà¤\95रणमà¥\8d', 'à¤\86वà¥\83तà¥\8dतà¥\80' ],
+       'Wantedcategories'          => [ 'वाà¤\9eà¥\8dà¤\9bितवरà¥\8dà¤\97ाà¤\83', 'पà¥\8dरारà¥\8dथितवरà¥\8dà¤\97' ],
+       'Wantedfiles'               => [ 'वाà¤\9eà¥\8dà¤\9bितसà¤\9eà¥\8dà¤\9aिà¤\95ाà¤\83', 'पà¥\8dरारà¥\8dथितसà¤\82à¤\9aिà¤\95ा' ],
+       'Wantedpages'               => [ 'वाà¤\9eà¥\8dà¤\9bितपà¥\83षà¥\8dठानि', 'पà¥\8dरारà¥\8dथितपà¥\83षà¥\8dà¤\9fानि' ],
+       'Wantedtemplates'           => [ 'वाà¤\9eà¥\8dà¤\9bितफलà¤\95ानि', 'पà¥\8dरारà¥\8dथितफलà¤\95ानि' ],
+       'Watchlist'                 => [ 'निरीक्षा_सूची', 'निरीक्षासूचिः' ],
+       'Whatlinkshere'             => [ 'à¤\95िमतà¥\8dर_सà¤\81लà¥\8dलà¤\97à¥\8dनमà¥\8d', 'à¤\95िमपà¥\83षà¥\8dठ_समà¥\8dबदà¥\8dधà¤\82à¤\95रà¥\8bति' ],
+       'Withoutinterwiki'          => [ 'à¤\85नà¥\8dतरà¥\8dविà¤\95िपरिसनà¥\8dधिहà¥\80नमà¥\8d', 'à¤\86नà¥\8dतरविà¤\95िहà¥\80न' ],
 ];
 
 $magicWords = [
index 245bb47..866f959 100644 (file)
@@ -203,7 +203,7 @@ abstract class Maintenance {
        /**
         * Do the actual work. All child classes will need to implement this
         *
-        * @return bool|null True for success, false for failure. Not returning
+        * @return bool|null|void True for success, false for failure. Not returning
         *   a value, or returning null, is also interpreted as success. Returning
         *   false for failure will cause doMaintenance.php to exit the process
         *   with a non-zero exit status.
@@ -1606,6 +1606,9 @@ abstract class Maintenance {
                if ( wfIsWindows() ) {
                        return $default;
                }
+               if ( Shell::isDisabled() ) {
+                       return $default;
+               }
                // It's possible to get the screen size with VT-100 terminal escapes,
                // but reading the responses is not possible without setting raw mode
                // (unless you want to require the user to press enter), and that
index a12cda7..bf7a22d 100644 (file)
@@ -220,7 +220,7 @@ SPARQL;
        ) {
                $tables = [ 'recentchanges', 'page_props', 'category' ];
                if ( $extra_tables ) {
-                       $tables += $extra_tables;
+                       $tables = array_merge( $tables, $extra_tables );
                }
                $it = new BatchRowIterator( $dbr,
                        $tables,
index b2e976c..707eb29 100644 (file)
@@ -151,7 +151,7 @@ class PopulateChangeTagDef extends Maintenance {
                $dbw = $this->lbFactory->getMainLB()->getConnection( DB_MASTER );
                $sleep = (int)$this->getOption( 'sleep', 10 );
                $lastId = 0;
-               $this->output( "Starting to add ct_tag_id = {$tagId} for ct_tag = {$tagName}" );
+               $this->output( "Starting to add ct_tag_id = {$tagId} for ct_tag = {$tagName}\n" );
                while ( true ) {
                        // Given that indexes might not be there, it's better to use replica
                        $ids = $dbr->selectFieldValues(
@@ -173,7 +173,7 @@ class PopulateChangeTagDef extends Maintenance {
                                );
                                continue;
                        } else {
-                               $this->output( "Updating ct_tag_id = {$tagId} up to row ct_id = {$lastId}" );
+                               $this->output( "Updating ct_tag_id = {$tagId} up to row ct_id = {$lastId}\n" );
                        }
 
                        $dbw->update(
@@ -189,7 +189,7 @@ class PopulateChangeTagDef extends Maintenance {
                        }
                }
 
-               $this->output( "Finished adding ct_tag_id = {$tagId} for ct_tag = {$tagName}" );
+               $this->output( "Finished adding ct_tag_id = {$tagId} for ct_tag = {$tagName}\n" );
        }
 
 }
index 271cbf3..7f36442 100644 (file)
@@ -24,6 +24,7 @@
 
 use MediaWiki\Logger\LegacyLogger;
 use MediaWiki\MediaWikiServices;
+use Wikimedia\Rdbms\IDatabase;
 
 $optionsWithArgs = RecompressTracked::getOptionsWithArgs();
 require __DIR__ . '/../commandLine.inc';
@@ -640,7 +641,7 @@ class RecompressTracked {
        /**
         * Gets a DB master connection for the given external cluster name
         * @param string $cluster
-        * @return Database
+        * @return IDatabase
         */
        function getExtDB( $cluster ) {
                $lbFactory = MediaWikiServices::getInstance()->getDBLoadBalancerFactory();
index d88d5e9..0670454 100644 (file)
@@ -187,13 +187,7 @@ TEXT
                                }
                                # cl_type will be wrong for lots of pages if cl_collation is 0,
                                # so let's update it while we're here.
-                               if ( $title->getNamespace() == NS_CATEGORY ) {
-                                       $type = 'subcat';
-                               } elseif ( $title->getNamespace() == NS_FILE ) {
-                                       $type = 'file';
-                               } else {
-                                       $type = 'page';
-                               }
+                               $type = MWNamespace::getCategoryLinkType( $title->getNamespace() );
                                $newSortKey = $collation->getSortKey(
                                        $title->getCategorySortkey( $prefix ) );
                                if ( $verboseStats ) {
index d0c52d8..b724306 100644 (file)
@@ -706,12 +706,6 @@ return [
                'group' => 'jquery.ui',
        ],
 
-       /* json2 */
-       'json' => [
-               'deprecated' => 'Use of the "json" module is deprecated since MediaWiki 1.29.0',
-               'targets' => [ 'desktop', 'mobile' ],
-       ],
-
        /* Moment.js */
 
        'moment' => [
@@ -2190,7 +2184,7 @@ return [
        ],
        'mediawiki.special.preferences.styles.ooui' => [
                'targets' => [ 'desktop', 'mobile' ],
-               'styles' => 'resources/src/mediawiki.special.preferences.styles.ooui.css',
+               'styles' => 'resources/src/mediawiki.special.preferences.styles.ooui.less',
        ],
        'mediawiki.special.recentchanges' => [
                'scripts' => 'resources/src/mediawiki.special.recentchanges.js',
index 7d4ed53..d38adcd 100644 (file)
         * @inheritdoc
         */
        mw.ForeignStructuredUpload.BookletLayout.prototype.getText = function () {
-               var language = mw.config.get( 'wgContentLanguage' );
+               var language = mw.config.get( 'wgContentLanguage' ),
+                       categories = this.categoriesWidget.getItems().map( function ( item ) {
+                               return item.data;
+                       } );
                this.upload.clearDescriptions();
                this.upload.addDescription( language, this.descriptionWidget.getValue() );
                this.upload.setDate( this.dateWidget.getValue() );
                this.upload.clearCategories();
-               this.upload.addCategories( this.categoriesWidget.getItemsData() );
+               this.upload.addCategories( categories );
                return this.upload.getText();
        };
 
                mw.ForeignStructuredUpload.BookletLayout.parent.prototype.clear.call( this );
 
                this.ownWorkCheckbox.setSelected( false );
-               this.categoriesWidget.setItemsFromData( [] );
+               this.categoriesWidget.setValue( [] );
                this.dateWidget.setValue( '' ).setValidityFlag( true );
        };
 
index 72ce9f0..cb9c286 100644 (file)
@@ -4,9 +4,11 @@
        background-color: #eaecf0;
        background-size: cover;
        background-position: center center;
-       padding: 1.5em;
-       margin: -1.5em;
-       margin-bottom: 1.5em;
+       /* Same as padding on `.oo-ui-bookletLayout-stackLayout > .oo-ui-panelLayout`,
+        * equals 20px at default font size */
+       padding: 1.42857143em;
+       margin: -1.42857143em;
+       margin-bottom: 1.42857143em;
        position: relative;
 }
 
index d1e40ca..fef5226 100644 (file)
                if ( !this.isHighlightSupported() ) {
                        return;
                }
+               // If the highlight color on the item and in the parameter is null/undefined, return early.
+               if ( !this.highlightColor && !highlightColor ) {
+                       return;
+               }
 
                if ( this.highlightColor !== highlightColor ) {
                        this.highlightColor = highlightColor;
index fad409b..390d873 100644 (file)
                }
        }
 
+       .mw-rcfilters-ui-highlights {
+               display: none;
+       }
+
        .mw-changeslist {
                // Reserve space for the highlight circles
                ul,
index 5f6fbea..920fec3 100644 (file)
@@ -1,4 +1,5 @@
 @import 'mw.rcfilters.mixins';
+@import 'mw.rcfilters.variables';
 
 .mw-rcfilters-ui-changesListWrapperWidget {
        ul {
@@ -8,59 +9,65 @@
                        list-style: none;
                }
        }
+}
 
-       // Make more specific for the overrides
-       div&-highlights {
+// Make more specific for the overrides
+div.mw-rcfilters-ui-highlights {
+       body.mw-rcfilters-ui-initialized & {
                display: inline-block;
+       }
 
-               &-color {
-                       &-none {
-                               display: inline-block;
-                               .mw-changeslist-watchedseen & {
-                                       .mw-rcfilters-ui-changesListWrapperWidget.mw-rcfilters-ui-changesListWrapperWidget-highlighted & {
-                                               .mw-rcfilters-mixin-circle( @highlight-none, @result-circle-diameter, 0, true, @highlight-grey, true );
-                                       }
-
-                                       .mw-rcfilters-ui-changesListWrapperWidget:not( .mw-rcfilters-ui-changesListWrapperWidget-highlighted ) & {
-                                               .mw-rcfilters-mixin-circle( @highlight-none, @result-circle-diameter, 0, true, @highlight-bluedot, true );
-                                       }
+       &-color {
+               &-none {
+                       display: inline-block;
+                       .mw-changeslist-watchedseen & {
+                               .mw-rcfilters-ui-changesListWrapperWidget.mw-rcfilters-ui-changesListWrapperWidget-highlighted & {
+                                       .mw-rcfilters-mixin-circle( @highlight-none, @result-circle-diameter, 0, true, @highlight-grey, true );
                                }
 
-                               .mw-changeslist-watchedunseen & {
-                                       .mw-rcfilters-ui-changesListWrapperWidget.mw-rcfilters-ui-changesListWrapperWidget-highlighted & {
-                                               .mw-rcfilters-mixin-circle( @highlight-grey, @result-circle-diameter, 0, true, @highlight-grey );
-                                       }
+                               .mw-rcfilters-ui-changesListWrapperWidget:not( .mw-rcfilters-ui-changesListWrapperWidget-highlighted ) & {
+                                       .mw-rcfilters-mixin-circle( @highlight-none, @result-circle-diameter, 0, true, @highlight-bluedot, true );
+                               }
+                       }
 
-                                       .mw-rcfilters-ui-changesListWrapperWidget:not( .mw-rcfilters-ui-changesListWrapperWidget-highlighted ) & {
-                                               .mw-rcfilters-mixin-circle( @highlight-bluedot, @result-circle-diameter, 0, true, @highlight-bluedot );
-                                       }
+                       .mw-changeslist-watchedunseen & {
+                               .mw-rcfilters-ui-changesListWrapperWidget.mw-rcfilters-ui-changesListWrapperWidget-highlighted & {
+                                       .mw-rcfilters-mixin-circle( @highlight-grey, @result-circle-diameter, 0, true, @highlight-grey );
                                }
 
+                               .mw-rcfilters-ui-changesListWrapperWidget:not( .mw-rcfilters-ui-changesListWrapperWidget-highlighted ) & {
+                                       .mw-rcfilters-mixin-circle( @highlight-bluedot, @result-circle-diameter, 0, true, @highlight-bluedot );
+                               }
                        }
 
-                       // Watchlist unseen highlighted fixes
-                       // Seen (empty circle)
-                       // There's no need to correct 'unseen' because that would be
-                       // a filled colorful circle, which is the regular rendering
-                       .mw-changeslist-watchedseen &-c1 {
-                               .mw-rcfilters-mixin-circle( @highlight-c1, @result-circle-diameter, 0, true, @highlight-c1, true );
-                       }
+               }
 
-                       .mw-changeslist-watchedseen &-c2 {
-                               .mw-rcfilters-mixin-circle( @highlight-c2, @result-circle-diameter, 0, true, @highlight-c2, true );
-                       }
+               // Watchlist unseen highlighted fixes
+               // Seen (empty circle)
+               // There's no need to correct 'unseen' because that would be
+               // a filled colorful circle, which is the regular rendering
+               .mw-changeslist-watchedseen &-c1 {
+                       .mw-rcfilters-mixin-circle( @highlight-c1, @result-circle-diameter, 0, true, @highlight-c1, true );
+               }
 
-                       .mw-changeslist-watchedseen &-c3 {
-                               .mw-rcfilters-mixin-circle( @highlight-c3, @result-circle-diameter, 0, true, @highlight-c3, true );
-                       }
+               .mw-changeslist-watchedseen &-c2 {
+                       .mw-rcfilters-mixin-circle( @highlight-c2, @result-circle-diameter, 0, true, @highlight-c2, true );
+               }
 
-                       .mw-changeslist-watchedseen &-c4 {
-                               .mw-rcfilters-mixin-circle( @highlight-c4, @result-circle-diameter, 0, true, @highlight-c4, true );
-                       }
+               .mw-changeslist-watchedseen &-c3 {
+                       .mw-rcfilters-mixin-circle( @highlight-c3, @result-circle-diameter, 0, true, @highlight-c3, true );
+               }
 
-                       .mw-changeslist-watchedseen &-c5 {
-                               .mw-rcfilters-mixin-circle( @highlight-c5, @result-circle-diameter, 0, true, @highlight-c5, true );
-                       }
+               .mw-changeslist-watchedseen &-c4 {
+                       .mw-rcfilters-mixin-circle( @highlight-c4, @result-circle-diameter, 0, true, @highlight-c4, true );
                }
+
+               .mw-changeslist-watchedseen &-c5 {
+                       .mw-rcfilters-mixin-circle( @highlight-c5, @result-circle-diameter, 0, true, @highlight-c5, true );
+               }
+       }
+
+       .mw-rcfilters-ui-changesListWrapperWidget & > div {
+               margin-right: @result-circle-margin;
        }
 }
index 907c535..6d36c71 100644 (file)
 
        /* Methods */
 
+       /**
+        * Override parent method to avoid unnecessary resize events.
+        */
+       mw.rcfilters.ui.FilterTagMultiselectWidget.prototype.updateIfHeightChanged = function () { };
+
        /**
         * Respond to view select widget choose event
         *
         * @inheritdoc
         */
        mw.rcfilters.ui.FilterTagMultiselectWidget.prototype.onChangeTags = function () {
-               // Parent method
-               mw.rcfilters.ui.FilterTagMultiselectWidget.parent.prototype.onChangeTags.call( this );
+               // If initialized, call parent method.
+               if ( this.controller.isInitialized() ) {
+                       mw.rcfilters.ui.FilterTagMultiselectWidget.parent.prototype.onChangeTags.call( this );
+               }
 
                this.emptyFilterMessage.toggle( this.isEmpty() );
        };
index 04b7709..40b2fcf 100644 (file)
         */
        mw.rcfilters.ui.MenuSelectWidget.prototype.onModelInitialize = function () {
                this.menuInitialized = false;
+               // Set timeout for the menu to lazy build.
+               setTimeout( this.lazyMenuCreation.bind( this ) );
        };
 
        /**
index 65860ea..1b37ec3 100644 (file)
@@ -54,3 +54,9 @@
 .mw-changeslist-legend.mw-collapsed + h4 + div > table.mw-changeslist-line:first-child {
        clear: right;
 }
+
+/* Hide RCFilters highlight containers if RCFilters is not enabled.
+   This is overridden in mw.ui.rcfilters.ChangesListWrapperWidget.less if RCFilters is enabled. */
+.mw-rcfilters-ui-highlights {
+       display: none;
+}
diff --git a/resources/src/mediawiki.special.preferences.styles.ooui.css b/resources/src/mediawiki.special.preferences.styles.ooui.css
deleted file mode 100644 (file)
index 4c5d344..0000000
+++ /dev/null
@@ -1,145 +0,0 @@
-/* Reuses colors from mediawiki.legacy/shared.css */
-.mw-email-not-authenticated .oo-ui-labelWidget,
-.mw-email-none .oo-ui-labelWidget {
-       border: 1px solid #fde29b;
-       background-color: #fdf1d1;
-       color: #000;
-       padding: 0.5em;
-}
-/* Authenticated email field has its own class too. Unstyled by default */
-/*
-.mw-email-authenticated .oo-ui-labelWidget { }
-*/
-
-/* This is needed because add extra buttons in a weird way */
-.mw-prefs-buttons .mw-htmlform-submit-buttons {
-       margin: 0;
-       display: inline;
-}
-
-.mw-prefs-buttons {
-       margin-top: 1em;
-}
-
-#prefcontrol {
-       margin-right: 0.5em;
-}
-
-/*
- * Hide, but keep accessible for screen-readers.
- */
-.client-js .mw-navigation-hint {
-       overflow: hidden;
-       height: 0;
-       zoom: 1;
-}
-
-/* Override OOUI styles so that dropdowns near the bottom of the form don't get clipped,
- * e.g.'Appearance' / 'Threshold for stub link formatting'. This is hacky and bad, it would be
- * better solved by setting overlays for the widgets, but we can't do it from PHP... */
-#preferences .oo-ui-panelLayout {
-       position: static;
-       overflow: visible;
-       -webkit-transform: none;
-       transform: none;
-}
-
-#preferences .oo-ui-menuLayout .oo-ui-panelLayout-framed .oo-ui-panelLayout-framed {
-       border-width: 0;
-       border-radius: 0;
-       box-shadow: none;
-       padding-left: 0;
-       padding-right: 0;
-}
-
-.mw-prefs-faketabs > .oo-ui-menuLayout > .oo-ui-menuLayout-menu a {
-       color: inherit;
-       text-decoration: none;
-}
-
-/* Adjust the borders when JS is disabled: frame each prefsection instead of the
- * whole tabLayout wrapper */
-.client-nojs #preferences .oo-ui-menuLayout .oo-ui-panelLayout-framed .oo-ui-panelLayout-framed {
-       border-color: #c8ccd1;
-       border-width: 1px 0 0;
-}
-
-.client-nojs .mw-prefs-faketabs {
-       border-width: 0;
-       border-radius: 0;
-       box-shadow: none;
-}
-
-.client-nojs .mw-prefs-faketabs > .oo-ui-menuLayout > .oo-ui-menuLayout-content > .oo-ui-stackLayout {
-       margin-bottom: 1em;
-}
-
-/* Hide the tab menu when JS is disabled as we can't use this feature */
-.client-nojs .mw-prefs-faketabs > .oo-ui-menuLayout > .oo-ui-menuLayout-menu {
-       display: none;
-}
-
-.client-nojs #preferences .oo-ui-panelLayout-framed .oo-ui-panelLayout-framed:last-child {
-       padding-bottom: 0;
-       margin-bottom: 0;
-}
-
-/* Hide top level legends when JS is enabled, as they will not be visible
- * when the real tabLayout is built */
-.client-js #preferences .oo-ui-tabPanelLayout > fieldset > legend {
-       display: none;
-}
-
-.client-js #preferences .oo-ui-tabPanelLayout {
-       padding-top: 0.5em;
-}
-
-.client-js #preferences .oo-ui-panelLayout-framed .oo-ui-panelLayout-framed {
-       margin-left: 0;
-       margin-bottom: 0;
-       padding: 0;
-       border-width: 0;
-       border-radius: 0;
-       box-shadow: none;
-}
-
-.client-js #preferences > .oo-ui-panelLayout > .oo-ui-fieldsetLayout > .oo-ui-fieldsetLayout-header {
-       margin-bottom: 1em;
-}
-
-/* Make the "Basic information" section more compact */
-/* OOUI's `align: 'left'` for FieldLayouts sucks, so we do our own */
-#mw-htmlform-info > .oo-ui-fieldLayout-align-top > .oo-ui-fieldLayout-body > .oo-ui-fieldLayout-header {
-       width: 20%;
-       display: inline-block;
-       vertical-align: middle;
-       padding: 0;
-}
-
-#mw-htmlform-info > .oo-ui-fieldLayout-align-top .oo-ui-fieldLayout-help {
-       margin-right: 0;
-}
-
-#mw-htmlform-info > .oo-ui-fieldLayout.oo-ui-fieldLayout-align-top > .oo-ui-fieldLayout-body > .oo-ui-fieldLayout-field {
-       width: 80%;
-       display: inline-block;
-       vertical-align: middle;
-}
-
-/* Expand the dropdown and textfield of "Time zone" field to the */
-/* usual maximum width and display them on separate lines. */
-#wpTimeCorrection .oo-ui-dropdownInputWidget,
-#wpTimeCorrection .oo-ui-textInputWidget {
-       display: block;
-       max-width: 50em;
-}
-
-#wpTimeCorrection .oo-ui-textInputWidget {
-       margin-top: 0.5em;
-}
-
-/* HACK: expand width of gadget descriptions.
- * This should be moved to the Gadgets extension */
-#mw-htmlform-gadgets .oo-ui-fieldLayout.oo-ui-fieldLayout-align-inline > .oo-ui-fieldLayout-body {
-       max-width: none;
-}
diff --git a/resources/src/mediawiki.special.preferences.styles.ooui.less b/resources/src/mediawiki.special.preferences.styles.ooui.less
new file mode 100644 (file)
index 0000000..ecf6887
--- /dev/null
@@ -0,0 +1,159 @@
+@import 'mediawiki.mixins';
+
+/* Reuses colors from mediawiki.legacy/shared.css */
+.mw-email-not-authenticated .oo-ui-labelWidget,
+.mw-email-none .oo-ui-labelWidget {
+       background-color: #fdf1d1;
+       color: #000;
+       border: 1px solid #fde29b;
+       padding: 0.5em;
+}
+/* Authenticated email field has its own class too. Unstyled by default */
+/*
+.mw-email-authenticated .oo-ui-labelWidget { }
+*/
+
+/* This is needed because add extra buttons in a weird way */
+.mw-prefs-buttons .mw-htmlform-submit-buttons {
+       display: inline;
+       margin: 0;
+}
+
+.mw-prefs-buttons {
+       margin-top: 1em;
+}
+
+#prefcontrol {
+       margin-right: 0.5em;
+}
+
+/*
+ * Hide, but keep accessible for screen-readers.
+ */
+.client-js .mw-navigation-hint {
+       overflow: hidden;
+       height: 0;
+       zoom: 1;
+}
+
+/* Override OOUI styles so that dropdowns near the bottom of the form don't get clipped,
+ * e.g.'Appearance' / 'Threshold for stub link formatting'. This is hacky and bad, it would be
+ * better solved by setting overlays for the widgets, but we can't do it from PHP... */
+#preferences .oo-ui-panelLayout {
+       position: static;
+       overflow: visible;
+       .transform( none );
+}
+
+#preferences .oo-ui-menuLayout .oo-ui-panelLayout-framed .oo-ui-panelLayout-framed {
+       border-width: 0;
+       border-radius: 0;
+       padding-left: 0;
+       padding-right: 0;
+       box-shadow: none;
+}
+
+.mw-prefs-faketabs > .oo-ui-menuLayout > .oo-ui-menuLayout-menu a {
+       color: inherit;
+       text-decoration: none;
+}
+
+/* Disabled JavaScript */
+.client-nojs {
+       /* Adjust the borders: frame each prefsection instead of the
+        * whole tabLayout wrapper */
+       #preferences .oo-ui-menuLayout .oo-ui-panelLayout-framed .oo-ui-panelLayout-framed:first-child {
+               border-color: #c8ccd1;
+               border-width: 1px 0 0;
+       }
+
+       #preferences .oo-ui-panelLayout-framed .oo-ui-panelLayout-framed:last-child {
+               padding-bottom: 0;
+               margin-bottom: 0;
+       }
+
+       /* Fake Tabs to address reflow */
+       .mw-prefs-faketabs {
+               border-width: 0;
+               border-radius: 0;
+               .box-shadow( none );
+
+               > .oo-ui-menuLayout > .oo-ui-menuLayout-content > .oo-ui-stackLayout {
+                       margin-bottom: 1em;
+               }
+
+               /* Hide the tab menu when JS is disabled as we can't use this feature */
+               > .oo-ui-menuLayout > .oo-ui-menuLayout-menu {
+                       display: none;
+               }
+       }
+}
+
+/* Enabled JavaScript
+ * Hide top level legends when JS is enabled, as they will not be visible
+ * when the real tabLayout is built */
+.client-js #preferences {
+       .oo-ui-tabPanelLayout {
+               padding-top: 0.5em;
+
+               & > fieldset > legend {
+                       display: none;
+               }
+       }
+
+       .oo-ui-panelLayout-framed .oo-ui-panelLayout-framed {
+               margin-top: 2.286em; /* equals `32px` at `font-size: 14px;` */
+               margin-bottom: 0;
+               border-width: 0;
+               border-radius: 0;
+               padding: 0;
+               box-shadow: none;
+
+               &:first-child {
+                       margin-top: 0.85714286em;
+               }
+       }
+
+       > .oo-ui-panelLayout > .oo-ui-fieldsetLayout > .oo-ui-fieldsetLayout-header {
+               margin-bottom: 1em;
+       }
+}
+
+/* Make the "Basic information" section more compact */
+/* OOUI's `align: 'left'` for FieldLayouts sucks, so we do our own */
+#mw-htmlform-info {
+       > .oo-ui-fieldLayout-align-top > .oo-ui-fieldLayout-body > .oo-ui-fieldLayout-header {
+               display: inline-block;
+               width: 20%;
+               padding: 0;
+               vertical-align: middle;
+       }
+
+       > .oo-ui-fieldLayout-align-top .oo-ui-fieldLayout-help {
+               margin-right: 0;
+       }
+
+       > .oo-ui-fieldLayout.oo-ui-fieldLayout-align-top > .oo-ui-fieldLayout-body > .oo-ui-fieldLayout-field {
+               display: inline-block;
+               width: 80%;
+               vertical-align: middle;
+       }
+}
+
+/* Expand the dropdown and textfield of "Time zone" field to the */
+/* usual maximum width and display them on separate lines. */
+#wpTimeCorrection .oo-ui-dropdownInputWidget,
+#wpTimeCorrection .oo-ui-textInputWidget {
+       display: block;
+       max-width: 50em;
+}
+
+#wpTimeCorrection .oo-ui-textInputWidget {
+       margin-top: 0.5em;
+}
+
+/* HACK: expand width of gadget descriptions.
+ * This should be moved to the Gadgets extension */
+#mw-htmlform-gadgets .oo-ui-fieldLayout.oo-ui-fieldLayout-align-inline > .oo-ui-fieldLayout-body {
+       max-width: none;
+}
index 2bbeabf..2340f9c 100644 (file)
@@ -26,8 +26,8 @@
         * @cfg {boolean} [showMissing=true] Show missing pages
         * @cfg {boolean} [addQueryInput=true] Add exact user's input query to results
         * @cfg {boolean} [excludeCurrentPage] Exclude the current page from suggestions
-        * @cfg {boolean} [validateTitle=true] Whether the input must be a valid title (if set to true,
-        *  the widget will marks itself red for invalid inputs, including an empty query).
+        * @cfg {boolean} [validateTitle=true] Whether the input must be a valid title
+        * @cfg {boolean} [required=false] Whether the input must not be empty
         * @cfg {Object} [cache] Result cache which implements a 'set' method, taking keyed values as an argument
         * @cfg {mw.Api} [api] API object to use, creates a default mw.Api instance if not specified
         */
         * @return {boolean} The query is valid
         */
        mw.widgets.TitleWidget.prototype.isQueryValid = function () {
-               return this.validateTitle ? !!this.getMWTitle() : true;
+               if ( !this.validateTitle ) {
+                       return true;
+               }
+               if ( !this.required && this.getQueryValue() === '' ) {
+                       return true;
+               }
+               return !!this.getMWTitle();
        };
 
 }( jQuery, mediaWiki ) );
index 1e008ee..4730005 100644 (file)
@@ -16,7 +16,9 @@ class FirejailCommandIntegrationTest extends PHPUnit\Framework\TestCase {
 
        public function setUp() {
                parent::setUp();
-               if ( Shell::command( 'which', 'firejail' )->execute()->getExitCode() ) {
+               if ( Shell::isDisabled() ) {
+                       $this->markTestSkipped( 'shelling out is disabled' );
+               } elseif ( Shell::command( 'which', 'firejail' )->execute()->getExitCode() ) {
                        $this->markTestSkipped( 'firejail not installed' );
                } elseif ( wfIsWindows() ) {
                        $this->markTestSkipped( 'test supports POSIX environments only' );
index e06a732..0b12c84 100644 (file)
@@ -2272,6 +2272,83 @@ hi
 <link rel="mw:PageProp/Category" href="./Category:Ho" />
 !! end
 
+!! test
+Paragraph wrapping following unclosed table
+!! options
+parsoid=wt2html,html2html
+!! wikitext
+{|
+|-
+
+{|
+| x
+|}
+
+a
+
+b
+
+c
+!! html/php+tidy
+<table>
+
+
+</table><table>
+<tbody><tr>
+<td>x
+</td></tr></tbody></table>
+<p>a
+</p><p>b
+</p><p>c
+</p>
+!! html/parsoid
+<table data-parsoid='{"autoInsertedEnd":true}'>
+<tbody><tr class="mw-empty-elt" data-parsoid='{"startTagSrc":"|-"}'></tr>
+
+</tbody></table><table>
+<tbody><tr data-parsoid='{"autoInsertedStart":true}'><td>x</td></tr>
+</tbody></table>
+
+<p>a</p>
+
+<p>b</p>
+
+<p>c</p>
+!! end
+
+!! test
+Paragraph wrapping suppressed in html p
+!! options
+parsoid=wt2html,html2html
+!! wikitext
+<p>
+
+
+hi
+
+
+
+</p>
+!! html/php+tidy
+<p>
+
+
+hi
+
+
+
+</p>
+!! html/parsoid
+<p data-parsoid='{"stx":"html"}'>
+
+
+hi
+
+
+
+</p>
+!! end
+
 ###
 ### Preformatted text
 ###
 a
 <table></table>
 !! html/parsoid
-<p data-parsoid='{"fostered":true,"autoInsertedEnd":true}'>a</p><table>
-<tbody><tr data-parsoid='{"startTagSrc":"|-","autoInsertedEnd":true}'>
-
-</tr></tbody></table>
+<span data-parsoid='{"fostered":true,"autoInsertedEnd":true,"autoInsertedStart":true}'>
+a
+</span><table>
+<tbody><tr class="mw-empty-elt" data-parsoid='{"startTagSrc":"|-"}'></tr></tbody></table>
 !! end
 
 !! test
@@ -12786,16 +12863,22 @@ Templates: Block Tags: 2. Back-to-back template uses
 
 !!end
 
-# This is an edge case relating to paragraph wrapping.
-!!test
+## This is an edge case relating to paragraph wrapping.
+## Note that Parsoid fails to match Remex because it's using the closing tag
+## as a heuristic to determine if it's in a block, rather than SAX based events.
+!! test
 Templates: Correctly encapsulate templates producing </p> tag without a corresponding <p> tag
 !! wikitext
 {{echo|a
 b</p>}}
+!! html/php+tidy
+<p>a
+</p><p>
+b</p><p class="mw-empty-elt"></p>
 !! html/parsoid
-<p about="#mwt1" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"a\nb&lt;/p>"}},"i":0}}]}'>a
-b</p>
-!!end
+<p about="#mwt1" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"a\nb&lt;/p>"}},"i":0}}]}'>a</p><span about="#mwt1">
+</span><span about="#mwt1">b</span><p about="#mwt1" data-parsoid='{"autoInsertedStart":true,"stx":"html"}'></p>
+!! end
 
 !!test
 Templates: Links: 1. Simple example
@@ -13164,13 +13247,13 @@ parsoid=wt2html,wt2wt
 <link rel="mw:PageProp/Category" href="./Category:Bar1"><link rel="mw:PageProp/Category" href="./Category:Bar2"><table><tbody><tr><td>foo</td></tr></tbody></table>
 !!end
 
-!!test
+!! test
 Templates: Wiki Tables: 1a. Fostering of entire template content
 !! wikitext
 {|
 {{echo|a}}
 |}
-!! html
+!! html/php
 <table>
 a
 <tr><td></td></tr></table>
 a
 <table><tbody><tr><td></td></tr></tbody></table>
 !! html/parsoid
-<p about="#mwt2" typeof="mw:Transclusion" data-parsoid='{"fostered":true,"autoInsertedEnd":true,"firstWikitextNode":"TABLE","pi":[[{"k":"1"}]]}' data-mw='{"parts":["{|\n",{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"a"}},"i":0}},"\n|}"]}'>a</p><table about="#mwt2">
+<span about="#mwt2" typeof="mw:Transclusion" data-parsoid='{"fostered":true,"autoInsertedEnd":true,"autoInsertedStart":true,"firstWikitextNode":"TABLE","pi":[[{"k":"1"}]]}' data-mw='{"parts":["{|\n",{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"a"}},"i":0}},"\n|}"]}'>a</span><table about="#mwt2">
 
 </table>
 !! end
@@ -13216,14 +13299,14 @@ foo
 </table>
 !! end
 
-!!test
+!! test
 Templates: Wiki Tables: 2. Fostering of partial template content
 !! wikitext
 {|
 {{echo|a
 <div>b</div>}}
 |}
-!! html
+!! html/php
 <table>
 a
 <div>b</div>
 <div>b</div><table>
 <tbody><tr><td></td></tr></tbody></table>
 !! html/parsoid
-<p about="#mwt2" typeof="mw:Transclusion" data-parsoid='{"fostered":true,"autoInsertedEnd":true,"firstWikitextNode":"TABLE","pi":[[{"k":"1"}]]}' data-mw='{"parts":["{|\n",{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"a\n&lt;div>b&lt;/div>"}},"i":0}},"\n|}"]}'>a</p><div about="#mwt2">b</div><table about="#mwt2">
+<span about="#mwt2" typeof="mw:Transclusion" data-parsoid='{"fostered":true,"autoInsertedEnd":true,"autoInsertedStart":true,"firstWikitextNode":"TABLE","pi":[[{"k":"1"}]]}' data-mw='{"parts":["{|\n",{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"a\n&lt;div>b&lt;/div>"}},"i":0}},"\n|}"]}'>a</span><div about="#mwt2">b</div><table about="#mwt2">
 
 
 </table>
@@ -22099,11 +22182,11 @@ conversion:
 
 ==Latinski==
 !! html/php
-<h2><span id="-.7BNaslov.7D-"></span><span class="mw-headline" id="-{Naslov}-">Naslov</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=1" title="Уреди одељак „Naslov“">уреди</a><span class="mw-editsection-bracket">]</span></span></h2>
+<h2><span id="-.7BNaslov.7D-"></span><span class="mw-headline" id="-{Naslov}-">Naslov</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=1" title="Уредите одељак „Naslov“">уреди</a><span class="mw-editsection-bracket">]</span></span></h2>
 <p>Ноте тхат евен ан унпротецтед хеадлине ИД ис нот аффецтед бy лангуаге
 цонверсион:
 </p>
-<h2><span class="mw-headline" id="Latinski">Латински</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=2" title="Уреди одељак „Латински“">уреди</a><span class="mw-editsection-bracket">]</span></span></h2>
+<h2><span class="mw-headline" id="Latinski">Латински</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=2" title="Уредите одељак „Латински“">уреди</a><span class="mw-editsection-bracket">]</span></span></h2>
 
 !! html/parsoid
 <h2 id="-{Naslov}-"><span id="-.7BNaslov.7D-" typeof="mw:FallbackId"></span><span typeof="mw:LanguageVariant" data-mw-variant='{"disabled":{"t":"Naslov"}}'></span></h2>
@@ -22871,7 +22954,7 @@ language=sr
 !! wikitext
 [[Датотека:Foobar.jpg|thumb|-{R|caption:}-]]
 !! html/php
-<div class="thumb tright"><div class="thumbinner" style="width:182px;"><a href="/wiki/%D0%94%D0%B0%D1%82%D0%BE%D1%82%D0%B5%D0%BA%D0%B0:Foobar.jpg" class="image"><img alt="" src="http://example.com/images/thumb/3/3a/Foobar.jpg/180px-Foobar.jpg" width="180" height="20" class="thumbimage" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/270px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/360px-Foobar.jpg 2x" /></a>  <div class="thumbcaption"><div class="magnify"><a href="/wiki/%D0%94%D0%B0%D1%82%D0%BE%D1%82%D0%B5%D0%BA%D0%B0:Foobar.jpg" class="internal" title="Повећај"></a></div>caption:</div></div></div>
+<div class="thumb tright"><div class="thumbinner" style="width:182px;"><a href="/wiki/%D0%94%D0%B0%D1%82%D0%BE%D1%82%D0%B5%D0%BA%D0%B0:Foobar.jpg" class="image"><img alt="" src="http://example.com/images/thumb/3/3a/Foobar.jpg/180px-Foobar.jpg" width="180" height="20" class="thumbimage" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/270px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/360px-Foobar.jpg 2x" /></a>  <div class="thumbcaption"><div class="magnify"><a href="/wiki/%D0%94%D0%B0%D1%82%D0%BE%D1%82%D0%B5%D0%BA%D0%B0:Foobar.jpg" class="internal" title="Повећајте"></a></div>caption:</div></div></div>
 
 !! html/parsoid
 <figure class="mw-default-size" typeof="mw:Image/Thumb" data-parsoid='{"optList":[{"ck":"thumbnail","ak":"thumb"}]}'><a href="./Датотека:Foobar.jpg"><img resource="./Датотека:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/220px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="25" width="220"/></a><figcaption><span typeof="mw:LanguageVariant" data-mw-variant='{"disabled":{"t":"caption:"}}' data-parsoid='{"fl":["R"]}'></span></figcaption></figure>
@@ -23415,7 +23498,12 @@ Line two
 
 !! end
 
-# FIXME: Why does/should the blockquote+div combo suppress p-wrapping here?
+## This is a corner case interaction between the paragraph wrapping in the
+## php parser's BlockLevelPass and Remex.  `doBlockLevels` has a notion of
+## some tags which close paragraphs (and thus prevent wrapping on their line),
+## of which "div" is one, but do p-wrapping inside them.  These are referred
+## to as "never suppressing".  Remex, for its part, doesn't traverse into
+## "div"s to p-wrap.  Hence, we only get this partial wrapping.
 !! test
 Paragraphs inside blockquotes/divs (no extra line breaks)
 !! wikitext
index 4140c23..e8ab412 100644 (file)
@@ -1043,7 +1043,16 @@ abstract class MediaWikiTestCase extends PHPUnit\Framework\TestCase {
         * @since 1.18
         */
        public function dbPrefix() {
-               return $this->db->getType() == 'oracle' ? self::ORA_DB_PREFIX : self::DB_PREFIX;
+               return self::getTestPrefixFor( $this->db );
+       }
+
+       /**
+        * @param IDatabase $db
+        * @return string
+        * @since 1.32
+        */
+       public static function getTestPrefixFor( IDatabase $db ) {
+               return $db->getType() == 'oracle' ? self::ORA_DB_PREFIX : self::DB_PREFIX;
        }
 
        /**
@@ -1075,12 +1084,14 @@ abstract class MediaWikiTestCase extends PHPUnit\Framework\TestCase {
         * @param string|Title $pageName Page name or title
         * @param string $text Page's content
         * @param int $namespace Namespace id (name cannot already contain namespace)
+        * @param User $user If null, static::getTestSysop()->getUser() is used.
         * @return array Title object and page id
         */
        protected function insertPage(
                $pageName,
                $text = 'Sample page for unit test.',
-               $namespace = null
+               $namespace = null,
+               User $user = null
        ) {
                if ( is_string( $pageName ) ) {
                        $title = Title::newFromText( $pageName, $namespace );
@@ -1088,7 +1099,9 @@ abstract class MediaWikiTestCase extends PHPUnit\Framework\TestCase {
                        $title = $pageName;
                }
 
-               $user = static::getTestSysop()->getUser();
+               if ( !$user ) {
+                       $user = static::getTestSysop()->getUser();
+               }
                $comment = __METHOD__ . ': Sample page for unit test.';
 
                $page = WikiPage::factory( $title );
@@ -1222,33 +1235,95 @@ abstract class MediaWikiTestCase extends PHPUnit\Framework\TestCase {
        }
 
        /**
-        * Setups a database with the given prefix.
+        * Prepares the given database connection for usage in the context of usage tests.
+        * This sets up clones database tables and changes the table prefix as appropriate.
+        * If the database connection already has cloned tables, calling this method has no
+        * effect. The tables are not re-cloned or reset in that case.
+        *
+        * @param IMaintainableDatabase $db
+        */
+       protected function prepareConnectionForTesting( IMaintainableDatabase $db ) {
+               if ( !self::$dbSetup ) {
+                       throw new LogicException(
+                               'Cannot use prepareConnectionForTesting()'
+                               . ' if the test case is not defined to use the database!'
+                       );
+               }
+
+               if ( isset( $db->_originalTablePrefix ) ) {
+                       // The DB connection was already prepared for testing.
+                       return;
+               }
+
+               $testPrefix = self::getTestPrefixFor( $db );
+               $oldPrefix = $db->tablePrefix();
+
+               $tablesCloned = self::listTables( $db );
+
+               if ( $oldPrefix === $testPrefix ) {
+                       // The database connection already has the test prefix, but presumably not
+                       // the cloned tables. This is the typical case, since the LBFactory will
+                       // have the prefix set during testing, but LoadBalancers will still return
+                       // connections that don't have the cloned table structure.
+                       $oldPrefix = self::$oldTablePrefix;
+               }
+
+               $dbClone = new CloneDatabase( $db, $tablesCloned, $testPrefix, $oldPrefix );
+               $dbClone->useTemporaryTables( self::$useTemporaryTables );
+
+               $db->_originalTablePrefix = $oldPrefix;
+
+               if ( ( $db->getType() == 'oracle' || !self::$useTemporaryTables ) && self::$reuseDB ) {
+                       throw new LogicException( 'Cannot clone database tables' );
+               } else {
+                       $dbClone->cloneTableStructure();
+               }
+       }
+
+       /**
+        * Setups a database with cloned tables using the given prefix.
         *
         * If reuseDB is true and certain conditions apply, it will just change the prefix.
         * Otherwise, it will clone the tables and change the prefix.
         *
-        * Clones all tables in the given database (whatever database that connection has
-        * open), to versions with the test prefix.
-        *
         * @param IMaintainableDatabase $db Database to use
-        * @param string $prefix Prefix to use for test tables
+        * @param string $prefix Prefix to use for test tables. If not given, the prefix is determined
+        *        automatically for $db.
         * @return bool True if tables were cloned, false if only the prefix was changed
         */
-       protected static function setupDatabaseWithTestPrefix( IMaintainableDatabase $db, $prefix ) {
-               $tablesCloned = self::listTables( $db );
-               $dbClone = new CloneDatabase( $db, $tablesCloned, $prefix );
-               $dbClone->useTemporaryTables( self::$useTemporaryTables );
-
-               $db->_originalTablePrefix = $db->tablePrefix();
+       protected static function setupDatabaseWithTestPrefix(
+               IMaintainableDatabase $db,
+               $prefix = null
+       ) {
+               if ( $prefix === null ) {
+                       $prefix = self::getTestPrefixFor( $db );
+               }
 
                if ( ( $db->getType() == 'oracle' || !self::$useTemporaryTables ) && self::$reuseDB ) {
-                       CloneDatabase::changePrefix( $prefix );
-
+                       $db->tablePrefix( $prefix );
                        return false;
-               } else {
+               }
+
+               if ( !isset( $db->_originalTablePrefix ) ) {
+                       $oldPrefix = $db->tablePrefix();
+
+                       if ( $oldPrefix === $prefix ) {
+                               // table already has the correct prefix, but presumably no cloned tables
+                               $oldPrefix = self::$oldTablePrefix;
+                       }
+
+                       $db->tablePrefix( $oldPrefix );
+                       $tablesCloned = self::listTables( $db );
+                       $dbClone = new CloneDatabase( $db, $tablesCloned, $prefix, $oldPrefix );
+                       $dbClone->useTemporaryTables( self::$useTemporaryTables );
+
                        $dbClone->cloneTableStructure();
-                       return true;
+
+                       $db->tablePrefix( $prefix );
+                       $db->_originalTablePrefix = $oldPrefix;
                }
+
+               return true;
        }
 
        /**
@@ -1267,6 +1342,10 @@ abstract class MediaWikiTestCase extends PHPUnit\Framework\TestCase {
                if ( self::isUsingExternalStoreDB() ) {
                        self::setupExternalStoreTestDBs( $testPrefix );
                }
+
+               // NOTE: Change the prefix in the LBFactory and $wgDBprefix, to prevent
+               // *any* database connections to operate on live data.
+               CloneDatabase::changePrefix( $testPrefix );
        }
 
        /**
@@ -1321,19 +1400,12 @@ abstract class MediaWikiTestCase extends PHPUnit\Framework\TestCase {
        /**
         * Clones the External Store database(s) for testing
         *
-        * @param string $testPrefix Prefix for test tables
+        * @param string|null $testPrefix Prefix for test tables. Will be determined automatically
+        *        if not given.
         */
-       protected static function setupExternalStoreTestDBs( $testPrefix ) {
+       protected static function setupExternalStoreTestDBs( $testPrefix = null ) {
                $connections = self::getExternalStoreDatabaseConnections();
                foreach ( $connections as $dbw ) {
-                       // Hack: cloneTableStructure sets $wgDBprefix to the unit test
-                       // prefix,.  Even though listTables now uses tablePrefix, that
-                       // itself is populated from $wgDBprefix by default.
-
-                       // We have to set it back, or we won't find the original 'blobs'
-                       // table to copy.
-
-                       $dbw->tablePrefix( self::$oldTablePrefix );
                        self::setupDatabaseWithTestPrefix( $dbw, $testPrefix );
                }
        }
@@ -1712,6 +1784,29 @@ abstract class MediaWikiTestCase extends PHPUnit\Framework\TestCase {
                return $tables;
        }
 
+       /**
+        * Copy test data from one database connection to another.
+        *
+        * This should only be used for small data sets.
+        *
+        * @param IDatabase $source
+        * @param IDatabase $target
+        */
+       public function copyTestData( IDatabase $source, IDatabase $target ) {
+               $tables = self::listOriginalTables( $source, 'unprefixed' );
+
+               foreach ( $tables as $table ) {
+                       $res = $source->select( $table, '*', [], __METHOD__ );
+                       $allRows = [];
+
+                       foreach ( $res as $row ) {
+                               $allRows[] = (array)$row;
+                       }
+
+                       $target->insert( $table, $allRows, __METHOD__, [ 'IGNORE' ] );
+               }
+       }
+
        /**
         * @throws MWException
         * @since 1.18
index 15e2def..1b91a87 100644 (file)
@@ -575,4 +575,34 @@ class MWNamespaceTest extends MediaWikiTestCase {
        private function assertDifferentSubject( $ns1, $ns2, $msg = '' ) {
                $this->assertFalse( MWNamespace::subjectEquals( $ns1, $ns2 ), $msg );
        }
+
+       public function provideGetCategoryLinkType() {
+               return [
+                       [ NS_MAIN, 'page' ],
+                       [ NS_TALK, 'page' ],
+                       [ NS_USER, 'page' ],
+                       [ NS_USER_TALK, 'page' ],
+
+                       [ NS_FILE, 'file' ],
+                       [ NS_FILE_TALK, 'page' ],
+
+                       [ NS_CATEGORY, 'subcat' ],
+                       [ NS_CATEGORY_TALK, 'page' ],
+
+                       [ 100, 'page' ],
+                       [ 101, 'page' ],
+               ];
+       }
+
+       /**
+        * @dataProvider provideGetCategoryLinkType
+        * @covers MWNamespace::getCategoryLinkType
+        *
+        * @param int $index
+        * @param string $expected
+        */
+       public function testGetCategoryLinkType( $index, $expected ) {
+               $actual = MWNamespace::getCategoryLinkType( $index );
+               $this->assertSame( $expected, $actual, "NS $index" );
+       }
 }
index 93c7ed3..093cb07 100644 (file)
@@ -5,6 +5,7 @@ use MediaWiki\Interwiki\InterwikiLookup;
 use MediaWiki\Linker\LinkRenderer;
 use MediaWiki\Linker\LinkRendererFactory;
 use MediaWiki\MediaWikiServices;
+use MediaWiki\Preferences\PreferencesFactory;
 use MediaWiki\Services\DestructibleService;
 use MediaWiki\Services\SalvageableService;
 use MediaWiki\Services\ServiceDisabledException;
@@ -12,6 +13,7 @@ use MediaWiki\Shell\CommandFactory;
 use MediaWiki\Storage\BlobStore;
 use MediaWiki\Storage\BlobStoreFactory;
 use MediaWiki\Storage\NameTableStore;
+use MediaWiki\Storage\RevisionFactory;
 use MediaWiki\Storage\RevisionLookup;
 use MediaWiki\Storage\RevisionStore;
 use MediaWiki\Storage\SqlBlobStore;
@@ -305,8 +307,6 @@ class MediaWikiServicesTest extends MediaWikiTestCase {
 
        public function provideGetService() {
                // NOTE: This should list all service getters defined in ServiceWiring.php.
-               // NOTE: For every test case defined here there should be a corresponding
-               // test case defined in provideGetters().
                return [
                        'BootstrapConfig' => [ 'BootstrapConfig', Config::class ],
                        'ConfigFactory' => [ 'ConfigFactory', ConfigFactory::class ],
@@ -314,6 +314,8 @@ class MediaWikiServicesTest extends MediaWikiTestCase {
                        'SiteStore' => [ 'SiteStore', SiteStore::class ],
                        'SiteLookup' => [ 'SiteLookup', SiteLookup::class ],
                        'StatsdDataFactory' => [ 'StatsdDataFactory', IBufferingStatsdDataFactory::class ],
+                       'PerDbNameStatsdDataFactory' =>
+                               [ 'PerDbNameStatsdDataFactory', IBufferingStatsdDataFactory::class ],
                        'InterwikiLookup' => [ 'InterwikiLookup', InterwikiLookup::class ],
                        'EventRelayerGroup' => [ 'EventRelayerGroup', EventRelayerGroup::class ],
                        'SearchEngineFactory' => [ 'SearchEngineFactory', SearchEngineFactory::class ],
@@ -347,9 +349,21 @@ class MediaWikiServicesTest extends MediaWikiTestCase {
                        '_SqlBlobStore' => [ '_SqlBlobStore', SqlBlobStore::class ],
                        'RevisionStore' => [ 'RevisionStore', RevisionStore::class ],
                        'RevisionLookup' => [ 'RevisionLookup', RevisionLookup::class ],
+                       'RevisionFactory' => [ 'RevisionFactory', RevisionFactory::class ],
+                       'ContentModelStore' => [ 'ContentModelStore', NameTableStore::class ],
+                       'SlotRoleStore' => [ 'SlotRoleStore', NameTableStore::class ],
                        'HttpRequestFactory' => [ 'HttpRequestFactory', HttpRequestFactory::class ],
                        'CommentStore' => [ 'CommentStore', CommentStore::class ],
                        'ChangeTagDefStore' => [ 'ChangeTagDefStore', NameTableStore::class ],
+                       'ConfiguredReadOnlyMode' => [ 'ConfiguredReadOnlyMode', ConfiguredReadOnlyMode::class ],
+                       'ReadOnlyMode' => [ 'ReadOnlyMode', ReadOnlyMode::class ],
+                       'UploadRevisionImporter' => [ 'UploadRevisionImporter', UploadRevisionImporter::class ],
+                       'OldRevisionImporter' => [ 'OldRevisionImporter', OldRevisionImporter::class ],
+                       'WikiRevisionOldRevisionImporterNoUpdates' =>
+                               [ 'WikiRevisionOldRevisionImporterNoUpdates', ImportableOldRevisionImporter::class ],
+                       'ExternalStoreFactory' => [ 'ExternalStoreFactory', ExternalStoreFactory::class ],
+                       'PreferencesFactory' => [ 'PreferencesFactory', PreferencesFactory::class ],
+                       'ActorMigration' => [ 'ActorMigration', ActorMigration::class ],
                ];
        }
 
@@ -378,4 +392,15 @@ class MediaWikiServicesTest extends MediaWikiTestCase {
                }
        }
 
+       public function testDefaultServiceWiringServicesHaveTests() {
+               global $IP;
+               $testedServices = array_keys( $this->provideGetService() );
+               $allServices = array_keys( include $IP . '/includes/ServiceWiring.php' );
+               $this->assertEquals(
+                       [],
+                       array_diff( $allServices, $testedServices ),
+                       'The following services have not been added to MediaWikiServicesTest::provideGetService'
+               );
+       }
+
 }
index c984142..f03d403 100644 (file)
@@ -159,8 +159,8 @@ class McrWriteBothRevisionStoreDbTest extends RevisionStoreDbTestBase {
                                                'role_name' => $db->addQuotes( 'main' ),
                                                'content_size' => 'slots.rev_len',
                                                'content_sha1' => 'slots.rev_sha1',
-                                               'content_address' =>
-                                                       'CONCAT(' . $db->addQuotes( 'tt:' ) . ',slots.rev_text_id)',
+                                               'content_address' => $db->buildConcat( [
+                                                       $db->addQuotes( 'tt:' ), 'slots.rev_text_id' ] ),
                                                'model_name' => 'slots.rev_content_model',
                                        ]
                                ),
index 2337805..1d504de 100644 (file)
@@ -156,7 +156,7 @@ class NoContentModelRevisionStoreDbTest extends RevisionStoreDbTestBase {
                                                'content_size' => 'slots.rev_len',
                                                'content_sha1' => 'slots.rev_sha1',
                                                'content_address' =>
-                                                       'CONCAT(' . $db->addQuotes( 'tt:' ) . ',slots.rev_text_id)',
+                                                       $db->buildConcat( [ $db->addQuotes( 'tt:' ), 'slots.rev_text_id' ] ),
                                                'model_name' => 'NULL',
                                        ]
                                ),
index a27d2bb..7cc3131 100644 (file)
@@ -130,7 +130,7 @@ class PreMcrRevisionStoreDbTest extends RevisionStoreDbTestBase {
                                                'content_size' => 'slots.rev_len',
                                                'content_sha1' => 'slots.rev_sha1',
                                                'content_address' =>
-                                                       'CONCAT(' . $db->addQuotes( 'tt:' ) . ',slots.rev_text_id)',
+                                                       $db->buildConcat( [ $db->addQuotes( 'tt:' ), 'slots.rev_text_id' ] ),
                                                'model_name' => 'slots.rev_content_model',
                                        ]
                                ),
index cf605c1..d6b43e5 100644 (file)
@@ -190,32 +190,38 @@ class LoadBalancerTest extends MediaWikiTestCase {
 
        private function assertWriteAllowed( Database $db ) {
                $table = $db->tableName( 'some_table' );
+               // Trigger a transaction so that rollback() will remove all the tables.
+               // Don't do this for MySQL/Oracle as they auto-commit transactions for DDL
+               // statements such as CREATE TABLE.
+               $useAtomicSection = in_array( $db->getType(), [ 'sqlite', 'postgres', 'mssql' ], true );
                try {
                        $db->dropTable( 'some_table' ); // clear for sanity
+                       $this->assertNotEquals( $db::STATUS_TRX_ERROR, $db->trxStatus() );
 
-                       // Trigger DBO_TRX to create a transaction so the flush below will
-                       // roll everything here back in sqlite. But don't actually do the
-                       // code below inside an atomic section becaue MySQL and Oracle
-                       // auto-commit transactions for DDL statements like CREATE TABLE.
-                       $db->startAtomic( __METHOD__ );
-                       $db->endAtomic( __METHOD__ );
-
+                       if ( $useAtomicSection ) {
+                               $db->startAtomic( __METHOD__ );
+                       }
                        // Use only basic SQL and trivial types for these queries for compatibility
                        $this->assertNotSame(
                                false,
                                $db->query( "CREATE TABLE $table (id INT, time INT)", __METHOD__ ),
                                "table created"
                        );
+                       $this->assertNotEquals( $db::STATUS_TRX_ERROR, $db->trxStatus() );
                        $this->assertNotSame(
                                false,
                                $db->query( "DELETE FROM $table WHERE id=57634126", __METHOD__ ),
                                "delete query"
                        );
+                       $this->assertNotEquals( $db::STATUS_TRX_ERROR, $db->trxStatus() );
                } finally {
-                       // Drop the table to clean up, ignoring any error.
-                       $db->query( "DROP TABLE $table", __METHOD__, true );
-                       // Rollback the DBO_TRX transaction for sqlite's benefit.
+                       if ( !$useAtomicSection ) {
+                               // Drop the table to clean up, ignoring any error.
+                               $db->dropTable( 'some_table' );
+                       }
+                       // Rollback the atomic section for sqlite's benefit.
                        $db->rollback( __METHOD__, 'flush' );
+                       $this->assertNotEquals( $db::STATUS_TRX_ERROR, $db->trxStatus() );
                }
        }
 
index 2a962b7..79f7b96 100644 (file)
@@ -11,11 +11,14 @@ class MapCacheLRUTest extends PHPUnit\Framework\TestCase {
         * @covers MapCacheLRU::toArray()
         * @covers MapCacheLRU::getAllKeys()
         * @covers MapCacheLRU::clear()
+        * @covers MapCacheLRU::getMaxSize()
+        * @covers MapCacheLRU::setMaxSize()
         */
        function testArrayConversion() {
                $raw = [ 'd' => 4, 'c' => 3, 'b' => 2, 'a' => 1 ];
                $cache = MapCacheLRU::newFromArray( $raw, 3 );
 
+               $this->assertEquals( 3, $cache->getMaxSize() );
                $this->assertSame( true, $cache->has( 'a' ) );
                $this->assertSame( true, $cache->has( 'b' ) );
                $this->assertSame( true, $cache->has( 'c' ) );
@@ -43,6 +46,27 @@ class MapCacheLRUTest extends PHPUnit\Framework\TestCase {
                        [],
                        $cache->toArray()
                );
+
+               $cache = MapCacheLRU::newFromArray( [ 'd' => 4, 'c' => 3, 'b' => 2, 'a' => 1 ], 4 );
+               $cache->setMaxSize( 3 );
+               $this->assertSame(
+                       [ 'c' => 3, 'b' => 2, 'a' => 1 ],
+                       $cache->toArray()
+               );
+       }
+
+       /**
+        * @covers MapCacheLRU::serialize()
+        * @covers MapCacheLRU::unserialize()
+        */
+       function testSerialize() {
+               $cache = MapCacheLRU::newFromArray( [ 'd' => 4, 'c' => 3, 'b' => 2, 'a' => 1 ], 10 );
+               $string = serialize( $cache );
+               $ncache = unserialize( $string );
+               $this->assertSame(
+                       [ 'd' => 4, 'c' => 3, 'b' => 2, 'a' => 1 ],
+                       $ncache->toArray()
+               );
        }
 
        /**
@@ -114,4 +138,75 @@ class MapCacheLRUTest extends PHPUnit\Framework\TestCase {
                        $cache->toArray()
                );
        }
+
+       /**
+        * @covers MapCacheLRU::has()
+        * @covers MapCacheLRU::get()
+        * @covers MapCacheLRU::set()
+        */
+       public function testExpiry() {
+               $raw = [ 'a' => 1, 'b' => 2, 'c' => 3 ];
+               $cache = MapCacheLRU::newFromArray( $raw, 3 );
+
+               $now = microtime( true );
+               $cache->setMockTime( $now );
+
+               $cache->set( 'd', 'xxx' );
+               $this->assertTrue( $cache->has( 'd', 30 ) );
+               $this->assertEquals( 'xxx', $cache->get( 'd' ) );
+
+               $now += 29;
+               $this->assertTrue( $cache->has( 'd', 30 ) );
+               $this->assertEquals( 'xxx', $cache->get( 'd' ) );
+
+               $now += 1.5;
+               $this->assertFalse( $cache->has( 'd', 30 ) );
+               $this->assertEquals( 'xxx', $cache->get( 'd' ) );
+       }
+
+       /**
+        * @covers MapCacheLRU::hasField()
+        * @covers MapCacheLRU::getField()
+        * @covers MapCacheLRU::setField()
+        */
+       public function testFields() {
+               $raw = [ 'a' => 1, 'b' => 2, 'c' => 3 ];
+               $cache = MapCacheLRU::newFromArray( $raw, 3 );
+
+               $now = microtime( true );
+               $cache->setMockTime( $now );
+
+               $cache->setField( 'PMs', 'Tony Blair', 'Labour' );
+               $cache->setField( 'PMs', 'Margaret Thatcher', 'Tory' );
+               $this->assertTrue( $cache->hasField( 'PMs', 'Tony Blair', 30 ) );
+               $this->assertEquals( 'Labour', $cache->getField( 'PMs', 'Tony Blair' ) );
+
+               $now += 29;
+               $this->assertTrue( $cache->hasField( 'PMs', 'Tony Blair', 30 ) );
+               $this->assertEquals( 'Labour', $cache->getField( 'PMs', 'Tony Blair' ) );
+
+               $now += 1.5;
+               $this->assertFalse( $cache->hasField( 'PMs', 'Tony Blair', 30 ) );
+               $this->assertEquals( 'Labour', $cache->getField( 'PMs', 'Tony Blair' ) );
+
+               $this->assertEquals(
+                       [ 'Tony Blair' => 'Labour', 'Margaret Thatcher' => 'Tory' ],
+                       $cache->get( 'PMs' )
+               );
+
+               $cache->set( 'MPs', [
+                       'Edwina Currie' => 1983,
+                       'Neil Kinnock' => 1970
+               ] );
+               $this->assertEquals(
+                       [
+                               'Edwina Currie' => 1983,
+                               'Neil Kinnock' => 1970
+                       ],
+                       $cache->get( 'MPs' )
+               );
+
+               $this->assertEquals( 1983, $cache->getField( 'MPs', 'Edwina Currie' ) );
+               $this->assertEquals( 1970, $cache->getField( 'MPs', 'Neil Kinnock' ) );
+       }
 }
index c8940e5..c9fa320 100644 (file)
@@ -18,7 +18,7 @@ class ProcessCacheLRUTest extends PHPUnit\Framework\TestCase {
         * Compare against an array so we get the cache content difference.
         */
        protected function assertCacheEmpty( $cache, $msg = 'Cache should be empty' ) {
-               $this->assertAttributeEquals( [], 'cache', $cache, $msg );
+               $this->assertEquals( 0, $cache->getEntriesCount(), $msg );
        }
 
        /**
@@ -256,13 +256,11 @@ class ProcessCacheLRUTest extends PHPUnit\Framework\TestCase {
  * Overrides some ProcessCacheLRU methods and properties accessibility.
  */
 class ProcessCacheLRUTestable extends ProcessCacheLRU {
-       public $cache = [];
-
        public function getCache() {
-               return $this->cache;
+               return $this->cache->toArray();
        }
 
        public function getEntriesCount() {
-               return count( $this->cache );
+               return count( $this->cache->toArray() );
        }
 }
index 4a9f6cc..8a95ae7 100644 (file)
@@ -137,4 +137,13 @@ class MultiWriteBagOStuffTest extends MediaWikiTestCase {
 
                $this->assertSame( 'special', $cache->makeGlobalKey( 'a', 'b' ) );
        }
+
+       public function testDuplicateStoreAdd() {
+               $bag = new HashBagOStuff();
+               $cache = new MultiWriteBagOStuff( [
+                       'caches' => [ $bag, $bag ],
+               ] );
+
+               $this->assertTrue( $cache->add( 'key', 1, 30 ) );
+       }
 }
index c12882b..8f4aae3 100644 (file)
@@ -440,6 +440,7 @@ class DatabaseTest extends PHPUnit\Framework\TestCase {
                        'numFields', 'numRows',
                        'open',
                        'strencode',
+                       'tableExists'
                ];
                $db = $this->getMockBuilder( Database::class )
                        ->disableOriginalConstructor()
index 63cf02f..e0364c4 100644 (file)
@@ -1,5 +1,6 @@
 <?php
 
+use MediaWiki\MediaWikiServices;
 use MediaWiki\Storage\RevisionSlotsUpdate;
 use Wikimedia\TestingAccessWrapper;
 
@@ -1028,6 +1029,9 @@ more stuff
                // Use the confirmed group for user2 to make sure the user is different
                $user2 = $this->getTestUser( [ 'confirmed' ] )->getUser();
 
+               // make sure we can test autopatrolling
+               $this->setMwGlobals( 'wgUseRCPatrol', true );
+
                // TODO: MCR: test rollback of multiple slots!
                $page = $this->newPage( __METHOD__ );
 
@@ -1085,61 +1089,21 @@ more stuff
                        "rollback did not revert to the correct revision" );
                $this->assertEquals( "one\n\ntwo", $page->getContent()->getNativeData() );
 
-               // TODO: MCR: assert origin once we write slot data
-               // $mainSlot = $page->getRevision()->getRevisionRecord()->getSlot( 'main' );
-               // $this->assertTrue( $mainSlot->isInherited(), 'isInherited' );
-               // $this->assertSame( $rev2->getId(), $mainSlot->getOrigin(), 'getOrigin' );
-       }
-
-       /**
-        * @covers WikiPage::doRollback
-        * @covers WikiPage::commitRollback
-        */
-       public function testDoRollback_simple() {
-               $admin = $this->getTestSysop()->getUser();
-
-               $text = "one";
-               $page = $this->newPage( __METHOD__ );
-               $page->doEditContent(
-                       ContentHandler::makeContent( $text, $page->getTitle(), CONTENT_MODEL_WIKITEXT ),
-                       "section one",
-                       EDIT_NEW,
-                       false,
-                       $admin
-               );
-               $rev1 = $page->getRevision();
-
-               $user1 = $this->getTestUser()->getUser();
-               $text .= "\n\ntwo";
-               $page = new WikiPage( $page->getTitle() );
-               $page->doEditContent(
-                       ContentHandler::makeContent( $text, $page->getTitle(), CONTENT_MODEL_WIKITEXT ),
-                       "adding section two",
-                       0,
-                       false,
-                       $user1
+               $rc = MediaWikiServices::getInstance()->getRevisionStore()->getRecentChange(
+                       $page->getRevision()->getRevisionRecord()
                );
 
-               # now, try the rollback
-               $token = $admin->getEditToken( 'rollback' );
-               $errors = $page->doRollback(
-                       $user1->getName(),
-                       "testing revert",
-                       $token,
-                       false,
-                       $details,
-                       $admin
+               $this->assertNotNull( $rc, 'RecentChanges entry' );
+               $this->assertEquals(
+                       RecentChange::PRC_AUTOPATROLLED,
+                       $rc->getAttribute( 'rc_patrolled' ),
+                       'rc_patrolled'
                );
 
-               if ( $errors ) {
-                       $this->fail( "Rollback failed:\n" . print_r( $errors, true )
-                               . ";\n" . print_r( $details, true ) );
-               }
-
-               $page = new WikiPage( $page->getTitle() );
-               $this->assertEquals( $rev1->getSha1(), $page->getRevision()->getSha1(),
-                       "rollback did not revert to the correct revision" );
-               $this->assertEquals( "one", $page->getContent()->getNativeData() );
+               // TODO: MCR: assert origin once we write slot data
+               // $mainSlot = $page->getRevision()->getRevisionRecord()->getSlot( 'main' );
+               // $this->assertTrue( $mainSlot->isInherited(), 'isInherited' );
+               // $this->assertSame( $rev2->getId(), $mainSlot->getOrigin(), 'getOrigin' );
        }
 
        /**
index fe1ebed..247c958 100644 (file)
@@ -1,5 +1,5 @@
 module.exports = {
        getTestString( prefix = '' ) {
-               return prefix + Math.random().toString() + '-Iñtërnâtiônàlizætiøn';
+               return prefix + Math.random().toString() + '-Iñtërnâtiônàlizætiøn';
        }
 };