Merge "RCLFilters: make sticky filters default and current value equal"
authorjenkins-bot <jenkins-bot@gerrit.wikimedia.org>
Fri, 16 Feb 2018 22:39:55 +0000 (22:39 +0000)
committerGerrit Code Review <gerrit@wikimedia.org>
Fri, 16 Feb 2018 22:39:55 +0000 (22:39 +0000)
347 files changed:
.travis.yml
Gruntfile.js
RELEASE-NOTES-1.31
autoload.php
composer.json
docs/globals.txt
includes/CategoryFinder.php
includes/DefaultSettings.php
includes/DevelopmentSettings.php [new file with mode: 0644]
includes/EditPage.php
includes/MovePage.php
includes/OutputPage.php
includes/Revision.php
includes/SiteStats.php
includes/SiteStatsInit.php [new file with mode: 0644]
includes/Storage/RevisionStore.php
includes/api/ApiFeedRecentChanges.php
includes/api/ApiParse.php
includes/api/i18n/ar.json
includes/api/i18n/ba.json
includes/api/i18n/de.json
includes/api/i18n/en.json
includes/api/i18n/es.json
includes/api/i18n/fr.json
includes/api/i18n/gl.json
includes/api/i18n/he.json
includes/api/i18n/hu.json
includes/api/i18n/it.json
includes/api/i18n/ksh.json
includes/api/i18n/lb.json
includes/api/i18n/lt.json
includes/api/i18n/mk.json
includes/api/i18n/nb.json
includes/api/i18n/pl.json
includes/api/i18n/pt-br.json
includes/api/i18n/pt.json
includes/api/i18n/qqq.json
includes/api/i18n/ru.json
includes/api/i18n/sv.json
includes/api/i18n/uk.json
includes/api/i18n/zh-hans.json
includes/cache/MessageCache.php
includes/changes/EnhancedChangesList.php
includes/db/DatabaseOracle.php
includes/deferred/DeferredUpdates.php
includes/deferred/SiteStatsUpdate.php
includes/diff/DifferenceEngine.php
includes/exception/MWException.php
includes/installer/Installer.php
includes/installer/i18n/ast.json
includes/installer/i18n/es-formal.json
includes/installer/i18n/ia.json
includes/installer/i18n/sv.json
includes/jobqueue/jobs/RecentChangesUpdateJob.php
includes/jobqueue/jobs/UserGroupExpiryJob.php [new file with mode: 0644]
includes/libs/objectcache/WANObjectCache.php
includes/libs/rdbms/database/Database.php
includes/libs/rdbms/database/DatabaseMssql.php
includes/libs/rdbms/database/DatabaseMysqlBase.php
includes/libs/rdbms/database/DatabaseMysqli.php
includes/libs/rdbms/database/DatabasePostgres.php
includes/libs/rdbms/database/DatabaseSqlite.php
includes/libs/rdbms/database/IDatabase.php
includes/libs/rdbms/database/position/MySQLMasterPos.php
includes/libs/rdbms/loadbalancer/ILoadBalancer.php
includes/libs/rdbms/loadbalancer/LoadBalancer.php
includes/page/Article.php
includes/page/WikiPage.php
includes/parser/Parser.php
includes/parser/ParserCache.php
includes/parser/ParserOptions.php
includes/parser/ParserOutput.php
includes/registration/ExtensionJsonValidator.php
includes/registration/ExtensionRegistry.php
includes/registration/VersionChecker.php
includes/resourceloader/ResourceLoaderModule.php
includes/sparql/SparqlClient.php [new file with mode: 0644]
includes/sparql/SparqlException.php [new file with mode: 0644]
includes/specials/SpecialLog.php
includes/specials/SpecialRecentchanges.php
includes/specials/SpecialUndelete.php
includes/user/UserGroupMembership.php
includes/watcheditem/NoWriteWatchedItemStore.php
includes/watcheditem/WatchedItemStoreInterface.php
languages/i18n/ace.json
languages/i18n/ady-cyrl.json
languages/i18n/af.json
languages/i18n/ais.json
languages/i18n/am.json
languages/i18n/an.json
languages/i18n/ang.json
languages/i18n/ar.json
languages/i18n/arc.json
languages/i18n/ary.json
languages/i18n/arz.json
languages/i18n/as.json
languages/i18n/ast.json
languages/i18n/avk.json
languages/i18n/awa.json
languages/i18n/az.json
languages/i18n/azb.json
languages/i18n/ba.json
languages/i18n/bar.json
languages/i18n/bcc.json
languages/i18n/bcl.json
languages/i18n/be-tarask.json
languages/i18n/be.json
languages/i18n/bg.json
languages/i18n/bgn.json
languages/i18n/bho.json
languages/i18n/bjn.json
languages/i18n/bn.json
languages/i18n/bo.json
languages/i18n/br.json
languages/i18n/bs.json
languages/i18n/bto.json
languages/i18n/ca.json
languages/i18n/ce.json
languages/i18n/ckb.json
languages/i18n/crh-cyrl.json
languages/i18n/crh-latn.json
languages/i18n/cs.json
languages/i18n/cu.json
languages/i18n/cv.json
languages/i18n/cy.json
languages/i18n/da.json
languages/i18n/de-ch.json
languages/i18n/de.json
languages/i18n/diq.json
languages/i18n/dsb.json
languages/i18n/dty.json
languages/i18n/egl.json
languages/i18n/el.json
languages/i18n/en.json
languages/i18n/eo.json
languages/i18n/es-formal.json
languages/i18n/es.json
languages/i18n/et.json
languages/i18n/eu.json
languages/i18n/ext.json
languages/i18n/fa.json
languages/i18n/fi.json
languages/i18n/fo.json
languages/i18n/fr.json
languages/i18n/frp.json
languages/i18n/frr.json
languages/i18n/fur.json
languages/i18n/fy.json
languages/i18n/ga.json
languages/i18n/gan-hans.json
languages/i18n/gan-hant.json
languages/i18n/gd.json
languages/i18n/gl.json
languages/i18n/gom-deva.json
languages/i18n/gom-latn.json
languages/i18n/grc.json
languages/i18n/gsw.json
languages/i18n/gu.json
languages/i18n/gv.json
languages/i18n/hak.json
languages/i18n/he.json
languages/i18n/hi.json
languages/i18n/hif-latn.json
languages/i18n/hil.json
languages/i18n/hr.json
languages/i18n/hrx.json
languages/i18n/hsb.json
languages/i18n/hu.json
languages/i18n/hy.json
languages/i18n/ia.json
languages/i18n/id.json
languages/i18n/ie.json
languages/i18n/ig.json
languages/i18n/ilo.json
languages/i18n/inh.json
languages/i18n/io.json
languages/i18n/is.json
languages/i18n/it.json
languages/i18n/ja.json
languages/i18n/jv.json
languages/i18n/ka.json
languages/i18n/kaa.json
languages/i18n/kab.json
languages/i18n/kk-arab.json
languages/i18n/kk-cyrl.json
languages/i18n/kk-latn.json
languages/i18n/km.json
languages/i18n/kn.json
languages/i18n/ko.json
languages/i18n/krc.json
languages/i18n/ksh.json
languages/i18n/ku-latn.json
languages/i18n/kum.json
languages/i18n/ky.json
languages/i18n/la.json
languages/i18n/lad.json
languages/i18n/lb.json
languages/i18n/lez.json
languages/i18n/lfn.json
languages/i18n/li.json
languages/i18n/lij.json
languages/i18n/lki.json
languages/i18n/lmo.json
languages/i18n/lrc.json
languages/i18n/lt.json
languages/i18n/lus.json
languages/i18n/lv.json
languages/i18n/lzh.json
languages/i18n/lzz.json
languages/i18n/mai.json
languages/i18n/map-bms.json
languages/i18n/mdf.json
languages/i18n/mg.json
languages/i18n/mk.json
languages/i18n/ml.json
languages/i18n/mn.json
languages/i18n/mr.json
languages/i18n/ms.json
languages/i18n/mt.json
languages/i18n/mwl.json
languages/i18n/my.json
languages/i18n/myv.json
languages/i18n/nah.json
languages/i18n/nan.json
languages/i18n/nap.json
languages/i18n/nb.json
languages/i18n/nds-nl.json
languages/i18n/nds.json
languages/i18n/ne.json
languages/i18n/nl-informal.json
languages/i18n/nl.json
languages/i18n/nn.json
languages/i18n/oc.json
languages/i18n/or.json
languages/i18n/os.json
languages/i18n/pa.json
languages/i18n/pam.json
languages/i18n/pdc.json
languages/i18n/pfl.json
languages/i18n/pl.json
languages/i18n/pms.json
languages/i18n/pnb.json
languages/i18n/pnt.json
languages/i18n/prg.json
languages/i18n/ps.json
languages/i18n/pt-br.json
languages/i18n/pt.json
languages/i18n/qqq.json
languages/i18n/qu.json
languages/i18n/rm.json
languages/i18n/ro.json
languages/i18n/roa-tara.json
languages/i18n/ru.json
languages/i18n/rue.json
languages/i18n/sa.json
languages/i18n/sah.json
languages/i18n/sc.json
languages/i18n/scn.json
languages/i18n/sco.json
languages/i18n/sd.json
languages/i18n/sdc.json
languages/i18n/se.json
languages/i18n/sei.json
languages/i18n/ses.json
languages/i18n/sgs.json
languages/i18n/sh.json
languages/i18n/shi.json
languages/i18n/shn.json
languages/i18n/si.json
languages/i18n/sk.json
languages/i18n/sl.json
languages/i18n/sli.json
languages/i18n/so.json
languages/i18n/sq.json
languages/i18n/sr-ec.json
languages/i18n/sr-el.json
languages/i18n/stq.json
languages/i18n/su.json
languages/i18n/sv.json
languages/i18n/sw.json
languages/i18n/szl.json
languages/i18n/ta.json
languages/i18n/tay.json
languages/i18n/tcy.json
languages/i18n/te.json
languages/i18n/tg-cyrl.json
languages/i18n/tg-latn.json
languages/i18n/th.json
languages/i18n/tk.json
languages/i18n/tl.json
languages/i18n/tly.json
languages/i18n/to.json
languages/i18n/tpi.json
languages/i18n/tr.json
languages/i18n/tt-cyrl.json
languages/i18n/tt-latn.json
languages/i18n/tzm.json
languages/i18n/ug-arab.json
languages/i18n/uk.json
languages/i18n/ur.json
languages/i18n/vec.json
languages/i18n/vep.json
languages/i18n/vi.json
languages/i18n/vo.json
languages/i18n/vro.json
languages/i18n/wa.json
languages/i18n/war.json
languages/i18n/wo.json
languages/i18n/xmf.json
languages/i18n/yi.json
languages/i18n/yo.json
languages/i18n/yue.json
languages/i18n/zea.json
languages/i18n/zh-hans.json
languages/i18n/zh-hant.json
maintenance/Maintenance.php
maintenance/findHooks.php
resources/Resources.php
resources/src/mediawiki.special/mediawiki.special.upload.js
resources/src/mediawiki/mediawiki.ForeignStructuredUpload.js
resources/src/startup.js
tests/phpunit/ResourceLoaderTestCase.php
tests/phpunit/data/registration/bad_spdx.json [new file with mode: 0644]
tests/phpunit/data/registration/good.json [new file with mode: 0644]
tests/phpunit/data/registration/invalid.json [new file with mode: 0644]
tests/phpunit/data/registration/newer_manifest_version.json [new file with mode: 0644]
tests/phpunit/data/registration/no_manifest_version.json [new file with mode: 0644]
tests/phpunit/data/registration/notjson.txt [new file with mode: 0644]
tests/phpunit/data/registration/old_manifest_version.json [new file with mode: 0644]
tests/phpunit/includes/SiteStatsTest.php
tests/phpunit/includes/db/DatabaseSqliteTest.php
tests/phpunit/includes/db/DatabaseTestHelper.php
tests/phpunit/includes/db/LBFactoryTest.php
tests/phpunit/includes/exception/BadTitleErrorTest.php
tests/phpunit/includes/exception/ThrottledErrorTest.php
tests/phpunit/includes/libs/rdbms/database/DatabaseMysqlBaseTest.php
tests/phpunit/includes/libs/rdbms/database/DatabaseTest.php
tests/phpunit/includes/parser/ParserOptionsTest.php
tests/phpunit/includes/parser/ParserOutputTest.php
tests/phpunit/includes/registration/ExtensionJsonValidatorTest.php [new file with mode: 0644]
tests/phpunit/includes/registration/ExtensionRegistryTest.php
tests/phpunit/includes/registration/VersionCheckerTest.php
tests/phpunit/includes/resourceloader/ResourceLoaderClientHtmlTest.php
tests/phpunit/includes/sparql/SparqlClientTest.php [new file with mode: 0644]
tests/phpunit/phpunit.php
tests/phpunit/structure/ApiStructureTest.php
tests/qunit/QUnitTestResources.php

index b06d9f4..a28dac0 100644 (file)
@@ -69,6 +69,8 @@ before_script:
       --dbuser "$dbuser"
       --dbpass ""
       --scriptpath "/w"
+  - echo -en "\n\nrequire_once __DIR__ . '/includes/DevelopmentSettings.php';\n" >> ./LocalSettings.php
+  - php -l ./LocalSettings.php
 
 script:
   - php tests/phpunit/phpunit.php
index d1ef72f..cb9a20d 100644 (file)
@@ -98,8 +98,8 @@ module.exports = function ( grunt ) {
                        chromium: {
                                browsers: [ 'Chromium' ]
                        },
-                       more: {
-                               browsers: [ 'Chrome', 'Firefox' ]
+                       firefox: {
+                               browsers: [ 'Firefox' ]
                        }
                },
                copy: {
index cc08b33..24239fd 100644 (file)
@@ -26,6 +26,8 @@ production.
   default mode.
 * CACHE_ACCEL now only supports APC(u) or WinCache. XCache support was removed
   as upstream is inactive and has no plans to move to PHP 7.
+* The old CategorizedRecentChanges feature, including its related configuration
+  option $wgAllowCategorizedRecentChanges, has been removed.
 
 === New features in 1.31 ===
 * Wikimedia\Rdbms\IDatabase->select() and similar methods now support
@@ -63,6 +65,7 @@ production.
 * Updated wikimedia/running-stat from 1.1.0 to 1.2.0.
 * Updated wikimedia/wrappedstring from 2.2.0 to 2.3.0.
 * Updated mediawiki/at-ease from 1.1.0 to 1.2.0.
+* Updated wikimedia/php-session-serializer from 1.0.4 to 1.0.5.
 * …
 
 ==== New external libraries ====
@@ -233,6 +236,7 @@ changes to languages because of Phabricator reports.
   * CommentStore::getCommentLegacy
   * CommentStore::insert
   * CommentStore::insertWithTemplate
+* The method ResourceLoaderModule::getPosition(), deprecated in 1.29, has been removed.
 
 == Compatibility ==
 MediaWiki 1.31 requires PHP 5.5.9 or later. Although HHVM 3.18.5 or later is supported,
index 9618a8f..9042f7b 100644 (file)
@@ -939,6 +939,8 @@ $wgAutoloadLocalClasses = [
        'MediaWiki\\Shell\\Result' => __DIR__ . '/includes/shell/Result.php',
        'MediaWiki\\Shell\\Shell' => __DIR__ . '/includes/shell/Shell.php',
        'MediaWiki\\Site\\MediaWikiPageNameNormalizer' => __DIR__ . '/includes/site/MediaWikiPageNameNormalizer.php',
+       'MediaWiki\\Sparql\\SparqlClient' => __DIR__ . '/includes/sparql/SparqlClient.php',
+       'MediaWiki\\Sparql\\SparqlException' => __DIR__ . '/includes/sparql/SparqlException.php',
        'MediaWiki\\Storage\\BlobAccessException' => __DIR__ . '/includes/Storage/BlobAccessException.php',
        'MediaWiki\\Storage\\BlobStore' => __DIR__ . '/includes/Storage/BlobStore.php',
        'MediaWiki\\Storage\\BlobStoreFactory' => __DIR__ . '/includes/Storage/BlobStoreFactory.php',
@@ -1361,7 +1363,7 @@ $wgAutoloadLocalClasses = [
        'SiteLookup' => __DIR__ . '/includes/site/SiteLookup.php',
        'SiteSQLStore' => __DIR__ . '/includes/site/SiteSQLStore.php',
        'SiteStats' => __DIR__ . '/includes/SiteStats.php',
-       'SiteStatsInit' => __DIR__ . '/includes/SiteStats.php',
+       'SiteStatsInit' => __DIR__ . '/includes/SiteStatsInit.php',
        'SiteStatsUpdate' => __DIR__ . '/includes/deferred/SiteStatsUpdate.php',
        'SiteStore' => __DIR__ . '/includes/site/SiteStore.php',
        'SitesCacheFileBuilder' => __DIR__ . '/includes/site/SitesCacheFileBuilder.php',
@@ -1589,6 +1591,7 @@ $wgAutoloadLocalClasses = [
        'UserBlockedError' => __DIR__ . '/includes/exception/UserBlockedError.php',
        'UserCache' => __DIR__ . '/includes/cache/UserCache.php',
        'UserDupes' => __DIR__ . '/maintenance/userDupes.inc',
+       'UserGroupExpiryJob' => __DIR__ . '/includes/jobqueue/jobs/UserGroupExpiryJob.php',
        'UserGroupMembership' => __DIR__ . '/includes/user/UserGroupMembership.php',
        'UserMailer' => __DIR__ . '/includes/mail/UserMailer.php',
        'UserNamePrefixSearch' => __DIR__ . '/includes/user/UserNamePrefixSearch.php',
index c3ff8d6..56d1633 100644 (file)
@@ -37,7 +37,7 @@
                "wikimedia/html-formatter": "1.0.1",
                "wikimedia/ip-set": "1.2.0",
                "wikimedia/object-factory": "1.0.0",
-               "wikimedia/php-session-serializer": "1.0.4",
+               "wikimedia/php-session-serializer": "1.0.5",
                "wikimedia/purtle": "1.0.6",
                "wikimedia/relpath": "2.1.1",
                "wikimedia/remex-html": "1.0.2",
index 8b4c755..5bdb31c 100644 (file)
@@ -9,7 +9,7 @@ in a much more flexible way. Consider the elegance of:
     # Generate the article HTML as if viewed by a web request
     $article = new Article( Title::newFromText( $t ) );
     $article->view();
+
 versus
 
     # Save current globals
index 3561f7f..7446b59 100644 (file)
@@ -42,6 +42,8 @@ use Wikimedia\Rdbms\IDatabase;
  *     $a = $cf->run();
  *     print implode( ',' , $a );
  * @endcode
+ *
+ * @deprecated since 1.31
  */
 class CategoryFinder {
        /** @var int[] The original article IDs passed to the seed function */
index a6a3686..ae5cef5 100644 (file)
@@ -6673,9 +6673,9 @@ $wgGitBin = '/usr/bin/git';
  */
 $wgGitRepositoryViewers = [
        'https://(?:[a-z0-9_]+@)?gerrit.wikimedia.org/r/(?:p/)?(.*)' =>
-               'https://phabricator.wikimedia.org/r/revision/%R;%H',
+               'https://gerrit.wikimedia.org/g/%R/+/%H',
        'ssh://(?:[a-z0-9_]+@)?gerrit.wikimedia.org:29418/(.*)' =>
-               'https://phabricator.wikimedia.org/r/revision/%R;%H',
+               'https://gerrit.wikimedia.org/g/%R/+/%H',
 ];
 
 /** @} */ # End of maintenance }
@@ -6953,11 +6953,6 @@ $wgShowUpdatedMarker = true;
  */
 $wgDisableAnonTalk = false;
 
-/**
- * Enable filtering of categories in Recentchanges
- */
-$wgAllowCategorizedRecentChanges = false;
-
 /**
  * Allow filtering by change tag in recentchanges, history, etc
  * Has no effect if no tags are defined in valid_tag.
@@ -7459,6 +7454,7 @@ $wgJobClasses = [
        'clearUserWatchlist' => ClearUserWatchlistJob::class,
        'cdnPurge' => CdnPurgeJob::class,
        'enqueue' => EnqueueJob::class, // local queue for multi-DC setups
+       'userGroupExpiry' => UserGroupExpiryJob::class,
        'null' => NullJob::class,
 ];
 
diff --git a/includes/DevelopmentSettings.php b/includes/DevelopmentSettings.php
new file mode 100644 (file)
index 0000000..a74353a
--- /dev/null
@@ -0,0 +1,59 @@
+<?php
+/**
+ * Extra settings useful for MediaWiki development.
+ *
+ * To enable built-in debug and development settings, add the
+ * following to your LocalSettings.php file.
+ *
+ *     require "$IP/includes/DevelopmentSettings.php";
+ *
+ * Alternatively, if running phpunit.php (or another Maintenance script),
+ * you can use the --mwdebug option to automatically load these settings.
+ *
+ * @file
+ */
+
+/**
+ * Debugging: PHP
+ */
+
+// Enable showing of errors
+error_reporting( -1 );
+ini_set( 'display_errors', 1 );
+
+/**
+ * Debugging: MediaWiki
+ */
+global $wgDevelopmentWarnings, $wgShowDBErrorBacktrace, $wgShowExceptionDetails,
+       $wgShowSQLErrors, $wgDebugRawPage,
+       $wgDebugComments, $wgDebugDumpSql, $wgDebugTimestamps,
+       $wgCommandLineMode, $wgDebugLogFile, $wgDBerrorLog, $wgDebugLogGroups;
+
+// Use of wfWarn() should cause tests to fail
+$wgDevelopmentWarnings = true;
+
+// Enable showing of errors
+$wgShowDBErrorBacktrace = true;
+$wgShowExceptionDetails = true;
+$wgShowSQLErrors = true;
+$wgDebugRawPage = true; // T49960
+
+// Enable verbose logging
+$wgDebugComments = true;
+$wgDebugDumpSql = true;
+$wgDebugTimestamps = true;
+
+// Enable log files
+$logDir = getenv( 'MW_LOG_DIR' );
+if ( $logDir ) {
+       if ( $wgCommandLineMode ) {
+               $wgDebugLogFile = "$logDir/mw-debug-cli.log";
+       } else {
+               $wgDebugLogFile = "$logDir/mw-debug-www.log";
+       }
+       $wgDBerrorLog = "$logDir/mw-dberror.log";
+       $wgDebugLogGroups['ratelimit'] = "$logDir/mw-ratelimit.log";
+       $wgDebugLogGroups['exception'] = "$logDir/mw-exception.log";
+       $wgDebugLogGroups['error'] = "$logDir/mw-error.log";
+}
+unset( $logDir );
index 6fbeed7..f9c7fb2 100644 (file)
@@ -325,7 +325,7 @@ class EditPage {
        /** @var bool Has a summary been preset using GET parameter &summary= ? */
        public $hasPresetSummary = false;
 
-       /** @var Revision|bool */
+       /** @var Revision|bool|null */
        public $mBaseRevision = false;
 
        /** @var bool */
@@ -2369,7 +2369,7 @@ ERROR;
        /**
         * @note: this method is very poorly named. If the user opened the form with ?oldid=X,
         *        one might think of X as the "base revision", which is NOT what this returns.
-        * @return Revision Current version when the edit was started
+        * @return Revision|null Current version when the edit was started
         */
        public function getBaseRevision() {
                if ( !$this->mBaseRevision ) {
@@ -4028,7 +4028,6 @@ ERROR;
                        $this->mTitle, $pstContent, $user );
                $parserOutput = $pstContent->getParserOutput( $this->mTitle, null, $parserOptions );
                ScopedCallback::consume( $scopedCallback );
-               $parserOutput->setEditSectionTokens( false ); // no section edit links
                return [
                        'parserOutput' => $parserOutput,
                        'html' => $parserOutput->getText( [
index fe82465..fc9f6a6 100644 (file)
@@ -597,7 +597,12 @@ class MovePage {
 
                                $redirectArticle->doEditUpdates( $redirectRevision, $user, [ 'created' => true ] );
 
-                               ChangeTags::addTags( $changeTags, null, $redirectRevId, null );
+                               // make a copy because of log entry below
+                               $redirectTags = $changeTags;
+                               if ( in_array( 'mw-new-redirect', ChangeTags::getSoftwareTags() ) ) {
+                                       $redirectTags[] = 'mw-new-redirect';
+                               }
+                               ChangeTags::addTags( $redirectTags, null, $redirectRevId, null );
                        }
                }
 
index 6b44a55..f95327a 100644 (file)
@@ -287,11 +287,6 @@ class OutputPage extends ContextSource {
         */
        private $mEnableTOC = false;
 
-       /**
-        * @var bool Whether parser output should contain section edit links
-        */
-       private $mEnableSectionEditLinks = true;
-
        /**
         * @var string|null The URL to send in a <link> element with rel=license
         */
@@ -493,7 +488,7 @@ class OutputPage extends ContextSource {
         * Filter an array of modules to remove insufficiently trustworthy members, and modules
         * which are no longer registered (eg a page is cached before an extension is disabled)
         * @param array $modules
-        * @param string|null $position If not null, only return modules with this position
+        * @param string|null $position Unused
         * @param string $type
         * @return array
         */
@@ -506,7 +501,6 @@ class OutputPage extends ContextSource {
                        $module = $resourceLoader->getModule( $val );
                        if ( $module instanceof ResourceLoaderModule
                                && $module->getOrigin() <= $this->getAllowedModules( $type )
-                               && ( is_null( $position ) || $module->getPosition() == $position )
                        ) {
                                if ( $this->mTarget && !in_array( $this->mTarget, $module->getTargets() ) ) {
                                        $this->warnModuleTargetFilter( $module->getName() );
@@ -537,7 +531,7 @@ class OutputPage extends ContextSource {
         * Get the list of modules to include on this page
         *
         * @param bool $filter Whether to filter out insufficiently trustworthy modules
-        * @param string|null $position If not null, only return modules with this position
+        * @param string|null $position Unused
         * @param string $param
         * @param string $type
         * @return array Array of module names
@@ -547,7 +541,7 @@ class OutputPage extends ContextSource {
        ) {
                $modules = array_values( array_unique( $this->$param ) );
                return $filter
-                       ? $this->filterModules( $modules, $position, $type )
+                       ? $this->filterModules( $modules, null, $type )
                        : $modules;
        }
 
@@ -566,11 +560,11 @@ class OutputPage extends ContextSource {
         * Get the list of module JS to include on this page
         *
         * @param bool $filter
-        * @param string|null $position
+        * @param string|null $position Unused
         * @return array Array of module names
         */
        public function getModuleScripts( $filter = false, $position = null ) {
-               return $this->getModules( $filter, $position, 'mModuleScripts',
+               return $this->getModules( $filter, null, 'mModuleScripts',
                        ResourceLoaderModule::TYPE_SCRIPTS
                );
        }
@@ -590,11 +584,11 @@ class OutputPage extends ContextSource {
         * Get the list of module CSS to include on this page
         *
         * @param bool $filter
-        * @param string|null $position
+        * @param string|null $position Unused
         * @return array Array of module names
         */
        public function getModuleStyles( $filter = false, $position = null ) {
-               return $this->getModules( $filter, $position, 'mModuleStyles',
+               return $this->getModules( $filter, null, 'mModuleStyles',
                        ResourceLoaderModule::TYPE_STYLES
                );
        }
@@ -1548,7 +1542,6 @@ class OutputPage extends ContextSource {
                        // Someone is trying to set a bogus pre-$wgUser PO. Check if it has
                        // been changed somehow, and keep it if so.
                        $anonPO = ParserOptions::newFromAnon();
-                       $anonPO->setEditSection( false );
                        $anonPO->setAllowUnsafeRawHtml( false );
                        if ( !$options->matches( $anonPO ) ) {
                                wfLogWarning( __METHOD__ . ': Setting a changed bogus ParserOptions: ' . wfGetAllCallers( 5 ) );
@@ -1562,7 +1555,6 @@ class OutputPage extends ContextSource {
                                // ParserOptions for it. And don't cache this ParserOptions
                                // either.
                                $po = ParserOptions::newFromAnon();
-                               $po->setEditSection( false );
                                $po->setAllowUnsafeRawHtml( false );
                                $po->isBogus = true;
                                if ( $options !== null ) {
@@ -1572,7 +1564,6 @@ class OutputPage extends ContextSource {
                        }
 
                        $this->mParserOptions = ParserOptions::newFromContext( $this->getContext() );
-                       $this->mParserOptions->setEditSection( false );
                        $this->mParserOptions->setAllowUnsafeRawHtml( false );
                }
 
@@ -1822,7 +1813,7 @@ class OutputPage extends ContextSource {
                // so that extensions may modify ParserOutput to toggle TOC.
                // This cannot be moved to addParserOutputText because that is not
                // called by EditPage for Preview.
-               if ( $parserOutput->getTOCEnabled() && $parserOutput->getTOCHTML() ) {
+               if ( $parserOutput->getTOCHTML() ) {
                        $this->mEnableTOC = true;
                }
        }
@@ -1868,17 +1859,6 @@ class OutputPage extends ContextSource {
         */
        function addParserOutput( $parserOutput, $poOptions = [] ) {
                $this->addParserOutputMetadata( $parserOutput );
-
-               // Touch section edit links only if not previously disabled
-               if ( $parserOutput->getEditSectionTokens() ) {
-                       $parserOutput->setEditSectionTokens( $this->mEnableSectionEditLinks );
-               }
-               if ( !$this->mEnableSectionEditLinks
-                       && !array_key_exists( 'enableSectionEditLinks', $poOptions )
-               ) {
-                       $poOptions['enableSectionEditLinks'] = false;
-               }
-
                $this->addParserOutputText( $parserOutput, $poOptions );
        }
 
@@ -2977,8 +2957,8 @@ class OutputPage extends ContextSource {
        }
 
        /**
-        * JS stuff to put at the bottom of the `<body>`. These are modules with position 'bottom',
-        * legacy scripts ($this->mScripts), and user JS.
+        * JS stuff to put at the bottom of the `<body>`.
+        * These are legacy scripts ($this->mScripts), and user JS.
         *
         * @return string|WrappedStringList HTML
         */
@@ -3896,7 +3876,7 @@ class OutputPage extends ContextSource {
         * @deprecated since 1.31, use $poOptions to addParserOutput() instead.
         */
        public function enableSectionEditLinks( $flag = true ) {
-               $this->mEnableSectionEditLinks = $flag;
+               wfDeprecated( __METHOD__, '1.31' );
        }
 
        /**
@@ -3905,7 +3885,8 @@ class OutputPage extends ContextSource {
         * @deprecated since 1.31, use $poOptions to addParserOutput() instead.
         */
        public function sectionEditLinksEnabled() {
-               return $this->mEnableSectionEditLinks;
+               wfDeprecated( __METHOD__, '1.31' );
+               return true;
        }
 
        /**
index eba563c..d9d3149 100644 (file)
@@ -906,6 +906,11 @@ class Revision implements IDBAccessObject {
                        return $this->mRecord->getContent( 'main', $audience, $user );
                }
                catch ( RevisionAccessException $e ) {
+                       wfDebugLog(
+                               'T184670',
+                               __METHOD__ . ": Cannot get content: " . $e->getMessage() .
+                               "\n" . $e->getTraceAsString()
+                       );
                        return null;
                }
        }
index f10e6a2..745c891 100644 (file)
 use Wikimedia\Rdbms\Database;
 use Wikimedia\Rdbms\IDatabase;
 use MediaWiki\MediaWikiServices;
+use Wikimedia\Rdbms\LoadBalancer;
 
 /**
  * Static accessor class for site_stats and related things
  */
 class SiteStats {
-       /** @var bool|stdClass */
+       /** @var stdClass */
        private static $row;
 
-       /** @var bool */
-       private static $loaded = false;
-       /** @var int[] */
-       private static $pageCount = [];
-
-       static function unload() {
-               self::$loaded = false;
-       }
-
-       static function recache() {
-               self::load( true );
-       }
-
        /**
-        * @param bool $recache
+        * Trigger a reload next time a field is accessed
         */
-       static function load( $recache = false ) {
-               if ( self::$loaded && !$recache ) {
-                       return;
-               }
-
-               self::$row = self::loadAndLazyInit();
+       public static function unload() {
+               self::$row = null;
+       }
 
-               self::$loaded = true;
+       protected static function load() {
+               if ( self::$row === null ) {
+                       self::$row = self::loadAndLazyInit();
+               }
        }
 
        /**
-        * @return bool|stdClass
+        * @return stdClass
         */
-       static function loadAndLazyInit() {
-               global $wgMiserMode;
+       protected static function loadAndLazyInit() {
+               $config = MediaWikiServices::getInstance()->getMainConfig();
 
+               $lb = self::getLB();
+               $dbr = $lb->getConnection( DB_REPLICA );
                wfDebug( __METHOD__ . ": reading site_stats from replica DB\n" );
-               $row = self::doLoad( wfGetDB( DB_REPLICA ) );
-
-               if ( !self::isSane( $row ) ) {
-                       $lb = MediaWikiServices::getInstance()->getDBLoadBalancer();
-                       if ( $lb->hasOrMadeRecentMasterChanges() ) {
-                               // Might have just been initialized during this request? Underflow?
-                               wfDebug( __METHOD__ . ": site_stats damaged or missing on replica DB\n" );
-                               $row = self::doLoad( wfGetDB( DB_MASTER ) );
-                       }
+               $row = self::doLoadFromDB( $dbr );
+
+               if ( !self::isRowSane( $row ) && $lb->hasOrMadeRecentMasterChanges() ) {
+                       // Might have just been initialized during this request? Underflow?
+                       wfDebug( __METHOD__ . ": site_stats damaged or missing on replica DB\n" );
+                       $row = self::doLoadFromDB( $lb->getConnection( DB_MASTER ) );
                }
 
-               if ( !self::isSane( $row ) ) {
-                       if ( $wgMiserMode ) {
+               if ( !self::isRowSane( $row ) ) {
+                       if ( $config->get( 'MiserMode' ) ) {
                                // Start off with all zeroes, assuming that this is a new wiki or any
                                // repopulations where done manually via script.
                                SiteStatsInit::doPlaceholderInit();
@@ -86,88 +73,73 @@ class SiteStats {
                                // broken, however, for instance when importing from a dump into a
                                // clean schema with mwdumper.
                                wfDebug( __METHOD__ . ": initializing damaged or missing site_stats\n" );
-                               SiteStatsInit::doAllAndCommit( wfGetDB( DB_REPLICA ) );
+                               SiteStatsInit::doAllAndCommit( $dbr );
                        }
 
-                       $row = self::doLoad( wfGetDB( DB_MASTER ) );
+                       $row = self::doLoadFromDB( $lb->getConnection( DB_MASTER ) );
                }
 
-               if ( !self::isSane( $row ) ) {
+               if ( !self::isRowSane( $row ) ) {
                        wfDebug( __METHOD__ . ": site_stats persistently nonsensical o_O\n" );
-
-                       $row = (object)array_fill_keys( self::selectFields(), 0 );
+                       // Always return a row-like object
+                       $row = self::salvageInsaneRow( $row );
                }
 
                return $row;
        }
 
        /**
-        * @param IDatabase $db
-        * @return bool|stdClass
-        */
-       static function doLoad( $db ) {
-               return $db->selectRow( 'site_stats', self::selectFields(), [], __METHOD__ );
-       }
-
-       /**
-        * Return the total number of page views. Except we don't track those anymore.
-        * Stop calling this function, it will be removed some time in the future. It's
-        * kept here simply to prevent fatal errors.
-        *
-        * @deprecated since 1.25
         * @return int
         */
-       static function views() {
-               wfDeprecated( __METHOD__, '1.25' );
-               return 0;
-       }
-
-       /**
-        * @return int
-        */
-       static function edits() {
+       public static function edits() {
                self::load();
-               return self::$row->ss_total_edits;
+
+               return (int)self::$row->ss_total_edits;
        }
 
        /**
         * @return int
         */
-       static function articles() {
+       public static function articles() {
                self::load();
-               return self::$row->ss_good_articles;
+
+               return (int)self::$row->ss_good_articles;
        }
 
        /**
         * @return int
         */
-       static function pages() {
+       public static function pages() {
                self::load();
-               return self::$row->ss_total_pages;
+
+               return (int)self::$row->ss_total_pages;
        }
 
        /**
         * @return int
         */
-       static function users() {
+       public static function users() {
                self::load();
-               return self::$row->ss_users;
+
+               return (int)self::$row->ss_users;
        }
 
        /**
         * @return int
         */
-       static function activeUsers() {
+       public static function activeUsers() {
                self::load();
-               return self::$row->ss_active_users;
+
+               return (int)self::$row->ss_active_users;
        }
 
        /**
         * @return int
         */
-       static function images() {
+       public static function images() {
                self::load();
-               return self::$row->ss_images;
+
+               return (int)self::$row->ss_images;
        }
 
        /**
@@ -175,17 +147,17 @@ class SiteStats {
         * @param string $group Name of group
         * @return int
         */
-       static function numberingroup( $group ) {
+       public static function numberingroup( $group ) {
                $cache = MediaWikiServices::getInstance()->getMainWANObjectCache();
+
                return $cache->getWithSetCallback(
                        $cache->makeKey( 'SiteStats', 'groupcounts', $group ),
                        $cache::TTL_HOUR,
                        function ( $oldValue, &$ttl, array &$setOpts ) use ( $group ) {
-                               $dbr = wfGetDB( DB_REPLICA );
-
+                               $dbr = self::getLB()->getConnection( DB_REPLICA );
                                $setOpts += Database::getCacheSetOptions( $dbr );
 
-                               return $dbr->selectField(
+                               return (int)$dbr->selectField(
                                        'user_groups',
                                        'COUNT(*)',
                                        [
@@ -203,8 +175,9 @@ class SiteStats {
         * Total number of jobs in the job queue.
         * @return int
         */
-       static function jobs() {
+       public static function jobs() {
                $cache = MediaWikiServices::getInstance()->getMainWANObjectCache();
+
                return $cache->getWithSetCallback(
                        $cache->makeKey( 'SiteStats', 'jobscount' ),
                        $cache::TTL_MINUTE,
@@ -222,20 +195,27 @@ class SiteStats {
 
        /**
         * @param int $ns
-        *
         * @return int
         */
-       static function pagesInNs( $ns ) {
-               if ( !isset( self::$pageCount[$ns] ) ) {
-                       $dbr = wfGetDB( DB_REPLICA );
-                       self::$pageCount[$ns] = (int)$dbr->selectField(
-                               'page',
-                               'COUNT(*)',
-                               [ 'page_namespace' => $ns ],
-                               __METHOD__
-                       );
-               }
-               return self::$pageCount[$ns];
+       public static function pagesInNs( $ns ) {
+               $cache = MediaWikiServices::getInstance()->getMainWANObjectCache();
+
+               return $cache->getWithSetCallback(
+                       $cache->makeKey( 'SiteStats', 'page-in-namespace', $ns ),
+                       $cache::TTL_HOUR,
+                       function ( $oldValue, &$ttl, array &$setOpts ) use ( $ns ) {
+                               $dbr = self::getLB()->getConnection( DB_REPLICA );
+                               $setOpts += Database::getCacheSetOptions( $dbr );
+
+                               return (int)$dbr->selectField(
+                                       'page',
+                                       'COUNT(*)',
+                                       [ 'page_namespace' => $ns ],
+                                       __METHOD__
+                               );
+                       },
+                       [ 'pcTTL' => $cache::TTL_PROC_LONG ]
+               );
        }
 
        /**
@@ -243,7 +223,6 @@ class SiteStats {
         */
        public static function selectFields() {
                return [
-                       'ss_row_id',
                        'ss_total_edits',
                        'ss_good_articles',
                        'ss_total_pages',
@@ -253,16 +232,28 @@ class SiteStats {
                ];
        }
 
+       /**
+        * @param IDatabase $db
+        * @return stdClass|bool
+        */
+       private static function doLoadFromDB( IDatabase $db ) {
+               return $db->selectRow(
+                       'site_stats',
+                       self::selectFields(),
+                       [ 'ss_row_id' => 1 ],
+                       __METHOD__
+               );
+       }
+
        /**
         * Is the provided row of site stats sane, or should it be regenerated?
         *
         * Checks only fields which are filled by SiteStatsInit::refresh.
         *
         * @param bool|object $row
-        *
         * @return bool
         */
-       private static function isSane( $row ) {
+       private static function isRowSane( $row ) {
                if ( $row === false
                        || $row->ss_total_pages < $row->ss_good_articles
                        || $row->ss_total_edits < $row->ss_total_pages
@@ -277,167 +268,34 @@ class SiteStats {
                        'ss_users',
                        'ss_images',
                ] as $member ) {
-                       if ( $row->$member > 2000000000 || $row->$member < 0 ) {
+                       if ( $row->$member < 0 ) {
                                return false;
                        }
                }
-               return true;
-       }
-}
-
-/**
- * Class designed for counting of stats.
- */
-class SiteStatsInit {
-
-       // Database connection
-       private $db;
 
-       // Various stats
-       private $mEdits = null, $mArticles = null, $mPages = null;
-       private $mUsers = null, $mFiles = null;
-
-       /**
-        * @param bool|IDatabase $database
-        * - bool: Whether to use the master DB
-        * - IDatabase: Database connection to use
-        */
-       public function __construct( $database = false ) {
-               if ( $database instanceof IDatabase ) {
-                       $this->db = $database;
-               } elseif ( $database ) {
-                       $this->db = wfGetDB( DB_MASTER );
-               } else {
-                       $this->db = wfGetDB( DB_REPLICA, 'vslow' );
-               }
-       }
-
-       /**
-        * Count the total number of edits
-        * @return int
-        */
-       public function edits() {
-               $this->mEdits = $this->db->selectField( 'revision', 'COUNT(*)', '', __METHOD__ );
-               $this->mEdits += $this->db->selectField( 'archive', 'COUNT(*)', '', __METHOD__ );
-               return $this->mEdits;
-       }
-
-       /**
-        * Count pages in article space(s)
-        * @return int
-        */
-       public function articles() {
-               global $wgArticleCountMethod;
-
-               $tables = [ 'page' ];
-               $conds = [
-                       'page_namespace' => MWNamespace::getContentNamespaces(),
-                       'page_is_redirect' => 0,
-               ];
-
-               if ( $wgArticleCountMethod == 'link' ) {
-                       $tables[] = 'pagelinks';
-                       $conds[] = 'pl_from=page_id';
-               } elseif ( $wgArticleCountMethod == 'comma' ) {
-                       // To make a correct check for this, we would need, for each page,
-                       // to load the text, maybe uncompress it, maybe decode it and then
-                       // check if there's one comma.
-                       // But one thing we are sure is that if the page is empty, it can't
-                       // contain a comma :)
-                       $conds[] = 'page_len > 0';
-               }
-
-               $this->mArticles = $this->db->selectField( $tables, 'COUNT(DISTINCT page_id)',
-                       $conds, __METHOD__ );
-               return $this->mArticles;
-       }
-
-       /**
-        * Count total pages
-        * @return int
-        */
-       public function pages() {
-               $this->mPages = $this->db->selectField( 'page', 'COUNT(*)', '', __METHOD__ );
-               return $this->mPages;
-       }
-
-       /**
-        * Count total users
-        * @return int
-        */
-       public function users() {
-               $this->mUsers = $this->db->selectField( 'user', 'COUNT(*)', '', __METHOD__ );
-               return $this->mUsers;
-       }
-
-       /**
-        * Count total files
-        * @return int
-        */
-       public function files() {
-               $this->mFiles = $this->db->selectField( 'image', 'COUNT(*)', '', __METHOD__ );
-               return $this->mFiles;
+               return true;
        }
 
        /**
-        * Do all updates and commit them. More or less a replacement
-        * for the original initStats, but without output.
-        *
-        * @param IDatabase|bool $database
-        * - bool: Whether to use the master DB
-        * - IDatabase: Database connection to use
-        * @param array $options Array of options, may contain the following values
-        * - activeUsers bool: Whether to update the number of active users (default: false)
+        * @param stdClass|bool $row
+        * @return stdClass
         */
-       public static function doAllAndCommit( $database, array $options = [] ) {
-               $options += [ 'update' => false, 'activeUsers' => false ];
-
-               // Grab the object and count everything
-               $counter = new SiteStatsInit( $database );
-
-               $counter->edits();
-               $counter->articles();
-               $counter->pages();
-               $counter->users();
-               $counter->files();
-
-               $counter->refresh();
-
-               // Count active users if need be
-               if ( $options['activeUsers'] ) {
-                       SiteStatsUpdate::cacheUpdate( wfGetDB( DB_MASTER ) );
+       private static function salvageInsaneRow( $row ) {
+               $map = $row ? (array)$row : [];
+               // Fill in any missing values with zero
+               $map += array_fill_keys( self::selectFields(), 0 );
+               // Convert negative values to zero
+               foreach ( $map as $field => $value ) {
+                       $map[$field] = max( 0, $value );
                }
-       }
 
-       /**
-        * Insert a dummy row with all zeroes if no row is present
-        */
-       public static function doPlaceholderInit() {
-               $dbw = wfGetDB( DB_MASTER );
-               if ( $dbw->selectRow( 'site_stats', '1', [], __METHOD__ ) === false ) {
-                       $dbw->insert(
-                               'site_stats',
-                               array_fill_keys( SiteStats::selectFields(), 0 ),
-                               __METHOD__,
-                               [ 'IGNORE' ]
-                       );
-               }
+               return (object)$row;
        }
 
        /**
-        * Refresh site_stats
+        * @return LoadBalancer
         */
-       public function refresh() {
-               $values = [
-                       'ss_row_id' => 1,
-                       'ss_total_edits' => ( $this->mEdits === null ? $this->edits() : $this->mEdits ),
-                       'ss_good_articles' => ( $this->mArticles === null ? $this->articles() : $this->mArticles ),
-                       'ss_total_pages' => ( $this->mPages === null ? $this->pages() : $this->mPages ),
-                       'ss_users' => ( $this->mUsers === null ? $this->users() : $this->mUsers ),
-                       'ss_images' => ( $this->mFiles === null ? $this->files() : $this->mFiles ),
-               ];
-
-               $dbw = wfGetDB( DB_MASTER );
-               $dbw->upsert( 'site_stats', $values, [ 'ss_row_id' ], $values, __METHOD__ );
+       private static function getLB() {
+               return MediaWikiServices::getInstance()->getDBLoadBalancer();
        }
 }
diff --git a/includes/SiteStatsInit.php b/includes/SiteStatsInit.php
new file mode 100644 (file)
index 0000000..f527cb2
--- /dev/null
@@ -0,0 +1,209 @@
+<?php
+/**
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ */
+use Wikimedia\Rdbms\IDatabase;
+use MediaWiki\MediaWikiServices;
+
+/**
+ * Class designed for counting of stats.
+ */
+class SiteStatsInit {
+       /* @var IDatabase */
+       private $dbr;
+       /** @var int */
+       private $edits;
+       /** @var int */
+       private $articles;
+       /** @var int */
+       private $pages;
+       /** @var int */
+       private $users;
+       /** @var int */
+       private $files;
+
+       /**
+        * @param bool|IDatabase $database
+        * - bool: Whether to use the master DB
+        * - IDatabase: Database connection to use
+        */
+       public function __construct( $database = false ) {
+               if ( $database instanceof IDatabase ) {
+                       $this->dbr = $database;
+               } elseif ( $database ) {
+                       $this->dbr = self::getDB( DB_MASTER );
+               } else {
+                       $this->dbr = self::getDB( DB_REPLICA, 'vslow' );
+               }
+       }
+
+       /**
+        * Count the total number of edits
+        * @return int
+        */
+       public function edits() {
+               $this->edits = $this->dbr->selectField( 'revision', 'COUNT(*)', '', __METHOD__ );
+               $this->edits += $this->dbr->selectField( 'archive', 'COUNT(*)', '', __METHOD__ );
+
+               return $this->edits;
+       }
+
+       /**
+        * Count pages in article space(s)
+        * @return int
+        */
+       public function articles() {
+               $config = MediaWikiServices::getInstance()->getMainConfig();
+
+               $tables = [ 'page' ];
+               $conds = [
+                       'page_namespace' => MWNamespace::getContentNamespaces(),
+                       'page_is_redirect' => 0,
+               ];
+
+               if ( $config->get( 'ArticleCountMethod' ) == 'link' ) {
+                       $tables[] = 'pagelinks';
+                       $conds[] = 'pl_from=page_id';
+               } elseif ( $config->get( 'ArticleCountMethod' ) == 'comma' ) {
+                       // To make a correct check for this, we would need, for each page,
+                       // to load the text, maybe uncompress it, maybe decode it and then
+                       // check if there's one comma.
+                       // But one thing we are sure is that if the page is empty, it can't
+                       // contain a comma :)
+                       $conds[] = 'page_len > 0';
+               }
+
+               $this->articles = $this->dbr->selectField(
+                       $tables,
+                       'COUNT(DISTINCT page_id)',
+                       $conds,
+                       __METHOD__
+               );
+
+               return $this->articles;
+       }
+
+       /**
+        * Count total pages
+        * @return int
+        */
+       public function pages() {
+               $this->pages = $this->dbr->selectField( 'page', 'COUNT(*)', '', __METHOD__ );
+
+               return $this->pages;
+       }
+
+       /**
+        * Count total users
+        * @return int
+        */
+       public function users() {
+               $this->users = $this->dbr->selectField( 'user', 'COUNT(*)', '', __METHOD__ );
+
+               return $this->users;
+       }
+
+       /**
+        * Count total files
+        * @return int
+        */
+       public function files() {
+               $this->files = $this->dbr->selectField( 'image', 'COUNT(*)', '', __METHOD__ );
+
+               return $this->files;
+       }
+
+       /**
+        * Do all updates and commit them. More or less a replacement
+        * for the original initStats, but without output.
+        *
+        * @param IDatabase|bool $database
+        * - bool: Whether to use the master DB
+        * - IDatabase: Database connection to use
+        * @param array $options Array of options, may contain the following values
+        * - activeUsers bool: Whether to update the number of active users (default: false)
+        */
+       public static function doAllAndCommit( $database, array $options = [] ) {
+               $options += [ 'update' => false, 'activeUsers' => false ];
+
+               // Grab the object and count everything
+               $counter = new self( $database );
+
+               $counter->edits();
+               $counter->articles();
+               $counter->pages();
+               $counter->users();
+               $counter->files();
+
+               $counter->refresh();
+
+               // Count active users if need be
+               if ( $options['activeUsers'] ) {
+                       SiteStatsUpdate::cacheUpdate( self::getDB( DB_MASTER ) );
+               }
+       }
+
+       /**
+        * Insert a dummy row with all zeroes if no row is present
+        */
+       public static function doPlaceholderInit() {
+               $dbw = self::getDB( DB_MASTER );
+               $exists = $dbw->selectField( 'site_stats', '1', [ 'ss_row_id' => 1 ],  __METHOD__ );
+               if ( $exists === false ) {
+                       $dbw->insert(
+                               'site_stats',
+                               [ 'ss_row_id' => 1 ] + array_fill_keys( SiteStats::selectFields(), 0 ),
+                               __METHOD__,
+                               [ 'IGNORE' ]
+                       );
+               }
+       }
+
+       /**
+        * Refresh site_stats
+        */
+       public function refresh() {
+               $values = [
+                       'ss_row_id' => 1,
+                       'ss_total_edits' => $this->edits === null ? $this->edits() : $this->edits,
+                       'ss_good_articles' => $this->articles === null ? $this->articles() : $this->articles,
+                       'ss_total_pages' => $this->pages === null ? $this->pages() : $this->pages,
+                       'ss_users' => $this->users === null ? $this->users() : $this->users,
+                       'ss_images' => $this->files === null ? $this->files() : $this->files,
+               ];
+
+               self::getDB( DB_MASTER )->upsert(
+                       'site_stats',
+                       $values,
+                       [ 'ss_row_id' ],
+                       $values,
+                       __METHOD__
+               );
+       }
+
+       /**
+        * @param int $index
+        * @param string[] $groups
+        * @return IDatabase
+        */
+       private static function getDB( $index, $groups = [] ) {
+               $lb = MediaWikiServices::getInstance()->getDBLoadBalancer();
+
+               return $lb->getConnection( $index, $groups );
+       }
+}
index d832104..e7c9060 100644 (file)
@@ -252,7 +252,7 @@ class RevisionStore
                        if ( $title ) {
                                $this->logger->info(
                                        __METHOD__ . ' fell back to READ_LATEST and got a Title.',
-                                       [ 'trace' => wfDebugBacktrace() ]
+                                       [ 'trace' => wfBacktrace() ]
                                );
                                return $title;
                        }
index 2a80dd5..e5dba8f 100644 (file)
@@ -169,16 +169,6 @@ class ApiFeedRecentChanges extends ApiBase {
                        'showlinkedto' => false,
                ];
 
-               if ( $config->get( 'AllowCategorizedRecentChanges' ) ) {
-                       $ret += [
-                               'categories' => [
-                                       ApiBase::PARAM_TYPE => 'string',
-                                       ApiBase::PARAM_ISMULTI => true,
-                               ],
-                               'categories_any' => false,
-                       ];
-               }
-
                return $ret;
        }
 
index 3326fab..cbd62a9 100644 (file)
@@ -536,7 +536,6 @@ class ApiParse extends ApiBase {
                $popts->enableLimitReport( !$params['disablepp'] && !$params['disablelimitreport'] );
                $popts->setIsPreview( $params['preview'] || $params['sectionpreview'] );
                $popts->setIsSectionPreview( $params['sectionpreview'] );
-               $popts->setEditSection( !$params['disableeditsection'] );
                if ( $params['disabletidy'] ) {
                        $popts->setTidy( false );
                }
index 57d4b05..f07c6e2 100644 (file)
        "apihelp-feedrecentchanges-param-tagfilter": "فلتر بالوسم.",
        "apihelp-feedrecentchanges-param-target": "أحدث التغييرات في الصفحات الموصولة من هذه الصفحة فقط",
        "apihelp-feedrecentchanges-param-showlinkedto": "أظهر التغييرات للصفحات الموصولة للصفحة المعطاة عوضا عن ذلك",
-       "apihelp-feedrecentchanges-param-categories": "أظهر التغييرات في الصفحات في كل تصنيف من هذه التصنيفات فقط.",
-       "apihelp-feedrecentchanges-param-categories_any": "أظهر التغييرات في الصفحات في أي تصنيف بدلا من ذلك.",
        "apihelp-feedrecentchanges-example-simple": " اظهر التغييرات الحديثة",
        "apihelp-feedrecentchanges-example-30days": "أظهر التغييرات الأخيرة في 30 يوم.",
        "apihelp-feedwatchlist-summary": "إرجاع تغذية قائمة المراقبة.",
index da8535d..99421fe 100644 (file)
        "apihelp-feedrecentchanges-param-tagfilter": "Тэг буйынса һөҙгөс",
        "apihelp-feedrecentchanges-param-target": "Был биттән һылтанған биттәрҙә һуңғы үҙгәртеүҙәрҙе күрһәтергә",
        "apihelp-feedrecentchanges-param-showlinkedto": "Киреһенсә, был биткә һылтанма яһаған биттәрҙәге үҙгәртеүҙәрҙе күрһәтергә",
-       "apihelp-feedrecentchanges-param-categories": "Бар категория биттәрендәге үҙгәрештәрҙе генә күрһәтергә",
-       "apihelp-feedrecentchanges-param-categories_any": "Был категориянан башҡа теләһә ҡайһы категориялар биттәрендәге үҙгәрештәрҙе генә күрһәтергә",
        "apihelp-feedrecentchanges-example-simple": "Һуңғы үҙгәртеүҙәрҙе күрһәтергә.",
        "apihelp-feedrecentchanges-example-30days": "30 көн арауығындағы һуңғы үҙгәртеүҙәрҙе күрһәтергә.",
        "apihelp-feedwatchlist-summary": "Күҙәтеү каналын ҡайтара",
index 37a259d..bbee4fa 100644 (file)
        "apihelp-feedrecentchanges-param-tagfilter": "Nach Markierung filtern.",
        "apihelp-feedrecentchanges-param-target": "Nur Änderungen an Seiten anzeigen, die von dieser Seite verlinkt sind.",
        "apihelp-feedrecentchanges-param-showlinkedto": "Zeige Änderungen an Seiten die von der ausgewählten Seite verlinkt sind.",
-       "apihelp-feedrecentchanges-param-categories": "Zeigt nur Änderungen von Seiten in all diesen Kategorien.",
-       "apihelp-feedrecentchanges-param-categories_any": "Zeigt stattdessen nur Änderungen auf Seiten in einer dieser Kategorien.",
        "apihelp-feedrecentchanges-example-simple": "Letzte Änderungen anzeigen",
        "apihelp-feedrecentchanges-example-30days": "Letzte Änderungen für 30 Tage anzeigen",
        "apihelp-feedwatchlist-summary": "Gibt einen Beobachtungslisten-Feed zurück.",
index 1689019..8d7a61c 100644 (file)
        "apihelp-feedrecentchanges-param-tagfilter": "Filter by tag.",
        "apihelp-feedrecentchanges-param-target": "Show only changes on pages linked from this page.",
        "apihelp-feedrecentchanges-param-showlinkedto": "Show changes on pages linked to the selected page instead.",
-       "apihelp-feedrecentchanges-param-categories": "Show only changes on pages in all of these categories.",
-       "apihelp-feedrecentchanges-param-categories_any": "Show only changes on pages in any of the categories instead.",
        "apihelp-feedrecentchanges-example-simple": "Show recent changes.",
        "apihelp-feedrecentchanges-example-30days": "Show recent changes for 30 days.",
 
index d2aaa77..7cbf1e1 100644 (file)
        "apihelp-feedrecentchanges-param-tagfilter": "Filtrar por etiquetas.",
        "apihelp-feedrecentchanges-param-target": "Mostrar solo los cambios en las páginas enlazadas en esta.",
        "apihelp-feedrecentchanges-param-showlinkedto": "Mostrar los cambios en páginas enlazadas con la página seleccionada.",
-       "apihelp-feedrecentchanges-param-categories": "Mostrar sólo cambios en las páginas en todas estas categorías.",
-       "apihelp-feedrecentchanges-param-categories_any": "Mostrar sólo cambios en las páginas en cualquiera de las categorías en lugar.",
        "apihelp-feedrecentchanges-example-simple": "Mostrar los cambios recientes.",
        "apihelp-feedrecentchanges-example-30days": "Mostrar los cambios recientes limitados a 30 días.",
        "apihelp-feedwatchlist-summary": "Devuelve el suministro de una lista de seguimiento.",
index 3e5fb41..4c3b74d 100644 (file)
        "apihelp-feedrecentchanges-param-tagfilter": "Filtrer par balise.",
        "apihelp-feedrecentchanges-param-target": "Afficher uniquement les modifications sur les pages liées depuis cette page.",
        "apihelp-feedrecentchanges-param-showlinkedto": "Afficher les modifications plutôt sur les pages liées vers la page sélectionnée.",
-       "apihelp-feedrecentchanges-param-categories": "Afficher uniquement les modifications sur les pages dans toutes ces catégories",
-       "apihelp-feedrecentchanges-param-categories_any": "Afficher plutôt uniquement les modifications sur les pages dans n’importe laquelle de ces catégories.",
        "apihelp-feedrecentchanges-example-simple": "Afficher les modifications récentes",
        "apihelp-feedrecentchanges-example-30days": "Afficher les modifications récentes sur 30 jours",
        "apihelp-feedwatchlist-summary": "Renvoie un flux de liste de suivi.",
index 6b01875..4c66794 100644 (file)
        "apihelp-feedrecentchanges-param-tagfilter": "Filtrar por etiqueta.",
        "apihelp-feedrecentchanges-param-target": "Mostrar só os cambios nas páxinas ligadas a esta.",
        "apihelp-feedrecentchanges-param-showlinkedto": "Mostrar os cambios nas páxinas ligadas coa páxina seleccionada.",
-       "apihelp-feedrecentchanges-param-categories": "Só mostrar cambios en páxinas pertencentes a todas estas categorías.",
-       "apihelp-feedrecentchanges-param-categories_any": "Só mostrar cambios en páxinas pertencentes a calquera das categorías.",
        "apihelp-feedrecentchanges-example-simple": "Mostrar os cambios recentes",
        "apihelp-feedrecentchanges-example-30days": "Mostrar os cambios recentes limitados a 30 días",
        "apihelp-feedwatchlist-summary": "Devolve o fluxo dunha lista de vixiancia.",
index 2e68946..2064b7b 100644 (file)
        "apihelp-feedrecentchanges-param-tagfilter": "סינון לפי תגית.",
        "apihelp-feedrecentchanges-param-target": "הצגת שינויים שנעשו בדפים המקושרים לדף זה בלבד.",
        "apihelp-feedrecentchanges-param-showlinkedto": "להציג את השינויים בדפים שמקושרים לדף שנבחר במקום זה.",
-       "apihelp-feedrecentchanges-param-categories": "להציג רק שינויים בדפים בכל הקטגוריות האלו.",
-       "apihelp-feedrecentchanges-param-categories_any": "להציג רק שינויים בדפים בכל הקטגוריות במקום.",
        "apihelp-feedrecentchanges-example-simple": "הצגת שינויים אחרונים.",
        "apihelp-feedrecentchanges-example-30days": "הצגת שינויים אחרונים עבור 30 ימים.",
        "apihelp-feedwatchlist-summary": "החזרת הזנת רשימת מעקב.",
index 7c03097..f6f813d 100644 (file)
        "apihelp-feedrecentchanges-param-tagfilter": "Szűrés címke szerint.",
        "apihelp-feedrecentchanges-param-target": "Csak a megadott lapról hivatkozott lapok szerkesztéseinek megjelenítése.",
        "apihelp-feedrecentchanges-param-showlinkedto": "Inkább a megadott lap''ra'' hivatkozó lapok szerkesztéseinek megjelenítése.",
-       "apihelp-feedrecentchanges-param-categories": "Csak a megadott kategóriák mindegyikében szereplő lapok szerkesztéseinek megjelenítése.",
-       "apihelp-feedrecentchanges-param-categories_any": "Inkább a megadott kategóriák bármelyikében szereplő lapok szerkesztéseinek megjelenítése.",
        "apihelp-feedrecentchanges-example-simple": "Friss változtatások megjelenítése.",
        "apihelp-feedrecentchanges-example-30days": "Az elmúlt 30 nap friss változtatásainak megjelenítése.",
        "apihelp-feedwatchlist-summary": "A figyelőlista lekérése hírcsatornaként.",
index 25da0e6..66b0942 100644 (file)
        "apihelp-feedrecentchanges-param-tagfilter": "Filtra per etichetta.",
        "apihelp-feedrecentchanges-param-target": "Mostra solo le modifiche alle pagine collegate da questa pagina.",
        "apihelp-feedrecentchanges-param-showlinkedto": "Mostra solo le modifiche alle pagine collegate a quella specificata.",
-       "apihelp-feedrecentchanges-param-categories": "Mostra solo le variazioni sulle pagine di tutte queste categorie.",
-       "apihelp-feedrecentchanges-param-categories_any": "Mostra invece solo le variazioni sulle pagine in una qualunque categoria.",
        "apihelp-feedrecentchanges-example-simple": "Mostra le ultime modifiche.",
        "apihelp-feedrecentchanges-example-30days": "Mostra le modifiche degli ultimi 30 giorni.",
        "apihelp-feedwatchlist-param-feedformat": "Il formato del feed.",
index 1ed917a..b0231df 100644 (file)
        "apihelp-feedrecentchanges-param-tagfilter": "Noh Makkehronge beschängke.",
        "apihelp-feedrecentchanges-param-target": "Zeijsch Änderonge aan Sigge, op di vun heh dä Sigg ene Lengk jeihd.",
        "apihelp-feedrecentchanges-param-showlinkedto": "Zeijsch Änderonge aan Sigge, op di vun dä ußjesöhk Sigg ene Lengk jeihd.",
-       "apihelp-feedrecentchanges-param-categories": "Donn blohß de Änderonge aan de Zohjehüreshkeit för all heh di Saachjroppe zeije.",
-       "apihelp-feedrecentchanges-param-categories_any": "Donn deföhr blohß de Änderonge aan de Zohjehüreshkeit för öhndseijn fun heh dä Saachjroppe zeije.",
        "apihelp-feedrecentchanges-example-simple": "Zeijsch de {{LCFIRST:{{int:recentchanges}}}}",
        "apihelp-feedrecentchanges-example-30days": "Zeijsch de {{LCFIRST:{{int:recentchanges}}}} vun de läzde 30 Dähsch.",
        "apihelp-feedwatchlist-summary": "Donn ene Kannahl met dä Oppaßleß zerökjävve.",
index fc2c789..d2c7593 100644 (file)
@@ -52,8 +52,6 @@
        "apihelp-feedrecentchanges-param-hideliu": "Ännerunge vu registréierte Benotzer verstoppen.",
        "apihelp-feedrecentchanges-param-hidemyself": "Ännerunge vum aktuelle Benotzer verstoppen.",
        "apihelp-feedrecentchanges-param-hidecategorization": "Ännerunge vun der Memberschaft a Kategorie verstoppen.",
-       "apihelp-feedrecentchanges-param-categories": "Nëmmen Ännerunge vu Säiten aus all dëse Kategorië weisen.",
-       "apihelp-feedrecentchanges-param-categories_any": "Nëmmen Ännerunge vu Säiten aus enger vun dëse Kategorië weisen.",
        "apihelp-feedrecentchanges-example-simple": "Rezent Ännerunge weisen",
        "apihelp-filerevert-param-comment": "Bemierkung eroplueden.",
        "apihelp-help-example-main": "Hëllef fir den Haaptmodul.",
index 6f4c6a3..9d39405 100644 (file)
@@ -72,8 +72,6 @@
        "apihelp-feedrecentchanges-param-tagfilter": "Filtruoti pagal žymę.",
        "apihelp-feedrecentchanges-param-target": "Rodyti tik keitimus puslapiuose, pasiekiamuose iš šio puslapio.",
        "apihelp-feedrecentchanges-param-showlinkedto": "Vietoj to, rodyti pakeitimus puslapyje, susietame su pasirinktu puslapiu.",
-       "apihelp-feedrecentchanges-param-categories": "Rodyti pakeitimus tik puslapiuose, esančiuose visuose šiuose kategorijose.",
-       "apihelp-feedrecentchanges-param-categories_any": "Vietoj to, rodyti tik pakeitimus puslapiuse, esančiuose bet kurioje iš kategorijų.",
        "apihelp-feedrecentchanges-example-simple": "Parodyti naujausius keitimus.",
        "apihelp-feedrecentchanges-example-30days": "Rodyti naujausius pakeitimus per 30 dienų.",
        "apihelp-feedwatchlist-summary": "Gražina stebimųjų sąrašo srautą.",
index a012900..3cec5d4 100644 (file)
        "apihelp-feedrecentchanges-param-tagfilter": "Филтрирање по ознака.",
        "apihelp-feedrecentchanges-param-target": "Прикажи само промени на страници што водат од оваа.",
        "apihelp-feedrecentchanges-param-showlinkedto": "Наместо тоа, прикажи ги промените на страниците поврзани со избраната страница.",
-       "apihelp-feedrecentchanges-param-categories": "Прикажи само промени на страниците во сите овие категории.",
-       "apihelp-feedrecentchanges-param-categories_any": "Прикажи само промени на страниците во било која од категориите.",
        "apihelp-feedrecentchanges-example-simple": "Прикажи скорешни промени",
        "apihelp-feedrecentchanges-example-30days": "Прикажувај скорешни промени 30 дена",
        "apihelp-feedwatchlist-summary": "Дава тековник со набљудуваните.",
index dc9fb11..c2fea1c 100644 (file)
        "apihelp-feedrecentchanges-param-tagfilter": "Filtrer etter tagger.",
        "apihelp-feedrecentchanges-param-target": "Vis bare endringer på sider som lenkes fra denne siden.",
        "apihelp-feedrecentchanges-param-showlinkedto": "Vis endringer på sider som lenker til den valgte siden i stedet.",
-       "apihelp-feedrecentchanges-param-categories": "Vis bare endringer på sider i alle disse kategoriene.",
-       "apihelp-feedrecentchanges-param-categories_any": "Vis bare endringer på sider som er i noen av kategoriene i stedet.",
        "apihelp-feedrecentchanges-example-simple": "Vis siste endringer.",
        "apihelp-feedrecentchanges-example-30days": "Vis siste endringer for 30 døgn.",
        "apihelp-feedwatchlist-summary": "Returnerer en overvåkningslistemating.",
index 6c311d0..8591eba 100644 (file)
        "apihelp-feedrecentchanges-param-tagfilter": "Filtruj po znacznikach.",
        "apihelp-feedrecentchanges-param-target": "Pokaż tylko zmiany na stronach linkowanych z tej strony.",
        "apihelp-feedrecentchanges-param-showlinkedto": "Pokaż zmiany na stronach linkujących do wybranej strony.",
-       "apihelp-feedrecentchanges-param-categories": "Pokaż zmiany tylko na stronach będących we wszystkich tych kategoriach.",
-       "apihelp-feedrecentchanges-param-categories_any": "Pokaż zmiany tylko na stronach będących w jednej z tych kategorii.",
        "apihelp-feedrecentchanges-example-simple": "Pokaż ostatnie zmiany.",
        "apihelp-feedrecentchanges-example-30days": "Pokaż ostatnie zmiany z 30 dni.",
        "apihelp-feedwatchlist-summary": "Zwraca kanał listy obserwowanych.",
index 706b93c..fec224e 100644 (file)
        "apihelp-feedrecentchanges-param-tagfilter": "Filtrar por tag.",
        "apihelp-feedrecentchanges-param-target": "Mostrar apenas as alterações nas páginas vinculadas por esta página.",
        "apihelp-feedrecentchanges-param-showlinkedto": "Mostra as alterações nas páginas vigiadas à página selecionada.",
-       "apihelp-feedrecentchanges-param-categories": "Mostre apenas as alterações em páginas em todas essas categorias.",
-       "apihelp-feedrecentchanges-param-categories_any": "Mostre apenas as alterações em páginas em qualquer uma das categorias.",
        "apihelp-feedrecentchanges-example-simple": "Mostrar as mudanças recentes.",
        "apihelp-feedrecentchanges-example-30days": "Mostrar as mudanças recentes por 30 dias.",
        "apihelp-feedwatchlist-summary": "Retornar um feed da lista de páginas vigiadas.",
        "apihelp-parse-param-disablepp": "Use <var>$1disablelimitreport</var> em vez.",
        "apihelp-parse-param-disableeditsection": "Omita os links da seção de edição da saída do analisador.",
        "apihelp-parse-param-disabletidy": "Não executa a limpeza HTML (por exemplo, tidy) na saída do analisador.",
+       "apihelp-parse-param-disablestylededuplication": "Não desduplica as folhas de estilo inline na saída do analisador.",
        "apihelp-parse-param-generatexml": "Gerar XML parse tree (requer modelo de conteúdo <code>$1</code>, substituído por <kbd>$2prop=parsetree</kbd>).",
        "apihelp-parse-param-preview": "Analisar no mode de visualização.",
        "apihelp-parse-param-sectionpreview": "Analise no modo de visualização de seção (também permite o modo de visualização).",
index aa697fb..c18160a 100644 (file)
        "apihelp-feedrecentchanges-param-tagfilter": "Filtrar por etiqueta.",
        "apihelp-feedrecentchanges-param-target": "Mostrar apenas mudanças em páginas afluentes a esta.",
        "apihelp-feedrecentchanges-param-showlinkedto": "Mostrar mudanças em páginas com hiperligações para a página selecionada.",
-       "apihelp-feedrecentchanges-param-categories": "Mostrar apenas mudanças nas páginas que estão em todas estas categorias.",
-       "apihelp-feedrecentchanges-param-categories_any": "Mostrar apenas mudanças nas páginas que estão em qualquer uma das categorias.",
        "apihelp-feedrecentchanges-example-simple": "Mostrar mudanças recentes.",
        "apihelp-feedrecentchanges-example-30days": "Mostrar as mudanças recentes de 30 dias.",
        "apihelp-feedwatchlist-summary": "Devolve um ''feed'' das páginas vigiadas.",
        "apihelp-parse-param-disablepp": "Em vez deste, usar <var>$1disablelimitreport</var>.",
        "apihelp-parse-param-disableeditsection": "Omitir as hiperligações para edição da secção no resultado da análise sintática.",
        "apihelp-parse-param-disabletidy": "Não fazer a limpeza do HTML (isto é, o ''tidy'') no resultado da análise sintática.",
+       "apihelp-parse-param-disablestylededuplication": "Não desduplica as folhas de estilo incluídas na saída do analisador sintático.",
        "apihelp-parse-param-generatexml": "Gerar a árvore de análise XML (requer o modelo de conteúdo <code>$1</code>; substituído por <kbd>$2prop=parsetree</kbd>).",
        "apihelp-parse-param-preview": "Executar a análise em modo de antevisão.",
        "apihelp-parse-param-sectionpreview": "Executar a análise em modo de antevisão (também ativa o modo de antevisão).",
index e769880..fc0de4e 100644 (file)
        "apihelp-feedrecentchanges-param-tagfilter": "{{doc-apihelp-param|feedrecentchanges|tagfilter}}",
        "apihelp-feedrecentchanges-param-target": "{{doc-apihelp-param|feedrecentchanges|target}}",
        "apihelp-feedrecentchanges-param-showlinkedto": "{{doc-apihelp-param|feedrecentchanges|showlinkedto}}",
-       "apihelp-feedrecentchanges-param-categories": "{{doc-apihelp-param|feedrecentchanges|categories}}",
-       "apihelp-feedrecentchanges-param-categories_any": "{{doc-apihelp-param|feedrecentchanges|categories_any}}",
        "apihelp-feedrecentchanges-example-simple": "{{doc-apihelp-example|feedrecentchanges}}",
        "apihelp-feedrecentchanges-example-30days": "{{doc-apihelp-example|feedrecentchanges}}",
        "apihelp-feedwatchlist-summary": "{{doc-apihelp-summary|feedwatchlist}}",
index 9ee3527..215e2ff 100644 (file)
        "apihelp-feedrecentchanges-param-tagfilter": "Фильтр по меткам.",
        "apihelp-feedrecentchanges-param-target": "Показать только правки на страницах, на которые ссылается данная.",
        "apihelp-feedrecentchanges-param-showlinkedto": "Показать правки на страницах, ссылающихся на данную.",
-       "apihelp-feedrecentchanges-param-categories": "Показать только правки на страницах, включённых во все данные категории.",
-       "apihelp-feedrecentchanges-param-categories_any": "Показать только правки на страницах, включённых в хотя бы одну из данных категорий.",
        "apihelp-feedrecentchanges-example-simple": "Список последних изменений.",
        "apihelp-feedrecentchanges-example-30days": "Список последних изменений за 30 дней.",
        "apihelp-feedwatchlist-summary": "Возвращает ленту списка наблюдения.",
index 8e5228a..e4cff6a 100644 (file)
        "apihelp-feedrecentchanges-param-tagfilter": "Filtrera efter tagg.",
        "apihelp-feedrecentchanges-param-target": "Visa endast ändringarna av sidor som den här sidan länkar till.",
        "apihelp-feedrecentchanges-param-showlinkedto": "Visa ändringarna på sidor som är länkade till den valda sidan i stället.",
-       "apihelp-feedrecentchanges-param-categories": "Visa endast ändringar på sidor i alla dessa kategorier.",
-       "apihelp-feedrecentchanges-param-categories_any": "Visa endast ändringar på sidor i någon av kategorierna istället.",
        "apihelp-feedrecentchanges-example-simple": "Visa senaste ändringar",
        "apihelp-feedrecentchanges-example-30days": "Visa senaste ändringar för 30 dygn",
        "apihelp-feedwatchlist-summary": "Returnerar ett flöde från bevakningslistan.",
index ca0b0a8..f55f65e 100644 (file)
        "apihelp-feedrecentchanges-param-tagfilter": "Фільтрувати за теґом.",
        "apihelp-feedrecentchanges-param-target": "Показати лише зміни на сторінках, на які посилається ця сторінка.",
        "apihelp-feedrecentchanges-param-showlinkedto": "Показати натомість лише зміни на сторінках, які посилаються на цю сторінку.",
-       "apihelp-feedrecentchanges-param-categories": "Показати лише зміни сторінок у всіх цих категоріях.",
-       "apihelp-feedrecentchanges-param-categories_any": "Показати натомість лише зміни на сторінках у будь-якій з цих категорій.",
        "apihelp-feedrecentchanges-example-simple": "Показати нещодавні зміни.",
        "apihelp-feedrecentchanges-example-30days": "Показати нещодавні зміни за 30 днів.",
        "apihelp-feedwatchlist-summary": "Видає стрічку списку спостереження.",
index c081ffc..5eec830 100644 (file)
        "apihelp-feedrecentchanges-param-tagfilter": "按标签过滤。",
        "apihelp-feedrecentchanges-param-target": "仅仅显示从该页面链出的那些页面的变更。",
        "apihelp-feedrecentchanges-param-showlinkedto": "仅仅显示链入到该页面的那些页面的变更。",
-       "apihelp-feedrecentchanges-param-categories": "只显示所有这些分类中的页面上的更改。",
-       "apihelp-feedrecentchanges-param-categories_any": "只显示这些分类以外页面的更改。",
        "apihelp-feedrecentchanges-example-simple": "显示最近更改。",
        "apihelp-feedrecentchanges-example-30days": "显示最近30天的更改。",
        "apihelp-feedwatchlist-summary": "返回监视列表纲要。",
        "apihelp-parse-param-disablepp": "请改用<var>$1disablelimitreport</var>。",
        "apihelp-parse-param-disableeditsection": "从解析器输出中省略编辑段落链接。",
        "apihelp-parse-param-disabletidy": "不要在解析器输出中运行HTML清理(例如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": "在段落预览模式下解析(同时要启用预览模式)。",
index 63c03af..d5ff6cb 100644 (file)
@@ -191,13 +191,11 @@ class MessageCache {
                                // ParserOptions for it. And don't cache this ParserOptions
                                // either.
                                $po = ParserOptions::newFromAnon();
-                               $po->setEditSection( false );
                                $po->setAllowUnsafeRawHtml( false );
                                return $po;
                        }
 
                        $this->mParserOptions = new ParserOptions;
-                       $this->mParserOptions->setEditSection( false );
                        // Messages may take parameters that could come
                        // from malicious sources. As a precaution, disable
                        // the <html> parser tag when parsing messages.
index 0df6828..6c7666f 100644 (file)
@@ -324,7 +324,7 @@ class EnhancedChangesList extends ChangesList {
                                $first--;
                        }
                        # Get net change
-                       $charDifference = $this->formatCharacterDifference( $block[$first], $block[$last] );
+                       $charDifference = $this->formatCharacterDifference( $block[$first], $block[$last] ) ?: false;
                }
 
                $numberofWatchingusers = $this->numberofWatchingusers( $block[0]->numberofWatchingusers );
index eb28b30..156e315 100644 (file)
@@ -61,7 +61,7 @@ class DatabaseOracle extends Database {
        }
 
        function __destruct() {
-               if ( $this->mOpened ) {
+               if ( $this->opened ) {
                        Wikimedia\suppressWarnings();
                        $this->close();
                        Wikimedia\restoreWarnings();
@@ -100,21 +100,21 @@ class DatabaseOracle extends Database {
                }
 
                $this->close();
-               $this->mUser = $user;
-               $this->mPassword = $password;
+               $this->user = $user;
+               $this->password = $password;
                // changed internal variables functions
                // mServer now holds the TNS endpoint
                // mDBname is schema name if different from username
                if ( !$server ) {
                        // backward compatibillity (server used to be null and TNS was supplied in dbname)
-                       $this->mServer = $dbName;
-                       $this->mDBname = $user;
+                       $this->server = $dbName;
+                       $this->dbName = $user;
                } else {
-                       $this->mServer = $server;
+                       $this->server = $server;
                        if ( !$dbName ) {
-                               $this->mDBname = $user;
+                               $this->dbName = $user;
                        } else {
-                               $this->mDBname = $dbName;
+                               $this->dbName = $dbName;
                        }
                }
 
@@ -126,53 +126,53 @@ class DatabaseOracle extends Database {
                        $this->setFlag( DBO_PERSISTENT );
                }
 
-               $session_mode = $this->mFlags & DBO_SYSDBA ? OCI_SYSDBA : OCI_DEFAULT;
+               $session_mode = $this->flags & DBO_SYSDBA ? OCI_SYSDBA : OCI_DEFAULT;
 
                Wikimedia\suppressWarnings();
-               if ( $this->mFlags & DBO_PERSISTENT ) {
-                       $this->mConn = oci_pconnect(
-                               $this->mUser,
-                               $this->mPassword,
-                               $this->mServer,
+               if ( $this->flags & DBO_PERSISTENT ) {
+                       $this->conn = oci_pconnect(
+                               $this->user,
+                               $this->password,
+                               $this->server,
                                $this->defaultCharset,
                                $session_mode
                        );
-               } elseif ( $this->mFlags & DBO_DEFAULT ) {
-                       $this->mConn = oci_new_connect(
-                               $this->mUser,
-                               $this->mPassword,
-                               $this->mServer,
+               } elseif ( $this->flags & DBO_DEFAULT ) {
+                       $this->conn = oci_new_connect(
+                               $this->user,
+                               $this->password,
+                               $this->server,
                                $this->defaultCharset,
                                $session_mode
                        );
                } else {
-                       $this->mConn = oci_connect(
-                               $this->mUser,
-                               $this->mPassword,
-                               $this->mServer,
+                       $this->conn = oci_connect(
+                               $this->user,
+                               $this->password,
+                               $this->server,
                                $this->defaultCharset,
                                $session_mode
                        );
                }
                Wikimedia\restoreWarnings();
 
-               if ( $this->mUser != $this->mDBname ) {
+               if ( $this->user != $this->dbName ) {
                        // change current schema in session
-                       $this->selectDB( $this->mDBname );
+                       $this->selectDB( $this->dbName );
                }
 
-               if ( !$this->mConn ) {
+               if ( !$this->conn ) {
                        throw new DBConnectionError( $this, $this->lastError() );
                }
 
-               $this->mOpened = true;
+               $this->opened = true;
 
                # removed putenv calls because they interfere with the system globaly
                $this->doQuery( 'ALTER SESSION SET NLS_TIMESTAMP_FORMAT=\'DD-MM-YYYY HH24:MI:SS.FF6\'' );
                $this->doQuery( 'ALTER SESSION SET NLS_TIMESTAMP_TZ_FORMAT=\'DD-MM-YYYY HH24:MI:SS.FF6\'' );
                $this->doQuery( 'ALTER SESSION SET NLS_NUMERIC_CHARACTERS=\'.,\'' );
 
-               return $this->mConn;
+               return $this->conn;
        }
 
        /**
@@ -181,11 +181,11 @@ class DatabaseOracle extends Database {
         * @return bool
         */
        protected function closeConnection() {
-               return oci_close( $this->mConn );
+               return oci_close( $this->conn );
        }
 
        function execFlags() {
-               return $this->mTrxLevel ? OCI_NO_AUTO_COMMIT : OCI_COMMIT_ON_SUCCESS;
+               return $this->trxLevel ? OCI_NO_AUTO_COMMIT : OCI_COMMIT_ON_SUCCESS;
        }
 
        protected function doQuery( $sql ) {
@@ -217,9 +217,9 @@ class DatabaseOracle extends Database {
 
                Wikimedia\suppressWarnings();
 
-               $this->mLastResult = $stmt = oci_parse( $this->mConn, $sql );
+               $this->mLastResult = $stmt = oci_parse( $this->conn, $sql );
                if ( $stmt === false ) {
-                       $e = oci_error( $this->mConn );
+                       $e = oci_error( $this->conn );
                        $this->reportQueryError( $e['message'], $e['code'], $sql, __METHOD__ );
 
                        return false;
@@ -335,20 +335,20 @@ class DatabaseOracle extends Database {
        }
 
        function lastError() {
-               if ( $this->mConn === false ) {
+               if ( $this->conn === false ) {
                        $e = oci_error();
                } else {
-                       $e = oci_error( $this->mConn );
+                       $e = oci_error( $this->conn );
                }
 
                return $e['message'];
        }
 
        function lastErrno() {
-               if ( $this->mConn === false ) {
+               if ( $this->conn === false ) {
                        $e = oci_error();
                } else {
-                       $e = oci_error( $this->mConn );
+                       $e = oci_error( $this->conn );
                }
 
                return $e['code'];
@@ -470,9 +470,9 @@ class DatabaseOracle extends Database {
                }
                $sql .= ')';
 
-               $this->mLastResult = $stmt = oci_parse( $this->mConn, $sql );
+               $this->mLastResult = $stmt = oci_parse( $this->conn, $sql );
                if ( $stmt === false ) {
-                       $e = oci_error( $this->mConn );
+                       $e = oci_error( $this->conn );
                        $this->reportQueryError( $e['message'], $e['code'], $sql, __METHOD__ );
 
                        return false;
@@ -502,7 +502,7 @@ class DatabaseOracle extends Database {
                                }
                        } else {
                                /** @var OCI_Lob[] $lob */
-                               $lob[$col] = oci_new_descriptor( $this->mConn, OCI_D_LOB );
+                               $lob[$col] = oci_new_descriptor( $this->conn, OCI_D_LOB );
                                if ( $lob[$col] === false ) {
                                        $e = oci_error( $stmt );
                                        throw new DBUnexpectedError( $this, "Cannot create LOB descriptor: " . $e['message'] );
@@ -545,8 +545,8 @@ class DatabaseOracle extends Database {
                        }
                }
 
-               if ( !$this->mTrxLevel ) {
-                       oci_commit( $this->mConn );
+               if ( !$this->trxLevel ) {
+                       oci_commit( $this->conn );
                }
 
                return oci_free_statement( $stmt );
@@ -658,13 +658,13 @@ class DatabaseOracle extends Database {
                        FROM all_sequences asq, all_tab_columns atc
                        WHERE decode(
                                        atc.table_name,
-                                       '{$this->mTablePrefix}MWUSER',
-                                       '{$this->mTablePrefix}USER',
+                                       '{$this->tablePrefix}MWUSER',
+                                       '{$this->tablePrefix}USER',
                                        atc.table_name
                                ) || '_' ||
-                               atc.column_name || '_SEQ' = '{$this->mTablePrefix}' || asq.sequence_name
-                               AND asq.sequence_owner = upper('{$this->mDBname}')
-                               AND atc.owner = upper('{$this->mDBname}')" );
+                               atc.column_name || '_SEQ' = '{$this->tablePrefix}' || asq.sequence_name
+                               AND asq.sequence_owner = upper('{$this->dbName}')
+                               AND atc.owner = upper('{$this->dbName}')" );
 
                        while ( ( $row = $result->fetchRow() ) !== false ) {
                                $this->sequenceData[$row[1]] = [
@@ -730,9 +730,9 @@ class DatabaseOracle extends Database {
                $newName = strtoupper( $newName );
                $oldName = strtoupper( $oldName );
 
-               $tabName = substr( $newName, strlen( $this->mTablePrefix ) );
+               $tabName = substr( $newName, strlen( $this->tablePrefix ) );
                $oldPrefix = substr( $oldName, 0, strlen( $oldName ) - strlen( $tabName ) );
-               $newPrefix = strtoupper( $this->mTablePrefix );
+               $newPrefix = strtoupper( $this->tablePrefix );
 
                return $this->doQuery( "BEGIN DUPLICATE_TABLE( '$tabName', " .
                        "'$oldPrefix', '$newPrefix', $temporary ); END;" );
@@ -744,7 +744,7 @@ class DatabaseOracle extends Database {
                        $listWhere = ' AND table_name LIKE \'' . strtoupper( $prefix ) . '%\'';
                }
 
-               $owner = strtoupper( $this->mDBname );
+               $owner = strtoupper( $this->dbName );
                $result = $this->doQuery( "SELECT table_name FROM all_tables " .
                        "WHERE owner='$owner' AND table_name NOT LIKE '%!_IDX\$_' ESCAPE '!' $listWhere" );
 
@@ -805,7 +805,7 @@ class DatabaseOracle extends Database {
                );
                $row = $rset->fetchRow();
                if ( !$row ) {
-                       return oci_server_version( $this->mConn );
+                       return oci_server_version( $this->conn );
                }
 
                return $row['version'];
@@ -822,7 +822,7 @@ class DatabaseOracle extends Database {
                $table = $this->tableName( $table );
                $table = strtoupper( $this->removeIdentifierQuotes( $table ) );
                $index = strtoupper( $index );
-               $owner = strtoupper( $this->mDBname );
+               $owner = strtoupper( $this->dbName );
                $sql = "SELECT 1 FROM all_indexes WHERE owner='$owner' AND index_name='{$table}_{$index}'";
                $res = $this->doQuery( $sql );
                if ( $res ) {
@@ -844,7 +844,7 @@ class DatabaseOracle extends Database {
        function tableExists( $table, $fname = __METHOD__ ) {
                $table = $this->tableName( $table );
                $table = $this->addQuotes( strtoupper( $this->removeIdentifierQuotes( $table ) ) );
-               $owner = $this->addQuotes( strtoupper( $this->mDBname ) );
+               $owner = $this->addQuotes( strtoupper( $this->dbName ) );
                $sql = "SELECT 1 FROM all_tables WHERE owner=$owner AND table_name=$table";
                $res = $this->doQuery( $sql );
                if ( $res && $res->numRows() > 0 ) {
@@ -890,7 +890,7 @@ class DatabaseOracle extends Database {
                }
 
                $fieldInfoStmt = oci_parse(
-                       $this->mConn,
+                       $this->conn,
                        'SELECT * FROM wiki_field_info_full WHERE table_name ' .
                                $tableWhere . ' and column_name = \'' . $field . '\''
                );
@@ -935,25 +935,25 @@ class DatabaseOracle extends Database {
        }
 
        protected function doBegin( $fname = __METHOD__ ) {
-               $this->mTrxLevel = 1;
+               $this->trxLevel = 1;
                $this->doQuery( 'SET CONSTRAINTS ALL DEFERRED' );
        }
 
        protected function doCommit( $fname = __METHOD__ ) {
-               if ( $this->mTrxLevel ) {
-                       $ret = oci_commit( $this->mConn );
+               if ( $this->trxLevel ) {
+                       $ret = oci_commit( $this->conn );
                        if ( !$ret ) {
                                throw new DBUnexpectedError( $this, $this->lastError() );
                        }
-                       $this->mTrxLevel = 0;
+                       $this->trxLevel = 0;
                        $this->doQuery( 'SET CONSTRAINTS ALL IMMEDIATE' );
                }
        }
 
        protected function doRollback( $fname = __METHOD__ ) {
-               if ( $this->mTrxLevel ) {
-                       oci_rollback( $this->mConn );
-                       $this->mTrxLevel = 0;
+               if ( $this->trxLevel ) {
+                       oci_rollback( $this->conn );
+                       $this->trxLevel = 0;
                        $this->doQuery( 'SET CONSTRAINTS ALL IMMEDIATE' );
                }
        }
@@ -1041,12 +1041,12 @@ class DatabaseOracle extends Database {
        }
 
        function selectDB( $db ) {
-               $this->mDBname = $db;
-               if ( $db == null || $db == $this->mUser ) {
+               $this->dbName = $db;
+               if ( $db == null || $db == $this->user ) {
                        return true;
                }
                $sql = 'ALTER SESSION SET CURRENT_SCHEMA=' . strtoupper( $db );
-               $stmt = oci_parse( $this->mConn, $sql );
+               $stmt = oci_parse( $this->conn, $sql );
                Wikimedia\suppressWarnings();
                $success = oci_execute( $stmt );
                Wikimedia\restoreWarnings();
@@ -1245,9 +1245,9 @@ class DatabaseOracle extends Database {
                        $sql .= ' WHERE ' . $this->makeList( $conds, LIST_AND );
                }
 
-               $this->mLastResult = $stmt = oci_parse( $this->mConn, $sql );
+               $this->mLastResult = $stmt = oci_parse( $this->conn, $sql );
                if ( $stmt === false ) {
-                       $e = oci_error( $this->mConn );
+                       $e = oci_error( $this->conn );
                        $this->reportQueryError( $e['message'], $e['code'], $sql, __METHOD__ );
 
                        return false;
@@ -1276,7 +1276,7 @@ class DatabaseOracle extends Database {
                                }
                        } else {
                                /** @var OCI_Lob[] $lob */
-                               $lob[$col] = oci_new_descriptor( $this->mConn, OCI_D_LOB );
+                               $lob[$col] = oci_new_descriptor( $this->conn, OCI_D_LOB );
                                if ( $lob[$col] === false ) {
                                        $e = oci_error( $stmt );
                                        throw new DBUnexpectedError( $this, "Cannot create LOB descriptor: " . $e['message'] );
@@ -1319,8 +1319,8 @@ class DatabaseOracle extends Database {
                        }
                }
 
-               if ( !$this->mTrxLevel ) {
-                       oci_commit( $this->mConn );
+               if ( !$this->trxLevel ) {
+                       oci_commit( $this->conn );
                }
 
                return oci_free_statement( $stmt );
@@ -1340,11 +1340,11 @@ class DatabaseOracle extends Database {
        }
 
        function getDBname() {
-               return $this->mDBname;
+               return $this->dbName;
        }
 
        function getServer() {
-               return $this->mServer;
+               return $this->server;
        }
 
        public function buildGroupConcatField(
index 3c4833c..9b25d53 100644 (file)
@@ -106,10 +106,10 @@ class DeferredUpdates {
         *
         * @param callable $callable
         * @param int $stage DeferredUpdates constant (PRESEND or POSTSEND) (since 1.27)
-        * @param IDatabase|null $dbw Abort if this DB is rolled back [optional] (since 1.28)
+        * @param IDatabase|IDatabase[]|null $dbw Abort if this DB is rolled back [optional] (since 1.28)
         */
        public static function addCallableUpdate(
-               $callable, $stage = self::POSTSEND, IDatabase $dbw = null
+               $callable, $stage = self::POSTSEND, $dbw = null
        ) {
                self::addUpdate( new MWCallableUpdate( $callable, wfGetCaller(), $dbw ), $stage );
        }
index 44876a6..2f882b8 100644 (file)
@@ -25,6 +25,8 @@ use Wikimedia\Rdbms\IDatabase;
  * Class for handling updates to the site_stats table
  */
 class SiteStatsUpdate implements DeferrableUpdate, MergeableUpdate {
+       /** @var BagOStuff */
+       protected $stash;
        /** @var int */
        protected $edits = 0;
        /** @var int */
@@ -44,6 +46,8 @@ class SiteStatsUpdate implements DeferrableUpdate, MergeableUpdate {
                $this->articles = $good;
                $this->pages = $pages;
                $this->users = $users;
+
+               $this->stash = MediaWikiServices::getInstance()->getMainObjectStash();
        }
 
        public function merge( MergeableUpdate $update ) {
@@ -72,11 +76,9 @@ class SiteStatsUpdate implements DeferrableUpdate, MergeableUpdate {
        }
 
        public function doUpdate() {
-               global $wgSiteStatsAsyncFactor;
-
                $this->doUpdateContextStats();
 
-               $rate = $wgSiteStatsAsyncFactor; // convenience
+               $rate = MediaWikiServices::getInstance()->getMainConfig()->get( 'SiteStatsAsyncFactor' );
                // If set to do so, only do actual DB updates 1 every $rate times.
                // The other times, just update "pending delta" values in memcached.
                if ( $rate && ( $rate < 0 || mt_rand( 0, $rate - 1 ) != 0 ) ) {
@@ -91,16 +93,15 @@ class SiteStatsUpdate implements DeferrableUpdate, MergeableUpdate {
         * Do not call this outside of SiteStatsUpdate
         */
        public function tryDBUpdateInternal() {
-               global $wgSiteStatsAsyncFactor;
+               $services = MediaWikiServices::getInstance();
+               $config = $services->getMainConfig();
 
-               $dbw = wfGetDB( DB_MASTER );
-               $lockKey = wfWikiID() . ':site_stats'; // prepend wiki ID
+               $dbw = $services->getDBLoadBalancer()->getConnection( DB_MASTER );
+               $lockKey = $dbw->getDomainID() . ':site_stats'; // prepend wiki ID
                $pd = [];
-               if ( $wgSiteStatsAsyncFactor ) {
+               if ( $config->get( 'SiteStatsAsyncFactor' ) ) {
                        // Lock the table so we don't have double DB/memcached updates
-                       if ( !$dbw->lockIsFree( $lockKey, __METHOD__ )
-                               || !$dbw->lock( $lockKey, __METHOD__, 1 ) // 1 sec timeout
-                       ) {
+                       if ( !$dbw->lock( $lockKey, __METHOD__, 0 ) ) {
                                $this->doUpdatePendingDeltas();
 
                                return;
@@ -125,7 +126,7 @@ class SiteStatsUpdate implements DeferrableUpdate, MergeableUpdate {
                        $dbw->update( 'site_stats', [ $updates ], [], __METHOD__ );
                }
 
-               if ( $wgSiteStatsAsyncFactor ) {
+               if ( $config->get( 'SiteStatsAsyncFactor' ) ) {
                        // Decrement the async deltas now that we applied them
                        $this->removePendingDeltas( $pd );
                        // Commit the updates and unlock the table
@@ -140,9 +141,11 @@ class SiteStatsUpdate implements DeferrableUpdate, MergeableUpdate {
         * @param IDatabase $dbw
         * @return bool|mixed
         */
-       public static function cacheUpdate( $dbw ) {
-               global $wgActiveUserDays;
-               $dbr = wfGetDB( DB_REPLICA, 'vslow' );
+       public static function cacheUpdate( IDatabase $dbw ) {
+               $services = MediaWikiServices::getInstance();
+               $config = $services->getMainConfig();
+
+               $dbr = $services->getDBLoadBalancer()->getConnection( DB_REPLICA, 'vslow' );
                # Get non-bot users than did some recent action other than making accounts.
                # If account creation is included, the number gets inflated ~20+ fold on enwiki.
                $activeUsers = $dbr->selectField(
@@ -153,8 +156,8 @@ class SiteStatsUpdate implements DeferrableUpdate, MergeableUpdate {
                                'rc_user != 0',
                                'rc_bot' => 0,
                                'rc_log_type != ' . $dbr->addQuotes( 'newusers' ) . ' OR rc_log_type IS NULL',
-                               'rc_timestamp >= ' . $dbr->addQuotes( $dbr->timestamp( wfTimestamp( TS_UNIX )
-                                       - $wgActiveUserDays * 24 * 3600 ) ),
+                               'rc_timestamp >= ' . $dbr->addQuotes(
+                                       $dbr->timestamp( time() - $config->get( 'ActiveUserDays' ) * 24 * 3600 ) ),
                        ],
                        __METHOD__
                );
@@ -208,13 +211,13 @@ class SiteStatsUpdate implements DeferrableUpdate, MergeableUpdate {
        }
 
        /**
-        * @param BagOStuff $cache
+        * @param BagOStuff $stash
         * @param string $type
         * @param string $sign ('+' or '-')
         * @return string
         */
-       private function getTypeCacheKey( BagOStuff $cache, $type, $sign ) {
-               return $cache->makeKey( 'sitestatsupdate', 'pendingdelta', $type, $sign );
+       private function getTypeCacheKey( BagOStuff $stash, $type, $sign ) {
+               return $stash->makeKey( 'sitestatsupdate', 'pendingdelta', $type, $sign );
        }
 
        /**
@@ -224,15 +227,14 @@ class SiteStatsUpdate implements DeferrableUpdate, MergeableUpdate {
         * @param int $delta Delta (positive or negative)
         */
        protected function adjustPending( $type, $delta ) {
-               $cache = MediaWikiServices::getInstance()->getMainObjectStash();
                if ( $delta < 0 ) { // decrement
-                       $key = $this->getTypeCacheKey( $cache, $type, '-' );
+                       $key = $this->getTypeCacheKey( $this->stash, $type, '-' );
                } else { // increment
-                       $key = $this->getTypeCacheKey( $cache, $type, '+' );
+                       $key = $this->getTypeCacheKey( $this->stash, $type, '+' );
                }
 
                $magnitude = abs( $delta );
-               $cache->incrWithInit( $key, 0, $magnitude, $magnitude );
+               $this->stash->incrWithInit( $key, 0, $magnitude, $magnitude );
        }
 
        /**
@@ -240,16 +242,20 @@ class SiteStatsUpdate implements DeferrableUpdate, MergeableUpdate {
         * @return array Positive and negative deltas for each type
         */
        protected function getPendingDeltas() {
-               $cache = MediaWikiServices::getInstance()->getMainObjectStash();
-
                $pending = [];
                foreach ( [ 'ss_total_edits',
                        'ss_good_articles', 'ss_total_pages', 'ss_users', 'ss_images' ] as $type
                ) {
                        // Get pending increments and pending decrements
                        $flg = BagOStuff::READ_LATEST;
-                       $pending[$type]['+'] = (int)$cache->get( $this->getTypeCacheKey( $cache, $type, '+' ), $flg );
-                       $pending[$type]['-'] = (int)$cache->get( $this->getTypeCacheKey( $cache, $type, '-' ), $flg );
+                       $pending[$type]['+'] = (int)$this->stash->get(
+                               $this->getTypeCacheKey( $this->stash, $type, '+' ),
+                               $flg
+                       );
+                       $pending[$type]['-'] = (int)$this->stash->get(
+                               $this->getTypeCacheKey( $this->stash, $type, '-' ),
+                               $flg
+                       );
                }
 
                return $pending;
@@ -260,12 +266,11 @@ class SiteStatsUpdate implements DeferrableUpdate, MergeableUpdate {
         * @param array $pd Result of getPendingDeltas(), used for DB update
         */
        protected function removePendingDeltas( array $pd ) {
-               $cache = MediaWikiServices::getInstance()->getMainObjectStash();
-
                foreach ( $pd as $type => $deltas ) {
                        foreach ( $deltas as $sign => $magnitude ) {
                                // Lower the pending counter now that we applied these changes
-                               $cache->decr( $this->getTypeCacheKey( $cache, $type, $sign ), $magnitude );
+                               $key = $this->getTypeCacheKey( $this->stash, $type, $sign );
+                               $this->stash->decr( $key, $magnitude );
                        }
                }
        }
index e76bffc..fa30d68 100644 (file)
@@ -658,11 +658,6 @@ class DifferenceEngine extends ContextSource {
         */
        protected function getParserOutput( WikiPage $page, Revision $rev ) {
                $parserOptions = $page->makeParserOptions( $this->getContext() );
-
-               if ( !$rev->isCurrent() || !$rev->getTitle()->quickUserCan( 'edit', $this->getUser() ) ) {
-                       $parserOptions->setEditSection( false );
-               }
-
                $parserOutput = $page->getParserOutput( $parserOptions, $rev->getId() );
 
                return $parserOutput;
index 16f226c..b3e9422 100644 (file)
@@ -189,7 +189,7 @@ class MWException extends Exception {
                } elseif ( self::isCommandLine() ) {
                        $message = $this->getText();
                        // T17602: STDERR may not be available
-                       if ( defined( 'STDERR' ) ) {
+                       if ( !defined( 'MW_PHPUNIT_TEST' ) && defined( 'STDERR' ) ) {
                                fwrite( STDERR, $message );
                        } else {
                                echo $message;
index f22b63d..f5e12d6 100644 (file)
@@ -445,7 +445,6 @@ abstract class Installer {
 
                $this->parserTitle = Title::newFromText( 'Installer' );
                $this->parserOptions = new ParserOptions( $wgUser ); // language will be wrong :(
-               $this->parserOptions->setEditSection( false );
                // Don't try to access DB before user language is initialised
                $this->setParserLanguage( Language::factory( 'en' ) );
        }
@@ -1564,7 +1563,7 @@ abstract class Installer {
                        $user->saveSettings();
 
                        // Update user count
-                       $ssUpdate = new SiteStatsUpdate( 0, 0, 0, 0, 1 );
+                       $ssUpdate = SiteStatsUpdate::factory( [ 'users' => 1 ] );
                        $ssUpdate->doUpdate();
                }
                $status = Status::newGood();
index 5b24d7c..92eef95 100644 (file)
@@ -63,7 +63,7 @@
        "config-apc": "[http://www.php.net/apc APC] ta instaláu",
        "config-apcu": "[http://www.php.net/apcu APCu] ta instaláu",
        "config-wincache": "[https://www.iis.net/download/WinCacheForPhp WinCache] ta instaláu",
-       "config-no-cache-apcu": "<strong>Warning:</strong> Non pudo atopase[http://www.php.net/apcu APCu], [http://xcache.lighttpd.net/ XCache] o [http://www.iis.net/download/WinCacheForPhp WinCache].\nEl caxé d'oxetos nun ta activáu.",
+       "config-no-cache-apcu": "<strong>Atención:</strong> Nun pudo alcontrase [http://www.php.net/apcu APCu] o [http://www.iis.net/download/WinCacheForPhp WinCache].\nLa caché d'oxetos nun ta activada.",
        "config-mod-security": "<strong>Alvertencia:</strong> El to servidor web tien activáu [https://modsecurity.org/mod_security]/mod_security2 .Munches de les sos configuraciones comunes pueden causar problemes a MediaWiki o otru software que dexe a los usuarios publicar conteníu arbitrario. De ser posible, tendríes de desactivalo. Si non, consulta la  [https://modsecurity.org/documentation/ mod_security documentation] o contacta col alministrador del to servidor si atopes erros aleatorios.",
        "config-diff3-bad": "Nun s'alcontró GNU diff3.",
        "config-git": "Alcontróse'l software de control de versiones Git: <code>$1</code>.",
index b15c7f2..da63fdc 100644 (file)
@@ -2,8 +2,18 @@
        "@metadata": {
                "authors": [
                        "Dferg",
-                       "Seb35"
+                       "Seb35",
+                       "MarcoAurelio"
                ]
        },
-       "mainpagedocfooter": "Consulte usted la [https://meta.wikimedia.org/wiki/Help:Contents/es Guía de usuario] para obtener información sobre el uso del software wiki.\n\n== Empezando ==\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Configuration_settings Lista de ajustes de configuración]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ/es FAQ de MediaWiki]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce Lista de correo de anuncios de distribución de MediaWiki]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Localisation#Translation_resources Regionalizar MediaWiki para su idioma]"
+       "config-localsettings-upgrade": "Se ha encontrado un archivo <code>LocalSettings.php</code>.\nPara actualizar esta instalación, escriba el valor de <code>$wgUpgradeKey</code> en el cuadro de abajo.\nLo encontrará en <code>LocalSettings.php</code>.",
+       "config-localsettings-cli-upgrade": "Se ha detectado un archivo <code>LocalSettings.php</code>.\nPara actualizar la instalación, en su lugar ejecute <code>update.php</code>",
+       "config-localsettings-connection-error": "Se ha producido un error al conectar con la base de datos a través de la configuración especificada en <code>LocalSettings.php</code>. Corrija estos ajustes e inténtelo de nuevo.\n\n$1",
+       "config-your-language-help": "Seleccione un idioma para usar durante el proceso de instalación.",
+       "config-page-welcome": "Le damos la bienvenida a MediaWiki.",
+       "config-page-readme": "Léame",
+       "config-help-restart": "¿Desea borrar todos los datos guardados que ha escrito y reiniciar el proceso de instalación?",
+       "config-env-good": "El entorno ha sido comprobado.\nPuede instalar MediaWiki.",
+       "config-env-bad": "El entorno ha sido comprobado.\nNo puede instalar MediaWiki.",
+       "mainpagedocfooter": "Consulte la [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Contents guía] para obtener información sobre el uso del software wiki.\n\n== Primeros pasos ==\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Configuration_settings Lista de ajustes de configuración]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ Preguntas frecuentes sobre MediaWiki]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce Lista de correo de anuncios de publicación de MediaWiki]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Localisation#Translation_resources Traducir MediaWiki a su idioma]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Combating_spam Aprenda a combatir el spam en su wiki]"
 }
index d20b3e7..a7ede0a 100644 (file)
@@ -3,7 +3,8 @@
                "authors": [
                        "McDutchie",
                        "아라",
-                       "Macofe"
+                       "Macofe",
+                       "Fanjiayi"
                ]
        },
        "config-desc": "Le installator de MediaWiki",
@@ -62,8 +63,8 @@
        "config-apc": "[http://www.php.net/apc APC] es installate",
        "config-apcu": "[http://www.php.net/apcu APCu] es installate",
        "config-wincache": "[https://www.iis.net/download/WinCacheForPhp WinCache] es installate",
-       "config-no-cache-apcu": "<strong>Attention:</strong> Impossibile trovar [http://www.php.net/apcu APCu], [http://xcache.lighttpd.net/ XCache] o [http://www.iis.net/download/WinCacheForPhp WinCache].\nLe cache de objectos non es activate.",
-       "config-mod-security": "'''Attention''': [https://modsecurity.org/ mod_security] es active in tu servitor web. Si mal configurate, isto pote causar problemas pro MediaWiki o altere software que permitte al usatores de publicar contento arbitrari.\nConsulta le [https://modsecurity.org/documentation/ documentation de mod_security] o contacta le servicio de adjuta de tu host si tu incontra estranie errores.",
+       "config-no-cache-apcu": "<strong>Attention:</strong> Impossibile trovar [http://www.php.net/apcu APCu] o [http://www.iis.net/download/WinCacheForPhp WinCache].\nLe cache de objectos non es activate.",
+       "config-mod-security": "<strong>Attention</strong>: [https://modsecurity.org/ mod_security]/mod_security2 es active in tu servitor web. Multe configurationes commun de isto causa problemas pro MediaWiki o altere software que permitte al usatores de publicar contento arbitrari. Si possibile, isto deberea esser disactivate.\nAlteremente, consulta le [https://modsecurity.org/documentation/ documentation de mod_security] o contacta le servicio de adjuta de tu servitor si tu incontra estranie errores.",
        "config-diff3-bad": "GNU diff3 non trovate.",
        "config-git": "Systema de controlo de version Git trovate: <code>$1</code>",
        "config-git-bad": "Systema de controlo de version Git non trovate.",
        "config-cache-options": "Configuration del cache de objectos:",
        "config-cache-help": "Le cache de objectos es usate pro meliorar le rapiditate de MediaWiki per immagazinar le datos frequentemente usate.\nLe sitos medie o grande es multo incoragiate de activar isto, ma anque le sitos parve percipera le beneficios.",
        "config-cache-none": "Nulle cache (nulle functionalitate es removite, ma le rapiditate pote diminuer in grande sitos wiki)",
-       "config-cache-accel": "Cache de objectos PHP (APC, APCu, XCache o WinCache)",
+       "config-cache-accel": "Cache de objectos PHP (APC, APCu o WinCache)",
        "config-cache-memcached": "Usar Memcached (require additional installation e configuration)",
        "config-memcached-servers": "Servitores Memcached:",
        "config-memcached-help": "Lista de adresses IP a usar pro Memcached.\nDebe specificar un per linea e specificar le porto a usar. Per exemplo:\n 127.0.0.1:11211\n 192.168.1.25:1234",
index 74b8ac1..0ca73d3 100644 (file)
@@ -68,7 +68,7 @@
        "config-apc": "[http://www.php.net/apc APC] är installerat",
        "config-apcu": "[http://www.php.net/apcu APCu] är installerat",
        "config-wincache": "[https://www.iis.net/download/WinCacheForPhp WinCache] är installerat",
-       "config-no-cache-apcu": "'''Varning:''' Kunde inte hitta [http://www.php.net/apcu APCu], [http://xcache.lighttpd.net/ XCache] eller [http://www.iis.net/download/WinCacheForPhp WinCache].\nCachelagring av objekt är inte aktiverat.",
+       "config-no-cache-apcu": "<strong>Varning:</strong> Kunde inte hitta [http://www.php.net/apcu APCu] eller [http://www.iis.net/download/WinCacheForPhp WinCache].\nCachelagring av objekt är inte aktiverat.",
        "config-mod-security": "'''Varning:''' Din webbserver har [https://modsecurity.org/ mod_security] aktiverat. Om felaktigt konfigurerat kan den skapa problem för MediaWiki eller annan programvara som tillåter användaren att posta godtyckligt innehåll.\nTitta på [https://modsecurity.org/documentation/ mod_security-dokumentationen] eller kontakta din värd om du påträffar slumpmässiga fel.",
        "config-diff3-bad": "GNU diff3 hittades inte.",
        "config-git": "Hittade Git-mjukvara för versionskontroll: <code>$1</code>.",
        "config-cache-options": "Inställningar för cachelagring av objekt:",
        "config-cache-help": "Cachelagring av objekt används för att förbättra hastigheten på MediaWiki genom att cachelagra data som används ofta.\nMedelstora till stora webbplatser är starkt uppmuntrade att aktivera detta, och små webbplatser kommer även att se fördelar.",
        "config-cache-none": "Ingen cachelagring (ingen funktionalitet tas bort, men hastighet kan påverkas på större wiki-webbplatser)",
-       "config-cache-accel": "Cachelagring av PHP-objekt (APC, APCu, XCache eller WinCache)",
+       "config-cache-accel": "Cachelagring av PHP-objekt (APC, APCu eller WinCache)",
        "config-cache-memcached": "Använda Memcached (kräver ytterligare inställningar och konfiguration)",
        "config-memcached-servers": "Memcached-servrar:",
        "config-memcached-help": "Lista över IP-adresser som ska användas för Memcached.\nBör ange en per rad och specificera den port som ska användas. Till exempel:\n 127.0.0.1:11211\n 192.168.1.25:1234",
index a92ae96..d97e4f9 100644 (file)
@@ -76,10 +76,9 @@ class RecentChangesUpdateJob extends Job {
                $lockKey = wfWikiID() . ':recentchanges-prune';
 
                $dbw = wfGetDB( DB_MASTER );
-               if ( !$dbw->lockIsFree( $lockKey, __METHOD__ )
-                       || !$dbw->lock( $lockKey, __METHOD__, 1 )
-               ) {
-                       return; // already in progress
+               if ( !$dbw->lock( $lockKey, __METHOD__, 0 ) ) {
+                       // already in progress
+                       return;
                }
 
                $factory = MediaWikiServices::getInstance()->getDBLoadBalancerFactory();
@@ -138,7 +137,7 @@ class RecentChangesUpdateJob extends Job {
                                $dbw->setSessionOptions( [ 'connTimeout' => 900 ] );
 
                                $lockKey = wfWikiID() . '-activeusers';
-                               if ( !$dbw->lockIsFree( $lockKey, __METHOD__ ) || !$dbw->lock( $lockKey, __METHOD__, 1 ) ) {
+                               if ( !$dbw->lock( $lockKey, __METHOD__, 0 ) ) {
                                        // Exclusive update (avoids duplicate entries)… it's usually fine to just drop out here,
                                        // if the Job is already running.
                                        return;
diff --git a/includes/jobqueue/jobs/UserGroupExpiryJob.php b/includes/jobqueue/jobs/UserGroupExpiryJob.php
new file mode 100644 (file)
index 0000000..0945e58
--- /dev/null
@@ -0,0 +1,39 @@
+<?php
+/**
+ * Job that purges expired user group memberships.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ * @ingroup JobQueue
+ */
+
+class UserGroupExpiryJob extends Job {
+       public function __construct( $params = false ) {
+               parent::__construct( 'userGroupExpiry', Title::newMainPage(), $params );
+               $this->removeDuplicates = true;
+       }
+
+       /**
+        * Run the job
+        * @return bool Success
+        */
+       public function run() {
+               UserGroupMembership::purgeExpired();
+
+               return true;
+       }
+}
index eec766b..58d359c 100644 (file)
@@ -1536,7 +1536,7 @@ class WANObjectCache implements IExpiringStore, LoggerAwareInterface {
        }
 
        /**
-        * Locally set a key to expire soon if it is stale based on $purgeTimestamp
+        * Set a key to soon expire in the local cluster if it pre-dates $purgeTimestamp
         *
         * This sets stale keys' time-to-live at HOLDOFF_TTL seconds, which both avoids
         * broadcasting in mcrouter setups and also avoids races with new tombstones.
@@ -1568,7 +1568,7 @@ class WANObjectCache implements IExpiringStore, LoggerAwareInterface {
        }
 
        /**
-        * Locally set a "check" key to expire soon if it is stale based on $purgeTimestamp
+        * Set a "check" key to soon expire in the local cluster if it pre-dates $purgeTimestamp
         *
         * @param string $key Cache key
         * @param int $purgeTimestamp UNIX timestamp of purge
index d1814e1..9a8996c 100644 (file)
@@ -59,19 +59,19 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
        const SMALL_WRITE_ROWS = 100;
 
        /** @var string SQL query */
-       protected $mLastQuery = '';
+       protected $lastQuery = '';
        /** @var float|bool UNIX timestamp of last write query */
-       protected $mLastWriteTime = false;
+       protected $lastWriteTime = false;
        /** @var string|bool */
-       protected $mPHPError = false;
+       protected $phpError = false;
        /** @var string */
-       protected $mServer;
+       protected $server;
        /** @var string */
-       protected $mUser;
+       protected $user;
        /** @var string */
-       protected $mPassword;
+       protected $password;
        /** @var string */
-       protected $mDBname;
+       protected $dbName;
        /** @var array[] $aliases Map of (table => (dbname, schema, prefix) map) */
        protected $tableAliases = [];
        /** @var bool Whether this PHP instance is for a CLI script */
@@ -89,35 +89,33 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
        protected $errorLogger;
 
        /** @var resource|null Database connection */
-       protected $mConn = null;
+       protected $conn = null;
        /** @var bool */
-       protected $mOpened = false;
+       protected $opened = false;
 
        /** @var array[] List of (callable, method name) */
-       protected $mTrxIdleCallbacks = [];
+       protected $trxIdleCallbacks = [];
        /** @var array[] List of (callable, method name) */
-       protected $mTrxPreCommitCallbacks = [];
+       protected $trxPreCommitCallbacks = [];
        /** @var array[] List of (callable, method name) */
-       protected $mTrxEndCallbacks = [];
+       protected $trxEndCallbacks = [];
        /** @var callable[] Map of (name => callable) */
-       protected $mTrxRecurringCallbacks = [];
+       protected $trxRecurringCallbacks = [];
        /** @var bool Whether to suppress triggering of transaction end callbacks */
-       protected $mTrxEndCallbacksSuppressed = false;
+       protected $trxEndCallbacksSuppressed = false;
 
        /** @var string */
-       protected $mTablePrefix = '';
+       protected $tablePrefix = '';
        /** @var string */
-       protected $mSchema = '';
+       protected $schema = '';
        /** @var int */
-       protected $mFlags;
+       protected $flags;
        /** @var array */
-       protected $mLBInfo = [];
-       /** @var bool|null */
-       protected $mDefaultBigSelects = null;
+       protected $lbInfo = [];
        /** @var array|bool */
-       protected $mSchemaVars = false;
+       protected $schemaVars = false;
        /** @var array */
-       protected $mSessionVars = [];
+       protected $sessionVars = [];
        /** @var array|null */
        protected $preparedArgs;
        /** @var string|bool|null Stashed value of html_errors INI setting */
@@ -135,94 +133,94 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
         *
         * @var int
         */
-       protected $mTrxLevel = 0;
+       protected $trxLevel = 0;
        /**
         * Either a short hexidecimal string if a transaction is active or ""
         *
         * @var string
-        * @see Database::mTrxLevel
+        * @see Database::trxLevel
         */
-       protected $mTrxShortId = '';
+       protected $trxShortId = '';
        /**
         * The UNIX time that the transaction started. Callers can assume that if
         * snapshot isolation is used, then the data is *at least* up to date to that
         * point (possibly more up-to-date since the first SELECT defines the snapshot).
         *
         * @var float|null
-        * @see Database::mTrxLevel
+        * @see Database::trxLevel
         */
-       private $mTrxTimestamp = null;
+       private $trxTimestamp = null;
        /** @var float Lag estimate at the time of BEGIN */
-       private $mTrxReplicaLag = null;
+       private $trxReplicaLag = null;
        /**
         * Remembers the function name given for starting the most recent transaction via begin().
         * Used to provide additional context for error reporting.
         *
         * @var string
-        * @see Database::mTrxLevel
+        * @see Database::trxLevel
         */
-       private $mTrxFname = null;
+       private $trxFname = null;
        /**
         * Record if possible write queries were done in the last transaction started
         *
         * @var bool
-        * @see Database::mTrxLevel
+        * @see Database::trxLevel
         */
-       private $mTrxDoneWrites = false;
+       private $trxDoneWrites = false;
        /**
         * Record if the current transaction was started implicitly due to DBO_TRX being set.
         *
         * @var bool
-        * @see Database::mTrxLevel
+        * @see Database::trxLevel
         */
-       private $mTrxAutomatic = false;
+       private $trxAutomatic = false;
        /**
         * Array of levels of atomicity within transactions
         *
         * @var array
         */
-       private $mTrxAtomicLevels = [];
+       private $trxAtomicLevels = [];
        /**
         * Record if the current transaction was started implicitly by Database::startAtomic
         *
         * @var bool
         */
-       private $mTrxAutomaticAtomic = false;
+       private $trxAutomaticAtomic = false;
        /**
         * Track the write query callers of the current transaction
         *
         * @var string[]
         */
-       private $mTrxWriteCallers = [];
+       private $trxWriteCallers = [];
        /**
         * @var float Seconds spent in write queries for the current transaction
         */
-       private $mTrxWriteDuration = 0.0;
+       private $trxWriteDuration = 0.0;
        /**
         * @var int Number of write queries for the current transaction
         */
-       private $mTrxWriteQueryCount = 0;
+       private $trxWriteQueryCount = 0;
        /**
         * @var int Number of rows affected by write queries for the current transaction
         */
-       private $mTrxWriteAffectedRows = 0;
+       private $trxWriteAffectedRows = 0;
        /**
-        * @var float Like mTrxWriteQueryCount but excludes lock-bound, easy to replicate, queries
+        * @var float Like trxWriteQueryCount but excludes lock-bound, easy to replicate, queries
         */
-       private $mTrxWriteAdjDuration = 0.0;
+       private $trxWriteAdjDuration = 0.0;
        /**
-        * @var int Number of write queries counted in mTrxWriteAdjDuration
+        * @var int Number of write queries counted in trxWriteAdjDuration
         */
-       private $mTrxWriteAdjQueryCount = 0;
+       private $trxWriteAdjQueryCount = 0;
        /**
         * @var float RTT time estimate
         */
-       private $mRTTEstimate = 0.0;
+       private $rttEstimate = 0.0;
 
        /** @var array Map of (name => 1) for locks obtained via lock() */
-       private $mNamedLocksHeld = [];
+       private $namedLocksHeld = [];
        /** @var array Map of (table name => 1) for TEMPORARY tables */
-       protected $mSessionTempTables = [];
+       protected $sessionTempTables = [];
 
        /** @var IDatabase|null Lazy handle to the master DB this server replicates from */
        private $lazyMasterHandle;
@@ -230,7 +228,7 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
        /** @var float UNIX timestamp */
        protected $lastPing = 0.0;
 
-       /** @var int[] Prior mFlags values */
+       /** @var int[] Prior flags member variable values */
        private $priorFlags = [];
 
        /** @var object|string Class name or object With profileIn/profileOut methods */
@@ -252,23 +250,23 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                $password = $params['password'];
                $dbName = $params['dbname'];
 
-               $this->mSchema = $params['schema'];
-               $this->mTablePrefix = $params['tablePrefix'];
+               $this->schema = $params['schema'];
+               $this->tablePrefix = $params['tablePrefix'];
 
                $this->cliMode = $params['cliMode'];
                // Agent name is added to SQL queries in a comment, so make sure it can't break out
                $this->agent = str_replace( '/', '-', $params['agent'] );
 
-               $this->mFlags = $params['flags'];
-               if ( $this->mFlags & self::DBO_DEFAULT ) {
+               $this->flags = $params['flags'];
+               if ( $this->flags & self::DBO_DEFAULT ) {
                        if ( $this->cliMode ) {
-                               $this->mFlags &= ~self::DBO_TRX;
+                               $this->flags &= ~self::DBO_TRX;
                        } else {
-                               $this->mFlags |= self::DBO_TRX;
+                               $this->flags |= self::DBO_TRX;
                        }
                }
 
-               $this->mSessionVars = $params['variables'];
+               $this->sessionVars = $params['variables'];
 
                $this->srvCache = isset( $params['srvCache'] )
                        ? $params['srvCache']
@@ -290,9 +288,9 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                }
 
                // Set the domain object after open() sets the relevant fields
-               if ( $this->mDBname != '' ) {
+               if ( $this->dbName != '' ) {
                        // Domains with server scope but a table prefix are not used by IDatabase classes
-                       $this->currentDomain = new DatabaseDomain( $this->mDBname, null, $this->mTablePrefix );
+                       $this->currentDomain = new DatabaseDomain( $this->dbName, null, $this->tablePrefix );
                }
        }
 
@@ -464,9 +462,9 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                if ( $ignoreErrors !== null ) {
                        // setFlag()/clearFlag() do not allow DBO_IGNORE changes for sanity
                        if ( $ignoreErrors ) {
-                               $this->mFlags |= self::DBO_IGNORE;
+                               $this->flags |= self::DBO_IGNORE;
                        } else {
-                               $this->mFlags &= ~self::DBO_IGNORE;
+                               $this->flags &= ~self::DBO_IGNORE;
                        }
                }
 
@@ -474,19 +472,19 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
        }
 
        public function trxLevel() {
-               return $this->mTrxLevel;
+               return $this->trxLevel;
        }
 
        public function trxTimestamp() {
-               return $this->mTrxLevel ? $this->mTrxTimestamp : null;
+               return $this->trxLevel ? $this->trxTimestamp : null;
        }
 
        public function tablePrefix( $prefix = null ) {
-               $old = $this->mTablePrefix;
+               $old = $this->tablePrefix;
                if ( $prefix !== null ) {
-                       $this->mTablePrefix = $prefix;
-                       $this->currentDomain = ( $this->mDBname != '' )
-                               ? new DatabaseDomain( $this->mDBname, null, $this->mTablePrefix )
+                       $this->tablePrefix = $prefix;
+                       $this->currentDomain = ( $this->dbName != '' )
+                               ? new DatabaseDomain( $this->dbName, null, $this->tablePrefix )
                                : DatabaseDomain::newUnspecified();
                }
 
@@ -494,9 +492,9 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
        }
 
        public function dbSchema( $schema = null ) {
-               $old = $this->mSchema;
+               $old = $this->schema;
                if ( $schema !== null ) {
-                       $this->mSchema = $schema;
+                       $this->schema = $schema;
                }
 
                return $old;
@@ -504,10 +502,10 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
 
        public function getLBInfo( $name = null ) {
                if ( is_null( $name ) ) {
-                       return $this->mLBInfo;
+                       return $this->lbInfo;
                } else {
-                       if ( array_key_exists( $name, $this->mLBInfo ) ) {
-                               return $this->mLBInfo[$name];
+                       if ( array_key_exists( $name, $this->lbInfo ) ) {
+                               return $this->lbInfo[$name];
                        } else {
                                return null;
                        }
@@ -516,9 +514,9 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
 
        public function setLBInfo( $name, $value = null ) {
                if ( is_null( $value ) ) {
-                       $this->mLBInfo = $name;
+                       $this->lbInfo = $name;
                } else {
-                       $this->mLBInfo[$name] = $value;
+                       $this->lbInfo[$name] = $value;
                }
        }
 
@@ -544,55 +542,55 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
        }
 
        public function lastQuery() {
-               return $this->mLastQuery;
+               return $this->lastQuery;
        }
 
        public function doneWrites() {
-               return (bool)$this->mLastWriteTime;
+               return (bool)$this->lastWriteTime;
        }
 
        public function lastDoneWrites() {
-               return $this->mLastWriteTime ?: false;
+               return $this->lastWriteTime ?: false;
        }
 
        public function writesPending() {
-               return $this->mTrxLevel && $this->mTrxDoneWrites;
+               return $this->trxLevel && $this->trxDoneWrites;
        }
 
        public function writesOrCallbacksPending() {
-               return $this->mTrxLevel && (
-                       $this->mTrxDoneWrites || $this->mTrxIdleCallbacks || $this->mTrxPreCommitCallbacks
+               return $this->trxLevel && (
+                       $this->trxDoneWrites || $this->trxIdleCallbacks || $this->trxPreCommitCallbacks
                );
        }
 
        public function pendingWriteQueryDuration( $type = self::ESTIMATE_TOTAL ) {
-               if ( !$this->mTrxLevel ) {
+               if ( !$this->trxLevel ) {
                        return false;
-               } elseif ( !$this->mTrxDoneWrites ) {
+               } elseif ( !$this->trxDoneWrites ) {
                        return 0.0;
                }
 
                switch ( $type ) {
                        case self::ESTIMATE_DB_APPLY:
                                $this->ping( $rtt );
-                               $rttAdjTotal = $this->mTrxWriteAdjQueryCount * $rtt;
-                               $applyTime = max( $this->mTrxWriteAdjDuration - $rttAdjTotal, 0 );
+                               $rttAdjTotal = $this->trxWriteAdjQueryCount * $rtt;
+                               $applyTime = max( $this->trxWriteAdjDuration - $rttAdjTotal, 0 );
                                // For omitted queries, make them count as something at least
-                               $omitted = $this->mTrxWriteQueryCount - $this->mTrxWriteAdjQueryCount;
+                               $omitted = $this->trxWriteQueryCount - $this->trxWriteAdjQueryCount;
                                $applyTime += self::TINY_WRITE_SEC * $omitted;
 
                                return $applyTime;
                        default: // everything
-                               return $this->mTrxWriteDuration;
+                               return $this->trxWriteDuration;
                }
        }
 
        public function pendingWriteCallers() {
-               return $this->mTrxLevel ? $this->mTrxWriteCallers : [];
+               return $this->trxLevel ? $this->trxWriteCallers : [];
        }
 
        public function pendingWriteRowsAffected() {
-               return $this->mTrxWriteAffectedRows;
+               return $this->trxWriteAffectedRows;
        }
 
        /**
@@ -602,15 +600,15 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
         * @return array
         */
        protected function pendingWriteAndCallbackCallers() {
-               if ( !$this->mTrxLevel ) {
+               if ( !$this->trxLevel ) {
                        return [];
                }
 
-               $fnames = $this->mTrxWriteCallers;
+               $fnames = $this->trxWriteCallers;
                foreach ( [
-                       $this->mTrxIdleCallbacks,
-                       $this->mTrxPreCommitCallbacks,
-                       $this->mTrxEndCallbacks
+                       $this->trxIdleCallbacks,
+                       $this->trxPreCommitCallbacks,
+                       $this->trxEndCallbacks
                ] as $callbacks ) {
                        foreach ( $callbacks as $callback ) {
                                $fnames[] = $callback[1];
@@ -621,7 +619,7 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
        }
 
        public function isOpen() {
-               return $this->mOpened;
+               return $this->opened;
        }
 
        public function setFlag( $flag, $remember = self::REMEMBER_NOTHING ) {
@@ -630,9 +628,9 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                }
 
                if ( $remember === self::REMEMBER_PRIOR ) {
-                       array_push( $this->priorFlags, $this->mFlags );
+                       array_push( $this->priorFlags, $this->flags );
                }
-               $this->mFlags |= $flag;
+               $this->flags |= $flag;
        }
 
        public function clearFlag( $flag, $remember = self::REMEMBER_NOTHING ) {
@@ -641,9 +639,9 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                }
 
                if ( $remember === self::REMEMBER_PRIOR ) {
-                       array_push( $this->priorFlags, $this->mFlags );
+                       array_push( $this->priorFlags, $this->flags );
                }
-               $this->mFlags &= ~$flag;
+               $this->flags &= ~$flag;
        }
 
        public function restoreFlags( $state = self::RESTORE_PRIOR ) {
@@ -652,15 +650,15 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                }
 
                if ( $state === self::RESTORE_INITIAL ) {
-                       $this->mFlags = reset( $this->priorFlags );
+                       $this->flags = reset( $this->priorFlags );
                        $this->priorFlags = [];
                } else {
-                       $this->mFlags = array_pop( $this->priorFlags );
+                       $this->flags = array_pop( $this->priorFlags );
                }
        }
 
        public function getFlag( $flag ) {
-               return !!( $this->mFlags & $flag );
+               return !!( $this->flags & $flag );
        }
 
        /**
@@ -701,7 +699,7 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
         * Set a custom error handler for logging errors during database connection
         */
        protected function installErrorHandler() {
-               $this->mPHPError = false;
+               $this->phpError = false;
                $this->htmlErrors = ini_set( 'html_errors', '0' );
                set_error_handler( [ $this, 'connectionErrorLogger' ] );
        }
@@ -724,8 +722,8 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
         * @return string|bool Last PHP error for this DB (typically connection errors)
         */
        protected function getLastPHPError() {
-               if ( $this->mPHPError ) {
-                       $error = preg_replace( '!\[<a.*</a>\]!', '', $this->mPHPError );
+               if ( $this->phpError ) {
+                       $error = preg_replace( '!\[<a.*</a>\]!', '', $this->phpError );
                        $error = preg_replace( '!^.*?:\s?(.*)$!', '$1', $error );
 
                        return $error;
@@ -742,7 +740,7 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
         * @param string $errstr
         */
        public function connectionErrorLogger( $errno, $errstr ) {
-               $this->mPHPError = $errstr;
+               $this->phpError = $errstr;
        }
 
        /**
@@ -754,32 +752,32 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
        protected function getLogContext( array $extras = [] ) {
                return array_merge(
                        [
-                               'db_server' => $this->mServer,
-                               'db_name' => $this->mDBname,
-                               'db_user' => $this->mUser,
+                               'db_server' => $this->server,
+                               'db_name' => $this->dbName,
+                               'db_user' => $this->user,
                        ],
                        $extras
                );
        }
 
        public function close() {
-               if ( $this->mConn ) {
+               if ( $this->conn ) {
                        if ( $this->trxLevel() ) {
                                $this->commit( __METHOD__, self::FLUSHING_INTERNAL );
                        }
 
                        $closed = $this->closeConnection();
-                       $this->mConn = false;
+                       $this->conn = false;
                } elseif (
-                       $this->mTrxIdleCallbacks ||
-                       $this->mTrxPreCommitCallbacks ||
-                       $this->mTrxEndCallbacks
+                       $this->trxIdleCallbacks ||
+                       $this->trxPreCommitCallbacks ||
+                       $this->trxEndCallbacks
                ) { // sanity
                        throw new RuntimeException( "Transaction callbacks still pending." );
                } else {
                        $closed = true;
                }
-               $this->mOpened = false;
+               $this->opened = false;
 
                return $closed;
        }
@@ -868,7 +866,7 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                        $sql,
                        $matches
                ) ) {
-                       $this->mSessionTempTables[$matches[1]] = 1;
+                       $this->sessionTempTables[$matches[1]] = 1;
 
                        return true;
                } elseif ( preg_match(
@@ -876,8 +874,8 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                        $sql,
                        $matches
                ) ) {
-                       $isTemp = isset( $this->mSessionTempTables[$matches[1]] );
-                       unset( $this->mSessionTempTables[$matches[1]] );
+                       $isTemp = isset( $this->sessionTempTables[$matches[1]] );
+                       unset( $this->sessionTempTables[$matches[1]] );
 
                        return $isTemp;
                } elseif ( preg_match(
@@ -885,13 +883,13 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                        $sql,
                        $matches
                ) ) {
-                       return isset( $this->mSessionTempTables[$matches[1]] );
+                       return isset( $this->sessionTempTables[$matches[1]] );
                } elseif ( preg_match(
                        '/^(?:INSERT\s+(?:\w+\s+)?INTO|UPDATE|DELETE\s+FROM)\s+[`"\']?(\w+)[`"\']?/i',
                        $sql,
                        $matches
                ) ) {
-                       return isset( $this->mSessionTempTables[$matches[1]] );
+                       return isset( $this->sessionTempTables[$matches[1]] );
                }
 
                return false;
@@ -899,7 +897,7 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
 
        public function query( $sql, $fname = __METHOD__, $tempIgnore = false ) {
                $priorWritesPending = $this->writesOrCallbacksPending();
-               $this->mLastQuery = $sql;
+               $this->lastQuery = $sql;
 
                $isWrite = $this->isWriteQuery( $sql );
                if ( $isWrite ) {
@@ -922,7 +920,7 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                                throw new DBReadOnlyError( $this, "Database is read-only: $reason" );
                        }
                        # Set a flag indicating that writes have been done
-                       $this->mLastWriteTime = microtime( true );
+                       $this->lastWriteTime = microtime( true );
                }
 
                # Add trace comment to the begin of the sql string, right after the operator.
@@ -930,22 +928,22 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                $commentedSql = preg_replace( '/\s|$/', " /* $fname {$this->agent} */ ", $sql, 1 );
 
                # Start implicit transactions that wrap the request if DBO_TRX is enabled
-               if ( !$this->mTrxLevel && $this->getFlag( self::DBO_TRX )
+               if ( !$this->trxLevel && $this->getFlag( self::DBO_TRX )
                        && $this->isTransactableQuery( $sql )
                ) {
                        $this->begin( __METHOD__ . " ($fname)", self::TRANSACTION_INTERNAL );
-                       $this->mTrxAutomatic = true;
+                       $this->trxAutomatic = true;
                }
 
                # Keep track of whether the transaction has write queries pending
-               if ( $this->mTrxLevel && !$this->mTrxDoneWrites && $isWrite ) {
-                       $this->mTrxDoneWrites = true;
+               if ( $this->trxLevel && !$this->trxDoneWrites && $isWrite ) {
+                       $this->trxDoneWrites = true;
                        $this->trxProfiler->transactionWritingIn(
-                               $this->mServer, $this->mDBname, $this->mTrxShortId );
+                               $this->server, $this->dbName, $this->trxShortId );
                }
 
                if ( $this->getFlag( self::DBO_DEBUG ) ) {
-                       $this->queryLogger->debug( "{$this->mDBname} {$commentedSql}" );
+                       $this->queryLogger->debug( "{$this->dbName} {$commentedSql}" );
                }
 
                # Avoid fatals if close() was called
@@ -1024,7 +1022,7 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                }
 
                # Include query transaction state
-               $queryProf .= $this->mTrxShortId ? " [TRX#{$this->mTrxShortId}]" : "";
+               $queryProf .= $this->trxShortId ? " [TRX#{$this->trxShortId}]" : "";
 
                $startTime = microtime( true );
                if ( $this->profiler ) {
@@ -1042,14 +1040,14 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
 
                if ( $ret !== false ) {
                        $this->lastPing = $startTime;
-                       if ( $isWrite && $this->mTrxLevel ) {
+                       if ( $isWrite && $this->trxLevel ) {
                                $this->updateTrxWriteQueryTime( $sql, $queryRuntime, $this->affectedRows() );
-                               $this->mTrxWriteCallers[] = $fname;
+                               $this->trxWriteCallers[] = $fname;
                        }
                }
 
                if ( $sql === self::PING_QUERY ) {
-                       $this->mRTTEstimate = $queryRuntime;
+                       $this->rttEstimate = $queryRuntime;
                }
 
                $this->trxProfiler->recordQueryCompletion(
@@ -1089,12 +1087,12 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                        }
                }
 
-               $this->mTrxWriteDuration += $runtime;
-               $this->mTrxWriteQueryCount += 1;
-               $this->mTrxWriteAffectedRows += $affected;
+               $this->trxWriteDuration += $runtime;
+               $this->trxWriteQueryCount += 1;
+               $this->trxWriteAffectedRows += $affected;
                if ( $indicativeOfReplicaRuntime ) {
-                       $this->mTrxWriteAdjDuration += $runtime;
-                       $this->mTrxWriteAdjQueryCount += 1;
+                       $this->trxWriteAdjDuration += $runtime;
+                       $this->trxWriteAdjQueryCount += 1;
                }
        }
 
@@ -1113,7 +1111,7 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                # Dropped connections also mean that named locks are automatically released.
                # Only allow error suppression in autocommit mode or when the lost transaction
                # didn't matter anyway (aside from DBO_TRX snapshot loss).
-               if ( $this->mNamedLocksHeld ) {
+               if ( $this->namedLocksHeld ) {
                        return false; // possible critical section violation
                } elseif ( $sql === 'COMMIT' ) {
                        return !$priorWritesPending; // nothing written anyway? (T127428)
@@ -1134,13 +1132,13 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
         * @return null|Exception
         */
        private function handleSessionLoss() {
-               $this->mTrxLevel = 0;
-               $this->mTrxIdleCallbacks = []; // T67263
-               $this->mTrxPreCommitCallbacks = []; // T67263
-               $this->mSessionTempTables = [];
-               $this->mNamedLocksHeld = [];
+               $this->trxLevel = 0;
+               $this->trxIdleCallbacks = []; // T67263
+               $this->trxPreCommitCallbacks = []; // T67263
+               $this->sessionTempTables = [];
+               $this->namedLocksHeld = [];
                try {
-                       // Handle callbacks in mTrxEndCallbacks
+                       // Handle callbacks in trxEndCallbacks
                        $this->runOnTransactionIdleCallbacks( self::TRIGGER_ROLLBACK );
                        $this->runTransactionListenerCallbacks( self::TRIGGER_ROLLBACK );
                        return null;
@@ -1405,13 +1403,9 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                                $this->tableNamesWithIndexClauseOrJOIN(
                                        $table, $useIndexes, $ignoreIndexes, $join_conds );
                } elseif ( $table != '' ) {
-                       if ( $table[0] == ' ' ) {
-                               $from = ' FROM ' . $table;
-                       } else {
-                               $from = ' FROM ' .
-                                       $this->tableNamesWithIndexClauseOrJOIN(
-                                               [ $table ], $useIndexes, $ignoreIndexes, [] );
-                       }
+                       $from = ' FROM ' .
+                               $this->tableNamesWithIndexClauseOrJOIN(
+                                       [ $table ], $useIndexes, $ignoreIndexes, [] );
                } else {
                        $from = '';
                }
@@ -1545,7 +1539,7 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
 
        public function tableExists( $table, $fname = __METHOD__ ) {
                $tableRaw = $this->tableName( $table, 'raw' );
-               if ( isset( $this->mSessionTempTables[$tableRaw] ) ) {
+               if ( isset( $this->sessionTempTables[$tableRaw] ) ) {
                        return true; // already known to exist
                }
 
@@ -1811,17 +1805,17 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                # Stub. Shouldn't cause serious problems if it's not overridden, but
                # if your database engine supports a concept similar to MySQL's
                # databases you may as well.
-               $this->mDBname = $db;
+               $this->dbName = $db;
 
                return true;
        }
 
        public function getDBname() {
-               return $this->mDBname;
+               return $this->dbName;
        }
 
        public function getServer() {
-               return $this->mServer;
+               return $this->server;
        }
 
        public function tableName( $name, $format = 'quoted' ) {
@@ -1890,14 +1884,14 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                                $database = $this->tableAliases[$table]['dbname'];
                                $schema = is_string( $this->tableAliases[$table]['schema'] )
                                        ? $this->tableAliases[$table]['schema']
-                                       : $this->mSchema;
+                                       : $this->schema;
                                $prefix = is_string( $this->tableAliases[$table]['prefix'] )
                                        ? $this->tableAliases[$table]['prefix']
-                                       : $this->mTablePrefix;
+                                       : $this->tablePrefix;
                        } else {
                                $database = '';
-                               $schema = $this->mSchema; # Default schema
-                               $prefix = $this->mTablePrefix; # Default prefix
+                               $schema = $this->schema; # Default schema
+                               $prefix = $this->tablePrefix; # Default prefix
                        }
                }
 
@@ -2349,7 +2343,7 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                }
 
                $affectedRowCount = 0;
-               $useTrx = !$this->mTrxLevel;
+               $useTrx = !$this->trxLevel;
                if ( $useTrx ) {
                        $this->begin( $fname, self::TRANSACTION_INTERNAL );
                }
@@ -2756,25 +2750,25 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
        }
 
        final public function onTransactionResolution( callable $callback, $fname = __METHOD__ ) {
-               if ( !$this->mTrxLevel ) {
+               if ( !$this->trxLevel ) {
                        throw new DBUnexpectedError( $this, "No transaction is active." );
                }
-               $this->mTrxEndCallbacks[] = [ $callback, $fname ];
+               $this->trxEndCallbacks[] = [ $callback, $fname ];
        }
 
        final public function onTransactionIdle( callable $callback, $fname = __METHOD__ ) {
-               $this->mTrxIdleCallbacks[] = [ $callback, $fname ];
-               if ( !$this->mTrxLevel ) {
+               $this->trxIdleCallbacks[] = [ $callback, $fname ];
+               if ( !$this->trxLevel ) {
                        $this->runOnTransactionIdleCallbacks( self::TRIGGER_IDLE );
                }
        }
 
        final public function onTransactionPreCommitOrIdle( callable $callback, $fname = __METHOD__ ) {
-               if ( $this->mTrxLevel || $this->getFlag( self::DBO_TRX ) ) {
+               if ( $this->trxLevel || $this->getFlag( self::DBO_TRX ) ) {
                        // As long as DBO_TRX is set, writes will accumulate until the load balancer issues
                        // an implicit commit of all peer databases. This is true even if a transaction has
                        // not yet been triggered by writes; make sure $callback runs *after* any such writes.
-                       $this->mTrxPreCommitCallbacks[] = [ $callback, $fname ];
+                       $this->trxPreCommitCallbacks[] = [ $callback, $fname ];
                } else {
                        // No transaction is active nor will start implicitly, so make one for this callback
                        $this->startAtomic( __METHOD__ );
@@ -2790,9 +2784,9 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
 
        final public function setTransactionListener( $name, callable $callback = null ) {
                if ( $callback ) {
-                       $this->mTrxRecurringCallbacks[$name] = $callback;
+                       $this->trxRecurringCallbacks[$name] = $callback;
                } else {
-                       unset( $this->mTrxRecurringCallbacks[$name] );
+                       unset( $this->trxRecurringCallbacks[$name] );
                }
        }
 
@@ -2805,7 +2799,7 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
         * @since 1.28
         */
        final public function setTrxEndCallbackSuppression( $suppress ) {
-               $this->mTrxEndCallbacksSuppressed = $suppress;
+               $this->trxEndCallbacksSuppressed = $suppress;
        }
 
        /**
@@ -2818,7 +2812,7 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
         * @throws Exception
         */
        public function runOnTransactionIdleCallbacks( $trigger ) {
-               if ( $this->mTrxEndCallbacksSuppressed ) {
+               if ( $this->trxEndCallbacksSuppressed ) {
                        return;
                }
 
@@ -2827,11 +2821,11 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                $e = null; // first exception
                do { // callbacks may add callbacks :)
                        $callbacks = array_merge(
-                               $this->mTrxIdleCallbacks,
-                               $this->mTrxEndCallbacks // include "transaction resolution" callbacks
+                               $this->trxIdleCallbacks,
+                               $this->trxEndCallbacks // include "transaction resolution" callbacks
                        );
-                       $this->mTrxIdleCallbacks = []; // consumed (and recursion guard)
-                       $this->mTrxEndCallbacks = []; // consumed (recursion guard)
+                       $this->trxIdleCallbacks = []; // consumed (and recursion guard)
+                       $this->trxEndCallbacks = []; // consumed (recursion guard)
                        foreach ( $callbacks as $callback ) {
                                try {
                                        list( $phpCallback ) = $callback;
@@ -2852,7 +2846,7 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                                        }
                                }
                        }
-               } while ( count( $this->mTrxIdleCallbacks ) );
+               } while ( count( $this->trxIdleCallbacks ) );
 
                if ( $e instanceof Exception ) {
                        throw $e; // re-throw any first exception
@@ -2870,8 +2864,8 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
        public function runOnTransactionPreCommitCallbacks() {
                $e = null; // first exception
                do { // callbacks may add callbacks :)
-                       $callbacks = $this->mTrxPreCommitCallbacks;
-                       $this->mTrxPreCommitCallbacks = []; // consumed (and recursion guard)
+                       $callbacks = $this->trxPreCommitCallbacks;
+                       $this->trxPreCommitCallbacks = []; // consumed (and recursion guard)
                        foreach ( $callbacks as $callback ) {
                                try {
                                        list( $phpCallback ) = $callback;
@@ -2881,7 +2875,7 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                                        $e = $e ?: $ex;
                                }
                        }
-               } while ( count( $this->mTrxPreCommitCallbacks ) );
+               } while ( count( $this->trxPreCommitCallbacks ) );
 
                if ( $e instanceof Exception ) {
                        throw $e; // re-throw any first exception
@@ -2898,14 +2892,14 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
         * @since 1.20
         */
        public function runTransactionListenerCallbacks( $trigger ) {
-               if ( $this->mTrxEndCallbacksSuppressed ) {
+               if ( $this->trxEndCallbacksSuppressed ) {
                        return;
                }
 
                /** @var Exception $e */
                $e = null; // first exception
 
-               foreach ( $this->mTrxRecurringCallbacks as $phpCallback ) {
+               foreach ( $this->trxRecurringCallbacks as $phpCallback ) {
                        try {
                                $phpCallback( $trigger, $this );
                        } catch ( Exception $ex ) {
@@ -2920,29 +2914,29 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
        }
 
        final public function startAtomic( $fname = __METHOD__ ) {
-               if ( !$this->mTrxLevel ) {
+               if ( !$this->trxLevel ) {
                        $this->begin( $fname, self::TRANSACTION_INTERNAL );
                        // If DBO_TRX is set, a series of startAtomic/endAtomic pairs will result
                        // in all changes being in one transaction to keep requests transactional.
                        if ( !$this->getFlag( self::DBO_TRX ) ) {
-                               $this->mTrxAutomaticAtomic = true;
+                               $this->trxAutomaticAtomic = true;
                        }
                }
 
-               $this->mTrxAtomicLevels[] = $fname;
+               $this->trxAtomicLevels[] = $fname;
        }
 
        final public function endAtomic( $fname = __METHOD__ ) {
-               if ( !$this->mTrxLevel ) {
+               if ( !$this->trxLevel ) {
                        throw new DBUnexpectedError( $this, "No atomic transaction is open (got $fname)." );
                }
-               if ( !$this->mTrxAtomicLevels ||
-                       array_pop( $this->mTrxAtomicLevels ) !== $fname
+               if ( !$this->trxAtomicLevels ||
+                       array_pop( $this->trxAtomicLevels ) !== $fname
                ) {
                        throw new DBUnexpectedError( $this, "Invalid atomic section ended (got $fname)." );
                }
 
-               if ( !$this->mTrxAtomicLevels && $this->mTrxAutomaticAtomic ) {
+               if ( !$this->trxAtomicLevels && $this->trxAutomaticAtomic ) {
                        $this->commit( $fname, self::FLUSHING_INTERNAL );
                }
        }
@@ -2962,17 +2956,17 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
 
        final public function begin( $fname = __METHOD__, $mode = self::TRANSACTION_EXPLICIT ) {
                // Protect against mismatched atomic section, transaction nesting, and snapshot loss
-               if ( $this->mTrxLevel ) {
-                       if ( $this->mTrxAtomicLevels ) {
-                               $levels = implode( ', ', $this->mTrxAtomicLevels );
+               if ( $this->trxLevel ) {
+                       if ( $this->trxAtomicLevels ) {
+                               $levels = implode( ', ', $this->trxAtomicLevels );
                                $msg = "$fname: Got explicit BEGIN while atomic section(s) $levels are open.";
                                throw new DBUnexpectedError( $this, $msg );
-                       } elseif ( !$this->mTrxAutomatic ) {
-                               $msg = "$fname: Explicit transaction already active (from {$this->mTrxFname}).";
+                       } elseif ( !$this->trxAutomatic ) {
+                               $msg = "$fname: Explicit transaction already active (from {$this->trxFname}).";
                                throw new DBUnexpectedError( $this, $msg );
                        } else {
                                // @TODO: make this an exception at some point
-                               $msg = "$fname: Implicit transaction already active (from {$this->mTrxFname}).";
+                               $msg = "$fname: Implicit transaction already active (from {$this->trxFname}).";
                                $this->queryLogger->error( $msg );
                                return; // join the main transaction set
                        }
@@ -2987,27 +2981,27 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                $this->assertOpen();
 
                $this->doBegin( $fname );
-               $this->mTrxTimestamp = microtime( true );
-               $this->mTrxFname = $fname;
-               $this->mTrxDoneWrites = false;
-               $this->mTrxAutomaticAtomic = false;
-               $this->mTrxAtomicLevels = [];
-               $this->mTrxShortId = sprintf( '%06x', mt_rand( 0, 0xffffff ) );
-               $this->mTrxWriteDuration = 0.0;
-               $this->mTrxWriteQueryCount = 0;
-               $this->mTrxWriteAffectedRows = 0;
-               $this->mTrxWriteAdjDuration = 0.0;
-               $this->mTrxWriteAdjQueryCount = 0;
-               $this->mTrxWriteCallers = [];
+               $this->trxTimestamp = microtime( true );
+               $this->trxFname = $fname;
+               $this->trxDoneWrites = false;
+               $this->trxAutomaticAtomic = false;
+               $this->trxAtomicLevels = [];
+               $this->trxShortId = sprintf( '%06x', mt_rand( 0, 0xffffff ) );
+               $this->trxWriteDuration = 0.0;
+               $this->trxWriteQueryCount = 0;
+               $this->trxWriteAffectedRows = 0;
+               $this->trxWriteAdjDuration = 0.0;
+               $this->trxWriteAdjQueryCount = 0;
+               $this->trxWriteCallers = [];
                // First SELECT after BEGIN will establish the snapshot in REPEATABLE-READ.
                // Get an estimate of the replica DB lag before then, treating estimate staleness
                // as lag itself just to be safe
                $status = $this->getApproximateLagStatus();
-               $this->mTrxReplicaLag = $status['lag'] + ( microtime( true ) - $status['since'] );
+               $this->trxReplicaLag = $status['lag'] + ( microtime( true ) - $status['since'] );
                // T147697: make explicitTrxActive() return true until begin() finishes. This way, no
                // caller will think its OK to muck around with the transaction just because startAtomic()
-               // has not yet completed (e.g. setting mTrxAtomicLevels).
-               $this->mTrxAutomatic = ( $mode === self::TRANSACTION_INTERNAL );
+               // has not yet completed (e.g. setting trxAtomicLevels).
+               $this->trxAutomatic = ( $mode === self::TRANSACTION_INTERNAL );
        }
 
        /**
@@ -3018,13 +3012,13 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
         */
        protected function doBegin( $fname ) {
                $this->query( 'BEGIN', $fname );
-               $this->mTrxLevel = 1;
+               $this->trxLevel = 1;
        }
 
        final public function commit( $fname = __METHOD__, $flush = '' ) {
-               if ( $this->mTrxLevel && $this->mTrxAtomicLevels ) {
+               if ( $this->trxLevel && $this->trxAtomicLevels ) {
                        // There are still atomic sections open. This cannot be ignored
-                       $levels = implode( ', ', $this->mTrxAtomicLevels );
+                       $levels = implode( ', ', $this->trxAtomicLevels );
                        throw new DBUnexpectedError(
                                $this,
                                "$fname: Got COMMIT while atomic sections $levels are still open."
@@ -3032,20 +3026,20 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                }
 
                if ( $flush === self::FLUSHING_INTERNAL || $flush === self::FLUSHING_ALL_PEERS ) {
-                       if ( !$this->mTrxLevel ) {
+                       if ( !$this->trxLevel ) {
                                return; // nothing to do
-                       } elseif ( !$this->mTrxAutomatic ) {
+                       } elseif ( !$this->trxAutomatic ) {
                                throw new DBUnexpectedError(
                                        $this,
                                        "$fname: Flushing an explicit transaction, getting out of sync."
                                );
                        }
                } else {
-                       if ( !$this->mTrxLevel ) {
+                       if ( !$this->trxLevel ) {
                                $this->queryLogger->error(
                                        "$fname: No transaction to commit, something got out of sync." );
                                return; // nothing to do
-                       } elseif ( $this->mTrxAutomatic ) {
+                       } elseif ( $this->trxAutomatic ) {
                                // @TODO: make this an exception at some point
                                $msg = "$fname: Explicit commit of implicit transaction.";
                                $this->queryLogger->error( $msg );
@@ -3059,14 +3053,14 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                $this->runOnTransactionPreCommitCallbacks();
                $writeTime = $this->pendingWriteQueryDuration( self::ESTIMATE_DB_APPLY );
                $this->doCommit( $fname );
-               if ( $this->mTrxDoneWrites ) {
-                       $this->mLastWriteTime = microtime( true );
+               if ( $this->trxDoneWrites ) {
+                       $this->lastWriteTime = microtime( true );
                        $this->trxProfiler->transactionWritingOut(
-                               $this->mServer,
-                               $this->mDBname,
-                               $this->mTrxShortId,
+                               $this->server,
+                               $this->dbName,
+                               $this->trxShortId,
                                $writeTime,
-                               $this->mTrxWriteAffectedRows
+                               $this->trxWriteAffectedRows
                        );
                }
 
@@ -3081,19 +3075,19 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
         * @param string $fname
         */
        protected function doCommit( $fname ) {
-               if ( $this->mTrxLevel ) {
+               if ( $this->trxLevel ) {
                        $this->query( 'COMMIT', $fname );
-                       $this->mTrxLevel = 0;
+                       $this->trxLevel = 0;
                }
        }
 
        final public function rollback( $fname = __METHOD__, $flush = '' ) {
                if ( $flush === self::FLUSHING_INTERNAL || $flush === self::FLUSHING_ALL_PEERS ) {
-                       if ( !$this->mTrxLevel ) {
+                       if ( !$this->trxLevel ) {
                                return; // nothing to do
                        }
                } else {
-                       if ( !$this->mTrxLevel ) {
+                       if ( !$this->trxLevel ) {
                                $this->queryLogger->error(
                                        "$fname: No transaction to rollback, something got out of sync." );
                                return; // nothing to do
@@ -3109,17 +3103,17 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                $this->assertOpen();
 
                $this->doRollback( $fname );
-               $this->mTrxAtomicLevels = [];
-               if ( $this->mTrxDoneWrites ) {
+               $this->trxAtomicLevels = [];
+               if ( $this->trxDoneWrites ) {
                        $this->trxProfiler->transactionWritingOut(
-                               $this->mServer,
-                               $this->mDBname,
-                               $this->mTrxShortId
+                               $this->server,
+                               $this->dbName,
+                               $this->trxShortId
                        );
                }
 
-               $this->mTrxIdleCallbacks = []; // clear
-               $this->mTrxPreCommitCallbacks = []; // clear
+               $this->trxIdleCallbacks = []; // clear
+               $this->trxPreCommitCallbacks = []; // clear
                try {
                        $this->runOnTransactionIdleCallbacks( self::TRIGGER_ROLLBACK );
                } catch ( Exception $e ) {
@@ -3139,11 +3133,11 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
         * @param string $fname
         */
        protected function doRollback( $fname ) {
-               if ( $this->mTrxLevel ) {
+               if ( $this->trxLevel ) {
                        # Disconnects cause rollback anyway, so ignore those errors
                        $ignoreErrors = true;
                        $this->query( 'ROLLBACK', $fname, $ignoreErrors );
-                       $this->mTrxLevel = 0;
+                       $this->trxLevel = 0;
                }
        }
 
@@ -3161,7 +3155,7 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
        }
 
        public function explicitTrxActive() {
-               return $this->mTrxLevel && ( $this->mTrxAtomicLevels || !$this->mTrxAutomatic );
+               return $this->trxLevel && ( $this->trxAtomicLevels || !$this->trxAutomatic );
        }
 
        public function duplicateTableStructure(
@@ -3232,8 +3226,8 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
        public function ping( &$rtt = null ) {
                // Avoid hitting the server if it was hit recently
                if ( $this->isOpen() && ( microtime( true ) - $this->lastPing ) < self::PING_TTL ) {
-                       if ( !func_num_args() || $this->mRTTEstimate > 0 ) {
-                               $rtt = $this->mRTTEstimate;
+                       if ( !func_num_args() || $this->rttEstimate > 0 ) {
+                               $rtt = $this->rttEstimate;
                                return true; // don't care about $rtt
                        }
                }
@@ -3244,7 +3238,7 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                $this->restoreFlags( self::RESTORE_PRIOR );
 
                if ( $ok ) {
-                       $rtt = $this->mRTTEstimate;
+                       $rtt = $this->rttEstimate;
                }
 
                return $ok;
@@ -3257,10 +3251,10 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
         */
        protected function reconnect() {
                $this->closeConnection();
-               $this->mOpened = false;
-               $this->mConn = false;
+               $this->opened = false;
+               $this->conn = false;
                try {
-                       $this->open( $this->mServer, $this->mUser, $this->mPassword, $this->mDBname );
+                       $this->open( $this->server, $this->user, $this->password, $this->dbName );
                        $this->lastPing = microtime( true );
                        $ok = true;
                } catch ( DBConnectionError $e ) {
@@ -3286,8 +3280,8 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
         * @since 1.27
         */
        protected function getTransactionLagStatus() {
-               return $this->mTrxLevel
-                       ? [ 'lag' => $this->mTrxReplicaLag, 'since' => $this->trxTimestamp() ]
+               return $this->trxLevel
+                       ? [ 'lag' => $this->trxReplicaLag, 'since' => $this->trxTimestamp() ]
                        : null;
        }
 
@@ -3395,7 +3389,7 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
        }
 
        public function setSchemaVars( $vars ) {
-               $this->mSchemaVars = $vars;
+               $this->schemaVars = $vars;
        }
 
        public function sourceStream(
@@ -3547,8 +3541,8 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
         * @return array
         */
        protected function getSchemaVars() {
-               if ( $this->mSchemaVars ) {
-                       return $this->mSchemaVars;
+               if ( $this->schemaVars ) {
+                       return $this->schemaVars;
                } else {
                        return $this->getDefaultSchemaVars();
                }
@@ -3567,17 +3561,20 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
        }
 
        public function lockIsFree( $lockName, $method ) {
-               return true;
+               // RDBMs methods for checking named locks may or may not count this thread itself.
+               // In MySQL, IS_FREE_LOCK() returns 0 if the thread already has the lock. This is
+               // the behavior choosen by the interface for this method.
+               return !isset( $this->namedLocksHeld[$lockName] );
        }
 
        public function lock( $lockName, $method, $timeout = 5 ) {
-               $this->mNamedLocksHeld[$lockName] = 1;
+               $this->namedLocksHeld[$lockName] = 1;
 
                return true;
        }
 
        public function unlock( $lockName, $method ) {
-               unset( $this->mNamedLocksHeld[$lockName] );
+               unset( $this->namedLocksHeld[$lockName] );
 
                return true;
        }
@@ -3733,9 +3730,9 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
        }
 
        /**
-        * Get the underlying binding handle, mConn
+        * Get the underlying binding connection handle
         *
-        * Makes sure that mConn is set (disconnects and ping() failure can unset it).
+        * Makes sure the connection resource is set (disconnects and ping() failure can unset it).
         * This catches broken callers than catch and ignore disconnection exceptions.
         * Unlike checking isOpen(), this is safe to call inside of open().
         *
@@ -3744,14 +3741,14 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
         * @since 1.26
         */
        protected function getBindingHandle() {
-               if ( !$this->mConn ) {
+               if ( !$this->conn ) {
                        throw new DBUnexpectedError(
                                $this,
                                'DB connection was already closed or the connection dropped.'
                        );
                }
 
-               return $this->mConn;
+               return $this->conn;
        }
 
        /**
@@ -3759,7 +3756,7 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
         * @return string
         */
        public function __toString() {
-               return (string)$this->mConn;
+               return (string)$this->conn;
        }
 
        /**
@@ -3774,11 +3771,11 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
 
                if ( $this->isOpen() ) {
                        // Open a new connection resource without messing with the old one
-                       $this->mOpened = false;
-                       $this->mConn = false;
-                       $this->mTrxEndCallbacks = []; // don't copy
+                       $this->opened = false;
+                       $this->conn = false;
+                       $this->trxEndCallbacks = []; // don't copy
                        $this->handleSessionLoss(); // no trx or locks anymore
-                       $this->open( $this->mServer, $this->mUser, $this->mPassword, $this->mDBname );
+                       $this->open( $this->server, $this->user, $this->password, $this->dbName );
                        $this->lastPing = microtime( true );
                }
        }
@@ -3797,8 +3794,8 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
         * Run a few simple sanity checks and close dangling connections
         */
        public function __destruct() {
-               if ( $this->mTrxLevel && $this->mTrxDoneWrites ) {
-                       trigger_error( "Uncommitted DB writes (transaction from {$this->mTrxFname})." );
+               if ( $this->trxLevel && $this->trxDoneWrites ) {
+                       trigger_error( "Uncommitted DB writes (transaction from {$this->trxFname})." );
                }
 
                $danglingWriters = $this->pendingWriteAndCallbackCallers();
@@ -3807,14 +3804,14 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                        trigger_error( "DB transaction writes or callbacks still pending ($fnames)." );
                }
 
-               if ( $this->mConn ) {
+               if ( $this->conn ) {
                        // Avoid connection leaks for sanity. Normally, resources close at script completion.
                        // The connection might already be closed in zend/hhvm by now, so suppress warnings.
                        Wikimedia\suppressWarnings();
                        $this->closeConnection();
                        Wikimedia\restoreWarnings();
-                       $this->mConn = false;
-                       $this->mOpened = false;
+                       $this->conn = false;
+                       $this->opened = false;
                }
        }
 }
index 9a0e8c9..c7e1289 100644 (file)
@@ -93,10 +93,10 @@ class DatabaseMssql extends Database {
                }
 
                $this->close();
-               $this->mServer = $server;
-               $this->mUser = $user;
-               $this->mPassword = $password;
-               $this->mDBname = $dbName;
+               $this->server = $server;
+               $this->user = $user;
+               $this->password = $password;
+               $this->dbName = $dbName;
 
                $connectionInfo = [];
 
@@ -112,16 +112,16 @@ class DatabaseMssql extends Database {
                }
 
                Wikimedia\suppressWarnings();
-               $this->mConn = sqlsrv_connect( $server, $connectionInfo );
+               $this->conn = sqlsrv_connect( $server, $connectionInfo );
                Wikimedia\restoreWarnings();
 
-               if ( $this->mConn === false ) {
+               if ( $this->conn === false ) {
                        throw new DBConnectionError( $this, $this->lastError() );
                }
 
-               $this->mOpened = true;
+               $this->opened = true;
 
-               return $this->mConn;
+               return $this->conn;
        }
 
        /**
@@ -130,7 +130,7 @@ class DatabaseMssql extends Database {
         * @return bool
         */
        protected function closeConnection() {
-               return sqlsrv_close( $this->mConn );
+               return sqlsrv_close( $this->conn );
        }
 
        /**
@@ -186,10 +186,10 @@ class DatabaseMssql extends Database {
 
                if ( $this->mPrepareStatements ) {
                        // we do prepare + execute so we can get its field metadata for later usage if desired
-                       $stmt = sqlsrv_prepare( $this->mConn, $sql, [], $scrollArr );
+                       $stmt = sqlsrv_prepare( $this->conn, $sql, [], $scrollArr );
                        $success = sqlsrv_execute( $stmt );
                } else {
-                       $stmt = sqlsrv_query( $this->mConn, $sql, [], $scrollArr );
+                       $stmt = sqlsrv_query( $this->conn, $sql, [], $scrollArr );
                        $success = (bool)$stmt;
                }
 
@@ -953,7 +953,7 @@ class DatabaseMssql extends Database {
         * @return string Version information from the database
         */
        public function getServerVersion() {
-               $server_info = sqlsrv_server_info( $this->mConn );
+               $server_info = sqlsrv_server_info( $this->conn );
                $version = 'Error';
                if ( isset( $server_info['SQLServerVersion'] ) ) {
                        $version = $server_info['SQLServerVersion'];
@@ -977,7 +977,7 @@ class DatabaseMssql extends Database {
                }
 
                if ( $schema === false ) {
-                       $schema = $this->mSchema;
+                       $schema = $this->schema;
                }
 
                $res = $this->query( "SELECT 1 FROM INFORMATION_SCHEMA.TABLES
@@ -1042,8 +1042,8 @@ class DatabaseMssql extends Database {
         * @param string $fname
         */
        protected function doBegin( $fname = __METHOD__ ) {
-               sqlsrv_begin_transaction( $this->mConn );
-               $this->mTrxLevel = 1;
+               sqlsrv_begin_transaction( $this->conn );
+               $this->trxLevel = 1;
        }
 
        /**
@@ -1051,8 +1051,8 @@ class DatabaseMssql extends Database {
         * @param string $fname
         */
        protected function doCommit( $fname = __METHOD__ ) {
-               sqlsrv_commit( $this->mConn );
-               $this->mTrxLevel = 0;
+               sqlsrv_commit( $this->conn );
+               $this->trxLevel = 0;
        }
 
        /**
@@ -1061,8 +1061,8 @@ class DatabaseMssql extends Database {
         * @param string $fname
         */
        protected function doRollback( $fname = __METHOD__ ) {
-               sqlsrv_rollback( $this->mConn );
-               $this->mTrxLevel = 0;
+               sqlsrv_rollback( $this->conn );
+               $this->trxLevel = 0;
        }
 
        /**
@@ -1131,7 +1131,7 @@ class DatabaseMssql extends Database {
         */
        public function selectDB( $db ) {
                try {
-                       $this->mDBname = $db;
+                       $this->dbName = $db;
                        $this->query( "USE $db" );
                        return true;
                } catch ( Exception $e ) {
@@ -1255,8 +1255,8 @@ class DatabaseMssql extends Database {
        private function populateColumnCaches() {
                $res = $this->select( 'INFORMATION_SCHEMA.COLUMNS', '*',
                        [
-                               'TABLE_CATALOG' => $this->mDBname,
-                               'TABLE_SCHEMA' => $this->mSchema,
+                               'TABLE_CATALOG' => $this->dbName,
+                               'TABLE_SCHEMA' => $this->schema,
                                'DATA_TYPE' => [ 'varbinary', 'binary', 'image', 'bit' ]
                        ] );
 
index bd2d274..3085276 100644 (file)
@@ -60,6 +60,8 @@ abstract class DatabaseMysqlBase extends Database {
        protected $sqlMode;
        /** @var bool Use experimental UTF-8 transmission encoding */
        protected $utf8Mode;
+       /** @var bool|null */
+       protected $defaultBigSelects = null;
 
        /** @var string|null */
        private $serverVersion = null;
@@ -126,14 +128,14 @@ abstract class DatabaseMysqlBase extends Database {
                # Close/unset connection handle
                $this->close();
 
-               $this->mServer = $server;
-               $this->mUser = $user;
-               $this->mPassword = $password;
-               $this->mDBname = $dbName;
+               $this->server = $server;
+               $this->user = $user;
+               $this->password = $password;
+               $this->dbName = $dbName;
 
                $this->installErrorHandler();
                try {
-                       $this->mConn = $this->mysqlConnect( $this->mServer );
+                       $this->conn = $this->mysqlConnect( $this->server );
                } catch ( Exception $ex ) {
                        $this->restoreErrorHandler();
                        throw $ex;
@@ -141,7 +143,7 @@ abstract class DatabaseMysqlBase extends Database {
                $error = $this->restoreErrorHandler();
 
                # Always log connection errors
-               if ( !$this->mConn ) {
+               if ( !$this->conn ) {
                        if ( !$error ) {
                                $error = $this->lastError();
                        }
@@ -171,7 +173,7 @@ abstract class DatabaseMysqlBase extends Database {
                                        ] )
                                );
                                $this->queryLogger->debug(
-                                       "Error selecting database $dbName on server {$this->mServer}" );
+                                       "Error selecting database $dbName on server {$this->server}" );
 
                                $this->reportConnectionError( "Error selecting database $dbName" );
                        }
@@ -190,7 +192,7 @@ abstract class DatabaseMysqlBase extends Database {
                }
                // Set any custom settings defined by site config
                // (e.g. https://dev.mysql.com/doc/refman/4.1/en/innodb-parameters.html)
-               foreach ( $this->mSessionVars as $var => $val ) {
+               foreach ( $this->sessionVars as $var => $val ) {
                        // Escape strings but not numbers to avoid MySQL complaining
                        if ( !is_int( $val ) && !is_float( $val ) ) {
                                $val = $this->addQuotes( $val );
@@ -213,7 +215,7 @@ abstract class DatabaseMysqlBase extends Database {
                        }
                }
 
-               $this->mOpened = true;
+               $this->opened = true;
 
                return true;
        }
@@ -465,10 +467,10 @@ abstract class DatabaseMysqlBase extends Database {
         * @return string
         */
        public function lastError() {
-               if ( $this->mConn ) {
+               if ( $this->conn ) {
                        # Even if it's non-zero, it can still be invalid
                        Wikimedia\suppressWarnings();
-                       $error = $this->mysqlError( $this->mConn );
+                       $error = $this->mysqlError( $this->conn );
                        if ( !$error ) {
                                $error = $this->mysqlError();
                        }
@@ -477,7 +479,7 @@ abstract class DatabaseMysqlBase extends Database {
                        $error = $this->mysqlError();
                }
                if ( $error ) {
-                       $error .= ' (' . $this->mServer . ')';
+                       $error .= ' (' . $this->server . ')';
                }
 
                return $error;
@@ -594,7 +596,7 @@ abstract class DatabaseMysqlBase extends Database {
                list( $database, , $prefix, $table ) = $this->qualifiedTableComponents( $table );
                $tableName = "{$prefix}{$table}";
 
-               if ( isset( $this->mSessionTempTables[$tableName] ) ) {
+               if ( isset( $this->sessionTempTables[$tableName] ) ) {
                        return true; // already known to exist and won't show in SHOW TABLES anyway
                }
 
@@ -889,17 +891,15 @@ abstract class DatabaseMysqlBase extends Database {
                        return 0; // already reached this point for sure
                }
 
-               $useGTID = ( $this->useGTIDs && $pos->gtids );
-
                // Call doQuery() directly, to avoid opening a transaction if DBO_TRX is set
-               if ( $useGTID ) {
+               if ( $pos->gtids ) {
                        // Wait on the GTID set (MariaDB only)
                        $gtidArg = $this->addQuotes( implode( ',', $pos->gtids ) );
                        $res = $this->doQuery( "SELECT MASTER_GTID_WAIT($gtidArg, $timeout)" );
                } else {
                        // Wait on the binlog coordinates
-                       $encFile = $this->addQuotes( $pos->file );
-                       $encPos = intval( $pos->pos );
+                       $encFile = $this->addQuotes( $pos->getLogFile() );
+                       $encPos = intval( $pos->pos[1] );
                        $res = $this->doQuery( "SELECT MASTER_POS_WAIT($encFile, $encPos, $timeout)" );
                }
 
@@ -912,7 +912,7 @@ abstract class DatabaseMysqlBase extends Database {
                // Result can be NULL (error), -1 (timeout), or 0+ per the MySQL manual
                $status = ( $row[0] !== null ) ? intval( $row[0] ) : null;
                if ( $status === null ) {
-                       if ( !$useGTID ) {
+                       if ( !$pos->gtids ) {
                                // T126436: jobs programmed to wait on master positions might be referencing
                                // binlogs with an old master hostname; this makes MASTER_POS_WAIT() return null.
                                // Try to detect this case and treat the replica DB as having reached the given
@@ -938,24 +938,26 @@ abstract class DatabaseMysqlBase extends Database {
         * @return MySQLMasterPos|bool
         */
        public function getReplicaPos() {
-               $res = $this->query( 'SHOW SLAVE STATUS', __METHOD__ );
-               $row = $this->fetchObject( $res );
+               $now = microtime( true );
 
-               if ( $row ) {
-                       $pos = $row->Exec_Master_Log_Pos;
-                       // Also fetch the last-applied GTID set (MariaDB)
-                       if ( $this->useGTIDs ) {
-                               $res = $this->query( "SHOW GLOBAL VARIABLES LIKE 'gtid_slave_pos'", __METHOD__ );
-                               $gtidRow = $this->fetchObject( $res );
-                               $gtidSet = $gtidRow ? $gtidRow->Value : '';
-                       } else {
-                               $gtidSet = '';
+               if ( $this->useGTIDs ) {
+                       $res = $this->query( "SELECT @@global.gtid_slave_pos AS Value", __METHOD__ );
+                       $gtidRow = $this->fetchObject( $res );
+                       if ( $gtidRow && strlen( $gtidRow->Value ) ) {
+                               return new MySQLMasterPos( $gtidRow->Value, $now );
                        }
+               }
 
-                       return new MySQLMasterPos( $row->Relay_Master_Log_File, $pos, $gtidSet );
-               } else {
-                       return false;
+               $res = $this->query( 'SHOW SLAVE STATUS', __METHOD__ );
+               $row = $this->fetchObject( $res );
+               if ( $row && strlen( $row->Relay_Master_Log_File ) ) {
+                       return new MySQLMasterPos(
+                               "{$row->Relay_Master_Log_File}/{$row->Exec_Master_Log_Pos}",
+                               $now
+                       );
                }
+
+               return false;
        }
 
        /**
@@ -964,23 +966,23 @@ abstract class DatabaseMysqlBase extends Database {
         * @return MySQLMasterPos|bool
         */
        public function getMasterPos() {
-               $res = $this->query( 'SHOW MASTER STATUS', __METHOD__ );
-               $row = $this->fetchObject( $res );
+               $now = microtime( true );
 
-               if ( $row ) {
-                       // Also fetch the last-written GTID set (MariaDB)
-                       if ( $this->useGTIDs ) {
-                               $res = $this->query( "SHOW GLOBAL VARIABLES LIKE 'gtid_binlog_pos'", __METHOD__ );
-                               $gtidRow = $this->fetchObject( $res );
-                               $gtidSet = $gtidRow ? $gtidRow->Value : '';
-                       } else {
-                               $gtidSet = '';
+               if ( $this->useGTIDs ) {
+                       $res = $this->query( "SELECT @@global.gtid_binlog_pos AS Value", __METHOD__ );
+                       $gtidRow = $this->fetchObject( $res );
+                       if ( $gtidRow && strlen( $gtidRow->Value ) ) {
+                               return new MySQLMasterPos( $gtidRow->Value, $now );
                        }
+               }
 
-                       return new MySQLMasterPos( $row->File, $row->Position, $gtidSet );
-               } else {
-                       return false;
+               $res = $this->query( 'SHOW MASTER STATUS', __METHOD__ );
+               $row = $this->fetchObject( $res );
+               if ( $row && strlen( $row->File ) ) {
+                       return new MySQLMasterPos( "{$row->File}/{$row->Position}", $now );
                }
+
+               return false;
        }
 
        public function serverIsReadOnly() {
@@ -1079,6 +1081,10 @@ abstract class DatabaseMysqlBase extends Database {
         * @since 1.20
         */
        public function lockIsFree( $lockName, $method ) {
+               if ( !parent::lockIsFree( $lockName, $method ) ) {
+                       return false; // already held
+               }
+
                $encName = $this->addQuotes( $this->makeLockName( $lockName ) );
                $result = $this->query( "SELECT IS_FREE_LOCK($encName) AS lockstatus", $method );
                $row = $this->fetchObject( $result );
@@ -1170,14 +1176,14 @@ abstract class DatabaseMysqlBase extends Database {
         */
        public function setBigSelects( $value = true ) {
                if ( $value === 'default' ) {
-                       if ( $this->mDefaultBigSelects === null ) {
+                       if ( $this->defaultBigSelects === null ) {
                                # Function hasn't been called before so it must already be set to the default
                                return;
                        } else {
-                               $value = $this->mDefaultBigSelects;
+                               $value = $this->defaultBigSelects;
                        }
-               } elseif ( $this->mDefaultBigSelects === null ) {
-                       $this->mDefaultBigSelects =
+               } elseif ( $this->defaultBigSelects === null ) {
+                       $this->defaultBigSelects =
                                (bool)$this->selectField( false, '@@sql_big_selects', '', __METHOD__ );
                }
                $encValue = $value ? '1' : '0';
@@ -1376,7 +1382,7 @@ abstract class DatabaseMysqlBase extends Database {
         */
        public function listViews( $prefix = null, $fname = __METHOD__ ) {
                // The name of the column containing the name of the VIEW
-               $propertyName = 'Tables_in_' . $this->mDBname;
+               $propertyName = 'Tables_in_' . $this->dbName;
 
                // Query for the VIEWS
                $res = $this->query( 'SHOW FULL TABLES WHERE TABLE_TYPE = "VIEW"' );
@@ -1445,6 +1451,11 @@ abstract class DatabaseMysqlBase extends Database {
                        return $index;
                }
        }
+
+       protected function isTransactableQuery( $sql ) {
+               return parent::isTransactableQuery( $sql ) &&
+                       !preg_match( '/^SELECT\s+(GET|RELEASE|IS_FREE)_LOCK\(/', $sql );
+       }
 }
 
 class_alias( DatabaseMysqlBase::class, 'DatabaseMysqlBase' );
index 09ea66c..9152d1e 100644 (file)
@@ -86,7 +86,7 @@ class DatabaseMysqli extends DatabaseMysqlBase {
                $mysqli = mysqli_init();
 
                $connFlags = 0;
-               if ( $this->mFlags & self::DBO_SSL ) {
+               if ( $this->flags & self::DBO_SSL ) {
                        $connFlags |= MYSQLI_CLIENT_SSL;
                        $mysqli->ssl_set(
                                $this->sslKeyPath,
@@ -96,10 +96,10 @@ class DatabaseMysqli extends DatabaseMysqlBase {
                                $this->sslCiphers
                        );
                }
-               if ( $this->mFlags & self::DBO_COMPRESS ) {
+               if ( $this->flags & self::DBO_COMPRESS ) {
                        $connFlags |= MYSQLI_CLIENT_COMPRESS;
                }
-               if ( $this->mFlags & self::DBO_PERSISTENT ) {
+               if ( $this->flags & self::DBO_PERSISTENT ) {
                        $realServer = 'p:' . $realServer;
                }
 
@@ -112,8 +112,8 @@ class DatabaseMysqli extends DatabaseMysqlBase {
                }
                $mysqli->options( MYSQLI_OPT_CONNECT_TIMEOUT, 3 );
 
-               if ( $mysqli->real_connect( $realServer, $this->mUser,
-                       $this->mPassword, $this->mDBname, $port, $socket, $connFlags )
+               if ( $mysqli->real_connect( $realServer, $this->user,
+                       $this->password, $this->dbName, $port, $socket, $connFlags )
                ) {
                        return $mysqli;
                }
@@ -162,8 +162,8 @@ class DatabaseMysqli extends DatabaseMysqlBase {
         * @return int
         */
        function lastErrno() {
-               if ( $this->mConn ) {
-                       return $this->mConn->errno;
+               if ( $this->conn ) {
+                       return $this->conn->errno;
                } else {
                        return mysqli_connect_errno();
                }
@@ -185,7 +185,7 @@ class DatabaseMysqli extends DatabaseMysqlBase {
        function selectDB( $db ) {
                $conn = $this->getBindingHandle();
 
-               $this->mDBname = $db;
+               $this->dbName = $db;
 
                return $conn->select_db( $db );
        }
@@ -326,11 +326,11 @@ class DatabaseMysqli extends DatabaseMysqlBase {
         * @return string
         */
        public function __toString() {
-               if ( $this->mConn instanceof mysqli ) {
-                       return (string)$this->mConn->thread_id;
+               if ( $this->conn instanceof mysqli ) {
+                       return (string)$this->conn->thread_id;
                } else {
                        // mConn might be false or something.
-                       return (string)$this->mConn;
+                       return (string)$this->conn;
                }
        }
 }
index 8fbb7de..c6d5a14 100644 (file)
@@ -97,10 +97,10 @@ class DatabasePostgres extends Database {
                        );
                }
 
-               $this->mServer = $server;
-               $this->mUser = $user;
-               $this->mPassword = $password;
-               $this->mDBname = $dbName;
+               $this->server = $server;
+               $this->user = $user;
+               $this->password = $password;
+               $this->dbName = $dbName;
 
                $connectVars = [
                        // pg_connect() user $user as the default database. Since a database is *required*,
@@ -116,7 +116,7 @@ class DatabasePostgres extends Database {
                if ( (int)$this->port > 0 ) {
                        $connectVars['port'] = (int)$this->port;
                }
-               if ( $this->mFlags & self::DBO_SSL ) {
+               if ( $this->flags & self::DBO_SSL ) {
                        $connectVars['sslmode'] = 1;
                }
 
@@ -126,7 +126,7 @@ class DatabasePostgres extends Database {
 
                try {
                        // Use new connections to let LoadBalancer/LBFactory handle reuse
-                       $this->mConn = pg_connect( $this->connectString, PGSQL_CONNECT_FORCE_NEW );
+                       $this->conn = pg_connect( $this->connectString, PGSQL_CONNECT_FORCE_NEW );
                } catch ( Exception $ex ) {
                        $this->restoreErrorHandler();
                        throw $ex;
@@ -134,7 +134,7 @@ class DatabasePostgres extends Database {
 
                $phpError = $this->restoreErrorHandler();
 
-               if ( !$this->mConn ) {
+               if ( !$this->conn ) {
                        $this->queryLogger->debug(
                                "DB connection error\n" .
                                "Server: $server, Database: $dbName, User: $user, Password: " .
@@ -144,7 +144,7 @@ class DatabasePostgres extends Database {
                        throw new DBConnectionError( $this, str_replace( "\n", ' ', $phpError ) );
                }
 
-               $this->mOpened = true;
+               $this->opened = true;
 
                # If called from the command-line (e.g. importDump), only show errors
                if ( $this->cliMode ) {
@@ -159,11 +159,11 @@ class DatabasePostgres extends Database {
                        $this->query( "SET bytea_output = 'escape'", __METHOD__ ); // PHP bug 53127
                }
 
-               $this->determineCoreSchema( $this->mSchema );
+               $this->determineCoreSchema( $this->schema );
                // The schema to be used is now in the search path; no need for explicit qualification
-               $this->mSchema = '';
+               $this->schema = '';
 
-               return $this->mConn;
+               return $this->conn;
        }
 
        public function databasesAreIndependent() {
@@ -178,8 +178,8 @@ class DatabasePostgres extends Database {
         * @throws DBUnexpectedError
         */
        public function selectDB( $db ) {
-               if ( $this->mDBname !== $db ) {
-                       return (bool)$this->open( $this->mServer, $this->mUser, $this->mPassword, $db );
+               if ( $this->dbName !== $db ) {
+                       return (bool)$this->open( $this->server, $this->user, $this->password, $db );
                } else {
                        return true;
                }
@@ -199,7 +199,12 @@ class DatabasePostgres extends Database {
        }
 
        protected function closeConnection() {
-               return $this->mConn ? pg_close( $this->mConn ) : true;
+               return $this->conn ? pg_close( $this->conn ) : true;
+       }
+
+       protected function isTransactableQuery( $sql ) {
+               return parent::isTransactableQuery( $sql ) &&
+                       !preg_match( '/^SELECT\s+pg_(try_|)advisory_\w+\(/', $sql );
        }
 
        public function doQuery( $sql ) {
@@ -253,7 +258,7 @@ class DatabasePostgres extends Database {
                        }
                }
                /* Transaction stays in the ERROR state until rolled back */
-               if ( $this->mTrxLevel ) {
+               if ( $this->trxLevel ) {
                        // Throw away the transaction state, then raise the error as normal.
                        // Note that if this connection is managed by LBFactory, it's already expected
                        // that the other transactions LBFactory manages will be rolled back.
@@ -365,7 +370,7 @@ class DatabasePostgres extends Database {
        }
 
        public function lastError() {
-               if ( $this->mConn ) {
+               if ( $this->conn ) {
                        if ( $this->mLastResult ) {
                                return pg_result_error( $this->mLastResult );
                        } else {
@@ -1255,11 +1260,11 @@ SQL;
        }
 
        public function getDBname() {
-               return $this->mDBname;
+               return $this->dbName;
        }
 
        public function getServer() {
-               return $this->mServer;
+               return $this->server;
        }
 
        public function buildConcat( $stringList ) {
@@ -1319,6 +1324,9 @@ SQL;
        }
 
        public function lockIsFree( $lockName, $method ) {
+               if ( !parent::lockIsFree( $lockName, $method ) ) {
+                       return false; // already held
+               }
                // http://www.postgresql.org/docs/8.2/static/functions-admin.html#FUNCTIONS-ADVISORY-LOCKS
                $key = $this->addQuotes( $this->bigintFromLockName( $lockName ) );
                $result = $this->query( "SELECT (CASE(pg_try_advisory_lock($key))
index 01772cf..458d308 100644 (file)
@@ -51,7 +51,7 @@ class DatabaseSqlite extends Database {
        protected $mLastResult;
 
        /** @var PDO */
-       protected $mConn;
+       protected $conn;
 
        /** @var FSLockManager (hopefully on the same server as the DB) */
        protected $lockMgr;
@@ -79,8 +79,8 @@ class DatabaseSqlite extends Database {
                        throw new InvalidArgumentException( "Need 'dbDirectory' or 'dbFilePath' parameter." );
                } else {
                        $this->dbDir = $p['dbDirectory'];
-                       $this->mDBname = $p['dbname'];
-                       $lockDomain = $this->mDBname;
+                       $this->dbName = $p['dbname'];
+                       $lockDomain = $this->dbName;
                        // Stock wiki mode using standard file names per DB.
                        parent::__construct( $p );
                        // Super doesn't open when $user is false, but we can work with $dbName
@@ -153,12 +153,12 @@ class DatabaseSqlite extends Database {
                $this->close();
                $fileName = self::generateFileName( $this->dbDir, $dbName );
                if ( !is_readable( $fileName ) ) {
-                       $this->mConn = false;
+                       $this->conn = false;
                        throw new DBConnectionError( $this, "SQLite database not accessible" );
                }
                $this->openFile( $fileName );
 
-               return (bool)$this->mConn;
+               return (bool)$this->conn;
        }
 
        /**
@@ -173,29 +173,29 @@ class DatabaseSqlite extends Database {
 
                $this->dbPath = $fileName;
                try {
-                       if ( $this->mFlags & self::DBO_PERSISTENT ) {
-                               $this->mConn = new PDO( "sqlite:$fileName", '', '',
+                       if ( $this->flags & self::DBO_PERSISTENT ) {
+                               $this->conn = new PDO( "sqlite:$fileName", '', '',
                                        [ PDO::ATTR_PERSISTENT => true ] );
                        } else {
-                               $this->mConn = new PDO( "sqlite:$fileName", '', '' );
+                               $this->conn = new PDO( "sqlite:$fileName", '', '' );
                        }
                } catch ( PDOException $e ) {
                        $err = $e->getMessage();
                }
 
-               if ( !$this->mConn ) {
+               if ( !$this->conn ) {
                        $this->queryLogger->debug( "DB connection error: $err\n" );
                        throw new DBConnectionError( $this, $err );
                }
 
-               $this->mOpened = !!$this->mConn;
-               if ( $this->mOpened ) {
+               $this->opened = !!$this->conn;
+               if ( $this->opened ) {
                        # Set error codes only, don't raise exceptions
-                       $this->mConn->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_SILENT );
+                       $this->conn->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_SILENT );
                        # Enforce LIKE to be case sensitive, just like MySQL
                        $this->query( 'PRAGMA case_sensitive_like = 1' );
 
-                       return $this->mConn;
+                       return $this->conn;
                }
 
                return false;
@@ -218,7 +218,7 @@ class DatabaseSqlite extends Database {
         * @return bool
         */
        protected function closeConnection() {
-               $this->mConn = null;
+               $this->conn = null;
 
                return true;
        }
@@ -311,7 +311,7 @@ class DatabaseSqlite extends Database {
         * @return bool|ResultWrapper
         */
        protected function doQuery( $sql ) {
-               $res = $this->mConn->query( $sql );
+               $res = $this->conn->query( $sql );
                if ( $res === false ) {
                        return false;
                }
@@ -447,7 +447,7 @@ class DatabaseSqlite extends Database {
         */
        function insertId() {
                // PDO::lastInsertId yields a string :(
-               return intval( $this->mConn->lastInsertId() );
+               return intval( $this->conn->lastInsertId() );
        }
 
        /**
@@ -472,10 +472,10 @@ class DatabaseSqlite extends Database {
         * @return string
         */
        function lastError() {
-               if ( !is_object( $this->mConn ) ) {
+               if ( !is_object( $this->conn ) ) {
                        return "Cannot return last error, no db connection";
                }
-               $e = $this->mConn->errorInfo();
+               $e = $this->conn->errorInfo();
 
                return isset( $e[2] ) ? $e[2] : '';
        }
@@ -484,10 +484,10 @@ class DatabaseSqlite extends Database {
         * @return string
         */
        function lastErrno() {
-               if ( !is_object( $this->mConn ) ) {
+               if ( !is_object( $this->conn ) ) {
                        return "Cannot return last error, no db connection";
                } else {
-                       $info = $this->mConn->errorInfo();
+                       $info = $this->conn->errorInfo();
 
                        return $info[1];
                }
@@ -720,7 +720,7 @@ class DatabaseSqlite extends Database {
         * @return string Version information from the database
         */
        function getServerVersion() {
-               $ver = $this->mConn->getAttribute( PDO::ATTR_SERVER_VERSION );
+               $ver = $this->conn->getAttribute( PDO::ATTR_SERVER_VERSION );
 
                return $ver;
        }
@@ -752,7 +752,7 @@ class DatabaseSqlite extends Database {
                } else {
                        $this->query( 'BEGIN', $fname );
                }
-               $this->mTrxLevel = 1;
+               $this->trxLevel = 1;
        }
 
        /**
@@ -810,7 +810,7 @@ class DatabaseSqlite extends Database {
                        );
                        return "x'" . bin2hex( (string)$s ) . "'";
                } else {
-                       return $this->mConn->quote( (string)$s );
+                       return $this->conn->quote( (string)$s );
                }
        }
 
@@ -1054,7 +1054,7 @@ class DatabaseSqlite extends Database {
         * @return string
         */
        public function __toString() {
-               return 'SQLite ' . (string)$this->mConn->getAttribute( PDO::ATTR_SERVER_VERSION );
+               return 'SQLite ' . (string)$this->conn->getAttribute( PDO::ATTR_SERVER_VERSION );
        }
 }
 
index 0964dd5..d59bee3 100644 (file)
@@ -1776,7 +1776,7 @@ interface IDatabase {
        public function setSchemaVars( $vars );
 
        /**
-        * Check to see if a named lock is available (non-blocking)
+        * Check to see if a named lock is not locked by any thread (non-blocking)
         *
         * @param string $lockName Name of lock to poll
         * @param string $method Name of method calling us
index 9ca6b11..62809cd 100644 (file)
@@ -13,9 +13,9 @@ use InvalidArgumentException;
  *    that GTID sets are complete (e.g. include all domains on the server).
  */
 class MySQLMasterPos implements DBMasterPos {
-       /** @var string Binlog file */
-       public $file;
-       /** @var int Binglog file position */
+       /** @var string|null Binlog file base name */
+       public $binlog;
+       /** @var int[]|null Binglog file position tuple */
        public $pos;
        /** @var string[] GTID list */
        public $gtids = [];
@@ -23,29 +23,29 @@ class MySQLMasterPos implements DBMasterPos {
        public $asOfTime = 0.0;
 
        /**
-        * @param string $file Binlog file name
-        * @param int $pos Binlog position
-        * @param string $gtid Comma separated GTID set [optional]
+        * @param string $position One of (comma separated GTID list, <binlog file>/<integer>)
+        * @param float $asOfTime UNIX timestamp
         */
-       function __construct( $file, $pos, $gtid = '' ) {
-               $this->file = $file;
-               $this->pos = $pos;
-               $this->gtids = array_map( 'trim', explode( ',', $gtid ) );
-               $this->asOfTime = microtime( true );
-       }
+       public function __construct( $position, $asOfTime ) {
+               $m = [];
+               if ( preg_match( '!^(.+)\.(\d+)/(\d+)$!', $position, $m ) ) {
+                       $this->binlog = $m[1]; // ideally something like host name
+                       $this->pos = [ (int)$m[2], (int)$m[3] ];
+               } else {
+                       $this->gtids = array_map( 'trim', explode( ',', $position ) );
+                       if ( !$this->gtids ) {
+                               throw new InvalidArgumentException( "GTID set should not be empty." );
+                       }
+               }
 
-       /**
-        * @return string <binlog file>/<position>, e.g db1034-bin.000976/843431247
-        */
-       function __toString() {
-               return "{$this->file}/{$this->pos}";
+               $this->asOfTime = $asOfTime;
        }
 
-       function asOfTime() {
+       public function asOfTime() {
                return $this->asOfTime;
        }
 
-       function hasReached( DBMasterPos $pos ) {
+       public function hasReached( DBMasterPos $pos ) {
                if ( !( $pos instanceof self ) ) {
                        throw new InvalidArgumentException( "Position not an instance of " . __CLASS__ );
                }
@@ -54,14 +54,18 @@ class MySQLMasterPos implements DBMasterPos {
                $thisPosByDomain = $this->getGtidCoordinates();
                $thatPosByDomain = $pos->getGtidCoordinates();
                if ( $thisPosByDomain && $thatPosByDomain ) {
-                       $reached = true;
-                       // Check that this has positions GTE all of those in $pos for all domains in $pos
+                       $comparisons = [];
+                       // Check that this has positions reaching those in $pos for all domains in common
                        foreach ( $thatPosByDomain as $domain => $thatPos ) {
-                               $thisPos = isset( $thisPosByDomain[$domain] ) ? $thisPosByDomain[$domain] : -1;
-                               $reached = $reached && ( $thatPos <= $thisPos );
+                               if ( isset( $thisPosByDomain[$domain] ) ) {
+                                       $comparisons[] = ( $thatPos <= $thisPosByDomain[$domain] );
+                               }
                        }
-
-                       return $reached;
+                       // Check that $this has a GTID for at least one domain also in $pos; due to MariaDB
+                       // quirks, prior master switch-overs may result in inactive garbage GTIDs that cannot
+                       // be cleaned up. Assume that the domains in both this and $pos cover the relevant
+                       // active channels.
+                       return ( $comparisons && !in_array( false, $comparisons, true ) );
                }
 
                // Fallback to the binlog file comparisons
@@ -75,7 +79,7 @@ class MySQLMasterPos implements DBMasterPos {
                return false;
        }
 
-       function channelsMatch( DBMasterPos $pos ) {
+       public function channelsMatch( DBMasterPos $pos ) {
                if ( !( $pos instanceof self ) ) {
                        throw new InvalidArgumentException( "Position not an instance of " . __CLASS__ );
                }
@@ -84,8 +88,11 @@ class MySQLMasterPos implements DBMasterPos {
                $thisPosDomains = array_keys( $this->getGtidCoordinates() );
                $thatPosDomains = array_keys( $pos->getGtidCoordinates() );
                if ( $thisPosDomains && $thatPosDomains ) {
-                       // Check that this has GTIDs for all domains in $pos
-                       return !array_diff( $thatPosDomains, $thisPosDomains );
+                       // Check that $this has a GTID for at least one domain also in $pos; due to MariaDB
+                       // quirks, prior master switch-overs may result in inactive garbage GTIDs that cannot
+                       // easily be cleaned up. Assume that the domains in both this and $pos cover the
+                       // relevant active channels.
+                       return array_intersect( $thatPosDomains, $thisPosDomains ) ? true : false;
                }
 
                // Fallback to the binlog file comparisons
@@ -95,6 +102,22 @@ class MySQLMasterPos implements DBMasterPos {
                return ( $thisBinPos && $thatBinPos && $thisBinPos['binlog'] === $thatBinPos['binlog'] );
        }
 
+       /**
+        * @return string|null
+        */
+       public function getLogFile() {
+               return $this->gtids ? null : "{$this->binlog}.{$this->pos[0]}";
+       }
+
+       /**
+        * @return string GTID set or <binlog file>/<position> (e.g db1034-bin.000976/843431247)
+        */
+       public function __toString() {
+               return $this->gtids
+                       ? implode( ',', $this->gtids )
+                       : $this->getLogFile() . "/{$this->pos[1]}";
+       }
+
        /**
         * @note: this returns false for multi-source replication GTID sets
         * @see https://mariadb.com/kb/en/mariadb/gtid
@@ -127,11 +150,8 @@ class MySQLMasterPos implements DBMasterPos {
         * @return array|bool (binlog, (integer file number, integer position)) or false
         */
        protected function getBinlogCoordinates() {
-               $m = [];
-               if ( preg_match( '!^(.+)\.(\d+)/(\d+)$!', (string)$this, $m ) ) {
-                       return [ 'binlog' => $m[1], 'pos' => [ (int)$m[2], (int)$m[3] ] ];
-               }
-
-               return false;
+               return ( $this->binlog !== null && $this->pos !== null )
+                       ? [ 'binlog' => $this->binlog, 'pos' => $this->pos ]
+                       : false;
        }
 }
index e246b79..088c3f2 100644 (file)
@@ -170,15 +170,21 @@ interface ILoadBalancer {
        public function getAnyOpenConnection( $i );
 
        /**
-        * Get a connection by index
+        * Get a connection handle by server index
         *
         * Avoid using CONN_TRX_AUTO with sqlite (e.g. check getServerType() first)
         *
+        * If the caller uses $domain or sets CONN_TRX_AUTO in $flags, then it must also
+        * call ILoadBalancer::reuseConnection() on the handle when finished using it.
+        * In all other cases, this is not necessary, though not harmful either.
+        *
         * @param int $i Server index or DB_MASTER/DB_REPLICA
         * @param array|string|bool $groups Query group(s), or false for the generic reader
         * @param string|bool $domain Domain ID, or false for the current domain
         * @param int $flags Bitfield of CONN_* class constants
         *
+        * @note This method throws DBAccessError if ILoadBalancer::disable() was called
+        *
         * @throws DBError
         * @return Database
         */
@@ -254,7 +260,11 @@ interface ILoadBalancer {
         *
         * Avoid using CONN_TRX_AUTO with sqlite (e.g. check getServerType() first)
         *
-        * @note If disable() was called on this LoadBalancer, this method will throw a DBAccessError.
+        * If the caller uses $domain or sets CONN_TRX_AUTO in $flags, then it must also
+        * call ILoadBalancer::reuseConnection() on the handle when finished using it.
+        * In all other cases, this is not necessary, though not harmful either.
+        *
+        * @note This method throws DBAccessError if ILoadBalancer::disable() was called
         *
         * @param int $i Server index (does not support DB_MASTER/DB_REPLICA)
         * @param string|bool $domain Domain ID, or false for the current domain
index 04b3ea3..ccdb48e 100644 (file)
@@ -39,15 +39,15 @@ use Exception;
  */
 class LoadBalancer implements ILoadBalancer {
        /** @var array[] Map of (server index => server config array) */
-       private $mServers;
+       private $servers;
        /** @var Database[][][] Map of (connection category => server index => IDatabase[]) */
-       private $mConns;
+       private $conns;
        /** @var float[] Map of (server index => weight) */
-       private $mLoads;
+       private $loads;
        /** @var array[] Map of (group => server index => weight) */
-       private $mGroupLoads;
+       private $groupLoads;
        /** @var bool Whether to disregard replica DB lag as a factor in replica DB selection */
-       private $mAllowLagged;
+       private $allowLagged;
        /** @var int Seconds to spend waiting on replica DB lag to resolve */
        private $waitTimeout;
        /** @var array The LoadMonitor configuration */
@@ -79,15 +79,15 @@ class LoadBalancer implements ILoadBalancer {
        /** @var Database DB connection object that caused a problem */
        private $errorConnection;
        /** @var int The generic (not query grouped) replica DB index (of $mServers) */
-       private $mReadIndex;
+       private $readIndex;
        /** @var bool|DBMasterPos False if not set */
-       private $mWaitForPos;
+       private $waitForPos;
        /** @var bool Whether the generic reader fell back to a lagged replica DB */
        private $laggedReplicaMode = false;
        /** @var bool Whether the generic reader fell back to a lagged replica DB */
        private $allReplicasDownMode = false;
        /** @var string The last DB selection or connection error */
-       private $mLastError = 'Unknown error';
+       private $lastError = 'Unknown error';
        /** @var string|bool Reason the LB is read-only or false if not */
        private $readOnlyReason = false;
        /** @var int Total connections opened */
@@ -139,12 +139,12 @@ class LoadBalancer implements ILoadBalancer {
                if ( !isset( $params['servers'] ) ) {
                        throw new InvalidArgumentException( __CLASS__ . ': missing servers parameter' );
                }
-               $this->mServers = $params['servers'];
-               foreach ( $this->mServers as $i => $server ) {
+               $this->servers = $params['servers'];
+               foreach ( $this->servers as $i => $server ) {
                        if ( $i == 0 ) {
-                               $this->mServers[$i]['master'] = true;
+                               $this->servers[$i]['master'] = true;
                        } else {
-                               $this->mServers[$i]['replica'] = true;
+                               $this->servers[$i]['replica'] = true;
                        }
                }
 
@@ -157,8 +157,8 @@ class LoadBalancer implements ILoadBalancer {
                        ? $params['waitTimeout']
                        : self::MAX_WAIT_DEFAULT;
 
-               $this->mReadIndex = -1;
-               $this->mConns = [
+               $this->readIndex = -1;
+               $this->conns = [
                        // Connection were transaction rounds may be applied
                        self::KEY_LOCAL => [],
                        self::KEY_FOREIGN_INUSE => [],
@@ -168,9 +168,9 @@ class LoadBalancer implements ILoadBalancer {
                        self::KEY_FOREIGN_INUSE_NOROUND => [],
                        self::KEY_FOREIGN_FREE_NOROUND => []
                ];
-               $this->mLoads = [];
-               $this->mWaitForPos = false;
-               $this->mAllowLagged = false;
+               $this->loads = [];
+               $this->waitForPos = false;
+               $this->allowLagged = false;
 
                if ( isset( $params['readOnlyReason'] ) && is_string( $params['readOnlyReason'] ) ) {
                        $this->readOnlyReason = $params['readOnlyReason'];
@@ -188,13 +188,13 @@ class LoadBalancer implements ILoadBalancer {
                $this->loadMonitorConfig += [ 'lagWarnThreshold' => $this->maxLag ];
 
                foreach ( $params['servers'] as $i => $server ) {
-                       $this->mLoads[$i] = $server['load'];
+                       $this->loads[$i] = $server['load'];
                        if ( isset( $server['groupLoads'] ) ) {
                                foreach ( $server['groupLoads'] as $group => $ratio ) {
-                                       if ( !isset( $this->mGroupLoads[$group] ) ) {
-                                               $this->mGroupLoads[$group] = [];
+                                       if ( !isset( $this->groupLoads[$group] ) ) {
+                                               $this->groupLoads[$group] = [];
                                        }
-                                       $this->mGroupLoads[$group][$i] = $ratio;
+                                       $this->groupLoads[$group][$i] = $ratio;
                                }
                        }
                }
@@ -289,8 +289,8 @@ class LoadBalancer implements ILoadBalancer {
                foreach ( $lags as $i => $lag ) {
                        if ( $i != 0 ) {
                                # How much lag this server nominally is allowed to have
-                               $maxServerLag = isset( $this->mServers[$i]['max lag'] )
-                                       ? $this->mServers[$i]['max lag']
+                               $maxServerLag = isset( $this->servers[$i]['max lag'] )
+                                       ? $this->servers[$i]['max lag']
                                        : $this->maxLag; // default
                                # Constrain that futher by $maxLag argument
                                $maxServerLag = min( $maxServerLag, $maxLag );
@@ -332,18 +332,18 @@ class LoadBalancer implements ILoadBalancer {
        }
 
        public function getReaderIndex( $group = false, $domain = false ) {
-               if ( count( $this->mServers ) == 1 ) {
+               if ( count( $this->servers ) == 1 ) {
                        // Skip the load balancing if there's only one server
                        return $this->getWriterIndex();
-               } elseif ( $group === false && $this->mReadIndex >= 0 ) {
+               } elseif ( $group === false && $this->readIndex >= 0 ) {
                        // Shortcut if the generic reader index was already cached
-                       return $this->mReadIndex;
+                       return $this->readIndex;
                }
 
                if ( $group !== false ) {
                        // Use the server weight array for this load group
-                       if ( isset( $this->mGroupLoads[$group] ) ) {
-                               $loads = $this->mGroupLoads[$group];
+                       if ( isset( $this->groupLoads[$group] ) ) {
+                               $loads = $this->groupLoads[$group];
                        } else {
                                // No loads for this group, return false and the caller can use some other group
                                $this->connLogger->info( __METHOD__ . ": no loads for group $group" );
@@ -352,7 +352,7 @@ class LoadBalancer implements ILoadBalancer {
                        }
                } else {
                        // Use the generic load group
-                       $loads = $this->mLoads;
+                       $loads = $this->loads;
                }
 
                // Scale the configured load ratios according to each server's load and state
@@ -365,7 +365,7 @@ class LoadBalancer implements ILoadBalancer {
                        return false;
                }
 
-               if ( $this->mWaitForPos && $i != $this->getWriterIndex() ) {
+               if ( $this->waitForPos && $i != $this->getWriterIndex() ) {
                        // Before any data queries are run, wait for the server to catch up to the
                        // specified position. This is used to improve session consistency. Note that
                        // when LoadBalancer::waitFor() sets mWaitForPos, the waiting triggers here,
@@ -375,9 +375,9 @@ class LoadBalancer implements ILoadBalancer {
                        }
                }
 
-               if ( $this->mReadIndex <= 0 && $this->mLoads[$i] > 0 && $group === false ) {
+               if ( $this->readIndex <= 0 && $this->loads[$i] > 0 && $group === false ) {
                        // Cache the generic reader index for future ungrouped DB_REPLICA handles
-                       $this->mReadIndex = $i;
+                       $this->readIndex = $i;
                        // Record if the generic reader index is in "lagged replica DB" mode
                        if ( $laggedReplicaMode ) {
                                $this->laggedReplicaMode = true;
@@ -408,15 +408,15 @@ class LoadBalancer implements ILoadBalancer {
                // Quickly look through the available servers for a server that meets criteria...
                $currentLoads = $loads;
                while ( count( $currentLoads ) ) {
-                       if ( $this->mAllowLagged || $laggedReplicaMode ) {
+                       if ( $this->allowLagged || $laggedReplicaMode ) {
                                $i = ArrayUtils::pickRandom( $currentLoads );
                        } else {
                                $i = false;
-                               if ( $this->mWaitForPos && $this->mWaitForPos->asOfTime() ) {
+                               if ( $this->waitForPos && $this->waitForPos->asOfTime() ) {
                                        // ChronologyProtecter sets mWaitForPos for session consistency.
                                        // This triggers doWait() after connect, so it's especially good to
                                        // avoid lagged servers so as to avoid excessive delay in that method.
-                                       $ago = microtime( true ) - $this->mWaitForPos->asOfTime();
+                                       $ago = microtime( true ) - $this->waitForPos->asOfTime();
                                        // Aim for <= 1 second of waiting (being too picky can backfire)
                                        $i = $this->getRandomNonLagged( $currentLoads, $domain, $ago + 1 );
                                }
@@ -471,11 +471,11 @@ class LoadBalancer implements ILoadBalancer {
        }
 
        public function waitFor( $pos ) {
-               $oldPos = $this->mWaitForPos;
+               $oldPos = $this->waitForPos;
                try {
-                       $this->mWaitForPos = $pos;
+                       $this->waitForPos = $pos;
                        // If a generic reader connection was already established, then wait now
-                       $i = $this->mReadIndex;
+                       $i = $this->readIndex;
                        if ( $i > 0 ) {
                                if ( !$this->doWait( $i ) ) {
                                        $this->laggedReplicaMode = true;
@@ -488,14 +488,14 @@ class LoadBalancer implements ILoadBalancer {
        }
 
        public function waitForOne( $pos, $timeout = null ) {
-               $oldPos = $this->mWaitForPos;
+               $oldPos = $this->waitForPos;
                try {
-                       $this->mWaitForPos = $pos;
+                       $this->waitForPos = $pos;
 
-                       $i = $this->mReadIndex;
+                       $i = $this->readIndex;
                        if ( $i <= 0 ) {
                                // Pick a generic replica DB if there isn't one yet
-                               $readLoads = $this->mLoads;
+                               $readLoads = $this->loads;
                                unset( $readLoads[$this->getWriterIndex()] ); // replica DBs only
                                $readLoads = array_filter( $readLoads ); // with non-zero load
                                $i = ArrayUtils::pickRandom( $readLoads );
@@ -508,7 +508,7 @@ class LoadBalancer implements ILoadBalancer {
                        }
                } finally {
                        # Restore the old position, as this is not used for lag-protection but for throttling
-                       $this->mWaitForPos = $oldPos;
+                       $this->waitForPos = $oldPos;
                }
 
                return $ok;
@@ -517,14 +517,14 @@ class LoadBalancer implements ILoadBalancer {
        public function waitForAll( $pos, $timeout = null ) {
                $timeout = $timeout ?: $this->waitTimeout;
 
-               $oldPos = $this->mWaitForPos;
+               $oldPos = $this->waitForPos;
                try {
-                       $this->mWaitForPos = $pos;
-                       $serverCount = count( $this->mServers );
+                       $this->waitForPos = $pos;
+                       $serverCount = count( $this->servers );
 
                        $ok = true;
                        for ( $i = 1; $i < $serverCount; $i++ ) {
-                               if ( $this->mLoads[$i] > 0 ) {
+                               if ( $this->loads[$i] > 0 ) {
                                        $start = microtime( true );
                                        $ok = $this->doWait( $i, true, $timeout ) && $ok;
                                        $timeout -= ( microtime( true ) - $start );
@@ -535,7 +535,7 @@ class LoadBalancer implements ILoadBalancer {
                        }
                } finally {
                        # Restore the old position, as this is not used for lag-protection but for throttling
-                       $this->mWaitForPos = $oldPos;
+                       $this->waitForPos = $oldPos;
                }
 
                return $ok;
@@ -549,8 +549,8 @@ class LoadBalancer implements ILoadBalancer {
                        return;
                }
 
-               if ( !$this->mWaitForPos || $pos->hasReached( $this->mWaitForPos ) ) {
-                       $this->mWaitForPos = $pos;
+               if ( !$this->waitForPos || $pos->hasReached( $this->waitForPos ) ) {
+                       $this->waitForPos = $pos;
                }
        }
 
@@ -559,7 +559,7 @@ class LoadBalancer implements ILoadBalancer {
         * @return IDatabase|bool
         */
        public function getAnyOpenConnection( $i ) {
-               foreach ( $this->mConns as $connsByServer ) {
+               foreach ( $this->conns as $connsByServer ) {
                        if ( !empty( $connsByServer[$i] ) ) {
                                /** @var IDatabase[] $serverConns */
                                $serverConns = $connsByServer[$i];
@@ -588,7 +588,7 @@ class LoadBalancer implements ILoadBalancer {
                $knownReachedPos = $this->srvCache->get( $key );
                if (
                        $knownReachedPos instanceof DBMasterPos &&
-                       $knownReachedPos->hasReached( $this->mWaitForPos )
+                       $knownReachedPos->hasReached( $this->waitForPos )
                ) {
                        $this->replLogger->debug(
                                __METHOD__ .
@@ -631,14 +631,14 @@ class LoadBalancer implements ILoadBalancer {
                        [ 'dbserver' => $server ]
                );
 
-               $result = $conn->masterPosWait( $this->mWaitForPos, $timeout );
+               $result = $conn->masterPosWait( $this->waitForPos, $timeout );
 
                if ( $result === null ) {
                        $this->replLogger->warning(
                                __METHOD__ . ': Errored out waiting on {host} pos {pos}',
                                [
                                        'host' => $server,
-                                       'pos' => $this->mWaitForPos,
+                                       'pos' => $this->waitForPos,
                                        'trace' => ( new RuntimeException() )->getTraceAsString()
                                ]
                        );
@@ -648,7 +648,7 @@ class LoadBalancer implements ILoadBalancer {
                                __METHOD__ . ': Timed out waiting on {host} pos {pos}',
                                [
                                        'host' => $server,
-                                       'pos' => $this->mWaitForPos,
+                                       'pos' => $this->waitForPos,
                                        'trace' => ( new RuntimeException() )->getTraceAsString()
                                ]
                        );
@@ -657,7 +657,7 @@ class LoadBalancer implements ILoadBalancer {
                        $this->replLogger->info( __METHOD__ . ": Done" );
                        $ok = true;
                        // Remember that the DB reached this point
-                       $this->srvCache->set( $key, $this->mWaitForPos, BagOStuff::TTL_DAY );
+                       $this->srvCache->set( $key, $this->waitForPos, BagOStuff::TTL_DAY );
                }
 
                if ( $close ) {
@@ -699,14 +699,14 @@ class LoadBalancer implements ILoadBalancer {
 
                # Operation-based index
                if ( $i == self::DB_REPLICA ) {
-                       $this->mLastError = 'Unknown error'; // reset error string
+                       $this->lastError = 'Unknown error'; // reset error string
                        # Try the general server pool if $groups are unavailable.
                        $i = ( $groups === [ false ] )
                                ? false // don't bother with this if that is what was tried above
                                : $this->getReaderIndex( false, $domain );
                        # Couldn't find a working server in getReaderIndex()?
                        if ( $i === false ) {
-                               $this->mLastError = 'No working replica DB server: ' . $this->mLastError;
+                               $this->lastError = 'No working replica DB server: ' . $this->lastError;
                                // Throw an exception
                                $this->reportConnectionError();
                                return null; // not reached
@@ -773,20 +773,20 @@ class LoadBalancer implements ILoadBalancer {
                }
 
                $domain = $conn->getDomainID();
-               if ( !isset( $this->mConns[$connInUseKey][$serverIndex][$domain] ) ) {
+               if ( !isset( $this->conns[$connInUseKey][$serverIndex][$domain] ) ) {
                        throw new InvalidArgumentException( __METHOD__ .
                                ": connection $serverIndex/$domain not found; it may have already been freed." );
-               } elseif ( $this->mConns[$connInUseKey][$serverIndex][$domain] !== $conn ) {
+               } elseif ( $this->conns[$connInUseKey][$serverIndex][$domain] !== $conn ) {
                        throw new InvalidArgumentException( __METHOD__ .
                                ": connection $serverIndex/$domain mismatched; it may have already been freed." );
                }
 
                $conn->setLBInfo( 'foreignPoolRefCount', --$refCount );
                if ( $refCount <= 0 ) {
-                       $this->mConns[$connFreeKey][$serverIndex][$domain] = $conn;
-                       unset( $this->mConns[$connInUseKey][$serverIndex][$domain] );
-                       if ( !$this->mConns[$connInUseKey][$serverIndex] ) {
-                               unset( $this->mConns[$connInUseKey][$serverIndex] ); // clean up
+                       $this->conns[$connFreeKey][$serverIndex][$domain] = $conn;
+                       unset( $this->conns[$connInUseKey][$serverIndex][$domain] );
+                       if ( !$this->conns[$connInUseKey][$serverIndex] ) {
+                               unset( $this->conns[$connInUseKey][$serverIndex] ); // clean up
                        }
                        $this->connLogger->debug( __METHOD__ . ": freed connection $serverIndex/$domain" );
                } else {
@@ -838,14 +838,14 @@ class LoadBalancer implements ILoadBalancer {
                } else {
                        // Connection is to the local domain
                        $connKey = $autoCommit ? self::KEY_LOCAL_NOROUND : self::KEY_LOCAL;
-                       if ( isset( $this->mConns[$connKey][$i][0] ) ) {
-                               $conn = $this->mConns[$connKey][$i][0];
+                       if ( isset( $this->conns[$connKey][$i][0] ) ) {
+                               $conn = $this->conns[$connKey][$i][0];
                        } else {
-                               if ( !isset( $this->mServers[$i] ) || !is_array( $this->mServers[$i] ) ) {
+                               if ( !isset( $this->servers[$i] ) || !is_array( $this->servers[$i] ) ) {
                                        throw new InvalidArgumentException( "No server with index '$i'." );
                                }
                                // Open a new connection
-                               $server = $this->mServers[$i];
+                               $server = $this->servers[$i];
                                $server['serverIndex'] = $i;
                                $server['autoCommitOnly'] = $autoCommit;
                                if ( $this->localDomain->getDatabase() !== null ) {
@@ -856,7 +856,7 @@ class LoadBalancer implements ILoadBalancer {
                                $host = $this->getServerName( $i );
                                if ( $conn->isOpen() ) {
                                        $this->connLogger->debug( "Connected to database $i at '$host'." );
-                                       $this->mConns[$connKey][$i][0] = $conn;
+                                       $this->conns[$connKey][$i][0] = $conn;
                                } else {
                                        $this->connLogger->warning( "Failed to connect to database $i at '$host'." );
                                        $this->errorConnection = $conn;
@@ -916,39 +916,39 @@ class LoadBalancer implements ILoadBalancer {
                        $connInUseKey = self::KEY_FOREIGN_INUSE;
                }
 
-               if ( isset( $this->mConns[$connInUseKey][$i][$domain] ) ) {
+               if ( isset( $this->conns[$connInUseKey][$i][$domain] ) ) {
                        // Reuse an in-use connection for the same domain
-                       $conn = $this->mConns[$connInUseKey][$i][$domain];
+                       $conn = $this->conns[$connInUseKey][$i][$domain];
                        $this->connLogger->debug( __METHOD__ . ": reusing connection $i/$domain" );
-               } elseif ( isset( $this->mConns[$connFreeKey][$i][$domain] ) ) {
+               } elseif ( isset( $this->conns[$connFreeKey][$i][$domain] ) ) {
                        // Reuse a free connection for the same domain
-                       $conn = $this->mConns[$connFreeKey][$i][$domain];
-                       unset( $this->mConns[$connFreeKey][$i][$domain] );
-                       $this->mConns[$connInUseKey][$i][$domain] = $conn;
+                       $conn = $this->conns[$connFreeKey][$i][$domain];
+                       unset( $this->conns[$connFreeKey][$i][$domain] );
+                       $this->conns[$connInUseKey][$i][$domain] = $conn;
                        $this->connLogger->debug( __METHOD__ . ": reusing free connection $i/$domain" );
-               } elseif ( !empty( $this->mConns[$connFreeKey][$i] ) ) {
+               } elseif ( !empty( $this->conns[$connFreeKey][$i] ) ) {
                        // Reuse a free connection from another domain
-                       $conn = reset( $this->mConns[$connFreeKey][$i] );
-                       $oldDomain = key( $this->mConns[$connFreeKey][$i] );
+                       $conn = reset( $this->conns[$connFreeKey][$i] );
+                       $oldDomain = key( $this->conns[$connFreeKey][$i] );
                        if ( strlen( $dbName ) && !$conn->selectDB( $dbName ) ) {
-                               $this->mLastError = "Error selecting database '$dbName' on server " .
+                               $this->lastError = "Error selecting database '$dbName' on server " .
                                        $conn->getServer() . " from client host {$this->host}";
                                $this->errorConnection = $conn;
                                $conn = false;
                        } else {
                                $conn->tablePrefix( $prefix );
-                               unset( $this->mConns[$connFreeKey][$i][$oldDomain] );
+                               unset( $this->conns[$connFreeKey][$i][$oldDomain] );
                                // Note that if $domain is an empty string, getDomainID() might not match it
-                               $this->mConns[$connInUseKey][$i][$conn->getDomainId()] = $conn;
+                               $this->conns[$connInUseKey][$i][$conn->getDomainId()] = $conn;
                                $this->connLogger->debug( __METHOD__ .
                                        ": reusing free connection from $oldDomain for $domain" );
                        }
                } else {
-                       if ( !isset( $this->mServers[$i] ) || !is_array( $this->mServers[$i] ) ) {
+                       if ( !isset( $this->servers[$i] ) || !is_array( $this->servers[$i] ) ) {
                                throw new InvalidArgumentException( "No server with index '$i'." );
                        }
                        // Open a new connection
-                       $server = $this->mServers[$i];
+                       $server = $this->servers[$i];
                        $server['serverIndex'] = $i;
                        $server['foreignPoolRefCount'] = 0;
                        $server['foreign'] = true;
@@ -961,7 +961,7 @@ class LoadBalancer implements ILoadBalancer {
                        } else {
                                $conn->tablePrefix( $prefix ); // as specified
                                // Note that if $domain is an empty string, getDomainID() might not match it
-                               $this->mConns[$connInUseKey][$i][$conn->getDomainID()] = $conn;
+                               $this->conns[$connInUseKey][$i][$conn->getDomainID()] = $conn;
                                $this->connLogger->debug( __METHOD__ . ": opened new connection for $i/$domain" );
                        }
                }
@@ -1079,7 +1079,7 @@ class LoadBalancer implements ILoadBalancer {
                $conn = $this->errorConnection; // the connection which caused the error
                $context = [
                        'method' => __METHOD__,
-                       'last_error' => $this->mLastError,
+                       'last_error' => $this->lastError,
                ];
 
                if ( $conn instanceof IDatabase ) {
@@ -1090,7 +1090,7 @@ class LoadBalancer implements ILoadBalancer {
                        );
 
                        // throws DBConnectionError
-                       $conn->reportConnectionError( "{$this->mLastError} ({$context['db_server']})" );
+                       $conn->reportConnectionError( "{$this->lastError} ({$context['db_server']})" );
                } else {
                        // No last connection, probably due to all servers being too busy
                        $this->connLogger->error(
@@ -1099,7 +1099,7 @@ class LoadBalancer implements ILoadBalancer {
                        );
 
                        // If all servers were busy, mLastError will contain something sensible
-                       throw new DBConnectionError( null, $this->mLastError );
+                       throw new DBConnectionError( null, $this->lastError );
                }
        }
 
@@ -1108,22 +1108,22 @@ class LoadBalancer implements ILoadBalancer {
        }
 
        public function haveIndex( $i ) {
-               return array_key_exists( $i, $this->mServers );
+               return array_key_exists( $i, $this->servers );
        }
 
        public function isNonZeroLoad( $i ) {
-               return array_key_exists( $i, $this->mServers ) && $this->mLoads[$i] != 0;
+               return array_key_exists( $i, $this->servers ) && $this->loads[$i] != 0;
        }
 
        public function getServerCount() {
-               return count( $this->mServers );
+               return count( $this->servers );
        }
 
        public function getServerName( $i ) {
-               if ( isset( $this->mServers[$i]['hostName'] ) ) {
-                       $name = $this->mServers[$i]['hostName'];
-               } elseif ( isset( $this->mServers[$i]['host'] ) ) {
-                       $name = $this->mServers[$i]['host'];
+               if ( isset( $this->servers[$i]['hostName'] ) ) {
+                       $name = $this->servers[$i]['hostName'];
+               } elseif ( isset( $this->servers[$i]['host'] ) ) {
+                       $name = $this->servers[$i]['host'];
                } else {
                        $name = '';
                }
@@ -1132,7 +1132,7 @@ class LoadBalancer implements ILoadBalancer {
        }
 
        public function getServerType( $i ) {
-               return isset( $this->mServers[$i]['type'] ) ? $this->mServers[$i]['type'] : 'unknown';
+               return isset( $this->servers[$i]['type'] ) ? $this->servers[$i]['type'] : 'unknown';
        }
 
        public function getMasterPos() {
@@ -1140,7 +1140,7 @@ class LoadBalancer implements ILoadBalancer {
                # master (however unlikely that may be), then we can fetch the position from the replica DB.
                $masterConn = $this->getAnyOpenConnection( $this->getWriterIndex() );
                if ( !$masterConn ) {
-                       $serverCount = count( $this->mServers );
+                       $serverCount = count( $this->servers );
                        for ( $i = 1; $i < $serverCount; $i++ ) {
                                $conn = $this->getAnyOpenConnection( $i );
                                if ( $conn ) {
@@ -1166,7 +1166,7 @@ class LoadBalancer implements ILoadBalancer {
                        $conn->close();
                } );
 
-               $this->mConns = [
+               $this->conns = [
                        self::KEY_LOCAL => [],
                        self::KEY_FOREIGN_INUSE => [],
                        self::KEY_FOREIGN_FREE => [],
@@ -1179,7 +1179,7 @@ class LoadBalancer implements ILoadBalancer {
 
        public function closeConnection( IDatabase $conn ) {
                $serverIndex = $conn->getLBInfo( 'serverIndex' ); // second index level of mConns
-               foreach ( $this->mConns as $type => $connsByServer ) {
+               foreach ( $this->conns as $type => $connsByServer ) {
                        if ( !isset( $connsByServer[$serverIndex] ) ) {
                                continue;
                        }
@@ -1188,7 +1188,7 @@ class LoadBalancer implements ILoadBalancer {
                                if ( $conn === $trackedConn ) {
                                        $host = $this->getServerName( $i );
                                        $this->connLogger->debug( "Closing connection to database $i at '$host'." );
-                                       unset( $this->mConns[$type][$serverIndex][$i] );
+                                       unset( $this->conns[$type][$serverIndex][$i] );
                                        --$this->connsOpened;
                                        break 2;
                                }
@@ -1552,11 +1552,11 @@ class LoadBalancer implements ILoadBalancer {
 
        public function allowLagged( $mode = null ) {
                if ( $mode === null ) {
-                       return $this->mAllowLagged;
+                       return $this->allowLagged;
                }
-               $this->mAllowLagged = $mode;
+               $this->allowLagged = $mode;
 
-               return $this->mAllowLagged;
+               return $this->allowLagged;
        }
 
        public function pingAll() {
@@ -1571,7 +1571,7 @@ class LoadBalancer implements ILoadBalancer {
        }
 
        public function forEachOpenConnection( $callback, array $params = [] ) {
-               foreach ( $this->mConns as $connsByServer ) {
+               foreach ( $this->conns as $connsByServer ) {
                        foreach ( $connsByServer as $serverConns ) {
                                foreach ( $serverConns as $conn ) {
                                        $mergedParams = array_merge( [ $conn ], $params );
@@ -1583,7 +1583,7 @@ class LoadBalancer implements ILoadBalancer {
 
        public function forEachOpenMasterConnection( $callback, array $params = [] ) {
                $masterIndex = $this->getWriterIndex();
-               foreach ( $this->mConns as $connsByServer ) {
+               foreach ( $this->conns as $connsByServer ) {
                        if ( isset( $connsByServer[$masterIndex] ) ) {
                                /** @var IDatabase $conn */
                                foreach ( $connsByServer[$masterIndex] as $conn ) {
@@ -1595,7 +1595,7 @@ class LoadBalancer implements ILoadBalancer {
        }
 
        public function forEachOpenReplicaConnection( $callback, array $params = [] ) {
-               foreach ( $this->mConns as $connsByServer ) {
+               foreach ( $this->conns as $connsByServer ) {
                        foreach ( $connsByServer as $i => $serverConns ) {
                                if ( $i === $this->getWriterIndex() ) {
                                        continue; // skip master
@@ -1619,9 +1619,9 @@ class LoadBalancer implements ILoadBalancer {
 
                $lagTimes = $this->getLagTimes( $domain );
                foreach ( $lagTimes as $i => $lag ) {
-                       if ( $this->mLoads[$i] > 0 && $lag > $maxLag ) {
+                       if ( $this->loads[$i] > 0 && $lag > $maxLag ) {
                                $maxLag = $lag;
-                               $host = $this->mServers[$i]['host'];
+                               $host = $this->servers[$i]['host'];
                                $maxIndex = $i;
                        }
                }
@@ -1636,7 +1636,7 @@ class LoadBalancer implements ILoadBalancer {
 
                $knownLagTimes = []; // map of (server index => 0 seconds)
                $indexesWithLag = [];
-               foreach ( $this->mServers as $i => $server ) {
+               foreach ( $this->servers as $i => $server ) {
                        if ( empty( $server['is static'] ) ) {
                                $indexesWithLag[] = $i; // DB server might have replication lag
                        } else {
index 343c4c8..8eb3709 100644 (file)
@@ -480,12 +480,10 @@ class Article implements Page {
                # Render printable version, use printable version cache
                if ( $outputPage->isPrintable() ) {
                        $parserOptions->setIsPrintable( true );
-                       $parserOptions->setEditSection( false );
                        $poOptions['enableSectionEditLinks'] = false;
                } elseif ( $this->disableSectionEditForRender
                        || !$this->isCurrent() || !$this->getTitle()->quickUserCan( 'edit', $user )
                ) {
-                       $parserOptions->setEditSection( false );
                        $poOptions['enableSectionEditLinks'] = false;
                }
 
@@ -1526,7 +1524,6 @@ class Article implements Page {
        public function render() {
                $this->getContext()->getRequest()->response()->header( 'X-Robots-Tag: noindex' );
                $this->getContext()->getOutput()->setArticleBodyOnly( true );
-               $this->getContext()->getOutput()->enableSectionEditLinks( false );
                $this->disableSectionEditForRender = true;
                $this->view();
        }
index a7eed5a..a47b001 100644 (file)
@@ -2269,9 +2269,11 @@ class WikiPage implements Page, IDBAccessObject {
                        $good = 0;
                }
                $edits = $options['changed'] ? 1 : 0;
-               $total = $options['created'] ? 1 : 0;
+               $pages = $options['created'] ? 1 : 0;
 
-               DeferredUpdates::addUpdate( new SiteStatsUpdate( 0, $edits, $good, $total ) );
+               DeferredUpdates::addUpdate( SiteStatsUpdate::factory(
+                       [ 'edits' => $edits, 'articles' => $good, 'pages' => $pages ]
+               ) );
                DeferredUpdates::addUpdate( new SearchUpdate( $id, $title, $content ) );
 
                // If this is another user's talk page, update newtalk.
@@ -3018,7 +3020,9 @@ class WikiPage implements Page, IDBAccessObject {
                }
 
                // Update site status
-               DeferredUpdates::addUpdate( new SiteStatsUpdate( 0, 1, - (int)$countable, -1 ) );
+               DeferredUpdates::addUpdate( SiteStatsUpdate::factory(
+                       [ 'edits' => 1, 'articles' => -$countable, 'pages' => -1 ]
+               ) );
 
                // Delete pagelinks, update secondary indexes, etc
                $updates = $this->getDeletionUpdates( $content );
index b2d8511..2adfd0a 100644 (file)
@@ -4032,13 +4032,9 @@ class Parser {
 
                # Inhibit editsection links if requested in the page
                if ( isset( $this->mDoubleUnderscores['noeditsection'] ) ) {
-                       $maybeShowEditLink = $showEditLink = false;
+                       $maybeShowEditLink = false;
                } else {
-                       $maybeShowEditLink = true; /* Actual presence will depend on ParserOptions option */
-                       $showEditLink = $this->mOptions->getEditSection();
-               }
-               if ( $showEditLink ) {
-                       $this->mOutput->setEditSectionTokens( true );
+                       $maybeShowEditLink = true; /* Actual presence will depend on post-cache transforms */
                }
 
                # Get all headlines for numbering them and adding funky stuff like [edit]
@@ -4390,9 +4386,9 @@ class Parser {
                         * $this : caller
                         * $section : the section number
                         * &$sectionContent : ref to the content of the section
-                        * $showEditLinks : boolean describing whether this section has an edit link
+                        * $maybeShowEditLinks : boolean describing whether this section has an edit link
                         */
-                       Hooks::run( 'ParserSectionCreate', [ $this, $i, &$sections[$i], $showEditLink ] );
+                       Hooks::run( 'ParserSectionCreate', [ $this, $i, &$sections[$i], $maybeShowEditLink ] );
 
                        $i++;
                }
index c680129..8a7fca6 100644 (file)
@@ -253,11 +253,6 @@ class ParserCache {
 
                wfDebug( "ParserOutput cache found.\n" );
 
-               // The edit section preference may not be the appropiate one in
-               // the ParserOutput, as we are not storing it in the parsercache
-               // key. Force it here. See T33445.
-               $value->setEditSectionTokens( $popts->getEditSection() );
-
                $wikiPage = method_exists( $article, 'getPage' )
                        ? $article->getPage()
                        : $article;
index ca8e739..bbddbe2 100644 (file)
@@ -80,13 +80,6 @@ class ParserOptions {
         */
        private $mTimestamp;
 
-       /**
-        * The edit section flag is in ParserOptions for historical reasons, but
-        * doesn't actually affect the parser output since Feb 2015.
-        * @var bool
-        */
-       private $mEditSection = true;
-
        /**
         * Stored user object
         * @var User
@@ -876,7 +869,8 @@ class ParserOptions {
         * @return bool
         */
        public function getEditSection() {
-               return $this->mEditSection;
+               wfDeprecated( __METHOD__, '1.31' );
+               return true;
        }
 
        /**
@@ -886,7 +880,8 @@ class ParserOptions {
         * @return bool Old value
         */
        public function setEditSection( $x ) {
-               return wfSetVar( $this->mEditSection, $x );
+               wfDeprecated( __METHOD__, '1.31' );
+               return true;
        }
 
        /**
@@ -1284,18 +1279,6 @@ class ParserOptions {
                $defaults = self::getCanonicalOverrides() + self::getDefaults();
                $inCacheKey = self::$inCacheKey;
 
-               // Historical hack: 'editsection' hasn't been a true parser option since
-               // Feb 2015 (instead the parser outputs a constant placeholder and post-parse
-               // processing handles the option). But Wikibase forces it in $forOptions
-               // and expects the cache key to still vary on it for T85252.
-               // @deprecated since 1.30, Wikibase should use addExtraKey() or something instead.
-               if ( in_array( 'editsection', $forOptions, true ) ) {
-                       $options['editsection'] = $this->mEditSection;
-                       $defaults['editsection'] = true;
-                       $inCacheKey['editsection'] = true;
-                       ksort( $inCacheKey );
-               }
-
                // We only include used options with non-canonical values in the key
                // so adding a new option doesn't invalidate the entire parser cache.
                // The drawback to this is that changing the default value of an option
index 19375e0..8f0a1d7 100644 (file)
@@ -151,12 +151,6 @@ class ParserOutput extends CacheTime {
         */
        public $mSections = [];
 
-       /**
-        * @deprecated since 1.31 Use getText() options.
-        * @var bool $mEditSectionTokens prefix/suffix markers if edit sections were output as tokens.
-        */
-       public $mEditSectionTokens = true;
-
        /**
         * @var array $mProperties Name/value pairs to be cached in the DB.
         */
@@ -172,12 +166,6 @@ class ParserOutput extends CacheTime {
         */
        public $mTimestamp;
 
-       /**
-        * @deprecated since 1.31 Use getText() options.
-        * @var bool $mTOCEnabled Whether TOC should be shown, can't override __NOTOC__.
-        */
-       public $mTOCEnabled = true;
-
        /**
         * @var bool $mEnableOOUI Whether OOUI should be enabled.
         */
@@ -280,22 +268,9 @@ class ParserOutput extends CacheTime {
         * @return string HTML
         */
        public function getText( $options = [] ) {
-               if ( !array_key_exists( 'allowTOC', $options ) && empty( $this->mTOCEnabled ) ) {
-                       wfDeprecated( 'ParserOutput stateful allowTOC', '1.31' );
-               }
-
-               //  Note that while $this->mEditSectionTokens formerly defaulted to false,
-               //  ParserOptions->getEditSection() defaults to true and Parser copies
-               //  that to us so true makes more sense as the stateless default.
-               if ( !array_key_exists( 'enableSectionEditLinks', $options ) && !$this->mEditSectionTokens ) {
-                       wfDeprecated( 'ParserOutput stateful enableSectionEditLinks', '1.31' );
-               }
-
                $options += [
-                       // empty() here because old cached versions might lack the field somehow.
-                       // In that situation, the historical behavior (possibly buggy) is to remove the TOC.
-                       'allowTOC' => !empty( $this->mTOCEnabled ),
-                       'enableSectionEditLinks' => $this->mEditSectionTokens,
+                       'allowTOC' => true,
+                       'enableSectionEditLinks' => true,
                        'unwrap' => false,
                        'deduplicateStyles' => true,
                ];
@@ -442,7 +417,8 @@ class ParserOutput extends CacheTime {
         * @deprecated since 1.31 Use getText() options.
         */
        public function getEditSectionTokens() {
-               return $this->mEditSectionTokens;
+               wfDeprecated( __METHOD__, '1.31' );
+               return true;
        }
 
        public function &getLinks() {
@@ -532,7 +508,8 @@ class ParserOutput extends CacheTime {
         * @deprecated since 1.31 Use getText() options.
         */
        public function getTOCEnabled() {
-               return $this->mTOCEnabled;
+               wfDeprecated( __METHOD__, '1.31' );
+               return true;
        }
 
        public function getEnableOOUI() {
@@ -563,7 +540,8 @@ class ParserOutput extends CacheTime {
         * @deprecated since 1.31 Use getText() options.
         */
        public function setEditSectionTokens( $t ) {
-               return wfSetVar( $this->mEditSectionTokens, $t );
+               wfDeprecated( __METHOD__, '1.31' );
+               return true;
        }
 
        public function setIndexPolicy( $policy ) {
@@ -582,7 +560,8 @@ class ParserOutput extends CacheTime {
         * @deprecated since 1.31 Use getText() options.
         */
        public function setTOCEnabled( $flag ) {
-               return wfSetVar( $this->mTOCEnabled, $flag );
+               wfDeprecated( __METHOD__, '1.31' );
+               return true;
        }
 
        public function addCategory( $c, $sort ) {
index c8e5e19..7e3afaa 100644 (file)
@@ -40,6 +40,7 @@ class ExtensionJsonValidator {
        }
 
        /**
+        * @codeCoverageIgnore
         * @return bool
         */
        public function checkDependencies() {
index bb4c7fd..1876645 100644 (file)
@@ -82,6 +82,7 @@ class ExtensionRegistry {
        private static $instance;
 
        /**
+        * @codeCoverageIgnore
         * @return ExtensionRegistry
         */
        public static function getInstance() {
@@ -105,9 +106,11 @@ class ExtensionRegistry {
                        } else {
                                throw new Exception( "$path does not exist!" );
                        }
+                       // @codeCoverageIgnoreStart
                        if ( !$mtime ) {
                                $err = error_get_last();
                                throw new Exception( "Couldn't stat $path: {$err['message']}" );
+                               // @codeCoverageIgnoreEnd
                        }
                }
                $this->queued[$path] = $mtime;
@@ -406,16 +409,6 @@ class ExtensionRegistry {
                return $this->loaded;
        }
 
-       /**
-        * Mark a thing as loaded
-        *
-        * @param string $name
-        * @param array $credits
-        */
-       protected function markLoaded( $name, array $credits ) {
-               $this->loaded[$name] = $credits;
-       }
-
        /**
         * Fully expand autoloader paths
         *
index a31551c..02e3a7c 100644 (file)
@@ -175,13 +175,13 @@ class VersionChecker {
                if ( !isset( $this->loaded[$dependencyName]['version'] ) ) {
                        // If we depend upon any version, and none is set, that's fine.
                        if ( $constraint === '*' ) {
-                               wfDebug( "{$dependencyName} does not expose it's version, but {$checkedExt}
-                                       mentions it with constraint '*'. Assume it's ok so." );
+                               wfDebug( "{$dependencyName} does not expose its version, but {$checkedExt}"
+                                       . " mentions it with constraint '*'. Assume it's ok so." );
                                return false;
                        } else {
                                // Otherwise, mark it as incompatible.
-                               return "{$dependencyName} does not expose it's version, but {$checkedExt}
-                                       requires: {$constraint}.";
+                               return "{$dependencyName} does not expose its version, but {$checkedExt}"
+                                       . " requires: {$constraint}.";
                        }
                } else {
                        // Try to get a constraint for the dependency version
index def0eed..3be687b 100644 (file)
@@ -327,16 +327,6 @@ abstract class ResourceLoaderModule implements LoggerAwareInterface {
                return 'local';
        }
 
-       /**
-        * From where in the page HTML should this module be loaded?
-        *
-        * @deprecated since 1.29 Obsolete. All modules load async from `<head>`.
-        * @return string
-        */
-       public function getPosition() {
-               return 'top';
-       }
-
        /**
         * Whether this module's JS expects to work without the client-side ResourceLoader module.
         * Returning true from this function will prevent mw.loader.state() call from being
diff --git a/includes/sparql/SparqlClient.php b/includes/sparql/SparqlClient.php
new file mode 100644 (file)
index 0000000..6c913d2
--- /dev/null
@@ -0,0 +1,220 @@
+<?php
+/**
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ */
+
+namespace MediaWiki\Sparql;
+
+use Http;
+use MediaWiki\Http\HttpRequestFactory;
+
+/**
+ * Simple SPARQL client
+ *
+ * @author Stas Malyshev
+ */
+class SparqlClient {
+
+       /**
+        * Limit on how long can be the query to be sent by GET.
+        */
+       const MAX_GET_SIZE = 2048;
+
+       /**
+        * User agent for HTTP requests.
+        * @var string
+        */
+       private $userAgent;
+
+       /**
+        * Query timeout (seconds)
+        * @var int
+        */
+       private $timeout = 30;
+
+       /**
+        * SPARQL endpoint URL
+        * @var string
+        */
+       private $endpoint;
+
+       /**
+        * Client options
+        * @var array
+        */
+       private $options = [];
+
+       /**
+        * @var HttpRequestFactory
+        */
+       private $requestFactory;
+
+       /**
+        * @param string $url SPARQL Endpoint
+        * @param HttpRequestFactory $requestFactory
+        */
+       public function __construct( $url, HttpRequestFactory $requestFactory ) {
+               $this->endpoint = $url;
+               $this->requestFactory = $requestFactory;
+               $this->userAgent = Http::userAgent() . " SparqlClient";
+       }
+
+       /**
+        * Set query timeout (in seconds)
+        * @param int $timeout
+        * @return $this
+        */
+       public function setTimeout( $timeout ) {
+               if ( $timeout >= 0 ) {
+                       $this->timeout = $timeout;
+               }
+               return $this;
+       }
+
+       /**
+        * Set client options
+        * @param array $options
+        * @return $this
+        */
+       public function setClientOptions( $options ) {
+               $this->options = $options;
+               return $this;
+       }
+
+       /**
+        * Get current user agent.
+        * @return string
+        */
+       public function getUserAgent() {
+               return $this->userAgent;
+       }
+
+       /**
+        * Set user agent string.
+        *
+        * Mote it is not recommended to completely override user agent for
+        * most applications.
+        * @see appendUserAgent() for recommended way of specifying user agent.
+        *
+        * @param string $agent
+        */
+       public function setUserAgent( $agent ) {
+               $this->userAgent = $agent;
+       }
+
+       /**
+        * Append specific string to user agent.
+        *
+        * This is the recommended way of specifying the user agent
+        * for specific applications of the SparqlClient inside MediaWiki
+        * and extension code.
+        *
+        * @param string $agent
+        */
+       public function appendUserAgent( $agent ) {
+               $this->userAgent .= ' ' . $agent;
+       }
+
+       /**
+        * Query SPARQL endpoint
+        *
+        * @param string $sparql query
+        * @param bool $rawData Whether to return only values or full data objects
+        *
+        * @return array List of results, one row per array element
+        *               Each row will contain fields indexed by variable name.
+        * @throws SparqlException
+        */
+       public function query( $sparql, $rawData = false ) {
+               if ( empty( $this->endpoint ) ) {
+                       throw new SparqlException( 'Endpoint URL can not be empty' );
+               }
+               $queryData = [ "query" => $sparql, "format" => "json" ];
+               $options = array_merge( [ 'method' => 'GET' ], $this->options );
+
+               if ( empty( $options['userAgent'] ) ) {
+                       $options['userAgent'] = $this->userAgent;
+               }
+
+               if ( $this->timeout >= 0 ) {
+                       // Blazegraph setting, see https://wiki.blazegraph.com/wiki/index.php/REST_API
+                       $queryData['maxQueryTimeMillis'] = $this->timeout * 1000;
+                       $options['timeout'] = $this->timeout;
+               }
+
+               if ( strlen( $sparql ) > self::MAX_GET_SIZE ) {
+                       // big requests go to POST
+                       $options['method'] = 'POST';
+                       $options['postData'] = 'query=' . urlencode( $sparql );
+                       unset( $queryData['query'] );
+               }
+
+               $url = wfAppendQuery( $this->endpoint, $queryData );
+               $request = $this->requestFactory->create( $url, $options, __METHOD__ );
+
+               $status = $request->execute();
+
+               if ( !$status->isOK() ) {
+                       throw new SparqlException( "HTTP error: {$status->getWikiText()}" );
+               }
+               $result = $request->getContent();
+               \MediaWiki\suppressWarnings();
+               $data = json_decode( $result, true );
+               \MediaWiki\restoreWarnings();
+               if ( $data === null || $data === false ) {
+                       throw new SparqlException( "HTTP request failed, response:\n" .
+                               substr( $result, 1024 ) );
+               }
+
+               return $this->extractData( $data, $rawData );
+       }
+
+       /**
+        * Extract data from SPARQL response format.
+        * The response must be in format described in:
+        * https://www.w3.org/TR/sparql11-results-json/
+        *
+        * @param array $data SPARQL result
+        * @param bool  $rawData Whether to return only values or full data objects
+        *
+        * @return array List of results, one row per element.
+        */
+       private function extractData( $data, $rawData = false ) {
+               $result = [];
+               if ( $data && !empty( $data['results'] ) ) {
+                       $vars = $data['head']['vars'];
+                       $resrow = [];
+                       foreach ( $data['results']['bindings'] as $row ) {
+                               foreach ( $vars as $var ) {
+                                       if ( !isset( $row[$var] ) ) {
+                                               $resrow[$var] = null;
+                                               continue;
+                                       }
+                                       if ( $rawData ) {
+                                               $resrow[$var] = $row[$var];
+                                       } else {
+                                               $resrow[$var] = $row[$var]['value'];
+                                       }
+                               }
+                               $result[] = $resrow;
+                       }
+               }
+               return $result;
+       }
+
+}
diff --git a/includes/sparql/SparqlException.php b/includes/sparql/SparqlException.php
new file mode 100644 (file)
index 0000000..d65521e
--- /dev/null
@@ -0,0 +1,30 @@
+<?php
+/**
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ */
+
+namespace MediaWiki\Sparql;
+
+use Exception;
+
+/**
+ * Exception for SPARQLClient
+ * @author Stas Malyshev
+ */
+class SparqlException extends Exception {
+}
index 10f4864..cc43580 100644 (file)
@@ -82,7 +82,7 @@ class SpecialLog extends SpecialPage {
                        if ( $offender ) {
                                if ( $offender->getId() > 0 ) {
                                        $qc = [ 'ls_field' => 'target_author_id', 'ls_value' => $offender->getId() ];
-                               } elseif ( empty( $opts->getValue( 'offender' ) ) === false ) {
+                               } elseif ( !empty( $opts->getValue( 'offender' ) ) ) {
                                        $qc = [ 'ls_field' => 'target_author_ip', 'ls_value' => $offender->getName() ];
                                }
                        }
index 7cc0dc6..4abdebf 100644 (file)
@@ -220,20 +220,6 @@ class SpecialRecentChanges extends ChangesListSpecialPage {
                }
        }
 
-       /**
-        * Get a FormOptions object containing the default options
-        *
-        * @return FormOptions
-        */
-       public function getDefaultOptions() {
-               $opts = parent::getDefaultOptions();
-
-               $opts->add( 'categories', '' );
-               $opts->add( 'categories_any', false );
-
-               return $opts;
-       }
-
        /**
         * Get all custom filters
         *
@@ -359,11 +345,6 @@ class SpecialRecentChanges extends ChangesListSpecialPage {
                        $join_conds
                );
 
-               // Build the final data
-               if ( $this->getConfig()->get( 'AllowCategorizedRecentChanges' ) ) {
-                       $this->filterByCategories( $rows, $opts );
-               }
-
                return $rows;
        }
 
@@ -667,16 +648,12 @@ class SpecialRecentChanges extends ChangesListSpecialPage {
         */
        function getExtraOptions( $opts ) {
                $opts->consumeValues( [
-                       'namespace', 'invert', 'associated', 'tagfilter', 'categories', 'categories_any'
+                       'namespace', 'invert', 'associated', 'tagfilter'
                ] );
 
                $extraOpts = [];
                $extraOpts['namespace'] = $this->namespaceFilterForm( $opts );
 
-               if ( $this->getConfig()->get( 'AllowCategorizedRecentChanges' ) ) {
-                       $extraOpts['category'] = $this->categoryFilterForm( $opts );
-               }
-
                $tagFilter = ChangeTags::buildTagFilterSelector(
                        $opts['tagfilter'], false, $this->getContext() );
                if ( count( $tagFilter ) ) {
@@ -740,29 +717,17 @@ class SpecialRecentChanges extends ChangesListSpecialPage {
                return [ $nsLabel, "$nsSelect $invert $associated" ];
        }
 
-       /**
-        * Create an input to filter changes by categories
-        *
-        * @param FormOptions $opts
-        * @return array
-        */
-       protected function categoryFilterForm( FormOptions $opts ) {
-               list( $label, $input ) = Xml::inputLabelSep( $this->msg( 'rc_categories' )->text(),
-                       'categories', 'mw-categories', false, $opts['categories'] );
-
-               $input .= ' ' . Xml::checkLabel( $this->msg( 'rc_categories_any' )->text(),
-                       'categories_any', 'mw-categories_any', $opts['categories_any'] );
-
-               return [ $label, $input ];
-       }
-
        /**
         * Filter $rows by categories set in $opts
         *
+        * @deprecated since 1.31
+        *
         * @param ResultWrapper &$rows Database rows
         * @param FormOptions $opts
         */
        function filterByCategories( &$rows, FormOptions $opts ) {
+               wfDeprecated( __METHOD__, '1.31' );
+
                $categories = array_map( 'trim', explode( '|', $opts['categories'] ) );
 
                if ( !count( $categories ) ) {
index f821eff..127a36b 100644 (file)
@@ -450,9 +450,7 @@ class SpecialUndelete extends SpecialPage {
                if ( ( $this->mPreview || !$isText ) && $content ) {
                        // NOTE: non-text content has no source view, so always use rendered preview
 
-                       // Hide [edit]s
                        $popts = $out->parserOptions();
-                       $popts->setEditSection( false );
 
                        $pout = $content->getParserOutput( $this->mTargetObj, $rev->getId(), $popts, true );
                        $out->addParserOutput( $pout, [
index f771f42..e757e59 100644 (file)
@@ -21,6 +21,7 @@
  */
 
 use Wikimedia\Rdbms\IDatabase;
+use MediaWiki\MediaWikiServices;
 
 /**
  * Represents a "user group membership" -- a specific instance of a user belonging
@@ -158,7 +159,7 @@ class UserGroupMembership {
                }
 
                // Purge old, expired memberships from the DB
-               self::purgeExpired( $dbw );
+               JobQueueGroup::singleton()->push( new UserGroupExpiryJob() );
 
                // Check that the values make sense
                if ( $this->group === null ) {
@@ -236,38 +237,59 @@ class UserGroupMembership {
 
        /**
         * Purge expired memberships from the user_groups table
-        *
-        * @param IDatabase|null $dbw
         */
-       public static function purgeExpired( IDatabase $dbw = null ) {
-               if ( wfReadOnly() ) {
+       public static function purgeExpired() {
+               $services = MediaWikiServices::getInstance();
+               if ( $services->getReadOnlyMode()->isReadOnly() ) {
                        return;
                }
 
-               if ( $dbw === null ) {
-                       $dbw = wfGetDB( DB_MASTER );
-               }
+               $lbFactory = $services->getDBLoadBalancerFactory();
+               $ticket = $lbFactory->getEmptyTransactionTicket( __METHOD__ );
+               $dbw = $services->getDBLoadBalancer()->getConnection( DB_MASTER );
 
-               DeferredUpdates::addUpdate( new AtomicSectionUpdate(
-                       $dbw,
-                       __METHOD__,
-                       function ( IDatabase $dbw, $fname ) {
-                               $expiryCond = [ 'ug_expiry < ' . $dbw->addQuotes( $dbw->timestamp() ) ];
-                               $res = $dbw->select( 'user_groups', self::selectFields(), $expiryCond, $fname );
+               $lockKey = $dbw->getDomainID() . ':usergroups-prune'; // specific to this wiki
+               $scopedLock = $dbw->getScopedLockAndFlush( $lockKey, __METHOD__, 0 );
+               if ( !$scopedLock ) {
+                       return; // already running
+               }
 
-                               // save an array of users/groups to insert to user_former_groups
-                               $usersAndGroups = [];
+               $now = time();
+               do {
+                       $dbw->startAtomic( __METHOD__ );
+
+                       $res = $dbw->select(
+                               'user_groups',
+                               self::selectFields(),
+                               [ 'ug_expiry < ' . $dbw->addQuotes( $dbw->timestamp( $now ) ) ],
+                               __METHOD__,
+                               [ 'FOR UPDATE', 'LIMIT' => 100 ]
+                       );
+
+                       if ( $res->numRows() > 0 ) {
+                               $insertData = []; // array of users/groups to insert to user_former_groups
+                               $deleteCond = []; // array for deleting the rows that are to be moved around
                                foreach ( $res as $row ) {
-                                       $usersAndGroups[] = [ 'ufg_user' => $row->ug_user, 'ufg_group' => $row->ug_group ];
+                                       $insertData[] = [ 'ufg_user' => $row->ug_user, 'ufg_group' => $row->ug_group ];
+                                       $deleteCond[] = $dbw->makeList(
+                                               [ 'ug_user' => $row->ug_user, 'ug_group' => $row->ug_group ],
+                                               $dbw::LIST_AND
+                                       );
                                }
+                               // Delete the rows we're about to move
+                               $dbw->delete(
+                                       'user_groups',
+                                       $dbw->makeList( $deleteCond, $dbw::LIST_OR ),
+                                       __METHOD__
+                               );
+                               // Push the groups to user_former_groups
+                               $dbw->insert( 'user_former_groups', $insertData, __METHOD__, [ 'IGNORE' ] );
+                       }
 
-                               // delete 'em all
-                               $dbw->delete( 'user_groups', $expiryCond, $fname );
+                       $dbw->endAtomic( __METHOD__ );
 
-                               // and push the groups to user_former_groups
-                               $dbw->insert( 'user_former_groups', $usersAndGroups, __METHOD__, [ 'IGNORE' ] );
-                       }
-               ) );
+                       $lbFactory->commitAndWaitForReplication( __METHOD__, $ticket );
+               } while ( $res->numRows() > 0 );
        }
 
        /**
index 1439421..1a0f504 100644 (file)
@@ -131,4 +131,11 @@ class NoWriteWatchedItemStore implements WatchedItemStoreInterface {
                throw new DBReadOnlyError( null, 'The watchlist is currently readonly.' );
        }
 
+       public function clearUserWatchedItems( User $user ) {
+               throw new DBReadOnlyError( null, 'The watchlist is currently readonly.' );
+       }
+
+       public function clearUserWatchedItemsUsingJobQueue( User $user ) {
+               throw new DBReadOnlyError( null, 'The watchlist is currently readonly.' );
+       }
 }
index d5a3d7c..133f480 100644 (file)
@@ -288,4 +288,22 @@ interface WatchedItemStoreInterface {
         */
        public function duplicateEntry( LinkTarget $oldTarget, LinkTarget $newTarget );
 
+       /**
+        * Queues a job that will clear the users watchlist using the Job Queue.
+        *
+        * @since 1.31
+        *
+        * @param User $user
+        */
+       public function clearUserWatchedItems( User $user );
+
+       /**
+        * Queues a job that will clear the users watchlist using the Job Queue.
+        *
+        * @since 1.31
+        *
+        * @param User $user
+        */
+       public function clearUserWatchedItemsUsingJobQueue( User $user );
+
 }
index 985f664..ed36e93 100644 (file)
        "newpageletter": "B",
        "boteditletter": "b",
        "number_of_watching_users_pageview": "[$1 kalön {{PLURAL:$1|ureuëng ngui}}]",
-       "rc_categories_any": "Pue-pue mantöng",
        "rc-change-size-new": "$1 {{PLURAL:$1|bita}} lheuëh neuubah",
        "newsectionsummary": "/* $1 */ bideung barô",
        "rc-enhanced-expand": "Peuleumah rincian",
index 2350e81..264a16d 100644 (file)
        "minoreditletter": "ц",
        "newpageletter": "КӀ",
        "boteditletter": "б",
-       "rc_categories_any": "ХэшыпыкIыгъэмэ ащыщ горэ",
        "rc-change-size-new": "$1 {{PLURAL:$1|байт}} зэхъокӀым ыуж",
        "newsectionsummary": "/* $1 */ секциякIэ",
        "rc-enhanced-expand": "Ӏэмэ-псымэхэр къэгъэлъагъу",
index 85441b6..c467a1e 100644 (file)
        "newpageletter": "N",
        "boteditletter": "b",
        "number_of_watching_users_pageview": "[$1 {{PLURAL:$1|gebruiker|gebruikers}} hou die bladsy dop]",
-       "rc_categories": "Beperk tot kategorieë (skei met \"|\"):",
-       "rc_categories_any": "Enige van die gekose",
        "rc-change-size-new": "$1 {{PLURAL:$1|greep|grepe}} na die wysiging",
        "newsectionsummary": "/* $1 */ nuwe afdeling",
        "rc-enhanced-expand": "Wys details",
index 488a0b4..adae8ab 100644 (file)
        "newpageletter": "baluhay",
        "boteditletter": "kikay a tademaw",
        "number_of_watching_users_pageview": "[$1 imahini miazihay a {{PLURAL:$1|misaungayay}}]",
-       "rc_categories": "kakuniza kelec (ku \"|\" palaliyas):",
-       "rc_categories_any": "amahicahica tu mipili’ay",
        "rc-change-size-new": "masumadtu sa u $1 {{PLURAL:$1|wyiyincu}}",
        "newsectionsummary": "/* $1 */ baluhay a tusil",
        "rc-enhanced-expand": "paazih pulita kalunasulitan",
index 85ab197..7128e15 100644 (file)
        "newpageletter": "አ",
        "boteditletter": "B",
        "number_of_watching_users_pageview": "[$1 የሚከታተሉ {{PLURAL:$1|ተጠቃሚ|ተጠቃሚዎች}}]",
-       "rc_categories_any": "ማንኛውም",
        "newsectionsummary": "/* $1 */ አዲስ ክፍል",
        "rc-enhanced-expand": "ዝርዝሩን አሳይ (JavaScript ያስፈልጋል)",
        "rc-enhanced-hide": "ዝርዝሩን ደብቅ",
index dac87ec..792b9e0 100644 (file)
        "newpageletter": "N",
        "boteditletter": "b",
        "number_of_watching_users_pageview": "[$1 {{PLURAL:$1|usuario|usuarios}} cosirando]",
-       "rc_categories": "Limite ta las categorías (deseparatas por \"|\")",
-       "rc_categories_any": "Todas",
        "rc-change-size-new": "$1 {{PLURAL:$1|byte|bytes}} dimpués d'o cambio",
        "newsectionsummary": "Nueva sección: /* $1 */",
        "rc-enhanced-expand": "Amostrar detalles",
index d1e4b14..84eaa79 100644 (file)
        "minoreditletter": "ly",
        "newpageletter": "N",
        "boteditletter": "þr",
-       "rc_categories_any": "Ǣnig",
        "rc-enhanced-expand": "Īwan stafas",
        "rc-enhanced-hide": "Hȳdan stafas",
        "recentchangeslinked": "Sibba andwendunga",
index 9a0844a..42ebab8 100644 (file)
        "newpageletter": "ج‌",
        "boteditletter": "ب",
        "number_of_watching_users_pageview": "[{{PLURAL:$1|لا مستخدمون يراقبون|مستخدم واحد يراقب|مستخدمان يراقبان|$1 مستخدمين يراقبون|$1 مستخدما يراقب|$1 مستخدم يراقب}}]",
-       "rc_categories": "حصر لتصنيفات (مفرقة برمز \"|\"):",
-       "rc_categories_any": "أي من المختار",
        "rc-change-size-new": "$1 {{PLURAL:$1|بايت|بايت}} بعد التغيير",
        "newsectionsummary": "/* $1 */ قسم جديد",
        "rc-enhanced-expand": "عرض التفاصيل",
        "rollback-success": "تم استرجاع تعديلات {{GENDER:$3|$1}}، حتى آخر نسخة بواسطة {{GENDER:$4|$2}}.",
        "rollback-success-notify": "تم استرجاع التعديلات بواسطة $1;\nتم التغيير إلى آخر مراجعة بواسطة $2. [$3 عرض التغييرات]",
        "sessionfailure-title": "فشل في الجلسة",
-       "sessionfailure": "Ù\8aبدÙ\88 Ø£Ù\86Ù\87 Ù\87Ù\86اÙ\83 Ù\85Ø´Ù\83Ù\84Ø© Ù\81Ù\8a Ø¬Ù\84سة Ø§Ù\84دخÙ\88Ù\84 Ø§Ù\84خاصة Ø¨Ù\83Ø\9b\nÙ\84Ø°Ù\84Ù\83 Ù\81Ù\82د Ø£Ù\84غÙ\8aت Ù\87Ø°Ù\87 Ø§Ù\84عÙ\85Ù\84Ù\8aØ© Ù\83إجراء Ø§Ø­ØªØ±Ø§Ø²Ù\8a Ø¶Ø¯ Ø§Ù\84اختراÙ\82.\nÙ\85Ù\86 Ù\81ضÙ\84Ù\83 Ø§Ø¶ØºØ· Ø¹Ù\84Ù\89 Ù\85Ù\81تاح \"رجÙ\88ع\" Ù\84تحÙ\85Ù\8aÙ\84 Ø§Ù\84صÙ\81حة Ø§Ù\84تÙ\8a Ø¬Ø¦Øª Ù\85Ù\86Ù\87اØ\8c Ø«Ù\85 Ø­Ø§Ù\88Ù\84 مرة أخرى.",
+       "sessionfailure": "Ù\8aبدÙ\88 Ø£Ù\86Ù\87 Ù\87Ù\86اÙ\83 Ù\85Ø´Ù\83Ù\84Ø© Ù\81Ù\8a Ø¬Ù\84سة Ø§Ù\84دخÙ\88Ù\84 Ø§Ù\84خاصة Ø¨Ù\83Ø\9b\nÙ\84Ø°Ù\84Ù\83 Ù\81Ù\82د Ø£Ù\84غÙ\8aت Ù\87Ø°Ù\87 Ø§Ù\84عÙ\85Ù\84Ù\8aØ© Ù\83إجراء Ø§Ø­ØªØ±Ø§Ø²Ù\8a Ø¶Ø¯ Ø§Ù\84اختراÙ\82.\nÙ\85Ù\86 Ù\81ضÙ\84Ù\83 Ø£Ø¹Ø¯ Ø¥Ø±Ø³Ø§Ù\84 Ø§Ù\84استÙ\85ارة مرة أخرى.",
        "changecontentmodel": "غير نموذج المحتوى لصفحة",
        "changecontentmodel-legend": "غير نموذج المحتوى",
        "changecontentmodel-title-label": "عنوان الصفحة",
        "watchlistedit-clear-titles": "العناوين:",
        "watchlistedit-clear-submit": "امسح قائمة المراقبة (هذا دائم!)",
        "watchlistedit-clear-done": "مُسِحت قائمة مراقبتك.",
+       "watchlistedit-clear-jobqueue": "قائمة مراقبتك يتم إفراغها. هذا قد يستغرق بعض الوقت!",
        "watchlistedit-clear-removed": "{{PLURAL:$1||أزيل العنوان التالي|أزيل العنوانان التاليان|أزيلت العناوين ال$1 التالية}}:",
        "watchlistedit-too-many": "الصفحات أكثر من أن تعرض هنا.",
        "watchlisttools-clear": "امسح قائمة المراقبة",
index 93fc59e..9a9b6a8 100644 (file)
        "minoreditletter": "ܙ",
        "newpageletter": "ܚ",
        "boteditletter": "ܒ",
-       "rc_categories_any": "ܐܝܢܐ ܕܗܘ",
        "rc-change-size-new": "$1 {{PLURAL:$1|ܒܐܝܛ|ܒܐܝܛ̈ܐ}} ܒܬܪ ܫܘܚܠܦܐ",
        "newsectionsummary": "/* $1 */ ܡܢܬܐ ܚܕܬܐ",
        "rc-enhanced-expand": "ܚܘܝ ܐܪ̈ܝܟܬܐ",
index ed0e562..367890f 100644 (file)
        "newpageletter": "J",
        "boteditletter": "b",
        "number_of_watching_users_pageview": "[$1 katchof  {{PLURAL:$1|mostkhdim|mostkhdimin}}]",
-       "rc_categories": "limiti tsnifat (frqha b  \"|\")",
-       "rc_categories_any": "ay wahd",
        "rc-change-size": "$1",
        "newsectionsummary": "/* $1 */ qism jdid",
        "rc-enhanced-expand": "Werri ṫ-ṫafaṣil (kayḫṫaj JavaScript)",
index 1d36eba..fbc25af 100644 (file)
        "newpageletter": "ج",
        "boteditletter": "ب",
        "number_of_watching_users_pageview": "[$1 {{PLURAL:$1| يوزر مراقب|يوزر مراقب}}]",
-       "rc_categories": "حصر لتصنيفات (مفصولة برمز \"|\")",
-       "rc_categories_any": "أى",
        "rc-change-size-new": "$1 {{PLURAL:$1|بايت|بايتس}} بعد التغيير",
        "newsectionsummary": "/* $1 */ قسم جديد",
        "rc-enhanced-expand": "[اعرض التفاصيل]",
index 98b5675..43e7591 100644 (file)
        "newpageletter": "ন",
        "boteditletter": "ব",
        "number_of_watching_users_pageview": "[$1 {{PLURAL:$1|জন সদস্যই|জন সদস্যই}} এই পৃষ্ঠা নিৰীক্ষণ কৰিছে]",
-       "rc_categories": "শ্ৰেণীসমূহৰ সীমাবদ্ধতা (\"|\" দি পৃথক কৰক):",
-       "rc_categories_any": "বাছনি কৰাৰ মাজত যিকোনো",
        "rc-change-size-new": "$1 {{PLURAL:$1|বাইট}} যোগ দিয়া হ’ল",
        "newsectionsummary": "/* $1 */ নতুন অনুচ্ছেদ",
        "rc-enhanced-expand": "সবিশেষ দেখুৱাওক",
index 10c3855..258e0c1 100644 (file)
        "newpageletter": "N",
        "boteditletter": "b",
        "number_of_watching_users_pageview": "[$1 {{PLURAL:$1|usuariu|usuarios}} vixilando]",
-       "rc_categories": "Llendar a les categoríes (dixebrar con \"|\"):",
-       "rc_categories_any": "Cualquiera de les esbillaes",
        "rc-change-size-new": "$1 {{PLURAL:$1|byte|bytes}} dempués del cambiu",
        "newsectionsummary": "/* $1 */ nueva seición",
        "rc-enhanced-expand": "Amosar detalles",
        "rollback-success": "Revertíes les ediciones de {{GENDER:$3|$1}}; devueltu a la última revisión de {{GENDER:$4|$2}}.",
        "rollback-success-notify": "Revertíes les ediciones de $1 a la última revisión de $2. [$3 Ver cambeos]",
        "sessionfailure-title": "Fallu de sesión",
-       "sessionfailure": "Paez qu'hai un problema col aniciu de sesión;\natayóse esta aición por precaución escontra secuestru de sesiones.\nTorna a la páxina anterior, recarga esa páxina y vuelve a tentalo.",
+       "sessionfailure": "Paez qu'hai un problema col aniciu de sesión;\natayóse esta aición por precaución escontra secuestru de sesiones.\nUnvia'l formulariu otra vegada.",
        "changecontentmodel": "Cambiar el modelu de conteníu d'una páxina",
        "changecontentmodel-legend": "Cambiar el modelu de conteníu",
        "changecontentmodel-title-label": "Títulu de la páxina",
        "watchlistedit-clear-titles": "Títulos:",
        "watchlistedit-clear-submit": "Llimpiar la llista de siguimientu (¡Esto ye permanente!)",
        "watchlistedit-clear-done": "Llimpióse la to llista de siguimientu.",
+       "watchlistedit-clear-jobqueue": "Ta llimpiándose la llista de siguimientu. ¡Esta aición puede tardar daqué de tiempu!",
        "watchlistedit-clear-removed": "{{PLURAL:$1|Desanicióse 1 títulu|Desaniciáronse $1 títulos}}:",
        "watchlistedit-too-many": "Hai demasiaes páxines p'amosales equí.",
        "watchlisttools-clear": "Llimpiar la llista de siguimientu",
index a7d5330..39b2b30 100644 (file)
        "newpageletter": "W",
        "boteditletter": "s",
        "number_of_watching_users_pageview": "[$1 nedis {{PLURAL:$1|favesik|favesik}}]",
-       "rc_categories": "Kimara kare loma yo (solparsana kan \"|\")",
-       "rc_categories_any": "Kon",
        "newsectionsummary": "/* $1 */ warzaf gabot",
        "rc-enhanced-expand": "Pintanedira (JavaScript tir adraf)",
        "rc-enhanced-hide": "Pintapalsera",
index a1eadcb..6849379 100644 (file)
        "newpageletter": "न",
        "boteditletter": "बॉ",
        "number_of_watching_users_pageview": "[$1 ध्यान राखय वाले {{PLURAL:$1|सदस्य}}]",
-       "rc_categories": "श्रेणीन् तक सीमीत रक्खा जाय (\"|\" से अलग करा जाय)",
-       "rc_categories_any": "कवनो भी",
        "rc-change-size-new": "बदलाव कय बाद $1 {{PLURAL:$1|बाइट}}",
        "newsectionsummary": "/* $1 */ नँवा अनुभाग",
        "rc-enhanced-expand": "विस्तृत जानकारी देखावा जाय",
index 48c0971..f428e9c 100644 (file)
        "newpageletter": "Y",
        "boteditletter": "b",
        "number_of_watching_users_pageview": "[$1 izləyən istifadəçi]",
-       "rc_categories": "Kateqoriyalara limit qoy (\"|\" ilə ayır)",
-       "rc_categories_any": "Seçilənlərdən hər hansı biri",
        "rc-change-size": "$1",
        "rc-change-size-new": "Dəyişiklikdən sonrakı ölçü: $1 bayt",
        "newsectionsummary": "/* $1 */ yeni bölmə",
index 9abf0be..3137638 100644 (file)
        "newpageletter": "ی",
        "boteditletter": "ب",
        "number_of_watching_users_pageview": "[{{PLURAL:$1|بیر|$1}} ایزله‌ین ایستیفاده‌چی]",
-       "rc_categories": "بؤلمه‌لره محدودلاشدیر («|» ایله آییر)",
-       "rc_categories_any": "سئچیلمیشلرین هر بیریسی",
        "rc-change-size-new": "دَییشیکلیک‌دن سوْنرا {{PLURAL:|بیر|$1}} بایت",
        "newsectionsummary": "/* $1 */ یئنی بؤلمه",
        "rc-enhanced-expand": "تفصیل‌لری گؤستر",
index 988ecdf..a44a7c0 100644 (file)
        "newpageletter": "Я",
        "boteditletter": "б",
        "number_of_watching_users_pageview": "[$1 күҙәткән {{PLURAL:$1|ҡатнашыусы}}]",
-       "rc_categories": "Тик категорияларҙан ғына (бүлеүсе «|»):",
-       "rc_categories_any": "Һайланғандың теләһә ҡайһыһы",
        "rc-change-size-new": "Үҙгәртештән һуң күләм: $1 {{PLURAL:$1|1=байт|байт}}",
        "newsectionsummary": "/* $1 */ яңы бүлек",
        "rc-enhanced-expand": "Ваҡ-төйәгенә тиклем күрһәтергә",
index 5e6571d..143531c 100644 (file)
        "newpageletter": "N",
        "boteditletter": "B",
        "number_of_watching_users_pageview": "[$1 {{PLURAL:$1|beówochtender|beówochtende}} Benutzer]",
-       "rc_categories": "Netter Seiten aus d' Kategorien (trennd mid \"l\"):",
-       "rc_categories_any": "Olle",
        "newsectionsummary": "Neicher Obschnit /* $1 */",
        "rc-enhanced-expand": "Details zoagn (braucht JavaScript)",
        "rc-enhanced-hide": "Details vastecka",
index 49f9457..22f8bbb 100644 (file)
        "newpageletter": "ن",
        "boteditletter": "ب",
        "number_of_watching_users_pageview": "[$1 چارگنت {{PLURAL:$1|کاربر|کابران}}]",
-       "rc_categories": "محدودیت په دسته جات(دورش گون\"|\")",
-       "rc_categories_any": "هرچی",
        "rc-change-size-new": "$1 {{PLURAL:$1|بایت}} رند چه تغییر",
        "newsectionsummary": "/* $1 */ نوکین بخش",
        "rc-enhanced-expand": "جزئیاتء پیس دارگ",
index cdacb1a..2208f5b 100644 (file)
        "newpageletter": "B",
        "boteditletter": "b",
        "number_of_watching_users_pageview": "[$1 naka-antabay sa {{PLURAL:$1|paragamit|mga paragamit}}]",
-       "rc_categories": "Limitado sa mga kategorya (suhayon nin \"|\")",
-       "rc_categories_any": "Dawà arín",
        "rc-change-size-new": "$1 {{PLURAL:$1|byte|bytes}} pagtatapos kan pagbabago",
        "newsectionsummary": "/* $1 */ bàgong seksyon",
        "rc-enhanced-expand": "Ipahiling an mga detalye",
index 30ea1c9..061f26b 100644 (file)
        "right-purge": "ачыстка кэшу старонак бяз запыту пацьверджаньня",
        "right-autoconfirmed": "Ня дзейнічаюць абмежаваньні хуткасьці па IP",
        "right-bot": "Лічыцца аўтаматычным працэсам",
-       "right-nominornewtalk": "не паведамляць удзельнікам пра новыя паведамленьні на іх старонках гутарак, калі зробленыя там праўкі былі дробнымі",
+       "right-nominornewtalk": "Ð\9dе паведамляць удзельнікам пра новыя паведамленьні на іх старонках гутарак, калі зробленыя там праўкі былі дробнымі",
        "right-apihighlimits": "менш абмежаваньняў на выкананьне API-запытаў",
        "right-writeapi": "выкарыстаньне API для запісу",
-       "right-delete": "выдаленьне старонак",
+       "right-delete": "Ð\92ыдаленьне старонак",
        "right-bigdelete": "Выдаленьне старонак зь вялікімі гісторыямі",
        "right-deletelogentry": "выдаленьне і аднаўленьне асобных запісаў журналу",
        "right-deleterevision": "выдаленьне і аднаўленьне асобных вэрсіяў старонак",
-       "right-deletedhistory": "пÑ\80аглÑ\8fд Ð²Ñ\8bдаленай Ð³Ñ\96Ñ\81Ñ\82оÑ\80Ñ\8bÑ\96 Ñ\81Ñ\82аÑ\80онак Ð±Ðµз доступу да выдаленага тэксту",
-       "right-deletedtext": "прагляд выдаленага тэксту і зьменаў паміж выдаленымі вэрсіямі старонак",
-       "right-browsearchive": "пошук выдаленых старонак",
+       "right-deletedhistory": "Ð\9fÑ\80аглÑ\8fд Ð²Ñ\8bдаленай Ð³Ñ\96Ñ\81Ñ\82оÑ\80Ñ\8bÑ\96 Ñ\81Ñ\82аÑ\80онак Ð±Ñ\8fз доступу да выдаленага тэксту",
+       "right-deletedtext": "Ð\9fрагляд выдаленага тэксту і зьменаў паміж выдаленымі вэрсіямі старонак",
+       "right-browsearchive": "Ð\9fошук выдаленых старонак",
        "right-undelete": "аднаўленьне старонак",
        "right-suppressrevision": "праглядаць, хаваць і аднаўляць пэўныя вэрсіі старонак, зробленыя любым удзельнікам",
        "right-viewsuppressed": "праглядаць вэрсіі старонак, схаваныя ад усіх удзельнікаў",
        "newpageletter": "Н",
        "boteditletter": "р",
        "number_of_watching_users_pageview": "[$1 {{PLURAL:$1|назіральнік|назіральнікі|назіральнікаў}}]",
-       "rc_categories": "Абмежаваць катэгорыямі (разьдзяляйце знакам «|»):",
-       "rc_categories_any": "Любая з абраных",
        "rc-change-size-new": "$1 {{PLURAL:$1|байт|байты|байтаў}} пасьля зьмены",
        "newsectionsummary": "/* $1 */ новая сэкцыя",
        "rc-enhanced-expand": "Паказаць падрабязнасьці",
index 6dac67e..795ab33 100644 (file)
        "newpageletter": "Н",
        "boteditletter": "р",
        "number_of_watching_users_pageview": "[$1 {{PLURAL:$1|назіральнік|назіральнікі|назіральнікаў}}]",
-       "rc_categories": "Абмежаваць катэгорыямі (размяжоўваць знакам \"|\"):",
-       "rc_categories_any": "Любая з абраных",
        "rc-change-size-new": "$1 {{PLURAL:$1|байт|байты|байтаў}} пасля змены",
        "newsectionsummary": "/* $1 */ новы падраздзел",
        "rc-enhanced-expand": "Паказаць падрабязнасці",
index f166881..2b07773 100644 (file)
        "newpageletter": "Н",
        "boteditletter": "б",
        "number_of_watching_users_pageview": "[$1 {{PLURAL:$1|наблюдаващ потребител|наблюдаващи потребители}}]",
-       "rc_categories": "Само от категории (разделител „|“)",
-       "rc_categories_any": "Която и да е от избраните",
        "rc-change-size-new": "$1 {{PLURAL:$1|байт|байта}} след редакцията",
        "newsectionsummary": "Нова тема /* $1 */",
        "rc-enhanced-expand": "Показване на детайли",
index d919c28..c25ab3e 100644 (file)
        "newpageletter": "نوک",
        "boteditletter": "ر",
        "number_of_watching_users_pageview": "[$1 {{PLURAL:$1|کار زوروک}} دیستینوک]",
-       "rc_categories": "ای تهرهانی حد ئا (گۆ «|» ئا جیتا کنیت)",
-       "rc_categories_any": "هر گوجام",
        "rc-change-size-new": "$1 {{PLURAL:$1|بایٹ}} پد شه تغیرا",
        "newsectionsummary": "/* $1 */ نوکین بخش",
        "rc-enhanced-expand": "جزئیات ئی نشان داتین",
index 79f2d7e..bda0e06 100644 (file)
        "newpageletter": "न",
        "boteditletter": "बॉ",
        "number_of_watching_users_pageview": "[$1 {{PLURAL:$1|प्रयोगकर्ता|प्रयोगकर्ता लोग}} के धियानसूची में बा]",
-       "rc_categories": "श्रेणिन के सीमा (\"|\" से अलगा करीं):",
-       "rc_categories_any": "बीछल में से कौनों एक ठो",
        "rc-change-size-new": "बदलाव के बाद $1 {{PLURAL:$1|बाइट|बाइट्स}}",
        "newsectionsummary": "/* $1 */ नया खंड",
        "rc-enhanced-expand": "डिटेल देखावल जाय",
index 9431cf9..e1a1d8e 100644 (file)
        "newpageletter": "H",
        "boteditletter": "b",
        "number_of_watching_users_pageview": "[$1 {{PLURAL:$1|pa'itihi|papa'itihi}}]",
-       "rc_categories": "Watasi tutumbung (pisahakan lawan \"|\")",
-       "rc_categories_any": "Napa gin",
        "rc-change-size-new": "$1 {{PLURAL:$1|bita|bita}} limbah paubahan",
        "newsectionsummary": "/* $1 */ hagian hanyar",
        "rc-enhanced-expand": "Tampaiakan rincian (parlu ada JavaScript)",
index 48f961f..e39abd1 100644 (file)
        "newpageletter": "ন",
        "boteditletter": "ব",
        "number_of_watching_users_pageview": "[$1 {{PLURAL:$1|জন ব্যবহারকারী|জন ব্যবহারকারী}} এই পাতার উপর নজর রাখছেন]",
-       "rc_categories": "বিষয়শ্রেণীগুলিতে সীমা (\"|\" দিয়ে আলাদা করুন):",
-       "rc_categories_any": "চয়নের জন্য যেকোনো কিছু",
        "rc-change-size-new": "পরিবর্তনের পর $1 {{PLURAL:$1|বাইট}}",
        "newsectionsummary": "/* $1 */ নতুন অনুচ্ছেদ",
        "rc-enhanced-expand": "বিস্তারিত দেখাও",
index ca9d0bd..33a3f39 100644 (file)
        "minoreditletter": "སྒྲིག་ཆུང་།",
        "newpageletter": "ཤོག་གསར།",
        "boteditletter": "རང་འགུལ་འཕྲུལ་ཆས།",
-       "rc_categories_any": "གང་རུང་།",
        "rc-enhanced-expand": "ཞིབ་ཕྲར་སྟོན།",
        "rc-enhanced-hide": "ཞིབ་ཕྲ་སྦས་བ།",
        "recentchangeslinked": "འབྲེལ་བའི་བཟོ་བཅོས།",
index 3147d4c..8f05d05 100644 (file)
        "newpageletter": "N",
        "boteditletter": "b",
        "number_of_watching_users_pageview": "[$1 {{PLURAL:$1|implijer o heuliañ|implijer}} o heuliañ]",
-       "rc_categories": "Bevenniñ d'ar rummadoù (dispartiet gant \"|\") :",
-       "rc_categories_any": "Unan e-touez ar re zibabet",
        "rc-change-size-new": "$1 {{PLURAL:$1|okted|okted}} goude kemmañ",
        "newsectionsummary": "/* $1 */ rann nevez",
        "rc-enhanced-expand": "Diskouez ar munudoù",
index 2715118..991dc1e 100644 (file)
        "newpageletter": "N",
        "boteditletter": "b",
        "number_of_watching_users_pageview": "[$1 {{PLURAL:$1|korisnik|korisnika}} koji pregledaju]",
-       "rc_categories": "Ograniči na kategorije (razdvoji sa \"|\"):",
-       "rc_categories_any": "Bilo koju odabranu",
        "rc-change-size-new": "$1 {{PLURAL:$1|bajt|bajta|bajtova}} poslije izmjene",
        "newsectionsummary": "/* $1 */ novi odlomak",
        "rc-enhanced-expand": "Prikaži detalje",
index e06a65f..3eaf1b5 100644 (file)
        "minoreditletter": "m",
        "newpageletter": "B",
        "boteditletter": "b",
-       "rc_categories_any": "Dawa uno",
        "newsectionsummary": "/* $1 */ bagong seksyon",
        "rc-enhanced-expand": "Ipabayad a mga detalye",
        "filename": "Filename",
index 5657fb2..13918d8 100644 (file)
        "botpasswords-insert-failed": "No s'ha pogut afegir el nom del bot «$1». Ja hi estava afegit?",
        "botpasswords-update-failed": "No s'ha pogut actualitzar el nom del bot «$1». Hi estava suprimit?",
        "botpasswords-created-title": "S'ha creat la contrasenya del bot",
-       "botpasswords-created-body": "S'ha creat la contrasenya per al bot «$1» de l'usuari «$2».",
+       "botpasswords-created-body": "S'ha creat la contrasenya per al bot «$1» de {{GENDER:$2||l'usuari|la usuària}} «$2».",
        "botpasswords-updated-title": "Contrasenya de bot actualitzada",
-       "botpasswords-updated-body": "La contrasenya pel bot «$1» de l'usuari «$2» ha estat actualitzada.",
+       "botpasswords-updated-body": "La contrasenya pel bot «$1» de {{GENDER:$2|l'usuari|la usuària}} «$2» ha estat actualitzada.",
        "botpasswords-deleted-title": "S'ha eliminat la contrasenya del bot",
-       "botpasswords-deleted-body": "La contrasenya del bot \"$1\", pertanyent a l'usuari \"$2\", ha estat eliminada.",
+       "botpasswords-deleted-body": "La contrasenya pel bot «$1» de {{GENDER:$2|l'usuari|la usuària}} «$2» ha estat eliminada.",
        "botpasswords-newpassword": "La nova contrasenya per a iniciar sessió amb <strong>$1</strong> és <strong>$2</strong>. <em>Guardeu-la de cara al futur.</em><br> (Per a bots vells que necessiten que el nom per a iniciar sessió sigui el mateix que el nom d'usuari, també podeu usar <strong>$3</strong> com a nom d'usuari i <strong>$4</strong> com a contrasenya.)",
        "botpasswords-no-provider": "BotPasswordsSessionProvider no està disponible.",
        "botpasswords-restriction-failed": "Les restriccions de contrasenyes de bots impedeixen aquest inici de sessió.",
        "recentchangesdays-max": "(màxim $1 {{PLURAL:$1|dia|dies}})",
        "recentchangescount": "Nombre d'edicions a mostrar per defecte:",
        "prefs-help-recentchangescount": "Inclou els canvis recents, els historials de pàgines i els registres.",
-       "prefs-help-watchlist-token2": "Aquesta és la clau secreta pel canal de continguts de la vostra llista de seguiment.\nQualsevol que la conegui podria llegir la vostra llista de seguiment, així que no la compartiu.\n[[Special:ResetTokens|Cliqueu aquí si voleu restaurar-la]].",
+       "prefs-help-watchlist-token2": "Aquesta és la clau secreta pel canal de continguts de la vostra llista de seguiment.\nQualsevol que la conegui podria llegir la vostra llista de seguiment, així que no la compartiu.\nSi és necessari, [[Special:ResetTokens|la podeu restaurar]].",
        "savedprefs": "S’han desat les vostres preferències.",
        "savedrights": "S'han desat els grups d'usuari de {{GENDER:$1|$1}}.",
        "timezonelegend": "Fus horari:",
        "recentchanges-legend": "Opcions de canvis recents",
        "recentchanges-summary": "Seguiu els canvis més recents del wiki en aquesta pàgina.",
        "recentchanges-noresult": "Cap canvi corresponent a aquests criteris en el període indicat.",
+       "recentchanges-timeout": "Aquesta cerca ha temporitzat. Podeu provar amb paràmetres de cerca diferents.",
+       "recentchanges-network": "A causa d'un error tècnic no s'ha pogut recuperar cap resultat. Intenteu refrescar la pàgina.",
        "recentchanges-feed-description": "Segueix en aquest canal els canvis més recents del wiki.",
        "recentchanges-label-newpage": "Aquesta modificació creà una pàgina",
        "recentchanges-label-minor": "Aquesta és una modificació menor",
        "rcfilters-filter-previousrevision-label": "No la darrera revisió",
        "rcfilters-filter-previousrevision-description": "Tots els canvis que no són «la darrera revisió».",
        "rcfilters-filter-excluded": "Exclòs",
+       "rcfilters-tag-prefix-namespace-inverted": "<strong>:no</strong> $1",
        "rcfilters-exclude-button-off": "Exclou els seleccionats",
        "rcfilters-exclude-button-on": "Excloent els seleccionats",
        "rcfilters-view-tags": "Canvis etiquetats",
        "boteditletter": "b",
        "unpatrolledletter": "!",
        "number_of_watching_users_pageview": "[{{PLURAL:$1|Un usuari vigila|$1 usuaris vigilen}} aquesta pàgina]",
-       "rc_categories": "Limita a les categories (separades amb «|»):",
-       "rc_categories_any": "Qualsevol de les triades",
        "rc-change-size": "$1",
        "rc-change-size-new": "$1 {{PLURAL:$1|byte|bytes}} després del canvi",
        "newsectionsummary": "/* $1 */ secció nova",
        "recentchangeslinked-feed": "Canvis relacionats",
        "recentchangeslinked-toolbox": "Canvis relacionats",
        "recentchangeslinked-title": "Canvis relacionats amb «$1»",
-       "recentchangeslinked-summary": "Aquesta llista reflecteix els canvis recents a les pàgines enllaçades des d'una pàgina concreta (o als membres d'una categoria concreta).\nLes pàgines de la vostra [[Special:Watchlist|llista de seguiment]] apareixen en <strong>negreta</strong>.",
+       "recentchangeslinked-summary": "Introduïu un nom de pàgina per veure els canvis en les pàgines enllaçades des de o cap a aquesta pàgina (per veure els membres d'una categoria, introduïu Categoria:Nom de la categoria).\nEls canvis en pàgines de la vostra [[Special:Watchlist|llista de seguiment]] apareixen en <strong>negreta</strong>.",
        "recentchangeslinked-page": "Nom de la pàgina:",
        "recentchangeslinked-to": "Mostra els canvis de les pàgines enllaçades amb la pàgina donada",
        "recentchanges-page-added-to-category": "[[:$1]] afegida a la categoria",
        "doubleredirects": "Redireccions dobles",
        "doubleredirectstext": "Aquesta pàgina llista les pàgines que redirigeixen a altres pàgines de redirecció.\nCada fila conté enllaços a la primera i la segona redireccions, així com la destinació de la segona redirecció, que generalment és la pàgina de destinació \"real\" a la qual hauria d'apuntar la primera redirecció.\nLes entrades <del>ratllades</del> s'han resolt.",
        "double-redirect-fixed-move": "S'ha reanomenat [[$1]].\nS'ha actualitzat automàticament i ara redirigeix a [[$2]].",
-       "double-redirect-fixed-maintenance": "S'ha arreglat automàticament la redirecció doble de [[$1]] a [[$2]] en un treball de manteniment.",
+       "double-redirect-fixed-maintenance": "Correcció automàtica de la redirecció doble de [[$1]] a [[$2]] en un tasca de manteniment",
        "double-redirect-fixer": "Supressor de dobles redireccions",
        "brokenredirects": "Redireccions rompudes",
        "brokenredirectstext": "Les següents redireccions enllacen a pàgines inexistents:",
        "import-mapping-namespace": "Importa a un espai de noms:",
        "import-mapping-subpage": "Importa com a subpàgines de la pàgina següent:",
        "import-upload-filename": "Nom de fitxer:",
+       "import-upload-username-prefix": "Prefix interwiki:",
        "import-comment": "Comentari:",
        "importtext": "Exporteu el fitxer des del wiki d'origen utilitzant l'[[Special:Export|eina d'exportació]].\nDeseu-lo al vostre ordinador i carregueu-ne una còpia ací.",
        "importstart": "S'estan important pàgines...",
        "version-poweredby-others": "altres",
        "version-poweredby-translators": "Traductors de translatewiki.net",
        "version-credits-summary": "El nostre reconeixement a les següents persones per la seva aportació a [[Special:Version|MediaWiki]]",
-       "version-license-info": "MediaWiki és programari lliure, podeu redistribuir-lo i/o modificar-lo sota els termes de la Llicència Pública General GNU publicada per la Free Software Foundation, sigui de la seva versió 2 o (a elecció vostra) de qualsevol versió posterior. \n\nMediaWiki es distribueix en l'esperança de ser d'utilitat, però SENSE CAP GARANTIA; ni tan sols la garantia implícita de COMERCIALITZACIÓ o ADEQUACIÓ A UNA FINALITAT DETERMINADA. En trobareu més detalls a  la Llicència Pública General GNU.\n\nAmb aquest programa heu d'haver rebut [{{SERVER}}{{SCRIPTPATH}}/COPYING una còpia de la Llicència Pública General GNU]; si no és així, adreceu-vos a la Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA o bé [//www.gnu.org/licenses/old-licenses/gpl-2.0.html llegiu-la en línia].",
+       "version-license-info": "MediaWiki és programari lliure, podeu redistribuir-lo i/o modificar-lo sota els termes de la Llicència Pública General GNU publicada per la Free Software Foundation, sigui de la seva versió 2 o (a elecció vostra) de qualsevol versió posterior. \n\nMediaWiki es distribueix en l'esperança de ser d'utilitat, però <em>SENSE CAP GARANTIA</em>; ni tan sols la garantia implícita de <strong>COMERCIALITZACIÓ</strong> o <strong>ADEQUACIÓ A UNA FINALITAT DETERMINADA</strong>. Vegeu la Llicència Pública General GNU per a més informació.\n\nAmb aquest programa heu d'haver rebut [{{SERVER}}{{SCRIPTPATH}}/COPYING una còpia de la Llicència Pública General GNU]; si no és així, adreceu-vos a la Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA o bé [//www.gnu.org/licenses/old-licenses/gpl-2.0.html llegiu-la en línia].",
        "version-software": "Programari instal·lat",
        "version-software-product": "Producte",
        "version-software-version": "Versió",
index d5aa840..cfc24e5 100644 (file)
        "newpageletter": "К",
        "boteditletter": "б",
        "number_of_watching_users_pageview": "[$1 {{PLURAL:$1|тӀехьожу декъашхо|тӀехьожу декъашхой}}]",
-       "rc_categories": "Категори чура бен (къасторг «|»)",
-       "rc_categories_any": "Муьлха а хаьржиначух",
        "rc-change-size-new": "Хийцам бин чул тӀехьа болу барам: $1 {{PLURAL:$1|байт}}",
        "newsectionsummary": "/* $1 */ Керла хьедар",
        "rc-enhanced-expand": "Гайта мадарра",
index f6da1db..76d1f58 100644 (file)
        "newpageletter": "ن",
        "boteditletter": "بۆت",
        "number_of_watching_users_pageview": "[$1 {{PLURAL:$1|بەکارھێنەر}}ی چاودێر]",
-       "rc_categories": "بەرتەسککردنەوە بە هاوپۆلەکان (به «|» جیای بکەوە‌)",
-       "rc_categories_any": "هەرکامێک بێت",
        "rc-change-size-new": "$1 {{PLURAL:$1|بایت}} پاش گۆڕانکاری",
        "newsectionsummary": "/* $1 */ بەشی نوێ",
        "rc-enhanced-expand": "وردەکارییەکان نیشان بدە",
        "autosumm-replace": "«$1»ی لە جێی ناوەرۆک دانا",
        "autoredircomment": "ڕەوانە کرا بۆ [[$1]]",
        "autosumm-removed-redirect": "ڕەوانەکەرەکەی بۆ [[$1]] داندرا بوو لابرد",
+       "autosumm-changed-redirect-target": "ئامانجی ڕەوانەکەری لە [[$1]]ەوە گۆڕی بۆ [[$2]]",
        "autosumm-new": "پەڕەی دروست کرد بە «$1»ەوە",
        "autosumm-newblank": "پەڕەی واڵای دروست کرد",
        "size-bytes": "$1 بایت",
index 81902e2..3eaeffe 100644 (file)
        "newpageletter": "Я",
        "boteditletter": "б",
        "number_of_watching_users_pageview": "[$1 {{PLURAL:$1|1=къулланыджы|къулланыджы}} козете]",
-       "rc_categories": "Тек категориялардан («|» иле айырыла)",
-       "rc_categories_any": "Эр анги",
        "rc-change-size-new": "Денъиштирильген сонъ $1 {{PLURAL:$1|байт|байт}}",
        "newsectionsummary": "/* $1 */ янъы болюк",
        "rc-enhanced-expand": "Тафсилятыны косьтер",
index 9fc1e44..13d8a41 100644 (file)
        "newpageletter": "Y",
        "boteditletter": "b",
        "number_of_watching_users_pageview": "[$1 {{PLURAL:$1|qullanıcı|qullanıcı}} közete]",
-       "rc_categories": "Tek kategoriyalardan (\"|\" ile ayırıla)",
-       "rc_categories_any": "Er angi",
        "rc-change-size-new": "Deñiştirilgen soñ $1 {{PLURAL:$1|bayt|bayt}}",
        "newsectionsummary": "/* $1 */ yañı bölük",
        "rc-enhanced-expand": "Tafsilâtını köster",
index bebe16c..ad271fc 100644 (file)
        "newpageletter": "N",
        "boteditletter": "r",
        "number_of_watching_users_pageview": "[$1 {{PLURAL:$1|sledující uživatel|sledující uživatelé|sledujících uživatelů}}]",
-       "rc_categories": "Omezit na kategorie (oddělené „|“):",
-       "rc_categories_any": "Jakákoli z vybraných",
        "rc-change-size-new": "$1 {{PLURAL:$1|bajt|bajty|bajtů}} po změně",
        "newsectionsummary": "Nová sekce /* $1 */",
        "rc-enhanced-expand": "Zobrazit detaily",
        "lockmanager-fail-closelock": "Soubor se zámkem pro „$1“ nelze zavřít.",
        "lockmanager-fail-deletelock": "Soubor se zámkem pro „$1“ nelze smazat.",
        "lockmanager-fail-acquirelock": "Zámek pro „$1“ nelze získat.",
-       "lockmanager-fail-openlock": "Soubor se zámkem „$1“ nelze otevřít. Ujistěte se, že vámi nahraný adresář je správně nakonfigurován a že váš webový server má povolení k editaci tohoto adresáře. Pro další informace vizte https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:$wgUploadDirectory.",
+       "lockmanager-fail-openlock": "Soubor zámku „$1“ nelze otevřít. Ujistěte se, že váš adresář nahraných souborů je správně nakonfigurován a že váš webový server má povolení k zápisu do tohoto adresáře. Pro další informace vizte https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:$wgUploadDirectory.",
        "lockmanager-fail-releaselock": "Zámek pro „$1“ nelze uvolnit.",
        "lockmanager-fail-db-bucket": "Nelze navázat spojení s dostatečným počtem databází zámků v bloku $1.",
        "lockmanager-fail-db-release": "Uzamčení databáze $1 nelze uvolnit.",
index 8a10d62..6d27e3e 100644 (file)
        "minoreditletter": "м҃л",
        "newpageletter": "н҃в",
        "boteditletter": "а҃ѵ",
-       "rc_categories_any": "Любы из выбраных",
        "rc-change-size-new": "$1 {{PLURAL:$1|баитъ|баита|баитъ}} послѣди мѣнꙑ",
        "rc-old-title": "напрьва страница створѥна ꙗко ⁖ $1 ⁖",
        "recentchangeslinked": "съвѧꙁанꙑ страницѧ",
index cac833e..00fdd2f 100644 (file)
        "newpageletter": "Ç",
        "boteditletter": "б",
        "unpatrolledletter": "!",
-       "rc_categories_any": "Кашни",
        "newsectionsummary": "/* $1 */ Çĕнĕ тема",
        "recentchangeslinked": "Çыхăннă улшăнусем",
        "recentchangeslinked-feed": "Çыхăннă улшăнусем",
index 1a1e6a2..10b4025 100644 (file)
        "newpageletter": "N",
        "boteditletter": "b",
        "number_of_watching_users_pageview": "[$1 {{PLURAL:$1|defnyddwyr|defnyddiwr|ddefnyddiwr|defnyddiwr|defnyddiwr|o ddefnyddwyr}} yn gwylio]",
-       "rc_categories": "Cyfyngu i gategorïau (gwahanwch gyda \"|\")",
-       "rc_categories_any": "Unrhyw un",
        "rc-change-size-new": "$1 {{PLURAL:$1|beit}} wedi'r newid",
        "newsectionsummary": "/* $1 */ adran newydd",
        "rc-enhanced-expand": "Dangos y manylion",
index 9e4e93f..e065bb9 100644 (file)
        "newpageletter": "N",
        "boteditletter": "b",
        "number_of_watching_users_pageview": "[$1 {{PLURAL:$1|overvågende bruger|overvågende brugere}}]",
-       "rc_categories": "Grænse for kategorier (adskilt med \"|\"):",
-       "rc_categories_any": "Nogen af de valgte",
        "rc-change-size": "$1 {{PLURAL:$1|Byte|Bytes}}",
        "rc-change-size-new": "$1 {{PLURAL:$1|byte|bytes}} efter ændring",
        "newsectionsummary": "/* $1 */ nyt afsnit",
index 8a26c7d..642130b 100644 (file)
        "right-editmyprivateinfo": "Eigene private Daten bearbeiten (beispielsweise E-Mail-Adresse, richtiger Name)",
        "right-override-export-depth": "Exportiere Seiten einschliesslich verlinkter Seiten bis zu einer Tiefe von 5",
        "recentchanges-label-plusminus": "Die Änderung der Seitengrösse in Bytes",
-       "rc_categories": "Nur Seiten aus den Kategorien (getrennt mit «|»):",
        "rc-change-size-new": "$1 {{PLURAL:$1|Byte|Bytes}} nach der Änderung",
        "rc-old-title": "ursprünglich erstellt als «$1»",
        "recentchangeslinked-title": "Änderungen an Seiten, die von «$1» verlinkt sind",
index 79a3ab6..e51edde 100644 (file)
        "newpageletter": "N",
        "boteditletter": "B",
        "number_of_watching_users_pageview": "[$1 {{PLURAL:$1|beobachtender|beobachtende}} Benutzer]",
-       "rc_categories": "Nur Seiten aus den Kategorien (getrennt mit „|“):",
-       "rc_categories_any": "Beliebige der ausgewählten",
        "rc-change-size": "$1 {{PLURAL:$1|Byte|Bytes}}",
        "rc-change-size-new": "$1 {{PLURAL:$1|Byte|Bytes}} nach der Änderung",
        "newsectionsummary": "Neuer Abschnitt /* $1 */",
index af8a580..d5e5ca8 100644 (file)
        "boteditletter": "b",
        "unpatrolledletter": "!",
        "number_of_watching_users_pageview": "[$1 ho seyr keno {{PLURAL:$1|karber|karberî}}]",
-       "rc_categories": "Kategoriyan rêz kı ( \"|“ ya ciya yo):",
-       "rc_categories_any": "Weçinayiyan ra her yew",
        "rc-change-size": "$1",
        "rc-change-size-new": "$1 {{PLURAL:$1|bayt|bayti}} ra dıma vurnayış",
        "newsectionsummary": "/* $1 */ qısımo newe",
        "exportcuronly": "têna revizyonê peyin bıger",
        "exportnohistory": "----\n'''Not:''' pê no form teberdayişê verê (tarix) pelan battal biyo",
        "exportlistauthors": "zerre de qandê her pela listey iştiraxkara esto",
-       "export-submit": "Teber de",
+       "export-submit": "Teberdayış",
        "export-addcattext": "Kategoriye ra pelan têare ke",
        "export-addcat": "Têare ke",
        "export-addnstext": "pelan cayê nameyan ra têare ker",
        "import-interwiki-sourcepage": "Perra çımey:",
        "import-interwiki-history": "Qeydanê pele pêrune kopya ke",
        "import-interwiki-templates": "Şablonan pêro zerre ke",
-       "import-interwiki-submit": "Zerre ke",
+       "import-interwiki-submit": "Zerredayış",
        "import-mapping-default": "Hesıbyaye lokasyonan miyan ke",
        "import-mapping-namespace": "Dek yu canamey miyan",
        "import-mapping-subpage": "Bınnpeley ena peler deyne azere ke",
index 53f742a..2919aed 100644 (file)
        "newpageletter": "N",
        "boteditletter": "B",
        "number_of_watching_users_pageview": "[$1 {{PLURAL:$1|wobglědowaŕ|wobglědowarja|wobglědowarje}}]",
-       "rc_categories": "Jano boki z kategorijow (źělone z pomocu „|“):",
-       "rc_categories_any": "wše",
        "rc-change-size-new": "$1 {{PLURAL:$1|byte|byta|byty|bytow}} pó změnje",
        "newsectionsummary": "Nowy wótrězk /* $1 */",
        "rc-enhanced-expand": "Drobnostki pokazaś",
index dc25eb0..5d5449a 100644 (file)
        "minoreditletter": "ना",
        "newpageletter": "नौ",
        "boteditletter": "बो",
-       "rc_categories": "श्रेणीहरूमी सीमित (\"|\" ले छुट्याओ)",
        "rc-change-size-new": "$1 {{PLURAL:$1|बाइट|बाइट्स}}फेरबदल पाछा",
        "recentchangeslinked": "सम्बन्धित फेरबदल",
        "recentchangeslinked-toolbox": "सम्बन्धित फेरबदल",
index 52595ad..4d97f4b 100644 (file)
        "newpageletter": "N",
        "boteditletter": "b",
        "number_of_watching_users_pageview": "[vésta da {{PLURAL:$1|un utèint|$1 utèint}}]",
-       "rc_categories": "Lémita al categoréi (separêdi da \"|\")",
-       "rc_categories_any": "Bast' ech sia fra còli sgnêdi",
        "rc-change-size-new": "$1 {{PLURAL:$1|byte|byte}} dôp la mudéfica",
        "newsectionsummary": "/* $1 */ sesiòn nōva",
        "rc-enhanced-expand": "Fà vèder i particulêr.",
index 7d9c891..09e5fae 100644 (file)
        "newpageletter": "Ν",
        "boteditletter": "ρ",
        "number_of_watching_users_pageview": "[$1 {{PLURAL:$1|χρήστης|χρήστες}} παρακολουθούν]",
-       "rc_categories": "Περιορίστε τις κατηγορίες (διαχωρίστε τις με \"|\"):",
-       "rc_categories_any": "Οποιαδήποτε από τις επιλεγμένες",
        "rc-change-size-new": "$1 {{PLURAL:$1|byte|bytes}} μετά από την αλλαγή",
        "newsectionsummary": "/* $1 */ νέα ενότητα",
        "rc-enhanced-expand": "Εμφάνιση λεπτομερειών",
        "log-title-wildcard": "Αναζήτησε τίτλους που αρχίζουν με αυτό το κείμενο",
        "showhideselectedlogentries": "Αλλαγή ορατότητας των επιλεγμένων καταχωρήσεων στο αρχείο καταγραφής συμβάντων",
        "log-edit-tags": "Επεξεργασία ετικετών των επιλεγμένων καταχωρήσεων του αρχείου καταγραφής",
+       "checkbox-select": "Επιλογή: $1",
        "checkbox-all": "Όλα",
        "checkbox-none": "Κανένα",
        "checkbox-invert": "Αντιστροφή",
        "newimages-user": "Διεύθυνση IP ή όνομα χρήστη",
        "newimages-showbots": "Εμφάνιση αρχείων ανεβασμένων από ρομπότ",
        "newimages-hidepatrolled": "Απόκρυψη ελεγμένων αρχείων.",
+       "newimages-mediatype": "Τύπος μέσου:",
        "noimages": "Δεν υπάρχουν εικόνες.",
        "ilsubmit": "Αναζήτηση",
        "bydate": "ημερομηνίας",
index 9d06c96..b710762 100644 (file)
        "unpatrolledletter": "!",
        "number_of_watching_users_RCview": "[$1]",
        "number_of_watching_users_pageview": "[$1 watching {{PLURAL:$1|user|users}}]",
-       "rc_categories": "Limit to categories (separate with \"|\"):",
-       "rc_categories_any": "Any of the chosen",
        "rc-change-size": "$1",
        "rc-change-size-new": "$1 {{PLURAL:$1|byte|bytes}} after change",
        "newsectionsummary": "/* $1 */ new section",
index 57213c2..1ebc823 100644 (file)
        "newpageletter": "N",
        "boteditletter": "r",
        "number_of_watching_users_pageview": "[$1 {{PLURAL:$1|priatentanta uzanto|priatentantaj uzantoj}}]",
-       "rc_categories": "Nur paĝoj el jenaj kategorioj (disigu per \"|\"):",
-       "rc_categories_any": "Iuj el la elektitaj",
        "rc-change-size-new": "$1 {{PLURAL:$1|bitoko|bitokoj}} post ŝanĝo",
        "newsectionsummary": "/* $1 */ nova sekcio",
        "rc-enhanced-expand": "Montri detalojn (per JavaScript)",
index e62887f..a98ddae 100644 (file)
@@ -15,6 +15,7 @@
        "tog-hidepatrolled": "Ocultar ediciones patrulladas de los cambios recientes",
        "tog-newpageshidepatrolled": "Ocultar páginas patrulladas de la lista de páginas nuevas",
        "tog-showtoolbar": "Mostrar barra de edición",
+       "tog-oldsig": "Su firma actual:",
        "tog-ccmeonemails": "Enviarme una copia de los correos electrónicos que yo envíe a otros usuarios",
        "sunday": "domingo",
        "monday": "lunes",
        "views": "Vistas",
        "toolbox": "Herramientas",
        "otherlanguages": "Otros idiomas",
-       "lastmodifiedat": "Esta página fue modificada por última vez el $1, a las $2.",
+       "lastmodifiedat": "Esta página fue editada por última vez el $1, a las $2.",
        "protectedpage": "Página protegida",
        "jumpto": "Saltar a:",
        "jumptonavigation": "navegación",
        "jumptosearch": "buscar",
        "view-pool-error": "Lo sentimos, los servidores están sobrecargados en este momento.\nDemasiados usuarios están intentando ver esta página.\nPor favor espere unos instantes antes de reintentar acceder nuevamente a esta página.\n\n$1",
+       "generic-pool-error": "Lo sentimos, los servidores están sobrecargados en este momento.\nHay demasiados usuarios tratando de ver este recurso.\nPor favor espere un momento antes de intentar acceder de nuevo.",
        "aboutsite": "Acerca de {{SITENAME}}",
        "aboutpage": "Project:Acerca de",
        "currentevents": "Actualidad",
        "ok": "Aceptar",
        "retrievedfrom": "Obtenido de «$1»",
        "youhavenewmessages": "{{PLURAL:$3|Tiene}} $1 ($2).",
-       "youhavenewmessagesmulti": "Tienes mensajes nuevos en $1",
+       "youhavenewmessagesfromusers": "{{PLURAL:$4|Tiene}} $1 de {{PLURAL:$3|otro usuario|$3 usuarios}} ($2).",
+       "youhavenewmessagesmanyusers": "Tiene $1 de muchos usuarios ($2).",
+       "youhavenewmessagesmulti": "Tiene mensajes nuevos en $1",
        "editsection": "editar",
        "editold": "editar",
        "viewsourceold": "ver código",
        "databaseerror-query": "Consulta: $1",
        "databaseerror-function": "Función: $1",
        "databaseerror-error": "Error: $1",
+       "transaction-duration-limit-exceeded": "Con el fin de evitar un aumento excesivo del retardo de replicación, se anuló esta transacción porque la duración de escritura ($1) excedió el límite de $2 {{PLURAL:$2|segundo|segundos}}.\nSi está cambiando muchos elementos a la vez, trate de hacer operaciones similares más pequeñas.",
        "laggedslavemode": "<strong>Aviso:</strong> la página puede no contener las actualizaciones más recientes.",
+       "readonly": "Base de datos bloqueada",
        "enterlockreason": "Proporcione el motivo del bloqueo, así como una estimación de cuándo se producirá el desbloqueo",
-       "readonlytext": "La base de datos se encuentra actualmente bloqueada y no permite la creación de páginas nuevas y otras modificaciones, probablemente de forma temporal debido al mantenimiento rutinario de la base de datos. Después de esas operaciones el sitio se encontrará nuevamente disponible.\n\nLa razón dada por el administrador que bloqueó la base de datos es la que sigue: $1",
+       "readonlytext": "Actualmente la base de datos no permite nuevas entradas u otras modificaciones, probablemente por mantenimiento rutinario, tras lo cual volverá a la normalidad.\n\nLa explicación dada por el administrador que la bloqueó fue: $1",
        "missing-article": "La base de datos no encuentra el texto de una página que debería hallarse, llamada \"$1\" $2.\n\nLa causa de esto suele deberse a un ''diff'' anacrónico o un enlace al historial de una página que ha sido borrada.\n\nSi no fuera el caso, usted puede haber encontrado un fallo en el sistema.\n\nPor favor, avise a un [[Special:ListUsers/sysop|administrador]], tomando nota de la URL.",
        "internalerror": "Error interno",
        "internalerror_info": "Error interno: $1",
        "viewsource": "Ver código",
-       "actionthrottledtext": "Como medida de protección contra el ''spam'', la acción que está realizando está limitada a un número determinado de veces en un periodo corto de tiempo. Usted ha excedido ese límite. Por favor pruebe de nuevo en unos minutos.",
-       "viewsourcetext": "Puede ver y copiar el código fuente de esta página:",
-       "editinginterface": "'''Aviso:''' Está usted editando una página usada para proporcionar texto de interfaz para el software. Los cambios en esta página afectarán a la apariencia de la interfaz para los demás usuarios. Para traducciones, por favor considere usar [//translatewiki.net/wiki/Main_Page?setlang=en translatewiki.net], el proyecto de traducción de MediaWiki.",
+       "actionthrottledtext": "Como medida contra los abusos, la acción que está realizando está limitada a un número determinado de veces en un periodo corto de tiempo, y ha excedido ese límite.\nPor favor inténtelo de nuevo en unos minutos.",
+       "viewsourcetext": "Puede ver y copiar el código fuente de esta página.",
+       "viewyourtext": "Puede ver y copiar el código de <strong>sus ediciones</strong> en esta página.",
+       "protectedinterface": "Esta página proporciona el texto de la interfaz del software en este wiki, y está protegida para prevenir el abuso.\nPara agregar o cambiar las traducciones para todos los wikis, use [https://translatewiki.net/ translatewiki.net], el proyecto de localización de MediaWiki.",
+       "editinginterface": "<strong>Advertencia:</strong> está editando una página usada para proporcionar texto de la interfaz al software. \nLos cambios en esta página afectarán la apariencia de la interfaz de los demás usuarios de este wiki.",
+       "translateinterface": "Para añadir o cambiar traducciones para todos los wikis, use [https://translatewiki.net/ translatewiki.net], el proyecto de traducción de MediaWiki.",
+       "namespaceprotected": "No tiene permiso para editar las páginas del espacio de nombres <strong>$1</strong>.",
+       "customcssprotected": "No tiene permiso para editar esta página CSS, porque contiene configuraciones personales de otro usuario.",
+       "customjsprotected": "No tiene permiso para editar esta página JavaScript, porque contiene configuraciones personales de otro usuario.",
+       "mycustomcssprotected": "No tiene permiso para editar esta página CSS.",
+       "mycustomjsprotected": "No tiene permiso para editar esta página JavaScript.",
+       "myprivateinfoprotected": "No tiene permiso para editar su información privada.",
+       "mypreferencesprotected": "No tiene permiso para editar sus preferencias.",
+       "exception-nologin-text": "Por favor inicie sesión para acceder a esta página o llevar a cabo esta acción.",
+       "exception-nologin-text-manual": "Necesita $1 para poder ver esta página o llevar a cabo esta acción.",
+       "logouttext": "<strong>Su sesión ha finalizado.</strong>\n\nPuede que algunas páginas continúen mostrándose como si la sesión estuviera iniciada hasta que actualice la caché de su navegador.",
        "welcomeuser": "Le damos la bienvenida, $1.",
        "welcomecreation-msg": "Se ha creado su cuenta.\nPuede cambiar las [[Special:Preferences|preferencias]] de {{SITENAME}} si lo desea.",
        "yourname": "Nombre de usuario:",
        "yourpasswordagain": "Escriba la contraseña otra vez:",
        "createacct-yourpasswordagain": "Confirme la contraseña",
        "createacct-yourpasswordagain-ph": "Escriba la contraseña otra vez",
+       "yourdomainname": "Su dominio:",
+       "password-change-forbidden": "No puede cambiar las contraseñas en este wiki.",
+       "externaldberror": "Hubo un error de autenticación en la base de datos, o bien no tiene autorización para actualizar su cuenta externa.",
        "login": "Acceder",
+       "login-security": "Verifique su identidad",
        "nav-login-createaccount": "Iniciar sesión / crear cuenta",
        "logout": "Desconectar",
        "userlogout": "Salir",
+       "notloggedin": "No ha accedido",
        "userlogin-noaccount": "¿No tiene una cuenta?",
        "userlogin-joinproject": "Únase a {{SITENAME}}",
        "userlogin-resetpassword-link": "¿Olvidó su contraseña?",
+       "userlogin-loggedin": "Ya está {{GENDER:$1|conectado|conectada}} como $1.\nUse el formulario de abajo para iniciar sesión como otro usuario.",
+       "userlogin-reauth": "Debe iniciar sesión de nuevo para verificar que usted es {{GENDER:$1|$1}}.",
        "createacct-emailrequired": "Dirección de correo electrónico",
        "createacct-emailoptional": "Dirección de correo electrónico (opcional)",
-       "anoneditwarning": "'''Aviso:''' No ha iniciado sesión con una cuenta de usuario.\nSu dirección IP se almacenará en el historial de ediciones de la página.",
+       "createacct-email-ph": "Escriba su dirección de correo electrónico",
+       "createacct-another-email-ph": "Escriba la dirección de correo electrónico",
+       "createacct-reason-ph": "Por qué está creando otra cuenta",
+       "createacct-submit": "Cree su cuenta",
+       "createacct-benefit-heading": "Personas como usted son las que construyen {{SITENAME}}.",
+       "badretype": "Las contraseñas que usted ha introducido no coinciden.",
+       "usernameinprogress": "Ya está en marcha la creación de una cuenta para este nombre de usuario.\nPor favor, espere.",
+       "userexists": "El nombre de usuario indicado ya está en uso.\nPor favor elija un nombre diferente.",
+       "nocookiesnew": "Se ha creado la cuenta de usuario, pero aún no ha iniciado sesión.\n{{SITENAME}} usa <em>cookies</em> para identificar a los usuarios registrados.\nSu navegador tiene desactivadas las <em>cookies</em>.\nPor favor, actívelas e inicie sesión con su nuevo nombre de usuario y contraseña.",
+       "nocookieslogin": "{{SITENAME}} utiliza <em>cookies</em> para la autenticación de usuarios. Las <em>cookies</em> están desactivadas en su navegador. Por favor, actívelas e inténtelo de nuevo.",
+       "nocookiesfornew": "No se pudo crear la cuenta de usuario, porque no pudimos confirmar su origen.\nAsegúrese de que tiene las <em>cookies</em> activadas, luego recargue esta página e inténtelo de nuevo.",
+       "createacct-loginerror": "La cuenta se ha creado correctamente, pero no se pudo ingresar automáticamente. Proceda al [[Special:UserLogin|acceso manual]].",
+       "loginsuccess": "<strong>Ha accedido a {{SITENAME}} como «$1».</strong>",
+       "nosuchuser": "No existe ninguna cuenta llamada «$1».\nLos nombres de usuario distinguen mayúsculas y minúsculas.\nCompruebe su escritura o [[Special:CreateAccount|cree una cuenta nueva]].",
+       "nosuchusershort": "No existe ningún usuario llamado «$1».\nCompruebe que lo ha escrito correctamente.",
+       "nouserspecified": "Debe especificar un nombre de usuario.",
+       "login-userblocked": "No puede iniciar sesión porque su cuenta está bloqueada.",
+       "wrongpassword": "El nombre de usuario o la contraseña que ha proporcionado son incorrectos.\nPor favor inténtelo de nuevo.",
+       "wrongpasswordempty": "No ha introducido una contraseña.\nPor favor inténtelo de nuevo.",
+       "password-name-match": "Su contraseña debe ser diferente de su nombre de usuario.",
+       "passwordsent": "Se ha enviado una nueva contraseña al correo electrónico de «$1».\nPor favor, identifíquese de nuevo tras recibirla.",
+       "anoneditwarning": "<strong>Advertencia:</strong> no ha iniciado sesión. Su dirección IP se hará pública si hace cualquier edición en estas condiciones. Si <strong>[$1 inicia sesión]</strong> o <strong>[$2 crea una cuenta]</strong>, sus ediciones se atribuirán a su nombre de usuario, además de otros beneficios.",
        "newarticletext": "Ha seguido usted un enlace a una página que aún no existe.\nPara crear esta página, escriba en el campo a continuación. Para más información, consulte la [$1 página de ayuda].\nSi ha llegado aquí por error, vuelva a la página anterior.",
-       "noarticletext": "En este momento no hay texto en esta página.\nPuede [[Special:Search/{{PAGENAME}}|buscar el título de esta página]] en otras páginas,\n<span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} buscar en los registros],\no [{{fullurl:{{FULLPAGENAME}}|action=edit}} editar esta página]</span>.",
+       "noarticletext": "En este momento no hay texto en esta página.\nPuede [[Special:Search/{{PAGENAME}}|buscar el título de esta página]] en otras páginas,\n<span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} buscar en los registros relacionados],\no [{{fullurl:{{FULLPAGENAME}}|action=edit}} crear esta página]</span>.",
        "copyrightwarning": "Por favor observe que todas las contribuciones realizadas en {{SITENAME}} serán consideradas como liberadas bajo $2 (véase $1 para más detalles).\nSi no desea que sus escritos sean editados o redistribuídos a voluntad, entonces no contribuya aquí.<br />\nAl mismo tiempo está usted prometiendo que lo que usted va a enviar lo ha escrito usted, o copiado de una fuente de dominio público.\n'''¡No envíe textos con derechos de autor sin el debido permiso!'''",
        "permissionserrorstext-withaction": "No tiene permiso para $2 por {{PLURAL:$1|la|las}} {{PLURAL:$1|siguiente|siguientes}} {{PLURAL:$1|razón|razones}}:",
        "rev-deleted-text-permission": "Esta revisión de la página ha sido '''borrada'''.\nPuede encontrar detalles en el [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} registro de borrados].",
-       "rev-deleted-text-unhide": "Esta revisión de página ha sido '''borrada'''.\nPuede haber detalles en el [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} registro de borrados].\nComo administrador todavía puede [$1 ver esta revisión] si así lo desea.",
-       "rev-suppressed-text-unhide": "Esta revisión de la página ha sido '''suprimida'''.\nPuede haber detalles en el [{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGENAMEE}}}} registro de supresiones].\nComo administrador podrá seguir [$1 viendo esta revisión] si desea continuar.",
-       "rev-deleted-text-view": "Esta revisión de la página ha sido '''borrada'''.\nComo administrador puede verla; puede haber detalles en el [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} registro de borrados].",
-       "rev-suppressed-text-view": "Esta revisión de la página ha sido '''suprimida'''.\nComo administrador puede verla; puede haber detalles en el [{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGENAMEE}}}} registro de supresiones].",
+       "rev-deleted-text-unhide": "Esta revisión ha sido <strong>eliminada</strong>.\nPara más información, consulte el [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} registro de borrados].\nComo administrador, aún puede [$1 ver esta revisión] si lo desea.",
+       "rev-suppressed-text-unhide": "Esta revisión ha sido <strong>suprimida</strong>.\nPara más información, consulte el [{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGENAMEE}}}} registro de supresiones].\nComo supresor, aún puede [$1 ver esta revisión] si lo desea.",
+       "rev-deleted-text-view": "Esta revisión ha sido <strong>eliminada</strong>.\nAún tiene la posibilidad de verla. Para más información, consulte el [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} registro de borrados].",
+       "rev-suppressed-text-view": "Esta revisión ha sido <strong>suprimida</strong>.\nAún tiene la posibilidad de verla. Para más información, consulte el [{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGENAMEE}}}} registro de supresiones].",
        "rev-deleted-no-diff": "No puede visualizarse este cambio debido a que las revisiones han sido '''borradas'''.\nPuede haber detalles en el [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} registro de borrados].",
-       "revdelete-nooldid-text": "No se ha especificado una revisión o revisiones destino sobre las que realizar esta función.",
+       "revdelete-nooldid-text": "O bien no se ha especificado una revisión destino sobre la que realizar esta función, o bien la revisión especificada no existe, o bien está intentando ocultar la revisión actual.",
        "revdelete-show-file-confirm": "¿Está seguro de que desea ver la revisión borrada del archivo \"<nowiki>$1</nowiki>\" del $2 a las $3?",
        "revdelete-confirm": "Confirme que quiere realizar la operación, que entiende las consecuencias y que está ejecutando dicha acción acorde con [[{{MediaWiki:Policy-url}}|las políticas]].",
        "lineno": "Línea $1:",
        "rightslog": "Registro de cambios de permisos de usuarios",
        "recentchanges": "Cambios recientes",
        "recentchangeslinked-toolbox": "Cambios relacionados",
-       "recentchangeslinked-summary": "Esta es una lista de cambios efectuados recientemente a páginas enlazadas desde una página dada (o de miembros de una categoría dada).\nLas páginas que se encuentran en tu [[Special:Watchlist|lista de seguimiento]] están en <strong>negritas</strong>.",
+       "recentchangeslinked-summary": "Escriba el nombre de una página para ver cambios realizados en páginas con enlaces entrantes o salientes a esa página. (Para ver lo que pertenece a una categoría, escriba «Categoría:Nombre de la categoría»). Los cambios en páginas de su [[Special:Watchlist|lista de seguimiento]] aparecen en <strong>negrita</strong>.",
        "upload": "Subir archivo",
        "filehist-help": "Haga clic sobre una fecha/hora para ver el archivo a esa fecha.",
        "randompage": "Página aleatoria",
        "nbytes": "$1 {{PLURAL:$1|byte|bytes}}",
        "emailuser": "Enviar un correo electrónico a este usuario",
-       "addedwatchtext": "La página «[[:$1]]» ha sido añadida a su [[Special:Watchlist|lista de seguimiento]]. Los cambios futuros en esta página y en su página de discusión asociada se indicarán ahí, y la página aparecerá '''en negritas''' en la [[Special:RecentChanges|lista de cambios recientes]] para hacerla más fácil de detectar.\n\nCuando quiera eliminar la página de su lista de seguimiento, presione «Dejar de vigilar» en el menú.",
+       "addedwatchtext": "Se han añadido «[[:$1]]» y su página de discusión a su [[Special:Watchlist|lista de seguimiento]].",
        "removedwatchtext": "Se han eliminado «[[:$1]]» y su página de discusión de tu [[Special:Watchlist|lista de seguimiento]].",
        "confirmdeletetext": "Está a punto de borrar una página junto con su historial.\nPor favor confirme que desea realizar esto, que entiende las consecuencias y que está realizando esta acción de acuerdo con las [[{{MediaWiki:Policy-url}}|políticas]]",
        "deletedtext": "\"$1\" ha sido borrado.\nVea $2 para un registro de los borrados recientes.",
        "rollbacklink": "revertir",
        "protect-text": "Puede ver y modificar el nivel de protección de la página '''$1'''.",
        "protect-locked-access": "Su cuenta no tiene permiso para cambiar los niveles de protección de una página.\nA continuación se muestran las opciones actuales de la página '''$1''':",
-       "protect-cascadeon": "Actualmente esta página está protegida porque está incluida en {{PLURAL:$1|la siguiente página|las siguientes páginas}}, que tienen activada la opción de protección en cascada. Puede cambiar el nivel de protección de esta página, pero no afectará a la protección en cascada.",
+       "protect-cascadeon": "Actualmente esta página está protegida porque está transcluida en {{PLURAL:$1|la siguiente página, que tiene|las siguientes páginas, que tienen}} activada la opción de protección de cascada.\nPuede cambiar el nivel de protección de esta página, pero no afectará a la protección de cascada.",
        "protect-cantedit": "No puede cambiar el nivel de protección porque no tiene permiso para editarla.",
        "blanknamespace": "(Principal)",
        "whatlinkshere": "Lo que enlaza aquí",
        "confirmemail_body": "Alguien, probablemente usted mismo, ha registrado desde la dirección IP $1 la cuenta \"$2\" en {{SITENAME}}, utilizando esta dirección de correo.\n\nPara confirmar que esta cuenta realmente le pertenece y activar el correo en {{SITENAME}}, siga este enlace:\n\n$3\n\nSi la cuenta *no* es suya, siga este otro enlace para cancelar la confirmación de la dirección de correo:\n\n$5\n\nEl código de confirmación expirará en $4.",
        "confirmemail_body_changed": "Alguien, probablemente usted,\nha modificado la dirección de correo electrónico asociado a la cuenta \"$2\" hacia esta en {{SITENAME}}, desde la dirección IP $1.\n\nPara confirmar que esta cuenta realmente le pertenece y reactivar las funciones de correo electrónico en {{SITENAME}}, abra este enlace en su navegador:\n\n$3\n\nSi la cuenta *no* le pertenece, sigua el siguiente enlace para cancelar la confirmación:\n\n$5\n\nEste código de confirmación expirará el $4.",
        "deletedwhileediting": "'''Aviso''': ¡Esta página fue borrada después de que usted empezara a editar!",
-       "confirmrecreate": "El usuario [[User:$1|$1]] ([[User talk:$1|discusión]]) borró este artículo después de que usted empezara a editarlo y dio esta razón:\n: ''$2'' \nPor favor, confirme que realmente desea crear de nuevo esta página.",
+       "confirmrecreate": "{{GENDER:$1|El usuario|La usuaria}} [[User:$1|$1]] ([[User talk:$1|discusión]]) borró esta página después de que usted comenzara a editarla, por este motivo:\n: <em>$2</em>\nPor favor confirme que realmente quiere volver a crearla.",
        "watchlistedit-normal-explain": "Los títulos de su lista de seguimiento se muestran debajo.\nPara eliminar un título, marque la casilla junto a él, y haga clic en ''{{int:Watchlistedit-normal-submit}}''.\nTambién puede [[Special:EditWatchlist/raw|editar la lista de en crudo]].",
        "watchlistedit-raw-explain": "Los títulos de su lista de seguimiento se muestran debajo. Esta lista puede ser editada añadiendo o eliminando líneas de la lista;\nun título por línea.\nCuando acabe, haga clic en \"{{int:Watchlistedit-raw-submit}}\".\nTambién puede [[Special:EditWatchlist|usar el editor estándar]].",
        "watchlistedit-raw-done": "Su lista de seguimiento ha sido actualizada.",
index 94f3a21..7cbd953 100644 (file)
        "newpageletter": "N",
        "boteditletter": "b",
        "number_of_watching_users_pageview": "[$1 {{PLURAL:$1|usuario|usuarios}} vigilando]",
-       "rc_categories": "Limitar a categorías (sep.: |):",
-       "rc_categories_any": "Cualquiera de las elegidas",
        "rc-change-size-new": "$1 {{PLURAL:$1|byte|bytes}} después del cambio",
        "newsectionsummary": "Sección nueva: /* $1 */",
        "rc-enhanced-expand": "Mostrar detalles",
index 3030d0a..152bfc4 100644 (file)
        "newpageletter": "U",
        "boteditletter": "R",
        "number_of_watching_users_pageview": "[$1 {{PLURAL:$1|jälgiv kasutaja|jälgivat kasutajat}}]",
-       "rc_categories": "Ainult neist kategooriatest (eraldajaks \"|\"):",
-       "rc_categories_any": "Mõnes valitutest",
        "rc-change-size-new": "$1 {{PLURAL:$1|bait|baiti}} pärast muudatust",
        "newsectionsummary": "/* $1 */ uus alaosa",
        "rc-enhanced-expand": "Näita üksikasju",
index 8bb471c..3100c46 100644 (file)
        "newpageletter": "B",
        "boteditletter": "b",
        "number_of_watching_users_pageview": "[$1 {{PLURAL:$1|lankide|lankide}} jarraitzen]",
-       "rc_categories": "Kategorietara mugatu (\"|\" karaktereaz banandu):",
-       "rc_categories_any": "Aukeratutako edozein",
        "rc-change-size-new": "{{PLURAL:$1|Byte 1|$1 byte}} aldaketaren ostean",
        "newsectionsummary": "/* $1 */ atal berria",
        "rc-enhanced-expand": "Erakutsi xehetasunak",
index 41cf60f..0b1ecfa 100644 (file)
        "newpageletter": "N",
        "boteditletter": "b",
        "number_of_watching_users_pageview": "[$1 {{PLURAL:$1|usuáriu está|usuárius están}} vehilandu]",
-       "rc_categories": "Arrayal a categorias (separás pol \"|\")",
-       "rc_categories_any": "Cualisquiá",
        "rc-change-size-new": "$1 {{PLURAL:$1|byte|bytes}} dempués el chambu",
        "newsectionsummary": "/* $1 */ seción nueva",
        "rc-enhanced-expand": "muestral detallis (es mestel JavaScript)",
index 9a69939..9c1f343 100644 (file)
        "newpageletter": "نو",
        "boteditletter": "ر",
        "number_of_watching_users_pageview": "[$1 {{PLURAL:$1|کاربر}} پی‌گیرنده]",
-       "rc_categories": "محدود به این رده‌ها (رده‌ها را با «|» جدا کنید):",
-       "rc_categories_any": "هر کدام از منتخب‌ها",
        "rc-change-size-new": "$1 {{PLURAL:$1|بایت}} پس از تغییر",
        "newsectionsummary": "/* $1 */ بخش جدید",
        "rc-enhanced-expand": "نمایش جزئیات",
index d8aae31..e23d311 100644 (file)
        "newpageletter": "U",
        "boteditletter": "b",
        "number_of_watching_users_pageview": "[$1 {{PLURAL:$1|tarkkaileva käyttäjä|tarkkailevaa käyttäjää}}]",
-       "rc_categories": "Rajoita luokkiin (erota luokat merkillä ”|”)",
-       "rc_categories_any": "Mikä tahansa valituista",
        "rc-change-size-new": "$1 {{PLURAL:$1|tavu|tavua}} muutosten jälkeen",
        "newsectionsummary": "/* $1 */ uusi osio",
        "rc-enhanced-expand": "Näytä yksityiskohdat",
        "delete_and_move_text": "Kohdesivu [[:$1]] on jo olemassa. \nHaluatko poistaa sen, jotta nykyinen sivu voitaisiin siirtää sen tilalle?",
        "delete_and_move_confirm": "Kyllä, poista kohdesivu",
        "delete_and_move_reason": "Sivu on sivun [[$1]] siirron tiellä.",
-       "selfmove": " Nimi on sama;\nSivua ei voi siirtää itsensä päälle.",
+       "selfmove": "Nimi on sama;\nSivua ei voi siirtää itsensä päälle.",
        "immobile-source-namespace": "Sivuja ei voi siirtää nimiavaruudessa ”$1”",
        "immobile-target-namespace": "Sivuja ei voi siirtää nimiavaruuteen ”$1”",
        "immobile-target-namespace-iw": "Kielilinkki ei ole kelvollinen kohde sivun siirrolle.",
        "fix-double-redirects": "Päivitä kaikki vanhalle nimelle viittaavat ohjaukset ohjaamaan uudelle nimelle",
        "move-leave-redirect": "Jätä paikalle ohjaus",
        "protectedpagemovewarning": "'''Varoitus:''' Tämä sivu on lukittu siten, että vain ylläpitäjät voivat siirtää sen.\nAlla on viimeisin lokitapahtuma:",
-       "semiprotectedpagemovewarning": "Tämä sivu on lukittu siten, että vain rekisteröityneet käyttäjät voivat siirtää sitä.\nAlla on viimeisin lokitapahtuma:",
+       "semiprotectedpagemovewarning": "<strong>Huomaa:</strong> Tämä sivu on lukittu siten, että vain rekisteröityneet käyttäjät voivat siirtää sen.\nAlla on viimeisin lokitapahtuma:",
        "move-over-sharedrepo": "[[:$1]] on olemassa yhteisessä tietovarastossa. Tiedoston siirtäminen tälle nimelle korvaa yhteisen tiedoston.",
        "file-exists-sharedrepo": "Valittu tiedostonimi on jo käytössä jaetussa varastossa.\nValitse toinen nimi.",
        "export": "Vie sivuja",
index 535d81f..d1142f8 100644 (file)
        "newpageletter": "N",
        "boteditletter": "b",
        "number_of_watching_users_pageview": "[$1 ansar eftir {{PLURAL:$1|brúkara|brúkarum}}]",
-       "rc_categories": "Avmarkað til síður frá bólkunum (skil sundur við \"|\")",
-       "rc_categories_any": "Nakar",
        "rc-change-size-new": "$1 {{PLURAL:$1|byte|bytes}} eftir broyting",
        "newsectionsummary": "/* $1 */ nýtt innlegg",
        "rc-enhanced-expand": "Vís smálutir",
index 4ca7a18..7a34010 100644 (file)
        "protectedpagetext": "Cette page a été protégée pour empêcher sa modification ou d’autres actions.",
        "viewsourcetext": "Vous pouvez voir et copier le contenu de cette page.",
        "viewyourtext": "Vous pouvez voir et copier le contenu de <strong>vos modifications</strong> à cette page.",
-       "protectedinterface": "Cette page fournit du texte d’interface pour le logiciel sur ce wiki et est protégée pour éviter les abus.\nPour ajouter ou modifier des traductions sur tous les wikis, veuillez utiliser [https://translatewiki.net/ translatewiki.net], le projet de localisation de MediaWiki.",
+       "protectedinterface": "Cette page fournit du texte d’interface pour le logiciel sur ce wiki et est protégée pour éviter les abus.\nPour ajouter ou modifier des traductions sur tous les wikis, veuillez utiliser [https://translatewiki.net/ translatewiki.net], le projet de régionalisation de MediaWiki.",
        "editinginterface": "<strong>Attention :</strong> vous êtes en train de modifier une page utilisée pour créer le texte de l’interface du logiciel.\nLes changements sur cette page se répercuteront sur l’apparence de l’interface utilisateur pour les autres utilisateurs de ce wiki.",
        "translateinterface": "Pour ajouter ou modifier des traductions pour tous les wikis, veuillez utiliser [https://translatewiki.net/ translatewiki.net], le projet de localisation linguistique de MediaWiki.",
        "cascadeprotected": "Cette page est protégée contre les modifications car elle est transcluse par {{PLURAL:$1|la page suivante, qui a été protégée|les pages suivantes, qui ont été protégées}} avec l’option « protection en cascade » activée :\n$2",
        "boteditletter": "b",
        "unpatrolledletter": "!",
        "number_of_watching_users_pageview": "[$1 utilisateur{{PLURAL:$1||s}} en train de suivre]",
-       "rc_categories": "Limiter aux catégories (séparées par « | ») :",
-       "rc_categories_any": "Une des sélectionnées",
        "rc-change-size": "$1",
        "rc-change-size-new": "$1 {{PLURAL:$1|octet|octets}} après changement",
        "newsectionsummary": "/* $1 */ nouvelle section",
index 048526e..bebff59 100644 (file)
        "newpageletter": "N",
        "boteditletter": "r",
        "number_of_watching_users_pageview": "[$1 {{PLURAL:$1|utilisator qu’est|utilisators que sont}} aprés siuvre]",
-       "rc_categories": "Limitar a les catègories (sèparâyes per « | ») :",
-       "rc_categories_any": "Yona de les chouèsies",
        "rc-change-size-new": "$1 octèt{{PLURAL:$1||s}} aprés changement",
        "newsectionsummary": "/* $1 */ novèla sèccion",
        "rc-enhanced-expand": "Montrar los dètalys",
index 3c5c93a..396ff16 100644 (file)
        "newpageletter": "N",
        "boteditletter": "B",
        "number_of_watching_users_pageview": "[$1 {{PLURAL:$1|brüker|brükern}}, diar tuluke]",
-       "rc_categories": "Bluas sidjen ütj jo kategoriin (apdiald mä „|“):",
-       "rc_categories_any": "Arke ütjsoocht",
        "rc-change-size-new": "$1 {{PLURAL:$1|byte|bytes}} efter't feranrin",
        "newsectionsummary": "Nei kirew /* $1 */",
        "rc-enhanced-expand": "Enkelthaiden wise",
index 3ed0d0d..c71f994 100644 (file)
        "newpageletter": "G",
        "boteditletter": "b",
        "number_of_watching_users_pageview": "[tignude di voli di {{PLURAL:$1|un utent|$1 utents}}]",
-       "rc_categories": "Limite aes categoriis (dividilis cun \"|\")",
-       "rc_categories_any": "Cualsisei",
        "rc-change-size-new": "$1 {{PLURAL:$1|byte|bytes}} dopo la modifiche",
        "newsectionsummary": "/* $1 */ gnove sezion",
        "rc-enhanced-expand": "Cjale i detais (al covente JavaScript)",
index 25d3964..3a25100 100644 (file)
        "boteditletter": "b",
        "unpatrolledletter": "!",
        "number_of_watching_users_pageview": "[$1 folgjende {{PLURAL:$1|meidogger|meidoggers}}]",
-       "rc_categories": "Alline kategoryen (skiede mei in \"|\")",
-       "rc_categories_any": "Elk",
        "rc-change-size": "$1",
        "rc-change-size-new": "$1 {{PLURAL:$1|byte|bytes}} nei de wiziging",
        "newsectionsummary": "/* $1 */ nije seksje",
index df5c885..40b2919 100644 (file)
        "newpageletter": "N",
        "boteditletter": "r",
        "number_of_watching_users_pageview": "[{{PLURAL:$1|úsáideoir amháin|$1 úsáideoirí}} ag faire]",
-       "rc_categories_any": "Aon chatagóir",
        "rc-change-size-new": "$1 {{PLURAL:$1|bheart|beart}} tar éis an athraithe",
        "newsectionsummary": "/* $1 */ mír nua",
        "rc-enhanced-expand": "Taispeáin mionsonraithe",
index c57b95f..0764f30 100644 (file)
@@ -16,7 +16,8 @@
                        "Duolaimi",
                        "Impersonator 1",
                        "Babanwalia",
-                       "Macofe"
+                       "Macofe",
+                       "Fanjiayi"
                ]
        },
        "tog-underline": "下划链接",
        "nstab-template": "模版",
        "nstab-help": "帮助页",
        "nstab-category": "分类",
+       "mainpage-nstab": "封面",
        "nosuchaction": "冇有个只命令",
        "nosuchactiontext": "Wiki识别伓到个只URL命令",
        "nosuchspecialpage": "冇有个只特殊页",
        "createaccount-title": "到{{SITENAME}}创建𠮶帐户",
        "createaccount-text": "有人到{{SITENAME}}用倷𠮶电子邮件地址开设喽只名字系 \"$2\" 𠮶新帐户($4),密码系 \"$3\" 。请倷仰上登录同到修改密码。\n\n要系帐户创建不对𠮶话,倷就莫搭个只消息。",
        "loginlanguagelabel": "语言: $1",
+       "pt-login": "登入",
+       "pt-createaccount": "新开只帐户",
        "changepassword": "改过密码",
        "resetpass_announce": "倷系用到临时email𠮶代码登入𠮶。要登正入,倷要到个首设定只新密码:",
        "resetpass_header": "设过密码",
        "rclistfrom": "显示自$3 $2后𠮶新改动",
        "rcshowhideminor": "$1细编辑",
        "rcshowhidebots": "$1机器人𠮶编辑",
-       "rcshowhideliu": "$1登入用户𠮶编辑",
+       "rcshowhideliu": "$1注册用户",
        "rcshowhideanons": "$1匿名用户𠮶编辑",
        "rcshowhidepatr": "$1检查过𠮶编辑",
        "rcshowhidemine": "$1偶𠮶编辑",
-       "rclinks": "显示最晏$2日之内最新𠮶$1改动。",
+       "rclinks": "显示最晏$2日之内最新𠮶$1改动。",
        "diff": "差异",
        "hist": "历史",
        "hide": "弆到",
        "newpageletter": "新",
        "boteditletter": "机",
        "number_of_watching_users_pageview": "[$1只监视用户]",
-       "rc_categories": "分类界定(用\"|\"隔开)",
-       "rc_categories_any": "任何",
        "newsectionsummary": "/* $1 */ 新段落",
        "rc-enhanced-expand": "显到细节(需要 JavaScript)",
        "rc-enhanced-hide": "弆到细节",
        "namespace": "空间名:",
        "invert": "反选",
        "blanknamespace": "(主要)",
-       "contributions": "用户贡献",
+       "contributions": "{{GENDER:$1|用户}}贡献",
        "contributions-title": "$1𠮶用户贡献",
        "mycontris": "偶𠮶贡献",
        "contribsub2": "$1𠮶贡献 ($2)",
        "tooltip-t-recentchangeslinked": "从个页连出𠮶全部页面𠮶改动",
        "tooltip-feed-rss": "个页𠮶RSS订阅",
        "tooltip-feed-atom": "个页𠮶Atom订阅",
-       "tooltip-t-contributions": "望吖个只用户𠮶贡献",
+       "tooltip-t-contributions": "由{{GENDER:$1|此用户}}做出的贡献列表",
        "tooltip-t-emailuser": "发封邮件到个只用户",
        "tooltip-t-upload": "上传图像或多媒体文件",
        "tooltip-t-specialpages": "全部特殊页列表",
        "file-info-size": "$1 × $2 像素,档案大细:$3 ,MIME类型:$4",
        "file-nohires": "冇更高分辨率𠮶图像。",
        "svg-long-desc": "SVG档案,表面大细: $1 × $2 像素,档案大细:$3",
-       "show-big-image": "å®\8cæ\95´å\88\86辨ç\8e\87",
+       "show-big-image": "å\8e\9få§\8bæ\96\87件",
        "newimages": "新建图像画廊",
        "imagelisttext": "底下系按$2排列𠮶$1只档案列表。",
        "noimages": "冇什哩可望。",
        "external_image_whitelist": "#留住个行字<pre>\n#到下首(//𠮶中间)输入正规表达式\n#佢俚会同得外部(已超连结𠮶)图片配合\n#许滴配合到出来𠮶会显示做图片,否则就光会显示做连结\n#有 # 开头𠮶行会当做注解\n#大小写冇有差别\n\n#到个行上首输入所有𠮶regex。留住个行字</pre>",
        "tag-filter": "[[Special:Tags|标签]]过滤器:",
        "rightsnone": "(冇)",
-       "searchsuggest-search": "寻吖"
+       "searchsuggest-search": "寻吖{{SITENAME}}"
 }
index 03c6063..a683acb 100644 (file)
        "newpageletter": "新",
        "boteditletter": "機",
        "number_of_watching_users_pageview": "[$1隻監視用戶]",
-       "rc_categories": "分類界定(用\"|\"隔開)",
-       "rc_categories_any": "任何",
        "newsectionsummary": "/* $1 */ 新段落",
        "rc-enhanced-expand": "顯到細節(需要 JavaScript)",
        "rc-enhanced-hide": "弆到細節",
index 600f0e9..b30a5bd 100644 (file)
        "boteditletter": "bt",
        "unpatrolledletter": "!",
        "number_of_watching_users_pageview": "[Tha $1 {{PLURAL:$1|chleachdaiche|chleachdaiche|cleachdaichean|cleachdaiche}} a' cumail sùil air]",
-       "rc_categories": "Dìreach sna roinnean-seòrsa (sgaraich le “|”):",
-       "rc_categories_any": "Gin dhe na chaidh a thaghadh",
        "rc-change-size": "$1",
        "rc-change-size-new": "$1 {{PLURAL:$1|bhaidht|bhaidht|baidhtichean|baidht}} às dèidh an atharrachaidh",
        "newsectionsummary": "Earrann ùr /* $1 */",
index 5be7056..fb44ca6 100644 (file)
        "boteditletter": "b",
        "unpatrolledletter": "!",
        "number_of_watching_users_pageview": "[$1 {{PLURAL:$1|usuario|usuarios}} vixiando]",
-       "rc_categories": "Limitar ás categorías (separadas por \"|\"):",
-       "rc_categories_any": "Calquera das elixidas",
        "rc-change-size": "$1",
        "rc-change-size-new": "$1 {{PLURAL:$1|byte|bytes}} despois da modificación",
        "newsectionsummary": "Nova sección: /* $1 */",
index e8b07f6..beecd23 100644 (file)
        "minoreditletter": "द",
        "newpageletter": "न",
        "boteditletter": "र",
-       "rc_categories_any": "वेंचिल्ल्या मदलें खंयचेय",
        "rc-change-size-new": "$1 {{बहुवचन:$1|byte|bytes}}बदल केल्या उपरांत",
        "rc-enhanced-expand": "म्हायती दाखय",
        "rc-enhanced-hide": "म्हायती लिपय",
index 493e033..976847b 100644 (file)
        "minoreditletter": "d",
        "newpageletter": "N",
        "boteditletter": "r",
-       "rc_categories_any": "Vinchlele modlem khuimchem-i",
        "rc-change-size-new": "$1 {{PLURAL:$1|byte|byti}} bodol kel'lea uprant",
        "rc-enhanced-expand": "Bariksann dakhoi",
        "rc-enhanced-hide": "Bariksann lipoi",
index 492adc8..c9d4291 100644 (file)
        "newpageletter": "Ν",
        "boteditletter": "αὐτ",
        "number_of_watching_users_pageview": "[$1 ἐφορᾶν {{PLURAL:$1|χρώμενον|χρωμένους}}]",
-       "rc_categories": "Ὅριον κατηγοριῶν (σήμανσις διαχωρίσεως: \"|\")",
-       "rc_categories_any": "Οἵα δήποτε",
        "rc-change-size-new": "$1 {{PLURAL:$1|δυφιολέξις|δυφιολέξεις}} μεθύστερον μεταβολής",
        "newsectionsummary": "/* $1 */ νέον τμῆμα",
        "rc-enhanced-expand": "Δεικνύναι λεπτομέρειας (ἀπαιτεῖ JavaScript)",
index 6814844..f16e09e 100644 (file)
        "newpageletter": "N",
        "boteditletter": "B",
        "number_of_watching_users_pageview": "[$1 {{PLURAL:$1|Benutzer, wu beobachtet|Benutzer, wu beobachte}}]",
-       "rc_categories": "Nume Syten us bestimmte Kategorie (mit «|» trenne):",
-       "rc_categories_any": "Beliebigi vo den usgwählte",
        "rc-change-size-new": "$1 {{PLURAL:$1|Byte|Byte}} no dr Änderig",
        "newsectionsummary": "Neje Abschnitt /* $1 */",
        "rc-enhanced-expand": "Detail aazeige",
index c0424f6..a75b84c 100644 (file)
        "newpageletter": "નવું",
        "boteditletter": "બૉટ",
        "number_of_watching_users_pageview": "[$1 જોઇરહેલ  {{PLURAL:$1|સભ્ય|સભ્યો}}]",
-       "rc_categories": "શ્રેણીઓ સુધી મર્યાદિત (\"|\" થી જુદા પાડો):",
-       "rc_categories_any": "કોઇ પણ પસંદ કરેલ",
        "rc-change-size-new": "બદલાયા પછી $1 {{PLURAL:$1|બાઈટ|બાઇટ્સ}}",
        "newsectionsummary": "/* $1 */ નવો વિભાગ",
        "rc-enhanced-expand": "વિગતો બતાવો",
index 0c4d19e..c80216e 100644 (file)
        "minoreditletter": "m",
        "newpageletter": "N",
        "boteditletter": "r",
-       "rc_categories_any": "Ronney erbee",
        "rc-enhanced-expand": "Taishbyn sonreeaghtyn (ta feme er JavaScript)",
        "rc-enhanced-hide": "Follee sonreeaghtyn",
        "recentchangeslinked": "Caghlaaghyn conastagh",
index 126d1e2..c4819f7 100644 (file)
        "newpageletter": "Sîn",
        "boteditletter": "kî",
        "number_of_watching_users_pageview": "[$1隻用戶關注]",
-       "rc_categories": "分類界限(以“|”分割)",
-       "rc_categories_any": "任意",
        "rc-change-size-new": "Kiên-kói heu ke $1 vi-ngièn-chû",
        "rc-enhanced-expand": "展示細節 (愛有JavaScript)",
        "rc-enhanced-hide": "隱藏細節",
index 1e5187b..15197b7 100644 (file)
        "newpageletter": "ח",
        "boteditletter": "ב",
        "number_of_watching_users_pageview": "[{{PLURAL:$1|משתמש אחד עוקב|$1 משתמשים עוקבים}} אחרי הדף]",
-       "rc_categories": "הגבלה לקטגוריות (מופרדות בתו \"|\"):",
-       "rc_categories_any": "כל אחת מהנבחרות",
        "rc-change-size-new": "{{PLURAL:$1|בית אחד|$1 בתים}} לאחר השינוי",
        "newsectionsummary": "/* $1 */ פסקה חדשה",
        "rc-enhanced-expand": "הצגת הפרטים",
index fd01409..7e0397d 100644 (file)
        "newpageletter": "न",
        "boteditletter": "बॉ",
        "number_of_watching_users_pageview": "[$1 ध्यान रखने वाले {{PLURAL:$1|सदस्य}}]",
-       "rc_categories": "श्रेणीयों तक सीमीत रखें (\"|\" से अलग करें)",
-       "rc_categories_any": "कोई भी चुनिन्दा",
        "rc-change-size-new": "बदलाव के बाद $1 {{PLURAL:$1|बाइट}}",
        "newsectionsummary": "/* $1 */ नया अनुभाग",
        "rc-enhanced-expand": "विस्तृत जानकारी दिखाएँ",
index 0c8b570..c60a534 100644 (file)
        "newpageletter": "N",
        "boteditletter": "b",
        "number_of_watching_users_pageview": "[$1 {{PLURAL:$1|user|users}} ke dekhta hae]",
-       "rc_categories": "Categories me limit (\"|\" se separate karo)",
-       "rc_categories_any": "Chuna gais me se koi",
        "rc-change-size-new": "$1 {{PLURAL:$1|byte|bytes}} badlao ke baad",
        "newsectionsummary": "/* $1 */ nawaa vibhag",
        "rc-enhanced-expand": "Details dekhao",
index 4a94fc3..4829231 100644 (file)
        "newpageletter": "B",
        "boteditletter": "b",
        "number_of_watching_users_pageview": "[$1 ginabantayan {{PLURAL:$1|naga-usar|mga naga-usar}}]",
-       "rc_categories": "Limitahan ang mga kategorya (ibulag lakip sang \"|\")",
-       "rc_categories_any": "Bisan ano",
        "rc-change-size-new": "$1 {{PLURAL:$1|byte|mga byte}} pagkatapos sang pag-ilis",
        "newsectionsummary": "/* $1 */ bag-o nga seksyon",
        "rc-enhanced-expand": "Ipakita ang mga detalye",
index 5fd0fe9..63b9bce 100644 (file)
        "newpageletter": "N",
        "boteditletter": "b",
        "number_of_watching_users_pageview": "[$1 {{PLURAL:$1|suradnik|suradnika|suradnika}} prati ovu stranicu]",
-       "rc_categories": "Ograniči na kategorije (odvoji sa \"|\")",
-       "rc_categories_any": "Bilo koji od odabranih",
        "rc-change-size-new": "$1 {{PLURAL:$1|bajt|bajta|bajtova}} poslije uređivanja",
        "newsectionsummary": "/* $1 */ novi odlomak",
        "rc-enhanced-expand": "Pokaži detalje (potreban JavaScript)",
index c20b3ad..09ee5b6 100644 (file)
        "newpageletter": "N",
        "boteditletter": "B",
        "number_of_watching_users_pageview": "[$1 {{PLURAL:$1|beobachtender|beobachtende}} Benutzer]",
-       "rc_categories": "Nur Seite aus den Kategorie (getrennt mit „|“):",
-       "rc_categories_any": "Alle",
        "rc-change-size-new": "$1 {{PLURAL:$1|Byte|Bytes}} noh der Ännrung",
        "newsectionsummary": "Neier Abschnitt /* $1 */",
        "rc-enhanced-expand": "Einzelheite oonzeiche",
index e203fed..1a19adb 100644 (file)
        "newpageletter": "N",
        "boteditletter": "B",
        "number_of_watching_users_pageview": "[$1 {{PLURAL:$1|wobkedźbowacy wužiwar|wobkedźbowacaj wužiwarjej|wobkedźbowacy wužiwarjo|wobkedźbowacych wužiwarjow}}]",
-       "rc_categories": "Jenož kategorije (dźělene z \"|\")",
-       "rc_categories_any": "Někajka z wubranych",
        "rc-change-size": "$1 {{PLURAL:$1|bajt|bajtaj|bajty|bajtow}}",
        "rc-change-size-new": "$1 {{PLURAL:$1|bajt|bajtaj|bajty|bajtow}} po změnje",
        "newsectionsummary": "Nowy wotrězk: /* $1 */",
index 47938c1..ffe80ec 100644 (file)
        "newpageletter": "Ú",
        "boteditletter": "b",
        "number_of_watching_users_pageview": "[Jelenleg {{PLURAL:$1|egy|$1}} felhasználó figyeli]",
-       "rc_categories": "Szűkítés kategóriákra („|” jellel válaszd el őket):",
-       "rc_categories_any": "Választottak közül bármelyik",
        "rc-change-size-new": "$1 bájt módosítás után",
        "newsectionsummary": "/* $1 */ (új szakasz)",
        "rc-enhanced-expand": "Részletek megjelenítése",
        "watchlistedit-clear-titles": "Címek:",
        "watchlistedit-clear-submit": "Figyelőlista kiürítése (Ez végleges!)",
        "watchlistedit-clear-done": "A figyelőlistád törölve.",
+       "watchlistedit-clear-jobqueue": "A figyelőlistád kiürítése folyamatban van. Ez eltarthat egy ideig.",
        "watchlistedit-clear-removed": "{{PLURAL:$1|$1 oldal}} törölve:",
        "watchlistedit-too-many": "Túl sok lap a megjelenítéshez.",
        "watchlisttools-clear": "A figyelőlista kiürítése",
index 3f6c0cb..6bcd7f7 100644 (file)
        "newpageletter": "Ն",
        "boteditletter": "բ",
        "number_of_watching_users_pageview": "[$1 հսկող {{PLURAL:$1|մասնակից|մասնակիցներին}}]",
-       "rc_categories": "Սահմանափակել կատեգորիաներով (բաժանեք «|» նշանով)",
-       "rc_categories_any": "Բոլոր",
        "rc-change-size-new": "$1 {{PLURAL:$1|բայթ|բայթ}} փոփոխությունից հետո",
        "newsectionsummary": "/* $1 */ Նոր բաժին",
        "rc-enhanced-expand": "Ցուցադրել մանրամասներ (պահանջում է ՋավաՍկրիպտ)",
index bcf8601..7703ba2 100644 (file)
        "nov": "nov",
        "dec": "dec",
        "january-date": "$1 de januario",
-       "february-date": "$1 de februario���",
+       "february-date": "$1 de februario",
        "march-date": "$1 de martio",
        "april-date": "$1 de april",
        "may-date": "$1 de maio",
        "newpageletter": "N",
        "boteditletter": "b",
        "number_of_watching_users_pageview": "[observate per $1 {{PLURAL:$1|usator|usatores}}]",
-       "rc_categories": "Limitar al categorias (separar con \"|\"):",
-       "rc_categories_any": "Qualcunque categoria seligite",
        "rc-change-size-new": "$1 {{PLURAL:$1|byte|bytes}} post cambio",
        "newsectionsummary": "/* $1 */ nove section",
        "rc-enhanced-expand": "Revelar detalios",
index 1d3b47c..62e0e97 100644 (file)
        "boteditletter": "b",
        "unpatrolledletter": "!",
        "number_of_watching_users_pageview": "[$1 {{PLURAL:$1|pemantau|pemantau}}]",
-       "rc_categories": "Batasi sampai kategori (dipisah dengan \"|\"):",
-       "rc_categories_any": "Setiap yang terpilih",
        "rc-change-size": "$1",
        "rc-change-size-new": "$1 {{PLURAL:$1|bita}} setelah perubahan",
        "newsectionsummary": "/* $1 */ bagian baru",
index 6cb2c4f..4748929 100644 (file)
@@ -14,7 +14,8 @@
                        "아라",
                        "Srdjan m",
                        "Macofe",
-                       "Stavanger7"
+                       "Stavanger7",
+                       "Fanjiayi"
                ]
        },
        "tog-underline": "Ultracatenun:",
        "october-date": "$1 octobre",
        "november-date": "$1 novembre",
        "december-date": "$1 decembre",
+       "period-am": "AM",
+       "period-pm": "PM",
        "pagecategories": "{{PLURAL:$1|Categorie|Categories}}",
        "category_header": "Articules in categorie \"$1\"",
        "subcategories": "Subcategories",
        "newwindow": "(es apertet in un nov fenestre)",
        "cancel": "Anullar",
        "moredotdotdot": "Plu...",
-       "morenotlisted": "Ti liste ne es complet.",
+       "morenotlisted": "Forsan ti liste es íncomplet.",
        "mypage": "Págine",
        "mytalk": "Conversation",
        "anontalk": "Discussion",
        "badaccess-groups": "Ti action es limitat a usatores in {{PLURAL:$2|li gruppe|un del secuent gruppes:}} $1",
        "versionrequired": "Version $1 de MediaWiki exiget",
        "versionrequiredtext": "Version $1 de MediaWiki es exiget por usar ti págine.\nVider [[Special:Version|págine de version]].",
+       "ok": "OK",
        "retrievedfrom": "Cargat de «$1»",
        "youhavenewmessages": "Vu have $1 ($2).",
        "youhavenewmessagesfromusers": "Tu have $1 de {{PLURAL:$3|un altri usator|$3 usatores}} ($2).",
        "nstab-template": "Avise",
        "nstab-help": "Auxilie",
        "nstab-category": "Categorie",
+       "mainpage-nstab": "Principal págine",
        "nosuchaction": "Null tal action existe",
        "nosuchactiontext": "Li action indicat in li URL es ínvalid.\nForsan tu ha mistypat li URL o secuet un íncorrect ligament.\nForsan it indica un erra in li programma usat de {{SITENAME}}.",
        "nosuchspecialpage": "Null tal special págine",
        "createaccount-title": "Creation de conto por {{SITENAME}}",
        "loginlanguagelabel": "Lingue: $1",
        "suspicious-userlogout": "Tui petition por surtir esset desaprobat pro que probabilmen esset inviat per un navigator ruptet o servitor de autorisation che caching.",
+       "pt-login": "Aperter session",
        "pt-login-button": "Aperter session",
        "pt-createaccount": "Crear un conto",
+       "pt-userlogout": "Surtir",
        "changepassword": "Modificar passa-parol",
        "oldpassword": "Anteyan passa-parol:",
        "newpassword": "Nov passa-parol:",
        "template-protected": "(protectet)",
        "template-semiprotected": "(medie-gardat)",
        "hiddencategories": "Ti págine es un membre de {{PLURAL:$1|1 categorie ocultat|$1 categories ocultat}}:",
+       "permissionserrors": "Tu ne have sufficent jures",
        "permissionserrorstext-withaction": "Vu ne have permission por $2, por li sequent {{PLURAL:$1|motive|motives}}:",
        "recreate-moveddeleted-warn": "'''Advertiment: Vu es recreant un págine que esset anteriorimen deletet.'''\n\nVu deve considerar ca it es convenent por continuar redactant ti págine.\nLi deletion e diarium de movement por li págine es sub li condition ci por convenience:",
        "moveddeleted-notice": "Ti págine ha esset deletet.\nLi deletion e diarium de movement por li págine es sub li condition in infra por referentie.",
        "rclistfrom": "Monstrar li nov modificationes desde $3 $2",
        "rcshowhideminor": "$1 redactiones minori",
        "rcshowhideminor-show": "Monstrar",
+       "rcshowhideminor-hide": "Ocultar",
        "rcshowhidebots": "$1 machines",
+       "rcshowhidebots-show": "Monstrar",
        "rcshowhidebots-hide": "Ocultar",
        "rcshowhideliu": "$1 usatores registrat",
+       "rcshowhideliu-show": "Monstrar",
        "rcshowhideliu-hide": "Ocultar",
        "rcshowhideanons": "$1 usatores anonim",
        "rcshowhideanons-show": "Monstrar",
+       "rcshowhideanons-hide": "Ocultar",
        "rcshowhidepatr": "$1 redactiones vigilat",
        "rcshowhidepatr-hide": "Ocultar",
        "rcshowhidemine": "$1 mi redactiones",
        "rcshowhidemine-show": "Monstrar",
+       "rcshowhidemine-hide": "Ocultar",
        "rclinks": "Monstrar li $1 ultim modificationes fat durante li $2 ultim dies",
        "diff": "dif",
        "hist": "hist",
        "tooltip-pt-login": "Tu es incorrageat crear un conto, ma to ne es un deventie.",
        "tooltip-pt-logout": "Surtir",
        "tooltip-ca-talk": "Discussion pri li articul.",
-       "tooltip-ca-edit": "Redacter ti págine. Ples usar li buton de prevision antequam conservar.",
+       "tooltip-ca-edit": "Redacter ti-ci págine",
        "tooltip-ca-addsection": "Comensar un nov section",
        "tooltip-ca-viewsource": "Ti págine es protectet. Ma tu posse vider e copiar su fonte.",
        "tooltip-ca-history": "Passat versiones de ti págine",
        "tooltip-preferences-save": "Conservar preferenties",
        "tooltip-summary": "Ples intrar un curt resummation.",
        "simpleantispam-label": "Control anti-spam.\n<strong>Ne</strong> plena to ci!",
+       "pageinfo-article-id": "Págine ID",
        "pageinfo-toolboxlink": "Information pri li págine",
        "previousdiff": "← Redaction anteriori",
        "nextdiff": "Proxim redaction →",
        "version-software": "Software installat",
        "version-software-product": "Producte",
        "version-software-version": "Version",
+       "redirect-submit": "Ear",
+       "redirect-user": "Usator ID",
        "specialpages": "Special págines",
        "specialpages-group-maintenance": "Raportes de conservation",
        "specialpages-group-other": "Altri págines special",
        "tags-display-header": "Aspecte in listes de change",
        "tags-description-header": "Descrition complet de signification",
        "tags-hitcount-header": "Changes nómiat",
+       "tags-active-yes": "Yes",
        "tags-edit": "redacter",
        "tags-hitcount": "$1 {{PLURAL:$1|change|changes}}",
        "logentry-delete-delete": "$1 ha removet li págine $3",
index 59306c6..d739147 100644 (file)
        "newpageletter": "N",
        "boteditletter": "b",
        "number_of_watching_users_pageview": "[$1 {{PLURAL:$1|ọ'bànifé|ọ'bànifé}} ne lé anya]",
-       "rc_categories_any": "Nkówụlà",
        "newsectionsummary": "/* $1 */ nkeji ohúrù",
        "rc-enhanced-expand": "Zi ihe di ime (Í gí nwere JavaScript)",
        "rc-enhanced-hide": "Zonari ihe di ime",
index 78e20ff..abed7eb 100644 (file)
        "newpageletter": "B",
        "boteditletter": "b",
        "number_of_watching_users_pageview": "[$1 nga agbuybuya {{PLURAL:$1|nga agar-aramat|kadagiti agar-aramat}}]",
-       "rc_categories": "Patingga dagiti kategoria (pagsinaen iti \"|\"):",
-       "rc_categories_any": "Ti ania man a napili",
        "rc-change-size-new": "$1 {{PLURAL:$1|a byte|kadagiti byte}} kalpasan ti panagsukat",
        "newsectionsummary": "/* $1 */ baro a seksion",
        "rc-enhanced-expand": "Ipakita dagiti salaysay",
index f4fe4cd..3e871a5 100644 (file)
        "minoreditletter": "зI",
        "newpageletter": "К",
        "boteditletter": "б",
-       "rc_categories_any": "МоллагIа яр хержа йолчарна юкъера",
        "rc-change-size-new": "Хувцам баьнначул тӀехьагIа бола боарам: $1 {{PLURAL:$1|байт}}",
        "rc-enhanced-expand": "Хьахьокха ма дарра",
        "rc-enhanced-hide": "Къайладаккха ма дарра дар",
index 595ae1f..ba6d50e 100644 (file)
        "minoreditletter": "m",
        "newpageletter": "N",
        "boteditletter": "r",
-       "rc_categories_any": "Irga selektita",
        "rc-change-size-new": "$1 {{PLURAL:$1|bicoko|bicoki}} pos la modifiki",
        "newsectionsummary": "/* $1 */ nova seciono",
        "rc-enhanced-expand": "Montrez detali",
index f0d3cd3..5fac894 100644 (file)
        "boteditletter": "v",
        "unpatrolledletter": "!",
        "number_of_watching_users_pageview": "[{{PLURAL:$1|notandi skoðandi|$1 notendur skoðandi}}]",
-       "rc_categories": "Takmarka við flokka (aðskilja með \"|\"):",
-       "rc_categories_any": "Allt valið",
        "rc-change-size": "$1",
        "rc-change-size-new": "$1 {{PLURAL:$1|bæt|bæti}} eftir breytingu",
        "newsectionsummary": "Nýr hluti: /* $1 */",
index aafc2d2..73568c1 100644 (file)
        "newpageletter": "N",
        "boteditletter": "b",
        "number_of_watching_users_pageview": "[osservata da {{PLURAL:$1|un utente|$1 utenti}}]",
-       "rc_categories": "Limita alle categorie (separate da \"|\"):",
-       "rc_categories_any": "Qualsiasi fra quelle indicate",
        "rc-change-size-new": "$1 {{PLURAL:$1|byte}} dopo la modifica",
        "newsectionsummary": "/* $1 */ nuova sezione",
        "rc-enhanced-expand": "Mostra dettagli",
index 6be5b5d..0381d19 100644 (file)
        "boteditletter": "ボ",
        "unpatrolledletter": "!",
        "number_of_watching_users_pageview": "[{{PLURAL:$1|$1 人の利用者}}がウォッチしています]",
-       "rc_categories": "カテゴリを限定 (「|」で区切る):",
-       "rc_categories_any": "選択したもの全部",
        "rc-change-size": "$1",
        "rc-change-size-new": "変更後は $1 {{PLURAL:$1|バイト}}",
        "newsectionsummary": "/* $1 */ 新しい節",
index 48bd40e..b67539c 100644 (file)
        "newpageletter": "A",
        "boteditletter": "b",
        "number_of_watching_users_pageview": "[$1 {{PLURAL:$1|cacahé sing ngawasi|cacahé sing ngawasi}}]",
-       "rc_categories": "Watesi tekan kategori (dipisah nganggo \"|\")",
-       "rc_categories_any": "Apa waé sing dipilih",
        "rc-change-size-new": "$1 {{PLURAL:$1|bét|bét}} sawisé diowahi",
        "newsectionsummary": "/* $1 */ pérangan anyar",
        "rc-enhanced-expand": "Tuduhaké princèn",
index f77067d..8eab43c 100644 (file)
        "boteditletter": "რ",
        "unpatrolledletter": "!",
        "number_of_watching_users_pageview": "[$1 მომხმარებლის/ები კონტროლი]",
-       "rc_categories": "მხოლოდ კატეგორიებიდან (გამყოფი „|“)",
-       "rc_categories_any": "არჩეულიდან ნებისმიერი",
        "rc-change-size": "$1",
        "rc-change-size-new": "ზომა ცვლილების შემდეგ არის: {{PLURAL:$1|ბაიტი|ბაიტი}}",
        "newsectionsummary": "/* $1 */ ახალი სექცია",
index 9dc959c..2838ab1 100644 (file)
        "newpageletter": "T",
        "boteditletter": "b",
        "number_of_watching_users_pageview": "[Baqlag'an {{PLURAL:$1|1 paydalanıwshı|$1 paydalanıwshı}}]",
-       "rc_categories": "Kategoriyalarg'a sheklew (\"|\" belgisi menen ajıratın')",
-       "rc_categories_any": "Ha'r qanday",
        "newsectionsummary": "/* $1 */ taza bo'lim",
        "rc-enhanced-expand": "Tolıq mag'lıwmattı ko'rsetiw (JavaScriptti talap etedi)",
        "rc-enhanced-hide": "Tolıq mag'lıwmattı jasırıw",
index d79e343..e47ef2c 100644 (file)
        "newpageletter": "N",
        "boteditletter": "b",
        "number_of_watching_users_pageview": "[$1 {{PLURAL:$1|aɛessas|iɛessasen}}]",
-       "rc_categories": "Ḥedded i taggayin (ferreq s \"|\")",
-       "rc_categories_any": "Yiwet seg tid yettwafernen",
        "rc-change-size-new": "$1 {{PLURAL:$1|atamḍan|itamḍanen}} seld abeddel",
        "newsectionsummary": "/* $1 */ tigezmi tamaynut",
        "rc-enhanced-expand": "Ẓeṛ ttfaṣil",
index 27e73ff..bdc3318 100644 (file)
        "newpageletter": "ج",
        "boteditletter": "ب",
        "number_of_watching_users_pageview": "[باقىلاعان $1 قاتىسۋشى]",
-       "rc_categories": "ساناتتارعا شەكتەۋ (\"|\" بەلگىسىمەن بولىكتەڭىز)",
-       "rc_categories_any": "قايسىبىر",
        "newsectionsummary": "/* $1 */ جاڭا ٴبولىم",
        "recentchangeslinked": "قاتىستى وزگەرىستەر",
        "recentchangeslinked-feed": "قاتىستى وزگەرىستەر",
index d83a5ea..ca4071e 100644 (file)
        "newpageletter": "Ж",
        "boteditletter": "б",
        "number_of_watching_users_pageview": "[бақылаған $1 қатысушы]",
-       "rc_categories": "Санаттарға шектеу («|» белгісімен бөлектеңіз):",
-       "rc_categories_any": "Таңдалғанның кез келгені",
        "rc-change-size-new": "Өңдеуден кейінгі көлемі: $1 {{PLURAL:$1|байт|байт}}",
        "newsectionsummary": "/* $1 */ жаңа бөлім",
        "rc-enhanced-expand": "Толық ақпаратты көрсету",
index af23527..6b8e784 100644 (file)
        "newpageletter": "J",
        "boteditletter": "b",
        "number_of_watching_users_pageview": "[baqılağan $1 qatıswşı]",
-       "rc_categories": "Sanattarğa şektew (\"|\" belgisimen bölikteñiz)",
-       "rc_categories_any": "Qaýsıbir",
        "newsectionsummary": "/* $1 */ jaña bölim",
        "recentchangeslinked": "Qatıstı özgerister",
        "recentchangeslinked-feed": "Qatıstı özgerister",
index 7244ada..f467d58 100644 (file)
        "right-siteadmin": "ចាក់សោនិងបើកសោមូលដ្ឋានទិន្នន័យ",
        "right-override-export-depth": "នាំចេញទំព័ររួមទាំងទំព័រដែលមានភ្ជាប់តំណភ្ជាប់​រហូតដល់លំដាប់ទី៥",
        "right-sendemail": "ផ្ញើអ៊ីមែលទៅកាន់អ្នកប្រើដទៃ",
+       "grant-createaccount": "បង្កើតគណនី",
        "grant-basic": "សិទ្ធិបឋម",
        "grant-viewdeleted": "មើលឯកសារនិងទំព័រដែលបានលុបចោល",
        "grant-viewmywatchlist": "មើលបញ្ជីតាមដានរបស់អ្នក",
        "newpageletter": "ថ្មី",
        "boteditletter": "យន្ត",
        "number_of_watching_users_pageview": "[មាន{{PLURAL:$1|អ្នកប្រើប្រាស់|អ្នកប្រើប្រាស់}}$1នាក់កំពុងមើល]",
-       "rc_categories": "កំហិតត្រឹមចំណាត់ថ្នាក់ក្រុម(ខណ្ឌដោយសញ្ញា \"|\")៖",
-       "rc_categories_any": "មួយណាក៏បាន",
        "rc-change-size": "$1",
        "rc-change-size-new": "$1 {{PLURAL:$1|បៃ|បៃ}} បន្ទាប់ពីបន្លាស់ប្ដូរ",
        "newsectionsummary": "/* $1 */ ផ្នែកថ្មី",
        "editcomment": "ចំណារពន្យល់ពីការកែប្រែគឺ៖ <em>$1</em>។",
        "revertpage": "បានត្រឡប់កំណែប្រែដោយ[[Special:Contributions/$2|$2]] ([[User talk:$2|Talk]]) ទៅកំណែប្រែចុងក្រោយដោយ [[User:$1|$1]]",
        "rollback-success": "កំណែ​ដែល​ត្រូវ​បាន​ត្រឡប់​ដោយ​ $1។\nបាន​ផ្លាស់​ប្ដូរ​ទៅ​កំណែ​ចុង​ក្រោយ​វិញ​ដោយ $2។",
+       "changecontentmodel-reason-label": "មូលហេតុ៖",
        "protectlogpage": "កំណត់ហេតុនៃការការពារ",
        "protectlogtext": "ខាងក្រោមនេះជាបញ្ជីនៃទំព័រដែលត្រូវបានចាក់សោនិងដោះសោ។\n\nសូមមើល [[Special:ProtectedPages|បញ្ជីទំព័រត្រូវបានការពារ]] សម្រាប់បញ្ជីការការពារទំព័រដែលកំពុងនៅមានសុពលភាពនៅពេលនេះ។",
        "protectedarticle": "បានការពារ\"[[$1]]\"",
        "invalidateemail": "បោះបង់ចោលការបញ្ជាក់ទទួលស្គាល់អ៊ីមែល",
        "scarytranscludetoolong": "[URL វែងជ្រុល]",
        "deletedwhileediting": "'''ប្រយ័ត្ន''' ៖ ទំព័រនេះបានត្រូវលុបចោល បន្ទាប់ពីអ្នកបានចាប់ផ្តើមកែប្រែ!",
-       "confirmrecreate": "អ្នកប្រើប្រាស់ [[User:$1|$1]] ([[User talk:$1|talk]]) បានលុបទំព័រនេះចោលបន្ទាប់ពីអ្នកចាប់ផ្ដើមកែប្រែវា ដោយមានហេតុផលថា៖\n\n៖ ''$2''\n\nសូមអះអាងថាអ្នកពិតជាចង់បង្កើតទំព័រនេះឡើងវិញពិតប្រាកដមែន។",
+       "confirmrecreate": "អ្នកប្រើប្រាស់ [[User:$1|$1]] ([[User talk:$1|ការពិភាក្សា]]) {{GENDER:$1|បានលុប}} ទំព័រនេះចោលបន្ទាប់ពីអ្នកចាប់ផ្ដើមកែប្រែវា ដោយមានហេតុផលថា៖\n\n៖ <em>$2</em>\n\nសូមអះអាងថាអ្នកពិតជាចង់បង្កើតទំព័រនេះឡើងវិញពិតប្រាកដមែន។",
        "confirmrecreate-noreason": "អ្នកប្រើប្រាស់ [[User:$1|$1]] ([[User talk:$1|talk]]) បានលុបទំព័រនេះចោលបន្ទាប់ពីអ្នកចាប់ផ្ដើមកែប្រែវា។ សូមអះអាងថាអ្នកពិតជាចង់បង្កើតទំព័រនេះឡើងវិញមែន។\n\nសូមអះអាងថាអ្នកពិតជាចង់បង្កើតទំព័រនេះឡើងវិញពិតប្រាកដមែន។",
        "recreate": "បង្កើតឡើងវិញ",
        "confirm_purge_button": "យល់ព្រម",
        "tags-actions-header": "សកម្មភាព",
        "tags-active-yes": "បាទ/ចាស៎",
        "tags-active-no": "ទេ",
+       "tags-source-extension": "កំណត់ដោយសូហ្វវែរ",
        "tags-source-none": "គ្មានគេប្រើទៀតទេ",
        "tags-edit": "កែប្រែ",
        "tags-delete": "លុបចោល",
        "tags-activate": "បើកប្រើ",
        "tags-deactivate": "បិទមិនប្រើ",
        "tags-hitcount": "$1 {{PLURAL:$1|បន្លាស់ប្ដូរ|បន្លាស់ប្ដូរ}}",
+       "tags-create-heading": "បង្កើតស្លាកថ្មី",
+       "tags-create-explanation": "តាមលំនាំដើម ស្លាកបង្កើតថ្មីនឹងត្រូវដាក់អោយប្រើដោយអ្នកប្រើប្រាស់ឬរូបយន្ត។",
+       "tags-create-tag-name": "ឈ្មោះ​ស្លាក៖",
+       "tags-create-reason": "មូលហេតុ៖",
+       "tags-create-submit": "បង្កើត",
+       "tags-delete-reason": "មូលហេតុ៖",
+       "tags-activate-reason": "មូលហេតុ៖",
+       "tags-deactivate-reason": "មូលហេតុ៖",
+       "tags-edit-reason": "មូលហេតុ៖",
        "comparepages": "ប្រៀបធៀបទំព័រ",
        "compare-page1": "ទំព័រ ១",
        "compare-page2": "ទំព័រ ២",
        "mw-widgets-titleinput-description-redirect": "បញ្ជូនបន្តទៅ $1",
        "mw-widgets-usersmultiselect-placeholder": "បន្ថែមទៀត",
        "date-range-from": "ចាប់ពី៖",
-       "date-range-to": "ដល់៖"
+       "date-range-to": "ដល់៖",
+       "gotointerwiki": "កំពុងចាកចេញពី{{SITENAME}}"
 }
index c79f960..5dc544e 100644 (file)
        "newpageletter": "ಹೊ",
        "boteditletter": "ಬಾ",
        "number_of_watching_users_pageview": "[$1 ವೀಕ್ಷಿಸುತ್ತಿರುವ {{PLURAL:$1|ಸದಸ್ಯ|ಸದಸ್ಯರು}}]",
-       "rc_categories": "ವರ್ಗಗಳಿಗೆ ಮಾತ್ರ ಸೀಮಿತವಾಗಿಸು (\"|\" ಇಂದ ಬೇರ್ಪಡಿಸು)",
-       "rc_categories_any": "ಯಾವುದೇ",
        "rc-change-size-new": "$1 {{PLURAL:$1|byte|bytes}} ಬದಲಾವಣೆಯ ನಂತರ",
        "newsectionsummary": "/* $1 */ ಹೊಸ ವಿಭಾಗ",
        "rc-enhanced-expand": "ವಿವರಗಳನ್ನು ತೋರಿಸು",
index e6fa11a..ecf9ce8 100644 (file)
        "newpageletter": "새글",
        "boteditletter": "봇",
        "number_of_watching_users_pageview": "[{{PLURAL:$1|사용자}} $1명이 주시하고 있음]",
-       "rc_categories": "다음 분류로 제한 (\"|\"로 구분):",
-       "rc_categories_any": "선택된 것 중 아무거나",
        "rc-change-size-new": "바꾼 후 $1 {{PLURAL:$1|바이트}}",
        "newsectionsummary": "/* $1 */ 새 문단",
        "rc-enhanced-expand": "자세한 내용 보기",
        "rollback-success": "{{GENDER:$3|$1}}의 편집을 되돌렸습니다.\n{{GENDER:$4|$2}}의 마지막 판으로 바뀌었습니다.",
        "rollback-success-notify": "$1의 편집을 되돌렸습니다.\n$2의 마지막 판으로 바뀌었습니다. [$3 차이 보기]",
        "sessionfailure-title": "세션 실패",
-       "sessionfailure": "로그인 세션에 문제가 발생한 것 같습니다.\n세션 하이재킹을 막기 위해 동작이 취소되었습니다.\n브라우저의 뒤로 버튼을 누르고 문서를 새로 고침한 후에 다시 시도해 주세요.",
+       "sessionfailure": "로그인 세션에 문제가 발생한 것 같습니다.\n세션 하이재킹을 막기 위해 동작이 취소되었습니다.\n양식을 다시 제출해 주십시오.",
        "changecontentmodel": "문서의 콘텐츠 모델을 변경",
        "changecontentmodel-legend": "콘텐츠 모델 변경",
        "changecontentmodel-title-label": "문서 제목",
        "watchlistedit-clear-titles": "제목:",
        "watchlistedit-clear-submit": "주시목록 문서 지우기 (이는 영구적입니다!)",
        "watchlistedit-clear-done": "주시문서 목록을 지웠습니다.",
+       "watchlistedit-clear-jobqueue": "주시 목록을 비우고 있습니다. 시간이 어느 정도 소요될 수 있습니다!",
        "watchlistedit-clear-removed": "{{PLURAL:$1|문서 1개|문서 $1개}}를 제거했습니다:",
        "watchlistedit-too-many": "여기에 표시할 문서가 너무 많습니다.",
        "watchlisttools-clear": "주시문서 목록 비우기",
index d3e55ee..89e9c6a 100644 (file)
        "newpageletter": "Дж",
        "boteditletter": "б",
        "number_of_watching_users_pageview": "[$1 {{PLURAL:$1|кёзюнде тутуучу къошулуучу}}]",
-       "rc_categories": "Къуру бу категорияладан («|» бла айыр):",
-       "rc_categories_any": "Сайланнгандан къайсысы да",
        "rc-change-size": "$1",
        "rc-change-size-new": "Тюрлениуден сора ёлчеми: $1 {{PLURAL:$1|байт}}",
        "newsectionsummary": "/* $1 */ Джангы бёлюм",
index 0456b68..a2df772 100644 (file)
        "boteditletter": "B",
        "unpatrolledletter": "!",
        "number_of_watching_users_pageview": "[{{PLURAL:$1|eine|$1|kein}} Oppasser]",
-       "rc_categories": "Bejränz op de Saachjroppe (schrihv „|“ dozwesche):",
-       "rc_categories_any": "Öhndseijne vun dä aanjejovve Saachjroppe",
        "rc-change-size": "$1 {{PLURAL:$1|Byte|Bytes}}",
        "rc-change-size-new": "$1 {{PLURAL:$1|Byte|Bytes|Bytes}} noh dem Ändere",
        "newsectionsummary": "Neuje Afschnet /* $1 */",
index 2a05464..6ef7b8e 100644 (file)
        "newpageletter": "Nû",
        "boteditletter": "b",
        "number_of_watching_users_pageview": "[{{PLURAL:$1|bikarhênerek|$1 bikarhêner}} vê rûpelê {{PLURAL:$1|dişopîne|dişopînin}}.]",
-       "rc_categories_any": "Qet",
        "rc-change-size-new": "Piştî guhertinê $1 {{PLURAL:$1|bayt}}",
        "newsectionsummary": "/* $1 */ beşeke nû",
        "rc-enhanced-expand": "Hûragahiyan nîşan bide",
index bd008e6..dc85920 100644 (file)
        "category_header": "\"$1\" категориядан сагьифалар",
        "subcategories": "Субкатегориялар",
        "category-media-header": "\"$1\" категориядагъы сапламлар",
+       "category-empty": "\"Бу категория буссагьат бош.\"",
        "hidden-categories": "{{PLURAL:$1|Яшырылгъан категория|Яшырылгъан категориялар}}‎",
+       "category-subcat-count": "{{PLURAL:$2|Бу категорияда янгыз гелеген тюп категориясы бар.|Бу категорияда янгыз гелеген $2 тюп категорядан {{PLURAL:$1|тюп категория}} гёрсетилген.}}",
+       "category-article-count": "{{PLURAL:$2|Бу категорияда янгыз гелеген бир сагьифа бар.|Бу категорияда бар $2 сагьифаны {{PLURAL:$1|сагьифасы}} гёрсетилген.}}",
        "listingcontinuesabbrev": "давам",
        "noindex-category": "Индексленмейген сагьифалар",
        "broken-file-category": "Ишлеймейген саплам байланывлары булан сагьифалар",
        "jumptosearch": "излев",
        "aboutsite": "{{SITENAME}} гьакъында",
        "aboutpage": "Project:Сыпатлав",
+       "copyright": "Ичделиги $1 лисензиягъа гёре гиришли (башгъасы мекенленмеген буса).",
        "copyrightpage": "{{ns:project}}:Ясавчу гьакълар",
        "currentevents": "Гьалиги гьаллар",
        "currentevents-url": "Project:Гьалиги гьаллар",
        "showdiff": "Тюзлевлени гёрсетмек",
        "loginreqlink": "гирмек",
        "noarticletext": "Бу сагьифа гьали де матынсыз. Сен башгъа сагьифаларда [[Special:Search/{{PAGENAME}}|булай атын эсгеривлерини излемеге]]  боласан, <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} тийишли гюнделик язывланы тапмагъа] яда '''[{{fullurl:{{FULLPAGENAME}}|action=edit}} булай аты булан сагьифа яратмагъа боласан]'''</span>.",
+       "noarticletext-nopermission": "Бу сагьифа гьали де текстсиз. Сен башгъа сагьифаларда [[Special:Search/{{PAGENAME}}|булай атын эсгеривлерини излемеге]], яда <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} тийишли гюнделиклени тапмагъа боласан]. </span> Тек бу сагьифаны яратмагъа ихтиярынг ёкъ.",
        "userpage-userdoesnotexist-view": "\"$1\" гьисап къайытланмагъан.",
        "previewnote": "<strong>Бу ингкъарав экенни эсде сакъла.</strong>\nАлышынывларынг гьали де сакъланмагъан!",
        "continue-editing": "Тюзлевню давамламакъ",
        "hiddencategories": "Бу сагьифа {{PLURAL:$1|1 яшырылгъан категориягъа}} янаша:",
        "permissionserrors": "Гириш ихтиярланы хатасы",
        "permissionserrorstext-withaction": "Бугъар $2 гелеген {{PLURAL:$1|себепге|себеплеге}} гёре ихтиярынг ёкъ:",
+       "recreate-moveddeleted-warn": "<strong>Тергев бер: Алдын тайдырылгъан сагьифаны ярашдырма айланасан.</strong>\n\nБашлап тергеп къара, гертиден де тарыкъмы экен ол сагьифаны ярашдырмагъа.\nТайдырыв ва атын алышдырыв гюнделиги тюпде берилген:",
        "content-model-wikitext": "викиматын",
        "undo-failure": "Аралыкъ алышынывланы къыйышывсызлгъы учун тюзлев гери алынмай.",
        "viewpagelogs": "Бу сагьифа учун гюнделиклени гёрсетмек",
        "editundo": "гери алмакъ",
        "diff-empty": "(башгъалыкълар ёкъ)",
        "diff-multi-sameuser": "(шо къоллавчуну {{PLURAL:$1|$1 аралыкъ тюрю}} гёрсетилмеген)",
+       "diff-multi-otherusers": "({{PLURAL:$2|къоллавчуну}}{{PLURAL:$1|аралыкъ тюзлевю|$1 аралыкъ тюзлевлери}} гёрсетилмеген)",
        "searchresults": "Излевню натижалар",
        "searchresults-title": "\"$1\" учун натижаланы излемек",
        "prevn": "алдагъы {{PLURAL:$1|$1}}",
        "nextn-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=|Излевюнге кёре табылгъан сагьифалагъа да къара.|Дагъы да излев гьасиллеге къара.}}",
        "searchprofile-articles": "Аслу сагьифалар",
        "searchprofile-images": "Мюлтимедиа",
        "searchprofile-everything-tooltip": "Бары да сагьифаларда излемек (сёйлешив сагьифаланы да къошуп)",
        "searchprofile-advanced-tooltip": "Сайлангъан аралыкъларда излемек",
        "search-result-size": "$1 ({{PLURAL:$2|1 сёз|$2 сёз}})‎",
+       "search-result-category-size": "{{PLURAL:$1|1 ортакъчы|$1 ортакъчы}} ({{PLURAL:$2|1 тюп категория|$2 тюп категория}}, {{PLURAL:$3|1 саплам|$3 саплам}})",
        "search-redirect": "($1 сагьифадан бакъдырылгъан)‎",
        "search-section": "($1 бёлме)",
        "search-file-match": "(сапламны ичделигине рас геле)",
        "recentchangeslinked-feed": "Байлавлу тюзлевлер",
        "recentchangeslinked-toolbox": "Байлавлу тюзлевлер",
        "recentchangeslinked-title": "\"$1\" сагьифагъа байлавлу тюзлевлер",
+       "recentchangeslinked-summary": "Бу сагьифагъа байлавлу тюзлевлери булан сагьифаланы яда о сагьифа байлавлуланы гёрмек учун атын яз. (Категорияны ортакъчаларын гёрмек учун Category:категорияны атын яз). Сени [[Special:Watchlist|гьызарлав тизменгдеги]] алышынывлар <strong>къалын</strong> гьарплылар.",
        "recentchangeslinked-page": "Сагьифаны аты:",
        "recentchangeslinked-to": "Къайта, бу сагьифагъа байлавлу сагьифаланы алышынывларын гёрсетмек",
        "upload": "Сапламны юклемек",
        "statistics": "Истатистик",
        "double-redirect-fixer": "Ёллав дуруславу",
        "nbytes": "$1 {{PLURAL:$1|байт|байтлар}}‎",
+       "nmembers": "$1 {{PLURAL:$1|ортакъчы}}",
        "prefixindex": "Префикс булан бары да сагьифалар",
        "listusers": "Ортакъчы тизмеси",
        "newpages": "Янгы сагьифалар",
        "speciallogtitlelabel": "Мурат (аты яда {{ns:user}}:ортакъчы):",
        "log": "Гюнделиклер",
        "all-logs-page": "Бары да гиришли гюнделиклер",
+       "alllogstext": "{{SITENAME}} сайфаны жыйымлы гюнделик тизмеси.\nНатижаланы гюнделик тайпасына, ортакъчы атына (уллу-гиччи гьарпланы гьисапгъа алып) яда тийилген сагьифасына (уллу-гиччи гьарпланы гьисапгъа алып) гёре айырма боласан.",
        "logempty": "Къыйышывлу язывлар гюнделикде ёкъ.",
        "allpages": "Бары сагьифалар",
        "allarticles": "Бары сагьифалар",
        "namespace": "Атлар аралыгъы:",
        "invert": "Сайлангъанын айландырмакъ",
        "namespace_association": "Байланышлы атлар аралыгъы",
+       "tooltip-namespace_association": "Сайлангъан атысакъламагъа байлавлу атсакъламаны, пикирлешивлени къошмакъ учун бу белгини де сал.",
        "blanknamespace": "(Аслу)",
        "contributions": "{{GENDER:$1|Къоллавчуну}} къошуму",
        "contributions-title": "Ортакъчыны ярдымы $1",
        "tooltip-ca-nstab-category": "Категорияны сагьифасына къарамакъ",
        "tooltip-minoredit": "Увакъ алышынывдай белгилемек",
        "tooltip-save": "Алышдырывларынг сакъламакъ",
+       "tooltip-preview": "Сагьифаны ингкъараву. Сакъълагъанчакъы пайдалан.",
        "tooltip-diff": "Сен этген матынны тюзлевлеринг гёрсетмек",
        "tooltip-compareselectedversions": "Бу сагьифаны сайлангъан эки тюрлерин башгъалыгъына къарамакъ.",
        "tooltip-watch": "Сени тергев сиягьынга бу сагьифаны къошмакъ",
        "pageinfo-header-restrictions": "Сагьифа къорув",
        "pageinfo-header-properties": "Сагьифа кюйлемлер",
        "pageinfo-display-title": "Гёрсетилеген аты",
+       "pageinfo-default-sort": "Бар кюйде айырыв ачгъычы",
        "pageinfo-length": "Сагьифаны узунлугъу (байтларда)",
        "pageinfo-article-id": "Сагьифа ID",
        "pageinfo-language": "Сагьифаны тили",
        "show-big-image-other": "Башгъа {{PLURAL:$2|айырым|айырымлар}}: $1.",
        "show-big-image-size": "$1 × $2 пиксел",
        "metadata": "Мета маълюматлар",
+       "exif-orientation": "Онгарылым",
        "exif-xresolution": "Гёнделен айырым",
        "exif-yresolution": "Тик айырым",
        "exif-datetime": "Сапламны алышыныв тархы ва заманы",
        "exif-make": "Камераны ясавчусу",
        "exif-model": "Камераны модели",
+       "exif-software": "Програм таъмини",
        "exif-exifversion": "Exif тюрю",
        "exif-colorspace": "Тюслер аралыгъы",
        "exif-datetimeoriginal": "Аслу тарх ва заман",
+       "exif-datetimedigitized": "Санавлашдырывну тархы ва заманы",
        "exif-orientation-1": "Нормал",
        "namespacesall": "бары да",
        "monthsall": "бары да",
        "watchlisttools-edit": "Тизмени къарап тюзлемек",
        "watchlisttools-raw": "Саяв текстни тюзлемек",
        "signature": "[[{{ns:user}}:$1|$2]] ([[{{ns:user_talk}}:$1|сёйлешив]])",
+       "redirect": "Сапламны, къоллавчуну, сагьифаны, тюрню яда гюнделикни менлигине гёре ёллав",
        "redirect-submit": "Гёчмек",
        "redirect-lookup": "Излев:",
        "redirect-value": "Къыймат:",
        "tags-hitcount": "$1 {{PLURAL:$1|алышыныв|алышынывлар}}",
        "logentry-delete-delete": "$1 {{GENDER:$2|тайдыргъан}} сагьифаны $3",
        "logentry-delete-restore": "$1 бу $3 ($4) сагьифаны {{GENDER:$2ярашдыргъан|}}",
+       "logentry-delete-revision": "$1 бу сагьифаны $3: $4 {{PLURAL:$5|тюрюн}} гёрюнегенлигин {{GENDER:$2|алышдырды}}",
        "revdelete-content-hid": "ичделиги яшырылгъан",
        "logentry-move-move": "$1 къоллавчу $3 сагьифаны $4 сагьифагъа атын айландыргъан",
+       "logentry-move-move-noredirect": "$1 бу сагьифаны $3 атын бугъар $4 {{GENDER:$2|алышдырды}} онгарывсуз да къойду",
+       "logentry-move-move_redir": "$1 бу сагьифаны $3 атын бугъар $4 {{GENDER:$2|алышдырды}} онгарывсуз да къойду",
+       "logentry-patrol-patrol-auto": "$1 оьзлюгюнден $3 сагьифаны $4 тюрюн патруллангъандай {{GENDER:$2|белгилеген}}",
        "logentry-newusers-create": "$2 къоллавчу $1 бетин этген",
+       "logentry-newusers-autocreate": "$1 ортакъчыны гьисабы оьзлюгюнден {{GENDER:$2|яратылды}}",
        "logentry-upload-upload": "$1 {{GENDER:$2|юклеген}} $3",
        "logentry-upload-overwrite": "$1 буну $3 янгы тюрюн {{GENDER:$2|юклеген}}",
        "searchsuggest-search": "{{SITENAME}} ичинде излемек",
index 1dbb6c6..19f7d87 100644 (file)
        "minoreditletter": "м",
        "newpageletter": "Ж",
        "boteditletter": "б",
-       "rc_categories_any": "Каалаган",
        "rc-enhanced-expand": "Кошумча маалыматтарды көрсөтүү (JavaScript талап кылынат)",
        "rc-enhanced-hide": "Кошумча маалыматтарды жашыруу",
        "recentchangeslinked": "Байланыштуу өзгөрүүлөр",
index a70c190..e07ef69 100644 (file)
        "newpageletter": "N",
        "boteditletter": "a",
        "number_of_watching_users_pageview": "[$1 {{PLURAL:$1|usor observans|usores observantes}}]",
-       "rc_categories_any": "Ulla",
        "rc-change-size-new": "$1 {{PLURAL:$1|octetus|octeti}} post recensionem",
        "newsectionsummary": "/* $1 */ nova pars",
        "rc-enhanced-expand": "Minima monstrare",
index 53efa23..dfc7321 100644 (file)
        "minoreditletter": "ch",
        "newpageletter": "M",
        "boteditletter": "b",
-       "rc_categories_any": "Kualkyer",
        "rc-change-size-new": "$1 {{PLURAL:$1|bayt|baytes}} dospués del trocamiento",
        "rc-enhanced-expand": "Amostrar los detalios",
        "rc-enhanced-hide": "Esconder los detalios",
index 92531ef..6f98e93 100644 (file)
        "newpageletter": "N",
        "boteditletter": "B",
        "number_of_watching_users_pageview": "[$1 Benotzer {{PLURAL:$1|iwwerwaacht|iwwerwaachen}}]",
-       "rc_categories": "Limitéieren op d'Kategorie (getrennt mat \"|\"):",
-       "rc_categories_any": "Aus iergendenger vun den erausgesichten",
        "rc-change-size": "$1 {{PLURAL:$1|Byte|Bytes}}",
        "rc-change-size-new": "$1 {{PLURAL:$1|Byte|Bytes}} no der Ännerung",
        "newsectionsummary": "Neien Abschnitt /* $1 */",
index 832a9ec..0ea7d77 100644 (file)
        "minoreditletter": "гъ",
        "newpageletter": "Цl",
        "boteditletter": "б",
-       "rc_categories_any": "ГЬар са",
        "rc-change-size-new": "Масакlа авунилай ахпа кьадар: $1 байт",
        "rc-enhanced-expand": "Куьлуь-шуьлуьяр къалурун (JavaScript герекзава)",
        "rc-enhanced-hide": "Куьлуь-шуьлуьяр чуьнуьха",
index f590c4a..6cf48a3 100644 (file)
        "newpageletter": "N",
        "boteditletter": "b",
        "number_of_watching_users_pageview": "[$1 {{PLURAL:$1|usor|usores}} monitorinte]",
-       "rc_categories": "Limita de categorias (separa con \"|\"):",
-       "rc_categories_any": "Cualce de la elejedas",
        "rc-change-size-new": "$1 {{PLURAL:$1|bait|baites}} pos cambia",
        "newsectionsummary": "/* $1 */ parte nova",
        "rc-enhanced-expand": "Mostra detalias",
index 4c3fc7e..5797798 100644 (file)
        "newpageletter": "N",
        "boteditletter": "b",
        "number_of_watching_users_pageview": "[$1 {{PLURAL:$1|keer|keer}} op 'ne volglies]",
-       "rc_categories": "Bepirk tot categorieë (sjeij mit 'n \"|\")",
-       "rc_categories_any": "Idder vanne gekaozene",
        "rc-change-size-new": "$1 {{PLURAL:$1|byte|bytes}} nao verangering",
        "newsectionsummary": "/* $1 */ nuje subkop",
        "rc-enhanced-expand": "Toean details",
index 74558b9..58978b9 100644 (file)
        "newpageletter": "N",
        "boteditletter": "b",
        "number_of_watching_users_pageview": "[osservâ da {{PLURAL:$1|un utente|$1 utenti}}]",
-       "rc_categories": "Limite a-e categorie (separæ da \"|\"):",
-       "rc_categories_any": "Quâ-se-sæ fra quelle indicæ",
        "rc-change-size-new": "$1 {{PLURAL:$1|byte|bytes}} doppo a modiffica",
        "newsectionsummary": "/* $1 */ neuva seçion",
        "rc-enhanced-expand": "Fanni vedde i detaggi",
index 137a1bc..a375bcc 100644 (file)
        "newpageletter": "نو",
        "boteditletter": "ر",
        "number_of_watching_users_pageview": "[$1 {{PLURAL:$1|کاربر}} پی‌گیرنده]",
-       "rc_categories": "محدود به این رده‌ها (رده‌ها را با «|» جدا کنید):",
-       "rc_categories_any": "هر کدام از منتخب‌ها",
        "rc-change-size-new": " $1دؤما تۀقیر دائن{{PLURAL:$1|بایت|بایتل}}",
        "newsectionsummary": "/* $1 */ بەخش نوو",
        "rc-enhanced-expand": "نمایش جزئیات",
index f3b0346..6f924de 100644 (file)
        "newpageletter": "N",
        "boteditletter": "b",
        "number_of_watching_users_pageview": "[tignìda d'öcc de {{PLURAL:$1|1 ütènt|$1 ütèncc}}]",
-       "rc_categories_any": "Töcc",
        "rc-change-size-new": "$1 {{PLURAL:$1|byte|bytes}} dopo la mudìfica",
        "newsectionsummary": "/* $1 */ sezión növa",
        "rc-enhanced-expand": "Fà ved i detai",
index 4fcbd64..32d48b2 100644 (file)
        "boteditletter": "ب",
        "unpatrolledletter": "!",
        "number_of_watching_users_pageview": "[$1 دینه {{PLURAL:$1|کاریار|کاریاریا}}]",
-       "rc_categories": "جأرغە یا نە مأدوٙد کو(ڤا \"|\" جئگا بان)",
-       "rc_categories_any": "ھأرکوم کئ گولئ ڤورچیە بیینە",
        "rc-change-size": "$1",
        "rc-change-size-new": "$1 {{PLURAL:$1|بایت|بایتیا}} ناٛها آلشتکاری",
        "newsectionsummary": "/* $1 */ بهرجا تازه",
index 8055a37..5a0574b 100644 (file)
        "accmailtext": "Atsitiktinai sukurtas naudotojo [[User talk:$1|$1]] slaptažodis nusiųstas į $2.\n\nŠios naujos paskyros slaptažodis gali būti pakeistas <em>[[Special:ChangePassword|keisti slaptažodį]]</em> puslapyje beprisijungiant.",
        "newarticle": "(Naujas)",
        "newarticletext": "Jūs patekote į dar neegzistuojantį puslapį.\nNorėdami sukurti puslapį, pradėkite rašyti žemiau esančiame įvedimo lauke\n(plačiau [$1 pagalbos puslapyje]).\nJei patekote čia per klaidą, paprasčiausiai spustelkite  naršyklės mygtuką '''atgal'''.",
-       "anontalkpagetext": "----''Tai yra anoniminio naudotojo, nesusikūrusio arba nenaudojančio paskyros, aptarimų puslapis.\nDėl to naudojamas IP adresas jo identifikavimui.\nŠis IP adresas gali būti dalinamas keliems naudotojams.\nJeigu Jūs esate anoniminis naudotojas ir atrodo, kad komentarai nėra skirti Jums, [[Special:CreateAccount|sukurkite paskyrą]] arba [[Special:UserLogin|prisijunkite]], ir nebūsite tapatinamas su kitais anoniminiais naudotojais.''",
+       "anontalkpagetext": "----\n<em>Tai yra anoniminio naudotojo, nesusikūrusio arba nenaudojančio paskyros, aptarimų puslapis.</em>\nDėl to naudojamas IP adresas jo identifikavimui.\nŠis IP adresas gali priklausyti keliems naudotojams.\nJeigu Jūs esate anoniminis naudotojas ir atrodo, kad komentarai nėra skirti Jums, [[Special:CreateAccount|sukurkite paskyrą]] arba [[Special:UserLogin|prisijunkite]], ir nebūsite tapatinamas su kitais anoniminiais naudotojais.",
        "noarticletext": "Šiuo metu šiame puslapyje nėra jokio teksto.\nJūs galite [[Special:Search/{{PAGENAME}}|ieškoti šio puslapio pavadinimo]] kituose puslapiuose,\n<span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} ieškoti susijusių įrašų] arba [{{fullurl:{{FULLPAGENAME}}|action=edit}} sukurti šį puslapį]</span>.",
        "noarticletext-nopermission": "Šiuo metu šiame puslapyje nėra jokio teksto.\nJūs galite [[Special:Search/{{PAGENAME}}|ieškoti šio puslapio pavadinimo]] kituose puslapiuose,\n<span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} ieškoti susijusių įrašų]</span>, tačiau jūs neturite teisės sukurti šio puslapio.",
        "missing-revision": "Puslapio peržiūra #$1 pavadinto „{{FULLPAGENAME}}“ neegzistuoja.\n\nTai paprastai atsitinka kai pasenusi nuoroda veda į puslapį, kuris buvo ištrintas.\nInformaciją galima rasti [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} deletion log].",
        "newpageletter": "N",
        "boteditletter": "a",
        "number_of_watching_users_pageview": "[$1 {{PLURAL:$1|stebintis naudotojas|stebintys naudotojai|stebinčių naudotojų}}]",
-       "rc_categories": "Riboti kategorijoms (atskirkite su „|“)",
-       "rc_categories_any": "Bet kuris iš pasirinktųjų",
        "rc-change-size-new": "$1 {{PLURAL:$1|baitas|baitai|baitų}} po pakeitimo",
        "newsectionsummary": "/* $1 */ naujas skyrius",
        "rc-enhanced-expand": "Rodyti detales",
        "backend-fail-read": "Negalima nuskaityti failo $1.",
        "backend-fail-create": "Negalima sukurti failo $1.",
        "backend-fail-maxsize": "Failo $1 sukurti nepavyko nes jis didesnis nei {{PLURAL:$2|vienas baitas|$2 baitai|$2 baitų}}.",
-       "backend-fail-readonly": "Galutinė saugykla \"$1\" dabar yra skirta tik skaitymui. Buvo nurodyta priežastis: \"$2\"",
+       "backend-fail-readonly": "Galutinė saugykla \"$1\" dabar yra skirta tik skaitymui. Nurodyta priežastis: <em>$2</em>",
        "backend-fail-synced": "Failas \"$1\", esantis vidinėje galutinėje saugykloje, yra pažymėtas kaip nepilnas.",
        "backend-fail-connect": "Negalima prisijungti prie galutinės saugyklos \"$1\".",
        "backend-fail-internal": "Nežinoma klaida įvyko galutinėje saugykloje \"$1\".",
        "editcomment": "Pateiktas toks keitimo paaiškinimas: <em>$1</em>.",
        "revertpage": "Atmestas [[Special:Contributions/$2|$2]] ([[User talk:$2|Aptarimas]]) pakeitimas; sugrąžinta [[User:$1|$1]] versija",
        "revertpage-nouser": "Atversti pakeitimai paslėpto vartotojo, grąžino prieš tai buvusią versiją {{GENDER:$1|[[User:$1|$1]]}}",
-       "rollback-success": "Atmesti $1 pakeitimai;\ngrąžinta prieš tai buvusi $2 versija.",
+       "rollback-success": "Atmesti {{GENDER:$3|$1}} pakeitimai;\ngrąžinta prieš tai buvusi {{GENDER:$4|$2}} versija.",
        "rollback-success-notify": "Atmesti $1 pakeitimai;\ngrąžinta prieš tai buvusi $2 versija. [$3 Rodyti skirtumus]",
        "sessionfailure-title": "Sesijos klaida",
        "sessionfailure": "Atrodo yra problemų su jūsų prisijungimo sesija; šis veiksmas buvo atšauktas kaip atsargumo priemonė prieš sesijos vogimą.\nPrašome paspausti „atgal“ ir perkraukite puslapį iš kurio atėjote, ir pamėginkite vėl.",
        "import-nonewrevisions": "Nebuvo importuotos jokios versijos (visos jau buvo įkeltos arba praleistos dėl klaidų).",
        "xml-error-string": "$1 $2 eilutėje, $3 stulpelyje ($4 baitas): $5",
        "import-upload": "Įkelti XML duomenis",
-       "import-token-mismatch": "Sesijos duomenys prarasti.\n\nGali būti, kad esate atsijungęs. <strong>Prašome patikrinti, ar vis dar esate prisijungęs, ir pabandyti iš naujo</strong>.\nJei ir toliau nepavyksta, pamėginkite [[Special:UserLogout|atsijungti]] ir vėl prisijungti, taip pat patikrinkite, ar jūsų naršyklė priima šios svetainės slapukus.",
+       "import-token-mismatch": "Sesijos duomenys prarasti.\n\nGali būti, kad esate atsijungęs. '''Prašome patikrinti, ar vis dar esate prisijungęs, ir pabandyti iš naujo'''.\nJei ir toliau nepavyksta, pamėginkite [[Special:UserLogout|atsijungti]] ir vėl prisijungti, taip pat patikrinkite, ar jūsų naršyklė priima šios svetainės slapukus.",
        "import-invalid-interwiki": "Nepavyko importuoti iš nurodyto wiki projekto.",
        "import-error-edit": "Puslapis \"$1\" nebuvo įkeltas, nes jūs neturite teisės jį redaguoti.",
        "import-error-create": "Puslapis „$1“ nebuvo importuotas, nes jūs neturite teisės jį sukurti.",
index 3130025..c68c667 100644 (file)
        "newpageletter": "T",
        "boteditletter": "k",
        "number_of_watching_users_pageview": "[$1 hmangtu {{PLURAL:$1||te}} vil mék]",
-       "rc_categories": "Pawla bithliahna (\"|\" hmangin kárdan rawh)",
-       "rc_categories_any": "Väi",
        "rc-change-size-new": "Tihdanglam hnuah {{PLURAL:$1|bait|bait}} $1",
        "newsectionsummary": "/* $1 */ hläwm thar",
        "rc-enhanced-expand": "Tilang kim rawh (JavaScript a ngai)",
index ff62ec0..96c7c65 100644 (file)
        "newpageletter": "J",
        "boteditletter": "b",
        "number_of_watching_users_pageview": "[šo lapu uzrauga $1 {{PLURAL:$1|dalībnieki|dalībnieks|dalībnieki}}]",
-       "rc_categories": "Ierobežot uz kategorijām (atdalīt ar \"|\"):",
-       "rc_categories_any": "Jebkas no izvēlētā",
        "rc-change-size-new": "$1 {{PLURAL:$1|baiti|baits|baiti}} pēc izmaiņām",
        "newsectionsummary": "/* $1 */ jauna sadaļa",
        "rc-enhanced-expand": "Skatīt detaļas",
index 95d230f..e121124 100644 (file)
        "newpageletter": "新",
        "boteditletter": "僕",
        "number_of_watching_users_pageview": "[放有$1哨]",
-       "rc_categories_any": "任",
        "rc-change-size-new": "既纂,本文有$1字節",
        "newsectionsummary": "/* $1 */ 新節",
        "rc-enhanced-expand": "示細",
index 280eefa..c1f7582 100644 (file)
        "minoreditletter": "çʼ",
        "newpageletter": "A",
        "boteditletter": "b",
-       "rc_categories_any": "Çkar",
        "rc-enhanced-expand": "Detayepe ko3ʼiri (JavaScript-i unon)",
        "rc-enhanced-hide": "Detayepe doşinaxi",
        "recentchangeslinked": "Alakʼali na renan oktirobape",
index fc89c73..f76bfc0 100644 (file)
        "boteditletter": "ब",
        "unpatrolledletter": "!",
        "number_of_watching_users_pageview": "[$1 ध्यान राखैवाला {{PLURAL:$1|प्रयोक्ता|प्रयोक्तासभ}}]",
-       "rc_categories": "श्रेणीसभ धरि सीमीत राखी (\"|\" सँ अलग करी)",
-       "rc_categories_any": "कोनो भी चुनिन्दा",
        "rc-change-size": "$1",
        "rc-change-size-new": "परिवर्तनक बाद $1 {{PLURAL:$1|बाइट}}",
        "newsectionsummary": "/* $1 */ नव अनुभाग",
index e07c525..72dcde6 100644 (file)
        "minoreditletter": "c",
        "newpageletter": "A",
        "boteditletter": "b",
-       "rc_categories": "Batesi gutul kategori (dipisah karo \"|\")",
-       "rc_categories_any": "Apa baen",
        "newsectionsummary": "/* $1 */ bagiyan anyar",
        "rc-enhanced-expand": "Tidokna detile (merlokna JavaScript)",
        "rc-enhanced-hide": "Umpetna rincian",
index 21121e9..33f6892 100644 (file)
        "newpageletter": "О",
        "boteditletter": "р",
        "number_of_watching_users_pageview": "[$1 ваны {{PLURAL:$1|тии|тиихть}}]",
-       "rc_categories": "Аньцек категориеста (явфтомс \"|\" вельде)",
-       "rc_categories_any": "Эрь кодама",
        "newsectionsummary": "/* $1 */ од пялькс",
        "rc-enhanced-expand": "Няфтемс анцяйнятне (эряви JavaScript)",
        "rc-enhanced-hide": "Кяшемс анцяйнятне",
index 2a527db..c775763 100644 (file)
        "newpageletter": "V",
        "boteditletter": "r",
        "number_of_watching_users_pageview": "[$1 {{PLURAL:$1|mpikambana|mpikambana}} manara-maso]",
-       "rc_categories": "Ferana amin'ireto sokajy ireto (saraho amin'ny \"|\")",
-       "rc_categories_any": "Anisan'ireo nofidiana",
        "rc-change-size-new": "$1{{PLURAL:}} oktety taorian'ny fanovana",
        "newsectionsummary": "/* $1 */ fizarana vaovao",
        "rc-enhanced-expand": "Hijery ny antsipirihany",
index 4069ec0..ae3fc10 100644 (file)
        "newpageletter": "Н",
        "boteditletter": "б",
        "number_of_watching_users_pageview": "[$1 {{PLURAL:$1|корисник што набљудува|корисници што набљудуваат}}]",
-       "rc_categories": "Само од категории (одделувајќи со „|“):",
-       "rc_categories_any": "Било која од избраните",
        "rc-change-size": "$1",
        "rc-change-size-new": "$1 {{PLURAL:$1|бајт|бајти}} по промената",
        "newsectionsummary": "/* $1 */ ново заглавие",
index 8e986bf..7f068cd 100644 (file)
        "boteditletter": "(യ.)",
        "unpatrolledletter": "(!)",
        "number_of_watching_users_pageview": "[{{PLURAL:$1|ഒരു ഉപയോക്താവ്|$1 ഉപയോക്താക്കൾ}} ഈ താൾ ശ്രദ്ധിക്കുന്നുണ്ട്]",
-       "rc_categories": "വർഗ്ഗങ്ങളുടെ പരിധി (\"|\" ഉപയോഗിച്ച് പിരിക്കുക):",
-       "rc_categories_any": "തിരഞ്ഞെടുത്തതിൽ ഏതെങ്കിലും",
        "rc-change-size-new": "മാറ്റത്തിനു ശേഷം {{PLURAL:$1|ഒരു ബൈറ്റ്|$1 ബൈറ്റുകൾ}}",
        "newsectionsummary": "/* $1 */ പുതിയ ഉപവിഭാഗം",
        "rc-enhanced-expand": "അധികവിവരങ്ങൾ പ്രദർശിപ്പിക്കുക",
        "htmlform-user-not-exists": "<strong>$1</strong> നിലവിലില്ല.",
        "htmlform-user-not-valid": "<strong>$1</strong> സാധുതയുള്ള ഉപയോക്തൃനാമമല്ല.",
        "logentry-delete-delete": "$3 എന്ന താൾ $1 {{GENDER:$2|മായ്ച്ചിരിക്കുന്നു}}",
+       "logentry-delete-delete_redir": " $3 എന്ന തിരിച്ചുവിടൽ, $1, മുകളിൽ ചേർത്തത് വഴി {{GENDER:$2|മായ്‌ച്ചിരിക്കുന്നു}}",
        "logentry-delete-restore": "$3 എന്ന താൾ $1 {{GENDER:$2|പുനഃസ്ഥാപിച്ചിരിക്കുന്നു}} ($4)",
+       "logentry-delete-restore-nocount": "$3 എന്ന താൾ $1 {{GENDER:$2|പുനഃസ്ഥാപിച്ചിരിക്കുന്നു}}",
        "restore-count-revisions": "{{PLURAL:$1|ഒരു നാൾപ്പതിപ്പ്|$1 നാൾപ്പതിപ്പുകൾ}}",
        "restore-count-files": "{{PLURAL:$1|ഒരു പ്രമാണം|$1 പ്രമാണങ്ങൾ}}",
        "logentry-delete-event": "$3 എന്ന {{PLURAL:$5|രേഖയിലെ മാറ്റത്തിന്റെ|രേഖയിലെ $5 മാറ്റങ്ങളുടെ}} ദർശനീയത $1 {{GENDER:$2|മാറ്റിയിരിക്കുന്നു}}: $4",
        "logentry-protect-protect-cascade": "$3 താൾ $1 {{GENDER:$2|സംരക്ഷിച്ചു}} $4 [നിർഝരിതം]",
        "logentry-protect-modify": "$3 താളിന്റെ സംരക്ഷണതലം $1 {{GENDER:$2|മാറ്റി}} $4",
        "logentry-protect-modify-cascade": "$3 താളിന്റെ സംരക്ഷണതലം $1 {{GENDER:$2|മാറ്റി}} $4 [നിർഝരിതം]",
-       "logentry-rights-rights": "$3 എന്ന ഉപയോക്താവിന്റെ സംഘ അംഗത്വം, $4 എന്നതിൽ നിന്നു $5 എന്നതിലേക്ക്, $1 {{GENDER:$2|മാറ്റിയിരിക്കുന്നു}}",
+       "logentry-rights-rights": "{{GENDER:$6|$3}} എന്ന ഉപയോക്താവിന്റെ സംഘ അംഗത്വം, $4 എന്നതിൽ നിന്നു $5 എന്നതിലേക്ക്, $1 {{GENDER:$2|മാറ്റിയിരിക്കുന്നു}}",
        "logentry-rights-rights-legacy": "$3 എന്ന ഉപയോക്താവിന്റെ സംഘ അംഗത്വം $1 {{GENDER:$2|മാറ്റിയിരിക്കുന്നു}}",
        "logentry-rights-autopromote": "$1 എന്ന ഉപയോക്താവ് $4 എന്നതിൽ നിന്നും $5 എന്നതിലേയ്ക്ക് സ്വയമേവ {{GENDER:$2|ഉയർത്തപ്പെട്ടിരിക്കുന്നു}}",
        "logentry-upload-upload": "$1 $3 {{GENDER:$2|അപ്‌ലോഡ് ചെയ്തു}}",
        "logentry-tag-update-revision": "$3 എന്ന താളിന്റെ $4 എന്ന നാൾപ്പതിപ്പിൽ ടാഗുകൾ $1 {{GENDER:$2|പുതുക്കി}} ($6 {{PLURAL:$7|ചേർത്തു}}; $8 {{PLURAL:$9|നീക്കംചെയ്തു}})",
        "logentry-tag-update-logentry": "$3 എന്ന താളിന്റെ $5 എന്ന രേഖയിലെ ഉൾപ്പെടുത്തലിൽ ടാഗുകൾ $1 {{GENDER:$2|പുതുക്കി}} ($6 {{PLURAL:$7|ചേർത്തു}}; $8 {{PLURAL:$9|നീക്കംചെയ്തു}})",
        "rightsnone": "(ഒന്നുമില്ല)",
+       "rightslogentry-temporary-group": "$1 (താത്കാലികം, $2 വരെ)",
        "feedback-adding": "താങ്കളുടെ അഭിപ്രായങ്ങൾ താളിലേയ്ക്ക് ചേർക്കുന്നു...",
        "feedback-back": "പുറകോട്ട്",
        "feedback-bugcheck": "കൊള്ളാം! [$1 അറിയാവുന്ന ബഗുകളിൽ] ഒന്നല്ല എന്ന് ഒന്നു പരിശോധിച്ചേക്കുക.",
        "log-action-filter-delete-revision": "നാൾപ്പതിപ്പ് മായ്ക്കൽ",
        "log-action-filter-import-interwiki": "ട്രാൻസ്‌‌വിക്കി ഇറക്കുമതി",
        "log-action-filter-import-upload": "എക്സ്.എം.എൽ. അപ്‌ലോഡ് വഴിയുള്ള ഇറക്കുമതി",
+       "log-action-filter-protect-protect": "സംരക്ഷണം",
+       "log-action-filter-protect-unprotect": "സംരക്ഷണമൊഴിവാക്കൽ",
+       "log-action-filter-protect-move_prot": "സംരക്ഷണം മാറ്റി",
        "log-action-filter-suppress-event": "രേഖ ഒതുക്കൽ",
        "log-action-filter-suppress-revision": "നാൾപ്പതിപ്പ് ഒതുക്കൽ",
        "log-action-filter-suppress-delete": "താൾ ഒതുക്കൽ",
        "authmanager-link-no-primary": "അംഗത്വം ബന്ധിപ്പിക്കാൻ നൽകിയിരിക്കുന്ന വിവരങ്ങൾ ഉപയോഗിക്കാനാവില്ല.",
        "authmanager-link-not-in-progress": "സെഷൻ ഡേറ്റ നഷ്ടപ്പെട്ടതിനാൽ അംഗത്വം ബന്ധിപ്പിക്കലിന്റെ പുരോഗതി നഷ്ടമായിരിക്കുന്നു. ദയവായി  ആദ്യം മുതൽ വീണ്ടും തുടങ്ങുക.",
        "authmanager-authplugin-setpass-failed-title": "രഹസ്യവാക്ക് മാറ്റം പരാജയപ്പെട്ടു",
+       "authmanager-authplugin-setpass-bad-domain": "അസാധുവായ ഡൊമൈൻ.",
+       "authmanager-userdoesnotexist": "\"$1\" എന്ന ഉപയോക്തൃ അം‌ഗത്വം നിലവിലില്ല.",
+       "authmanager-userlogin-remembermypassword-help": "രഹസ്യവാക്ക് സെഷൻ കാലയളവിലധികം ഓർത്തുവെക്കണോ.",
+       "authmanager-username-help": "രഹസ്യവാക്ക് ഉപയോഗിച്ചുള്ള സാധൂകരണം.",
+       "authmanager-password-help": "രഹസ്യവാക്ക് ഉപയോഗിച്ചുള്ള സാധൂകരണം.",
+       "authmanager-domain-help": "ഡൊമൈൻ ഉപയോഗിച്ചുള്ള ബാഹ്യ സാധൂകരണം.",
        "authmanager-retype-help": "സ്ഥിരീകരിക്കാനായി വീണ്ടും രഹസ്യവാക്ക് നൽകുക.",
        "authmanager-email-label": "ഇമെയിൽ",
        "authmanager-email-help": "ഇമെയിൽ വിലാസം",
        "authmanager-realname-label": "യഥാർത്ഥ പേര്‌",
        "authmanager-realname-help": "ഉപയോക്താവിന്റെ യഥാർത്ഥ പേര്",
+       "authmanager-provider-password": "രഹസ്യവാക്ക്-അധിഷ്ഠിത സാധൂകരണം",
+       "authmanager-provider-password-domain": "രഹസ്യവാക്ക്-ഡൊമൈൻ-അധിഷ്ഠിത സാധൂകരണം",
+       "authmanager-provider-temporarypassword": "താത്കാലിക രഹസ്യവാക്ക്",
        "authprovider-resetpass-skip-label": "മറികടക്കുക",
        "specialpage-securitylevel-not-allowed-title": "അനുവദിച്ചിട്ടില്ല",
        "cannotauth-not-allowed-title": "അനുമതി നിഷേധിച്ചിരിക്കുന്നു",
        "cannotauth-not-allowed": "ഈ താൾ ഉപയോഗിക്കാൻ താങ്കൾക്ക് അനുവാദമില്ല",
+       "edit-error-short": "പിഴവ്: $1",
+       "edit-error-long": "പിഴവുകൾ:\n\n$1",
+       "revid": "നാൾപ്പതിപ്പ് $1",
+       "pageid": "താൾ ഐ.ഡി. $1",
+       "rawhtml-notallowed": "&lt;html&gt; ടാഗുകൾ സാധാരണ താളുകൾക്ക്പുറത്ത് ഉപയോഗിക്കാനാകില്ല.",
        "gotointerwiki": "{{SITENAME}} സംരംഭത്തിൽ നിന്നും പോകുകയാണ്",
+       "gotointerwiki-invalid": "നൽകിയിരിക്കുന്ന തലക്കെട്ട് അസാധുവാണ്.",
+       "pagedata-title": "താൾ വിവരങ്ങൾ",
        "pagedata-bad-title": "അസാധുവായ തലക്കെട്ട്: $1."
 }
index dabc353..78ffe43 100644 (file)
        "newpageletter": "Ш",
        "boteditletter": "р",
        "number_of_watching_users_pageview": "[$1 хэрэглэгч харж байна]",
-       "rc_categories": "Ангиллуудад хязгаарлах (\"|\" тэмдгээр тусгаарлана)",
-       "rc_categories_any": "Хамаагүй",
        "rc-change-size-new": "Өөрчилсний дараа $1 {{PLURAL:$1|байт|байт}}",
        "newsectionsummary": "/* $1 */ шинэ хэсэг",
        "rc-enhanced-expand": "Дэлгэрэнгүй мэдээллийг үзүүлэх (ЖаваСкрипт хэрэглэгдэнэ)",
index aa9690c..7c7994d 100644 (file)
        "newpageletter": "न.पा.",
        "boteditletter": "सां.",
        "number_of_watching_users_pageview": "[$1 {{PLURAL:$1|सदस्याने|सदस्यांनी}} पहारा दिलेला आहे]",
-       "rc_categories": "वर्गांपुरते मर्यादित ठेवा (\"|\"ने वेगळे करा):",
-       "rc_categories_any": "निवडल्यापैकी कोणतेही",
        "rc-change-size-new": " बदलानंतर $1 {{PLURAL:$1|बाईट|बाईटस्}}",
        "newsectionsummary": "/* $1 */ नवीन विभाग",
        "rc-enhanced-expand": "तपशील दाखवा",
index 058eb5b..74271eb 100644 (file)
        "toc": "Isi kandungan",
        "showtoc": "tunjukkan",
        "hidetoc": "sorokkan",
-       "collapsible-collapse": "Lipat",
-       "collapsible-expand": "Kembangkan",
+       "collapsible-collapse": "Tutup",
+       "collapsible-expand": "Buka",
        "confirmable-confirm": "Pastikah {{GENDER:$1|anda}}?",
        "confirmable-yes": "Ya",
        "confirmable-no": "Tidak",
        "botpasswords-created-title": "Kata laluan bot telah dicipta",
        "botpasswords-created-body": "Kata laluan bot untuk nama bot \"$1\" bagi {{GENDER:$2|pengguna}} \"$2\" telah dicipta.",
        "botpasswords-updated-title": "Kata laluan bot telah dikemaskinikan",
-       "botpasswords-updated-body": "Kata laluan bot untuk nama bot \"$1\" bagi {GENDER:$2|pengguna}} \"$2\" telah dikemaskini.",
+       "botpasswords-updated-body": "Kata laluan bot untuk nama bot \"$1\" bagi {{GENDER:$2|pengguna}} \"$2\" telah dikemaskini.",
        "botpasswords-deleted-title": "Kata laluan bot telah dipadam",
        "botpasswords-deleted-body": "Kata laluan bot untuk nama bot \"$1\" bagi {{GENDER:$2|pengguna}} \"$2\" telah dipadam.",
        "botpasswords-newpassword": "Kata laluan baru untuk log masuk dengan <strong>$1</strong> adalah <strong>$2</strong>. <em>Sila catatkan ini untuk rujukan masa depan.</em> <br> (Untuk bot-bot lama yang memerlukan nama log masuk agar sama dengan nama pengguna akhirnya, anda juga boleh menggunakan <strong>$3</strong> sebagai nama pengguna dan <strong>$4</strong> sebagai kata laluan.)",
        "newarticle": "(Baru)",
        "newarticletext": "Anda telah mengikuti pautan ke laman yang belum wujud.\nUntuk mencipta laman ini, sila taip dalam kotak di bawah\n(lihat [$1 laman bantuan] untuk maklumat lanjut).\nJika anda tiba di sini secara tak sengaja, hanya klik butang '''back''' pada pelayar anda.",
        "anontalkpagetext": "<em>Ini ialah laman perbincangan bagi pengguna tanpa nama yang belum membuka akaun atau tidak menggunakannya.</em>\nOleh itu, kami terpaksa menggunakan alamat IP angka untuk mengenal pasti pengguna tersebut. Alamat IP ini boleh dikongsi oleh ramai pengguna.\nSekiranya anda ialah seorang pengguna tanpa nama dan berasa bahawa komen yang tidak relevan telah ditujukan kepada anda, sila [[Special:CreateAccount|buka akaun baru]] atau [[Special:UserLogin|log masuk]] untuk mengelakkan sebarang kekeliruan dengan pengguna tanpa nama yang lain.",
-       "noarticletext": "Laman ini buat masa sekarang tidak berteks. Anda boleh [[Special:Search/{{PAGENAME}}|cari tajuk bagi laman ini]] dalam laman-laman lain, <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} cari log-log yang berkaitan], atau [{{fullurl:{{FULLPAGENAME}}|action=edit}} sunting laman ini]</span>.",
+       "noarticletext": "Laman ini tiada teks buat masa sekarang.\nAnda boleh [[Special:Search/{{PAGENAME}}|cari tajuk bagi laman ini]] di laman-laman lain, <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} cari log-log yang berkaitan], atau [{{fullurl:{{FULLPAGENAME}}|action=edit}} sunting laman ini]</span>.",
        "noarticletext-nopermission": "Tiada teks dalam laman ini ketika ini.\nAnda boleh [[Special:Search/{{PAGENAME}}|mencari tajuk laman ini]] dalam laman lain,\natau <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} mencari log yang berkaitan]</span>.",
        "missing-revision": "Semakan #$1 pada halaman \"{{FULLPAGENAME}}\" tidak wujud.\n\nHal ini biasanya disebabkan oleh pautan sejarah yang lapuk ke halaman yang sudah dihapuskan.\nButirannya boleh didapati di [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} log penghapusan].",
        "userpage-userdoesnotexist": "Akaun pengguna \"<nowiki>$1</nowiki>\" tidak berdaftar. Sila pastikan sama ada anda mahu mencipta/menyunting laman ini.",
        "postedit-confirmation-created": "Halaman telah diwujudkan.",
        "postedit-confirmation-restored": "Halaman telah dipulihkan.",
        "postedit-confirmation-saved": "Suntingan anda telah disimpan.",
+       "postedit-confirmation-published": "Suntingan anda telah disiarkan.",
        "edit-already-exists": "Tidak dapat mencipta laman baru kerana ia telah wujud.",
        "defaultmessagetext": "Teks mesej asal",
        "content-failed-to-parse": "Kandungan $2 tidak dapat dihuraikan untuk model $1: $3",
        "invalid-content-data": "Data kandungan tidak sah",
        "content-not-allowed-here": "Kandungan \"$1\" tidak dibenarkan di halaman [[$2]]",
        "editwarning-warning": "Meninggalkan laman ini mungkin akan menyebabkan sebarang perubahan yang telah anda lakukan hilang.\nJika anda sudah log masuk, anda boleh melumpuhkan amaran ini di bahagian \"{{int:prefs-editing}}\" dalam keutamaan anda.",
+       "editpage-invalidcontentmodel-title": "Model kandungan tidak disokong",
+       "editpage-invalidcontentmodel-text": "Model kandungan \"$1\" tidak disokong.",
        "editpage-notsupportedcontentformat-title": "Format kandungan tidak disokong",
        "editpage-notsupportedcontentformat-text": "Format kandungan $1 tidak disokong oleh model kandungan $2.",
        "content-model-wikitext": "wikiteks",
        "mergehistory-empty": "Tiada semakan yang boleh digabungkan",
        "mergehistory-done": "$3 semakan bagi $1 telah digabungkan ke dalam [[:$2]].",
        "mergehistory-fail": "Gagal melaksanakan penggabungan sejarah, sila semak semula laman tersebut dan parameter waktu.",
+       "mergehistory-fail-bad-timestamp": "Cap masa tidak sah.",
+       "mergehistory-fail-invalid-source": "Halaman asal tidak sah.",
+       "mergehistory-fail-invalid-dest": "Halaman tujuan tidak sah.",
        "mergehistory-fail-toobig": "Tidak dapat melakukan gabungan sejarah sebab lebih daripada had $1 semakan perlu dipindahkan.",
        "mergehistory-no-source": "Laman sumber $1 tidak wujud.",
        "mergehistory-no-destination": "Laman destinasi $1 tidak wujud.",
        "searchprofile-advanced-tooltip": "Cari dalam ruang nama yang tersuai",
        "search-result-size": "$1 ({{PLURAL:$2|$2 patah perkataan}})",
        "search-result-category-size": "$1 {{PLURAL:$1|ahli|ahli}} ($2 {{PLURAL:$2|subkategori|subkategori}}, $3 {{PLURAL:$3|fail|fail}})",
-       "search-redirect": "(pelencongan $1)",
+       "search-redirect": "(lencongan dari $1)",
        "search-section": "(bahagian $1)",
        "search-category": "(kategori $1)",
        "search-file-match": "(sepadan dengan kandungan fail)",
        "search-interwiki-caption": "Hasil dari projek lain",
        "search-interwiki-default": "Hasil dari $1:",
        "search-interwiki-more": "(lagi)",
+       "search-interwiki-more-results": "hasil-hasil selanjutnya",
        "search-relatedarticle": "Berkaitan",
        "searchrelated": "berkaitan",
        "searchall": "semua",
        "username": "{{GENDER:$1|Nama pengguna}}:",
        "prefs-memberingroups": "{{GENDER:$2|Ahli}} {{PLURAL:$1|kumpulan|kumpulan-kumpulan}}:",
        "prefs-memberingroups-type": "$1",
+       "group-membership-link-with-expiry": "$1 (hingga $2)",
        "prefs-registration": "Waktu pendaftaran:",
        "prefs-registration-date-time": "$1",
        "yourrealname": "Nama sebenar:",
        "grant-editmywatchlist": "Sunting senarai pantau anda",
        "grant-editpage": "Sunting laman sedia ada",
        "grant-editprotected": "Sunting laman yang dilindungi",
+       "grant-uploadfile": "Muat naik fail baru",
+       "grant-basic": "Hak-hak asas",
        "newuserlogpage": "Log akaun baru",
        "newuserlogpagetext": "Yang berikut ialah log penciptaan pengguna.",
        "rightslog": "Log hak pengguna",
        "rcfilters-other-review-tools": "Alat semakan lain",
        "rcfilters-activefilters": "Penapis yang aktif",
        "rcfilters-savedqueries-defaultlabel": "Penapis yang disimpan",
+       "rcfilters-savedqueries-setdefault": "Tetapkan sebagai asali",
+       "rcfilters-savedqueries-unsetdefault": "Gugurkan sebagai asali",
+       "rcfilters-savedqueries-remove": "Gugurkan",
+       "rcfilters-savedqueries-new-name-label": "Nama",
        "rcfilters-savedqueries-add-new-title": "Simpan tetapan penapis terkini",
        "rcfilters-filter-humans-label": "Manusia (bukan bot)",
        "rcfilters-filter-pageedits-label": "Suntingan laman",
        "boteditletter": "b",
        "unpatrolledletter": "!",
        "number_of_watching_users_pageview": "[$1 pemantau]",
-       "rc_categories": "Hadkan kepada kategori (asingkan dengan \"|\")",
-       "rc_categories_any": "Mana-mana yang terpilih",
        "rc-change-size": "$1",
        "rc-change-size-new": "$1 bait selepas perubahan",
        "newsectionsummary": "/* $1 */ bahagian baru",
index 5202c2e..55f3314 100644 (file)
        "newpageletter": "Ġ",
        "boteditletter": "b",
        "number_of_watching_users_pageview": "[osservat minn {{PLURAL:$1|$1 utent|$1 utent}}]",
-       "rc_categories": "Illimita għall-kategoriji (issepara b' \"|\")",
-       "rc_categories_any": "Kwalunkwe",
        "rc-change-size-new": "$1 {{PLURAL:$1|byte|bytes}} wara l-modifika",
        "newsectionsummary": "/* $1 */ sezzjoni ġdida",
        "rc-enhanced-expand": "Uri d-dettalji",
index 6729c10..8571dbd 100644 (file)
        "minoreditletter": "m",
        "newpageletter": "N",
        "boteditletter": "b",
-       "rc_categories_any": "Qualquiera de ls scolhidos",
        "rc-change-size-new": "$1 {{PLURAL:$1|byte|bytes}} açpuis las altaraçones",
        "newsectionsummary": "/* $1 */ nuobo cacho",
        "rc-enhanced-expand": "Amostrar detailhes",
index e78a52f..2a2b710 100644 (file)
        "newpageletter": "အသစ်",
        "boteditletter": "ဘော့",
        "number_of_watching_users_pageview": "[စောင့်ကြည့်နေသော အသုံးပြုသူ $1 {{PLURAL:$1|ဦး|ဦး}}]",
-       "rc_categories": "ကဏ္ဍများအား ကန့်သတ်ရန် (\"|\" ဖြင့် ခွဲခြား):",
-       "rc_categories_any": "ရွေးချယ်ခံရသော မည်သူမဆို",
        "rc-change-size-new": "$1 {{PLURAL:$1|byte|bytes}} ပြောင်းလဲပြီးနောက်",
        "newsectionsummary": "/* $1 */ အပိုင်းသစ်",
        "rc-enhanced-expand": "အသေးစိတ် ပြရန်",
index 41b957e..a13b456 100644 (file)
        "minoreditletter": "а",
        "newpageletter": "О",
        "boteditletter": "б",
-       "rc_categories_any": "Кочказетнень эйстэ кодамо-понгсь",
        "rc-change-size-new": "Полавтнемадонть мейле {{PLURAL:$1|байттнэде}}: $1",
        "newsectionsummary": "/* $1 */ од пелькс",
        "rc-enhanced-expand": "Невтемс седе ламо тень ланга",
index 7776556..19efe88 100644 (file)
        "newpageletter": "Y",
        "boteditletter": "T",
        "number_of_watching_users_pageview": "[$1 tlatequitiltilīlli {{PLURAL:$1|tlachiya|tlachiyah}}]",
-       "rc_categories_any": "Zāzo in tlaihittalli",
        "newsectionsummary": "Yancuīc tlahtōltzintli: /* $1 */",
        "recentchangeslinked": "Tlapatlaliztli tzonhuilizpan",
        "recentchangeslinked-feed": "Tlapatlaliztli tzonhuilizpan",
index 82c49f0..4bec17e 100644 (file)
        "search-section": "(toān-lo̍h $1)",
        "searchall": "choân-pō·",
        "showingresults": "Ē-kha tùi #<b>$2</b> khai-sí hián-sī <b>$1</b> hāng kiat-kó.",
+       "search-showingresults": "{{PLURAL:$4|<strong>$3</strong> ê kiat-kó <strong>$1</strong>|<strong>$3</strong> ê kiat-kó <strong>$1 – $2</strong>}}",
        "search-nonefound": "Chhoē m̄ tio̍h",
        "powersearch-legend": "Kiám-sek",
        "preferences": "Siat-tēng",
        "recentchangeslinked-title": "kap \"$1\" siong-koan ê kái-piàn",
        "recentchangeslinked-summary": "這是有相接到指定頁(抑是指定分類的所有成員),而且最近家己頁的內容有改過的清單。\n遐的頁[[Special:Watchlist|佇你的監視清單]]會用<strong>粗體</strong> 標示。",
        "recentchangeslinked-page": "Ia̍h ê miâ:",
+       "recentchangeslinked-to": "Ōaⁿ chò tián-sī liân kòe chí-tēng ia̍h-bīn ê ia̍h-bīn ê kái-piàn",
        "upload": "Kā tóng-àn chiūⁿ-bāng",
        "uploadbtn": "Kā tóng-àn chiūⁿ-bāng",
        "reuploaddesc": "Tò khì sàng-chiūⁿ-bāng ê pió.",
        "metadata-fields": "佇顯示圖片的頁,若掀開元資料,下跤的EXIF資料會儂看著。其他的元資料是先看無。\n* 廠商\n* 機型\n* 翕像的時陣\n* 曝光\n* 光圈\n* ISO 速率\n* 焦距\n* 作者\n* 版權\n* 說明\n* 緯度(GPS)\n* 經度(GPS)\n* 海拔(GPS)",
        "exif-xresolution": "Chúi-pêⁿ kái-siōng-tō͘",
        "exif-yresolution": "Sûi-ti̍t kái-siōng-tō͘",
+       "exif-datetime": "Tóng-àn kái-piàn ê ji̍t-chí kap sî-kan",
        "exif-software": "Sú-iōng ê nńg-thé",
        "exif-colorspace": "Sek-chhái khong-kan",
        "namespacesall": "choân-pō·",
index 61e4403..d8cd8f6 100644 (file)
        "newpageletter": "N",
        "boteditletter": "b",
        "number_of_watching_users_pageview": "[osservata 'a {{PLURAL:$1|n'utente|$1 utente}}]",
-       "rc_categories": "Lemmeta a 'e categurìe (spartute 'a \"|\"):",
-       "rc_categories_any": "Qualunque d' 'e scigliute",
        "rc-change-size-new": "$1 {{PLURAL:$1|byte|byte}} aropp'ô cagnamiento",
        "newsectionsummary": "/* $1 */ sezziona nnova",
        "rc-enhanced-expand": "Fa vede dettaglie",
index dd522a1..276c072 100644 (file)
        "newpageletter": "N",
        "boteditletter": "b",
        "number_of_watching_users_pageview": "[$1 overvåkende {{PLURAL:$1|bruker|brukere}}]",
-       "rc_categories": "Begrens til kategorier (skilletegn: «|»)",
-       "rc_categories_any": "Alle",
        "rc-change-size-new": "$1 {{PLURAL:$1|byte|bytes}} etter endring",
        "newsectionsummary": "/* $1 */ ny seksjon",
        "rc-enhanced-expand": "Vis detaljer",
index a3c2e33..b621163 100644 (file)
        "printableversion": "Aofdrokbaore versie",
        "permalink": "Vaste verwiezing",
        "print": "Aofdrokken",
-       "view": "Lezen",
+       "view": "Leasen",
        "view-foreign": "Bekieken op $1",
        "edit": "Bewarken",
        "edit-local": "Lokale beschrieving bewarken",
        "talkpagelinktext": "Overleg",
        "specialpage": "Spesiale zied",
        "personaltools": "Persoonlike instellingen",
-       "talk": "Overleg",
+       "talk": "Oaverleg",
        "views": "Weergaven",
        "toolbox": "Hulpmiddels",
        "imagepage": "Bestaandszied bekieken",
        "nstab-template": "Mal",
        "nstab-help": "Hulpe",
        "nstab-category": "Kategorie",
-       "mainpage-nstab": "Veurblad",
+       "mainpage-nstab": "Vöärblad",
        "nosuchaction": "De op-egeven haandeling besteet niet",
        "nosuchactiontext": "De opdrachte in t webadres in ongeldig.\nJe hebben t webadres misschien verkeerd in-etikt of de verkeerde verwiezing evolgd.\nDit kan oek dujen op n fout in de programmatuur van {{SITENAME}}.",
        "nosuchspecialpage": "Der besteet gien spesiale zied mit disse naam",
        "boteditletter": "B",
        "unpatrolledletter": "!",
        "number_of_watching_users_pageview": "[$1 {{PLURAL:$1|keer|keer}} op n volglieste]",
-       "rc_categories": "Beparking tot kategorieën (scheien mit \"|\")",
-       "rc_categories_any": "alles",
        "rc-change-size-new": "$1 {{PLURAL:$1|byte|bytes}} nao de wieziging",
        "newsectionsummary": "Niej onderwarp: /* $1 */",
        "rc-enhanced-expand": "Details bekieken",
        "feedback-subject": "Onderwarp:",
        "feedback-submit": "Opslaon",
        "feedback-thanks": "Bedankt! Joew kommentaar is op de zied \"[$2 $1]\" ezet.",
-       "searchsuggest-search": "{{SITENAME}} deurzeuken",
+       "searchsuggest-search": "{{SITENAME}} döärsöken",
        "searchsuggest-containing": "bevat...",
        "api-error-badtoken": "Interne fout: t token klopt niet.",
        "api-error-emptypage": "Je maggen gien lege nieje ziejen anmaken.",
index 19a85d0..e71366a 100644 (file)
        "newpageletter": "N",
        "boteditletter": "B",
        "number_of_watching_users_pageview": "[{{PLURAL:$1|Een Bruker|$1 Brukers}}, de oppasst]",
-       "rc_categories": "Blot Sieden ut de Kategorien (trennt mit „|“):",
-       "rc_categories_any": "All",
        "rc-change-size-new": "$1 {{PLURAL:$1|byte|bytes}} achter Ännern",
        "newsectionsummary": "/* $1 */ nee Afsnitt",
        "rc-enhanced-expand": "Details wiesen (bruukt JavaScript)",
index de3b42e..3a53657 100644 (file)
        "boteditletter": "बो",
        "unpatrolledletter": "!",
        "number_of_watching_users_pageview": "[$1 निगरानी गर्दै{{PLURAL:$1|प्रयोगकर्ता|प्रयोगकर्ताहरु}}]",
-       "rc_categories": "श्रेणीहरूमा सीमित (\"|\" ले छुट्याउनुहोस्)",
-       "rc_categories_any": "छानिएका कुनै",
        "rc-change-size": "$1",
        "rc-change-size-new": "परिवर्तनपछि $1 {{PLURAL:$1|बाइट|बाइट}}",
        "newsectionsummary": "/* $1 */ नयाँ खण्ड",
index fc0f156..a6d0fad 100644 (file)
@@ -9,7 +9,8 @@
                        "McDutchie",
                        "Romaine",
                        "Mainframe98",
-                       "Mar(c)"
+                       "Mar(c)",
+                       "Robin van der Vliet"
                ]
        },
        "view-pool-error": "De servers zijn op het moment helaas overbelast.\nTe veel gebruikers proberen deze pagina te bekijken.\nWacht even voordat je opnieuw toegang probeert te krijgen tot deze pagina.\n\n$1",
        "prefs-help-variant": "Jouw voorkeursvariant of -spelling om de inhoudspagina's van deze wiki in weer te geven.",
        "prefs-help-signature": "Reacties op de overlegpagina's worden meestal ondertekend met \"<nowiki>~~~~</nowiki>\".\nDe tildes worden omgezet in je ondertekening en een datum en tijd van de bewerking.",
        "badsiglength": "Je ondertekening is te lang.\nDeze moet minder dan $1 {{PLURAL:$1|teken|tekens}} bevatten.",
+       "gender-unknown": "De software gebruikt waar mogelijk geslachtsneutrale woorden als het over je gaat",
        "prefs-help-realname": "Echte naam is optioneel.\nAls je deze opgeeft, kan deze naam gebruikt worden om je erkenning te geven voor je werk.",
        "prefs-help-email": "E-mailadres is optioneel, maar maakt het mogelijk om jou je wachtwoord te e-mailen als je het bent vergeten.",
        "prefs-help-email-others": "Je kunt ook anderen in staat stellen per e-mail contact met je op te nemen via een koppeling op uw gebruikers- en overlegpagina zonder dat je je identiteit prijsgeeft.",
index 8fa9c61..48620c4 100644 (file)
        "newpageletter": "N",
        "boteditletter": "b",
        "number_of_watching_users_pageview": "[$1 {{PLURAL:$1|keer|keer}} op een volglijst]",
-       "rc_categories": "Beperken tot categorieën (scheiden met een \"|\"):",
-       "rc_categories_any": "Een van de gekozen",
        "rc-change-size-new": "$1 {{PLURAL:$1|byte|bytes}} na de wijziging",
        "newsectionsummary": "/* $1 */ nieuwe subkop",
        "rc-enhanced-expand": "Details weergeven",
        "watchlistedit-clear-titles": "Pagina's:",
        "watchlistedit-clear-submit": "Volglijst wissen (dit is definitief!)",
        "watchlistedit-clear-done": "Uw volglijst is gewist.",
+       "watchlistedit-clear-jobqueue": "Uw volglijst wordt leeggemaakt. Dit kan enige tijd duren!",
        "watchlistedit-clear-removed": "Er {{PLURAL:$1|is 1 pagina|zijn $1 pagina's}} verwijderd:",
        "watchlistedit-too-many": "Er zijn te veel pagina's om hier weer te geven.",
        "watchlisttools-clear": "Volglijst wissen",
index bf46ac3..17925d6 100644 (file)
        "newpageletter": "n",
        "boteditletter": "b",
        "number_of_watching_users_pageview": "[{{PLURAL:$1|Éin brukar|$1 brukarar}} overvakar]",
-       "rc_categories": "Avgrens til kategoriar (skil med «|»):",
-       "rc_categories_any": "Alle",
        "rc-change-size-new": "$1 {{PLURAL:$1|byte}} etter endringa",
        "newsectionsummary": "/* $1 */ ny bolk",
        "rc-enhanced-expand": "Vis detaljar",
index 6b16255..83fe89c 100644 (file)
        "newpageletter": "N",
        "boteditletter": "b",
        "number_of_watching_users_pageview": "[$1 {{PLURAL:$1|utilizaire seguent|utilizaires seguents}}]",
-       "rc_categories": "Limitar a las categorias (separadas per « | ») :",
-       "rc_categories_any": "Una de las seleccionadas",
        "rc-change-size-new": "$1 {{PLURAL:$1|octet|octets}} aprèp cambiament",
        "newsectionsummary": "/* $1 */ seccion novèla",
        "rc-enhanced-expand": "Vejatz los detalhs",
        "recentchangeslinked-feed": "Seguit dels ligams",
        "recentchangeslinked-toolbox": "Seguit dels ligams",
        "recentchangeslinked-title": "Seguit dels ligams associats a \"$1\"",
-       "recentchangeslinked-summary": "Aquesta pagina especiala fa veire los darrièrs cambiaments sus las paginas que son ligadas. Las paginas de [[Special:Watchlist|vòstra lista de seguimznt]] son '''en gras'''.",
+       "recentchangeslinked-summary": "Entrar un nom de pagina per veire las modificacions faitas recentament sus de paginas ligadas dempuèi o cap a aquesta pagina (per veire los membres d’una categoria, entratz Categoria:Nom de categoria). Las modificacions de las paginas de [[Special:Watchlist|vòstra lista de seguiment]] son <strong>en gras</strong>.",
        "recentchangeslinked-page": "Nom de la pagina :",
        "recentchangeslinked-to": "Afichar los cambiaments cap a las paginas ligadas al luòc de la pagina donada",
        "recentchanges-page-added-to-category": "[[:$1]] apondut a la categoria",
        "unwatchthispage": "Arrestar de seguir",
        "notanarticle": "Pas cap d'article",
        "notvisiblerev": "Version suprimida",
-       "watchlist-details": "I a {{PLURAL:$1|$1 pagina|$1 paginas}} dins vòstra lista de seguiment, sens comptar las paginas de discussion.",
+       "watchlist-details": "{{PLURAL:$1|$1 pagina es|$1 paginas son}} dins vòstra lista de seguiment (amai las paginas de discussion).",
        "wlheader-enotif": "La notificacion per corrièr electronic es activada.",
        "wlheader-showupdated": "Las paginas que son estadas modificadas dempuèi vòstra darrièra visita son afichadas en '''gras'''.",
        "wlnote": "Çaijós {{PLURAL:$1|figura la darrièra modificacion efectuada|figuran las <strong>$1</strong> darrièras modificacions efectuadas}} pendent {{PLURAL:$2|la darrièra ora|las <strong>$2</strong> darrièras oras}}, dempuèi $3, $4.",
index 87afb1e..3fbf2c4 100644 (file)
        "newpageletter": "ନୂଆ",
        "boteditletter": "ବଟ",
        "number_of_watching_users_pageview": "[$1 {{PLURAL:$1|ସଭ୍ୟ|ସଭ୍ୟଗଣା}}ଙ୍କୁ ଦେଖୁଅଛି]",
-       "rc_categories": "ଶ୍ରେଣୀସମୂହ ପାଇଁ ସୀମା ( \"|\" ଦେଇ ଅଲଗା କରିବେ)",
-       "rc_categories_any": "ଯେ କୌଣସି",
        "rc-change-size-new": "ବଦଳ ପରେ $1 {{PLURAL:$1|ବାଇଟ|ବାଇଟସବୁ}}",
        "newsectionsummary": "/* $1 */ ନୂଆ ଭାଗ",
        "rc-enhanced-expand": "ସବିଶେଷ ଦେଖାନ୍ତୁ",
index 1009452..f30e77c 100644 (file)
        "minoreditletter": "ч",
        "newpageletter": "Н",
        "boteditletter": "б",
-       "rc_categories_any": "Кæцы фæнды",
        "newsectionsummary": "/* $1 */ ног хай",
        "rc-enhanced-expand": "Лæмбынæг информаци равдисын",
        "rc-enhanced-hide": "Айсын лæмбынæг информаци",
index a3fad60..2460fdc 100644 (file)
        "newpageletter": "ਨ",
        "boteditletter": "ਬੋਟ",
        "number_of_watching_users_pageview": "[$1 ਵੇਖ ਰਹੇ ਹਨ {{PLURAL:$1|ਯੂਜ਼ਰ}}]",
-       "rc_categories_any": "ਚੁਣੇ ਹੋਇਅਾਂ ਵਿੱਚੋਂ ਕੋਈ ਵੀ",
        "rc-change-size-new": "$1 {{PLURAL:$|ਬਾਈਟ|ਬਾਈਟਾਂ}} ਤਬਦੀਲੀ ਤੋਂ ਬਾਅਦ",
        "newsectionsummary": "/* $1 */ ਨਵਾਂ ਭਾਗ",
        "rc-enhanced-expand": "ਵੇਰਵੇ ਵੇਖਾਓ",
index e75d87d..21f57d3 100644 (file)
        "newpageletter": "B",
        "boteditletter": "b",
        "number_of_watching_users_pageview": "[$1 lalbe {{PLURAL:$1|talagamit|talagamit}}]",
-       "rc_categories": "Angganan/limitasiun da reng kategoriya (pikawani la king \"|\")",
-       "rc_categories_any": "Andyang sanu",
        "newsectionsummary": "/* $1 */ bayung seksiyon/dake",
        "rc-enhanced-expand": "Pakit la reng detalle (mangailangan yang JavaScript)",
        "rc-enhanced-hide": "Isalikut la reng detalle",
index 4f526d1..97b1427 100644 (file)
        "minoreditletter": "g",
        "newpageletter": "N",
        "boteditletter": "W",
-       "rc_categories_any": "All",
        "rc-change-size-new": "$1 {{PLURAL:$1|Beit|Beit}} nooch daer Ennering",
        "newsectionsummary": "Neier Abschnitt /* $1 */",
        "recentchangeslinked": "Was on verlinkde Bledder geduh warre iss",
index f5807e4..fd24862 100644 (file)
        "minoreditletter": "k",
        "newpageletter": "N",
        "boteditletter": "B",
-       "rc_categories": "Oigschrengd uff Sachgrubbe (abgdeeld middm \"|\")",
-       "rc_categories_any": "Ebbes",
        "rc-change-size-new": "$1 {{PLURAL:$1|Byte}} nochde Ännarung",
        "rc-enhanced-expand": "Änzlhaide zaische",
        "rc-enhanced-hide": "Oagawe vaschdeggle",
index f602865..efcb32e 100644 (file)
        "newpageletter": "N",
        "boteditletter": "b",
        "number_of_watching_users_pageview": "[$1 {{PLURAL:$1|obserwujący użytkownik|obserwujących użytkowników}}]",
-       "rc_categories": "Ogranicz do kategorii (oddzielaj za pomocą „|”)",
-       "rc_categories_any": "Dowolna z wybranych",
        "rc-change-size-new": "$1 {{PLURAL:$1|bajt|bajty|bajtów}} po zmianie",
        "newsectionsummary": "/* $1 */ nowa sekcja",
        "rc-enhanced-expand": "Pokaż szczegóły",
index 9f03ec0..9644648 100644 (file)
        "newpageletter": "N",
        "boteditletter": "t",
        "number_of_watching_users_pageview": "[tnùa sot-euj da {{PLURAL:$1|n'utent|$1 utent}}]",
-       "rc_categories": "Limité a le categorìe (che a jë scriva separand-je antra 'd lor con un \"|\"):",
-       "rc_categories_any": "Un-a qualsëssìa ëd cole selessionà",
        "rc-change-size-new": "$1 {{PLURAL:$1|byte|byte}} apress ij cambi",
        "newsectionsummary": "/* $1 */ session neuva",
        "rc-enhanced-expand": "Mostré ij detaj",
index afc7d6b..ffcd741 100644 (file)
        "newpageletter": "نواں",
        "boteditletter": "بوٹ",
        "number_of_watching_users_pageview": "[ $1 ویکھ رہیا اے{{PLURAL:$1|ورتن والا|والے}}]",
-       "rc_categories": "گٹھاں دی حد (وکھرے کرو \"|\")",
-       "rc_categories_any": "کوئی",
        "rc-change-size-new": "$1 {{PLURAL:$1|بائٹ|بائٹاں}} تبدیلی مگروں",
        "newsectionsummary": "/* $1 */ نواں پاسہ",
        "rc-enhanced-expand": "تفضیل وکھاؤ (جاوا سکرپٹ چائیدا اے)",
        "autosumm-replace": "\"$1\" نال مواد بدلو",
        "autoredircomment": "صفے نوں [[$1]] ول ریڈائرکٹ کرو",
        "autosumm-new": "\"$1\" نال صفہ بنایا گیا۔",
+       "autosumm-newblank": "خالی صفحہ بنایا",
        "lag-warn-normal": "$1 توں نویاں تبدیلیاں {{PLURAL:$1|سکنٹ}}",
        "lag-warn-high": "تیز ڈیٹاسرور لاگ ، $1 توں نویاں تبدیلیاں {{PLURAL:$1|سکنٹ|سکنٹ}} ہوسکدا اے ایس لسٹ ناں دسے جان۔",
        "watchlistedit-normal-title": " اکھ تھلے رکھی ہوئی نو تبدیل کرو",
index bd423a5..c28659a 100644 (file)
        "minoreditletter": "μ",
        "newpageletter": "Ν",
        "boteditletter": "b",
-       "rc_categories_any": "Κάθαν",
        "rc-enhanced-expand": "Δείξον λεπτομέρειας (θελ' JavaScript)",
        "rc-enhanced-hide": "Κρύψον λεπτομέρειας",
        "recentchangeslinked": "Σχετικά αλλαγάς",
index a24b37d..f1e170f 100644 (file)
        "newpageletter": "N",
        "boteditletter": "b",
        "number_of_watching_users_pageview": "[$1 {{PLURAL:$1|nadirīnts tērpautajs|nadirīntei tērpautajai}}]",
-       "rc_categories": "Arāikinais prei kategōrijan (izsklaitinnais sen \"|\")",
-       "rc_categories_any": "Wisāi",
        "newsectionsummary": "/* $1 */ naunā sekciōni",
        "rc-enhanced-expand": "Waidinnais malkans (izkīnina JavaScript)",
        "rc-enhanced-hide": "Kliptinais malkans",
index ab90f28..a6c4a99 100644 (file)
        "boteditletter": "ر",
        "unpatrolledletter": "!",
        "number_of_watching_users_pageview": "[$1  {{PLURAL:$1|کتونکی کارن|کتونکي کارنان}}]",
-       "rc_categories": "د وېشنيزو تر بريده (په \"|\" بېلول)",
-       "rc_categories_any": "له ټاکل شويو هر يو",
        "rc-change-size": "$1",
        "rc-change-size-new": "$1 {{PLURAL:$1|بايټ|بايټونه}} د بدلون وروسته",
        "newsectionsummary": "/* $1 */ نوې برخه",
index 3820aa8..8069315 100644 (file)
        "newpageletter": "N",
        "boteditletter": "b",
        "number_of_watching_users_pageview": "[{{PLURAL:$1|$1 usuário|$1 usuários}} vigiando]",
-       "rc_categories": "Limitar às categorias (separar com \"|\"):",
-       "rc_categories_any": "Qualquer um dos escolhidos",
        "rc-change-size-new": "$1 {{PLURAL:$1|byte|bytes}} após alterações",
        "newsectionsummary": "/* $1 */ nova seção",
        "rc-enhanced-expand": "Exibir detalhes",
        "rollback-success": "Edições revertidas por {{GENDER:$3|$1}};\nalterado para a última revisão por {{GENDER:$4|$2}}.",
        "rollback-success-notify": "Revertidas as edições de $1;\nMudança para a última revisão de $2. [$3 Mostrar alterações]",
        "sessionfailure-title": "Erro de sessão",
-       "sessionfailure": "Foram detetados problemas com a sua sessão;\nEsta ação foi cancelada como medida de proteção contra a intercepção de sessões.\nExperimente usar o botão \"Voltar\" e atualizar a página de onde veio e tente novamente.",
+       "sessionfailure": "Parece haver um problema com sua sessão de login;\nEsta ação foi cancelada como uma precaução contra o seqüestro de sessão.\nPor favor, reenvie o formulário.",
        "changecontentmodel": "Alterar o modelo de conteúdo de uma página",
        "changecontentmodel-legend": "Alterar o modelo de conteúdo",
        "changecontentmodel-title-label": "Título da página",
        "watchlistedit-clear-titles": "Títulos:",
        "watchlistedit-clear-submit": "Limpar a lista de páginas vigiadas (Esta ação é permanente!)",
        "watchlistedit-clear-done": "Sua lista de páginas vigiadas foi limpa.",
+       "watchlistedit-clear-jobqueue": "A sua lista de páginas vigiadas está a ser esvaziada. Esta operação pode ser demorada.",
        "watchlistedit-clear-removed": "{{PLURAL:$1|Foi removido um título|Foram removidos $1 títulos}}:",
        "watchlistedit-too-many": "Há muitas páginas para exibir aqui.",
        "watchlisttools-clear": "Limpar a lista de páginas vigiadas",
index a272827..1f15823 100644 (file)
        "newpageletter": "N",
        "boteditletter": "b",
        "number_of_watching_users_pageview": "[{{PLURAL:$1|$1 utilizador|$1 utilizadores}} a vigiar]",
-       "rc_categories": "Limitar às categorias (separar com \"|\"):",
-       "rc_categories_any": "Qualquer dos escolhidos",
        "rc-change-size-new": "$1 {{PLURAL:$1|byte|bytes}} após mudança",
        "newsectionsummary": "/* $1 */ nova secção",
        "rc-enhanced-expand": "Mostrar detalhes",
index f3cbb7b..6a071ed 100644 (file)
                        "Pginer",
                        "Wladek92",
                        "Gombang",
-                       "Trizek (WMF)"
+                       "Trizek (WMF)",
+                       "Acamicamacaraca"
                ]
        },
        "sidebar": "{{notranslate}}",
        "rcfilters-view-tags-help-icon-tooltip": "Tooltip for the help button that leads user to Special:Tags page",
        "rcfilters-liveupdates-button": "Label for the button to enable or disable live updates on [[Special:RecentChanges]]",
        "rcfilters-liveupdates-button-title-on": "Title for the button to enable or disable live updates on [[Special:RecentChanges]] when the feature is ON.",
-       "rcfilters-liveupdates-button-title-off": "Title for the button to enable or disable live updates on [[Special:RecentChanges]] when the feature is OFF.",
+       "rcfilters-liveupdates-button-title-off": "Title for the button to enable or disable live updates on [[Special:RecentChanges]].",
        "rcfilters-watchlist-markseen-button": "Label for the button to mark all changes as seen on [[Special:Watchlist]] when using the structured filters interface.",
        "rcfilters-watchlist-edit-watchlist-button": "Label for the button to edit the watched pages on [[Special:Watchlist]] when using the structured filters interface.\n\nCf. {{msg-mw|watchlisttools-edit}}.",
        "rcfilters-watchlist-showupdated": "Message at the top of [[Special:Watchlist]] when the Structured filters are enabled that describes what unseen changes look like.\n\nCf. {{msg-mw|wlheader-showupdated}}",
        "unpatrolledletter": "{{optional}}\n\nUsed in {{msg-mw|Recentchanges-label-legend}}, meaning \"unpatrolled\".",
        "number_of_watching_users_RCview": "{{notranslate}}\nParameters:\n* $1 - number of users who are watching",
        "number_of_watching_users_pageview": "Used if <code>$wgPageShowWatchingUsers</code> is true.\n* $1 - number of watching user(s)",
-       "rc_categories": "A label of an input box. Appears on Special:RecentChanges if filtering recent changes by category is enabled (that is, $wgAllowCategorizedRecentChanges is set to true).",
-       "rc_categories_any": "Appears ''after'' the input box the label of which is {{msg-mw|rc_categories}}, which appears on [[Special:RecentChanges]], if <code>$wgAllowCategorizedRecentChanges</code> is true. \"Chosen\" refers to categories.",
        "rc-change-size": "{{optional}}\nDoes not work under $wgMiserMode ([[mwr:48986|r48986]]).\n\nParameters:\n* $1 - size of diff",
        "rc-change-size-new": "Tooltip when hovering a change list diff size. Parameters:\n* $1 - the resulting new size (in bytes)",
        "newsectionsummary": "Default summary when adding a new section to a page. Parameters:\n* $1 - section title",
index ab0277a..edf5b8f 100644 (file)
        "newpageletter": "M",
        "boteditletter": "r",
        "number_of_watching_users_pageview": "[$1 watiqachkaq {{PLURAL:$1|ruraq|ruraqkuna}}]",
-       "rc_categories": "Kay katiguriyakunaman saywachay (\"|\" nisqawan rakisqa)",
-       "rc_categories_any": "Imallapas",
        "rc-change-size-new": "$1 {{PLURAL:$1|byte|byte}} hukchasqa kaptinña",
        "newsectionsummary": "Musuq raki: /* $1 */",
        "rc-enhanced-expand": "Imaymanachakunata rikuchiy",
index 30cb14a..fa48180 100644 (file)
        "newpageletter": "N",
        "boteditletter": "B",
        "number_of_watching_users_pageview": "[$1 {{PLURAL:$1|utilisader|utilisaders}} observeschan quest artitgel]",
-       "rc_categories": "Be paginas ord las categorias (seperar cun \"|\")",
-       "rc_categories_any": "Tuts",
        "rc-change-size-new": "$1 {{PLURAL:$1|byte|bytes}} suenter la midada",
        "newsectionsummary": "Nov chapitel /* $1 */",
        "rc-enhanced-expand": "Mussar detagls",
index e4f3e9f..2b8d9e4 100644 (file)
        "boteditletter": "b",
        "unpatrolledletter": "!",
        "number_of_watching_users_pageview": "[$1 {{PLURAL:$1|utilizator|utilizatori|de utilizatori}} care urmăresc]",
-       "rc_categories": "Limitează la categoriile (separate prin „|”):",
-       "rc_categories_any": "Oricare dintre cele alese",
        "rc-change-size": "$1",
        "rc-change-size-new": "$1 {{PLURAL:$1|octet|octeți|de octeți}} după modificare",
        "newsectionsummary": "/* $1 */ secțiune nouă",
index 1c77450..640c040 100644 (file)
        "boteditletter": "b",
        "unpatrolledletter": "!",
        "number_of_watching_users_pageview": "[$1 {{PLURAL:$1|utende|utinde}} ca condrollene]",
-       "rc_categories": "Limite de le categorije (separate cu \"|\")",
-       "rc_categories_any": "Qualsiasi de le scacchiate",
        "rc-change-size": "$1",
        "rc-change-size-new": "$1 {{PLURAL:$1|byte|byte}} apprisse 'u cangiamende",
        "newsectionsummary": "/* $1 */ seziona nove",
index d7c8990..6400afb 100644 (file)
        "boteditletter": "б",
        "unpatrolledletter": "!",
        "number_of_watching_users_pageview": "[$1 {{PLURAL:$1|наблюдающий участник|наблюдающих участника|наблюдающих участников}}]",
-       "rc_categories": "Только из категорий (разделитель «|»):",
-       "rc_categories_any": "Любая из выбранных",
        "rc-change-size-new": "Размер после изменения: $1 {{PLURAL:$1|байт|байта|байт}}",
        "newsectionsummary": "/* $1 */ новая тема",
        "rc-enhanced-expand": "Показать подробности",
        "rollback-success": "Откачены правки {{GENDER:$3|$1}}; возврат к версии {{GENDER:$4|$2}}.",
        "rollback-success-notify": "Откачены правки $1; возврат к последней версии $2. [$3 Показать изменения]",
        "sessionfailure-title": "Ошибка сеанса",
-       "sessionfailure": "Ð\9fоÑ\85оже, Ð²Ð¾Ð·Ð½Ð¸ÐºÐ»Ð¸ Ð¿Ñ\80облемÑ\8b Ñ\81 Ñ\82екÑ\83Ñ\89им Ñ\81еанÑ\81ом Ñ\80абоÑ\82Ñ\8b;\nÑ\8dÑ\82о Ð´ÐµÐ¹Ñ\81Ñ\82вие Ð±Ñ\8bло Ð¾Ñ\82менено Ð² Ñ\86елÑ\8fÑ\85 Ð¿Ñ\80едоÑ\82вÑ\80аÑ\89ениÑ\8f Â«Ð·Ð°Ñ\85ваÑ\82а Ñ\81еанÑ\81а».\nÐ\9fожалÑ\83йÑ\81Ñ\82а, Ð½Ð°Ð¶Ð¼Ð¸Ñ\82е ÐºÐ½Ð¾Ð¿ÐºÑ\83 Â«Ð\9dазад» Ð¸ Ð¿ÐµÑ\80езагÑ\80Ñ\83зиÑ\82е Ñ\81Ñ\82Ñ\80аниÑ\86Ñ\83, Ñ\81 ÐºÐ¾Ñ\82оÑ\80ой Ð²Ñ\8b Ð¿Ñ\80иÑ\88ли.",
+       "sessionfailure": "Ð\9fоÑ\85оже, Ð²Ð¾Ð·Ð½Ð¸ÐºÐ»Ð¸ Ð¿Ñ\80облемÑ\8b Ñ\81 Ñ\82екÑ\83Ñ\89им Ñ\81еанÑ\81ом Ñ\80абоÑ\82Ñ\8b;\nÑ\8dÑ\82о Ð´ÐµÐ¹Ñ\81Ñ\82вие Ð±Ñ\8bло Ð¾Ñ\82менено Ð² Ñ\86елÑ\8fÑ\85 Ð¿Ñ\80едоÑ\82вÑ\80аÑ\89ениÑ\8f Â«Ð·Ð°Ñ\85ваÑ\82а Ñ\81еанÑ\81а».\nÐ\9fожалÑ\83йÑ\81Ñ\82а, Ð¿ÐµÑ\80еоÑ\82пÑ\80авÑ\8cÑ\82е Ñ\84оÑ\80мÑ\83.",
        "changecontentmodel": "Редактирование контентной модели страницы",
        "changecontentmodel-legend": "Изменить модель содержимого",
        "changecontentmodel-title-label": "Заголовок страницы",
        "newimages-newbies": "Показать только вклад, сделанный с новых учётных записей",
        "newimages-showbots": "Показать загрузки ботов",
        "newimages-hidepatrolled": "Скрыть отпатрулированные загрузки",
-       "newimages-mediatype": "Ð\9cедиа Ñ\82ип:",
+       "newimages-mediatype": "Тип Ð¼ÐµÐ´Ð¸Ð°Ñ\84айла:",
        "noimages": "Изображения отсутствуют.",
        "gallery-slideshow-toggle": "Переключить миниатюры",
        "ilsubmit": "Найти",
        "watchlistedit-clear-titles": "Заголовки:",
        "watchlistedit-clear-submit": "Очистить список наблюдения (это необратимо!)",
        "watchlistedit-clear-done": "Ваш список наблюдения очищен.",
+       "watchlistedit-clear-jobqueue": "Ваш список наблюдения очищается. Это может занять некоторое время!",
        "watchlistedit-clear-removed": "{{PLURAL:$1|Была удалена|Были удалены|Было удалено}} $1 {{PLURAL:$1|запись|записи|записей}}:",
        "watchlistedit-too-many": "Слишком много страниц для того, чтобы показать их здесь.",
        "watchlisttools-clear": "Очистить список наблюдения",
        "specialpages-group-other": "Другие служебные страницы",
        "specialpages-group-login": "Представиться / Зарегистрироваться",
        "specialpages-group-changes": "Свежие правки и журналы",
-       "specialpages-group-media": "Отчёты о медиа-материалах и загрузка",
+       "specialpages-group-media": "Отчёты о медиаматериалах и загрузка",
        "specialpages-group-users": "Участники и права",
        "specialpages-group-highuse": "Интенсивно используемые страницы",
        "specialpages-group-pages": "Списки страниц",
        "default-skin-not-found-no-skins": "Упс! Тема оформления по умолчанию для вашей вики <code>$wgDefaultSkin</code>, <code>$1</code> недоступна.\n\nУ вас нет установленных тем оформления.\n\n; Если вы только что установили или обновили MediaWiki:\n: Вы, видимо, сделали это с Git или непосредственно из исходного кода с использованием другого способа. Тогда такое возможно. MediaWiki версии 1.24 и новее не содержат темы оформления в основном репозитории. Попробуйте установить некоторые темы из [https://www.mediawiki.org/wiki/Category:All_skins каталога тем оформления сайта mediawiki.org]:\n:* скачав [https://www.mediawiki.org/wiki/Download архив установочных файлов], который содержит несколько тем оформления и расширений; вы можете скопировать папку <code>skins/</code> из него;\n:* скачав архивы отдельных тем оформления с [https://www.mediawiki.org/wiki/Special:SkinDistributor mediawiki.org];\n:* [https://www.mediawiki.org/wiki/Download_from_Git#Using_Git_to_download_MediaWiki_skins использовав Git для загрузки тем оформления].\n: Это не должно навредить вашему репозиторию Git, если вы разработчик MediaWiki. См. [https://www.mediawiki.org/wiki/Manual:Skin_configuration Manual:Skin configuration] с информацией о том, как включить темы оформления и выбрать тему по умолчанию.",
        "default-skin-not-found-row-enabled": "* <code>$1</code> / $2 (включено)",
        "default-skin-not-found-row-disabled": "* <code>$1</code> / $2 (<strong>отключено</strong>)",
-       "mediastatistics": "Ð\9cедиа-Ñ\81Ñ\82аÑ\82иÑ\81Ñ\82ика",
+       "mediastatistics": "СÑ\82аÑ\82иÑ\81Ñ\82ика Ð¼ÐµÐ´Ð¸а",
        "mediastatistics-summary": "Статистические данные о типах загруженных файлов. Она включает информацию только о последних версиях файлов. Более старые или удалённые версии файлов не учитываются.",
        "mediastatistics-nfiles": "$1 ($2%)",
        "mediastatistics-nbytes": "$1 {{PLURAL:$1|байт|байта|байт}} ($2; $3%)",
index 712c93e..2eb7f44 100644 (file)
        "newpageletter": "Н",
        "boteditletter": "б",
        "number_of_watching_users_pageview": "[$1 {{PLURAL:$1|слїдуючій хоснователь|слїдуючі хоснователї|слїдуючіх хоснователїв}}]",
-       "rc_categories": "Лем з катеґорій (роздїлёвач «|»)",
-       "rc_categories_any": "Будь-якый",
        "rc-change-size-new": "$1 {{PLURAL:$1|байтt|байты|байтів}} по змінї",
        "newsectionsummary": "/* $1 */ нова секція",
        "rc-enhanced-expand": "Вказати детайлы",
index 666f91a..0c2f265 100644 (file)
        "newpageletter": "(नवीनम्)",
        "boteditletter": "(बोट्)",
        "number_of_watching_users_pageview": "[$1 अवलोकयति {{PLURAL:$1|सदस्यः|सदस्याः}}]",
-       "rc_categories": "वर्गान् नियतीकरोतु ।",
-       "rc_categories_any": "कश्चित्",
        "rc-change-size-new": "$1 {{PLURAL:$1|byte|bytes}} परिवर्तनपश्चात् ।",
        "newsectionsummary": "/* $1 */ नवीनविभागः",
        "rc-enhanced-expand": "विवरणानि दृश्यन्ताम्",
index 55494e2..5820e6e 100644 (file)
        "newpageletter": "С",
        "boteditletter": "р",
        "number_of_watching_users_pageview": "[$1 кэтиир {{PLURAL:$1|кыттааччы|кыттааччылар}}]",
-       "rc_categories": "Бу эрэ категориялартан (араарар бэлиэ \"|\")",
-       "rc_categories_any": "Талыллыбыттан хайата баҕарар",
        "rc-change-size-new": "Уларытыы кээмэйэ: $1 баайт",
        "newsectionsummary": "/* $1 */ саҥа сиэксийэ",
        "rc-enhanced-expand": "Сиһилии көрдөр",
index ac93b67..6f3fefc 100644 (file)
        "minoreditletter": "m",
        "newpageletter": "N",
        "boteditletter": "b",
-       "rc_categories_any": "Calesisiat",
        "rc-change-size": "$1",
        "rc-change-size-new": "$1 {{PLURAL:$1|byte|bytes}} a pustis de sa modìfica",
        "newsectionsummary": "/* $1 */ setzione noa",
index ca6b172..d2c3b55 100644 (file)
        "newpageletter": "N",
        "boteditletter": "b",
        "number_of_watching_users_pageview": "[taliata di {{PLURAL:$1|nu utenti|$1 utenti}}]",
-       "rc_categories": "Lìmita a li catigurìi (spartuti cu «|»)",
-       "rc_categories_any": "Qualegghiè tra chiddi scigghiuti",
        "rc-change-size-new": "$1 {{PLURAL:$1|byte|byte}} appressu dû canciamentu",
        "newsectionsummary": "/* $1 */ sizzioni nova",
        "rc-enhanced-expand": "Ammustra li dittagghî",
index c6d54eb..c58040b 100644 (file)
        "newpageletter": "N",
        "boteditletter": "b",
        "number_of_watching_users_pageview": "[$1 watchin {{PLURAL:$1|uiser|uisers}}]",
-       "rc_categories": "Leemit tae categories (separate wi \"|\"):",
-       "rc_categories_any": "Ony o the chosen",
        "rc-change-size-new": "$1 {{PLURAL:$1|byte|bytes}} efter chynge",
        "newsectionsummary": "/* $1 */ new section",
        "rc-enhanced-expand": "Shaw details",
index 5983959..e23d82d 100644 (file)
        "boteditletter": "گ",
        "unpatrolledletter": "!",
        "number_of_watching_users_pageview": "[$1 {{PLURAL:$1|واپرائيندڙ|واپرائيندڙن}} کي نظر ۾ رکندي]",
-       "rc_categories_any": "چونڊيلن مان ڪو بہ",
        "rc-change-size-new": "$1 {{PLURAL:$1|بائيٽ|بائيٽس}} تبديليءَ کانپوءِ",
        "newsectionsummary": "/* $1 */ نئون سيڪشن",
        "rc-enhanced-expand": "تفصيل ڏيکاريو",
index 180e320..93a1a40 100644 (file)
        "newpageletter": "N",
        "boteditletter": "b",
        "number_of_watching_users_pageview": "[abbaidadda da {{PLURAL:$1|un'utenti|$1 utenti}}]",
-       "rc_categories": "Limita a li categuri (siparaddi da \"|\")",
-       "rc_categories_any": "Cassisia",
        "newsectionsummary": "/* $1 */ noba sezzioni",
        "rc-enhanced-expand": "Musthrà dettagli (dumanda JavaScript)",
        "rc-enhanced-hide": "Cua dettàgli",
index 9f53e48..901b15a 100644 (file)
        "minoreditletter": "u",
        "newpageletter": "O",
        "number_of_watching_users_pageview": "[$1 čuovvujeaddji geavaheaddji]",
-       "rc_categories": "Beare luohkáin (earuheaddji lea ”|”)",
-       "rc_categories_any": "Mii beare",
        "recentchangeslinked": "Dán siiddu varas rievdadusat",
        "recentchangeslinked-feed": "Dán siiddu varas rievdadusat",
        "recentchangeslinked-toolbox": "Dán siiddu varas rievdadusat",
index bfa6b5e..1436537 100644 (file)
        "newpageletter": "H",
        "boteditletter": "R",
        "number_of_watching_users_pageview": "[$1 cait(o/ó)m cáminot]",
-       "rc_categories": "Limitde cayliíb (separatman \"|\" mii)",
-       "rc_categories_any": "Jömde pac",
        "newsectionsummary": "/* $1 */ hunseccion",
        "recentchangeslinked": "Quiix hámíigonix",
        "recentchangeslinked-feed": "Quiix hámíigonix",
index f629d11..da31a63 100644 (file)
        "boteditletter": "b",
        "unpatrolledletter": "!",
        "number_of_watching_users_pageview": "[$1 goo ma {{PLURAL:$1|goykaa|goykey}} guna]",
-       "rc_categories": "Kayandi dumey ga (i fay nda \"|\")",
-       "rc_categories_any": "Affoo kul",
        "rc-change-size": "$1",
        "rc-change-size-new": "{{PLURAL:$1|cebsi}} $1 barmaa banda ga",
        "newsectionsummary": "/* $1 */ dunbu taaga",
index 392a55b..2ebb63a 100644 (file)
        "newpageletter": "N",
        "boteditletter": "r",
        "number_of_watching_users_pageview": "[$1 {{PLURAL:$1|keravuojontis nauduotuos|keravuojontīs nauduotuojē|keravuojontiu nauduotuoju}}]",
-       "rc_categories": "Ruodītė tėk tas kateguorėjės (atskirkat nauduojont „|“)",
-       "rc_categories_any": "Bikuokė",
        "rc-change-size-new": "$1 {{PLURAL:$1|baits|baitā|baitu}} pu pakeitėma",
        "newsectionsummary": "/* $1 */ naus skėrsnelis",
        "rc-enhanced-expand": "Ruodītė smolkmenas",
index 3f0065f..ca5597b 100644 (file)
        "newpageletter": "N/Н",
        "boteditletter": "b",
        "number_of_watching_users_pageview": "[$1 {{PLURAL:$1|korisnik|korisnika}} koji pregledaju]",
-       "rc_categories": "Ograniči na kategorije (razdvoji sa \"|\"):",
-       "rc_categories_any": "Bilo koju odabranu",
        "rc-change-size-new": "$1 {{PLURAL:$1|bajt|bajta|bajtova}} posle izmene",
        "newsectionsummary": "/* $1 */ nova sekcija",
        "rc-enhanced-expand": "Pokaži detalje",
        "feedback-subject": "Tema:",
        "feedback-submit": "Unesi",
        "feedback-thanks": "Hvala! Vaša povratna informacija je postavljena na stranicu „[$2 $1]“.",
-       "searchsuggest-search": "Traži",
+       "searchsuggest-search": "Traži {{GRAMMAR:akuzativ|{{SITENAME}}}}",
        "searchsuggest-containing": "sadrži...",
        "api-error-badtoken": "Unutrašnja greška: token nije ispravan.",
        "api-error-emptypage": "Stvaranje novih praznih stranica nije dozvoljeno.",
index 38894c0..7d7adf5 100644 (file)
        "boteditletter": "ⴱ",
        "unpatrolledletter": "!",
        "number_of_watching_users_pageview": "[$1 iżŗi {{PLURAL:$1|amsqdac|imsqdacn}}]",
-       "rc_categories_any": "wanna",
        "rc-change-size": "$1",
        "rc-change-size-new": "$1 {{PLURAL:$1|ⴱⴰⵢⵜ|ⵉⴷ ⴱⴰⵢⵜ}} ⴷⴼⴼⵉⵔ ⵏ ⵓⵙⵏⴼⵍ",
        "newsectionsummary": "/* $1 */ ⵜⵉⴳⵣⵎⵉ ⵜⴰⵎⴰⵢⵏⵓⵜ",
index 74f24b1..7849d68 100644 (file)
        "newpageletter": "N",
        "boteditletter": "b",
        "number_of_watching_users_pageview": "[$1 ပႂ်ႉတူၺ်း {{PLURAL:$1|ၽူႈၸႂ်ႉတိုဝ်း|ၽူႈၸႂ်ႉတိုဝ်းၶဝ်}}]",
-       "rc_categories_any": "လိူၵ်ႈသေဢၼ်ဢၼ်",
        "rc-change-size-new": "$1 {{PLURAL:$1|byte|bytes}} ဝၢႆးသေလႅၵ်ႈလၢႆႈ",
        "newsectionsummary": "/* $1 */ ၵၼ်ဢၼ်မႂ်ႇ",
        "rc-enhanced-expand": "ၼႄပၼ် ႁူဝ်ယွႆႈမၼ်း",
index b1980a4..0fb539b 100644 (file)
        "newpageletter": "නව",
        "boteditletter": "රොබෝ",
        "number_of_watching_users_pageview": "[ {{PLURAL:$1| එක් පරිශීලකයෙක් මුර-කරයි|පරිශීලකවරුන් $1 ක් මුර-කරති}} ]",
-       "rc_categories": "ප්‍රවර්ගයන්ට සීමා කරන්න (\"|\" මගින් වෙන් කරන්න):",
-       "rc_categories_any": "තෝරාගත් ඕනෑම එකක්",
        "rc-change-size": "$1",
        "rc-change-size-new": "වෙනස් කළ පසු {{PLURAL:$1|බයිට|බයිටයන්}} $1 ක්",
        "newsectionsummary": "/* $1 */ නව ඡේදය",
index 4ada884..e962b50 100644 (file)
        "newpageletter": "N",
        "boteditletter": "b",
        "number_of_watching_users_pageview": "[$1 {{PLURAL:$1|sledujúci používateľ|sledujúci používatelia|sledujúcich používateľov}}]",
-       "rc_categories": "Obmedziť na kategórie (oddeľte znakom „|“)",
-       "rc_categories_any": "Akékoľvek z vybraných",
        "rc-change-size-new": "$1 {{PLURAL:$1|bajt|bajty|bajtov}} po zmene",
        "newsectionsummary": "/* $1 */ nová sekcia",
        "rc-enhanced-expand": "Zobraziť podrobnosti",
index 982fb96..b08b5cf 100644 (file)
        "newpageletter": "N",
        "boteditletter": "b",
        "number_of_watching_users_pageview": "[temo {{PLURAL:$1|spremlja|spremljata|spremljajo|spremlja|spremlja}} $1 {{PLURAL:$1|uporabnik|uporabnika|uporabniki|uporabnikov|uporabnikov}}]",
-       "rc_categories": "Omejitev na kategorije (ločite jih z »|«):",
-       "rc_categories_any": "Katera koli od izbranih",
        "rc-change-size-new": "po spremembi: $1 {{PLURAL:$1|zlog|zloga|zlogi|zlogov}}",
        "newsectionsummary": "/* $1 */ nov razdelek",
        "rc-enhanced-expand": "Pokaži podrobnosti",
index e25511c..835e324 100644 (file)
        "newpageletter": "N",
        "boteditletter": "b",
        "number_of_watching_users_pageview": "[$1 {{PLURAL:$1|beobachtender|beobachtende}} Nutzer]",
-       "rc_categories": "Ock Seyta aus dann Kategorien (getrennt miet „|“):",
-       "rc_categories_any": "Olle",
        "newsectionsummary": "Neuer Obschnitt /* $1 */",
        "rc-enhanced-expand": "Details oazeega (beneetigt JavaScript)",
        "rc-enhanced-hide": "Details verstecka",
index e5f30ea..c043222 100644 (file)
        "minoreditletter": "y",
        "newpageletter": "C",
        "boteditletter": "b",
-       "rc_categories": "Wuxuu u gaar yahay qeybaha  (u kala qeybsan \"|\")",
        "rc-enhanced-expand": "Itus ka hadalka (waxaa loo baahanyahay JavaScript)",
        "rc-enhanced-hide": "Qari ka hadalka",
        "recentchangeslinked": "Isbedelada la'xiriira",
index fc400c0..0603a2e 100644 (file)
@@ -33,7 +33,8 @@
                        "Kosovastar",
                        "Matma Rex",
                        "Arianit",
-                       "Denisa"
+                       "Denisa",
+                       "Fanjiayi"
                ]
        },
        "tog-underline": "Nënvizimi i lidhjes:",
        "thu": "Enj",
        "fri": "Pre",
        "sat": "Sht",
-       "january": "Janar",
-       "february": "Shkurt",
-       "march": "Mars",
-       "april": "Prill",
-       "may_long": "Maj",
-       "june": "Qershor",
-       "july": "Korrik",
-       "august": "Gusht",
-       "september": "Shtator",
-       "october": "Tetor",
-       "november": "Nëntor",
-       "december": "Dhjetor",
-       "january-gen": "Janar",
-       "february-gen": "Shkurt",
-       "march-gen": "Mars",
-       "april-gen": "Prill",
-       "may-gen": "Maj",
-       "june-gen": "Qershor",
-       "july-gen": "Korrik",
-       "august-gen": "Gusht",
-       "september-gen": "Shtator",
-       "october-gen": "Tetor",
-       "november-gen": "Nëntor",
-       "december-gen": "Dhjetor",
+       "january": "janar",
+       "february": "shkurt",
+       "march": "mars",
+       "april": "prill",
+       "may_long": "maj",
+       "june": "qershor",
+       "july": "korrik",
+       "august": "gusht",
+       "september": "shtator",
+       "october": "tetor",
+       "november": "nëntor",
+       "december": "dhjetor",
+       "january-gen": "janar",
+       "february-gen": "shkurt",
+       "march-gen": "mars",
+       "april-gen": "prill",
+       "may-gen": "maj",
+       "june-gen": "qershor",
+       "july-gen": "korrik",
+       "august-gen": "gusht",
+       "september-gen": "shtator",
+       "october-gen": "tetor",
+       "november-gen": "nëntor",
+       "december-gen": "dhjetor",
        "jan": "Jan",
        "feb": "Shk",
        "mar": "Mar",
        "permissionserrorstext": "Nuk keni leje për të bërë këtë veprim për {{PLURAL:$1|këtë arsye|këto arsye}}:",
        "permissionserrorstext-withaction": "Ju nuk keni leje për $2, për {{PLURAL:$1|këtë arsye|këto arsye}}:",
        "recreate-moveddeleted-warn": "'''Kujdes: Po rikrijoni një faqe që është grisur më parë.'''\n\nMendohuni nëse dëshironi të vazhdoni me veprimin tuaj në këtë faqe.\nRegjistri i grisjes për këtë faqe jepet më poshtë:",
-       "moveddeleted-notice": "Kjo faqe është grisur. Të dhënat e grisjes për këtë faqe gjenden më poshtë, për referencë.",
+       "moveddeleted-notice": "Kjo faqe është grisur. Të dhënat, protection e grisjes për këtë faqe gjenden më poshtë, për referencë.",
        "log-fulllog": "Shihe ditaret të plota",
        "edit-hook-aborted": "Redaktimi u ndërpre nga një goditje.\nNuk dha asnjë shpjegim.",
        "edit-gone-missing": "Faqja nuk mund t freskohet.\nDuket se është grisur.",
        "newpageletter": "R",
        "boteditletter": "b",
        "number_of_watching_users_pageview": "[$1 duke u mbikqyrur nga {{PLURAL:$1|përdorues|përdorues}}]",
-       "rc_categories": "Kufizimi i kategorive (të ndara me \"|\")",
-       "rc_categories_any": "Ndonjë nga të zgjedhurat",
        "rc-change-size-new": "$1 {{PLURAL:$1|bajt|bajtë}} pas ndryshimit",
        "newsectionsummary": "/* $1 */ seksion i ri",
        "rc-enhanced-expand": "Trego detajet",
        "recentchangeslinked-feed": "Ndryshime të ndërvarura",
        "recentchangeslinked-toolbox": "Ndryshime të ndërvarura",
        "recentchangeslinked-title": "Ndryshime që kanë lidhje me \"$1\"",
-       "recentchangeslinked-summary": "Kjo është një listë e ndryshimeve së fundmi të faqeve të lidhura nga faqja e dhënë (ose bëjnë pjesë tek kategoria e dhënë).\nFaqet [[Special:Watchlist|nën mbikqyrjen tuaj]] duken të '''theksuara'''.",
+       "recentchangeslinked-summary": "Kjo është një listë e ndryshimeve së fundmi të faqeve të lidhura nga faqja e dhënë (ose bëjnë pjesë tek kategoria e dhënë).\nFaqet [[Special:Watchlist|nën mbikqyrjen tuaj]] duken të <strong>theksuara</strong>.",
        "recentchangeslinked-page": "Emri i faqes:",
        "recentchangeslinked-to": "Trego ndryshimet e faqeve që lidhen tek faqja e dhënë",
        "recentchanges-page-added-to-category": "[[:$1]] shtuar në kategori",
index 763be02..7ad7cec 100644 (file)
        "tog-watchrollback": "Додај странице на којима сам вратио измене у мој списак надгледања",
        "tog-minordefault": "Означавај све измене као мање",
        "tog-previewontop": "Прикажи претпреглед пре оквира за уређивање",
-       "tog-previewonfirst": "Прикажи преглед на првој измени",
-       "tog-enotifwatchlistpages": "Пошаљи ми имејл када се измени страница или датотека коју надгледам",
+       "tog-previewonfirst": "Прикажи претпреглед на првој измени",
+       "tog-enotifwatchlistpages": "Пошаљи ми имејл када се страница или датотека коју надгледам измени",
        "tog-enotifusertalkpages": "Пошаљи ми имејл када се моја страница за разговор измени",
        "tog-enotifminoredits": "Пошаљи ми имејл и за мање измене страница и датотека",
        "tog-enotifrevealaddr": "Прикажи моју имејл адресу у порукама обавештења",
        "tog-shownumberswatching": "Прикажи број корисника који надгледају",
-       "tog-oldsig": "Ð\92аÑ\88 Ñ\82ренутни потпис:",
+       "tog-oldsig": "Тренутни потпис:",
        "tog-fancysig": "Сматрај потпис као викитекст (без самоповезивања)",
-       "tog-uselivepreview": "Прикажи претпреглед без освежавања стране",
+       "tog-uselivepreview": "Ð\9fÑ\80икажи Ð¿Ñ\80еÑ\82пÑ\80еглед Ð±ÐµÐ· Ð¾Ñ\81вежаваÑ\9aа Ñ\81Ñ\82Ñ\80аниÑ\86е",
        "tog-forceeditsummary": "Упозори ме када не унесем опис измене",
        "tog-watchlisthideown": "Сакриј моје измене са списка надгледања",
        "tog-watchlisthidebots": "Сакриј измене ботова са списка надгледања",
        "tog-watchlisthideminor": "Сакриј мање измене са списка надгледања",
        "tog-watchlisthideliu": "Сакриј измене пријављених корисника са списка надгледања",
        "tog-watchlistreloadautomatically": "Аутоматски освежи списак надгледања кад год се филтер измени (потребан JavaScript)",
-       "tog-watchlistunwatchlinks": "Додај везе за директно додавање/уклањање ставки са списка надгледања (потребан ЈаваСкрипт)",
+       "tog-watchlistunwatchlinks": "Додај везе за директно додавање/уклањање ставки са списка надгледања (потребан JavaScript)",
        "tog-watchlisthideanons": "Сакриј измене анонимних корисника са списка надгледања",
        "tog-watchlisthidepatrolled": "Сакриј патролиране измене са списка надгледања",
        "tog-watchlisthidecategorization": "Сакриј категоризацију страница",
@@ -86,7 +86,7 @@
        "underline-always": "Увек",
        "underline-never": "Никад",
        "underline-default": "Према теми или прегледачу",
-       "editfont-style": "Ð\98зглед Ñ\84онÑ\82а Ñ\83 Ñ\83Ñ\80еÑ\92иваÑ\87ком Ð¾ÐºÐ²Ð¸Ñ\80Ñ\83:",
+       "editfont-style": "СÑ\82ил Ñ\84онÑ\82а Ñ\83 Ð¾ÐºÐ²Ð¸Ñ\80Ñ\83 Ð·Ð° Ñ\83Ñ\80еÑ\92иваÑ\9aе:",
        "editfont-monospace": "Сразмерно широк фонт",
        "editfont-sansserif": "Бесерифни фонт",
        "editfont-serif": "Серифни фонт",
        "oct": "окт",
        "nov": "нов",
        "dec": "дец",
-       "january-date": "$1 јануар",
-       "february-date": "$1 фебруар",
-       "march-date": "$1 март",
-       "april-date": "$1 април",
-       "may-date": "$1 мај",
-       "june-date": "$1 јун",
-       "july-date": "$1 јул",
-       "august-date": "$1 август",
-       "september-date": "$1 септембар",
-       "october-date": "$1 окотобар",
-       "november-date": "$1 новембар",
-       "december-date": "$1 децембар",
+       "january-date": "$1. јануар",
+       "february-date": "$1. фебруар",
+       "march-date": "$1. март",
+       "april-date": "$1. април",
+       "may-date": "$1. мај",
+       "june-date": "$1. јун",
+       "july-date": "$1. јул",
+       "august-date": "$1. август",
+       "september-date": "$1. септембар",
+       "october-date": "$1. окотобар",
+       "november-date": "$1. новембар",
+       "december-date": "$1. децембар",
        "period-am": "преподне",
        "period-pm": "поподне",
        "pagecategories": "{{PLURAL:$1|Категорија|Категорије|Категорија}}",
        "noindex-category": "Непописане странице",
        "broken-file-category": "Странице с неисправним везама до датотека",
        "about": "О нама",
-       "article": "СÑ\82Ñ\80аниÑ\86а Ñ\81а Ñ\81адÑ\80жаÑ\98ем",
+       "article": "Чланак",
        "newwindow": "(отвара се у новом прозору)",
        "cancel": "Откажи",
        "moredotdotdot": "Више…",
        "navigation-heading": "Навигациони мени",
        "errorpagetitle": "Грешка",
        "returnto": "Назад на $1.",
-       "tagline": "Из {{SITENAME}}",
+       "tagline": "Извор: {{SITENAME}}",
        "help": "Помоћ",
        "search": "Претражи",
+       "search-ignored-headings": " #<!-- не мењајте ништа у овом реду --> <pre>\n# Наслови који ће бити занемарени при претрази.\n# Измене су видљиве одмах након што се страница са насловом попише.\n# Можете изнудити поновно пописивање „нултом” изменом.\n# Синтакса је следећа:\n#  * Сваки ред који започиње знаком „#” је коментар.\n#  * Сваки не празни ред је тачан наслов који ће бити занемарен, с тим да се разликују мала и велика слова и све остало\nРеференце\nСпољашње везе\nТакође погледајте\n #</pre> <!-- не мењајте ништа у овом реду -->",
        "searchbutton": "Претражи",
        "go": "Иди",
        "searcharticle": "Иди",
        "create": "Направи",
        "create-local": "Додај локални опис",
        "delete": "Обриши",
-       "undelete_short": "Врати {{PLURAL:$1|1=једну обрисану измену|$1 обрисане измене|$1 обрисаних измена}}",
+       "undelete_short": "Врати {{PLURAL:$1|обрисану измену|$1 обрисане измене|$1 обрисаних измена}}",
        "viewdeleted_short": "Погледај {{PLURAL:$1|обрисану измену|$1 обрисане измене|$1 обрисаних измена}}",
        "protect": "Заштити",
        "protect_change": "промени",
        "confirmable-no": "Не",
        "thisisdeleted": "Погледати или вратити $1?",
        "viewdeleted": "Погледати $1?",
-       "restorelink": "{{PLURAL:$1|1=обрисану измену|$1 обрисане измене|$1 обрисаних измена}}",
+       "restorelink": "{{PLURAL:$1|обрисану измену|$1 обрисане измене|$1 обрисаних измена}}",
        "feedlinks": "Довод:",
        "feed-invalid": "Неисправна врста довода.",
        "feed-unavailable": "Доводи нису доступни",
        "cannotloginnow-title": "Пријава тренутно није могућа",
        "cannotloginnow-text": "Пријава није могућа када се користи $1.",
        "cannotcreateaccount-title": "Отварање налога није могуће",
+       "cannotcreateaccount-text": "Директно прављење налога није омогућено на овом викију.",
        "yourdomainname": "Домен:",
        "password-change-forbidden": "Не можете да промените лозинку на овом викију.",
        "externaldberror": "Дошло је до грешке при препознавању базе података или немате овлашћења да ажурирате свој спољни налог.",
        "createacct-email-ph": "Унесите Вашу имејл адресу",
        "createacct-another-email-ph": "Унесите имејл адресу",
        "createaccountmail": "Користите привремену, случајно створену лозинку и пошаљите на наведену имејл адресу",
+       "createaccountmail-help": "Може се користити да се некоме направи налог без сазнања лозинке.",
        "createacct-realname": "Право име (необавезно)",
        "createacct-reason": "Разлог",
        "createacct-reason-ph": "Зашто правите још један налог?",
+       "createacct-reason-help": "Порука која се приказује у дневнику стварања корисничких налога",
        "createacct-submit": "Отвори налог",
        "createacct-another-submit": "Отвори налог",
        "createacct-continue-submit": "Наставите отварање налога",
        "botpasswords-label-cancel": "Откажи",
        "botpasswords-label-delete": "Обриши",
        "botpasswords-label-resetpassword": "Ресетуј лозинку",
+       "botpasswords-label-grants": "Применљиве дозволе:",
        "botpasswords-label-grants-column": "Одобрено",
        "botpasswords-bad-appid": "„$1” није исправан назив бота.",
        "botpasswords-insert-failed": "Неуспешно додавање бота \"$1\". Да ли је већ додат?",
        "revdelete-no-file": "Тражена датотека не постоји.",
        "revdelete-show-file-confirm": "Желите ли да видите обрисану измену датотеке „<nowiki>$1</nowiki>“ од $2; $3?",
        "revdelete-show-file-submit": "Да",
-       "revdelete-selected-text": "{{PLURAL:$1|Изабрана измена|Изабране измене}} [[:$2]]:",
+       "revdelete-selected-text": "{{PLURAL:$1|Изабрана измена|Изабране измене|Изабраних измена}} [[:$2]]:",
        "revdelete-selected-file": "{{PLURAL:$1|Изабрана верзија датотеке|Изабране верзије датотеке}} [[:$2]]:",
        "logdelete-selected": "{{PLURAL:$1|Изабрана ставка у историји|Изабране ставке у историји}}:",
        "revdelete-text-text": "Избрисане измене ће и даље бити видљиве у историји странице, али делови њиховог садржаја неће бити јавно доступни.",
        "recentchangesdays-max": "Највише $1 {{PLURAL:$1|дан|дана}}",
        "recentchangescount": "Број измена за приказ:",
        "prefs-help-recentchangescount": "Подразумева скорашње измене, историје страница и дневнике.",
-       "prefs-help-watchlist-token2": "Ово је тајни кључ за веб-довод Вашег списка надгледања. \nСвако ко зна овај кључ биће у могућности да види Ваша списак надгледања, зато кључ немојте одавати никоме. \nАко је потребно, кључ [[Special:ResetTokens|можете ресетовати]].",
+       "prefs-help-watchlist-token2": "Ово је тајни кључ за веб-довод Вашег списка надгледања. \nСвако ко зна овај кључ биће у могућности да види Ваш списак надгледања, зато кључ немојте одавати никоме. \nАко је потребно, кључ [[Special:ResetTokens|можете ресетовати]].",
        "savedprefs": "Ваша подешавања су сачувана.",
        "savedrights": "Корисничке групе за {{GENDER:$1|$1}} су сачуване.",
        "timezonelegend": "Временска зона:",
        "email-blacklist-label": "Онемогући следећим корисницима да ми шаљу имејлове:",
        "prefs-searchoptions": "Претрага",
        "prefs-namespaces": "Именски простори",
-       "default": "подÑ\80азÑ\83мевано",
+       "default": "подÑ\80азÑ\83мевана",
        "prefs-files": "Датотеке",
        "prefs-custom-css": "Прилагођени CSS",
        "prefs-custom-js": "Прилагођени јаваскрипт",
        "grant-group-file-interaction": "Уређивање датотека",
        "grant-group-watchlist-interaction": "Уређивање вашег списка надгледања",
        "grant-group-email": "Пошаљи имејл",
+       "grant-group-high-volume": "Извршавање великог броја радњи",
+       "grant-group-customization": "Прилагођавање и подешавања",
+       "grant-group-administration": "Извршавање административних радњи",
+       "grant-group-private-information": "Приступање Вашим личним подацима",
        "grant-group-other": "Разне активности",
        "grant-blockusers": "Блокирање и деблокирање корисника",
        "grant-createaccount": "Отварање налога",
        "grant-editpage": "Уређивање постојећих страница",
        "grant-editprotected": "Уређивање заштићених страница",
        "grant-highvolume": "Масовно уређивање",
+       "grant-oversight": "Скривање корисника и измена",
        "grant-patrol": "Патролирање измена",
        "grant-privateinfo": "Приступи приватним информацијама",
        "grant-protect": "Закључавање и откључавање страница",
        "grant-basic": "Основна права",
        "grant-viewdeleted": "Преглед обрисаних страница и датотека",
        "grant-viewmywatchlist": "Преглед вашег списак надгледања",
+       "grant-viewrestrictedlogs": "Прегледање ограничених уноса у дневнику",
        "newuserlogpage": "Дневник нових корисника",
        "newuserlogpagetext": "Ово је дневник нових корисника.",
        "rightslog": "Дневник корисничких права",
        "action-writeapi": "писање АПИ-ја",
        "action-delete": "брисање ове странице",
        "action-deleterevision": "брисање измена",
+       "action-deletelogentry": "бирсање уноса у дневницима",
        "action-deletedhistory": "прегледање обрисане историје странице",
+       "action-deletedtext": "преглед обрисаног текста измене",
        "action-browsearchive": "претраживање обрисаних страница",
        "action-undelete": "враћање страница",
        "action-suppressrevision": "прегледање и враћање сакривених измена",
        "recentchanges": "Скорашње измене",
        "recentchanges-legend": "Опције скорашњих измена",
        "recentchanges-summary": "Пратите скорашње измене на овој страници.",
-       "recentchanges-noresult": "Нема промена у задатом времену за задате критеријуме.",
+       "recentchanges-noresult": "Нема измена у задатом периоду који одговарају овим критеријумима.",
+       "recentchanges-notargetpage": "Унесите назив странице како бисте видели сродне измене.",
        "recentchanges-feed-description": "Пратите скорашње измене уз помоћ овог довода.",
-       "recentchanges-label-newpage": "Ð\9eвом Ð¸Ð·Ð¼ÐµÐ½Ð¾Ð¼ Ð½Ð°Ð¿Ñ\80авÑ\99ена Ñ\98е Ð½ова страница",
-       "recentchanges-label-minor": "Ð\9eво Ñ\98е Ð¼ања измена",
-       "recentchanges-label-bot": "Ð\9eвÑ\83 Ð¸Ð·Ð¼ÐµÐ½Ñ\83 Ñ\98е Ð½Ð°Ð¿Ñ\80авио Ð±Ð¾Ñ\82",
+       "recentchanges-label-newpage": "Ð\9dова страница",
+       "recentchanges-label-minor": "Ð\9cања измена",
+       "recentchanges-label-bot": "Ð\91оÑ\82овÑ\81ка Ð¸Ð·Ð¼ÐµÐ½Ð°",
        "recentchanges-label-unpatrolled": "Ова измена још није патролирана",
        "recentchanges-label-plusminus": "Промена величине странице у бајтовима",
        "recentchanges-legend-heading": "<strong>Легенда:</strong>",
        "rcfilters-group-results-by-page": "Групиши резултате по страницама",
        "rcfilters-activefilters": "Активни филтери",
        "rcfilters-advancedfilters": "Напредни филтери",
-       "rcfilters-limit-title": "Ð\9fÑ\80иказаÑ\82и Ð¸Ð·Ð¼ÐµÐ½Ð°",
+       "rcfilters-limit-title": "Ð\98змена Ð·Ð° Ð¿Ñ\80иказ",
        "rcfilters-limit-and-date-label": "$1 {{PLURAL:$1|измена|измене}}, $2",
-       "rcfilters-date-popup-title": "Ð\92Ñ\80еменÑ\81ки Ð¾ÐºÐ²Ð¸Ñ\80",
-       "rcfilters-days-title": "Ð\9fÑ\80еÑ\82Ñ\85одниÑ\85 Ð½ÐµÐºÐ¾Ð»Ð¸ÐºÐ¾ Ð´Ð°Ð½Ð°",
-       "rcfilters-hours-title": "Ð\9fÑ\80еÑ\82Ñ\85одниÑ\85 Ð½ÐµÐºÐ¾Ð»Ð¸ÐºÐ¾ сати",
+       "rcfilters-date-popup-title": "Ð\92Ñ\80еменÑ\81ки Ð¿ÐµÑ\80иод",
+       "rcfilters-days-title": "СкоÑ\80аÑ\88Ñ\9aи Ð´Ð°Ð½Ð¸",
+       "rcfilters-hours-title": "СкоÑ\80аÑ\88Ñ\9aе сати",
        "rcfilters-days-show-days": "$1 {{PLURAL:$1|дан|дана}}",
        "rcfilters-days-show-hours": "$1 {{PLURAL:$1|сат|сата}}",
        "rcfilters-highlighted-filters-list": "Истакнуто: $1",
        "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 Ñ\83памÑ\9bени. Измените Ваша подешавања како бисте направили нове сачуване филтере.",
+       "rcfilters-savedqueries-already-saved": "Ð\9eви Ñ\84илÑ\82еÑ\80и Ñ\81Ñ\83 Ð²ÐµÑ\9b Ñ\81аÑ\87Ñ\83вани. Измените Ваша подешавања како бисте направили нове сачуване филтере.",
        "rcfilters-restore-default-filters": "Враћање подразумеваних филтера",
        "rcfilters-clear-all-filters": "Уклони све филтере",
-       "rcfilters-show-new-changes": "Погледајте најновије измене",
-       "rcfilters-search-placeholder": "Филтрирај скорашње измене (употребите мени или потражите име филтра)",
+       "rcfilters-show-new-changes": "Погледај најновије измене",
+       "rcfilters-search-placeholder": "Филтрирај скорашње измене (употребите мени или потражите име филтера)",
        "rcfilters-invalid-filter": "Неисправан филтер",
        "rcfilters-empty-filter": "Нема активних филтера. Сви доприноси су приказани.",
        "rcfilters-filterlist-title": "Филтери",
        "rcfilters-filterlist-whatsthis": "Како ово функционише?",
-       "rcfilters-filterlist-feedbacklink": "Ð\94аÑ\98Ñ\82е Ð¿Ð¾Ð²Ñ\80аÑ\82не Ð¸Ð½Ñ\84оÑ\80маÑ\86иÑ\98е Ð¾ Ð½Ð¾Ð²Ð¸Ð¼ (беÑ\82а) алатима за филтрирање",
+       "rcfilters-filterlist-feedbacklink": "Ð\9fоделиÑ\82е Ð²Ð°Ñ\88е Ð¼Ð¸Ñ\88Ñ\99еÑ\9aе Ð¾ (новим) алатима за филтрирање",
        "rcfilters-highlightbutton-title": "Истакни резултате",
        "rcfilters-highlightmenu-title": "Одабери боју",
        "rcfilters-highlightmenu-help": "Изаберите боју да бисте истакнули ово својство",
        "rcfilters-exclude-button-off": "Изостави означено",
        "rcfilters-exclude-button-on": "Изостави одабрано",
        "rcfilters-view-tags": "Означене измјене",
-       "rcfilters-view-namespaces-tooltip": "Филтер резултата према именском простору",
-       "rcfilters-view-tags-tooltip": "ФилÑ\82Ñ\80иÑ\80аÑ\9aе Ñ\80езÑ\83лÑ\82аÑ\82а према ознаци измјене",
+       "rcfilters-view-namespaces-tooltip": "Филтрирај резултате према именском простору",
+       "rcfilters-view-tags-tooltip": "ФилÑ\82Ñ\80иÑ\80аÑ\98 Ñ\80езÑ\83лÑ\82аÑ\82е према ознаци измјене",
        "rcfilters-view-return-to-default-tooltip": "Повратак на главни мени",
        "rcfilters-view-tags-help-icon-tooltip": "Сазнајте више о означеним измјенама",
        "rcfilters-liveupdates-button": "Ажурирања уживо",
        "rcfilters-watchlist-showupdated": "Измене на страницама које нисте посетили од када је измена извршена су <strong>подебљане</strong>, са испуњеним ознакама.",
        "rcfilters-preference-label": "Сакриј побољшану верзију скорашњих измена",
        "rcfilters-preference-help": "Поништава редизајн интерфејса из 2017. и све алатке додате тада и после.",
+       "rcfilters-filter-showlinkedfrom-label": "Прикажи измене на страницама са којих долазе везе",
+       "rcfilters-filter-showlinkedfrom-option-label": "<strong>Странице са којих долазе везе до</strong> изабране странице",
+       "rcfilters-filter-showlinkedto-label": "Прикажи измене на страницама ка којима воде везе",
+       "rcfilters-filter-showlinkedto-option-label": "<strong>Странице ка којима воде везе са</strong> одабране странице",
        "rcnotefrom": "Испод {{PLURAL:$5|је измена|су измене}} од <strong>$3, $4</strong> (до <strong>$1</strong> приказано).",
        "rclistfromreset": "Ресетуј одабир датума",
        "rclistfrom": "Прикажи нове измене почев од $2, $3",
        "boteditletter": "б",
        "unpatrolledletter": "!",
        "number_of_watching_users_pageview": "[$1 {{PLURAL:$1|корисник надгледа|корисника надгледају|корисника надгледају}}]",
-       "rc_categories": "Ограничи на категорије (раздвоји с усправном цртом):",
-       "rc_categories_any": "Сви изабрани",
        "rc-change-size": "$1",
        "rc-change-size-new": "$1 {{PLURAL:$1|бајт|бајта|бајтова}} после измене",
        "newsectionsummary": "/* $1 */ нови одељак",
        "uploaded-href-unsafe-target-svg": "Пронађен href са несигурним подацима: URI одредиште <code>&lt;$1 $2=\"$3\"&gt;</code> у постављеној SVG датотеци.",
        "uploaded-animate-svg": "Пронађена „animate“ ознака која можда мења href користећи се „from“ атрибутом <code>&lt;$1 $2=\"$3\"&gt;</code> у постављеној SVG датотеци.",
        "uploadscriptednamespace": "Ова SVG датотека садржи погрешан именски простор „<nowiki>$1</nowiki>“",
+       "uploadinvalidxml": "Није могуће рашчланити XML отпремљене датотеке.",
        "uploadvirus": "Датотека садржи вирус!\nДетаљи: $1",
        "uploadjava": "Датотека је формата ZIP који садржи јава .class елемент.\nСлање јава датотека није дозвољено јер оне могу изазвати заобилажење сигурносних ограничења.",
        "upload-source": "Изворна датотека",
        "upload-too-many-redirects": "Адреса садржи превише преусмерења",
        "upload-http-error": "Дошло је до HTTP грешке: $1",
        "upload-copy-upload-invalid-domain": "Примерци отпремања нису доступни на овом домену.",
-       "upload-dialog-title": "Ð\9eÑ\82пÑ\80емаÑ\9aе Ð´Ð°Ñ\82оÑ\82ека",
+       "upload-dialog-title": "Ð\9eÑ\82пÑ\80еми Ð´Ð°Ñ\82оÑ\82екÑ\83",
        "upload-dialog-button-cancel": "Откажи",
        "upload-dialog-button-back": "Назад",
        "upload-dialog-button-done": "Готово",
        "upload-form-label-own-work": "Ово је моје сопствено дело",
        "upload-form-label-infoform-categories": "Категорије",
        "upload-form-label-infoform-date": "Датум",
+       "upload-form-label-not-own-work-local-generic-local": "Такође можете покушати [[Special:Upload|подразумевану страницу за отпремање]].",
        "backend-fail-stream": "Не могу да емитујем датотеку $1.",
        "backend-fail-backup": "Не могу да направим резерву датотеке $1.",
        "backend-fail-notexists": "Датотека $1 не постоји.",
        "uploadstash-badtoken": "Извршавање дате радње није успело, разлог томе може бити истек времена за уређивање. Покушајте поново.",
        "uploadstash-errclear": "Чишћење датотека није успело.",
        "uploadstash-refresh": "Освежи списак датотека",
+       "uploadstash-thumbnail": "погледај минијатуру",
        "uploadstash-bad-path": "Путања не постоји.",
        "uploadstash-bad-path-invalid": "Путања није исправна.",
        "uploadstash-bad-path-unknown-type": "Непознат тип „$1“.",
+       "uploadstash-bad-path-unrecognized-thumb-name": "Непрепознато име минијатуре.",
+       "uploadstash-bad-path-bad-format": "Кључ „$1“ није у одговарајућем облику.",
+       "uploadstash-file-not-found-no-thumb": "Не могу добити минијатуру.",
+       "uploadstash-file-not-found-no-remote-thumb": "Добављање минијатуре није успело: $1\nАдреса = $2",
+       "uploadstash-file-not-found-missing-content-type": "Недостаје заглавље за врсту садржаја.",
+       "uploadstash-no-extension": "Нема траженог додатка.",
        "invalid-chunk-offset": "Неисправна полазна тачка",
        "img-auth-accessdenied": "Приступ је одбијен",
        "img-auth-nopathinfo": "Недостаје PATH_INFO.\nВаш сервер није подешен да прослеђује овакве податке.\nМожда је заснован на CGI-ју који не подржава img_auth.\nПогледајте https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Image_Authorization?uselang=sr-ec.",
        "apisandbox-sending-request": "Слање API захтева...",
        "apisandbox-loading-results": "Пријем API резултата...",
        "apisandbox-results-error": "Дошло је до грешке приликом учитавања резултата API упита: $1.",
+       "apisandbox-request-selectformat-label": "Прикажи сахтеване податке као:",
        "apisandbox-request-url-label": "Адреса захтева:",
        "apisandbox-continue": "Настави",
        "apisandbox-continue-clear": "Очисти",
        "listgrouprights-namespaceprotection-namespace": "Именски простор",
        "listgrouprights-namespaceprotection-restrictedto": "Права потребна за уређивање",
        "listgrants": "Дозволе",
+       "listgrants-grant": "Дозвола",
        "listgrants-rights": "Права",
        "trackingcategories": "Медијавики категорије",
        "trackingcategories-summary": "Ова посебна страница је списак категорија које су део Медијавикија, оне се аутоматски ажурирају и њихови називи се могу мењати уређивањем системских порука у именском простору {{ns:8}}.",
+       "trackingcategories-msg": "Праћење категорије",
        "trackingcategories-name": "Име поруке",
        "trackingcategories-desc": "Које странице се налазе у категорији",
+       "restricted-displaytitle-ignored": "Странице са занемареним насловима за приказ",
        "noindex-category-desc": "Странице које у себи имају магичну реч <code><nowiki>__NOINDEX__</nowiki></code>.",
        "index-category-desc": "Странице које у себи имају магичну реч <code><nowiki>__INDEX__</nowiki></code> и самим тим су индексиране од стране робота.",
        "broken-file-category-desc": "Странице које имају везе до непостојећих датотека.",
        "rollbacklinkcount": "врати $1 {{PLURAL:$1|измену|измене|измена}}",
        "rollbacklinkcount-morethan": "врати више од $1 {{PLURAL:$1|измене|измене|измена}}",
        "rollbackfailed": "Неуспешно враћање",
+       "rollback-missingrevision": "Не могу учитати податке о измени.",
        "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-nouser": "Ð\92Ñ\80аÑ\9bене Ñ\81Ñ\83 Ð¸Ð·Ð¼ÐµÐ½Ðµ Ñ\81кÑ\80ивеног ÐºÐ¾Ñ\80иÑ\81ника на последњу измену {{GENDER:$1|корисника|кориснице}} [[User:$1|$1]]",
-       "rollback-success": "Ð\92Ñ\80аÑ\9bене Ñ\81Ñ\83 Ð¸Ð·Ð¼ÐµÐ½Ðµ {{GENDER:$1|коÑ\80иÑ\81ника|коÑ\80иÑ\81ниÑ\86е}} {{GENDER:$3|$1}}\nна последњу измену {{GENDER:$2|корисника|кориснице}} {{GENDER:$4|$2}}.",
+       "revertpage-nouser": "Ð\98змене Ñ\81кÑ\80ивеног ÐºÐ¾Ñ\80иÑ\81ника Ñ\81Ñ\83 Ð²Ñ\80аÑ\9bене на последњу измену {{GENDER:$1|корисника|кориснице}} [[User:$1|$1]]",
+       "rollback-success": "Ð\98змене {{GENDER:$1|коÑ\80иÑ\81ника|коÑ\80иÑ\81ниÑ\86е}} {{GENDER:$3|$1}} Ñ\81Ñ\83 Ð²Ñ\80аÑ\9bене на последњу измену {{GENDER:$2|корисника|кориснице}} {{GENDER:$4|$2}}.",
        "sessionfailure-title": "Сесија је окончана",
        "sessionfailure": "Изгледа да постоји проблем с вашом сесијом;\nова радња је отказана да би се избегла злоупотреба.\nВратите се на претходну страницу, поново је учитајте и покушајте поново.",
        "changecontentmodel": "Промени модел садржаја странице",
        "changecontentmodel-success-text": "Модел садржаја странице [[:$1]] је промењен.",
        "changecontentmodel-cannot-convert": "Модел садржаја странице [[:$1]] се не може претворити у врсту $2.",
        "changecontentmodel-nodirectediting": "Модел садржаја $1 не подржава изравно уређивање",
+       "changecontentmodel-emptymodels-title": "Нема доступних модела садржаја",
        "log-name-contentmodel": "Дневник промене модела садржаја",
        "log-description-contentmodel": "Ова страница приказује измене у моделима садржаја страница и странице које су направљене са моделом садржаја који се разликује од подразумеваног.",
        "logentry-contentmodel-change": "$1 је {{GENDER:$2|променио|променила}} модел садржаја странице $3 из „$4“ у „$5“",
        "block-log-flags-hiddenname": "корисничко име је сакривено",
        "range_block_disabled": "Администраторска могућност за блокирање распона ИП адреса је онемогућена.",
        "ipb_expiry_invalid": "Време истека је неисправно.",
+       "ipb_expiry_old": "Време истека је у прошлости.",
        "ipb_expiry_temp": "Сакривене блокаде корисника морају бити трајне.",
        "ipb_hide_invalid": "Не могу да потиснем овај налог; има више од {{PLURAL:$1|једне измене|$1 измена}}.",
        "ipb_already_blocked": "„$1“ је већ блокиран.",
        "ipb_blocked_as_range": "Грешка: IP адреса $1 није директно блокирана и не може да се деблокира.\nОна је блокирана као део блокаде $2, која може бити деблокирана.",
        "ip_range_invalid": "Неисправан распон IP адреса.",
        "ip_range_toolarge": "Опсежна блокирања већа од /$1 нису дозвољена.",
+       "ip_range_toolow": "IP-опсези нису дозвољени.",
        "proxyblocker": "Блокер посредника",
        "proxyblockreason": "Ваша ИП адреса је блокирана јер представља отворени посредник.\nОбратите се вашем добављачу интернет услуга или техничку подршку и обавестите их о овом озбиљном безбедносном проблему.",
        "sorbs": "DNSBL",
        "cant-move-user-page": "Немате дозволу за премештање основних корисничких страница (осим подстраница).",
        "cant-move-to-user-page": "Немате дозволу за премештање странице на вашу корисничку страницу (осим на корисничку подстраницу).",
        "cant-move-category-page": "Немате дозволу да премештате странице категорија.",
+       "cant-move-to-category-page": "Немате дозволу да преместите страницу на страницу категорије.",
+       "cant-move-subpages": "Немате дозволу да премештате подстранице.",
+       "namespace-nosubpages": "Имениски простор „$1“ не дозвољава подстранице.",
        "newtitle": "Нови наслов:",
        "move-watch": "Надгледај ову страницу",
        "movepagebtn": "Премести страницу",
        "export-download": "Сачувај као датотеку",
        "export-templates": "Укључи шаблоне",
        "export-pagelinks": "Укључи повезане странице до дубине од:",
+       "export-manual": "Ручно додај странице:",
        "allmessages": "Системске поруке",
        "allmessagesname": "Назив",
        "allmessagesdefault": "Подразумевани текст",
        "importuploaderrortemp": "Не могу да пошаљем датотеку за увоз.\nНедостаје привремена фасцикла.",
        "import-parse-failure": "Погрешно рашчлањивање XML-а.",
        "import-noarticle": "Нема странице за увоз!",
-       "import-nonewrevisions": "Ð\98змене Ð½Ð¸Ñ\81Ñ\83 Ñ\83везене (Ñ\81ве Ñ\81Ñ\83 Ð²ÐµÑ\9b Ð±Ð¸Ð»Ðµ Ð¸Ð»Ð¸ Ð¿Ñ\80иÑ\81Ñ\83Ñ\82не Ð¸Ð»Ð¸ Ð¿Ñ\80еÑ\81коÑ\87ене Ð·Ð±Ð¾Ð³ Ð³Ñ\80еÑ\88ки).",
+       "import-nonewrevisions": "Ð\98змене Ð½Ð¸Ñ\81Ñ\83 Ñ\83везене (Ñ\81ве Ñ\81Ñ\83 Ð²ÐµÑ\9b Ð±Ð¸Ð»Ðµ Ð¸Ð»Ð¸ Ð¿Ñ\80иÑ\81Ñ\83Ñ\82не Ð¸Ð»Ð¸ Ð¿Ñ\80еÑ\81коÑ\87ене Ð·Ð±Ð¾Ð³ Ð³Ñ\80еÑ\88ака).",
        "xml-error-string": "$1 у реду $2, колона $3 (бајт $4): $5",
        "import-upload": "Отпремање XML података",
        "import-token-mismatch": "Губитак података о сесији.\n\nМожда сте одјављени. '''Молимо Вас проверите да ли сте још увек пријављени и покушајте поново'''.\n\nАко и даље не ради, покушајте се [[Special:UserLogout|одјавити]] и поново пријавити и проверите да ли Ваш веб-пртраживач дозвољава колачиће са овог сајта.",
        "tooltip-ca-move": "Премести ову страницу",
        "tooltip-ca-watch": "Додај ову страницу на списак надгледања",
        "tooltip-ca-unwatch": "Уклони ову страницу са списка надгледања",
-       "tooltip-search": "Ð\9fÑ\80еÑ\82Ñ\80ага",
+       "tooltip-search": "Ð\9fÑ\80еÑ\82Ñ\80ажи",
        "tooltip-search-go": "Идите на страницу с овим именом, ако постоји",
        "tooltip-search-fulltext": "Претражите странице с овим текстом",
        "tooltip-p-logo": "Посетите главну страну",
        "tag-mw-new-redirect-description": "Измене којима је направљено ново преусмерење или је страница измењена да буде преусмерење",
        "tag-mw-removed-redirect": "Уклоњено преусмјерење",
        "tag-mw-removed-redirect-description": "Измене које мењају постојеће преусмерење у страницу без преусмерења",
-       "tag-mw-changed-redirect-target": "Ð\9fÑ\80омеÑ\9aена Ð¾Ð´Ñ\80едиÑ\88на Ñ\81Ñ\82Ñ\80аниÑ\86а преусмерења",
+       "tag-mw-changed-redirect-target": "Ð\9fÑ\80омеÑ\9aено Ð¾Ð´Ñ\80едиÑ\88Ñ\82е преусмерења",
        "tag-mw-changed-redirect-target-description": "Измене које мењају одредиште преусмерења",
        "tag-mw-blank": "Страница испражњена",
        "tag-mw-blank-description": "Измене које бришу читав садржај странице",
        "tag-mw-replace-description": "Измене који уклањају више од 90% садржаја странице",
        "tag-mw-rollback": "Враћање",
        "tag-mw-rollback-description": "Измене које враћају страницу на претходне измене",
-       "tag-mw-undo": "Ð\9fониÑ\88Ñ\82ена Ð¿Ñ\80еÑ\82Ñ\85одна Ð¸Ð·Ð¼ÐµÐ½Ð°",
+       "tag-mw-undo": "Поништена измена",
        "tag-mw-undo-description": "Измене које поништавају претходне измене",
        "tags-title": "Ознаке",
        "tags-intro": "На овој страници је наведен списак ознака с којима програм може да означи измене и његово значење.",
        "feedback-termsofuse": "Прихватам да пошаљем повратне информације у складу са условима коришћења.",
        "feedback-thanks": "Хвала! Ваша повратна информација је постављена на страницу „[$2 $1]“.",
        "feedback-thanks-title": "Хвала вам!",
-       "searchsuggest-search": "Ð\9fÑ\80еÑ\82Ñ\80ага",
+       "searchsuggest-search": "Ð\9fÑ\80еÑ\82Ñ\80ажи",
        "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": "Претражи датотеке",
        "mw-widgets-mediasearch-noresults": "Нема резултата.",
        "mw-widgets-titleinput-description-new-page": "страница још увек не постоји",
        "mw-widgets-titleinput-description-redirect": "преусмерава на $1",
index 9b8059b..fca6d7c 100644 (file)
        "newwindow": "(otvara se u novom prozoru)",
        "cancel": "Otkaži",
        "moredotdotdot": "Više…",
-       "morenotlisted": "Ova lista je možda nepotpuna",
+       "morenotlisted": "Ovaj spisak možda nije potpun.",
        "mypage": "Stranica",
        "mytalk": "Razgovor",
        "anontalk": "Razgovor",
        "tagline": "Izvor: {{SITENAME}}",
        "help": "Pomoć",
        "search": "Pretraga",
-       "search-ignored-headings": "#<!-- ovu liniju ostavite kakva jeste --> <pre>\n# Naslovi koji će biti ignorisani upitom\n# Promene su vidljive odmah nakon što stranica sa naslovom bude popisana\n# Možete iznuditi ponovno popisivanje sa \"null\" promenom\n# Sintaksa je sledeća:\n# * Svaka vrsta koja započinje \"#\" znakom pa sve do kraja je komentar\n# * Svaka ne prazna vrsta je tačan naslov za zanemariti, u tačnom obliku\nReference\nSpoljašnje veze\nPogledajte\n#</pre> <!-- ovu liniju ostavite kakva jeste -->",
+       "search-ignored-headings": "#<!-- ovu liniju ostavite onakvu kakva jeste --> <pre>\n# Naslovi koji će biti ignorisani upitom\n# Promene su vidljive odmah nakon što stranica sa naslovom bude popisana\n# Možete iznuditi ponovno popisivanje sa \"null\" promenom\n# Sintaksa je sledeća:\n# * Svaka vrsta koja započinje \"#\" znakom pa sve do kraja je komentar\n# * Svaka ne prazna vrsta je tačan naslov za zanemariti, u tačnom obliku\nReference\nSpoljašnje veze\nPogledajte\n#</pre> <!-- ovu liniju ostavite onakvu kakva jeste -->",
        "searchbutton": "Pretraži",
        "go": "Idi",
        "searcharticle": "Idi",
        "talk": "Razgovor",
        "views": "Pregledi",
        "toolbox": "Alatke",
-       "tool-link-userrights": "Promeni {{GENDER:$1|korisničke}} grupe",
+       "tool-link-userrights": "Uredi {{GENDER:$1|korisničke}} grupe",
        "tool-link-userrights-readonly": "Prikaži {{GENDER:$1|korisnik}} grupe",
        "tool-link-emailuser": "Pošalji imejl",
        "imagepage": "Pogledaj stranicu datoteke",
        "recentchanges-legend": "Opcije skorašnjih izmena",
        "recentchanges-summary": "Pratite skorašnje izmene na ovoj stranici.",
        "recentchanges-noresult": "Nema promena u zadatom vremenu za zadate kriterijume.",
+       "recentchanges-notargetpage": "Unesite naziv stranice kako biste videli srodne izmene.",
        "recentchanges-feed-description": "Pratite skorašnje izmene uz pomoć ovog dovoda.",
        "recentchanges-label-newpage": "Ovom izmenom napravljena je nova izmena",
        "recentchanges-label-minor": "Ovo je manja izmena",
        "boteditletter": "b",
        "unpatrolledletter": "!",
        "number_of_watching_users_pageview": "[$1 {{PLURAL:$1|korisnik nadgleda|korisnika nadgledaju|korisnika nadgledaju}}]",
-       "rc_categories": "Ograniči na kategorije (razdvoji s uspravnom crtom):",
-       "rc_categories_any": "Sve",
        "rc-change-size": "$1",
        "rc-change-size-new": "$1 {{PLURAL:$1|bajt|bajta|bajtova}} posle izmene",
        "newsectionsummary": "/* $1 */ novi odeljak",
index 5eb4ab7..148cde9 100644 (file)
        "newpageletter": "Näi",
        "boteditletter": "B",
        "number_of_watching_users_pageview": "[$1 beooboachtjende {{PLURAL:$1|Benutser|Benutsere}}]",
-       "rc_categories": "Bloot Sieden uut do Kategorien (tränd mäd „|“):",
-       "rc_categories_any": "Aal",
        "rc-change-size": "$1 {{PLURAL:$1|Byte|Bytes}}",
        "newsectionsummary": "Näie Apsats /* $1 */",
        "rc-enhanced-expand": "Details anwiese (bruukt JavaScript)",
index ca646b2..fa6ae89 100644 (file)
        "newpageletter": "A",
        "boteditletter": "b",
        "number_of_watching_users_pageview": "[$1 {{PLURAL:$1|ngawaskeun|ngawaskeun}}]",
-       "rc_categories": "Watesan nepi ka kategori (dipisah ku \"|\"):",
-       "rc_categories_any": "Unggal nu kapilih",
        "rc-change-size-new": "$1 {{PLURAL:$1|bit|bit}} sanggeus robah",
        "newsectionsummary": "/* $1 */ bagean anyar",
        "rc-enhanced-expand": "Témbongkeun rincian",
index bd5e3ff..3ab3adb 100644 (file)
        "newpageletter": "N",
        "boteditletter": "b",
        "number_of_watching_users_pageview": "[$1 bevakande {{PLURAL:$1|användare|användare}}]",
-       "rc_categories": "Begränsa till följande kategorier (separera med \"|\"):",
-       "rc_categories_any": "Någon av de valda",
        "rc-change-size-new": "$1 {{PLURAL:$1|byte}} efter ändring",
        "newsectionsummary": "/* $1 */ nytt avsnitt",
        "rc-enhanced-expand": "Visa detaljer",
        "rollback-success": "Återställde ändringar av {{GENDER:$3|$1}};\nändrade tillbaka till senaste versionen av {{GENDER:$4|$2}}.",
        "rollback-success-notify": "Återställde ändringar av $1;\nändrade tillbaka till senaste sidversion av $2. [$3 Visa ändringar]",
        "sessionfailure-title": "Sessionsfel",
-       "sessionfailure": "Något med din session som inloggad är på tok. Din begärda åtgärd har avbrutits, för att förhindra att någon kapar din session. Klicka på \"Tillbaka\" i din webbläsare och ladda om den sida du kom ifrån. Försök sedan igen.",
+       "sessionfailure": "Någonting med din inloggningssession är på tok;\ndin begärda åtgärd har avbrutits för att förhindra att någon kapar din session.\nSkicka formuläret igen.",
        "changecontentmodel": "Ändra innehållsmodell för en sida",
        "changecontentmodel-legend": "Ändra innehållsmodell",
        "changecontentmodel-title-label": "Sidtitel",
        "watchlistedit-clear-titles": "Sidor:",
        "watchlistedit-clear-submit": "Rensa bevakningslistan (Detta är permanent!)",
        "watchlistedit-clear-done": "Din bevakningslista har rensats.",
+       "watchlistedit-clear-jobqueue": "Din bevakningslista skapas. Detta kan ta en stund!",
        "watchlistedit-clear-removed": "{{PLURAL:$1|1 sida|$1 sidor}} togs bort:",
        "watchlistedit-too-many": "Det finns för många sidor att visa här.",
        "watchlisttools-clear": "Rensa bevakningslistan",
index 7a2bbba..219a4f6 100644 (file)
        "newpageletter": "P",
        "boteditletter": "r",
        "number_of_watching_users_pageview": "[idadi ya {{PLURAL:$1|watumiaji}} wanaoufuatilia ni $1]",
-       "rc_categories": "Chagua jamii zingine (uzitenge na kigawaji hiki \"|\")",
-       "rc_categories_any": "Yoyote",
        "rc-change-size-new": "$1 {{PLURAL:$1|byte|bytes}} baada ya mabadiliko",
        "newsectionsummary": "/* $1 */ mjadala mpya",
        "rc-enhanced-expand": "Onyesha maelezo",
index 66ce850..0ba4ef5 100644 (file)
        "newpageletter": "N",
        "boteditletter": "b",
        "number_of_watching_users_pageview": "[$1 {{PLURAL:$1|dowajůncy pozůr užytkowńik|dowajůncych pozůr užytkowńikůw}}]",
-       "rc_categories": "Uůgrańič do katygorii (oddźelej za půmocům \"|\")",
-       "rc_categories_any": "Wšyskie",
        "rc-change-size-new": "$1 {{PLURAL:$1|bajt|bajty|bajtůw}} po půmjyńyńu",
        "newsectionsummary": "/* $1 */ nowo tajla",
        "rc-enhanced-expand": "Pokoż szczygůły",
index 638d3eb..979c3f2 100644 (file)
        "newpageletter": "பு",
        "boteditletter": "தா",
        "number_of_watching_users_pageview": "[இப்பக்க்த்தை {{PLURAL:$1|ஒரு பயனர் பார்கிறார்|$1 பயனர்கள் பார்கிறார்கள்}}]",
-       "rc_categories": "பகுப்புகளுக்கு மட்டுப்படுத்து (\"|\" குறியீட்டால் பிரிக்கப்பட்டுள்ளது)",
-       "rc_categories_any": "தெரிவு செய்ததில் ஏதாவது",
        "rc-change-size-new": "$1 {{PLURAL:$1|பைட்டு|பைட்டுகள்}} -மாற்றத்திற்குப் பிறகு",
        "newsectionsummary": "/* $1 */ புதிய பகுதி",
        "rc-enhanced-expand": "விவரத்தை காட்டு",
index 449a412..ca2bec2 100644 (file)
        "minoreditletter": "cipuq",
        "newpageletter": "Giqas",
        "boteditletter": "squliq na kikay",
-       "rc_categories_any": "Ana nanu’ binzyagan na",
        "rc-change-size-new": "sin-nbah$1 {{PLURAL:bzyaqan kkayal na llpgan}}",
        "rc-old-title": "pins’ruxsa minqsu’ na lalu’ ga \"$1\"",
        "recentchangeslinked": "M’ubuy quw zyuwaw na sinbahan",
index 8686631..9f1cba9 100644 (file)
        "minoreditletter": "ಕಿ",
        "newpageletter": "ಪೊ",
        "boteditletter": "ಬಾ",
-       "rc_categories_any": "ಒವ್ವೇ",
        "rc-change-size-new": "$1 {{PLURAL:$1|ಬೈಟ್|ಬೈಟ್‍ಲು}}ಬದಲಾವಣೆಡ್ದ್ ಬುಕ್ಕೊ",
        "newsectionsummary": "\n/* $1 */ಪೊಸ ವಿಭಾಗ",
        "rc-enhanced-expand": "ವಿವರೊಲೆನ್ ತೊಜಾವ್",
index 696bcfc..03054cd 100644 (file)
        "newpageletter": "కొ",
        "boteditletter": "బా",
        "number_of_watching_users_pageview": "[వీక్షిస్తున్న సభ్యులు: {{PLURAL:$1|ఒక్కరు|$1}}]",
-       "rc_categories": "ఈ వర్గాలకు పరిమితం చెయ్యి (\"|\" తో వేరు చెయ్యండి):",
-       "rc_categories_any": "ఎంచుకున్నది ఏదయినా",
        "rc-change-size-new": "మార్పు తర్వాత $1 {{PLURAL:$1|బైటు|బైట్లు}}",
        "newsectionsummary": "/* $1 */ కొత్త విభాగం",
        "rc-enhanced-expand": "వివరాలను చూపించు",
index 82a51cd..85d3bf0 100644 (file)
        "newpageletter": "Нав",
        "boteditletter": "б",
        "number_of_watching_users_pageview": "[$1 пайгирикунанда {{PLURAL:$1|корбар|корбарон}}]",
-       "rc_categories": "Маҳдудият ба гурӯҳҳо (бо аломати \"|\" ҷудо кунед)",
-       "rc_categories_any": "Ҳар кадом",
        "rc-change-size-new": "$1 {{PLURAL:$1|байт}} пас аз тағйир",
        "newsectionsummary": "/* $1 */ бахши ҷадид",
        "rc-enhanced-expand": "Намоиши ҷузъиёт",
index effda3d..36e76c3 100644 (file)
        "newpageletter": "Nav",
        "boteditletter": "b",
        "number_of_watching_users_pageview": "[$1 pajgirikunanda {{PLURAL:$1|korbar|korbaron}}]",
-       "rc_categories": "Mahdudijat ba gurūhho (bo alomati \"|\" çudo kuned)",
-       "rc_categories_any": "Har kadom",
        "newsectionsummary": "/* $1 */ baxşi çadid",
        "rc-enhanced-expand": "Namoişi çuz'ijot (nijozmand ba Çava Skript)",
        "rc-enhanced-hide": "Pinhoni çuz'ijot",
index e163eef..e55fa27 100644 (file)
        "talkpagelinktext": "คุย",
        "specialpage": "หน้าพิเศษ",
        "personaltools": "เครื่องมือส่วนตัว",
-       "talk": "อภิà¸\9bราย",
+       "talk": "à¸\84ุย",
        "views": "ดู",
        "toolbox": "เครื่องมือ",
        "tool-link-userrights": "เปลี่ยนกลุ่ม{{GENDER:$1|ผู้ใช้}}",
        "boteditletter": "บ",
        "unpatrolledletter": "!",
        "number_of_watching_users_pageview": "[$1 ผู้ใช้เฝ้าดู]",
-       "rc_categories": "จำกัดเฉพาะหมวดหมู่ (แยกด้วย \"|\"):",
-       "rc_categories_any": "อะไรก็ได้ที่เลือก",
        "rc-change-size-new": "$1 ไบต์หลังเปลี่ยนแปลง",
        "newsectionsummary": "/* $1 */ ส่วนใหม่",
        "rc-enhanced-expand": "แสดงรายละเอียด",
        "unwatchthispage": "เลิกเฝ้าดูหน้านี้",
        "notanarticle": "ไม่ใช่หน้าเนื้อหา",
        "notvisiblerev": "รุ่นล่าสุดโดยผู้ใช้อีกคนถูกลบแล้ว",
-       "watchlist-details": "มี $1 à¸«à¸\99à¹\89าà¹\83à¸\99รายà¸\81ารà¹\80à¸\9dà¹\89าà¸\94ูà¸\82อà¸\87à¸\84ุà¸\93 (รวมหà¸\99à¹\89าà¸\9eูà¸\94à¸\84ุย)",
+       "watchlist-details": "มี $1 หน้าในรายการเฝ้าดูของคุณ (รวมหน้าคุย)",
        "wlheader-enotif": "เปิดใช้งานการแจ้งเตือนผ่านอีเมล",
        "wlheader-showupdated": "หน้าที่มีการเปลี่ยนแปลงตั้งแต่คุณเยี่ยมครั้งสุดท้ายแสดงด้วย<strong>ตัวหนา</strong>",
        "wlnote": "ด้านล่างเป็น{{PLURAL:$1|การเปลี่ยนแปลงหลังสุด| <strong>$1</strong> การเปลี่ยนแปลงหลังสุด}} ใน{{PLURAL:$2|ชั่วโมง| <strong>$2</strong> ชั่วโมง}}ที่หลังสุด จนถึง $3, $4",
        "deletepage": "ลบหน้า",
        "confirm": "ยืนยัน",
        "excontent": "เนื้อหาเดิม: \"$1\"",
-       "excontentauthor": "à¹\80à¸\99ืà¹\89อหาà¹\80à¸\94ิม: \"$1\" à¹\81ละมีà¸\9cูà¹\89à¹\80à¸\82ียà¸\99à¸\84à¸\99à¹\80à¸\94ียวà¸\84ือ \"[[Special:Contributions/$2|$2]]\" ([[User talk:$2|à¸\9eูà¸\94à¸\84ุย]])",
+       "excontentauthor": "เนื้อหาเดิม: \"$1\" และมีผู้เขียนคนเดียวคือ \"[[Special:Contributions/$2|$2]]\" ([[User talk:$2|คุย]])",
        "exbeforeblank": "เนื้อหาก่อนถูกทำว่างคือ: \"$1\"",
        "delete-confirm": "ลบ \"$1\"",
        "delete-legend": "ลบ",
        "rollback-missingparam": "ในคำขอไม่มีตัวแปรเสริมที่ต้องการ",
        "rollback-missingrevision": "ไม่สามารถดึงข้อมูลรุ่น",
        "cantrollback": "ไม่สามารถย้อนการแก้ไขได้ ผู้เขียนคนล่าสุดเป็นผู้เขียนคนเดียวของหน้านี้",
-       "alreadyrolled": "à¹\84มà¹\88สามารà¸\96ยà¹\89อà¸\99รวà¸\94à¹\80à¸\94ียวà¸\81ารà¹\81à¸\81à¹\89à¹\84à¸\82สุà¸\94à¸\97à¹\89ายà¹\82à¸\94ย [[User:$2|$2]] ([[User talk:$2|à¸\9eูà¸\94à¸\84ุย]]{{int:pipe-separator}}[[Special:Contributions/$2|{{int:contribslink}}]]) à¹\83à¸\99หà¸\99à¹\89า [[:$1]] à¸¡à¸µà¸\9cูà¹\89อืà¹\88à¸\99à¹\84à¸\94à¹\89à¹\81à¸\81à¹\89à¹\84à¸\82หรือยà¹\89อà¸\99รวà¸\94à¹\80à¸\94ียวหà¸\99à¹\89าà¸\99ีà¹\89à¹\84à¸\9bà¸\81à¹\88อà¸\99à¹\81ลà¹\89ว\n\nà¸\9cูà¹\89à¹\81à¸\81à¹\89à¹\84à¸\82ลà¹\88าสุà¸\94à¸\82อà¸\87หà¸\99à¹\89าà¸\99ีà¹\89à¸\84ือ [[User:$3|$3]] ([[User talk:$3|à¸\9eูà¸\94คุย]]{{int:pipe-separator}}[[Special:Contributions/$3|{{int:contribslink}}]])",
+       "alreadyrolled": "à¹\84มà¹\88สามารà¸\96ยà¹\89อà¸\99รวà¸\94à¹\80à¸\94ียวà¸\81ารà¹\81à¸\81à¹\89à¹\84à¸\82สุà¸\94à¸\97à¹\89ายà¹\82à¸\94ย [[User:$2|$2]] ([[User talk:$2|à¸\84ุย]]{{int:pipe-separator}}[[Special:Contributions/$2|{{int:contribslink}}]]) à¹\83à¸\99หà¸\99à¹\89า [[:$1]] à¸¡à¸µà¸\9cูà¹\89อืà¹\88à¸\99à¹\84à¸\94à¹\89à¹\81à¸\81à¹\89à¹\84à¸\82หรือยà¹\89อà¸\99รวà¸\94à¹\80à¸\94ียวหà¸\99à¹\89าà¸\99ีà¹\89à¹\84à¸\9bà¸\81à¹\88อà¸\99à¹\81ลà¹\89ว\n\nà¸\9cูà¹\89à¹\81à¸\81à¹\89à¹\84à¸\82ลà¹\88าสุà¸\94à¸\82อà¸\87หà¸\99à¹\89าà¸\99ีà¹\89à¸\84ือ [[User:$3|$3]] ([[User talk:$3|คุย]]{{int:pipe-separator}}[[Special:Contributions/$3|{{int:contribslink}}]])",
        "editcomment": "คำอธิบายการแก้ไขคือ: <em>$1</em>",
-       "revertpage": "ย้อนการแก้ไขโดย [[Special:Contributions/$2|$2]] ([[User talk:$2|Talk]]) ไปยังรุ่นแก้ไขล่าสุดโดย [[User:$1|$1]]",
+       "revertpage": "ย้อนการแก้ไขโดย [[Special:Contributions/$2|$2]] ([[User talk:$2|คุย]]) ไปยังรุ่นแก้ไขล่าสุดโดย [[User:$1|$1]]",
        "revertpage-nouser": "ย้อนการแก้ไขโดยผู้ใช้ไม่ระบุชื่อไปยังรุ่นล่าสุดโดย {{GENDER:$1|[[User:$1|$1]]}}",
        "rollback-success": "ย้อนการแก้ไขโดย $1; \nเปลี่ยนกลับไปรุ่นล่าสุดโดย $2",
        "rollback-success-notify": "ย้อนการแก้ไขโดย $1;\nเปลี่ยนกลับไปรุ่นล่าสุดโดย $2 [$3 แสดงการเปลี่ยนแปลง]",
        "tooltip-invert": "เลือกกล่องนี้เพื่อซ่อนการเปลี่ยนแปลงไปยังหน้าในเนมเปซที่เลือก (และเนมสเปซที่เกี่ยวข้องถ้าเลือก)",
        "tooltip-whatlinkshere-invert": "เลือกกล่องนี้เพื่อซ่อนลิงก์จากหน้าในเนมสเปซที่เลือก",
        "namespace_association": "เนมสเปซที่เกี่ยวข้อง",
-       "tooltip-namespace_association": "à¹\80ลือà¸\81à¸\81ลà¹\88อà¸\87à¸\99ีà¹\89à¹\80à¸\9eืà¹\88อรวมà¹\80à¸\99มสà¹\80à¸\9bà¸\8bà¸\9eูà¸\94à¸\84ุยหรือหัวà¸\82à¹\89อที่เกี่ยวข้องกับเนมสเปซที่เลือกด้วย",
+       "tooltip-namespace_association": "à¹\80ลือà¸\81à¸\81ลà¹\88อà¸\87à¸\99ีà¹\89à¹\80à¸\9eืà¹\88อรวมà¹\80à¸\99มสà¹\80à¸\9bà¸\8bà¸\84ุยหรือà¹\80รืà¹\88อà¸\87ที่เกี่ยวข้องกับเนมสเปซที่เลือกด้วย",
        "blanknamespace": "(หลัก)",
        "contributions": "เรื่องที่{{GENDER:$1|ผู้ใช้}}นี้เขียน",
        "contributions-title": "เรื่องที่เขียนโดย $1",
        "sp-contributions-deleted": "การแก้ไขของผู้ใช้ที่ถูกลบ",
        "sp-contributions-uploads": "อัปโหลด",
        "sp-contributions-logs": "ปูม",
-       "sp-contributions-talk": "à¸\9eูà¸\94à¸\84ุย",
+       "sp-contributions-talk": "คุย",
        "sp-contributions-userrights": "การจัดการสิทธิผู้ใช้",
        "sp-contributions-blocked-notice": "ปัจจุบันผู้ใช้นี้ถูกบล็อก\nปูมการบล็อกล่าสุดแสดงด้านล่างนี้เพื่อการอ้างอิง:",
        "sp-contributions-blocked-notice-anon": "ปัจจุบันเลขที่อยู่ไอพีนี้ถูกบล็อก\nปูมการบล็อกล่าสุดแสดงด้านล่างนี้เพื่อการอ้างอิง:",
        "block-log-flags-nocreate": "ปิดใช้งานการสร้างบัญชี",
        "block-log-flags-noautoblock": "ปิดใช้งานการบล็อกอัตโนมัติ",
        "block-log-flags-noemail": "ปิดใช้งานอีเมล",
-       "block-log-flags-nousertalk": "à¹\84มà¹\88สามารà¸\96à¹\81à¸\81à¹\89à¹\84à¸\82หà¸\99à¹\89าà¸\9eูà¸\94à¸\84ุยของตนเอง",
+       "block-log-flags-nousertalk": "à¹\84มà¹\88สามารà¸\96à¹\81à¸\81à¹\89à¹\84à¸\82หà¸\99à¹\89าà¸\84ุยà¸\81ัà¸\9aà¸\9cูà¹\89à¹\83à¸\8aà¹\89ของตนเอง",
        "block-log-flags-angry-autoblock": "การบล็อกอัตโนมัติขั้นสูงเปิดใช้งาน",
        "block-log-flags-hiddenname": "ชื่อผู้ใช้ถูกซ่อน",
        "range_block_disabled": "การบล็อกช่วงไอพีของผู้ดูแลระบบถูกปิดใช้งาน",
        "move-page-legend": "เปลี่ยนชื่อ",
        "movepagetext": "การใช้แบบด้านล่างจะเปลี่ยนชื่อหน้า และย้ายประวัติทั้งหมดไปชื่อใหม่\nชื่อเรื่องเก่าจะกลายเป็นหน้าเปลี่ยนทางไปชื่อเรื่องใหม่\nคุณสามารถปรับการเปลี่ยนทางซึ่งชี้ไปยังชื่อเรื่องเดิมได้อัตโนมัติ\nแต่หากคุณเลือกไม่ทำเช่นนั้น ให้แน่ใจว่าตรวจสอบ[[Special:DoubleRedirects|หน้าเปลี่ยนทางซ้ำซ้อน]]หรือ[[Special:BrokenRedirects|หน้าเปลี่ยนทางเสีย]]\nคุณเป็นผู้รับผิดชอบเพื่อให้แน่ใจว่าลิงก์ต่าง ๆ ยังชี้ไปยังที่ที่สมควร\n\nโปรดทราบว่าหน้าดังกล่าวจะ<strong>ไม่</strong>ถูกย้าย ถ้ามีหน้าที่ใช้ชื่อเรื่องใหม่แล้ว เว้นแต่หน้านั้นเป็นหน้าเปลี่ยนทาง และไม่มีประวัติการแก้ไขในอดีต\nซึ่งหมายความว่า คุณสามารถเปลี่ยนชื่อหน้ากลับเป็นชื่อเดิมได้หากคุณทำผิดพลาด และคุณไม่สามารถเขียนทับหน้าที่มีอยู่แล้วได้\n\n<strong>คำเตือน!</strong>\nสิ่งนี้อาจเป็นการเปลี่ยนแปลงที่รุนแรงและไม่คาดคิดสำหรับหน้าที่เป็นที่นิยม\nโปรดให้แน่ใจว่าคุณเข้าใจผลลัพธ์นี้ก่อนดำเนินการ",
        "movepagetext-noredirectfixer": "การใช้แบบด้านล่างจะเปลี่ยนชื่อหน้า ซึ่งจะทำให้ประวัติทั้งหมดย้ายไปยังชื่อใหม่\nชื่อเรื่องเก่าจะกลายเป็นหน้าเปลี่ยนทางไปยังชื่อเรื่องใหม่\nให้แน่ใจว่า ตรวจสอบ[[Special:DoubleRedirects|หน้าเปลี่ยนทางซ้ำซ้อน]]หรือ[[Special:BrokenRedirects|หน้าเปลี่ยนทางที่เสีย]]\nคุณจะเป็นผู้รับผิดชอบเพื่อให้แน่ใจว่าลิงก์ต่าง ๆ ยังชี้ไปยังที่ที่สมควร\n\nโปรดทราบว่าหน้าดังกล่าวจะ'''ไม่'''ถูกย้าย ถ้ามีหน้าที่ใช้ชื่อเรื่องใหม่อยู่แล้ว เว้นแต่เป็นหน้าว่างหรือหน้าเปลี่ยนทาง และไม่มีประวัติการแก้ไขในอดีต\nซึ่งหมายความว่า คุณสามารถเปลี่ยนชื่อหน้ากลับเป็นชื่อเดิมได้หากคุณทำผิดพลาด และคุณไม่สามารถเขียนทับหน้าที่มีอยู่แล้วได้\n\n'''คำเตือน!'''\nสิ่งนี้อาจเป็นการเปลี่ยนแปลงที่รุนแรงและไม่คาดคิดสำหรับหน้าที่เป็นที่นิยม\nโปรดแน่ใจว่าคุณเข้าใจถึงผลลัพธ์นี้ก่อนที่จะดำเนินการต่อไป",
-       "movepagetalktext": "หาà¸\81à¸\84ุà¸\93à¹\80ลือà¸\81à¸\81ลà¹\88อà¸\87à¸\99ีà¹\89 à¸«à¸\99à¹\89าà¸\9eูà¸\94à¸\84ุยà¸\82อà¸\87หà¸\99à¹\89าà¸\99ีà¹\89à¸\88ะà¸\96ูà¸\81ยà¹\89ายà¹\84à¸\9bà¸\8aืà¹\88อà¹\80รืà¹\88อà¸\87à¹\83หมà¹\88à¹\82à¸\94ยอัà¸\95à¹\82à¸\99มัà¸\95ิà¹\80วà¹\89à¸\99à¹\81à¸\95à¹\88à¸\9bลายà¸\97าà¸\87มีหà¸\99à¹\89าà¸\9eูà¸\94คุยไม่ว่างแล้ว\n\nในกรณีเหล่านี้ คุณจะต้องย้ายหรือผสานหน้าเองหากต้องการ",
+       "movepagetalktext": "หาà¸\81à¸\84ุà¸\93à¹\80ลือà¸\81à¸\81ลà¹\88อà¸\87à¸\99ีà¹\89 à¸«à¸\99à¹\89าà¸\84ุยà¸\82อà¸\87หà¸\99à¹\89าà¸\99ีà¹\89à¸\88ะà¸\96ูà¸\81ยà¹\89ายà¹\84à¸\9bà¸\8aืà¹\88อà¹\80รืà¹\88อà¸\87à¹\83หมà¹\88à¹\82à¸\94ยอัà¸\95à¹\82à¸\99มัà¸\95ิà¹\80วà¹\89à¸\99à¹\81à¸\95à¹\88à¸\9bลายà¸\97าà¸\87มีหà¸\99à¹\89าคุยไม่ว่างแล้ว\n\nในกรณีเหล่านี้ คุณจะต้องย้ายหรือผสานหน้าเองหากต้องการ",
        "moveuserpage-warning": "<strong>คำเตือน:</strong> คุณกำลังย้ายหน้าผู้ใช้ โปรดทราบว่าหน้าผู้ใช้เท่านั้นที่จะถูกเปลี่ยนชื่อ แต่ผู้ใช้จะ<em>ไม่</em>ถูกเปลี่ยนชื่อ",
        "movecategorypage-warning": "<strong>คำเตือน:</strong> คุณกำลังย้ายหน้าหมวดหมู่ โปรดทราบว่า จะย้ายเฉพาะหน้าและทุกหน้าในหมวดหมู่เก่าจะ<em>ไม่</em>ถูกจัดเข้าหมวดหมู่ใหม่",
        "movenologintext": "ถ้าต้องการเปลี่ยนชื่อหน้านี้ ต้องเป็นผู้ใช้ลงทะเบียนและ[[Special:UserLogin|ล็อกอิน]]",
        "movepage-moved-noredirect": "การสร้างหน้าเปลี่ยนทางถูกระงับ",
        "articleexists": "หน้าที่ต้องการมีอยู่แล้ว หรือชื่อที่เลือกไม่ถูกต้อง กรุณาเลือกชื่อใหม่",
        "cantmove-titleprotected": "คุณไม่สามารถเปลี่ยนชื่อหน้าเป็นชื่อนี้ได้ เนื่องจากชื่อเรื่องใหม่ถูกป้องกันมิให้สร้าง",
-       "movetalk": "à¹\80à¸\9bลีà¹\88ยà¸\99à¸\8aืà¹\88อหà¸\99à¹\89าà¸\9eูà¸\94คุยที่สัมพันธ์",
+       "movetalk": "ยà¹\89ายหà¸\99à¹\89าคุยที่สัมพันธ์",
        "move-subpages": "ย้ายหน้าย่อยทั้งหมด (มากสุด $1 หน้า)",
-       "move-talk-subpages": "ยà¹\89ายหà¸\99à¹\89ายà¹\88อยà¸\97ัà¹\89à¸\87หมà¸\94à¸\82อà¸\87หà¸\99à¹\89าอภิà¸\9bราย (มากสุด $1 หน้า)",
+       "move-talk-subpages": "ยà¹\89ายหà¸\99à¹\89ายà¹\88อยà¸\97ัà¹\89à¸\87หมà¸\94à¸\82อà¸\87หà¸\99à¹\89าà¸\84ุย (มากสุด $1 หน้า)",
        "movepage-page-exists": "มีหน้า $1 อยู่แล้วและไม่สามารถบันทึกทับอัตโนมัติ",
        "movepage-page-moved": "เปลี่ยนชื่อหน้า $1 เป็น $2 แล้ว",
        "movepage-page-unmoved": "ไม่สามารถเปลี่ยนชื่อหน้า $1 เป็น $2",
        "movelogpagetext": "ด้านล่างเป็นรายการการเปลี่ยนชื่อทั้งหมด",
        "movesubpage": "{{PLURAL:$1|หน้าย่อย|หน้าย่อย}}",
        "movesubpagetext": "หน้านี้มีหน้าย่อย $1 หน้า ดังด้านล่าง",
-       "movesubpagetalktext": "หà¸\99à¹\89าà¸\9eูà¸\94à¸\84ุยà¸\97ีà¹\88สัมà¸\9eัà¸\99à¸\98à¹\8cมี $1 à¸«à¸\99à¹\89ายà¹\88อย à¸\94ัà¸\87à¹\81สà¸\94à¸\87à¸\94à¹\89าà¸\99ลà¹\88าà¸\87",
+       "movesubpagetalktext": "หน้าคุยที่สัมพันธ์มี $1 หน้าย่อย ดังแสดงด้านล่าง",
        "movenosubpage": "หน้านี้ไม่มีหน้าย่อย",
        "movereason": "เหตุผล:",
        "revertmove": "ย้อน",
        "javascripttest-qunit-intro": "ดู[$1 เอกสารกำกับการทดสอบ]บน mediawiki.org",
        "tooltip-pt-userpage": "{{GENDER:|หน้าผู้ใช้}}ของคุณ",
        "tooltip-pt-anonuserpage": "หน้าผู้ใช้ของเลขที่อยู่ไอพีที่คุณกำลังใช้แก้ไข",
-       "tooltip-pt-mytalk": "หà¸\99à¹\89าà¸\9eูà¸\94à¸\84ุย{{GENDER:|à¸\82อà¸\87à¸\84ุà¸\93}}",
+       "tooltip-pt-mytalk": "หน้าคุย{{GENDER:|ของคุณ}}",
        "tooltip-pt-anontalk": "อภิปรายเกี่ยวกับการแก้ไขจากเลขที่อยู่ไอพีนี้",
        "tooltip-pt-preferences": "การตั้งค่า{{GENDER:|ของคุณ}}",
        "tooltip-pt-watchlist": "รายการหน้าที่คุณกำลังเฝ้าดูการเปลี่ยนแปลง",
        "scarytranscludefailed": "[ไม่สามารถดึงแม่แบบมาได้สำหรับ $1]",
        "scarytranscludetoolong": "[ยูอาร์แอลยาวเกินไป]",
        "deletedwhileediting": "<strong>คำเตือน:</strong>  หน้านี้ถูกลบหลังคุณเริ่มแก้ไข!",
-       "confirmrecreate": "à¸\9cูà¹\89à¹\83à¸\8aà¹\89 [[User:$1|$1]] ([[User talk:$1|à¸\9eูà¸\94à¸\84ุย]]) à¸¥à¸\9aหà¸\99à¹\89าà¸\99ีà¹\89หลัà¸\87à¸\84ุà¸\93à¹\80ริà¹\88มà¹\81à¸\81à¹\89à¹\84à¸\82 à¸\94à¹\89วยà¹\80หà¸\95ุà¸\9cลวà¹\88า:\n: <em>$2</em>\nกรุณายืนยันว่า คุณต้องการสร้างหน้านี้ใหม่จริง ๆ",
-       "confirmrecreate-noreason": "à¸\9cูà¹\89à¹\83à¸\8aà¹\89 [[User:$1|$1]] ([[User talk:$1|à¸\9eูà¸\94à¸\84ุย]]) à¸¥à¸\9aหà¸\99à¹\89าà¸\99ีà¹\89หลัà¸\87à¸\84ุà¸\93à¹\80ริà¹\88มà¹\81à¸\81à¹\89à¹\84à¸\82 à¹\82à¸\9bรà¸\94ยืà¸\99ยัà¸\99วà¹\88าà¸\84ุà¸\93à¸\95à¹\89อà¸\87à¸\81ารสรà¹\89าà¸\87หà¸\99à¹\89าà¸\99ีà¹\89à¹\83หมà¹\88à¸\88ริà¸\87 à¹\86",
+       "confirmrecreate": "à¸\9cูà¹\89à¹\83à¸\8aà¹\89 [[User:$1|$1]] ([[User talk:$1|à¸\84ุย]]) à¸¥à¸\9aหà¸\99à¹\89าà¸\99ีà¹\89หลัà¸\87à¸\84ุà¸\93à¹\80ริà¹\88มà¹\81à¸\81à¹\89à¹\84à¸\82à¸\94à¹\89วยà¹\80หà¸\95ุà¸\9cล:\n: <em>$2</em>\nกรุณายืนยันว่า คุณต้องการสร้างหน้านี้ใหม่จริง ๆ",
+       "confirmrecreate-noreason": "ผู้ใช้ [[User:$1|$1]] ([[User talk:$1|คุย]]) ลบหน้านี้หลังคุณเริ่มแก้ไข โปรดยืนยันว่าคุณต้องการสร้างหน้านี้ใหม่จริง ๆ",
        "recreate": "สร้างใหม่",
        "confirm-purge-title": "ชะล้างหน้านี้",
        "confirm_purge_button": "ตกลง",
        "watchlisttools-view": "ดูการเปลี่ยนแปลงที่เกี่ยวข้อง",
        "watchlisttools-edit": "ดูและแก้ไขรายการเฝ้าดู",
        "watchlisttools-raw": "แก้ไขรายการเฝ้าดูดิบ",
-       "signature": "[[{{ns:user}}:$1|$2]] ([[{{ns:user_talk}}:$1|à¸\9eูà¸\94à¸\84ุย]])",
+       "signature": "[[{{ns:user}}:$1|$2]] ([[{{ns:user_talk}}:$1|คุย]])",
        "timezone-local": "ท้องถิ่น",
        "duplicate-defaultsort": "<strong>คำเตือน:</strong> หลักเรียงลำดับปริยาย \"$2\" ได้ลบล้างหลักเรียงลำดับปริยาย \"$1\" ที่มีอยู่ก่อนหน้า",
        "version": "รุ่น",
index 40d36a6..73e5cd2 100644 (file)
        "newpageletter": "T",
        "boteditletter": "b",
        "number_of_watching_users_pageview": "[$1 {{PLURAL:$1|ulanyjy|ulanyjy}} gözegçilik edýär]",
-       "rc_categories": "Kategoriýalar bilen çäklendir (\"|\" bilen aýyr)",
-       "rc_categories_any": "Islendik",
        "newsectionsummary": "/* $1 */ täze bölüm",
        "rc-enhanced-expand": "Jikme-jikligi görkez",
        "rc-enhanced-hide": "Jikme-jiklikleri gizle",
index 2e8b8e9..9d822ad 100644 (file)
        "boteditletter": "b",
        "unpatrolledletter": "!",
        "number_of_watching_users_pageview": "[$1 binabantayang {{PLURAL:$1|tagagamit|mga tagagamit}}]",
-       "rc_categories": "Itakda lang sa mga kaurian (ihiwalay sa pamamagitan ng \"|\")",
-       "rc_categories_any": "Kahit ano",
        "rc-change-size": "$1",
        "rc-change-size-new": "$1 {{PLURAL:$1|byte}} pagkaraan ng pagbabago",
        "newsectionsummary": "/* $1 */ bagong seksyon",
index 3bed975..02f50c0 100644 (file)
        "minoreditletter": "г",
        "newpageletter": "Т",
        "boteditletter": "б",
-       "rc_categories_any": "Һар гылә",
        "newsectionsummary": "/* $1 */ нујә мывзу",
        "rc-enhanced-expand": "Тәфсилотон нишо дој (JavaScript истифодә бедә)",
        "rc-enhanced-hide": "Тәфсилотон нијо кардеј",
index ed2838b..d62346b 100644 (file)
        "minoreditletter": "s",
        "newpageletter": "F",
        "boteditletter": "m",
-       "rc_categories": "Fakangatangata ki he faʻahinga (vaheʻi he \"|\")",
-       "rc_categories_any": "Faʻahinga noa pē",
        "rc-enhanced-expand": "ʻAsi ngaahi ʻeu (fiemaʻu ʻa e ''Javascript'')",
        "rc-enhanced-hide": "Toi ngaahi ʻeu",
        "recentchangeslinked": "Ngaahi liliu fekauʻaki",
index 324ac59..82afb38 100644 (file)
        "minoreditletter": "m",
        "newpageletter": "N",
        "boteditletter": "b",
-       "rc_categories": "Soim ol senis insait long ol dispela grup tasol (raitim wantaim \"|\" namel long wanwan)",
-       "rc_categories_any": "Olgeta",
        "recentchangeslinked": "Ol senis klostu",
        "recentchangeslinked-feed": "Ol senis klostu",
        "recentchangeslinked-toolbox": "Ol senis klostu",
index d0d8ceb..bf16795 100644 (file)
        "recentchanges-legend-heading": "<strong>Gösterge:</strong>",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (ayrıca [[Special:NewPages|yeni sayfalar listesine]] bakınız)",
        "recentchanges-submit": "Göster",
+       "rcfilters-legend-heading": "<strong>Kısaltmalar listesi:</strong>",
        "rcfilters-other-review-tools": "Diğer inceleme araçları",
        "rcfilters-group-results-by-page": "Sayfalandırılmış grup sonuçları",
        "rcfilters-activefilters": "Etkin süzgeçler",
        "rcfilters-advancedfilters": "Gelişmiş süzgeçler",
        "rcfilters-limit-title": "Gösterilecek sonuçlar",
        "rcfilters-limit-and-date-label": "$1 değişiklik, $2",
+       "rcfilters-date-popup-title": "Aranacak zaman dilimi",
        "rcfilters-days-title": "Son günler",
        "rcfilters-hours-title": "Son saatler",
        "rcfilters-days-show-days": "$1 gün",
        "newpageletter": "Y",
        "boteditletter": "b",
        "number_of_watching_users_pageview": "[$1 izlenilen {{PLURAL:$1|kullanıcı|kullanıcı}}]",
-       "rc_categories": "Kategorileri sınırla (\"|\" ile ayır)",
-       "rc_categories_any": "Seçilen herhangi bir",
        "rc-change-size-new": "Değişiklikten sonraki boyut: $1 {{PLURAL:$1|bayt|bayt}}",
        "newsectionsummary": "/* $1 */ yeni başlık",
        "rc-enhanced-expand": "Ayrıntıları göster",
index 56b6f9e..fe6c9bf 100644 (file)
        "newpageletter": "Я",
        "boteditletter": "б",
        "number_of_watching_users_pageview": "[$1 {{PLURAL:$1|күзәтүче кулланучы}}]",
-       "rc_categories": "Төркемнәрдән генә («|» бүлүче):",
-       "rc_categories_any": "Сайланганның һәрберсе",
        "rc-change-size-new": "Кертелгән үзгәрешләр белән бергә зурлык: $1 {{PLURAL:$1|байт}}",
        "newsectionsummary": "/* $1 */ яңа бүлек",
        "rc-enhanced-expand": "Ваклыкларны күрсәтү",
index 7bb64cf..91cf0b4 100644 (file)
        "newpageletter": "Y",
        "boteditletter": "b",
        "number_of_watching_users_pageview": "[$1 {{PLURAL:$1|küzätep tora qullanuçı}}]",
-       "rc_categories": "Törkemnärdä genä tora («|» bülüçe)",
-       "rc_categories_any": "Härber",
        "rc-change-size-new": "üzgäreştän soñ $1 {{PLURAL:$1|bayt}}",
        "newsectionsummary": "/* $1 */ yaña bülek",
        "rc-enhanced-expand": "Waqlıqlarnı kürsätü (JavaScript kiräk)",
index a1c22fb..dc4821d 100644 (file)
        "newpageletter": "ⵏ",
        "boteditletter": "ⴱ",
        "unpatrolledletter": "!",
-       "rc_categories_any": "ⵎⴰⵏ",
        "recentchangeslinked-toolbox": "ⵉⴱⴷⴷⴻⵍⵏ ⵖⵓⵔ ⵜⴰⵣⴷⴰⵢⵜ",
        "recentchangeslinked-page": "ⴰⵙⵙⴰⵖ ⵏ ⵜⴰⵙⵏⴰ:",
        "upload": "ⵣⴷⴻⵎ ⴰⵙⴷⴰⵡ",
index 82eefc5..706c3a4 100644 (file)
        "boteditletter": "ماشىنا ئادەم",
        "unpatrolledletter": "!",
        "number_of_watching_users_pageview": "[$1  {{PLURAL:$1|ئىشلەتكۈچى|ئىشلەتكۈچى}}كۆزىتىۋاتىدۇ]",
-       "rc_categories": "تۈر چېگرىسى (\"|\" بىلەن ئايرىلىدۇ )",
-       "rc_categories_any": "خالىغانچە تاللاش",
        "rc-change-size": "$1",
        "rc-change-size-new": "ئۆزگەرتكەندىن كېيىن $1 {{PLURAL:$1|بايت}}",
        "newsectionsummary": "* $1 * يېڭى ئابزاس",
index d40a8d8..10f2833 100644 (file)
        "boteditletter": "б",
        "unpatrolledletter": "!",
        "number_of_watching_users_pageview": "[$1 {{PLURAL:$1|користувач спостерігає|користувачі спостерігають|користувачів спостерігають}}]",
-       "rc_categories": "Тільки з категорій (розділювач «|»):",
-       "rc_categories_any": "Будь-яка з обраних",
        "rc-change-size": "$1",
        "rc-change-size-new": "Розмір після зміни: $1 {{PLURAL:$1|байт|байти|байтів}}",
        "newsectionsummary": "/* $1 */ нова тема",
index d363408..e33c545 100644 (file)
        "newpageletter": "نیا ..",
        "boteditletter": " خودکار",
        "number_of_watching_users_pageview": "[$1 مشاہد {{PLURAL:$1|صارف|صارفین}}]",
-       "rc_categories": "ان زمروں تک محدود رکھیں («|» سے علاحدہ کریں):",
-       "rc_categories_any": "کوئی بھی منتخب",
        "rc-change-size-new": "تبدیلی کے بعد $1 {{PLURAL:$1|بائٹ}}",
        "newsectionsummary": "/* $1 */ نیا قطعہ",
        "rc-enhanced-expand": "تفصیلات دکھائیں",
        "logentry-move-move": "$1 نے صفحہ $3 کو $4 کی جانب منتقل کیا",
        "logentry-move-move-noredirect": "$1 نے صفحہ $3 کو $4 کی جانب بدون رجوع مکرر {{GENDER:$2|منتقل کیا}}",
        "logentry-move-move_redir": "$1 نے رجوع مکرر ہٹا کر صفحہ $3 کو $4 کی جانب {{GENDER:$2|منتقل کیا}}",
-       "logentry-move-move_redir-noredirect": "$1 نے صفحہ $3 کو رجوع مکرر چھوڑے بغیر $4 کی جانب جو رجوع مکر تھا {{GENDER:$2|منتقل کیا}}",
+       "logentry-move-move_redir-noredirect": "$1 نے صفحہ $3 کو رجوع مکرر چھوڑے بغیر $4 کی جانب جو رجوع مکرر تھا {{GENDER:$2|منتقل کیا}}",
        "logentry-patrol-patrol": "$1 نے صفحہ $3 کے نسخہ $4 کو مراجعت شدہ {{GENDER:$2|نشان زد کیا}}",
        "logentry-patrol-patrol-auto": "$1 نے صفحہ $3 کے نسخہ $4 کو خودکار طور پر مراجعت شدہ {{GENDER:$2|نشان زد کیا}}",
        "logentry-newusers-newusers": "صارف کھاتہ $1 {{GENDER:$2|تخلیق ہو چکا ہے}}",
index 4c45461..b4b772b 100644 (file)
        "newpageletter": "N",
        "boteditletter": "b",
        "number_of_watching_users_pageview": "[osservà da {{PLURAL:$1|un utente|$1 utenti}}]",
-       "rc_categories": "Limita a le categorie (separà da \"|\")",
-       "rc_categories_any": "Qualsiasi",
        "rc-change-size-new": "$1 {{PLURAL:$1|byte}} dopo ła modifega",
        "newsectionsummary": "/* $1 */ sezion nova",
        "rc-enhanced-expand": "Mostra detaji",
index 33e5953..61c6728 100644 (file)
        "newpageletter": "U",
        "boteditletter": "b",
        "number_of_watching_users_pageview": "[$1 {{PLURAL:$1|kaclii kävutai|kaclijad kävutajad}}]",
-       "rc_categories": "Vaiše kategorijoišpäi (erigoitkat znamaižel \"|\")",
-       "rc_categories_any": "Eraz",
        "rc-change-size": "$1",
        "rc-change-size-new": "$1 {{PLURAL:$1|bait|baitad}} jäl'ges toižetamišt",
        "newsectionsummary": "/* $1 */ uz' jaguz",
index ab931ff..85456b2 100644 (file)
        "newpageletter": "M",
        "boteditletter": "b",
        "number_of_watching_users_pageview": "[$1 người đang xem]",
-       "rc_categories": "Hạn chế theo thể loại (phân cách bằng “|”):",
-       "rc_categories_any": "Bất kỳ được chọn",
        "rc-change-size-new": "$1 byte sau thay đổi",
        "newsectionsummary": "Đề mục mới: /* $1 */",
        "rc-enhanced-expand": "Xem chi tiết",
index 0162941..478a77f 100644 (file)
        "newpageletter": "N",
        "boteditletter": "b",
        "number_of_watching_users_pageview": "[{{PLURAL:$1|geban|gebans}} galädöl $1]",
-       "rc_categories": "Te klads fovik (ditolös me el \"|\")",
-       "rc_categories_any": "Alseimik",
        "rc-change-size-new": "{{PLURAL:$1|jölät|jöläts}} $1 po votükam",
        "newsectionsummary": "/* $1 */ diläd nulik",
        "rc-enhanced-expand": "Jonön patis",
index d77bff2..5caa187 100644 (file)
        "newpageletter": "V",
        "boteditletter": "rb",
        "number_of_watching_users_pageview": "[{{PLURAL:$1|$1 perräkaejat|üts perräkaeja}}]",
-       "rc_categories": "Õnnõ katõgoorijist (eräldedäs märgiga \"|\")",
-       "rc_categories_any": "Miä taht",
        "rc-change-size-new": "$1 {{PLURAL:$1|bait|baiti}} peräst muutmist",
        "rc-enhanced-expand": "Näütäq ütsikasjo",
        "rc-enhanced-hide": "Käkiq ütsikas'aq ärq",
index 3b13ff3..c84e1e2 100644 (file)
        "newpageletter": "N",
        "boteditletter": "b",
        "number_of_watching_users_pageview": "[shuvou pa $1 {{PLURAL:$1|uzeu|uzeus}}]",
-       "rc_categories": "Limiter åzès categoreyes (separer avou des «|»)",
-       "rc_categories_any": "Totes",
        "rc-change-size-new": "$1 {{PLURAL:$1|octet|octets}} après l' candjmint",
        "newsectionsummary": "/* $1 */ novele seccion",
        "rc-enhanced-expand": "Mostrer les detays",
index d99800e..9c35d91 100644 (file)
        "newpageletter": "B",
        "boteditletter": "b",
        "number_of_watching_users_pageview": "[$1 nagbabatay hin {{PLURAL:$1|gumaramit|mga gumaramit}}]",
-       "rc_categories_any": "Bisan ano nga pinili",
        "rc-change-size-new": "$1 {{PLURAL:$1|nga byte|nga mga byte}} kahuman han pagbag-o",
        "newsectionsummary": "/* $1 */ bag-o nga bahin",
        "rc-enhanced-expand": "Igpakita an detalye",
index 5f96e7e..a82560f 100644 (file)
@@ -8,7 +8,8 @@
                        "SF-Language",
                        "Urhixidur",
                        "아라",
-                       "Macofe"
+                       "Macofe",
+                       "Fanjiayi"
                ]
        },
        "tog-underline": "Rëddaatu lëkkalekaay yi :",
        "newpageletter": "N",
        "boteditletter": "b",
        "number_of_watching_users_pageview": "[{{PLURAL:$1|jëfandikukat moo koy topp|$1 jëfandikukat ñoo koy topp}}]",
-       "rc_categories": "Digalub wàll yi (xaajale leen ak « \"|\" »)",
-       "rc_categories_any": "Yépp",
        "rc-change-size": "$1",
        "rc-change-size-new": "$1 {{PLURAL:$1|byte|bytes}} ginnaaw coppite gi",
        "newsectionsummary": "/* $1 */ xaaj bu bees",
        "contributions": "Cëruy bii {{GENDER:$1|jëfandikukat}}",
        "contributions-title": "Cëru yu jëfandikukat bii di $1",
        "mycontris": "Cëru",
+       "anoncontribs": "Cëru",
        "contribsub2": "Ngir $1 ($2)",
        "nocontribs": "Amul benn coppite bu melokaanoo nii bu ñu gis.",
        "uctop": "(bi mujj)",
        "spam_blanking": "Setal nañ wecc sumb yi amoon lëkkalekaay buy jëme $1",
        "simpleantispam-label": "Caytu lànk-spam.\n<strong>Bu</strong> fi yokk lenn!",
        "pageinfo-toolboxlink": "Xibaar ci xët wi",
+       "pageinfo-contentpage-yes": "Waaw",
        "previousdiff": "← Coppite yi gën a yàgg",
        "nextdiff": "Coppite yi mujj →",
        "file-info": "Réyaayu file bi : $1, type MIME : $2",
index 5aeadb0..eda5374 100644 (file)
        "newpageletter": "ახ.",
        "boteditletter": "ბ",
        "number_of_watching_users_pageview": "[$1 {{PLURAL:$1|მომხმარებლის|მომხმარებლის}} კონტროლი]",
-       "rc_categories": "ხვალო კატეგორიეფშე (გეგშართით \"|\"-იშ მეჯინათ)",
-       "rc_categories_any": "არძონერი",
        "rc-change-size-new": "ზჷმა თირუაშ უკული რე: {{PLURAL:$1|ბაიტი|ბაიტი}}",
        "newsectionsummary": "/* $1 */ ახალი სექცია",
        "rc-enhanced-expand": "დეტალების  ჩვენება",
index c4c61e2..d0d7069 100644 (file)
        "newpageletter": "נ",
        "boteditletter": "ב",
        "number_of_watching_users_pageview": "[{{PLURAL:$1|איין באַניצער פאַסט|$1 באַניצערס פאַסן}} אויף]",
-       "rc_categories": "גרענעץ פֿאַר קאַטעגאריעס (אָפשיידן מיט \"|\")",
-       "rc_categories_any": "איינער פון די געקליבענע",
        "rc-change-size-new": "$1 {{PLURAL:$1|בייט|בייטן}} נאך דער ענדערונג",
        "newsectionsummary": "/* $1 */ נייע אפטיילונג",
        "rc-enhanced-expand": "צייגן דעטאלן",
index ed42790..5183213 100644 (file)
        "newpageletter": "T",
        "boteditletter": "b",
        "number_of_watching_users_pageview": "[{{PLURAL:$1|Oníṣe $1|Àwọn oníṣe $1}} ún ṣe ìmójútó]",
-       "rc_categories": "Òpin sí àwọn ẹ̀ka (pínsọ́tọ̀ pẹ̀lú \"|\")",
-       "rc_categories_any": "Èyíkéyìí",
        "rc-change-size-new": "$1 {{PLURAL:$1|byte|bytes}} lẹ́yìn àtúnṣe",
        "newsectionsummary": "/* $1 */ abala tuntun",
        "rc-enhanced-expand": "Ìfihàn ẹ̀kúnrẹ́rẹ́",
index b303cf7..4a1f11d 100644 (file)
        "newpageletter": "N",
        "boteditletter": "b",
        "number_of_watching_users_pageview": "[$1位用戶監視]",
-       "rc_categories": "限定到分類(以\"|\"作分隔):",
-       "rc_categories_any": "任何揀咗嘅",
        "rc-change-size-new": "改完後係$1位元組",
        "newsectionsummary": "/* $1 */ 新小節",
        "rc-enhanced-expand": "顯示細節",
index 2eb2b61..01a162d 100644 (file)
        "newpageletter": "N",
        "boteditletter": "b",
        "number_of_watching_users_pageview": "[$1 {{PLURAL:$1|keêr|keêr}} op een volglieste]",
-       "rc_categories": "Beperk'n tot categorieën (scheien mie een \"|\")",
-       "rc_categories_any": "Elk'n",
        "newsectionsummary": "/* $1 */ nieuwe subkop",
        "rc-enhanced-expand": "Details weerheven (JavaScript vereist)",
        "rc-enhanced-hide": "Verbarg details",
index 298d6b3..f97c234 100644 (file)
        "newpageletter": "新",
        "boteditletter": "机",
        "number_of_watching_users_pageview": "[$1个关注用户]",
-       "rc_categories": "分类限制(用“|”分隔):",
-       "rc_categories_any": "任何选择的",
        "rc-change-size-new": "更改后有$1字节",
        "newsectionsummary": "/* $1 */ 新章节",
        "rc-enhanced-expand": "显示细节",
index 0387142..212487e 100644 (file)
        "nosuchaction": "無此動作",
        "nosuchactiontext": "URL 所指定的動作無效。\n您的 URL 可能輸入錯誤,或點選了錯誤的連結。\n這也可能是 {{SITENAME}} 使用的系統出現問題。",
        "nosuchspecialpage": "無此特殊頁面",
-       "nospecialpagetext": "<strong>您請求的特殊頁面無效。</strong>\n\n欲取得有效的特殊頁面清單可至 [[Special:SpecialPages|{{int:specialpages}}]]。",
+       "nospecialpagetext": "<strong>您請求的特定頁面無效。</strong>\n\n欲取得有效的特定頁面清單可至 [[Special:SpecialPages|{{int:specialpages}}]]。",
        "error": "錯誤",
        "databaseerror": "資料庫錯誤",
        "databaseerror-text": "出現資料庫查詢錯誤。\n這可能表示系統有問題存在。",
        "newpageletter": "新",
        "boteditletter": "機",
        "number_of_watching_users_pageview": "[$1 位正在監視的使用者]",
-       "rc_categories": "分類限制 (以 \"|\" 分隔):",
-       "rc_categories_any": "任何選擇的",
        "rc-change-size-new": "變更後為 $1 位元組",
        "newsectionsummary": "/* $1 */ 新章節",
        "rc-enhanced-expand": "顯示詳細資料",
        "creditspage": "頁面製作群",
        "nocredits": "此頁面沒有製作群資訊。",
        "spamprotectiontitle": "垃圾訊息過濾程式",
-       "spamprotectiontext": "您輸入文字內容已被垃圾訊息過濾程式禁止儲存,\n可能因您的內容包含了已封鎖的外部連結。",
+       "spamprotectiontext": "您輸入文字內容已被垃圾訊息過濾程式禁止儲存,可能因您的內容包含了已封鎖的外部連結。",
        "spamprotectionmatch": "以下文字內容觸發垃圾訊息過濾程式:$1",
        "spambot_username": "MediaWiki 垃圾訊息清理",
        "spam_reverting": "還原至未包含 $1 連結的最新修訂",
        "colon-separator": ":",
        "word-separator": "",
        "ellipsis": "…",
-       "parentheses": " ($1)",
+       "parentheses": "($1)",
        "quotation-marks": "\"$1\"",
        "imgmultipageprev": "← 上一頁",
        "imgmultipagenext": "下一頁 →",
        "logentry-protect-protect-cascade": "$1 {{GENDER:$2|已保護}} $3 $4 [連鎖]",
        "logentry-protect-modify": "$1 {{GENDER:$2|已更改}} $3 的保護層級 $4",
        "logentry-protect-modify-cascade": "$1 {{GENDER:$2|已更改}} $3 的保護層級 $4 [連鎖]",
-       "logentry-rights-rights": "$1 {{GENDER:$2|已更改}} {{GENDER:$6|$3}} 的群組成員資格由 $4 成為 $5",
+       "logentry-rights-rights": "$1已將{{GENDER:$6|$3}}的使用者群組從$4{{GENDER:$2|更改}}至$5",
        "logentry-rights-rights-legacy": "$1 {{GENDER:$2|已更改}} $3 的群組成員資格",
        "logentry-rights-autopromote": "$1 已自動{{GENDER:$2|提升}}從 $4 成為 $5",
        "logentry-upload-upload": "$1 {{GENDER:$2|已上傳}} $3",
        "logentry-tag-update-remove-logentry": "$1 {{GENDER:$2|已移除}}{{PLURAL:$9|標籤|標籤}} $8 自日誌項目 $3 的修訂 $5。",
        "logentry-tag-update-revision": "$1 {{GENDER:$2|已更新}}標籤於頁面 $3 的修訂 $4 ({{PLURAL:$7|加入}} $6; {{PLURAL:$9|移除}} $8)。",
        "logentry-tag-update-logentry": "$1 {{GENDER:$2|已更新}}標籤於頁面 $3 的日誌項目 $5 ({{PLURAL:$7|加入}} $6; {{PLURAL:$9|移除}} $8)。",
-       "rightsnone": "(無)",
+       "rightsnone": "(無)",
        "rightslogentry-temporary-group": "$1 (臨時,直到 $2)",
        "feedback-adding": "正在新增意見回饋至頁面...",
        "feedback-back": "返回",
index 617071b..7e4bf7c 100644 (file)
@@ -514,6 +514,8 @@ abstract class Maintenance {
                        "http://en.wikipedia.org. This is sometimes necessary because " .
                        "server name detection may fail in command line scripts.", false, true );
                $this->addOption( 'profiler', 'Profiler output format (usually "text")', false, true );
+               // This is named --mwdebug, because --debug would conflict in the phpunit.php CLI script.
+               $this->addOption( 'mwdebug', 'Enable built-in MediaWiki development settings', false, true );
 
                # Save generic options to display them separately in help
                $this->mGenericParameters = $this->mParams;
@@ -1149,6 +1151,11 @@ abstract class Maintenance {
                        MediaWikiServices::getInstance()->getDBLoadBalancerFactory()->destroy();
                }
 
+               # Apply debug settings
+               if ( $this->hasOption( 'mwdebug' ) ) {
+                       require __DIR__ . '/../includes/DevelopmentSettings.php';
+               }
+
                // Per-script profiling; useful for debugging
                $this->activateProfiler();
 
index 04c00e2..9903c9e 100644 (file)
@@ -245,7 +245,7 @@ class FindHooks extends Maintenance {
                $m = [];
                preg_match_all(
                        // All functions which runs hooks
-                       '/(?:wfRunHooks|Hooks\:\:run)\s*\(\s*' .
+                       '/(?:wfRunHooks|Hooks\:\:run|Hooks\:\:runWithoutAbort)\s*\(\s*' .
                                // First argument is the hook name as string
                                '([\'"])(.*?)\1' .
                                // Comma for second argument
index ad47ee0..e139c3a 100644 (file)
@@ -1441,7 +1441,6 @@ return [
        'mediawiki.action.edit.preview' => [
                'scripts' => 'resources/src/mediawiki.action/mediawiki.action.edit.preview.js',
                'dependencies' => [
-                       'jquery.form',
                        'jquery.spinner',
                        'jquery.textSelection',
                        'mediawiki.api',
@@ -1766,9 +1765,14 @@ return [
                        'oojs',
                        'mediawiki.api',
                        'mediawiki.api.options',
+                       'mediawiki.jqueryMsg',
                        'mediawiki.Uri',
                        'mediawiki.user',
                ],
+               'messages' => [
+                       'quotation-marks',
+                       'rcfilters-filterlist-title',
+               ],
        ],
        'mediawiki.rcfilters.filters.ui' => [
                'scripts' => [
@@ -1924,6 +1928,7 @@ return [
                'dependencies' => [
                        'oojs-ui-widgets',
                        'jquery.makeCollapsible',
+                       'mediawiki.jqueryMsg',
                        'mediawiki.language',
                        'mediawiki.user',
                        'mediawiki.util',
index 9af7ab2..57578a6 100644 (file)
@@ -6,7 +6,6 @@
  * @singleton
  */
 
-/* eslint-disable no-use-before-define */
 /* global Uint8Array */
 
 ( function ( mw, $ ) {
                        return mw.msg( sizeMsgs[ 0 ], Math.round( s ) );
                }
 
+               /**
+                * Start loading a file into memory; when complete, pass it as a
+                * data URL to the callback function. If the callbackBinary is set it will
+                * first be read as binary and afterwards as data URL. Useful if you want
+                * to do preprocessing on the binary data first.
+                *
+                * @param {File} file
+                * @param {Function} callback
+                * @param {Function} callbackBinary
+                */
+               function fetchPreview( file, callback, callbackBinary ) {
+                       var reader = new FileReader();
+                       if ( callbackBinary && 'readAsBinaryString' in reader ) {
+                               // To fetch JPEG metadata we need a binary string; start there.
+                               // TODO
+                               reader.onload = function () {
+                                       callbackBinary( reader.result );
+
+                                       // Now run back through the regular code path.
+                                       fetchPreview( file, callback );
+                               };
+                               reader.readAsBinaryString( file );
+                       } else if ( callbackBinary && 'readAsArrayBuffer' in reader ) {
+                               // readAsArrayBuffer replaces readAsBinaryString
+                               // However, our JPEG metadata library wants a string.
+                               // So, this is going to be an ugly conversion.
+                               reader.onload = function () {
+                                       var i,
+                                               buffer = new Uint8Array( reader.result ),
+                                               string = '';
+                                       for ( i = 0; i < buffer.byteLength; i++ ) {
+                                               string += String.fromCharCode( buffer[ i ] );
+                                       }
+                                       callbackBinary( string );
+
+                                       // Now run back through the regular code path.
+                                       fetchPreview( file, callback );
+                               };
+                               reader.readAsArrayBuffer( file );
+                       } else if ( 'URL' in window && 'createObjectURL' in window.URL ) {
+                               // Supported in Firefox 4.0 and above <https://developer.mozilla.org/en/DOM/window.URL.createObjectURL>
+                               // WebKit has it in a namespace for now but that's ok. ;)
+                               //
+                               // Lifetime of this URL is until document close, which is fine
+                               // for Special:Upload -- if this code gets used on longer-running
+                               // pages, add a revokeObjectURL() when it's no longer needed.
+                               //
+                               // Prefer this over readAsDataURL for Firefox 7 due to bug reading
+                               // some SVG files from data URIs <https://bugzilla.mozilla.org/show_bug.cgi?id=694165>
+                               callback( window.URL.createObjectURL( file ) );
+                       } else {
+                               // This ends up decoding the file to base-64 and back again, which
+                               // feels horribly inefficient.
+                               reader.onload = function () {
+                                       callback( reader.result );
+                               };
+                               reader.readAsDataURL( file );
+                       }
+               }
+
+               /**
+                * Clear the file upload preview area.
+                */
+               function clearPreview() {
+                       $( '#mw-upload-thumbnail' ).remove();
+               }
+
                /**
                 * Show a thumbnail preview of PNG, JPEG, GIF, and SVG files prior to upload
                 * in browsers supporting HTML5 FileAPI.
                        } : null );
                }
 
-               /**
-                * Start loading a file into memory; when complete, pass it as a
-                * data URL to the callback function. If the callbackBinary is set it will
-                * first be read as binary and afterwards as data URL. Useful if you want
-                * to do preprocessing on the binary data first.
-                *
-                * @param {File} file
-                * @param {Function} callback
-                * @param {Function} callbackBinary
-                */
-               function fetchPreview( file, callback, callbackBinary ) {
-                       var reader = new FileReader();
-                       if ( callbackBinary && 'readAsBinaryString' in reader ) {
-                               // To fetch JPEG metadata we need a binary string; start there.
-                               // TODO
-                               reader.onload = function () {
-                                       callbackBinary( reader.result );
-
-                                       // Now run back through the regular code path.
-                                       fetchPreview( file, callback );
-                               };
-                               reader.readAsBinaryString( file );
-                       } else if ( callbackBinary && 'readAsArrayBuffer' in reader ) {
-                               // readAsArrayBuffer replaces readAsBinaryString
-                               // However, our JPEG metadata library wants a string.
-                               // So, this is going to be an ugly conversion.
-                               reader.onload = function () {
-                                       var i,
-                                               buffer = new Uint8Array( reader.result ),
-                                               string = '';
-                                       for ( i = 0; i < buffer.byteLength; i++ ) {
-                                               string += String.fromCharCode( buffer[ i ] );
-                                       }
-                                       callbackBinary( string );
-
-                                       // Now run back through the regular code path.
-                                       fetchPreview( file, callback );
-                               };
-                               reader.readAsArrayBuffer( file );
-                       } else if ( 'URL' in window && 'createObjectURL' in window.URL ) {
-                               // Supported in Firefox 4.0 and above <https://developer.mozilla.org/en/DOM/window.URL.createObjectURL>
-                               // WebKit has it in a namespace for now but that's ok. ;)
-                               //
-                               // Lifetime of this URL is until document close, which is fine
-                               // for Special:Upload -- if this code gets used on longer-running
-                               // pages, add a revokeObjectURL() when it's no longer needed.
-                               //
-                               // Prefer this over readAsDataURL for Firefox 7 due to bug reading
-                               // some SVG files from data URIs <https://bugzilla.mozilla.org/show_bug.cgi?id=694165>
-                               callback( window.URL.createObjectURL( file ) );
-                       } else {
-                               // This ends up decoding the file to base-64 and back again, which
-                               // feels horribly inefficient.
-                               reader.onload = function () {
-                                       callback( reader.result );
-                               };
-                               reader.readAsDataURL( file );
-                       }
-               }
-
-               /**
-                * Clear the file upload preview area.
-                */
-               function clearPreview() {
-                       $( '#mw-upload-thumbnail' ).remove();
-               }
-
                /**
                 * Check if the file does not exceed the maximum size
                 *
index 4d56940..177861e 100644 (file)
         * @return {string}
         */
        ForeignStructuredUpload.prototype.getDescriptions = function () {
+               var upload = this;
                return this.descriptions.map( function ( desc ) {
-                       return this.config.format.description
+                       return upload.config.format.description
                                .replace( '$LANGUAGE', desc.language )
                                .replace( '$TEXT', desc.text );
                } ).join( '\n' );
index 596c118..fe0b029 100644 (file)
@@ -34,7 +34,7 @@ window.mwNow = ( function () {
  * - Firefox 4+
  * - Safari 5+
  * - Opera 15+
- * - Mobile Safari 5.1+ (iOS 5+)
+ * - Mobile Safari 6.0+ (iOS 6+)
  * - Android 4.1+
  *
  * Browsers we support in our no-javascript run-time (Grade C):
index 9719862..514150c 100644 (file)
@@ -87,7 +87,6 @@ class ResourceLoaderTestModule extends ResourceLoaderModule {
        protected $dependencies = [];
        protected $group = null;
        protected $source = 'local';
-       protected $position = 'bottom';
        protected $script = '';
        protected $styles = '';
        protected $skipFunction = null;
@@ -126,9 +125,6 @@ class ResourceLoaderTestModule extends ResourceLoaderModule {
        public function getSource() {
                return $this->source;
        }
-       public function getPosition() {
-               return $this->position;
-       }
 
        public function getType() {
                return $this->type;
diff --git a/tests/phpunit/data/registration/bad_spdx.json b/tests/phpunit/data/registration/bad_spdx.json
new file mode 100644 (file)
index 0000000..383ab04
--- /dev/null
@@ -0,0 +1,6 @@
+{
+       "name": "FooBar",
+       "license-name": "not a license identifier",
+       "manifest_version": 1
+}
+
diff --git a/tests/phpunit/data/registration/good.json b/tests/phpunit/data/registration/good.json
new file mode 100644 (file)
index 0000000..ad16c5e
--- /dev/null
@@ -0,0 +1,4 @@
+{
+       "name": "FooBar",
+       "manifest_version": 1
+}
diff --git a/tests/phpunit/data/registration/invalid.json b/tests/phpunit/data/registration/invalid.json
new file mode 100644 (file)
index 0000000..4d1fa58
--- /dev/null
@@ -0,0 +1,5 @@
+{
+       "name": "FooBar",
+       "license-name": [ "array" ],
+       "manifest_version": 1
+}
diff --git a/tests/phpunit/data/registration/newer_manifest_version.json b/tests/phpunit/data/registration/newer_manifest_version.json
new file mode 100644 (file)
index 0000000..29c668e
--- /dev/null
@@ -0,0 +1,4 @@
+{
+       "name": "FooBar",
+       "manifest_version": 999999
+}
diff --git a/tests/phpunit/data/registration/no_manifest_version.json b/tests/phpunit/data/registration/no_manifest_version.json
new file mode 100644 (file)
index 0000000..1a6119f
--- /dev/null
@@ -0,0 +1,3 @@
+{
+       "name": "FooBar"
+}
diff --git a/tests/phpunit/data/registration/notjson.txt b/tests/phpunit/data/registration/notjson.txt
new file mode 100644 (file)
index 0000000..d47b460
--- /dev/null
@@ -0,0 +1 @@
+This is definitely not JSON.
diff --git a/tests/phpunit/data/registration/old_manifest_version.json b/tests/phpunit/data/registration/old_manifest_version.json
new file mode 100644 (file)
index 0000000..f50faa1
--- /dev/null
@@ -0,0 +1,4 @@
+{
+       "name": "FooBar",
+       "manifest_version": -2
+}
index cdbf9fd..56bde5d 100644 (file)
@@ -11,9 +11,10 @@ class SiteStatsTest extends MediaWikiTestCase {
                $cache = \MediaWiki\MediaWikiServices::getInstance()->getMainWANObjectCache();
                $jobq = JobQueueGroup::singleton();
 
-               // Delete EditPage jobs that might have been left behind by other tests
+               // Delete jobs that might have been left behind by other tests
                $jobq->get( 'htmlCacheUpdate' )->delete();
                $jobq->get( 'recentChangesUpdate' )->delete();
+               $jobq->get( 'userGroupExpiry' )->delete();
                $cache->delete( $cache->makeKey( 'SiteStats', 'jobscount' ) );
 
                $jobq->push( new NullJob( Title::newMainPage(), [] ) );
index 369aa83..2de35a7 100644 (file)
@@ -6,8 +6,6 @@ use Wikimedia\Rdbms\DatabaseSqlite;
 use Wikimedia\Rdbms\ResultWrapper;
 
 class DatabaseSqliteMock extends DatabaseSqlite {
-       private $lastQuery;
-
        public static function newInstance( array $p = [] ) {
                $p['dbFilePath'] = ':memory:';
                $p['schema'] = false;
@@ -16,8 +14,6 @@ class DatabaseSqliteMock extends DatabaseSqlite {
        }
 
        function query( $sql, $fname = '', $tempIgnore = false ) {
-               $this->lastQuery = $sql;
-
                return true;
        }
 
index fa9898d..606c12d 100644 (file)
@@ -108,7 +108,7 @@ class DatabaseTestHelper extends Database {
 
        public function tableExists( $table, $fname = __METHOD__ ) {
                $tableRaw = $this->tableName( $table, 'raw' );
-               if ( isset( $this->mSessionTempTables[$tableRaw] ) ) {
+               if ( isset( $this->sessionTempTables[$tableRaw] ) ) {
                        return true; // already known to exist
                }
 
index 4097760..2892283 100644 (file)
@@ -194,12 +194,12 @@ class LBFactoryTest extends MediaWikiTestCase {
         * @covers \Wikimedia\Rdbms\ChronologyProtector
         */
        public function testChronologyProtector() {
-               // (a) First HTTP request
-               $m1Pos = new MySQLMasterPos( 'db1034-bin.000976', '843431247' );
-               $m2Pos = new MySQLMasterPos( 'db1064-bin.002400', '794074907' );
-
                $now = microtime( true );
 
+               // (a) First HTTP request
+               $m1Pos = new MySQLMasterPos( 'db1034-bin.000976/843431247', $now );
+               $m2Pos = new MySQLMasterPos( 'db1064-bin.002400/794074907', $now );
+
                // Master DB 1
                $mockDB1 = $this->getMockBuilder( DatabaseMysqli::class )
                        ->disableOriginalConstructor()
index dcdb1cd..b706fac 100644 (file)
@@ -10,8 +10,10 @@ class BadTitleErrorTest extends MediaWikiTestCase {
                try {
                        throw new BadTitleError();
                } catch ( BadTitleError $e ) {
+                       ob_start();
                        $e->report();
-                       $this->assertTrue( true );
+                       $text = ob_get_clean();
+                       $this->assertContains( $e->getText(), $text );
                }
        }
 
index 15f0896..5214b6d 100644 (file)
@@ -11,8 +11,10 @@ class ThrottledErrorTest extends MediaWikiTestCase {
                try {
                        throw new ThrottledError();
                } catch ( ThrottledError $e ) {
+                       ob_start();
                        $e->report();
-                       $this->assertTrue( true );
+                       $text = ob_get_clean();
+                       $this->assertContains( $e->getText(), $text );
                }
        }
 
index caf1281..ce067aa 100644 (file)
@@ -216,17 +216,32 @@ class DatabaseMysqlBaseTest extends PHPUnit_Framework_TestCase {
                        $db->listViews( '' ) );
        }
 
+       public function testBinLogName() {
+               $pos = new MySQLMasterPos( "db1052.2424/4643", 1 );
+
+               $this->assertEquals( "db1052", $pos->binlog );
+               $this->assertEquals( "db1052.2424", $pos->getLogFile() );
+               $this->assertEquals( [ 2424, 4643 ], $pos->pos );
+       }
+
        /**
         * @dataProvider provideComparePositions
         * @covers Wikimedia\Rdbms\MySQLMasterPos
         */
-       public function testHasReached( MySQLMasterPos $lowerPos, MySQLMasterPos $higherPos, $match ) {
+       public function testHasReached(
+               MySQLMasterPos $lowerPos, MySQLMasterPos $higherPos, $match, $hetero
+       ) {
                if ( $match ) {
                        $this->assertTrue( $lowerPos->channelsMatch( $higherPos ) );
 
-                       $this->assertTrue( $higherPos->hasReached( $lowerPos ) );
-                       $this->assertTrue( $higherPos->hasReached( $higherPos ) );
+                       if ( $hetero ) {
+                               // Each position is has one channel higher than the other
+                               $this->assertFalse( $higherPos->hasReached( $lowerPos ) );
+                       } else {
+                               $this->assertTrue( $higherPos->hasReached( $lowerPos ) );
+                       }
                        $this->assertTrue( $lowerPos->hasReached( $lowerPos ) );
+                       $this->assertTrue( $higherPos->hasReached( $higherPos ) );
                        $this->assertFalse( $lowerPos->hasReached( $higherPos ) );
                } else { // channels don't match
                        $this->assertFalse( $lowerPos->channelsMatch( $higherPos ) );
@@ -237,53 +252,100 @@ class DatabaseMysqlBaseTest extends PHPUnit_Framework_TestCase {
        }
 
        public static function provideComparePositions() {
+               $now = microtime( true );
+
                return [
                        // Binlog style
                        [
-                               new MySQLMasterPos( 'db1034-bin.000976', '843431247' ),
-                               new MySQLMasterPos( 'db1034-bin.000976', '843431248' ),
-                               true
+                               new MySQLMasterPos( 'db1034-bin.000976/843431247', $now ),
+                               new MySQLMasterPos( 'db1034-bin.000976/843431248', $now ),
+                               true,
+                               false
                        ],
                        [
-                               new MySQLMasterPos( 'db1034-bin.000976', '999' ),
-                               new MySQLMasterPos( 'db1034-bin.000976', '1000' ),
-                               true
+                               new MySQLMasterPos( 'db1034-bin.000976/999', $now ),
+                               new MySQLMasterPos( 'db1034-bin.000976/1000', $now ),
+                               true,
+                               false
                        ],
                        [
-                               new MySQLMasterPos( 'db1034-bin.000976', '999' ),
-                               new MySQLMasterPos( 'db1035-bin.000976', '1000' ),
+                               new MySQLMasterPos( 'db1034-bin.000976/999', $now ),
+                               new MySQLMasterPos( 'db1035-bin.000976/1000', $now ),
+                               false,
                                false
                        ],
                        // MySQL GTID style
                        [
-                               new MySQLMasterPos( 'db1-bin.2', '1', '3E11FA47-71CA-11E1-9E33-C80AA9429562:23' ),
-                               new MySQLMasterPos( 'db1-bin.2', '2', '3E11FA47-71CA-11E1-9E33-C80AA9429562:24' ),
-                               true
+                               new MySQLMasterPos( '3E11FA47-71CA-11E1-9E33-C80AA9429562:23', $now ),
+                               new MySQLMasterPos( '3E11FA47-71CA-11E1-9E33-C80AA9429562:24', $now ),
+                               true,
+                               false
                        ],
                        [
-                               new MySQLMasterPos( 'db1-bin.2', '1', '3E11FA47-71CA-11E1-9E33-C80AA9429562:99' ),
-                               new MySQLMasterPos( 'db1-bin.2', '2', '3E11FA47-71CA-11E1-9E33-C80AA9429562:100' ),
-                               true
+                               new MySQLMasterPos( '3E11FA47-71CA-11E1-9E33-C80AA9429562:99', $now ),
+                               new MySQLMasterPos( '3E11FA47-71CA-11E1-9E33-C80AA9429562:100', $now ),
+                               true,
+                               false
                        ],
                        [
-                               new MySQLMasterPos( 'db1-bin.2', '1', '3E11FA47-71CA-11E1-9E33-C80AA9429562:99' ),
-                               new MySQLMasterPos( 'db1-bin.2', '2', '1E11FA47-71CA-11E1-9E33-C80AA9429562:100' ),
+                               new MySQLMasterPos( '3E11FA47-71CA-11E1-9E33-C80AA9429562:99', $now ),
+                               new MySQLMasterPos( '1E11FA47-71CA-11E1-9E33-C80AA9429562:100', $now ),
+                               false,
                                false
                        ],
                        // MariaDB GTID style
                        [
-                               new MySQLMasterPos( 'db1-bin.2', '1', '255-11-23' ),
-                               new MySQLMasterPos( 'db1-bin.2', '2', '255-11-24' ),
-                               true
+                               new MySQLMasterPos( '255-11-23', $now ),
+                               new MySQLMasterPos( '255-11-24', $now ),
+                               true,
+                               false
+                       ],
+                       [
+                               new MySQLMasterPos( '255-11-99', $now ),
+                               new MySQLMasterPos( '255-11-100', $now ),
+                               true,
+                               false
+                       ],
+                       [
+                               new MySQLMasterPos( '255-11-999', $now ),
+                               new MySQLMasterPos( '254-11-1000', $now ),
+                               false,
+                               false
+                       ],
+                       [
+                               new MySQLMasterPos( '255-11-23,256-12-50', $now ),
+                               new MySQLMasterPos( '255-11-24', $now ),
+                               true,
+                               false
+                       ],
+                       [
+                               new MySQLMasterPos( '255-11-99,256-12-50,257-12-50', $now ),
+                               new MySQLMasterPos( '255-11-1000', $now ),
+                               true,
+                               false
                        ],
                        [
-                               new MySQLMasterPos( 'db1-bin.2', '1', '255-11-99' ),
-                               new MySQLMasterPos( 'db1-bin.2', '2', '255-11-100' ),
+                               new MySQLMasterPos( '255-11-23,256-12-50', $now ),
+                               new MySQLMasterPos( '255-11-24,155-52-63', $now ),
+                               true,
+                               false
+                       ],
+                       [
+                               new MySQLMasterPos( '255-11-99,256-12-50,257-12-50', $now ),
+                               new MySQLMasterPos( '255-11-1000,256-12-51', $now ),
+                               true,
+                               false
+                       ],
+                       [
+                               new MySQLMasterPos( '255-11-99,256-12-50', $now ),
+                               new MySQLMasterPos( '255-13-1000,256-14-49', $now ),
+                               true,
                                true
                        ],
                        [
-                               new MySQLMasterPos( 'db1-bin.2', '1', '255-11-999' ),
-                               new MySQLMasterPos( 'db1-bin.2', '2', '254-11-1000' ),
+                               new MySQLMasterPos( '253-11-999,255-11-999', $now ),
+                               new MySQLMasterPos( '254-11-1000', $now ),
+                               false,
                                false
                        ],
                ];
@@ -296,28 +358,33 @@ class DatabaseMysqlBaseTest extends PHPUnit_Framework_TestCase {
        public function testChannelsMatch( MySQLMasterPos $pos1, MySQLMasterPos $pos2, $matches ) {
                $this->assertEquals( $matches, $pos1->channelsMatch( $pos2 ) );
                $this->assertEquals( $matches, $pos2->channelsMatch( $pos1 ) );
+
+               $roundtripPos = new MySQLMasterPos( (string)$pos1, 1 );
+               $this->assertEquals( (string)$pos1, (string)$roundtripPos );
        }
 
        public static function provideChannelPositions() {
+               $now = microtime( true );
+
                return [
                        [
-                               new MySQLMasterPos( 'db1034-bin.000876', '44' ),
-                               new MySQLMasterPos( 'db1034-bin.000976', '74' ),
+                               new MySQLMasterPos( 'db1034-bin.000876/44', $now ),
+                               new MySQLMasterPos( 'db1034-bin.000976/74', $now ),
                                true
                        ],
                        [
-                               new MySQLMasterPos( 'db1052-bin.000976', '999' ),
-                               new MySQLMasterPos( 'db1052-bin.000976', '1000' ),
+                               new MySQLMasterPos( 'db1052-bin.000976/999', $now ),
+                               new MySQLMasterPos( 'db1052-bin.000976/1000', $now ),
                                true
                        ],
                        [
-                               new MySQLMasterPos( 'db1066-bin.000976', '9999' ),
-                               new MySQLMasterPos( 'db1035-bin.000976', '10000' ),
+                               new MySQLMasterPos( 'db1066-bin.000976/9999', $now ),
+                               new MySQLMasterPos( 'db1035-bin.000976/10000', $now ),
                                false
                        ],
                        [
-                               new MySQLMasterPos( 'db1066-bin.000976', '9999' ),
-                               new MySQLMasterPos( 'trump2016.000976', '10000' ),
+                               new MySQLMasterPos( 'db1066-bin.000976/9999', $now ),
+                               new MySQLMasterPos( 'trump2016.000976/10000', $now ),
                                false
                        ],
                ];
index e131506..b42a367 100644 (file)
@@ -370,10 +370,34 @@ class DatabaseTest extends PHPUnit_Framework_TestCase {
                $this->assertFalse( (bool)$db->trxLevel(), "Transaction cleared." );
        }
 
+       /**
+        * @covers Wikimedia\Rdbms\Database::getScopedLockAndFlush
+        * @covers Wikimedia\Rdbms\Database::lock
+        * @covers Wikimedia\Rdbms\Database::unlock
+        * @covers Wikimedia\Rdbms\Database::lockIsFree
+        */
        public function testGetScopedLock() {
                $db = $this->getMockDB( [ 'isOpen' ] );
                $db->method( 'isOpen' )->willReturn( true );
 
+               $this->assertEquals( 0, $db->trxLevel() );
+               $this->assertEquals( true, $db->lockIsFree( 'x', __METHOD__ ) );
+               $this->assertEquals( true, $db->lock( 'x', __METHOD__ ) );
+               $this->assertEquals( false, $db->lockIsFree( 'x', __METHOD__ ) );
+               $this->assertEquals( true, $db->unlock( 'x', __METHOD__ ) );
+               $this->assertEquals( true, $db->lockIsFree( 'x', __METHOD__ ) );
+               $this->assertEquals( 0, $db->trxLevel() );
+
+               $db->setFlag( DBO_TRX );
+               $this->assertEquals( true, $db->lockIsFree( 'x', __METHOD__ ) );
+               $this->assertEquals( true, $db->lock( 'x', __METHOD__ ) );
+               $this->assertEquals( false, $db->lockIsFree( 'x', __METHOD__ ) );
+               $this->assertEquals( true, $db->unlock( 'x', __METHOD__ ) );
+               $this->assertEquals( true, $db->lockIsFree( 'x', __METHOD__ ) );
+               $db->clearFlag( DBO_TRX );
+
+               $this->assertEquals( 0, $db->trxLevel() );
+
                $db->setFlag( DBO_TRX );
                try {
                        $this->badLockingMethodImplicit( $db );
index d55372c..e2ed1d5 100644 (file)
@@ -141,23 +141,6 @@ class ParserOptionsTest extends MediaWikiTestCase {
                $confstr .= '!onPageRenderingHash';
        }
 
-       // Test weird historical behavior is still weird
-       public function testOptionsHashEditSection() {
-               $popt = ParserOptions::newCanonical();
-               $popt->registerWatcher( function ( $name ) {
-                       $this->assertNotEquals( 'editsection', $name );
-               } );
-
-               $this->assertTrue( $popt->getEditSection() );
-               $this->assertSame( 'canonical', $popt->optionsHash( [] ) );
-               $this->assertSame( 'canonical', $popt->optionsHash( [ 'editsection' ] ) );
-
-               $popt->setEditSection( false );
-               $this->assertFalse( $popt->getEditSection() );
-               $this->assertSame( 'canonical', $popt->optionsHash( [] ) );
-               $this->assertSame( 'editsection=0', $popt->optionsHash( [ 'editsection' ] ) );
-       }
-
        /**
         * @expectedException InvalidArgumentException
         * @expectedExceptionMessage Unknown parser option bogus
index 44c1773..b08ba6c 100644 (file)
@@ -1,7 +1,5 @@
 <?php
 
-use Wikimedia\TestingAccessWrapper;
-
 /**
  * @group Database
  *        ^--- trigger DB shadowing because we are using Title magic
@@ -95,31 +93,17 @@ class ParserOutputTest extends MediaWikiTestCase {
         * @covers ParserOutput::getText
         * @dataProvider provideGetText
         * @param array $options Options to getText()
-        * @param array $poState ParserOptions state fields to set
         * @param string $text Parser text
         * @param string $expect Expected output
         */
-       public function testGetText( $options, $poState, $text, $expect ) {
+       public function testGetText( $options, $text, $expect ) {
                $this->setMwGlobals( [
                        'wgArticlePath' => '/wiki/$1',
                        'wgScriptPath' => '/w',
                        'wgScript' => '/w/index.php',
                ] );
-               $this->hideDeprecated( 'ParserOutput stateful allowTOC' );
-               $this->hideDeprecated( 'ParserOutput stateful enableSectionEditLinks' );
 
                $po = new ParserOutput( $text );
-
-               // Emulate Parser
-               $po->setEditSectionTokens( true );
-
-               if ( $poState ) {
-                       $wrap = TestingAccessWrapper::newFromObject( $po );
-                       foreach ( $poState as $key => $value ) {
-                               $wrap->$key = $value;
-                       }
-               }
-
                $actual = $po->getText( $options );
                $this->assertSame( $expect, $actual );
        }
@@ -169,89 +153,8 @@ EOF;
 EOF;
 
                return [
-                       'No stateless options, default state' => [
-                               [], [], $text, <<<EOF
-<div class="mw-parser-output"><p>Test document.
-</p>
-<div id="toc" class="toc"><div class="toctitle"><h2>Contents</h2></div>
-<ul>
-<li class="toclevel-1 tocsection-1"><a href="#Section_1"><span class="tocnumber">1</span> <span class="toctext">Section 1</span></a></li>
-<li class="toclevel-1 tocsection-2"><a href="#Section_2"><span class="tocnumber">2</span> <span class="toctext">Section 2</span></a>
-<ul>
-<li class="toclevel-2 tocsection-3"><a href="#Section_2.1"><span class="tocnumber">2.1</span> <span class="toctext">Section 2.1</span></a></li>
-</ul>
-</li>
-<li class="toclevel-1 tocsection-4"><a href="#Section_3"><span class="tocnumber">3</span> <span class="toctext">Section 3</span></a></li>
-</ul>
-</div>
-
-<h2><span class="mw-headline" id="Section_1">Section 1</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/w/index.php?title=Test_Page&amp;action=edit&amp;section=1" title="Edit section: Section 1">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
-<p>One
-</p>
-<h2><span class="mw-headline" id="Section_2">Section 2</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/w/index.php?title=Test_Page&amp;action=edit&amp;section=2" title="Edit section: Section 2">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
-<p>Two
-</p>
-<h3><span class="mw-headline" id="Section_2.1">Section 2.1</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/w/index.php?title=Test_Page&amp;action=edit&amp;section=3" title="Edit section: Section 2.1">edit</a><span class="mw-editsection-bracket">]</span></span></h3>
-<p>Two point one
-</p>
-<h2><span class="mw-headline" id="Section_3">Section 3</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/w/index.php?title=Test_Page&amp;action=edit&amp;section=4" title="Edit section: Section 3">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
-<p>Three
-</p></div>
-EOF
-                       ],
-                       'No stateless options, TOC statefully disabled' => [
-                               [], [ 'mTOCEnabled' => false ], $text, <<<EOF
-<div class="mw-parser-output"><p>Test document.
-</p>
-
-<h2><span class="mw-headline" id="Section_1">Section 1</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/w/index.php?title=Test_Page&amp;action=edit&amp;section=1" title="Edit section: Section 1">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
-<p>One
-</p>
-<h2><span class="mw-headline" id="Section_2">Section 2</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/w/index.php?title=Test_Page&amp;action=edit&amp;section=2" title="Edit section: Section 2">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
-<p>Two
-</p>
-<h3><span class="mw-headline" id="Section_2.1">Section 2.1</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/w/index.php?title=Test_Page&amp;action=edit&amp;section=3" title="Edit section: Section 2.1">edit</a><span class="mw-editsection-bracket">]</span></span></h3>
-<p>Two point one
-</p>
-<h2><span class="mw-headline" id="Section_3">Section 3</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/w/index.php?title=Test_Page&amp;action=edit&amp;section=4" title="Edit section: Section 3">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
-<p>Three
-</p></div>
-EOF
-                       ],
-                       'No stateless options, section edits statefully disabled' => [
-                               [], [ 'mEditSectionTokens' => false ], $text, <<<EOF
-<div class="mw-parser-output"><p>Test document.
-</p>
-<div id="toc" class="toc"><div class="toctitle"><h2>Contents</h2></div>
-<ul>
-<li class="toclevel-1 tocsection-1"><a href="#Section_1"><span class="tocnumber">1</span> <span class="toctext">Section 1</span></a></li>
-<li class="toclevel-1 tocsection-2"><a href="#Section_2"><span class="tocnumber">2</span> <span class="toctext">Section 2</span></a>
-<ul>
-<li class="toclevel-2 tocsection-3"><a href="#Section_2.1"><span class="tocnumber">2.1</span> <span class="toctext">Section 2.1</span></a></li>
-</ul>
-</li>
-<li class="toclevel-1 tocsection-4"><a href="#Section_3"><span class="tocnumber">3</span> <span class="toctext">Section 3</span></a></li>
-</ul>
-</div>
-
-<h2><span class="mw-headline" id="Section_1">Section 1</span></h2>
-<p>One
-</p>
-<h2><span class="mw-headline" id="Section_2">Section 2</span></h2>
-<p>Two
-</p>
-<h3><span class="mw-headline" id="Section_2.1">Section 2.1</span></h3>
-<p>Two point one
-</p>
-<h2><span class="mw-headline" id="Section_3">Section 3</span></h2>
-<p>Three
-</p></div>
-EOF
-                       ],
-                       'Stateless options override stateful settings' => [
-                               [ 'allowTOC' => true, 'enableSectionEditLinks' => true ],
-                               [ 'mTOCEnabled' => false, 'mEditSectionTokens' => false ],
-                               $text, <<<EOF
+                       'No options' => [
+                               [], $text, <<<EOF
 <div class="mw-parser-output"><p>Test document.
 </p>
 <div id="toc" class="toc"><div class="toctitle"><h2>Contents</h2></div>
@@ -280,8 +183,8 @@ EOF
 </p></div>
 EOF
                        ],
-                       'Statelessly disable section edit links' => [
-                               [ 'enableSectionEditLinks' => false ], [], $text, <<<EOF
+                       'Disable section edit links' => [
+                               [ 'enableSectionEditLinks' => false ], $text, <<<EOF
 <div class="mw-parser-output"><p>Test document.
 </p>
 <div id="toc" class="toc"><div class="toctitle"><h2>Contents</h2></div>
@@ -310,8 +213,8 @@ EOF
 </p></div>
 EOF
                        ],
-                       'Statelessly disable TOC' => [
-                               [ 'allowTOC' => false ], [], $text, <<<EOF
+                       'Disable TOC' => [
+                               [ 'allowTOC' => false ], $text, <<<EOF
 <div class="mw-parser-output"><p>Test document.
 </p>
 
@@ -329,8 +232,8 @@ EOF
 </p></div>
 EOF
                        ],
-                       'Statelessly unwrap text' => [
-                               [ 'unwrap' => true ], [], $text, <<<EOF
+                       'Unwrap text' => [
+                               [ 'unwrap' => true ], $text, <<<EOF
 <p>Test document.
 </p>
 <div id="toc" class="toc"><div class="toctitle"><h2>Contents</h2></div>
@@ -360,15 +263,15 @@ EOF
 EOF
                        ],
                        'Unwrap without a mw-parser-output wrapper' => [
-                               [ 'unwrap' => true ], [], '<div class="foobar">Content</div>', '<div class="foobar">Content</div>'
+                               [ 'unwrap' => true ], '<div class="foobar">Content</div>', '<div class="foobar">Content</div>'
                        ],
                        'Unwrap with extra comment at end' => [
-                               [ 'unwrap' => true ], [], '<div class="mw-parser-output"><p>Test document.</p></div>
+                               [ 'unwrap' => true ], '<div class="mw-parser-output"><p>Test document.</p></div>
 <!-- Saved in parser cache... -->', '<p>Test document.</p>
 <!-- Saved in parser cache... -->'
                        ],
                        'Style deduplication' => [
-                               [], [], $dedupText, <<<EOF
+                               [], $dedupText, <<<EOF
 <p>This is a test document.</p>
 <style data-mw-deduplicate="duplicate1">.Duplicate1 {}</style>
 <link rel="mw-deduplicated-inline-style" href="mw-data:duplicate1"/>
@@ -382,7 +285,7 @@ EOF
 EOF
                        ],
                        'Style deduplication disabled' => [
-                               [ 'deduplicateStyles' => false ], [], $dedupText, $dedupText
+                               [ 'deduplicateStyles' => false ], $dedupText, $dedupText
                        ],
                ];
                // phpcs:enable
diff --git a/tests/phpunit/includes/registration/ExtensionJsonValidatorTest.php b/tests/phpunit/includes/registration/ExtensionJsonValidatorTest.php
new file mode 100644 (file)
index 0000000..d69ad59
--- /dev/null
@@ -0,0 +1,84 @@
+<?php
+/**
+ * Copyright (C) 2018 Kunal Mehta <legoktm@member.fsf.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+/**
+ * @covers ExtensionJsonValidator
+ */
+class ExtensionJsonValidatorTest extends MediaWikiTestCase {
+
+       /**
+        * @dataProvider provideValidate
+        */
+       public function testValidate( $file, $expected ) {
+               // If a dependency is missing, skip this test.
+               $validator = new ExtensionJsonValidator( function ( $msg ) {
+                       $this->markTestSkipped( $msg );
+               } );
+
+               if ( is_string( $expected ) ) {
+                       $this->setExpectedException(
+                               ExtensionJsonValidationError::class,
+                               $expected
+                       );
+               }
+
+               $dir = __DIR__ . '/../../data/registration/';
+               $this->assertSame(
+                       $expected,
+                       $validator->validate( $dir . $file )
+               );
+       }
+
+       public function provideValidate() {
+               return [
+                       [
+                               'notjson.txt',
+                               'notjson.txt is not valid JSON'
+                       ],
+                       [
+                               'no_manifest_version.json',
+                               'no_manifest_version.json does not have manifest_version set.'
+                       ],
+                       [
+                               'old_manifest_version.json',
+                               'old_manifest_version.json is using a non-supported schema version'
+                       ],
+                       [
+                               'newer_manifest_version.json',
+                               'newer_manifest_version.json is using a non-supported schema version'
+                       ],
+                       [
+                               'bad_spdx.json',
+                               "bad_spdx.json did not pass validation.
+[license-name] Invalid SPDX license identifier, see <https://spdx.org/licenses/>"
+                       ],
+                       [
+                               'invalid.json',
+                               "invalid.json did not pass validation.
+[license-name] Array value found, but a string is required"
+                       ],
+                       [
+                               'good.json',
+                               true
+                       ],
+               ];
+       }
+
+}
index a6f69b6..67bc088 100644 (file)
@@ -1,9 +1,57 @@
 <?php
 
+/**
+ * @covers ExtensionRegistry
+ */
 class ExtensionRegistryTest extends MediaWikiTestCase {
 
+       private $dataDir;
+
+       public function setUp() {
+               parent::setUp();
+               $this->dataDir = __DIR__ . '/../../data/registration';
+       }
+
+       public function testQueue_invalid() {
+               $registry = new ExtensionRegistry();
+               $path = __DIR__ . '/doesnotexist.json';
+               $this->setExpectedException(
+                       Exception::class,
+                       "$path does not exist!"
+               );
+               $registry->queue( $path );
+       }
+
+       public function testQueue() {
+               $registry = new ExtensionRegistry();
+               $path = "{$this->dataDir}/good.json";
+               $registry->queue( $path );
+               $this->assertArrayHasKey(
+                       $path,
+                       $registry->getQueue()
+               );
+               $registry->clearQueue();
+               $this->assertEmpty( $registry->getQueue() );
+       }
+
+       public function testLoadFromQueue_empty() {
+               $registry = new ExtensionRegistry();
+               $registry->loadFromQueue();
+               $this->assertEmpty( $registry->getAllThings() );
+       }
+
+       public function testLoadFromQueue_late() {
+               $registry = new ExtensionRegistry();
+               $registry->finish();
+               $registry->queue( "{$this->dataDir}/good.json" );
+               $this->setExpectedException(
+                       MWException::class,
+                       "The following paths tried to load late: {$this->dataDir}/good.json"
+               );
+               $registry->loadFromQueue();
+       }
+
        /**
-        * @covers ExtensionRegistry::exportExtractedData
         * @dataProvider provideExportExtractedDataGlobals
         */
        public function testExportExtractedDataGlobals( $desc, $before, $globals, $expected ) {
index 6f0de16..4a2810b 100644 (file)
@@ -54,6 +54,7 @@ class VersionCheckerTest extends PHPUnit_Framework_TestCase {
                                'FakeDependency' => [
                                        'version' => '1.0.0',
                                ],
+                               'NoVersionGiven' => [],
                        ] );
                $this->assertEquals( $expected, $checker->checkArray( [
                        'FakeExtension' => $given,
@@ -78,6 +79,39 @@ class VersionCheckerTest extends PHPUnit_Framework_TestCase {
                                ],
                                []
                        ],
+                       [
+                               [
+                                       'extensions' => [
+                                               'NoVersionGiven' => '*'
+                                       ]
+                               ],
+                               [],
+                       ],
+                       [
+                               [
+                                       'extensions' => [
+                                               'NoVersionGiven' => '1.0',
+                                       ]
+                               ],
+                               [ 'NoVersionGiven does not expose its version, but FakeExtension requires: 1.0.' ],
+                       ],
+                       [
+                               [
+                                       'extensions' => [
+                                               'Missing' => '*',
+                                       ]
+                               ],
+                               [ 'FakeExtension requires Missing to be installed.' ],
+                       ],
+                       [
+                               [
+                                       'extensions' => [
+                                               'FakeDependency' => '2.0.0',
+                                       ]
+                               ],
+                               // phpcs:ignore Generic.Files.LineLength.TooLong
+                               [ 'FakeExtension is not compatible with the current installed version of FakeDependency (1.0.0), it requires: 2.0.0.' ],
+                       ]
                ];
        }
 
index c83f500..e51d0d6 100644 (file)
@@ -42,9 +42,7 @@ class ResourceLoaderClientHtmlTest extends PHPUnit_Framework_TestCase {
        protected static function makeSampleModules() {
                $modules = [
                        'test' => [],
-                       'test.top' => [ 'position' => 'top' ],
-                       'test.private.top' => [ 'group' => 'private', 'position' => 'top' ],
-                       'test.private.bottom' => [ 'group' => 'private', 'position' => 'bottom' ],
+                       'test.private' => [ 'group' => 'private' ],
                        'test.shouldembed.empty' => [ 'shouldEmbed' => true, 'isKnownEmpty' => true ],
                        'test.shouldembed' => [ 'shouldEmbed' => true ],
 
@@ -75,7 +73,6 @@ class ResourceLoaderClientHtmlTest extends PHPUnit_Framework_TestCase {
                        ],
 
                        'test.scripts' => [],
-                       'test.scripts.top' => [ 'position' => 'top' ],
                        'test.scripts.user' => [ 'group' => 'user' ],
                        'test.scripts.user.empty' => [ 'group' => 'user', 'isKnownEmpty' => true ],
                        'test.scripts.raw' => [ 'isRaw' => true ],
@@ -115,9 +112,7 @@ class ResourceLoaderClientHtmlTest extends PHPUnit_Framework_TestCase {
                $client = new ResourceLoaderClientHtml( $context );
                $client->setModules( [
                        'test',
-                       'test.private.bottom',
-                       'test.private.top',
-                       'test.top',
+                       'test.private',
                        'test.shouldembed.empty',
                        'test.shouldembed',
                        'test.unregistered',
@@ -133,15 +128,13 @@ class ResourceLoaderClientHtmlTest extends PHPUnit_Framework_TestCase {
                $client->setModuleScripts( [
                        'test.scripts',
                        'test.scripts.user.empty',
-                       'test.scripts.top',
                        'test.scripts.shouldembed',
                        'test.unregistered.scripts',
                ] );
 
                $expected = [
                        'states' => [
-                               'test.private.top' => 'loading',
-                               'test.private.bottom' => 'loading',
+                               'test.private' => 'loading',
                                'test.shouldembed.empty' => 'ready',
                                'test.shouldembed' => 'loading',
                                'test.styles.pure' => 'ready',
@@ -149,27 +142,23 @@ class ResourceLoaderClientHtmlTest extends PHPUnit_Framework_TestCase {
                                'test.styles.private' => 'ready',
                                'test.styles.shouldembed' => 'ready',
                                'test.scripts' => 'loading',
-                               'test.scripts.top' => 'loading',
                                'test.scripts.user.empty' => 'ready',
                                'test.scripts.shouldembed' => 'loading',
                        ],
                        'general' => [
                                'test',
-                               'test.top',
                        ],
                        'styles' => [
                                'test.styles.pure',
                        ],
                        'scripts' => [
                                'test.scripts',
-                               'test.scripts.top',
                                'test.scripts.shouldembed',
                        ],
                        'embed' => [
                                'styles' => [ 'test.styles.private', 'test.styles.shouldembed' ],
                                'general' => [
-                                       'test.private.bottom',
-                                       'test.private.top',
+                                       'test.private',
                                        'test.shouldembed',
                                ],
                        ],
@@ -193,15 +182,15 @@ class ResourceLoaderClientHtmlTest extends PHPUnit_Framework_TestCase {
                $client = new ResourceLoaderClientHtml( $context );
                $client->setConfig( [ 'key' => 'value' ] );
                $client->setModules( [
-                       'test.top',
-                       'test.private.top',
+                       'test',
+                       'test.private',
                ] );
                $client->setModuleStyles( [
                        'test.styles.pure',
                        'test.styles.private',
                ] );
                $client->setModuleScripts( [
-                       'test.scripts.top',
+                       'test.scripts',
                ] );
                $client->setExemptStates( [
                        'test.exempt' => 'ready',
@@ -211,10 +200,10 @@ class ResourceLoaderClientHtmlTest extends PHPUnit_Framework_TestCase {
                $expected = '<script>document.documentElement.className = document.documentElement.className.replace( /(^|\s)client-nojs(\s|$)/, "$1client-js$2" );</script>' . "\n"
                        . '<script>(window.RLQ=window.RLQ||[]).push(function(){'
                        . 'mw.config.set({"key":"value"});'
-                       . 'mw.loader.state({"test.exempt":"ready","test.private.top":"loading","test.styles.pure":"ready","test.styles.private":"ready","test.scripts.top":"loading"});'
-                       . 'mw.loader.implement("test.private.top@{blankVer}",function($,jQuery,require,module){},{"css":[]});'
-                       . 'mw.loader.load(["test.top"]);'
-                       . 'mw.loader.load("/w/load.php?debug=false\u0026lang=nl\u0026modules=test.scripts.top\u0026only=scripts\u0026skin=fallback");'
+                       . 'mw.loader.state({"test.exempt":"ready","test.private":"loading","test.styles.pure":"ready","test.styles.private":"ready","test.scripts":"loading"});'
+                       . 'mw.loader.implement("test.private@{blankVer}",function($,jQuery,require,module){},{"css":[]});'
+                       . 'mw.loader.load(["test"]);'
+                       . 'mw.loader.load("/w/load.php?debug=false\u0026lang=nl\u0026modules=test.scripts\u0026only=scripts\u0026skin=fallback");'
                        . '});</script>' . "\n"
                        . '<link rel="stylesheet" href="/w/load.php?debug=false&amp;lang=nl&amp;modules=test.styles.pure&amp;only=styles&amp;skin=fallback"/>' . "\n"
                        . '<style>.private{}</style>' . "\n"
@@ -266,9 +255,9 @@ class ResourceLoaderClientHtmlTest extends PHPUnit_Framework_TestCase {
                        ],
                        [
                                'context' => [],
-                               'modules' => [ 'test.private.top' ],
+                               'modules' => [ 'test.private' ],
                                'only' => ResourceLoaderModule::TYPE_COMBINED,
-                               'output' => '<script>(window.RLQ=window.RLQ||[]).push(function(){mw.loader.implement("test.private.top@{blankVer}",function($,jQuery,require,module){},{"css":[]});});</script>',
+                               'output' => '<script>(window.RLQ=window.RLQ||[]).push(function(){mw.loader.implement("test.private@{blankVer}",function($,jQuery,require,module){},{"css":[]});});</script>',
                        ],
                        [
                                'context' => [],
diff --git a/tests/phpunit/includes/sparql/SparqlClientTest.php b/tests/phpunit/includes/sparql/SparqlClientTest.php
new file mode 100644 (file)
index 0000000..e07e425
--- /dev/null
@@ -0,0 +1,188 @@
+<?php
+namespace MediaWiki\Sparql;
+
+use Http;
+use MediaWiki\Http\HttpRequestFactory;
+use MWHttpRequest;
+use PHPUnit_Framework_TestCase;
+
+/**
+ * @covers \MediaWiki\Sparql\SparqlClient
+ */
+class SparqlClientTest extends PHPUnit_Framework_TestCase {
+
+       private function getRequestFactory( $request ) {
+               $requestFactory = $this->getMock( HttpRequestFactory::class );
+               $requestFactory->method( 'create' )->willReturn( $request );
+               return $requestFactory;
+       }
+
+       private function getRequestMock( $content ) {
+               $request = $this->getMockBuilder( MWHttpRequest::class )->disableOriginalConstructor()->getMock();
+               $request->method( 'execute' )->willReturn( \Status::newGood( 200 ) );
+               $request->method( 'getContent' )->willReturn( $content );
+               return $request;
+       }
+
+       public function testQuery() {
+               $json = <<<JSON
+{
+  "head" : {
+    "vars" : [ "x", "y", "z" ]
+  },
+  "results" : {
+    "bindings" : [ {
+      "x" : {
+        "type" : "uri",
+        "value" : "http://wikiba.se/ontology#Dump"
+      },
+      "y" : {
+        "type" : "uri",
+        "value" : "http://creativecommons.org/ns#license"
+      },
+      "z" : {
+        "type" : "uri",
+        "value" : "http://creativecommons.org/publicdomain/zero/1.0/"
+      }
+    }, {
+      "x" : {
+        "type" : "uri",
+        "value" : "http://wikiba.se/ontology#Dump"
+      },
+      "z" : {
+        "type" : "literal",
+        "value" : "0.1.0"
+      }
+    } ]
+  }
+}
+JSON;
+
+               $request = $this->getRequestMock( $json );
+               $client = new SparqlClient( 'http://acme.test/', $this->getRequestFactory( $request ) );
+
+               // values only
+               $result = $client->query( "TEST SPARQL" );
+               $this->assertCount( 2, $result );
+               $this->assertEquals( 'http://wikiba.se/ontology#Dump', $result[0]['x'] );
+               $this->assertEquals( 'http://creativecommons.org/ns#license', $result[0]['y'] );
+               $this->assertEquals( '0.1.0', $result[1]['z'] );
+               $this->assertNull( $result[1]['y'] );
+               // raw data format
+               $result = $client->query( "TEST SPARQL 2", true );
+               $this->assertCount( 2, $result );
+               $this->assertEquals( 'uri', $result[0]['x']['type'] );
+               $this->assertEquals( 'http://wikiba.se/ontology#Dump', $result[0]['x']['value'] );
+               $this->assertEquals( 'literal', $result[1]['z']['type'] );
+               $this->assertEquals( '0.1.0', $result[1]['z']['value'] );
+               $this->assertNull( $result[1]['y'] );
+       }
+
+       /**
+        * @expectedException \Mediawiki\Sparql\SparqlException
+        */
+       public function testBadQuery() {
+               $request = $this->getMockBuilder( MWHttpRequest::class )->disableOriginalConstructor()->getMock();
+               $client = new SparqlClient( 'http://acme.test/', $this->getRequestFactory( $request ) );
+
+               $request->method( 'execute' )->willReturn( \Status::newFatal( "Bad query" ) );
+               $result = $client->query( "TEST SPARQL 3" );
+       }
+
+       public function optionsProvider() {
+               return [
+                       'defaults' => [
+                               'TEST тест SPARQL 4 ',
+                               null,
+                               null,
+                               [
+                                       'http://acme.test/',
+                                       'query=TEST+%D1%82%D0%B5%D1%81%D1%82+SPARQL+4+',
+                                       'format=json',
+                                       'maxQueryTimeMillis=30000',
+                               ],
+                               [
+                                       'method' => 'GET',
+                                       'userAgent' => Http::userAgent() ." SparqlClient",
+                                       'timeout' => 30
+                               ]
+                       ],
+                       'big query' => [
+                               str_repeat( 'ZZ', SparqlClient::MAX_GET_SIZE ),
+                               null,
+                               null,
+                               [
+                                       'format=json',
+                                       'maxQueryTimeMillis=30000',
+                               ],
+                               [
+                                       'method' => 'POST',
+                                       'postData' => 'query=' . str_repeat( 'ZZ', SparqlClient::MAX_GET_SIZE ),
+                               ]
+                       ],
+                       'timeout 1s' => [
+                               'TEST SPARQL 4',
+                               null,
+                               1,
+                               [
+                                       'maxQueryTimeMillis=1000',
+                               ],
+                               [
+                                       'timeout' => 1
+                               ]
+                       ],
+                       'more options' => [
+                               'TEST SPARQL 5',
+                               [
+                                       'userAgent' => 'My Test',
+                                       'randomOption' => 'duck',
+                               ],
+                               null,
+                               [],
+                               [
+                                       'userAgent' => 'My Test',
+                                       'randomOption' => 'duck',
+                               ]
+                       ],
+
+               ];
+       }
+
+       /**
+        * @dataProvider  optionsProvider
+        * @param string $sparql
+        * @param array|null $options
+        * @param int|null $timeout
+        * @param array $expectedUrl
+        * @param array $expectedOptions
+        */
+       public function testOptions( $sparql, $options, $timeout, $expectedUrl, $expectedOptions ) {
+               $requestFactory = $this->getMock( HttpRequestFactory::class );
+               $client = new SparqlClient( 'http://acme.test/',  $requestFactory );
+
+               $request = $this->getRequestMock( '{}' );
+
+               $requestFactory->method( 'create' )->willReturnCallback(
+                       function ( $url, $options ) use ( $request, $expectedUrl, $expectedOptions ) {
+                               foreach ( $expectedUrl as $eurl ) {
+                                       $this->assertContains( $eurl, $url );
+                               }
+                               foreach ( $expectedOptions as $ekey => $evalue ) {
+                                       $this->assertArrayHasKey( $ekey, $options );
+                                       $this->assertEquals( $options[$ekey], $evalue );
+                               }
+                               return $request;
+                       }
+               );
+
+               if ( !is_null( $options ) ) {
+                       $client->setClientOptions( $options );
+               }
+               if ( !is_null( $timeout ) ) {
+                       $client->setTimeout( $timeout );
+               }
+
+               $result = $client->query( $sparql );
+       }
+
+}
index 7203777..a78bd82 100755 (executable)
@@ -21,6 +21,7 @@ class PHPUnitMaintClass extends Maintenance {
                'use-bagostuff' => false,
                'use-jobqueue' => false,
                'use-normal-tables' => false,
+               'mwdebug' => false,
                'reuse-db' => false,
                'wiki' => false,
                'profiler' => false,
index 6d86551..d0126f2 100644 (file)
@@ -20,11 +20,9 @@ class ApiStructureTest extends MediaWikiTestCase {
        private static $testGlobals = [
                [
                        'MiserMode' => false,
-                       'AllowCategorizedRecentChanges' => false,
                ],
                [
                        'MiserMode' => true,
-                       'AllowCategorizedRecentChanges' => true,
                ],
        ];
 
index b168754..8390ab3 100644 (file)
@@ -33,7 +33,6 @@ return [
                        'mediawiki.page.startup',
                        'test.sinonjs',
                ],
-               'position' => 'top',
                'targets' => [ 'desktop', 'mobile' ],
        ],