Merge "maintenance: Enable gzip in router.php for static files"
authorjenkins-bot <jenkins-bot@gerrit.wikimedia.org>
Mon, 30 Sep 2019 14:38:53 +0000 (14:38 +0000)
committerGerrit Code Review <gerrit@wikimedia.org>
Mon, 30 Sep 2019 14:38:53 +0000 (14:38 +0000)
150 files changed:
.pipeline/blubber.yaml [new file with mode: 0644]
.pipeline/config.yaml [new file with mode: 0644]
.pipeline/dev_prereq.sh [new file with mode: 0755]
Gruntfile.js
RELEASE-NOTES-1.34
autoload.php
docs/Introduction.md
includes/DefaultSettings.php
includes/Revision/RevisionStore.php
includes/ServiceWiring.php
includes/api/ApiMain.php
includes/api/i18n/fr.json
includes/api/i18n/ja.json
includes/db/MWLBFactory.php
includes/filebackend/FileBackendGroup.php
includes/filerepo/FileRepo.php
includes/installer/MysqlUpdater.php
includes/installer/PostgresUpdater.php
includes/installer/SqliteUpdater.php
includes/installer/i18n/de.json
includes/installer/i18n/ja.json
includes/installer/i18n/mni.json [new file with mode: 0644]
includes/installer/i18n/uk.json
includes/libs/StringUtils.php
includes/libs/objectcache/wancache/WANObjectCache.php
includes/libs/rdbms/loadbalancer/LoadBalancerSingle.php
includes/logging/ProtectLogFormatter.php
includes/resourceloader/ResourceLoader.php
includes/resourceloader/ResourceLoaderClientHtml.php
includes/resourceloader/ResourceLoaderContext.php
includes/resourceloader/ResourceLoaderFileModule.php
includes/resourceloader/ResourceLoaderLanguageDataModule.php
includes/resourceloader/ResourceLoaderModule.php
includes/resourceloader/ResourceLoaderStartUpModule.php
includes/resourceloader/ResourceLoaderUserDefaultsModule.php
includes/resourceloader/ResourceLoaderUserOptionsModule.php
includes/resourceloader/ResourceLoaderUserTokensModule.php
includes/resourceloader/ResourceLoaderWikiModule.php
includes/specialpage/QueryPage.php
includes/specials/SpecialVersion.php
languages/i18n/ar.json
languages/i18n/awa.json
languages/i18n/da.json
languages/i18n/de.json
languages/i18n/diq.json
languages/i18n/el.json
languages/i18n/en.json
languages/i18n/eo.json
languages/i18n/es.json
languages/i18n/exif/de.json
languages/i18n/exif/nds-nl.json
languages/i18n/fa.json
languages/i18n/fi.json
languages/i18n/fit.json
languages/i18n/fr.json
languages/i18n/fy.json
languages/i18n/he.json
languages/i18n/hu.json
languages/i18n/it.json
languages/i18n/ja.json
languages/i18n/khw.json
languages/i18n/ko.json
languages/i18n/la.json
languages/i18n/lzh.json
languages/i18n/mk.json
languages/i18n/nap.json
languages/i18n/nb.json
languages/i18n/nds-nl.json
languages/i18n/nl.json
languages/i18n/nqo.json
languages/i18n/pl.json
languages/i18n/pt-br.json
languages/i18n/qqq.json
languages/i18n/ru.json
languages/i18n/sh.json
languages/i18n/sl.json
languages/i18n/sr-ec.json
languages/i18n/sv.json
languages/i18n/szl.json
languages/i18n/tcy.json
languages/i18n/tr.json
languages/i18n/xal.json
languages/i18n/yue.json
languages/i18n/zh-hans.json
languages/i18n/zh-hant.json
maintenance/archives/patch-archive-ar_comment_id.sql [new file with mode: 0644]
maintenance/archives/patch-comment-table.sql
maintenance/archives/patch-filearchive-fa_description_id.sql [new file with mode: 0644]
maintenance/archives/patch-image-img_description-default.sql [new file with mode: 0644]
maintenance/archives/patch-image_comment_temp-table.sql [new file with mode: 0644]
maintenance/archives/patch-ipblocks-ipb_reason_id.sql [new file with mode: 0644]
maintenance/archives/patch-logging-log_comment_id.sql [new file with mode: 0644]
maintenance/archives/patch-oldimage-oi_description_id.sql [new file with mode: 0644]
maintenance/archives/patch-protected_titles-pt_reason_id.sql [new file with mode: 0644]
maintenance/archives/patch-recentchanges-rc_comment_id.sql [new file with mode: 0644]
maintenance/archives/patch-rename-mysql-user_newtalk-indexes.sql [new file with mode: 0644]
maintenance/archives/patch-revision-rev_comment-default.sql [new file with mode: 0644]
maintenance/archives/patch-revision_comment_temp-table.sql [new file with mode: 0644]
maintenance/postgres/archives/patch-comment-table.sql
maintenance/postgres/archives/patch-image_comment_temp-table.sql [new file with mode: 0644]
maintenance/postgres/archives/patch-revision_comment_temp-table.sql [new file with mode: 0644]
maintenance/sqlite/archives/patch-archive-ar_comment_id.sql [new file with mode: 0644]
maintenance/sqlite/archives/patch-comment-table.sql [deleted file]
maintenance/sqlite/archives/patch-image-img_description-default.sql [new file with mode: 0644]
maintenance/sqlite/archives/patch-ipblocks-ipb_reason_id.sql [new file with mode: 0644]
maintenance/sqlite/archives/patch-logging-log_comment_id.sql [new file with mode: 0644]
maintenance/sqlite/archives/patch-oldimage-oi_description_id.sql [new file with mode: 0644]
maintenance/sqlite/archives/patch-protected_titles-pt_reason_id.sql [new file with mode: 0644]
maintenance/sqlite/archives/patch-recentchanges-rc_comment_id.sql [new file with mode: 0644]
maintenance/sqlite/archives/patch-revision-rev_comment-default.sql [new file with mode: 0644]
maintenance/storage/checkStorage.php
maintenance/storage/compressOld.php
maintenance/storage/fixT22757.php [deleted file]
maintenance/storage/recompressTracked.php
maintenance/updateSpecialPages.php
resources/Resources.php
tests/common/TestsAutoLoader.php
tests/phpunit/MediaWikiIntegrationTestCase.php
tests/phpunit/includes/Revision/NoContentModelRevisionStoreDbTest.php [deleted file]
tests/phpunit/includes/Revision/PreMcrRevisionStoreDbTest.php [deleted file]
tests/phpunit/includes/Revision/PreMcrSchemaOverride.php [deleted file]
tests/phpunit/includes/Revision/RevisionQueryInfoTest.php
tests/phpunit/includes/Revision/RevisionStoreFactoryTest.php
tests/phpunit/includes/Revision/RevisionStoreTest.php
tests/phpunit/includes/RevisionNoContentModelDbTest.php [deleted file]
tests/phpunit/includes/RevisionPreMcrDbTest.php [deleted file]
tests/phpunit/includes/api/ApiMainTest.php
tests/phpunit/includes/api/ApiQuerySiteinfoTest.php
tests/phpunit/includes/changes/CategoryMembershipChangeTest.php
tests/phpunit/includes/content/WikitextContentTest.php
tests/phpunit/includes/db/LBFactoryTest.php
tests/phpunit/includes/db/LoadBalancerTest.php
tests/phpunit/includes/filebackend/FileBackendTest.php
tests/phpunit/includes/libs/StringUtilsTest.php
tests/phpunit/includes/libs/objectcache/WANObjectCacheTest.php
tests/phpunit/includes/logging/ProtectLogFormatterTest.php
tests/phpunit/includes/page/PageArchivePreMcrTest.php [deleted file]
tests/phpunit/includes/page/WikiPageNoContentModelDbTest.php [deleted file]
tests/phpunit/includes/page/WikiPagePreMcrDbTest.php [deleted file]
tests/phpunit/includes/pager/RangeChronologicalPagerTest.php
tests/phpunit/includes/resourceloader/ResourceLoaderContextTest.php
tests/phpunit/includes/resourceloader/ResourceLoaderStartUpModuleTest.php
tests/phpunit/includes/resourceloader/ResourceLoaderTest.php
tests/phpunit/includes/session/CookieSessionProviderTest.php
tests/phpunit/unit/includes/FauxResponseTest.php
tests/phpunit/unit/includes/changes/ChangesListFilterGroupTest.php
tests/phpunit/unit/includes/diff/DiffOpTest.php
tests/phpunit/unit/includes/language/LanguageCodeTest.php
tests/phpunit/unit/includes/session/SessionUnitTest.php
tests/selenium/wdio.conf.js

diff --git a/.pipeline/blubber.yaml b/.pipeline/blubber.yaml
new file mode 100644 (file)
index 0000000..13ad966
--- /dev/null
@@ -0,0 +1,14 @@
+version: v4
+base: docker-registry.wikimedia.org/dev/stretch-php72-fpm-apache2
+
+lives:
+  in: /var/www/html
+
+variants:
+  dev:
+    runs:
+      insecurely: true
+    builder:
+      command: [.pipeline/dev_prereq.sh]
+      requirements: [.pipeline, .pipeline/dev_prereq.sh, composer.json]
+    copies: [local]
diff --git a/.pipeline/config.yaml b/.pipeline/config.yaml
new file mode 100644 (file)
index 0000000..f69ba98
--- /dev/null
@@ -0,0 +1,8 @@
+pipelines:
+  publish:
+    blubberfile: blubber.yaml
+    stages:
+      - name: publish
+        build: dev
+        publish:
+          image: true
diff --git a/.pipeline/dev_prereq.sh b/.pipeline/dev_prereq.sh
new file mode 100755 (executable)
index 0000000..a1f4bd0
--- /dev/null
@@ -0,0 +1,16 @@
+#!/bin/sh
+
+mkdir /tmp/php
+mkdir -p extensions
+
+git clone --depth 1 https://gerrit.wikimedia.org/r/mediawiki/extensions/VisualEditor.git /var/www/html/extensions/VisualEditor
+git clone --depth 1 https://gerrit.wikimedia.org/r/mediawiki/skins/Vector /var/www/html/skins/Vector
+cd /var/www/html/extensions/VisualEditor
+git submodule update --depth 1 --init
+
+cd /var/www/html
+composer install
+cat <<PHP > LocalSettings.php
+<?php
+require_once '/var/config/LocalSettings.php';
+PHP
index 8115ea2..9615330 100644 (file)
@@ -117,7 +117,7 @@ module.exports = function ( grunt ) {
                                        included: true,
                                        served: false
                                } ],
-                               logLevel: 'DEBUG',
+                               logLevel: ( process.env.ZUUL_PROJECT ? 'DEBUG' : 'INFO' ),
                                frameworks: [ 'qunit' ],
                                reporters: [ 'mocha' ],
                                singleRun: true,
index 0d6f1e1..48fcbaf 100644 (file)
@@ -600,6 +600,10 @@ because of Phabricator reports.
   ApiQueryBlockInfoTrait instead.
 
 === Other changes in 1.34 ===
+* Added option to specify "Various authors" as author in extension credits using
+  "..." as the only author name. If the "author" array contains more than one
+  entry and "..." is one of the entries in the array, "..." will be parsed as
+  "others" (version-poweredby-others i18n message) like previously.
 * …
 
 == Compatibility ==
index 55e5a7f..dc57ff6 100644 (file)
@@ -532,7 +532,6 @@ $wgAutoloadLocalClasses = [
        'FixDefaultJsonContentPages' => __DIR__ . '/maintenance/fixDefaultJsonContentPages.php',
        'FixDoubleRedirects' => __DIR__ . '/maintenance/fixDoubleRedirects.php',
        'FixExtLinksProtocolRelative' => __DIR__ . '/maintenance/fixExtLinksProtocolRelative.php',
-       'FixT22757' => __DIR__ . '/maintenance/storage/fixT22757.php',
        'FixTimestamps' => __DIR__ . '/maintenance/fixTimestamps.php',
        'FixUserRegistration' => __DIR__ . '/maintenance/fixUserRegistration.php',
        'ForeignAPIFile' => __DIR__ . '/includes/filerepo/file/ForeignAPIFile.php',
index 4814599..e54b5b1 100644 (file)
@@ -1,7 +1,6 @@
 Introduction {#mainpage}
 =======
 
-Welcome on MediaWiki autogenerated documentation system.
+Welcome to the MediaWiki autogenerated documentation system.
 
-If you are looking to use, install or configure your wiki, you probably
-want to look at the main site: <https://www.mediawiki.org/>.
+If you are looking to use, install or configure your wiki, see the main site: <https://www.mediawiki.org/>.
index 29b628c..31cb7ae 100644 (file)
@@ -7937,6 +7937,7 @@ $wgAllowSpecialInclusion = true;
 /**
  * Set this to an array of special page names to prevent
  * maintenance/updateSpecialPages.php from updating those pages.
+ * Mapping each special page name to an run mode like 'periodical' if a cronjob is set up.
  */
 $wgDisableQueryPageUpdate = false;
 
index a1aeccb..c444cc4 100644 (file)
@@ -182,9 +182,9 @@ class RevisionStore
                        'Reading needs to be enabled for the old or the new schema.'
                );
                Assert::parameter(
-                       ( $mcrMigrationStage & SCHEMA_COMPAT_WRITE_BOTH ) !== 0,
+                       ( $mcrMigrationStage & SCHEMA_COMPAT_WRITE_NEW ) !== 0,
                        '$mcrMigrationStage',
-                       'Writing needs to be enabled for the old or the new schema.'
+                       'Writing needs to be enabled for the new schema.'
                );
                Assert::parameter(
                        ( $mcrMigrationStage & SCHEMA_COMPAT_READ_OLD ) === 0
@@ -192,12 +192,6 @@ class RevisionStore
                        '$mcrMigrationStage',
                        'Cannot read the old schema when not also writing it.'
                );
-               Assert::parameter(
-                       ( $mcrMigrationStage & SCHEMA_COMPAT_READ_NEW ) === 0
-                       || ( $mcrMigrationStage & SCHEMA_COMPAT_WRITE_NEW ) !== 0,
-                       '$mcrMigrationStage',
-                       'Cannot read the new schema when not also writing it.'
-               );
 
                $this->loadBalancer = $loadBalancer;
                $this->blobStore = $blobStore;
index ab51eab..83847d8 100644 (file)
@@ -207,10 +207,7 @@ return [
                );
                $class = MWLBFactory::getLBFactoryClass( $lbConf );
 
-               $instance = new $class( $lbConf );
-               MWLBFactory::setSchemaAliases( $instance, $mainConfig->get( 'DBtype' ) );
-
-               return $instance;
+               return new $class( $lbConf );
        },
 
        'EventRelayerGroup' => function ( MediaWikiServices $services ) : EventRelayerGroup {
index 7bbce97..d2c957d 100644 (file)
@@ -1154,8 +1154,7 @@ class ApiMain extends ApiBase {
                }
 
                if ( $this->getParameter( 'curtimestamp' ) ) {
-                       $result->addValue( null, 'curtimestamp', wfTimestamp( TS_ISO_8601, time() ),
-                               ApiResult::NO_SIZE_CHECK );
+                       $result->addValue( null, 'curtimestamp', wfTimestamp( TS_ISO_8601 ), ApiResult::NO_SIZE_CHECK );
                }
 
                if ( $this->getParameter( 'responselanginfo' ) ) {
index 12ece4c..712033d 100644 (file)
@@ -79,7 +79,7 @@
        "apihelp-checktoken-param-type": "Type de jeton testé",
        "apihelp-checktoken-param-token": "Jeton à tester.",
        "apihelp-checktoken-param-maxtokenage": "Temps maximum autorisé pour l'utilisation du jeton, en secondes",
-       "apihelp-checktoken-example-simple": "Tester la validité d'un jeton de <kbd>csrf</kbd>.",
+       "apihelp-checktoken-example-simple": "Tester la validité d’un jeton <kbd>csrf</kbd>.",
        "apihelp-clearhasmsg-summary": "Efface le drapeau <code>hasmsg</code> pour l’utilisateur courant.",
        "apihelp-clearhasmsg-example-1": "Effacer le drapeau <code>hasmsg</code> pour l’utilisateur courant",
        "apihelp-clientlogin-summary": "Se connecter au wiki en utilisant la procédure interactive.",
index acdb05c..eb588c2 100644 (file)
        "apihelp-edit-param-summary": "編集の要約。$1section=new で $1sectiontitle が設定されていない場合は節名としても利用されます。",
        "apihelp-edit-param-tags": "この版に適用する変更タグ。",
        "apihelp-edit-param-minor": "この編集に細部の変更の印を付ける",
-       "apihelp-edit-param-notminor": "細部の編集ではない。",
+       "apihelp-edit-param-notminor": "利用者設定で「{{int:tog-minordefault}}」を指定してあっても、細部の編集とマークしないでください。",
        "apihelp-edit-param-bot": "この編集をボットの編集としてマークする。",
        "apihelp-edit-param-basetimestamp": "編集前の版のタイムスタンプ。編集競合を検出するために使用されます。\n[[Special:ApiHelp/query+revisions|action=query&prop=revisions&rvprop=timestamp]] で取得できます。",
        "apihelp-edit-param-starttimestamp": "編集作業を開始したときのタイムスタンプ。編集競合を検出するために使用されます。適切な値は <var>[[Special:ApiHelp/main|curtimestamp]]</var> を使用して編集作業を開始するとき (たとえば、編集するページの本文を読み込んだとき) に取得できます。",
        "apihelp-options-example-change": "<kbd>skin</kbd> および <kbd>hideminor</kbd> の個人設定を変更する。",
        "apihelp-options-example-complex": "すべての個人設定を初期化し、<kbd>skin</kbd> および <kbd> nickname </kbd> を設定する。",
        "apihelp-paraminfo-summary": "API モジュールに関する情報を取得します。",
-       "apihelp-paraminfo-param-modules": "モジュールの名前のリスト (<var>action</var> および <var>format</var> パラメーターの値, または <kbd>main</kbd>). <kbd>+</kbd> を使用して下位モジュールを指定できます。",
+       "apihelp-paraminfo-param-modules": "モジュール名のリスト (<var>action</var> および <var>format</var> パラメーターまたは <kbd>main</kbd>の値)。特定の下位モジュールの指定は<kbd>+</kbd> 、全下位モジュールの指定は<kbd>+*</kbd>を使い、あるいは<kbd>+**</kbd>ですべての下位モジュールを再帰的に指定します。",
        "apihelp-paraminfo-param-helpformat": "ヘルプ文字列の形式。",
        "apihelp-paraminfo-param-querymodules": "クエリモジュール名のリスト (<var>prop</var>, <var>meta</var> or <var>list</var> パラメータの値)。<kbd>$1querymodules=foo</kbd> の代わりに <kbd>$1modules=query+foo</kbd> を使用してください。",
        "apihelp-paraminfo-example-1": "<kbd>[[Special:ApiHelp/parse|action=parse]]</kbd>, <kbd>[[Special:ApiHelp/jsonfm|format=jsonfm]]</kbd>, <kbd>[[Special:ApiHelp/query+allpages|action=query&list=allpages]]</kbd>, and <kbd>[[Special:ApiHelp/query+siteinfo|action=query&meta=siteinfo]]</kbd> に関する情報を表示する。",
        "apihelp-parse-paramvalue-prop-revid": "構文解析されたページの版IDを追加します。",
        "apihelp-parse-paramvalue-prop-displaytitle": "構文解析されたウィキテキストのタイトルを追加します。",
        "apihelp-parse-paramvalue-prop-headitems": "ページの <code>&lt;head&gt;</code> の中に入れてアイテムを提供します。",
-       "apihelp-parse-paramvalue-prop-headhtml": "ページの解析された <code>&lt;head&gt;</code> を与える。",
+       "apihelp-parse-paramvalue-prop-headhtml": "ページの<code>&lt;html&gt;</code>と<code>&lt;head&gt;</code>の要素を開いて<code>&lt;body&gt;</code>を開示し、Doctype を解析する。",
        "apihelp-parse-paramvalue-prop-jsconfigvars": "ページに固有のJavaScriptの設定変数を提供します。適用するには、<code>mw.config.set()</code>を使用します。",
        "apihelp-parse-paramvalue-prop-encodedjsconfigvars": "JSON文字列としてページに固有のJavaScriptの設定変数を提供します。",
        "apihelp-parse-paramvalue-prop-indicators": "ページ上で使用されるページのステータスインジケータのHTMLを提供します。",
index ad5708a..63b320e 100644 (file)
@@ -23,7 +23,6 @@
 
 use MediaWiki\Config\ServiceOptions;
 use MediaWiki\Logger\LoggerFactory;
-use Wikimedia\Rdbms\LBFactory;
 use Wikimedia\Rdbms\DatabaseDomain;
 
 /**
@@ -359,34 +358,6 @@ abstract class MWLBFactory {
                return $class;
        }
 
-       /**
-        * @param LBFactory $lbFactory
-        * @param string $dbType 'mysql', 'sqlite', etc.
-        * @internal For use with service wiring
-        */
-       public static function setSchemaAliases( LBFactory $lbFactory, $dbType ) {
-               if ( $dbType === 'mysql' ) {
-                       /**
-                        * When SQLite indexes were introduced in r45764, it was noted that
-                        * SQLite requires index names to be unique within the whole database,
-                        * not just within a schema. As discussed in CR r45819, to avoid the
-                        * need for a schema change on existing installations, the indexes
-                        * were implicitly mapped from the new names to the old names.
-                        *
-                        * This mapping can be removed if DB patches are introduced to alter
-                        * the relevant tables in existing installations. Note that because
-                        * this index mapping applies to table creation, even new installations
-                        * of MySQL have the old names (except for installations created during
-                        * a period where this mapping was inappropriately removed, see
-                        * T154872).
-                        */
-                       $lbFactory->setIndexAliases( [
-                               'un_user_id' => 'user_id',
-                               'un_user_ip' => 'user_ip',
-                       ] );
-               }
-       }
-
        /**
         * Log a database deprecation warning
         * @param string $msg Deprecation message
index 9e04d09..f369f00 100644 (file)
@@ -123,8 +123,28 @@ class FileBackendGroup {
                        }
                        $class = $config['class'];
 
-                       // @FIXME: ideally this would default to the DB domain (which includes the schema)
-                       $config['domainId'] = $config['domainId'] ?? ( $config['wikiId'] ?? wfWikiID() );
+                       if ( isset( $config['domainId'] ) ) {
+                               $domainId = $config['domainId'];
+                       } elseif ( isset( $config['wikiId'] ) ) {
+                               $domainId = $config['wikiId']; // b/c
+                       } else {
+                               // Only use the raw database/prefix for backwards compatibility
+                               $ld = WikiMap::getCurrentWikiDbDomain();
+                               $domainId = strlen( $ld->getTablePrefix() )
+                                       ? "{$ld->getDatabase()}-{$ld->getTablePrefix()}"
+                                       : $ld->getDatabase();
+                               // If the local wiki ID and local domain ID do not match, probably due to a
+                               // non-default schema, issue a warning. A non-default schema indicates that
+                               // it might be used to disambiguate different wikis.
+                               $wikiId = WikiMap::getWikiIdFromDbDomain( $ld );
+                               if ( $ld->getSchema() !== null && $domainId !== $wikiId ) {
+                                       wfWarn(
+                                               "\$wgFileBackend entry '$name' should have 'domainId' set.\n" .
+                                               "Legacy default 'domainId' is '$domainId' but wiki ID is '$wikiId'."
+                                       );
+                               }
+                       }
+                       $config['domainId'] = $domainId;
                        $config['readOnly'] = $config['readOnly'] ?? $readOnlyReason;
 
                        unset( $config['class'] ); // backend won't need this
index ff8f056..f095066 100644 (file)
@@ -838,7 +838,11 @@ class FileRepo {
        /**
         * Store a file to a given destination.
         *
-        * @param string $srcPath Source file system path, storage path, or virtual URL
+        * Using FSFile/TempFSFile can improve performance via caching.
+        * Using TempFSFile can further improve performance by signalling that it is safe
+        * to touch the source file or write extended attribute metadata to it directly.
+        *
+        * @param string|FSFile $srcPath Source file system path, storage path, or virtual URL
         * @param string $dstZone Destination zone
         * @param string $dstRel Destination relative path
         * @param int $flags Bitwise combination of the following flags:
@@ -862,6 +866,8 @@ class FileRepo {
        /**
         * Store a batch of files
         *
+        * @see FileRepo::store()
+        *
         * @param array $triplets (src, dest zone, dest rel) triplets as per store()
         * @param int $flags Bitwise combination of the following flags:
         *   self::OVERWRITE         Overwrite an existing destination file instead of failing
@@ -884,11 +890,18 @@ class FileRepo {
                $operations = [];
                // Validate each triplet and get the store operation...
                foreach ( $triplets as $triplet ) {
-                       list( $srcPath, $dstZone, $dstRel ) = $triplet;
+                       list( $src, $dstZone, $dstRel ) = $triplet;
+                       $srcPath = ( $src instanceof FSFile ) ? $src->getPath() : $src;
                        wfDebug( __METHOD__
                                . "( \$src='$srcPath', \$dstZone='$dstZone', \$dstRel='$dstRel' )\n"
                        );
-
+                       // Resolve source path
+                       if ( $src instanceof FSFile ) {
+                               $op = 'store';
+                       } else {
+                               $src = $this->resolveToStoragePathIfVirtual( $src );
+                               $op = FileBackend::isStoragePath( $src ) ? 'copy' : 'store';
+                       }
                        // Resolve destination path
                        $root = $this->getZonePath( $dstZone );
                        if ( !$root ) {
@@ -904,13 +917,10 @@ class FileRepo {
                                return $this->newFatal( 'directorycreateerror', $dstDir );
                        }
 
-                       // Resolve source to a storage path if virtual
-                       $srcPath = $this->resolveToStoragePathIfVirtual( $srcPath );
-
                        // Copy the source file to the destination
                        $operations[] = [
-                               'op' => FileBackend::isStoragePath( $srcPath ) ? 'copy' : 'store',
-                               'src' => $srcPath, // storage path (copy) or local file path (store)
+                               'op' => $op,
+                               'src' => $src, // storage path (copy) or local file path (store)
                                'dst' => $dstPath,
                                'overwrite' => ( $flags & self::OVERWRITE ) ? true : false,
                                'overwriteSame' => ( $flags & self::OVERWRITE_SAME ) ? true : false,
@@ -970,6 +980,10 @@ class FileRepo {
         * This function can be used to write to otherwise read-only foreign repos.
         * This is intended for copying generated thumbnails into the repo.
         *
+        * Using FSFile/TempFSFile can improve performance via caching.
+        * Using TempFSFile can further improve performance by signalling that it is safe
+        * to touch the source file or write extended attribute metadata to it directly.
+        *
         * @param string|FSFile $src Source file system path, storage path, or virtual URL
         * @param string $dst Virtual URL or storage path
         * @param array|string|null $options An array consisting of a key named headers
@@ -981,39 +995,14 @@ class FileRepo {
                return $this->quickImportBatch( [ [ $src, $dst, $options ] ] );
        }
 
-       /**
-        * Purge a file from the repo. This does no locking nor journaling.
-        * This function can be used to write to otherwise read-only foreign repos.
-        * This is intended for purging thumbnails.
-        *
-        * @param string $path Virtual URL or storage path
-        * @return Status
-        */
-       final public function quickPurge( $path ) {
-               return $this->quickPurgeBatch( [ $path ] );
-       }
-
-       /**
-        * Deletes a directory if empty.
-        * This function can be used to write to otherwise read-only foreign repos.
-        *
-        * @param string $dir Virtual URL (or storage path) of directory to clean
-        * @return Status
-        */
-       public function quickCleanDir( $dir ) {
-               $status = $this->newGood();
-               $status->merge( $this->backend->clean(
-                       [ 'dir' => $this->resolveToStoragePathIfVirtual( $dir ) ] ) );
-
-               return $status;
-       }
-
        /**
         * Import a batch of files from the local file system into the repo.
         * This does no locking nor journaling and overrides existing files.
         * This function can be used to write to otherwise read-only foreign repos.
         * This is intended for copying generated thumbnails into the repo.
         *
+        * @see FileRepo::quickImport()
+        *
         * All path parameters may be a file system path, storage path, or virtual URL.
         * When "headers" are given they are used as HTTP headers if supported.
         *
@@ -1046,7 +1035,7 @@ class FileRepo {
 
                        $operations[] = [
                                'op' => $op,
-                               'src' => $src,
+                               'src' => $src, // storage path (copy) or local path/FSFile (store)
                                'dst' => $dst,
                                'headers' => $headers
                        ];
@@ -1057,6 +1046,33 @@ class FileRepo {
                return $status;
        }
 
+       /**
+        * Purge a file from the repo. This does no locking nor journaling.
+        * This function can be used to write to otherwise read-only foreign repos.
+        * This is intended for purging thumbnails.
+        *
+        * @param string $path Virtual URL or storage path
+        * @return Status
+        */
+       final public function quickPurge( $path ) {
+               return $this->quickPurgeBatch( [ $path ] );
+       }
+
+       /**
+        * Deletes a directory if empty.
+        * This function can be used to write to otherwise read-only foreign repos.
+        *
+        * @param string $dir Virtual URL (or storage path) of directory to clean
+        * @return Status
+        */
+       public function quickCleanDir( $dir ) {
+               $status = $this->newGood();
+               $status->merge( $this->backend->clean(
+                       [ 'dir' => $this->resolveToStoragePathIfVirtual( $dir ) ] ) );
+
+               return $status;
+       }
+
        /**
         * Purge a batch of files from the repo.
         * This function can be used to write to otherwise read-only foreign repos.
@@ -1169,6 +1185,10 @@ class FileRepo {
         * Returns a Status object. On success, the value contains "new" or
         * "archived", to indicate whether the file was new with that name.
         *
+        * Using FSFile/TempFSFile can improve performance via caching.
+        * Using TempFSFile can further improve performance by signalling that it is safe
+        * to touch the source file or write extended attribute metadata to it directly.
+        *
         * Options to $options include:
         *   - headers : name/value map of HTTP headers to use in response to GET/HEAD requests
         *
@@ -1199,6 +1219,8 @@ class FileRepo {
        /**
         * Publish a batch of files
         *
+        * @see FileRepo::publish()
+        *
         * @param array $ntuples (source, dest, archive) triplets or
         *   (source, dest, archive, options) 4-tuples as per publish().
         * @param int $flags Bitfield, may be FileRepo::DELETE_SOURCE to indicate
@@ -1277,7 +1299,7 @@ class FileRepo {
                        } else {
                                $operations[] = [
                                        'op' => 'store',
-                                       'src' => $src, // FSFile (preferred) or local file path
+                                       'src' => $src, // storage path (copy) or local path/FSFile (store)
                                        'dst' => $dstPath,
                                        'overwrite' => true, // replace current
                                        'headers' => $headers
index 7d41d04..a249ada 100644 (file)
@@ -327,6 +327,20 @@ class MysqlUpdater extends DatabaseUpdater {
                        [ 'renameIndex', 'user_properties', 'user_properties_user_property', 'PRIMARY', false,
                                'patch-user_properties-fix-pk.sql' ],
                        [ 'addTable', 'comment', 'patch-comment-table.sql' ],
+                       [ 'addTable', 'revision_comment_temp', 'patch-revision_comment_temp-table.sql' ],
+                       // image_comment_temp is no longer needed when upgrading to MW 1.31 or newer,
+                       // as it is dropped later in the update process as part of 'migrateImageCommentTemp'.
+                       // File kept on disk and the updater entry here for historical purposes.
+                       // [ 'addTable', 'image_comment_temp', 'patch-image_comment_temp-table.sql' ],
+                       [ 'addField', 'archive', 'ar_comment_id', 'patch-archive-ar_comment_id.sql' ],
+                       [ 'addField', 'filearchive', 'fa_description_id', 'patch-filearchive-fa_description_id.sql' ],
+                       [ 'modifyField', 'image', 'img_description', 'patch-image-img_description-default.sql' ],
+                       [ 'addField', 'ipblocks', 'ipb_reason_id', 'patch-ipblocks-ipb_reason_id.sql' ],
+                       [ 'addField', 'logging', 'log_comment_id', 'patch-logging-log_comment_id.sql' ],
+                       [ 'addField', 'oldimage', 'oi_description_id', 'patch-oldimage-oi_description_id.sql' ],
+                       [ 'addField', 'protected_titles', 'pt_reason_id', 'patch-protected_titles-pt_reason_id.sql' ],
+                       [ 'addField', 'recentchanges', 'rc_comment_id', 'patch-recentchanges-rc_comment_id.sql' ],
+                       [ 'modifyField', 'revision', 'rev_comment', 'patch-revision-rev_comment-default.sql' ],
 
                        // This field was added in 1.31, but is put here so it can be used by 'migrateComments'
                        [ 'addField', 'image', 'img_description_id', 'patch-image-img_description_id.sql' ],
@@ -390,6 +404,7 @@ class MysqlUpdater extends DatabaseUpdater {
                                'patch-drop-archive-ar_usertext_timestamp.sql' ],
                        [ 'dropIndex', 'archive', 'usertext_timestamp', 'patch-drop-archive-usertext_timestamp.sql' ],
                        [ 'dropField', 'logging', 'log_user', 'patch-drop-user-fields.sql' ],
+                       [ 'addIndex', 'user_newtalk', 'un_user_ip', 'patch-rename-mysql-user_newtalk-indexes.sql' ],
                ];
        }
 
index b2c7d66..d7b1457 100644 (file)
@@ -483,6 +483,11 @@ class PostgresUpdater extends DatabaseUpdater {
                        [ 'changeNullableField', 'protected_titles', 'pt_reason', 'NOT NULL', true ],
                        [ 'addPgField', 'protected_titles', 'pt_reason_id', 'INTEGER NOT NULL DEFAULT 0' ],
                        [ 'addTable', 'comment', 'patch-comment-table.sql' ],
+                       [ 'addTable', 'revision_comment_temp', 'patch-revision_comment_temp-table.sql' ],
+                       // image_comment_temp is no longer needed when upgrading to MW 1.31 or newer,
+                       // as it is dropped later in the update process as part of 'migrateImageCommentTemp'.
+                       // File kept on disk and the updater entry here for historical purposes.
+                       // [ 'addTable', 'image_comment_temp', 'patch-image_comment_temp-table.sql' ],
 
                        // This field was added in 1.31, but is put here so it can be used by 'migrateComments'
                        [ 'addPgField', 'image', 'img_description_id', 'INTEGER NOT NULL DEFAULT 0' ],
index 7c3878c..15b3a5a 100644 (file)
@@ -186,6 +186,19 @@ class SqliteUpdater extends DatabaseUpdater {
                        [ 'renameIndex', 'user_properties', 'user_properties_user_property', 'PRIMARY', false,
                                'patch-user_properties-fix-pk.sql' ],
                        [ 'addTable', 'comment', 'patch-comment-table.sql' ],
+                       [ 'addTable', 'revision_comment_temp', 'patch-revision_comment_temp-table.sql' ],
+                       // image_comment_temp is no longer needed when upgrading to MW 1.31 or newer,
+                       // as it is dropped later in the update process as part of 'migrateImageCommentTemp'.
+                       // File kept on disk and the updater entry here for historical purposes.
+                       // [ 'addTable', 'image_comment_temp', 'patch-image_comment_temp-table.sql' ],
+                       [ 'addField', 'archive', 'ar_comment_id', 'patch-archive-ar_comment_id.sql' ],
+                       [ 'modifyField', 'image', 'img_description', 'patch-image-img_description-default.sql' ],
+                       [ 'addField', 'ipblocks', 'ipb_reason_id', 'patch-ipblocks-ipb_reason_id.sql' ],
+                       [ 'addField', 'logging', 'log_comment_id', 'patch-logging-log_comment_id.sql' ],
+                       [ 'addField', 'oldimage', 'oi_description_id', 'patch-oldimage-oi_description_id.sql' ],
+                       [ 'addField', 'protected_titles', 'pt_reason_id', 'patch-protected_titles-pt_reason_id.sql' ],
+                       [ 'addField', 'recentchanges', 'rc_comment_id', 'patch-recentchanges-rc_comment_id.sql' ],
+                       [ 'modifyField', 'revision', 'rev_comment', 'patch-revision-rev_comment-default.sql' ],
 
                        // This field was added in 1.31, but is put here so it can be used by 'migrateComments'
                        [ 'addField', 'image', 'img_description_id', 'patch-image-img_description_id.sql' ],
index 4039391..866c3f5 100644 (file)
@@ -58,7 +58,7 @@
        "config-restart": "Ja, erneut starten",
        "config-welcome": "=== Prüfung der Installationsumgebung ===\nDie Basisprüfungen werden jetzt durchgeführt, um festzustellen, ob die Installationsumgebung für MediaWiki geeignet ist.\nNotiere diese Informationen und gib sie an, sofern du Hilfe beim Installieren benötigst.",
        "config-welcome-section-copyright": "=== Lizenz und Nutzungsbedingungen ===\n\n$1\n\nDieses Programm ist freie Software, d. h. es kann, gemäß den Bedingungen der von der Free Software Foundation veröffentlichten ''GNU General Public License'', weiterverteilt und/oder modifiziert werden. Dabei kann die Version 2, oder nach eigenem Ermessen, jede neuere Version der Lizenz verwendet werden.\n\nDieses Programm wird in der Hoffnung verteilt, dass es nützlich sein wird, allerdings '''ohne jegliche Garantie''' und sogar ohne die implizierte Garantie einer '''Marktgängigkeit''' oder '''Eignung für einen bestimmten Zweck'''. Hierzu sind weitere Hinweise in der ''GNU General Public License'' enthalten.\n\nEine [$2 Kopie der GNU General Public License] sollte zusammen mit diesem Programm verteilt worden sein. Sofern dies nicht der Fall war, kann eine Kopie bei der Free Software Foundation Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA, schriftlich angefordert oder auf deren Website [https://www.gnu.org/copyleft/gpl.html online gelesen] werden.",
-       "config-sidebar": "* [https://www.mediawiki.org/wiki/MediaWiki/de Website von MediaWiki]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Contents/de Benutzer­anleitung]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Contents/de Administratoren­anleitung]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ/de Häufig gestellte Fragen]\n----\n* <doclink href=Readme>Lies mich</doclink>\n* <doclink href=ReleaseNotes>Versions­informationen</doclink>\n* <doclink href=Copying>Lizenz­bestimmungen</doclink>\n* <doclink href=UpgradeDoc>Aktualisierung</doclink>",
+       "config-sidebar": "* [https://www.mediawiki.org/wiki/MediaWiki/de Website von MediaWiki]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Contents/de Benutzer­anleitung]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Contents/de Administratoren­anleitung]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ/de Häufig gestellte Fragen]",
        "config-sidebar-readme": "Lies mich",
        "config-sidebar-relnotes": "Veröffentlichungsinformationen",
        "config-sidebar-license": "Kopieren",
@@ -95,7 +95,7 @@
        "config-uploads-not-safe": "'''Warnung:''' Das Standardverzeichnis für hochgeladene Dateien <code>$1</code> ist für die willkürliche Ausführung von Skripten anfällig.\nObwohl MediaWiki die hochgeladenen Dateien auf Sicherheitsrisiken überprüft, wird dennoch dringend empfohlen, diese [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Security#Upload_security Sicherheitslücke] zu schließen, bevor das Hochladen von Dateien aktiviert wird.",
        "config-no-cli-uploads-check": "'''Warnung''': Das Standardverzeichnis für hochgeladene Dateien (<code>$1</code>) wird, während der Installation über die Kommandozeile, nicht auf Sicherheitsanfälligkeiten hinsichtlich willkürlicher Skriptausführungen geprüft.",
        "config-brokenlibxml": "Das System nutzt eine Kombination aus PHP- und libxml2-Versionen, die fehleranfällig ist und versteckte Datenfehler bei MediaWiki und anderen Webanwendungen verursachen kann.\nAktualisiere auf libxml2 2.7.3 oder später, um das Problem zu lösen. Installationsabbruch ([https://bugs.php.net/bug.php?id=45996 siehe hierzu die Fehlermeldung bei PHP]).",
-       "config-suhosin-max-value-length": "Suhosin ist installiert und beschränkt die Länge des GET-Parameters auf $1 Bytes.\nDer ResouceLoader von MediaWiki wird zwar unter diesen Bedingungen funktionieren, allerdings nur mit verminderter Leistungsfähigkeit.\nSofern möglich, sollte der Parameter <code>suhosin.get.max_value_length</code> in der Datei <code>php.ini</code> auf 1024 oder höher festgelegt werden.\nGleichzeitig muss der Parameter <code>$wgResourceLoaderMaxQueryLength</code> in der Datei <code>LocalSettings.php</code> auf den selben Wert eingestellt werden.",
+       "config-suhosin-max-value-length": "Suhosin ist installiert und beschränkt die Länge des GET-Parameters auf $1 Bytes.\nMediaWiki wird nur funktionieren, wenn code>suhosin.get.max_value_length</code> $2 oder höher ist. Deaktiviere diese Einstellung oder ändere sie in <code>php.ini</code> zu $3.",
        "config-using-32bit": "<strong>Warnung:</strong> Es scheint, als ob dein System mit 32-Bit-Ganzzahlen läuft. Dies wird [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:32-bit nicht empfohlen].",
        "config-db-type": "Datenbanksystem:",
        "config-db-host": "Datenbankserver:",
index 511b0da..7a614e8 100644 (file)
        "config-extension-not-found": "拡張機能「$1」の登録ファイルは見つかりませんでした",
        "config-extension-dependency": "拡張機能「$1」のインストール中に依存関係エラーが発生しました: $2",
        "mainpagetext": "<strong>MediaWiki はインストール済みです。</strong>",
-       "mainpagedocfooter": "ウィキソフトウェアの使い方に関する情報は[https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Contents 利用者案内]を参照してください。\n\n== はじめましょう ==\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Configuration_settings/ja 設定の一覧]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ/ja MediaWiki よくある質問と回答]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki リリース情報メーリングリスト]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Localisation/ja MediaWiki のあなたの言語へのローカライズ]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Combating_spam あなたのウィキでスパムと戦う方法を学ぶ]"
+       "mainpagedocfooter": "ウィキソフトウェアの使い方に関する情報は[https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Contents 利用者案内]を参照してください。\n\nウィキソフトウェアの使い方に関する情報は[https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Contents 利用者案内]を参照してください。\n\n== はじめましょう ==\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Configuration_settings/ja 設定の一覧]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ/ja MediaWiki よくある質問]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki リリース情報メーリングリスト]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Localisation/ja MediaWiki をご使用の言語へ地域化]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Combating_spam ご使用のウィキでスパムと戦う方法を学ぶ]"
 }
diff --git a/includes/installer/i18n/mni.json b/includes/installer/i18n/mni.json
new file mode 100644 (file)
index 0000000..5f6088a
--- /dev/null
@@ -0,0 +1,46 @@
+{
+       "@metadata": {
+               "authors": [
+                       "Awangba Mangang"
+               ]
+       },
+       "config-your-language": "ꯅꯡꯒꯤ ꯂꯣꯟ",
+       "config-wiki-language": "ꯃꯤꯇꯩꯂꯣꯟ",
+       "config-wiki-language-help": "ꯃꯤꯇꯩꯂꯣꯟ",
+       "config-back": "ꯍꯟꯂꯨ",
+       "config-continue": "ꯃꯈꯥꯆꯠꯊꯧ",
+       "config-page-language": "ꯂꯣꯟ",
+       "config-page-welcome": "ꯋꯤꯀꯤꯃꯦꯗꯤꯌꯥꯗ ꯂꯦꯡꯁꯤꯟꯕꯤꯔꯛꯁꯤ",
+       "config-page-dbconnect": "ꯗꯥꯇꯥꯕꯦꯁꯇ ꯁꯝꯃꯨ",
+       "config-page-upgrade": "ꯋꯥꯡꯈꯠꯍꯜꯂꯨ ꯂꯩꯔꯤꯕꯥ ꯄꯣꯠꯇꯨ ꯍꯥꯞꯁꯤꯟꯗꯨꯅꯥ",
+       "config-page-dbsettings": "ꯗꯥꯇꯥꯕꯦꯁ ꯁꯦꯝꯐꯝ",
+       "config-page-name": "ꯃꯃꯤꯡ",
+       "config-page-options": "ꯃꯌꯥꯝꯒꯤꯃꯔꯛꯇꯥ",
+       "config-page-install": "ꯈꯤꯟꯀꯠꯂꯨ",
+       "config-page-complete": "ꯂꯣꯏꯁꯤꯟꯂꯦ",
+       "config-page-restart": "ꯑꯃꯨꯛ ꯍꯟꯅꯥ ꯈꯤꯟꯀꯠꯂꯨ",
+       "config-page-readme": "ꯄꯥꯕꯤꯌꯣ ꯑꯩꯕꯨ",
+       "config-page-releasenotes": "ꯑꯌꯤꯕꯥ ꯊꯥꯗꯣꯛ ꯎ",
+       "config-page-copying": "ꯁꯤꯟꯗꯣꯛ ꯏ",
+       "config-page-upgradedoc": "ꯋꯥꯡꯈꯠꯍꯜꯂꯤ",
+       "config-page-existingwiki": "ꯂꯩꯔꯤꯕꯥ ꯋꯤꯀꯤ",
+       "config-help-restart": "ꯅꯪ ꯑꯃꯨꯛ ꯍꯟꯅꯥ ꯈꯤꯟꯀꯠ ꯄꯥꯒꯤ ꯊꯧꯑꯣꯡ ꯑꯃꯥꯗꯤ ꯍꯥꯟꯅꯅꯥ ꯌꯣꯛꯁꯤꯟꯗꯨꯅꯥ ꯊꯝꯕꯥ ꯗꯥꯇꯥ ꯁꯤ ꯃꯥꯡꯍꯟꯕꯥ ꯄꯥꯝꯕꯔꯥ?",
+       "config-restart": "ꯍꯣꯏ‌, ꯑꯃꯨꯛꯀꯥ ꯍꯧꯔꯦ ꯃꯥꯁꯤ",
+       "config-welcome": "===ꯑꯀꯣꯏꯕꯒꯤ ꯐꯤꯕꯝ ꯌꯦꯡꯁꯤꯟꯕ===\n\nꯇꯥꯉꯥꯏ ꯐꯥꯗꯅ ꯆꯡꯕꯔꯥ ꯌꯦꯡꯁꯤꯟꯕ ꯫ ꯃꯗꯨꯗꯤ ꯋꯤꯀꯤꯄꯦꯗꯤꯌꯥ ꯈꯤꯟꯀꯠꯄꯥ/ꯂꯤꯡꯈꯠꯄ ꯁꯤ ꯑꯀꯣꯏꯕꯒꯤ ꯒꯥ ꯆꯥꯟꯅꯥꯕꯔꯥ ꯍꯥꯏꯅ ꯫\nꯀꯥꯎꯊꯣꯛꯇꯅ ꯃꯁꯤꯒꯤ ꯋꯥꯔꯣꯜꯁꯤ ꯍꯥꯞꯆꯤꯟꯂꯨ ꯅꯡꯅꯥ ꯀꯃꯥꯏ ꯇꯧꯔꯒ ꯈꯤꯟꯀꯠ ꯂꯣꯏꯁꯤꯟꯅꯕ ꯃꯥꯇꯦꯡ ꯊꯤꯔꯥꯗꯤ ꯫",
+       "config-sidebar-readme": "ꯄꯥꯕꯤꯌꯣ ꯑꯩꯕꯨ",
+       "config-sidebar-relnotes": "ꯑꯌꯤꯕꯥ ꯊꯥꯗꯣꯛ ꯎ",
+       "config-sidebar-license": "ꯁꯤꯟꯗꯣꯛ ꯏ",
+       "config-sidebar-upgrade": "ꯋꯥꯡꯈꯠꯍꯜꯂꯤ",
+       "config-db-type": "ꯗꯥꯇꯥ ꯃꯈꯜ:",
+       "config-db-wiki-settings": "ꯃꯁꯤꯒꯤ ꯋꯤꯀꯤ ꯁꯛꯈꯪꯗꯣꯛꯎ",
+       "config-site-name": "ꯋꯤꯀꯤ ꯃꯃꯤꯡ:",
+       "config-project-namespace": "ꯊꯧꯔꯥꯡ ꯃꯃꯤꯡ ꯏꯐꯝ:",
+       "config-ns-generic": "ꯊꯧꯔꯥꯡ",
+       "config-ns-site-name": "$1ꯒ:ꯃꯥꯟꯅꯅꯕ ꯋꯤꯀꯤ ꯃꯃꯤꯡ",
+       "config-ns-other-default": "ꯑꯩꯒꯤ ꯋꯤꯀꯤ",
+       "config-admin-name": "ꯅꯪꯒꯤ ꯁꯤꯖꯤꯟꯅꯔꯤꯕ ꯃꯃꯤꯡ:",
+       "config-admin-password": "ꯆꯪꯁꯤꯟꯅꯕ ꯋꯥꯍꯩ:",
+       "config-admin-password-confirm": "ꯆꯪꯁꯤꯟꯅꯕ ꯋꯥꯍꯩ ꯑꯃꯨꯛꯀꯥ:",
+       "config-profile-wiki": "ꯋꯤꯀꯤ ꯍꯥꯡꯗꯣꯛꯎ",
+       "config-profile-private": "ꯂꯅꯥꯏ ꯋꯤꯀꯤ"
+}
index 938f199..e9d578b 100644 (file)
@@ -93,7 +93,7 @@
        "config-uploads-not-safe": "'''Увага:''' Ваша типова папка для завантажень <code>$1</code> вразлива до виконання довільних скриптів.\nХоча MediaWiki перевіряє усі завантажені файли на наявність загроз, наполегливо рекомендується [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Security#Upload_security закрити дану вразливість] перед тим, як дозволяти завантаження файлів.",
        "config-no-cli-uploads-check": "'''Увага:''' Ваша типова папка для завантажень (<code>$1</code>) не перевірялась на вразливість до виконання довільних скриптів під час встановлення CLI.",
        "config-brokenlibxml": "У Вашій системі невдале поєднання версій PHP і libxml2, яке може спричинити пошкодження прихованих даних у MediaWiki та інших веб-застосунках.\nОновіть libxml2 до версії 2.7.3 або пізнішої  ([https://bugs.php.net/bug.php?id=45996 відомості про помилку]).\nВстановлення перервано.",
-       "config-suhosin-max-value-length": "Suhosin Ð²Ñ\81Ñ\82ановлено Ñ\96 Ð¾Ð±Ð¼ÐµÐ¶Ñ\83Ñ\94 Ð¿Ð°Ñ\80амеÑ\82Ñ\80а GET  <code>length</code> Ð´Ð¾ $1 Ð±Ð°Ð¹Ñ\82а. Ð\9aомпоненÑ\82 MediaWiki ResourceLoader Ð±Ñ\83де Ð¾Ð±Ñ\85одиÑ\82и Ñ\86е Ð¾Ð±Ð¼ÐµÐ¶ÐµÐ½Ð½Ñ\8f, Ð¾Ð´Ð½Ð°Ðº Ñ\86е Ð·Ð¼ÐµÐ½Ñ\88иÑ\82Ñ\8c Ð¿Ñ\80одÑ\83кÑ\82ивнÑ\96Ñ\81Ñ\82Ñ\8c. Ð¯ÐºÑ\89о Ñ\86е Ð¼Ð¾Ð¶Ð»Ð¸Ð²Ð¾, Ð\92ам Ð²Ð°Ñ\80Ñ\82о Ð²Ñ\81Ñ\82ановиÑ\82и Ð·Ð½Ð°Ñ\87еннÑ\8f <code>suhosin.get.max_value_length</code> Ñ\8fк 1024 Ñ\96 Ð±Ñ\96лÑ\8cÑ\88е Ñ\83 <code>php.ini</code> Ñ\96 Ð²Ñ\81Ñ\82ановиÑ\82и Ñ\82аке Ð¶ Ð·Ð½Ð°Ñ\87еннÑ\8f <code>$wgResourceLoaderMaxQueryLength</code> Ñ\83 LocalSettings.php .",
+       "config-suhosin-max-value-length": "Suhosin Ð²Ñ\81Ñ\82ановлено Ñ\96 Ð²Ñ\96н Ð¾Ð±Ð¼ÐµÐ¶Ñ\83Ñ\94 GET-паÑ\80амеÑ\82Ñ\80 <code>length</code> Ð´Ð¾ $1 {{PLURAL:$1|байÑ\82|байÑ\82а|байÑ\82}}.   Ð\94лÑ\8f MediaWiki Ð¿Ð¾Ñ\82Ñ\80Ñ\96бно, Ñ\89об Ð·Ð½Ð°Ñ\87еннÑ\8f <code>suhosin.get.max_value_length</code> Ð±Ñ\83ло Ñ\85оÑ\87а Ð± $2. Ð\92имкнÑ\96Ñ\82Ñ\8c Ñ\86е Ð½Ð°Ð»Ð°Ñ\88Ñ\82Ñ\83ваннÑ\8f, Ð°Ð±Ð¾ Ð·Ð±Ñ\96лÑ\8cÑ\88Ñ\96Ñ\82Ñ\8c Ð·Ð½Ð°Ñ\87еннÑ\8f Ñ\83 <code>php.ini</code> Ð´Ð¾ $3.",
        "config-using-32bit": "<strong>Попередження:</strong> схоже, що Ваша система працює з 32-бітними цілими числами. Таке [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:32-bit не рекомендується].",
        "config-db-type": "Тип бази даних:",
        "config-db-host": "Хост бази даних:",
index 19dd8fe..7303d9b 100644 (file)
@@ -316,6 +316,23 @@ class StringUtils {
                return $text;
        }
 
+       /**
+        * Utility function to check if the given string is a valid PCRE regex. Avoids
+        * manually calling suppressWarnings and restoreWarnings, and provides a
+        * one-line solution without the need to use @.
+        *
+        * @since 1.34
+        * @param string $string The string you want to check being a valid regex
+        * @return bool
+        */
+       public static function isValidPCRERegex( $string ) {
+               AtEase::suppressWarnings();
+               // @phan-suppress-next-line PhanParamSuspiciousOrder False positive
+               $isValid = preg_match( $string, '' );
+               AtEase::restoreWarnings();
+               return $isValid !== false;
+       }
+
        /**
         * Escape a string to make it suitable for inclusion in a preg_replace()
         * replacement parameter.
@@ -343,21 +360,4 @@ class StringUtils {
                        return new ArrayIterator( explode( $separator, $subject ) );
                }
        }
-
-       /**
-        * Utility function to check if the given string is a valid regex. Avoids
-        * manually calling suppressWarnings and restoreWarnings, and provides a
-        * one-line solution without the need to use @.
-        *
-        * @since 1.34
-        * @param string $string The string you want to check being a valid regex
-        * @return bool
-        */
-       public static function isValidRegex( $string ) {
-               AtEase::suppressWarnings();
-               // @phan-suppress-next-line PhanParamSuspiciousOrder False positive
-               $isValid = preg_match( $string, '' );
-               AtEase::restoreWarnings();
-               return $isValid !== false;
-       }
 }
index 70f3553..2f44a55 100644 (file)
@@ -1269,7 +1269,7 @@ class WANObjectCache implements IExpiringStore, IStoreKeyEncoder, LoggerAwareInt
                // Nested callback process cache use is not lag-safe with regard to HOLDOFF_TTL since
                // process cached values are more lagged than persistent ones as they are not purged.
                if ( $pCache && $this->callbackDepth == 0 ) {
-                       $cached = $pCache->get( $this->getProcessCacheKey( $key, $version ), INF, false );
+                       $cached = $pCache->get( $this->getProcessCacheKey( $key, $version ), $pcTTL, false );
                        if ( $cached !== false ) {
                                return $cached;
                        }
@@ -2545,6 +2545,9 @@ class WANObjectCache implements IExpiringStore, IStoreKeyEncoder, LoggerAwareInt
                if ( !isset( $this->processCaches[$group] ) ) {
                        list( , $size ) = explode( ':', $group );
                        $this->processCaches[$group] = new MapCacheLRU( (int)$size );
+                       if ( $this->wallClockOverride !== null ) {
+                               $this->processCaches[$group]->setMockTime( $this->wallClockOverride );
+                       }
                }
 
                return $this->processCaches[$group];
@@ -2641,5 +2644,8 @@ class WANObjectCache implements IExpiringStore, IStoreKeyEncoder, LoggerAwareInt
        public function setMockTime( &$time ) {
                $this->wallClockOverride =& $time;
                $this->cache->setMockTime( $time );
+               foreach ( $this->processCaches as $pCache ) {
+                       $pCache->setMockTime( $time );
+               }
        }
 }
index 4c68833..a3e57ae 100644 (file)
@@ -27,11 +27,6 @@ use InvalidArgumentException;
 
 /**
  * Trivial LoadBalancer that always returns an injected connection handle.
- *
- * Note that, while this LoadBalancer does not open any connections itself,
- * it still closes the injected connection at times, including during destruction.
- * It is therefore unsuitable for use in tests unless you have a Database instance
- * separate from the main test database (which is expected to stay open).
  */
 class LoadBalancerSingle extends LoadBalancer {
        /** @var IDatabase */
index 6e3b26b..81d9aa2 100644 (file)
@@ -101,7 +101,7 @@ class ProtectLogFormatter extends LogFormatter {
                ];
 
                // Show change protection link
-               if ( !MediaWikiServices::getInstance()
+               if ( MediaWikiServices::getInstance()
                                ->getPermissionManager()
                                ->userHasRight( $this->context->getUser(), 'protect' )
                ) {
index 0d546fa..54ab6a1 100644 (file)
@@ -824,7 +824,7 @@ class ResourceLoader implements LoggerAwareInterface {
                        $errorResponse = self::makeComment( $errorText );
                        if ( $context->shouldIncludeScripts() ) {
                                $errorResponse .= 'if (window.console && console.error) { console.error('
-                                       . self::encodeJsonForScript( $errorText )
+                                       . $context->encodeJson( $errorText )
                                        . "); }\n";
                        }
 
@@ -1098,7 +1098,14 @@ MESSAGE;
                                                        $strContent = $scripts;
                                                } elseif ( is_array( $scripts ) ) {
                                                        // ...except when $scripts is an array of URLs or an associative array
-                                                       $strContent = self::makeLoaderImplementScript( $implementKey, $scripts, [], [], [] );
+                                                       $strContent = self::makeLoaderImplementScript(
+                                                               $context,
+                                                               $implementKey,
+                                                               $scripts,
+                                                               [],
+                                                               [],
+                                                               []
+                                                       );
                                                }
                                                break;
                                        case 'styles':
@@ -1124,6 +1131,7 @@ MESSAGE;
                                                        }
                                                }
                                                $strContent = self::makeLoaderImplementScript(
+                                                       $context,
                                                        $implementKey,
                                                        $scripts,
                                                        $content['styles'] ?? [],
@@ -1169,7 +1177,7 @@ MESSAGE;
 
                        // Set the state of modules we didn't respond to with mw.loader.implement
                        if ( $states ) {
-                               $stateScript = self::makeLoaderStateScript( $states );
+                               $stateScript = self::makeLoaderStateScript( $context, $states );
                                if ( !$context->getDebug() ) {
                                        $stateScript = self::filter( 'minify-js', $stateScript );
                                }
@@ -1178,7 +1186,7 @@ MESSAGE;
                        }
                } elseif ( $states ) {
                        $this->errors[] = 'Problematic modules: '
-                               . self::encodeJsonForScript( $states );
+                               . $context->encodeJson( $states );
                }
 
                return $out;
@@ -1217,6 +1225,7 @@ MESSAGE;
        /**
         * Return JS code that calls mw.loader.implement with given module properties.
         *
+        * @param ResourceLoaderContext $context
         * @param string $name Module name or implement key (format "`[name]@[version]`")
         * @param XmlJsCode|array|string $scripts Code as XmlJsCode (to be wrapped in a closure),
         *  list of URLs to JavaScript files, string of JavaScript for `$.globalEval`, or array with
@@ -1231,13 +1240,13 @@ MESSAGE;
         * @throws MWException
         * @return string JavaScript code
         */
-       protected static function makeLoaderImplementScript(
-               $name, $scripts, $styles, $messages, $templates
+       private static function makeLoaderImplementScript(
+               ResourceLoaderContext $context, $name, $scripts, $styles, $messages, $templates
        ) {
                if ( $scripts instanceof XmlJsCode ) {
                        if ( $scripts->value === '' ) {
                                $scripts = null;
-                       } elseif ( self::inDebugMode() ) {
+                       } elseif ( $context->getDebug() ) {
                                $scripts = new XmlJsCode( "function ( $, jQuery, require, module ) {\n{$scripts->value}\n}" );
                        } else {
                                $scripts = new XmlJsCode( 'function($,jQuery,require,module){' . $scripts->value . '}' );
@@ -1249,7 +1258,7 @@ MESSAGE;
                                // All of these essentially do $file = $file['content'];, some just have wrapping around it
                                if ( $file['type'] === 'script' ) {
                                        // Multi-file modules only get two parameters ($ and jQuery are being phased out)
-                                       if ( self::inDebugMode() ) {
+                                       if ( $context->getDebug() ) {
                                                $file = new XmlJsCode( "function ( require, module ) {\n{$file['content']}\n}" );
                                        } else {
                                                $file = new XmlJsCode( 'function(require,module){' . $file['content'] . '}' );
@@ -1260,8 +1269,8 @@ MESSAGE;
                        }
                        $scripts = XmlJsCode::encodeObject( [
                                'main' => $scripts['main'],
-                               'files' => XmlJsCode::encodeObject( $files, self::inDebugMode() )
-                       ], self::inDebugMode() );
+                               'files' => XmlJsCode::encodeObject( $files, $context->getDebug() )
+                       ], $context->getDebug() );
                } elseif ( !is_string( $scripts ) && !is_array( $scripts ) ) {
                        throw new MWException( 'Invalid scripts error. Array of URLs or string of code expected.' );
                }
@@ -1278,7 +1287,7 @@ MESSAGE;
                ];
                self::trimArray( $module );
 
-               return Xml::encodeJsCall( 'mw.loader.implement', $module, self::inDebugMode() );
+               return Xml::encodeJsCall( 'mw.loader.implement', $module, $context->getDebug() );
        }
 
        /**
@@ -1357,25 +1366,22 @@ MESSAGE;
        }
 
        /**
-        * Returns a JS call to mw.loader.state, which sets the state of one
-        * ore more modules to a given value. Has two calling conventions:
-        *
-        *    - ResourceLoader::makeLoaderStateScript( $name, $state ):
-        *         Set the state of a single module called $name to $state
+        * Returns a JS call to mw.loader.state, which sets the state of modules
+        * to a given value:
         *
-        *    - ResourceLoader::makeLoaderStateScript( [ $name => $state, ... ] ):
+        *    - ResourceLoader::makeLoaderStateScript( $context, [ $name => $state, ... ] ):
         *         Set the state of modules with the given names to the given states
         *
-        * @param array|string $states
-        * @param string|null $state
+        * @internal
+        * @param ResourceLoaderContext $context
+        * @param array $states
         * @return string JavaScript code
         */
-       public static function makeLoaderStateScript( $states, $state = null ) {
-               if ( !is_array( $states ) ) {
-                       $states = [ $states => $state ];
-               }
+       public static function makeLoaderStateScript(
+               ResourceLoaderContext $context, array $states
+       ) {
                return 'mw.loader.state('
-                       . self::encodeJsonForScript( $states )
+                       . $context->encodeJson( $states )
                        . ');';
        }
 
@@ -1420,15 +1426,15 @@ MESSAGE;
         * @par Example
         * @code
         *
-        *     ResourceLoader::makeLoaderRegisterScript( [
+        *     ResourceLoader::makeLoaderRegisterScript( $context, [
         *        [ $name1, $version1, $dependencies1, $group1, $source1, $skip1 ],
         *        [ $name2, $version2, $dependencies1, $group2, $source2, $skip2 ],
         *        ...
         *     ] ):
         * @endcode
         *
-        * @internal
-        * @since 1.32
+        * @internal For use by ResourceLoaderStartUpModule only
+        * @param ResourceLoaderContext $context
         * @param array $modules Array of module registration arrays, each containing
         *  - string: module name
         *  - string: module version
@@ -1438,7 +1444,9 @@ MESSAGE;
         *  - string|null: Script body of a skip function (optional)
         * @return string JavaScript code
         */
-       public static function makeLoaderRegisterScript( array $modules ) {
+       public static function makeLoaderRegisterScript(
+               ResourceLoaderContext $context, array $modules
+       ) {
                // Optimisation: Transform dependency names into indexes when possible
                // to produce smaller output. They are expanded by mw.loader.register on
                // the other end using resolveIndexedDependencies().
@@ -1461,30 +1469,29 @@ MESSAGE;
                array_walk( $modules, [ self::class, 'trimArray' ] );
 
                return 'mw.loader.register('
-                       . self::encodeJsonForScript( $modules )
+                       . $context->encodeJson( $modules )
                        . ');';
        }
 
        /**
         * Returns JS code which calls mw.loader.addSource() with the given
-        * parameters. Has two calling conventions:
-        *
-        *   - ResourceLoader::makeLoaderSourcesScript( $id, $properties ):
-        *       Register a single source
+        * parameters.
         *
-        *   - ResourceLoader::makeLoaderSourcesScript( [ $id1 => $loadUrl, $id2 => $loadUrl, ... ] );
+        *   - ResourceLoader::makeLoaderSourcesScript( $context,
+        *         [ $id1 => $loadUrl, $id2 => $loadUrl, ... ]
+        *     );
         *       Register sources with the given IDs and properties.
         *
-        * @param string|array $sources Source ID
-        * @param string|null $loadUrl load.php url
+        * @internal For use by ResourceLoaderStartUpModule only
+        * @param ResourceLoaderContext $context
+        * @param array $sources
         * @return string JavaScript code
         */
-       public static function makeLoaderSourcesScript( $sources, $loadUrl = null ) {
-               if ( !is_array( $sources ) ) {
-                       $sources = [ $sources => $loadUrl ];
-               }
+       public static function makeLoaderSourcesScript(
+               ResourceLoaderContext $context, array $sources
+       ) {
                return 'mw.loader.addSource('
-                       . self::encodeJsonForScript( $sources )
+                       . $context->encodeJson( $sources )
                        . ');';
        }
 
@@ -1810,10 +1817,11 @@ MESSAGE;
         * Get global LESS variables.
         *
         * @since 1.27
-        * @deprecated since 1.32 Use ResourceLoderModule::getLessVars() instead.
+        * @deprecated since 1.32 Use ResourceLoaderModule::getLessVars() instead.
         * @return array Map of variable names to string CSS values.
         */
        public function getLessVars() {
+               wfDeprecated( __METHOD__, '1.32' );
                return [];
        }
 }
index d98d86b..71961e2 100644 (file)
@@ -213,7 +213,7 @@ class ResourceLoaderClientHtml {
                                // Load from load.php?only=styles via <link rel=stylesheet>
                                $data['styles'][] = $name;
                        }
-                       $deprecation = $module->getDeprecationInformation();
+                       $deprecation = $module->getDeprecationInformation( $context );
                        if ( $deprecation ) {
                                $data['styleDeprecations'][] = $deprecation;
                        }
@@ -254,14 +254,14 @@ class ResourceLoaderClientHtml {
                // See also startup/startup.js.
                $nojsClass = $nojsClass ?? $this->getDocumentAttributes()['class'];
                $jsClass = preg_replace( '/(^|\s)client-nojs(\s|$)/', '$1client-js$2', $nojsClass );
-               $jsClassJson = ResourceLoader::encodeJsonForScript( $jsClass );
+               $jsClassJson = $this->context->encodeJson( $jsClass );
                $script = <<<JAVASCRIPT
 document.documentElement.className = {$jsClassJson};
 JAVASCRIPT;
 
                // Inline script: Declare mw.config variables for this page.
                if ( $this->config ) {
-                       $confJson = ResourceLoader::encodeJsonForScript( $this->config );
+                       $confJson = $this->context->encodeJson( $this->config );
                        $script .= <<<JAVASCRIPT
 RLCONF = {$confJson};
 JAVASCRIPT;
@@ -270,7 +270,7 @@ JAVASCRIPT;
                // Inline script: Declare initial module states for this page.
                $states = array_merge( $this->exemptStates, $data['states'] );
                if ( $states ) {
-                       $stateJson = ResourceLoader::encodeJsonForScript( $states );
+                       $stateJson = $this->context->encodeJson( $states );
                        $script .= <<<JAVASCRIPT
 RLSTATE = {$stateJson};
 JAVASCRIPT;
@@ -278,7 +278,7 @@ JAVASCRIPT;
 
                // Inline script: Declare general modules to load on this page.
                if ( $data['general'] ) {
-                       $pageModulesJson = ResourceLoader::encodeJsonForScript( $data['general'] );
+                       $pageModulesJson = $this->context->encodeJson( $data['general'] );
                        $script .= <<<JAVASCRIPT
 RLPAGEMODULES = {$pageModulesJson};
 JAVASCRIPT;
@@ -480,7 +480,7 @@ JAVASCRIPT;
                                                        ] );
                                                } else {
                                                        $chunk = ResourceLoader::makeInlineScript(
-                                                               'mw.loader.load(' . ResourceLoader::encodeJsonForScript( $url ) . ');',
+                                                               'mw.loader.load(' . $mainContext->encodeJson( $url ) . ');',
                                                                $nonce
                                                        );
                                                }
index 3db0c01..1274052 100644 (file)
@@ -406,7 +406,7 @@ class ResourceLoaderContext implements MessageLocalizer {
        /**
         * Get the request base parameters, omitting any defaults.
         *
-        * @internal For internal use by ResourceLoaderStartUpModule only
+        * @internal For use by ResourceLoaderStartUpModule only
         * @return array
         */
        public function getReqBase() {
@@ -422,4 +422,32 @@ class ResourceLoaderContext implements MessageLocalizer {
                }
                return $reqBase;
        }
+
+       /**
+        * Wrapper around json_encode that avoids needless escapes,
+        * and pretty-prints in debug mode.
+        *
+        * @internal
+        * @param mixed $data
+        * @return string|false JSON string, false on error
+        */
+       public function encodeJson( $data ) {
+               // Keep output as small as possible by disabling needless escape modes
+               // that PHP uses by default.
+               // However, while most module scripts are only served on HTTP responses
+               // for JavaScript, some modules can also be embedded in the HTML as inline
+               // scripts. This, and the fact that we sometimes need to export strings
+               // containing user-generated content and labels that may genuinely contain
+               // a sequences like "</script>", we need to encode either '/' or '<'.
+               // By default PHP escapes '/'. Let's escape '<' instead which is less common
+               // and allows URLs to mostly remain readable.
+               $jsonFlags = JSON_UNESCAPED_SLASHES |
+                       JSON_UNESCAPED_UNICODE |
+                       JSON_HEX_TAG |
+                       JSON_HEX_AMP;
+               if ( $this->getDebug() ) {
+                       $jsonFlags |= JSON_PRETTY_PRINT;
+               }
+               return json_encode( $data, $jsonFlags );
+       }
 }
index 23a9a14..3388058 100644 (file)
@@ -384,7 +384,7 @@ class ResourceLoaderFileModule extends ResourceLoaderModule {
         * @return string|array JavaScript code for $context, or package files data structure
         */
        public function getScript( ResourceLoaderContext $context ) {
-               $deprecationScript = $this->getDeprecationInformation();
+               $deprecationScript = $this->getDeprecationInformation( $context );
                if ( $this->packageFiles !== null ) {
                        $packageFiles = $this->getPackageFiles( $context );
                        if ( $deprecationScript ) {
@@ -906,7 +906,7 @@ class ResourceLoaderFileModule extends ResourceLoaderModule {
         *     keyed by media type
         * @throws MWException
         */
-       public function readStyleFiles( array $styles, $flip, $context ) {
+       public function readStyleFiles( array $styles, $flip, ResourceLoaderContext $context ) {
                if ( !$styles ) {
                        return [];
                }
@@ -933,7 +933,7 @@ class ResourceLoaderFileModule extends ResourceLoaderModule {
         * @return string CSS data in script file
         * @throws MWException If the file doesn't exist
         */
-       protected function readStyleFile( $path, $flip, $context ) {
+       protected function readStyleFile( $path, $flip, ResourceLoaderContext $context ) {
                $localPath = $this->getLocalPath( $path );
                $remotePath = $this->getRemotePath( $path );
                if ( !file_exists( $localPath ) ) {
@@ -973,7 +973,7 @@ class ResourceLoaderFileModule extends ResourceLoaderModule {
         * @param ResourceLoaderContext $context
         * @return bool
         */
-       public function getFlip( $context ) {
+       public function getFlip( ResourceLoaderContext $context ) {
                return $context->getDirection() === 'rtl' && !$this->noflip;
        }
 
index ffc9b3d..a6e5f15 100644 (file)
@@ -57,8 +57,8 @@ class ResourceLoaderLanguageDataModule extends ResourceLoaderFileModule {
        public function getScript( ResourceLoaderContext $context ) {
                return parent::getScript( $context )
                        . 'mw.language.setData('
-                       . ResourceLoader::encodeJsonForScript( $context->getLanguage() ) . ','
-                       . ResourceLoader::encodeJsonForScript( $this->getData( $context ) )
+                       . $context->encodeJson( $context->getLanguage() ) . ','
+                       . $context->encodeJson( $this->getData( $context ) )
                        . ');';
        }
 
index c9fd267..eca3a97 100644 (file)
@@ -128,7 +128,7 @@ abstract class ResourceLoaderModule implements LoggerAwareInterface {
         * @param ResourceLoaderContext $context
         * @return bool
         */
-       public function getFlip( $context ) {
+       public function getFlip( ResourceLoaderContext $context ) {
                return MediaWikiServices::getInstance()->getContentLanguage()->getDir() !==
                        $context->getDirection();
        }
@@ -136,9 +136,13 @@ abstract class ResourceLoaderModule implements LoggerAwareInterface {
        /**
         * Get JS representing deprecation information for the current module if available
         *
+        * @param ResourceLoaderContext|null $context Missing $context is deprecated in 1.34
         * @return string JavaScript code
         */
-       public function getDeprecationInformation() {
+       public function getDeprecationInformation( ResourceLoaderContext $context = null ) {
+               if ( $context === null ) {
+                       wfDeprecated( __METHOD__ . ' without a ResourceLoader context', '1.34' );
+               }
                $deprecationInfo = $this->deprecated;
                if ( $deprecationInfo ) {
                        $name = $this->getName();
@@ -146,7 +150,10 @@ abstract class ResourceLoaderModule implements LoggerAwareInterface {
                        if ( is_string( $deprecationInfo ) ) {
                                $warning .= "\n" . $deprecationInfo;
                        }
-                       return 'mw.log.warn(' . ResourceLoader::encodeJsonForScript( $warning ) . ');';
+                       if ( $context === null ) {
+                               return 'mw.log.warn(' . ResourceLoader::encodeJsonForScript( $warning ) . ');';
+                       }
+                       return 'mw.log.warn(' . $context->encodeJson( $warning ) . ');';
                } else {
                        return '';
                }
index 78775fb..df8126e 100644 (file)
@@ -58,7 +58,7 @@ class ResourceLoaderStartUpModule extends ResourceLoaderModule {
         * @param ResourceLoaderContext $context
         * @return array
         */
-       private function getConfigSettings( $context ) {
+       private function getConfigSettings( ResourceLoaderContext $context ) {
                $conf = $this->getConfig();
 
                /**
@@ -310,7 +310,7 @@ class ResourceLoaderStartUpModule extends ResourceLoaderModule {
                        }
 
                        $skipFunction = $module->getSkipFunction();
-                       if ( $skipFunction !== null && !ResourceLoader::inDebugMode() ) {
+                       if ( $skipFunction !== null && !$context->getDebug() ) {
                                $skipFunction = ResourceLoader::filter( 'minify-js', $skipFunction );
                        }
 
@@ -326,7 +326,7 @@ class ResourceLoaderStartUpModule extends ResourceLoaderModule {
                self::compileUnresolvedDependencies( $registryData );
 
                // Register sources
-               $out .= ResourceLoader::makeLoaderSourcesScript( $resourceLoader->getSources() );
+               $out .= ResourceLoader::makeLoaderSourcesScript( $context, $resourceLoader->getSources() );
 
                // Figure out the different call signatures for mw.loader.register
                $registrations = [];
@@ -344,10 +344,10 @@ class ResourceLoaderStartUpModule extends ResourceLoaderModule {
                }
 
                // Register modules
-               $out .= "\n" . ResourceLoader::makeLoaderRegisterScript( $registrations );
+               $out .= "\n" . ResourceLoader::makeLoaderRegisterScript( $context, $registrations );
 
                if ( $states ) {
-                       $out .= "\n" . ResourceLoader::makeLoaderStateScript( $states );
+                       $out .= "\n" . ResourceLoader::makeLoaderStateScript( $context, $states );
                }
 
                return $out;
@@ -426,23 +426,23 @@ class ResourceLoaderStartUpModule extends ResourceLoaderModule {
 
                // Perform replacements for mediawiki.js
                $mwLoaderPairs = [
-                       '$VARS.reqBase' => ResourceLoader::encodeJsonForScript( $context->getReqBase() ),
-                       '$VARS.baseModules' => ResourceLoader::encodeJsonForScript( $this->getBaseModules() ),
-                       '$VARS.maxQueryLength' => ResourceLoader::encodeJsonForScript(
+                       '$VARS.reqBase' => $context->encodeJson( $context->getReqBase() ),
+                       '$VARS.baseModules' => $context->encodeJson( $this->getBaseModules() ),
+                       '$VARS.maxQueryLength' => $context->encodeJson(
                                $conf->get( 'ResourceLoaderMaxQueryLength' )
                        ),
                        // The client-side module cache can be disabled by site configuration.
                        // It is also always disabled in debug mode.
-                       '$VARS.storeEnabled' => ResourceLoader::encodeJsonForScript(
+                       '$VARS.storeEnabled' => $context->encodeJson(
                                $conf->get( 'ResourceLoaderStorageEnabled' ) && !$context->getDebug()
                        ),
-                       '$VARS.wgLegacyJavaScriptGlobals' => ResourceLoader::encodeJsonForScript(
+                       '$VARS.wgLegacyJavaScriptGlobals' => $context->encodeJson(
                                $conf->get( 'LegacyJavaScriptGlobals' )
                        ),
-                       '$VARS.storeKey' => ResourceLoader::encodeJsonForScript( $this->getStoreKey() ),
-                       '$VARS.storeVary' => ResourceLoader::encodeJsonForScript( $this->getStoreVary( $context ) ),
-                       '$VARS.groupUser' => ResourceLoader::encodeJsonForScript( $this->getGroupId( 'user' ) ),
-                       '$VARS.groupPrivate' => ResourceLoader::encodeJsonForScript( $this->getGroupId( 'private' ) ),
+                       '$VARS.storeKey' => $context->encodeJson( $this->getStoreKey() ),
+                       '$VARS.storeVary' => $context->encodeJson( $this->getStoreVary( $context ) ),
+                       '$VARS.groupUser' => $context->encodeJson( $this->getGroupId( 'user' ) ),
+                       '$VARS.groupPrivate' => $context->encodeJson( $this->getGroupId( 'private' ) ),
                ];
                $profilerStubs = [
                        '$CODE.profileExecuteStart();' => 'mw.loader.profiler.onExecuteStart( module );',
@@ -461,7 +461,7 @@ class ResourceLoaderStartUpModule extends ResourceLoaderModule {
 
                // Perform string replacements for startup.js
                $pairs = [
-                       '$VARS.configuration' => ResourceLoader::encodeJsonForScript(
+                       '$VARS.configuration' => $context->encodeJson(
                                $this->getConfigSettings( $context )
                        ),
                        // Raw JavaScript code (not JSON)
index 9610cce..75a2d7a 100644 (file)
@@ -42,7 +42,7 @@ class ResourceLoaderUserDefaultsModule extends ResourceLoaderModule {
         */
        public function getScript( ResourceLoaderContext $context ) {
                return 'mw.user.options.set('
-                       . ResourceLoader::encodeJsonForScript( User::getDefaultOptions() )
+                       . $context->encodeJson( User::getDefaultOptions() )
                        . ');';
        }
 }
index 866d98b..b89324c 100644 (file)
@@ -55,7 +55,7 @@ class ResourceLoaderUserOptionsModule extends ResourceLoaderModule {
                // Use FILTER_NOMIN annotation to prevent needless minification and caching (T84960).
                return ResourceLoader::FILTER_NOMIN
                        . 'mw.user.options.set('
-                       . ResourceLoader::encodeJsonForScript(
+                       . $context->encodeJson(
                                $context->getUserObj()->getOptions( User::GETOPTIONS_EXCLUDE_DEFAULTS )
                        )
                        . ');';
index 45edd6e..21944ee 100644 (file)
@@ -55,7 +55,7 @@ class ResourceLoaderUserTokensModule extends ResourceLoaderModule {
                // Use FILTER_NOMIN annotation to prevent needless minification and caching (T84960).
                return ResourceLoader::FILTER_NOMIN
                        . 'mw.user.tokens.set('
-                       . ResourceLoader::encodeJsonForScript( $this->contextUserTokens( $context ) )
+                       . $context->encodeJson( $this->contextUserTokens( $context ) )
                        . ');';
        }
 
index 37501d4..237cea4 100644 (file)
@@ -165,11 +165,11 @@ class ResourceLoaderWikiModule extends ResourceLoaderModule {
 
        /**
         * @param string $titleText
-        * @param ResourceLoaderContext|null $context (but passing null is deprecated)
+        * @param ResourceLoaderContext $context
         * @return null|string
         * @since 1.32 added the $context parameter
         */
-       protected function getContent( $titleText, ResourceLoaderContext $context = null ) {
+       protected function getContent( $titleText, ResourceLoaderContext $context ) {
                $title = Title::newFromText( $titleText );
                if ( !$title ) {
                        return null; // Bad title
@@ -194,20 +194,16 @@ class ResourceLoaderWikiModule extends ResourceLoaderModule {
 
        /**
         * @param Title $title
-        * @param ResourceLoaderContext|null $context (but passing null is deprecated)
+        * @param ResourceLoaderContext $context
         * @param int|null $maxRedirects Maximum number of redirects to follow. If
         *  null, uses $wgMaxRedirects
         * @return Content|null
         * @since 1.32 added the $context and $maxRedirects parameters
         */
        protected function getContentObj(
-               Title $title, ResourceLoaderContext $context = null, $maxRedirects = null
+               Title $title, ResourceLoaderContext $context, $maxRedirects = null
        ) {
-               if ( $context === null ) {
-                       wfDeprecated( __METHOD__ . ' without a ResourceLoader context', '1.32' );
-               }
-
-               $overrideCallback = $context ? $context->getContentOverrideCallback() : null;
+               $overrideCallback = $context->getContentOverrideCallback();
                $content = $overrideCallback ? call_user_func( $overrideCallback, $title ) : null;
                if ( $content ) {
                        if ( !$content instanceof Content ) {
index b7eb3c0..6ed5e12 100644 (file)
@@ -118,6 +118,30 @@ abstract class QueryPage extends SpecialPage {
                return $qp;
        }
 
+       /**
+        * Get a list of query pages disabled and with it's run mode
+        * @param Config $config
+        * @return string[]
+        */
+       public static function getDisabledQueryPages( Config $config ) {
+               $disableQueryPageUpdate = $config->get( 'DisableQueryPageUpdate' );
+
+               if ( !is_array( $disableQueryPageUpdate ) ) {
+                       return [];
+               }
+
+               $pages = [];
+               foreach ( $disableQueryPageUpdate as $name => $runMode ) {
+                       if ( is_int( $name ) ) {
+                               // The run mode may be omitted
+                               $pages[$runMode] = 'disabled';
+                       } else {
+                               $pages[$name] = $runMode;
+                       }
+               }
+               return $pages;
+       }
+
        /**
         * A mutator for $this->listoutput;
         *
@@ -632,13 +656,21 @@ abstract class QueryPage extends SpecialPage {
 
                                # If updates on this page have been disabled, let the user know
                                # that the data set won't be refreshed for now
-                               if ( is_array( $this->getConfig()->get( 'DisableQueryPageUpdate' ) )
-                                       && in_array( $this->getName(), $this->getConfig()->get( 'DisableQueryPageUpdate' ) )
-                               ) {
-                                       $out->wrapWikiMsg(
-                                               "<div class=\"mw-querypage-no-updates\">\n$1\n</div>",
-                                               'querypage-no-updates'
-                                       );
+                               $disabledQueryPages = self::getDisabledQueryPages( $this->getConfig() );
+                               if ( isset( $disabledQueryPages[$this->getName()] ) ) {
+                                       $runMode = $disabledQueryPages[$this->getName()];
+                                       if ( $runMode === 'disabled' ) {
+                                               $out->wrapWikiMsg(
+                                                       "<div class=\"mw-querypage-no-updates\">\n$1\n</div>",
+                                                       'querypage-no-updates'
+                                               );
+                                       } else {
+                                               // Messages used here: querypage-updates-periodical
+                                               $out->wrapWikiMsg(
+                                                       "<div class=\"mw-querypage-updates-" . $runMode . "\">\n$1\n</div>",
+                                                       'querypage-updates-' . $runMode
+                                               );
+                                       }
                                }
                        }
                }
index fa78cbe..6ad02f0 100644 (file)
@@ -988,7 +988,27 @@ class SpecialVersion extends SpecialPage {
                $linkRenderer = $this->getLinkRenderer();
 
                $list = [];
-               foreach ( (array)$authors as $item ) {
+               $authors = (array)$authors;
+
+               // Special case: if the authors array has only one item and it is "...",
+               // it should not be rendered as the "version-poweredby-others" i18n msg,
+               // but rather as "version-poweredby-various" i18n msg instead.
+               if ( count( $authors ) === 1 && $authors[0] === '...' ) {
+                       // Link to the extension's or skin's AUTHORS or CREDITS file, if there is
+                       // such a file; otherwise just return the i18n msg as-is
+                       if ( $extName && $this->getExtAuthorsFileName( $extDir ) ) {
+                               return $linkRenderer->makeLink(
+                                       $this->getPageTitle( "Credits/$extName" ),
+                                       $this->msg( 'version-poweredby-various' )->text()
+                               );
+                       } else {
+                               return $this->msg( 'version-poweredby-various' )->escaped();
+                       }
+               }
+
+               // Otherwise, if we have an actual array that has more than one item,
+               // process each array item as usual
+               foreach ( $authors as $item ) {
                        if ( $item == '...' ) {
                                $hasOthers = true;
 
index ce93ce2..d2ed7e5 100644 (file)
        "perfcached": "البيانات التالية مخبأة و قد لا تكون محدثة. {{PLURAL:$1||نتيجة واحدة|نتيجتان|$1 نتائج|$1 نتيجة}} على الأكثر {{PLURAL:$1||مخبّأة|مخبّأتان|مخبّأة}}.",
        "perfcachedts": "البيانات التالية مخزنة، وكان آخر تحديث لها في $1. العدد الأقصى للنتائج المخزنة هو {{PLURAL:$4||نتيجة واحدة|نتيجتان|$4 نتائج|$4 نتيجة}}.",
        "querypage-no-updates": "تحديثات هذه الصفحة معطلة حاليا.\nالبيانات هنا لن يتم تحديثها حاليا.",
+       "querypage-updates-periodical": "يتم تشغيل تحديثات هذه الصفحة بشكل دوري.",
        "viewsource": "عرض المصدر",
        "viewsource-title": "عرض مصدر $1",
        "actionthrottled": "تم كبح الفعل",
index 25e2ae9..1d4d8b1 100644 (file)
@@ -54,6 +54,7 @@
        "tog-useeditwarning": "जब हम कवनो सम्पादन पन्ना कय बिना सहेजे बदलाव कय साथे छोड दि तव हम्मै बतावो।",
        "tog-prefershttps": "सत्र आरम्भ करते समय सदैव सुरक्षित कनेक्शन का प्रयोग करें",
        "tog-showrollbackconfirmation": "रोलबैक लिंक पर क्लिक करते समय एक पुष्टिकरण संकेत दिखाएं",
+       "tog-requireemail": "पासवर्ड रीसेट के बरे ईमेल कय जरूरति होति है",
        "underline-always": "हमेशा",
        "underline-never": "कब्बो नाई",
        "underline-default": "देखावट या ब्राउज़र डिफ़ॉल्ट",
        "perfcached": "नीचे दिया हुआ डेटा कैशे मेमोरी से लिया हुआ है, अतः हो सकता है कि इसका पूर्ण अद्यतन न हुआ हो। कैशे मेमोरी में अधिकतम {{PLURAL:$1|एक  नतीजा|$1 नतीजे}} उपलब्ध हैं।",
        "perfcachedts": "नीचे दिया हुआ डेटा कैशे मेमोरी से है, और इसका अंतिम अद्यतन $1 को हुआ था। कैशे मेमोरी में अधिकतम {{PLURAL:$4|एक  नतीजा|$4 नतीजे}} उपलब्ध हैं।",
        "querypage-no-updates": "इस पृष्ठ का नवीनीकरण करना मना है। अभी यहाँ के डाटा को ताज़ा नहीं कर सकते।",
+       "querypage-updates-periodical": "एह पन्ना के बरे अपडेट समय-समय पय चलावा जात है।",
        "viewsource": "स्रोत देखा जाय",
        "viewsource-title": "$1 कय लिए स्रोत देखा जाय",
        "actionthrottled": "काम खतम कई दिहा है",
        "createaccountmail": "एकठु अस्थायी मनलागा (रैंडम) गुप्त कुंजी चुना जाय अउर ओका निर्दिष्ट ई-मेल ठहर पे भेजा जाय",
        "createaccountmail-help": "इसका उपयोग बिना पासवर्ड जाने किसी और के लिए खाता खोलने के लिए उपयोग किया जाता है।",
        "createacct-realname": "असली नावँ (वैकल्पिक)",
-       "createacct-reason": "कारण",
+       "createacct-reason": "कारण (सार्वजनिक रूप से लॉग इन)",
        "createacct-reason-ph": "आप दुसर खाता काहे बनावा जात है",
        "createacct-reason-help": "खाता निर्माण लॉग में यह सन्देश दिखाई देगा।",
        "createacct-submit": "आपन खाता बनावा जाय",
        "content-model-javascript": "जावास्क्रिप्ट",
        "content-json-empty-object": "खाली चिज",
        "content-json-empty-array": "खाली एरे",
+       "unsupported-content-model": "<strong>चेतावनी:</strong> सामग्री मॉडल $1 एह विकी पय समर्थित नहीं अहै।",
+       "unsupported-content-diff": "सामग्री मॉडल $1 के बरे Diffs कय समर्थन नही करत।",
+       "unsupported-content-diff2": "एह विकी पय सामग्री मॉडल $1 अउर $2 के बीच कय Diffs समर्थित नही अहै।",
        "deprecated-self-close-category": "अमान्य खुदै-बंद HTML टैग कय उपयोग करय वाले पृष्ठ",
        "deprecated-self-close-category-desc": "इस पृष्ठ में स्वयं-बंद ऍचटीएमएल चिप्पियाँ समाहित हैं जैसे <code>&lt;b/></code> अथवा <code>&lt;span/></code> आदि। इनका व्यवहार जल्दी ही ऍचटीएमएल५ विनिर्देशों के अनुरूप परिवर्तित हो जायेगा अतः विकि-पाठ में इनके प्रयोग को न करने की सलाह दी जाती है।",
        "duplicate-args-warning": "<strong>चेतावनी:</strong> [[:$1]] प्राचल \"$3\" के लिए [[:$2]] को एक से अधिक बार काम में ले रहा है। केवल अन्त में दिया गया मान ही काम में लिया जायेगा।",
        "undo-norev": "ई बदलाव वापिस नाई भय काहे से या तो एका पहीलवे से पलटाई गा है या फिर पन्ना हटाई दिहा है।",
        "undo-nochange": "अईसन लागत है की ई सम्पादन कय पहिलवे पहिले जैसन कई दीहा है ।",
        "undo-summary": "[[Special:Contributions/$2|$2]] ([[User talk:$2|बातचीत]]) कय करल बदलाव $1 कय पहिले जईसन कई गय",
+       "undo-summary-anon": "[[Special:Contributions/$2|$2]] द्वारा $1 का पहिले जइसे करैं।",
        "undo-summary-username-hidden": "लुकुआवल सदस्यन् कय करल बदलाव $1 कय पहिले जईसन कई गय",
        "cantcreateaccount-text": "इ आइ॰पी ठहर ('''$1''') कय खाता बनावे कय [[User:$3|$3]] रोक लगाए हैँ।\n\nएकरे लिये $3 ''$2'' कारण दिहे हैं।",
        "cantcreateaccount-range-text": "<strong>$1</strong> कय श्रेणी में आवे वाला आई॰पी ठहर से, जवनेमें आप कय आई॰पी ठहर (<strong>$4</strong>) शामिल है, नँवा खाता बनावे कय लिए [[User:$3|$3]] अवरोधित कई गा है। \n\n$3 द्वारा दिया गया कारण है: \"$2\"",
        "prefs-help-email": "ई-मेल ठहर वैकल्पिक होय, लेकिन यदि आप आपन गुप्तकुंजी भूलाई गवा गय तव एकरे माध्यम से रीसेट कई सका जात है।",
        "prefs-help-email-others": "आप आपन पहिचान बिना देखाए, अउर सदस्यन् कय अपने सदस्य या बातचीत पन्ना से ,अपने आप से सम्पर्क कराय सका जात है।",
        "prefs-help-email-required": "ई-मेल ठहर जरुरी है।",
+       "prefs-help-requireemail": "अगर जांच करी गय, तौ केवल पासवर्ड रीसेट ईमेल भेजे अगर रीसेट करय वाला मनई एह खाता के बरे उपयोगकर्ता नाँव अउर ईमेल द्विनव व्यवस्था कीनि गयि अहै।",
        "prefs-info": "मूलभूत जानकारी",
        "prefs-i18n": "अंतर्राष्ट्रीयकरण",
        "prefs-signature": "हस्ताक्षर",
        "backend-fail-contenttype": "\"$1\" मा सहेजै खत्तिर फाइल कय प्रकार नाइ निश्चित कै मिला ।",
        "backend-fail-batchsize": "भंडारण बैकेंड कय $1 फ़ाइल {{PLURAL:$1|काम}} दिहा गा रहा; सीमा {{PLURAL:$2|$2 काम}} कय है।",
        "backend-fail-usable": "फ़ाइल \"$1\" कय पर्याप्त अनुमति या अनुपस्थित डायरेक्ट्रीज़/कंटेनरन् कय कारण पढ़ा या लिखा नाइ जाय सकत है।",
+       "backend-fail-stat": "फ़ाइल \"$1\" कय स्थिति नही पढ़ सकिस।",
+       "backend-fail-hash": "फ़ाइल \"$1\" कय क्रिप्टोग्राफ़िक हैश कय निर्धारण नही कइ सकिस।",
        "filejournal-fail-dbconnect": "भंडारण बैकेंड \"$1\" कय जर्नल डाटाबेस से सम्पर्क नाइ होइ पाय।",
        "filejournal-fail-dbquery": "भंडारण बैकेंड \"$1\" कय जर्नल डाटाबेस कय अद्यतन नाइ कै मिला ।",
        "lockmanager-notlocked": "\"$1\" कय अनलॉक नाइ कै मिला,इ बन्द नाइ है।",
        "listfiles-userdoesnotexist": "सदस्य \"$1\" पंजीकृत नाइ है।",
        "imgfile": "फ़ाइल",
        "listfiles": "फ़ाइल सूची",
+       "listfiles_subpage": "$1 द्वारा अपलोड कीन गा",
        "listfiles_thumb": "अंगूठाकार",
        "listfiles_date": "मिती",
        "listfiles_name": "नाँव",
        "alreadyrolled": "[[User:$2|$2]] ([[User talk:$2|बातचीत]]{{int:pipe-separator}}[[Special:Contributions/$2|{{int:contribslink}}]]) द्वारा किए गए  [[:$1]] के पिछले संपादन को वापिस पुरानी स्थिति पर नहीं लाया जा सकता है;\nकिसी और ने इस बीच या तो इस पृष्ठ को फिर से संपादित कर दिया है या पहले ही पृष्ठ पुरानी स्थिति पर लाया जा चुका है।\n\nइस पृष्ठ का अन्तिम संपादन [[User:$3|$3]] ([[User talk:$3|बातचीत]]{{int:pipe-separator}}[[Special:Contributions/$3|{{int:contribslink}}]]) ने किया है।",
        "editcomment": "संपादन सारांश रहा: <em>$1</em>।",
        "revertpage": "[[Special:Contributions/$2|$2]] ([[User talk:$2|बातचीत]])से [[User:$1|$1]] कय करल पिछला संशोधन उल्टाई कय पहिले जैसन कै गय",
+       "revertpage-anon": "[[Special:Contributions/$2|$2]] पहिले जइसा द्वारा पहिले जइसे करय वाला संपादन से  [[User:$1|$1]] द्वारा अंतिम संशोधन",
        "revertpage-nouser": "(सदस्य नाँव हटाइ गा है) कय संपादन कय हटाइकए {{GENDER:$1|[[User:$1|$1]]}} कय अन्तिम अवतरण कय पहिले जैसन कै गय।",
        "rollback-success": "{{GENDER:$3|$1}} के संपादन हटाए;\n{{GENDER:$4|$2}} द्वारा संपादित अन्तिम अवतरण को पुनर्स्थापित किया।",
        "sessionfailure-title": "सत्र विफलता",
        "changecontentmodel-legend": "पृष्ठ सामग्री का नमूना",
        "changecontentmodel-title-label": "पृष्ठ शीर्षक:",
        "changecontentmodel-current-label": "Current content model:",
-       "changecontentmodel-model-label": "नयि सामग्री कय नमूना:",
+       "changecontentmodel-model-label": "नयà¥\80 सामग्री कय नमूना:",
        "changecontentmodel-reason-label": "कारण:",
        "changecontentmodel-submit": "बदला",
        "changecontentmodel-success-title": "सामगरि का नामुने मे बदलाव हुुुाा हेेे",
        "ipblocklist-legend": "अवरोधित सदस्य कय खोजा जाय",
        "blocklist-userblocks": "खाता कय अवरोध लुकुआवा जाए",
        "blocklist-tempblocks": "अस्थाई अवरोध लुकुआवा जाए",
+       "blocklist-indefblocks": "अनिश्चित ब्लॉक लुकुवावा",
        "blocklist-addressblocks": "एक्ठु आईपी अवरोध लुकुआवा जाए",
        "blocklist-type": "प्रकार:",
        "blocklist-type-opt-all": "सगरौ",
        "mycustomjsredirectprotected": "You do not have permission to edit this JavaScript page because it is a redirect and it does not point inside your userspace.",
        "easydeflate-invaliddeflate": "Content provided is not properly deflated",
        "unprotected-js": "सुरक्षा कारणों से जावास्क्रिप्ट असुरक्षित पन्नों से लोड नहीं किया जा सका। कृपया जावास्क्रिप्ट केवल मीडियाविकि में बनाये:नामस्थान या सदस्य उपपृष्ठ",
-       "userlogout-continue": "का आप लॉग आउट करा चाहत अहैं?"
+       "userlogout-continue": "का आप लॉग आउट करा चाहत अहैं?",
+       "rest-prefix-mismatch": "अनुरोधित पथ ($1) REST API रूट पथ ($2) के अंदर नही रहा।",
+       "rest-wrong-method": "अनुरोध विधि ($1) {{PLURAL:$3| एह पथ के बरे अनुमत विधि नही अहै। एह पथ के बरे अनुमत तरीकऽन् मा से एक}} ($2)",
+       "rest-no-match": "अनुरोधित सापेक्ष पथ ($1) कउनो भी ज्ञात हैंडलर से मेल नही खात"
 }
index fac7ebd..d3fd00c 100644 (file)
        "rcfilters-clear-all-filters": "Ryd alle filtre",
        "rcfilters-show-new-changes": "Vis seneste ændringer siden $1",
        "rcfilters-search-placeholder": "Filtrer ændringer (brug menuen eller søg på filternavn)",
+       "rcfilters-search-placeholder-mobile": "Filtre",
        "rcfilters-invalid-filter": "Ugyldigt filter",
        "rcfilters-empty-filter": "Ingen aktive filtre. All bidrag vises.",
        "rcfilters-filterlist-title": "Filtre",
        "rcfilters-filter-showlinkedto-option-label": "<strong>Sider som linker til</strong> den valgte side",
        "rcfilters-target-page-placeholder": "Indtast et sidenavn (eller en kategori)",
        "rcfilters-allcontents-label": "Alt indhold",
+       "rcfilters-alldiscussions-label": "Alle diskussioner",
        "rcnotefrom": "Nedenfor er op til '''$1''' {{PLURAL:$5|ændring|ændringer}} siden '''$2''' vist.",
        "rclistfromreset": "Nulstil datovalg",
        "rclistfrom": "Vis nye ændringer startende fra den $3 kl. $2",
index 5c60cff..4ae22c8 100644 (file)
        "perfcached": "Die folgenden Daten stammen aus dem Cache und sind möglicherweise nicht aktuell. Maximal {{PLURAL:$1|ein Ergebnis ist|$1 Ergebnisse sind}} im Cache verfügbar.",
        "perfcachedts": "Diese Daten stammen aus dem Cache. Der Zeitpunkt der letzten Aktualisierung: $2, $3 Uhr. Maximal {{PLURAL:$4|ein Ergebnis ist|$4 Ergebnisse sind}} im Cache verfügbar.",
        "querypage-no-updates": "Die Aktualisierungsfunktion dieser Seite ist zurzeit deaktiviert.\nDie Daten werden bis auf Weiteres nicht erneuert.",
+       "querypage-updates-periodical": "Aktualisierungen für diese Seite werden periodisch erneuert.",
        "viewsource": "Quelltext anzeigen",
        "viewsource-title": "Quelltext der Seite $1",
        "actionthrottled": "Aktionsanzahl limitiert",
        "easydeflate-invaliddeflate": "Der angegebene Inhalt ist nicht ordnungsgemäß komprimiert",
        "unprotected-js": "Aus Sicherheitsgründen kann JavaScript-Code nicht mehr von ungeschützten Seiten geladen werden. Erstelle die JavaScript-Seite bitte ausschließlich im Namensraum „MediaWiki“ oder als Benutzerunterseite.",
        "userlogout-continue": "Möchtest du dich abmelden?",
-       "rest-prefix-mismatch": "Der angeforderte Pfad ($1) kannte nicht innerhalb des REST-API-Root-Pfades ($2) gefunden werden"
+       "rest-prefix-mismatch": "Der angeforderte Pfad ($1) kannte nicht innerhalb des REST-API-Root-Pfades ($2) gefunden werden",
+       "rest-wrong-method": "Die angeforderte Methode ($1) war keine {{PLURAL:$3|erlaubte Methode für diesen Pfad|der erlaubten Methoden für diesen Pfas}} ($2)"
 }
index 67cdbad..ecddb15 100644 (file)
        "sp-contributions-userrights": "idareyê heqanê {{GENDER:$1|karberan}}",
        "sp-contributions-blocked-notice": "Eno karber/ena karbere emanet blokekerdeyo/blokekerdiya.\nCıkewtışo tewr peyêno ke bloke biyo, cêr seba referansi belikerdeyo:",
        "sp-contributions-blocked-notice-anon": "Eno adresê IPi bloke biyo.\nCıkewtışo tewr peyêno ke bloke biyo, cêr seba referansi belikerdeyo:",
-       "sp-contributions-search": "Dekerdena cı geyrê",
+       "sp-contributions-search": "İştırakan cı geyrê",
        "sp-contributions-username": "Adresa IPy ya zi nameyê karberi:",
        "sp-contributions-toponly": "Tenya tewr çım ra viyarnayışanê peyniyan bımocne",
        "sp-contributions-newonly": "Tenya vurnayışanê pelevıraştışi bımocne",
index 266fdb4..5ae517d 100644 (file)
        "createaccountmail": "Χρήση τυχαίου προσωρινού κωδικού πρόσβασης και αποστολή του στην καθοριζόμενη διεύθυνση ηλεκτρονικού ταχυδρομείου",
        "createaccountmail-help": "Μπορεί να χρησιμοποιηθεί για την δημιουργία λογαριασμού τρίτων χωρίς την γνωστοποίηση των κωδικών πρόσβασής τους.",
        "createacct-realname": "Πραγματικό όνομα (προαιρετικό)",
-       "createacct-reason": "Î\9bÏ\8cγοÏ\82",
+       "createacct-reason": "Î\91ιÏ\84ία (δημÏ\8cÏ\83ια ÎºÎ±Ï\84αγÏ\81αÏ\86ή)",
        "createacct-reason-ph": "Γιατί δημιουργείτε έναν άλλο λογαριασμό",
        "createacct-reason-help": "Εμφανιζόμενο μήνυμα στο μητρώο δημιουργίας λογαριασμών",
        "createacct-submit": "Δημιουργία λογαριασμού χρήστη",
        "sessionfailure": "Φαίνεται ότι υπάρχει κάποιο πρόβλημα με την περίοδο σύνδεσής σας.\nΑυτή η ενέργεια ακυρώθηκε ως προφύλαξη για την αντιμετώπιση τυχόν σφετερισμού της περιόδου σύνδεσης από κάποιον τρίτο (session hijacking).\nΠαρακαλούμε υποβάλετε ξανά τη φόρμα.",
        "changecontentmodel": "Αλλαγή μοντέλου περιεχομένου της σελίδας",
        "changecontentmodel-legend": "Μοντέλο περιεχομένου σελίδας",
-       "changecontentmodel-title-label": "Τίτλος σελίδας",
-       "changecontentmodel-model-label": "Νέο μοντέλο περιεχομένου",
+       "changecontentmodel-title-label": "Τίτλος σελίδας:",
+       "changecontentmodel-model-label": "Νέο μοντέλο περιεχομένου:",
        "changecontentmodel-reason-label": "Αιτία:",
        "changecontentmodel-submit": "Αλλαγή",
        "changecontentmodel-success-title": "Το περιεχόμενο πρότυπο άλλαξε",
        "blocklist-editing-page": "σελίδες",
        "blocklist-editing-ns": "ονοματοχώροι",
        "ipblocklist-empty": "Η λίστα φραγών είναι άδεια.",
-       "ipblocklist-no-results": "Î\97 Î¶Î·Ï\84οÏ\8dμενη Î´Î¹ÎµÏ\8dθÏ\85νÏ\83η IP Î® Ï\84ο Ï\8cνομα Ï\87Ï\81ήÏ\83Ï\84η Î´ÎµÎ½ ÎµÎ¯Î½Î±Î¹ Ï\86Ï\81αγμένα.",
+       "ipblocklist-no-results": "Î\94εν Î²Ï\81έθηκαν Ï\86Ï\81αγέÏ\82 Ï\80οÏ\85 Î½Î± Ï\84αιÏ\81ιάζοÏ\85ν Î³Î¹Î± Ï\84η Î¶Î·Ï\84οÏ\8dμενη Î´Î¹ÎµÏ\8dθÏ\85νÏ\83η IP Î® Ï\8cνομα Ï\87Ï\81ήÏ\83Ï\84η.",
        "blocklink": "φραγή",
        "unblocklink": "άρση φραγής",
        "change-blocklink": "αλλαγή φραγής",
index 7944a37..54f5567 100644 (file)
        "perfcached": "The following data is cached and may not be up to date. A maximum of {{PLURAL:$1|one result is|$1 results are}} available in the cache.",
        "perfcachedts": "The following data is cached, and was last updated $1. A maximum of {{PLURAL:$4|one result is|$4 results are}} available in the cache.",
        "querypage-no-updates": "Updates for this page are currently disabled.\nData here will not presently be refreshed.",
+       "querypage-updates-periodical": "Updates for this page are run periodically.",
        "viewsource": "View source",
        "viewsource-title": "View source for $1",
        "actionthrottled": "Action throttled",
        "version-poweredby-credits": "This wiki is powered by <strong>[https://www.mediawiki.org/ MediaWiki]</strong>, copyright © 2001-$1 $2.",
        "version-poweredby-others": "others",
        "version-poweredby-translators": "translatewiki.net translators",
+       "version-poweredby-various": "Various authors",
        "version-credits-summary": "We would like to recognize the following persons for their contribution to [[Special:Version|MediaWiki]].",
        "version-license-info": "MediaWiki 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.\n\nMediaWiki is distributed in the hope that it will be useful, but <em>WITHOUT ANY WARRANTY</em>; without even the implied warranty of <strong>MERCHANTABILITY</strong> or <strong>FITNESS FOR A PARTICULAR PURPOSE</strong>. See the GNU General Public License for more details.\n\nYou should have received [{{SERVER}}{{SCRIPTPATH}}/COPYING 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 or [//www.gnu.org/licenses/old-licenses/gpl-2.0.html read it online].",
        "version-software": "Installed software",
index 35223c3..65669ec 100644 (file)
        "createaccountmail": "Uzi provizoran hazardan pasvorton kaj sendi ĝin al la retpoŝta adreso ĉi-suba",
        "createaccountmail-help": "Uzebla por krei konton de alia persono sen ekscii la pasvorton.",
        "createacct-realname": "Vera nomo (nedeviga)",
-       "createacct-reason": "Kialo",
+       "createacct-reason": "Kialo (publike protokolata)",
        "createacct-reason-ph": "Kial vi kreas plian konton",
        "createacct-reason-help": "Mesaĝo montrita en la protokolo pri kreado de konto",
        "createacct-submit": "Krei vian konton",
        "sessionfailure": "Ŝajnas, ke estas problemo kun via ensalutado;\nĈi ago estis nuligita por malhelpi fiensalutadon.\nBonvolu resendi la formularoj",
        "changecontentmodel": "Ŝanĝi la enhavomodelon de paĝo",
        "changecontentmodel-legend": "Ŝanĝi la enhavomodelon",
-       "changecontentmodel-title-label": "Titolo de paĝo",
+       "changecontentmodel-title-label": "Titolo de paĝo:",
        "changecontentmodel-current-label": "Aktuala enhavmodelo:",
-       "changecontentmodel-model-label": "Nova enhavomodelo",
+       "changecontentmodel-model-label": "Nova enhavomodelo:",
        "changecontentmodel-reason-label": "Kialo:",
        "changecontentmodel-submit": "Ŝanĝi",
        "changecontentmodel-success-title": "Enhavomodelo estis ŝanĝigita",
index bdf7e75..a8bbaf1 100644 (file)
                        "Waldyrious",
                        "Johny Weissmuller Jr",
                        "Dark Dragoon",
-                       "Elisardojm"
+                       "Elisardojm",
+                       "Madamebiblio"
                ]
        },
        "tog-underline": "Subrayar enlaces:",
        "listfiles-userdoesnotexist": "La cuenta de usuario «$1» no está registrada.",
        "imgfile": "archivo",
        "listfiles": "Lista de archivos",
+       "listfiles_subpage": "Subidas por $1",
        "listfiles_thumb": "Miniatura",
        "listfiles_date": "Fecha",
        "listfiles_name": "Nombre",
index 136aafb..7528ef5 100644 (file)
@@ -9,7 +9,8 @@
                        "Purodha",
                        "Red Baron",
                        "Umherirrender",
-                       "W (aka Wuzur)"
+                       "W (aka Wuzur)",
+                       "Tobi 406"
                ]
        },
        "exif-imagewidth": "Breite",
        "exif-scenetype-1": "Normal",
        "exif-customrendered-0": "Standard",
        "exif-customrendered-1": "Benutzerdefiniert",
+       "exif-customrendered-6": "Panorama",
+       "exif-customrendered-8": "Poträt",
        "exif-exposuremode-0": "Automatische Belichtung",
        "exif-exposuremode-1": "Manuelle Belichtung",
        "exif-exposuremode-2": "Belichtungsreihe",
index 57fac84..005426a 100644 (file)
        "exif-originaldocumentid": "Unik ID van et originele dokument",
        "exif-licenseurl": "Webadres vöär autöörsrechtenlicensy",
        "exif-morepermissionsurl": "Alternative licensygegeavens",
-       "exif-attributionurl": "Bruuk de volgende verwysing as dit wark herbruked wördt",
-       "exif-preferredattributionname": "Bruuk de volgende makersvermelding as dit wark herbruked wördt",
+       "exif-attributionurl": "Gebruuk de volgende verwysing as dit wark hergebruked wördt",
+       "exif-preferredattributionname": "Gebruuk de volgende makersvermelding as dit wark hergebruked wördt",
        "exif-pngfilecomment": "Upmarking by PNG-bestand",
        "exif-disclaimer": "Vöärbehold",
        "exif-contentwarning": "Inholdswårsküwing",
index 66db5bd..e5baac8 100644 (file)
        "createaccountmail": "استفاده از رمز عبور موقت تصادفی و ارسال آن به آدرس ایمیل مشخص شده",
        "createaccountmail-help": "جهت ايجاد حساب برای شخص ديگری بدون دانستن گذرواژهٔ آن کاربرد دارد.",
        "createacct-realname": "نام واقعی (اختیاری)",
-       "createacct-reason": "دلیل",
+       "createacct-reason": "دلیل (به صورت عمومی ثبت می‌شود)",
        "createacct-reason-ph": "چرا شما حساب دیگری می‌سازید؟",
        "createacct-reason-help": "پیامی که در سياههٔ ایجاد حساب نمایش داده می‌شود",
        "createacct-submit": "حسابتان را بسازید",
        "sessionfailure": "به نظر می‌رسد مشکلی در مورد نشست کاربری شما وجود دارد؛\nعمل درخواست شده در اقدامی پیشگیرانه در برابر ربوده‌شدن اطلاعات نشست کاربری، لغو شد.\nلطفاً فرم را از نو بارگذاری کنید.",
        "changecontentmodel": "ویرایش مدل محتوای یک صفحه",
        "changecontentmodel-legend": "تغییر نوع محتوی",
-       "changecontentmodel-title-label": "عنوان صفحه",
-       "changecontentmodel-model-label": "مدل محتوای جدید",
+       "changecontentmodel-title-label": "عنوان صفحه:",
+       "changecontentmodel-model-label": "مدل محتوای جدید:",
        "changecontentmodel-reason-label": "دلیل:",
        "changecontentmodel-submit": "تغییر",
        "changecontentmodel-success-title": "نمونه محتوی تغییر یافت",
        "edit-error-short": "خطا: $1",
        "edit-error-long": "خطاها:\n\n$1",
        "specialmute": "بی‌صدا",
-       "specialmute-success": "تنظیمات بی‌صدا به روز شد. دیدن فهرست همهٔ کاربرانی که در [[Special:Preferences|ترجیحاتتان]] به عنوان بی‌صدا انتخاب کردید.",
+       "specialmute-success": "تنظیمات بی‌صدا به روز شد. دیدن فهرست همهٔ کاربرانی که در [[Special:Preferences|ترجیحاتتان]] به عنوان بی‌صدا انتخاب کردید.",
        "specialmute-submit": "تأیید",
        "specialmute-label-mute-email": "بی‌صدا کردن ایمیل از این کاربر",
-       "specialmute-header": "لطفاً ترجیحات بی‌صدا برای <b>{{BIDI:[[User:$1]]}}</b> را انتخاب کنید.",
+       "specialmute-header": "لطفاً ترجیحات بی‌صدا برای <b>{{BIDI:[[User:$1|$1]]}}</b> را انتخاب کنید.",
        "specialmute-error-invalid-user": "نام کاربری درخواست شده یافت نشد.",
-       "specialmute-email-footer": "[$1 مدیریت ترجیحات ایمیل برای {{BIDI:$2}}.]",
+       "specialmute-email-footer": "برای مدیریت ترجیحات ایمیل برای {{BIDI:$2}} به <$1> مراجعه کنید.",
        "specialmute-login-required": "لطفاً برای تغییر ترجیحات بی‌صدا به سامانه وارد شوید.",
        "revid": "نسخهٔ $1",
        "pageid": "شناسهٔ صفحهٔ $1",
index 20d2991..3f1ae4b 100644 (file)
        "listfiles-userdoesnotexist": "Käyttäjätunnusta ”$1” ei ole rekisteröity.",
        "imgfile": "tiedosto",
        "listfiles": "Tiedostoluettelo",
+       "listfiles_subpage": "Käyttäjän $1 tallennukset",
        "listfiles_thumb": "Pienoiskuva",
        "listfiles_date": "Päiväys",
        "listfiles_name": "Nimi",
index 57f8978..982b7d7 100644 (file)
@@ -25,7 +25,7 @@
        "tog-previewonfirst": "Näytä esitarkastelu kun mookkaus alethaan",
        "tog-enotifwatchlistpages": "Lähätä e-postipreivi mulle kun sivu tai fiili minun valvontalistala on muutettu",
        "tog-enotifusertalkpages": "Lähätä E-posti, kun käyttäjäsivun keskustelusivu muuttuu",
-       "tog-enotifminoredits": "Lähätä epostieto pienistäki muutoksista",
+       "tog-enotifminoredits": "Lähätä epostieto pienistäki muutoksista sivuissa ja fiileissä",
        "tog-enotifrevealaddr": "Näytä minun e-posti atressin muile lähetetyissä ilmoituksissa",
        "tog-shownumberswatching": "Näytä kuinka moni käyttäjä valvoo sivua",
        "tog-oldsig": "Sinun nykynen allekirjotus:",
@@ -99,6 +99,7 @@
        "mytalk": "Keskustelu",
        "anontalk": "Keskustelu",
        "navigation": "Navikeerinki",
+       "and": "&#32;ja",
        "faq": "Useasti kysytyt kysymykset",
        "actions": "Toiminat",
        "namespaces": "Nimityhjyyet",
        "help": "Apua",
        "search": "Haku",
        "searchbutton": "Hae",
+       "go": "Mene",
        "searcharticle": "Mene",
        "history": "Sivun histuuria",
        "history_short": "Histuuria",
        "protect_change": "muuta",
        "newpage": "Uusi sivu",
        "talkpagelinktext": "Keskustelu",
-       "specialpage": "Spesiaali sivu",
+       "specialpage": "Spesiaalisivu",
        "personaltools": "Henkilökohtaiset työneuvot",
        "talk": "Keskustelu",
        "views": "Näyttöjä",
        "portal-url": "Project: Kaikitten purthaali",
        "privacy": "Tietosuojakäytäntö",
        "privacypage": "Project: Intekriteettisääntö",
+       "ok": "OK",
        "retrievedfrom": "Nouettu osoitheesta $1",
        "youhavenewmessages": "{{PLURAL:$3|Sulla on}} $1 ($2).",
        "editsection": "mookkaa",
        "viewsourcelink": "näytä lähekooti",
        "editsectionhint": "Mookkaa seksuunia $1",
        "toc": "Sisältö",
+       "confirmable-yes": "Kyllä",
+       "confirmable-no": "Ei",
        "site-atom-feed": "$1-Atom-syöttö",
        "page-atom-feed": "$1 (Atom-syöttö)",
        "red-link-title": "$1 (sivua ei ole)",
        "nstab-main": "Sivu",
        "nstab-user": "Käyttäjäsivu",
-       "nstab-special": "Spesiaali sivut",
+       "nstab-special": "Spesiaalisivut",
        "nstab-project": "Prujektisivu",
        "nstab-image": "Fiili",
        "nstab-template": "Malli",
        "nstab-category": "Katekuuri",
        "mainpage-nstab": "Alkusivu",
+       "error": "Virhe",
        "missing-article": "Sivun sisältöä ei löytyny taattapaasista: $1 $2.\n\nUseimiten tämä johtuu vanhentuneesta vertailu- tai histuuriasivulinkistä poistethuun sivhuun.\n\nJos kysheessä ei ole poistettu sivu, olet piian löytäny virheen ohjelmassa.\nIlmota tämän sivun atressi wikin [[Special:ListUsers/sysop|atministratöörile]].",
        "missingarticle-rev": "(versuuni: $1)",
        "badtitle": "Virheelinen titteli",
        "createacct-emailrequired": "E-postin atressi",
        "createacct-another-submit": "Luo konttu",
        "createacct-benefit-body1": "{{PLURAL:$1|mookkaus|mookhausta}}",
+       "loginsuccesstitle": "Lokattu sisäle",
        "mailmypassword": "Uusi salasana",
        "loginlanguagelabel": "Kieli: $1",
        "pt-login": "Lokkaa sisäle",
        "anoneditwarning": "'''Varotus:''' Et ole lokanu sisäle.\nIP-atressi säästethään tämän sivun muutoshistuuriassa.",
        "loginreqlink": "lokkaa sisäle",
        "newarticle": "(Uusi)",
-       "newarticletext": "Linkki vei sinun sivule, joka ei vielä ole.\nSaatat luoa sivun kirjottamalla alla olehvaan kenthään (katto [$1 apusivu] lisää tietoja).\nJos et halua luoa sivua, käytä browserin <strong>takashii</strong> knappia.",
+       "newarticletext": "Linkki vei sinun sivule, joka ei vielä ole.\nSaatat luoa sivun kirjottamalla alla olehvaan kenthään (katto [$1 apusivu] lissää tietoja).\nJos et halua luoa sivua, käytä browserin <strong>takashii</strong> knappia.",
        "noarticletext": "Tällä hetkelä tällä sivula ei ole tekstiä.\nSaatat [[Special:Search/{{PAGENAME}}|hakea sivun nimelä]] muilta sivuilta,\n<span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} hakea aiheesheen liittyviä lokkia]\neli [{{fullurl:{{FULLPAGENAME}}|action=edit}} luoa tämä sivu]</span>.",
        "noarticletext-nopermission": "Tällä hetkelä tällä sivula ei ole tekstiä.\nSaatat [[Special:Search/{{PAGENAME}}|hakea sivun nimelä]] muilta sivuilta,\neli <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} hakea relevantista lokista]\neli [{{fullurl:{{FULLPAGENAME}}|action=edit}} mookata tätä sivua]</span>.",
        "previewnote": "'''Tämä on vasta sivun etukattelu. Sivua ei ole vielä säästetty!'''",
        "redirect-submit": "Mene",
        "redirect-file": "Fiilinimi",
        "fileduplicatesearch-filename": "Fiilinimi:",
-       "specialpages": "Spesiaali sivut",
+       "specialpages": "Spesiaalisivut",
        "specialpages-group-pagetools": "Sivutyöneuvot",
        "external_image_whitelist": "#Älä muuta tätä riviä ollenkhaan.<pre>\n#Kirjota rekyljääri frakmentitten meininkit (vain osa, joka mennee //-merkkitten välhiin) tähhään alle\n#Niitä verrathaan ulkoisitten (suoralinkitetyitten) kuvitten URLhin\n#Net jokka sopivat, näytethään kuvina, muuten kuvhiin näytethään vain linkit\n#Rivit, jokka alkavat #-merkilä on komentaaria\n#Tämä on riippumaton puukstavitten kokosta",
        "tag-filter": "[[Special:Tags|Merkki]] filtteri:",
index 53d54a2..9faf2b1 100644 (file)
        "perfcached": "Les données suivantes sont en cache et peuvent ne pas être à jour. Un maximum de {{PLURAL:$1|1=un résultat|$1 résultats}} est disponible dans le cache.",
        "perfcachedts": "Les données suivantes sont en cache et ont été mises à jour pour la dernière fois le $1. Un maximum de {{PLURAL:$4|1=un résultat est disponible|$4 résultats sont disponibles}} dans le cache.",
        "querypage-no-updates": "Les mises à jour pour cette page sont actuellement désactivées.\nLes données ci-dessous ne seront pas mises à jour.",
+       "querypage-updates-periodical": "Les mises à jour pour cette page sont lancées régulièrement.",
        "viewsource": "Voir le texte source",
        "viewsource-title": "Voir la source de $1",
        "actionthrottled": "Action limitée",
        "createaccountmail": "Utiliser un mot de passe aléatoire temporaire et l’envoyer à l’adresse de courriel spécifiée",
        "createaccountmail-help": "Peut être utilisé pour créer un compte pour une autre personne sans connaître le mot de passe.",
        "createacct-realname": "Nom réel (facultatif)",
-       "createacct-reason": "Motif (connecté publiquement)",
+       "createacct-reason": "Motif (journalisé publiquement)",
        "createacct-reason-ph": "Pourquoi créez-vous un autre compte",
        "createacct-reason-help": "Message affiché dans le journal de création de compte",
        "createacct-submit": "Créez votre compte",
        "badretype": "Les mots de passe que vous avez saisis ne correspondent pas.",
        "usernameinprogress": "Une création de compte pour ce nom d’utilisateur est déjà en cours.\nVeuillez patienter.",
        "userexists": "Le nom d’utilisateur saisi est déjà utilisé.\nVeuillez choisir un nom différent.",
-       "createacct-normalization": "Votre nom d’utilisateur sera modifié en « $2 » à cause de restrictions techniques.",
+       "createacct-normalization": "Votre nom d’utilisateur sera modifié en « $2 » à cause de restrictions techniques.",
        "loginerror": "Erreur de connexion",
        "createacct-error": "Erreur lors de la création du compte",
        "createaccounterror": "Impossible de créer le compte : $1",
        "noname": "Vous n’avez pas saisi un nom d’utilisateur valide.",
        "loginsuccesstitle": "Connecté",
        "loginsuccess": "<strong>Vous êtes maintenant connecté{{GENDER:$1||e|(e)}} à {{SITENAME}} en tant que « $1 ».</strong>",
-       "nosuchuser": "L’utilisateur « $1 » n’existe pas.\nLes noms d’utilisateur sont sensibles à la casse.\nVérifiez l’orthographe ou [[Special:CreateAccount|créez un nouveau compte]].",
+       "nosuchuser": "L’utilisateur « $1 » n’existe pas.\nLes noms d’utilisateur sont sensibles à la casse.\nVérifiez l’orthographe ou [[Special:CreateAccount|créez un nouveau compte]].",
        "nosuchusershort": "Il n’y a pas de contributeur avec le nom « $1 ».\nVeuillez vérifier l’orthographe.",
        "nouserspecified": "Vous devez saisir un nom d’utilisateur.",
        "login-userblocked": "{{GENDER:$1|Cet utilisateur|Cette utilisatrice}} est bloqué{{GENDER:$1||e}}. La connexion n’est pas autorisée.",
        "password-login-forbidden": "L’utilisation de ce nom d’utilisateur ou de ce mot de passe a été interdite.",
        "mailmypassword": "Réinitialiser le mot de passe",
        "passwordremindertitle": "Nouveau mot de passe temporaire pour {{SITENAME}}",
-       "passwordremindertext": "Quelqu’un (depuis l’adresse IP $1) a demandé un nouveau mot de passe\npour {{SITENAME}} ($4). Un mot de passe temporaire pour l’utilisateur\n« $2 » a été créé et défini comme « $3 ». Si c’était bien votre intention,\nvous devrez vous connecter et choisir un nouveau mot de passe.\nVotre mot de passe temporaire expirera dans $5 jour{{PLURAL:$5||s}}.\n\nSi vous n’êtes pas l’auteur de cette demande ou si vous vous avez retrouvé votre\nmot de passe et ne souhaitez plus en changer, vous pouvez ignorer ce message et\ncontinuer à utiliser votre ancien mot de passe.",
+       "passwordremindertext": "Quelqu’un (depuis l’adresse IP $1) a demandé un nouveau mot de passe\npour {{SITENAME}} ($4). Un mot de passe temporaire pour l’utilisateur\n« $2 » a été créé et défini comme « $3 ». Si c’était bien votre intention,\nvous devrez vous connecter et choisir un nouveau mot de passe.\nVotre mot de passe temporaire expirera dans $5 jour{{PLURAL:$5||s}}.\n\nSi vous n’êtes pas l’auteur de cette demande ou si vous vous avez retrouvé votre\nmot de passe et ne souhaitez plus en changer, vous pouvez ignorer ce message et\ncontinuer à utiliser votre ancien mot de passe.",
        "noemail": "Aucune adresse de courriel n’a été enregistrée pour l’utilisat{{GENDER:$1|eur|rice}} « $1 ».",
        "noemailcreate": "Vous devez fournir une adresse de courriel valide",
        "passwordsent": "Un nouveau mot de passe a été envoyé à l’adresse de courriel de l’utilisat{{GENDER:$1|eur|rice}} « $1 ».\nVeuillez vous reconnecter après l’avoir reçu.",
        "botpasswords-help-grants": "Les autorisations permettent d’accéder aux droits déjà accordés à votre compte utilisateur. Activer une autorisation ici ne fournit l’accès à aucun droit que votre compte utilisateur n’aurait pas par ailleurs. Voyez le [[Special:ListGrants|tableau des autorisations]] pour plus d’informations.",
        "botpasswords-label-grants-column": "Accordé",
        "botpasswords-bad-appid": "Le nom de robot « $1 » n’est pas valide.",
-       "botpasswords-insert-failed": "Échec de l’ajout du nom de robot « $1 ». A-t-il déjà été ajouté ?",
-       "botpasswords-update-failed": "Échec à la mise à jour du nom de robot « $1 ». A-t-il déjà été supprimé ?",
+       "botpasswords-insert-failed": "Échec de l’ajout du nom de robot « $1 ». A-t-il déjà été ajouté ?",
+       "botpasswords-update-failed": "Échec à la mise à jour du nom de robot « $1 ». A-t-il déjà été supprimé ?",
        "botpasswords-created-title": "Mot de passe de robots créé",
        "botpasswords-created-body": "Le mot de passe pour le robot « $1 » de l’{{GENDER:$2|utilisateur|utilisatrice}} « $2 » a été créé.",
        "botpasswords-updated-title": "Mot de passe de robots mis à jour",
        "userrights-expiry-none": "N'expire pas",
        "userrights-expiry": "Date d’expiration :",
        "userrights-expiry-existing": "Date d'expiration existante : $2 à $3",
-       "userrights-expiry-othertime": "Autre temps :",
+       "userrights-expiry-othertime": "Autre durée :",
        "userrights-expiry-options": "1 jour:1 day,1 semaine:1 week,1 mois:1 month,3 mois:3 montghs,6 mois:6 month,1 an:1 year",
        "userrights-invalid-expiry": "La date d'expiration pour le groupe « $1 » n'est pas valide.",
        "userrights-expiry-in-past": "La date d'expiration pour le groupe « $1 » est dépassée.",
index 6f1c119..62bae7d 100644 (file)
        "minoredit": "Dit is fan lytse betsjutting",
        "watchthis": "Dizze side folgje",
        "savearticle": "Side bewarje",
+       "savechanges": "Feroarings bewarje",
        "publishpage": "Side fêstlizze",
        "publishchanges": "Feroarings publisearje",
        "preview": "Oerlêze",
        "showpreview": "Earst oerlêze",
-       "showdiff": "Wizigings",
+       "showdiff": "Ferskillen besjen",
        "anoneditwarning": "<strong>Warskôging:</strong> Jo binne net oanmeld. By it fêstlizzen wurdt jo ynternet-adres opnaam yn de sideskiednis. At jo <strong>[$1 oanmelde]</strong> of <strong>[$2 in akkount oanmeitsje]</strong> ferskine jo bewurkingen ûnder jo meidochnamme, njonken oare foardielen.",
        "missingsummary": "<strong>Tink derom:</strong> Jo hawwe gjin gearfetting jûn foar jo bewurking.\nAs jo nochris op ''Side opslaan'' klikke wurdt de bewurking sûnder gearfetting opslein.",
        "missingcommenttext": "Set jo opmerking beleaven hjir ûnder.",
        "tooltip-ca-nstab-template": "It berjocht sjen litte",
        "tooltip-ca-nstab-help": "Helpside sjen litte",
        "tooltip-ca-nstab-category": "De kategoryside sjen litte",
-       "tooltip-minoredit": "Markearje dizze feroaring as fan lytse betsjutting",
+       "tooltip-minoredit": "Dizze feroaring as fan lytse betsjutting markearje",
        "tooltip-save": "Jo feroarings bewarje",
-       "tooltip-preview": "Oerlêze foar't de side fêstlein is!",
-       "tooltip-diff": "Sjen litte hokker feroarings jo yn'e tekst makke hawwe.",
+       "tooltip-publish": "Jo feroarings publisearje",
+       "tooltip-preview": "Graach oerlêze foar't de side fêstlein wurdt.",
+       "tooltip-diff": "De ferskillen mei jo tekstbewurking besjen",
        "tooltip-compareselectedversions": "Sjoch de ferskillen tusken de twa keazen ferzjes fan dizze side",
-       "tooltip-watch": "Foegje dizze side ta oan jo folchlist [alt-w]",
+       "tooltip-watch": "Dizze side oan jo folchlist tafoegje",
        "tooltip-watchlistedit-normal-submit": "Titels wiskje",
        "tooltip-watchlistedit-raw-submit": "Folchlist bywurkje",
        "tooltip-upload": "Opladen starte",
        "tooltip-rollback": "\"Weromdraaie\" set dizze side yn ien klik werom nei hoe't er wie foar't de lêste bydrager syn bewurkings trochfierde",
        "tooltip-undo": "\"Weromsette\" makket dizze wiziging ûngedien, en iepenet it bewurkingsformulier. Hjirtroch kin yn 'e gearfetting in reden tafoege wurde.",
        "tooltip-preferences-save": "Foarkarren bewarje",
+       "tooltip-summary": "Jou in koarte gearfetting",
        "interlanguage-link-title": "$1 – $2",
        "interlanguage-link-title-nonlang": "$1 – $2",
        "common.js": "/* Alles wat hjir oan JavaScript delset wurdt, wurdt foar alle meidoggers laden foar eltse side! */",
index 714f258..2a4d7ed 100644 (file)
        "perfcached": "המידע הבא הוא עותק שמור בזיכרון המטמון, ועשוי שלא להיות מעודכן. לכל היותר {{PLURAL:$1|תוצאה אחת נשמרת|$1 תוצאות נשמרות}} בזיכרון המטמון.",
        "perfcachedts": "המידע הבא הוא עותק שמור בזיכרון המטמון, שעודכן לאחרונה ב־$1. לכל היותר {{PLURAL:$4|תוצאה אחת נשמרת|$4 תוצאות נשמרות}} בזיכרון המטמון.",
        "querypage-no-updates": "העדכונים לדף הזה מופסקים כרגע.\nהמידע לא יעודכן באופן שוטף.",
+       "querypage-updates-periodical": "הדף הזה מעודכן מפעם לפעם.",
        "viewsource": "הצגת מקור",
        "viewsource-title": "הצגת המקור של הדף \"$1\"",
        "actionthrottled": "הפעולה הוגבלה",
index a346ed2..ad1299d 100644 (file)
        "oct": "okt",
        "nov": "nov",
        "dec": "dec",
-       "january-date": "Január $1",
-       "february-date": "Február $1",
-       "march-date": "Március $1",
-       "april-date": "Ã\81prilis $1",
-       "may-date": "Május $1",
-       "june-date": "Június $1",
-       "july-date": "Július $1",
-       "august-date": "Augusztus $1",
-       "september-date": "Szeptember $1",
-       "october-date": "Október $1",
-       "november-date": "November $1",
-       "december-date": "December $1",
+       "january-date": "január $1",
+       "february-date": "február $1",
+       "march-date": "március $1",
+       "april-date": "április $1",
+       "may-date": "május $1",
+       "june-date": "június $1",
+       "july-date": "július $1",
+       "august-date": "augusztus $1",
+       "september-date": "szeptember $1",
+       "october-date": "október $1",
+       "november-date": "november $1",
+       "december-date": "december $1",
        "period-am": "de.",
        "period-pm": "du.",
        "pagecategories": "{{PLURAL:$1|Kategória|Kategória}}",
        "category_header": "A(z) „$1” kategóriába tartozó lapok",
        "subcategories": "Alkategóriák",
        "category-media-header": "A(z) „$1” kategóriába tartozó médiafájlok",
-       "category-empty": "''Ebben a kategóriában pillanatnyilag egyetlen lap vagy médiafájl sem szerepel.''",
+       "category-empty": "<em>Ebben a kategóriában pillanatnyilag egyetlen lap vagy médiafájl sem szerepel.</em>",
        "hidden-categories": "{{PLURAL:$1|Rejtett kategória|Rejtett kategóriák}}",
        "hidden-category-category": "Rejtett kategóriák",
        "category-subcat-count": "{{PLURAL:$2|Ennek a kategóriának csak egyetlen alkategóriája van.|Ez a kategória az alábbi {{PLURAL:$1|alkategóriával|$1 alkategóriával}} rendelkezik (összesen $2 alkategóriája van).}}",
        "copyright": "A tartalom további jelölés hiányában a(z) $1 feltételei szerint használható fel.",
        "copyrightpage": "{{ns:project}}:Szerzői jogok",
        "currentevents": "Aktuális események",
-       "currentevents-url": "Project:Friss események",
+       "currentevents-url": "Project:Aktuális események",
        "disclaimers": "Jogi nyilatkozat",
        "disclaimerpage": "Project:Jogi nyilatkozat",
        "edithelp": "Szerkesztési segítség",
index 50ef092..cdbb2f4 100644 (file)
        "perfcached": "I dati che seguono sono estratti da una copia ''cache'' del database, e potrebbero non essere aggiornati. Un massimo di {{PLURAL:$1|un risultato è disponibile|$1 risultati sono disponibili}} in cache.",
        "perfcachedts": "I dati che seguono sono estratti da una copia ''cache'' del database, il cui ultimo aggiornamento risale al $1. Un massimo di {{PLURAL:$4|un risultato è disponibile|$4 risultati è disponibile}} in cache.",
        "querypage-no-updates": "Gli aggiornamenti della pagina sono temporaneamente sospesi. I dati in essa contenuti non verranno aggiornati.",
+       "querypage-updates-periodical": "Gli aggiornamenti per questa pagina sono eseguiti periodicamente.",
        "viewsource": "Visualizza wikitesto",
        "viewsource-title": "Visualizza wikitesto di $1",
        "actionthrottled": "Azione ritardata",
index 20e2bb7..187a7ef 100644 (file)
        "perfcached": "以下のデータはキャッシュされており、最新ではない可能性があります。最大 $1 {{PLURAL:$1|件の結果}}がキャッシュされます。",
        "perfcachedts": "以下のデータはキャッシュされており、最終更新日時は $1 です。最大 $4 {{PLURAL:$4|件の結果}}がキャッシュされます。",
        "querypage-no-updates": "このページの更新は現在無効化されています。\n以下のデータは当分更新されません。",
+       "querypage-updates-periodical": "このページの更新は定期的に実行されます。",
        "viewsource": "ソースを表示",
        "viewsource-title": "$1のソースを表示",
        "actionthrottled": "操作が速度規制されました",
        "createaccountmail": "無作為な仮パスワードを生成し、指定のメールアドレスに送信",
        "createaccountmail-help": "パスワードを知ることなく他人のアカウントを作成することができます。",
        "createacct-realname": "本名 (省略可能)",
-       "createacct-reason": "理由",
+       "createacct-reason": "理由(公開ログが残ります)",
        "createacct-reason-ph": "アカウントを作成する理由",
        "createacct-reason-help": "アカウント作成記録に表示されるメッセージ",
        "createacct-submit": "アカウントを作成",
        "botpasswords-insert-failed": "ボット「$1」の追加に失敗しました。既に追加されていないか確認してください。",
        "botpasswords-update-failed": "ボット「$1」の更新に失敗しました。削除されていないか確認してください。",
        "botpasswords-created-title": "ボット用パスワードが作成されました",
-       "botpasswords-created-body": "利用者「$2」のボット名「$1」のためのパスワードが作成されました。",
+       "botpasswords-created-body": "{{GENDER:$2|利用者}}「$2」のボット「$1」のパスワードが作成されました。",
        "botpasswords-updated-title": "ボット用パスワードが更新されました",
-       "botpasswords-updated-body": "利用者「$2」のボット名「$1」のためのパスワードが更新されました。",
+       "botpasswords-updated-body": "{{GENDER:$2|利用者}}「$2」のボット「$1」のパスワードが更新されました。",
        "botpasswords-deleted-title": "ボット用パスワードが削除されました",
-       "botpasswords-deleted-body": "利用者「$2」のボット名「$1」のためのパスワードが削除されました。",
+       "botpasswords-deleted-body": "{{GENDER:$2|利用者}}「$2」のボット「$1」のパスワードが削除されました。",
        "botpasswords-newpassword": "<strong>$1</strong>用の新しいパスワードは<strong>$2</strong>です。<em>後で参照するために、この情報を控えておいてください。</em><br />(古いボットの制約などでログイン名と利用者名が同じでなければならない場合は、<strong>$3</strong>を利用者名とし、<strong>$4</strong>をパスワードとしてください。)",
        "botpasswords-no-provider": "BotPasswordsSessionProvider が有効ではありません。",
        "botpasswords-restriction-failed": "ボットパスワード制限によりログインできません。",
        "tags-delete-not-allowed": "拡張機能によって定義されているタグは削除できません(ただし拡張機能が明示的に削除を許可している場合を除く)。",
        "tags-delete-not-found": "タグ「$1」は存在しません。",
        "tags-delete-too-many-uses": "タグ「$1」は少なくとも$2版に付与されており、削除できません。",
-       "tags-delete-warnings-after-delete": "ã\82¿ã\82°ã\80\8c$1ã\80\8dã\81®å\89\8aé\99¤ã\81\97ã\81¾ã\81\97ã\81\9fã\81\8c、以下の{{PLURAL:$2|警告}}が発生しました:",
+       "tags-delete-warnings-after-delete": "ã\82¿ã\82°ã\80\8c$1ã\80\8dã\82\92å\89\8aé\99¤ã\81\97ã\81\9fã\81¨ã\81\93ã\82\8d、以下の{{PLURAL:$2|警告}}が発生しました:",
        "tags-delete-no-permission": "変更タグを削除する権限がありません。",
        "tags-activate-title": "タグの有効化",
        "tags-activate-question": "タグ「$1」を有効化しようとしています。",
index 4153130..56175e9 100644 (file)
@@ -7,7 +7,8 @@
                        "Macofe",
                        "Saraiki",
                        "BukhariSaeed",
-                       "Fitoschido"
+                       "Fitoschido",
+                       "Amire80"
                ]
        },
        "tog-underline": "ربطو خط کشیدگی",
index f293d56..7a7b9d5 100644 (file)
        "perfcached": "다음 자료는 캐시된 것이며 최신이 아닐 수 있습니다. 캐시에 최대 {{PLURAL:$1|결과 한 개|결과 $1개}}가 있습니다.",
        "perfcachedts": "다음 자료는 캐시된 것으로, $1에 마지막으로 업데이트되었습니다. 캐시에 최대 {{PLURAL:$4|결과 한 개|결과 $4개}}가 있습니다.",
        "querypage-no-updates": "이 문서의 갱신이 현재 중지되어 있습니다.\n지금은 자료가 갱신되지 않을 것입니다.",
+       "querypage-updates-periodical": "이 문서의 갱신은 주기적으로 수행됩니다.",
        "viewsource": "원본 보기",
        "viewsource-title": "$1 문서 원본 보기",
        "actionthrottled": "동작 중지",
index b128eaf..0072272 100644 (file)
@@ -30,7 +30,8 @@
                        "Guillermo2149",
                        "Fitoschido",
                        "LittlePuppers",
-                       "Vlad5250"
+                       "Vlad5250",
+                       "1233qwer1234qwer4"
                ]
        },
        "tog-underline": "Versores linea denotandi:",
        "virus-scanfailed": "scrutinium fefellit (codex $1)",
        "virus-unknownscanner": "antivirus incognitus:",
        "logouttext": "<strong>Secessisti a {{grammar:ablative|{{SITENAME}}}}.</strong>\n\nNota bene, paginae fortasse videantur quasi nomen tuum dedisses, priusquam navigatrum purgaveris.",
+       "cannotlogoutnow-title": "Nequitur secedere",
        "welcomeuser": "Salve, $1!",
        "welcomecreation-msg": "Tibi nomen impositum est.\nCura, ut [[Special:Preferences|modos tuos]] deligas.",
        "yourname": "Nomen usoris:",
        "recentchanges-legend-heading": "<strong>Legenda:</strong>",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (vide etiam [[Special:NewPages|indicem paginarum novarum]])",
        "rcfilters-tag-prefix-namespace-inverted": "<strong>:non</strong> $1",
+       "rcfilters-alldiscussions-label": "Cunctae disputationes",
        "rcnotefrom": "Subter sunt '''$1''' nuperrime mutata in proxima '''$2''' die.",
        "rclistfrom": "Monstrare mutata nova incipiens ab $3 $2",
        "rcshowhideminor": "$1 recensiones minores",
index 659bbec..bf2ca77 100644 (file)
        "showpreview": "示覽",
        "showdiff": "示異",
        "anoneditwarning": "'''警示:'''子未登簿,若確纂,IP將誌。茍[$1 登]或[$2 開戶口],是纂欲存以子名,及他效。",
-       "anonpreviewwarning": "''子未登簿,IP將誌。''",
+       "anonpreviewwarning": "子未登簿,IP將誌。",
        "missingsummary": "'''醒示:'''子未概之,復「$1」則文倍焉。",
        "missingcommenttext": "請贊之",
        "missingcommentheader": "'''醒示:'''子未概標之,復「$1」則文倍焉。",
index f33e981..dc132bb 100644 (file)
        "perfcached": "Следните податоци се меѓускладирани и може да не се тековни. Во меѓускладот {{PLURAL:$1|е достапен највеќе еден запис|се достапни највеќе $1 записи}}.",
        "perfcachedts": "Следните податоци се меѓускладирани, последен пат подновени во $1. Во меѓускладот {{PLURAL:$4|е достапен највеќе еден запис|се достапни највеќе $4 записи}}.",
        "querypage-no-updates": "Подновите на оваа страница моментално се оневозможени.\nПодатоците овде во моментов нема да се подновуваат.",
+       "querypage-updates-periodical": "Подновите на оваа страница се вршат повремено.",
        "viewsource": "Преглед",
        "viewsource-title": "Преглед на кодот на $1",
        "actionthrottled": "Дејството е успорено",
        "rcfilters-highlighted-filters-list": "Истакнато: $1",
        "rcfilters-quickfilters": "Зачувани филтри",
        "rcfilters-quickfilters-placeholder-title": "Засега нема зачувани филтри",
-       "rcfilters-quickfilters-placeholder-description": "За да ги зачувате вашите филтерски псотавки за да ги употребите другпат, стиснете на иконката за бележник во подрачјето „Активен филтер“ подолу.",
+       "rcfilters-quickfilters-placeholder-description": "За да ги зачувате вашите филтерски поставки за да ги употребите другпат, стиснете на иконката за бележник во подрачјето „Активен филтер“ подолу.",
        "rcfilters-savedqueries-defaultlabel": "Зачувани филтри",
        "rcfilters-savedqueries-rename": "Преименувај",
        "rcfilters-savedqueries-setdefault": "Задај како основно",
index 14235e1..105f3d3 100644 (file)
        "errorpagetitle": "Sbaglio",
        "returnto": "Torna a $1.",
        "tagline": "'A {{SITENAME}}.",
-       "help": "Ajùto",
+       "help": "Ajuto",
        "help-mediawiki": "Ajuto ncopp' 'a MediaWiki",
-       "search": "Truova",
+       "search": "Cerca",
        "search-ignored-headings": " #<!-- lassa sta linea comme sta --> <pre>\n# Testate ca se sarranno gnurate int' 'a ricerca.\n# Cagnamiente a chesto addeventarranno affettive quanno 'a paggena sarrà innecizzata.\n# Vuje putite forzà 'a reinnecezzazzione d' 'a paggena facenno nu cagnamiento abbacante.\n# 'A sintasse è 'a seguente:\n#   * Ogneccosa 'a 'o carattere \"#\" 'nzegna 'a fine d' 'a linea è 'nu cummanno\n#   * Ogne linea chiena è 'o titolo esatto 'a gnurà, case e tutteccose\nRiferimente\nJonte 'e fore\nVide pure\n #</pre> <!-- lassa sta linea comme sta  -->",
-       "searchbutton": "Truova",
+       "searchbutton": "Cerca",
        "go": "Vàje",
-       "searcharticle": "Vàje",
+       "searcharticle": "Vaje",
        "history": "Verziune 'e primma",
        "history_short": "Cronologgia",
        "history_small": "cronologgia",
        "updatedmarker": "cagnamiénte 'e ll'urdema visita d' 'a mia",
-       "printableversion": "Verzione pe' stampa",
+       "printableversion": "Verzione p''a stampa",
        "permalink": "Jonta permanente",
        "print": "Stampà",
        "view": "Vire",
        "view-foreign": "Vide ncopp'a $1",
-       "edit": "Càgna",
+       "edit": "Cagna",
        "edit-local": "Càgna descrizione lucale",
        "create": "Crèa",
        "create-local": "Azzecca descrizione lucale",
        "protect_change": "càgna",
        "unprotect": "Càgna prutezzione",
        "newpage": "Paggena nova",
-       "talkpagelinktext": "Chiàcchiera",
+       "talkpagelinktext": "chiacchiera",
        "specialpage": "Paggena speciàle",
-       "personaltools": "Strumiente perzonale",
-       "talk": "Chiàcchiera",
+       "personaltools": "Strumente perzonale",
+       "talk": "Chiacchiera",
        "views": "Visite",
-       "toolbox": "Strumiente",
+       "toolbox": "Strumente",
        "tool-link-userrights": "Càgna gruppe {{GENDER:$1|utente}}",
        "tool-link-userrights-readonly": "Vire gruppe {{GENDER:$1|utente}}",
        "tool-link-emailuser": "Manna na masciata email a st'{{GENDER:$1|utente}}",
        "viewcount": "Chesta paggena è stata liggiùta {{PLURAL:$1|una vòta|$1 vòte}}.",
        "protectedpage": "Paggena prutetta",
        "jumpto": "Vaje a:",
-       "jumptonavigation": "navigazione",
-       "jumptosearch": "truova",
+       "jumptonavigation": "navigazzione",
+       "jumptosearch": "cerca",
        "view-pool-error": "Ve cercammo scusa, 'e servers hanno troppo carico mo'.\nTroppe utente stanno cercanno 'e veré sta paggena.\nPe' piacere, aspettate nu poco primma 'e turnà a carrecà sta paggena.\n\n$1",
        "generic-pool-error": "Ve cercammo scusa, 'e servers hanno troppo carico mo'.\nTroppe utente stanno cercanno 'e veré sta risorsa.\nPe' piacere, aspettate nu poco primma 'e turnà a carrecà sta risorsa.",
        "pool-timeout": "Tiempo pe' s'aspettà ô blocco",
        "pool-errorunknown": "Errore scanusciuto",
        "pool-servererror": "'O servizio contatore d''e fatiche nun è a disposizióne ($1).",
        "poolcounter-usage-error": "Errore d'uso: $1",
-       "aboutsite": "'Nfrummazione ncòpp'a {{SITENAME}}",
-       "aboutpage": "Project:'Nfrummazione",
+       "aboutsite": "'Nfurmazzione ncòpp''a {{SITENAME}}",
+       "aboutpage": "Project:'Nfurmazzione",
        "copyright": "Cuntenute suggiette a licienza 'e auso $1 se nun fuje ritto atro.",
        "copyrightpage": "{{ns:project}}:Copyrights",
        "currentevents": "Nuvità",
        "currentevents-url": "Project:Novità",
-       "disclaimers": "Avvertimiènte",
-       "disclaimerpage": "Project:Avvertimiènte generale",
+       "disclaimers": "Avvertimiente",
+       "disclaimerpage": "Project:Avvertimiente generale",
        "edithelp": "Guida",
        "helppage-top-gethelp": "Ajùto",
        "mainpage": "Paggena prencepale",
        "mainpage-description": "Paggena prencepale",
        "policy-url": "Project:Policy",
-       "portal": "Porta d’'a commonetà",
-       "portal-url": "Project:Porta d''a commonetà",
-       "privacy": "'Nformazzione ppe a privacy",
-       "privacypage": "Project:'Nfrummazione ncopp'â privacy",
+       "portal": "Porta d''a communetà",
+       "portal-url": "Project:Porta d''a communetà",
+       "privacy": "'Nfurmazzione p''a privacy",
+       "privacypage": "Project:'Nfurmazzione p''a privacy",
        "badaccess": "Nun aie bastante licenzia",
        "badaccess-group0": "Nun tiene 'a licenzia pe ffà l'azione richiesta.",
        "badaccess-groups": "L'azione ch'ê addemmannato 'a pô ffà sulamente ll'utente ca stanno dint'a {{PLURAL:$2|'o gruppo|uno d' 'e gruppe}}: $1.",
        "newmessageslinkplural": "{{PLURAL:$1|na mmasciata nova|999=mmasciate nnove}}",
        "newmessagesdifflinkplural": "{{PLURAL:$1|urdemo cagnamiento|999=urdeme cagnamiente}}",
        "youhavenewmessagesmulti": "Tiene nuove mmasciate $1",
-       "editsection": "càgna",
+       "editsection": "cagna",
        "editold": "càgna",
        "viewsourceold": "vire sorgente",
        "editlink": "càgna",
        "site-atom-feed": "Feed Atom 'e $1",
        "page-rss-feed": "Feed RSS pe' \"$1\"",
        "page-atom-feed": "Feed Atom ppe \"$1\"",
-       "red-link-title": "$1 ('a paggena nun esiste)",
+       "red-link-title": "$1 (sta paggena nun esiste)",
        "sort-descending": "Urdinamento dicriscente",
        "sort-ascending": "Urdinamento criscente",
        "nstab-main": "Articulo",
        "loginlanguagelabel": "Lengua: $1",
        "suspicious-userlogout": "'A richiesta 'e disconnessione d' 'a toja è stata negate pecché pare ca fosse mannata 'a nu navigatóre rutto o nu proxy 'e \"caching\".",
        "createacct-another-realname-tip": "'O nomme overo vuosto è ozzionale.\nSi sciglite 'e nzertà 'o nomme overo, chesto s'ausarrà pe' dà l'utente l'attribuzione d' 'a fatica fatta.",
-       "pt-login": "Tràse",
+       "pt-login": "Trase",
        "pt-login-button": "Tràse",
        "pt-login-continue-button": "Và annanze e tràse",
-       "pt-createaccount": "Crèa nu cunto nuovo",
+       "pt-createaccount": "Crea 'nu cunto nuovo",
        "pt-userlogout": "Jèsce",
        "php-mail-error-unknown": "Errore scanusciuto dint'a funzione PHP mail()",
        "user-mail-no-addy": "Avite cercato 'e mannà na mmasciata e-mail senza indirizzo.",
        "nchanges": "$1 {{PLURAL:$1|cagnamiento|cagnamiente}}",
        "enhancedrc-since-last-visit": "$1 {{PLURAL:$1|'a ll'urdema visita}}",
        "enhancedrc-history": "cronologgia",
-       "recentchanges": "Urdeme nove",
+       "recentchanges": "Urdeme cagnamiente",
        "recentchanges-legend": "Opzione urdeme cagnamiénte",
        "recentchanges-summary": "Ncopp'a chesta paggena song' appresentate ll'urdeme cagnamiente fatte ê cuntenute d\"o sito.",
        "recentchanges-noresult": "Nisciuno cagnamiento dint'o periodo dato ca soddisfà sti criterie.",
        "minoreditletter": "m",
        "newpageletter": "N",
        "boteditletter": "b",
-       "rc-change-size-new": "$1 {{PLURAL:$1|byte|byte}} aropp'ô cagnamiento",
+       "rc-change-size-new": "$1 {{PLURAL:$1|byte}} aropp''o cagnamiento",
        "newsectionsummary": "/* $1 */ sezziona nnova",
        "rc-enhanced-expand": "Fa vede dettaglie",
        "rc-enhanced-hide": "Annascunne dettaglie",
        "recentchanges-page-removed-from-category": "[[:$1]] luvato d' 'a categurìa",
        "recentchanges-page-removed-from-category-bundled": "[[:$1]]  luvate 'e categurìa, [[Special:WhatLinksHere/$1|sta paggena è azzeccata dint'a n'ati paggene]]",
        "autochange-username": "Cagnamiento automateco MediaWiki",
-       "upload": "Carreca file",
+       "upload": "Careca 'na fiùra",
        "uploadbtn": "Carreca file",
        "reuploaddesc": "Torna a 'o modulo pe ffà 'a carreca",
        "upload-tryagain": "Manna 'a descrizione d' 'o file cagnato",
        "sp-contributions-newonly": "Sulamente 'e contribbute ca songo criazione 'e paggene",
        "sp-contributions-hideminor": "Annascunne cagnamiénte piccerille",
        "sp-contributions-submit": "Truova",
-       "whatlinkshere": "Paggene ca cullegano a chesta",
+       "whatlinkshere": "Paggene ca se cullegano a chesta",
        "whatlinkshere-title": "Paggene ca cullegano a $1",
        "whatlinkshere-page": "Paggena:",
        "linkshere": "'E ppaggene ccà abbascio teneno jonte a <strong>$2</strong>.",
        "tooltip-pt-watchlist": "'A lista d' 'e paggene ca state a cuntrullà",
        "tooltip-pt-mycontris": "N'elenco 'e cuntribbute {{GENDER:|vòste}}",
        "tooltip-pt-anoncontribs": "N'elenco 'e cagnamiente fatte 'a st'indirizzo IP",
-       "tooltip-pt-login": "A reggistrazione è cunsigliata",
+       "tooltip-pt-login": "Ve cunsigliamme 'e trasì dint'o cunto vostro, ma nun l'avite a ffà pe' fforza",
        "tooltip-pt-logout": "Jésce (logout)",
-       "tooltip-pt-createaccount": "Pigliateve curaggio e criate n'utente e trasìte; eziamme ca chisto nun s'avesse 'a ffà pe' fforza",
-       "tooltip-ca-talk": "Vide 'e chiacchere rilative a chesta paggena",
+       "tooltip-pt-createaccount": "Ve cunsigliamme 'e ve reggistrà 'nu cunte e trasì, ma nun l'avite a ffà pe' fforza",
+       "tooltip-ca-talk": "Vide 'e chiacchere 'e chesta paggena",
        "tooltip-ca-edit": "Cagna sta paggena",
        "tooltip-ca-addsection": "Cummincia 'na nova sezzione",
        "tooltip-ca-viewsource": "Chista paggena è prutetta, ma può verè 'o codice sorgente",
-       "tooltip-ca-history": "Vversione 'e primma 'e chesta paggena",
+       "tooltip-ca-history": "Verzione 'e primma 'e chesta paggena",
        "tooltip-ca-protect": "Prutegge chesta paggena",
        "tooltip-ca-unprotect": "Càgna 'a prutezzione 'e chesta paggena",
        "tooltip-ca-delete": "Scancèlla chesta paggena",
        "tooltip-ca-move": "Mòve sta paggena",
        "tooltip-ca-watch": "Azzecca sta paggena int' 'a lista 'e paggene cuntrullate vuosta",
        "tooltip-ca-unwatch": "Lèva sta paggena d' 'a lista 'e paggene cuntrullate vuosta",
-       "tooltip-search": "Truova dint'a {{SITENAME}}",
-       "tooltip-search-go": "Vaje â paggena cu stu nomme si esiste",
-       "tooltip-search-fulltext": "Ascià 'o testo indicato dint'e paggene",
+       "tooltip-search": "Cerca dint''a {{SITENAME}}",
+       "tooltip-search-go": "Vaje a 'na paggena cu stu nomme, si ce sta",
+       "tooltip-search-fulltext": "Cerca chistu testo dint''e paggene",
        "tooltip-p-logo": "Visita a paggena prencepale",
        "tooltip-n-mainpage": "Visita a paggena prencepale",
        "tooltip-n-mainpage-description": "Visita a paggena prencepale",
-       "tooltip-n-portal": "Descrizione d' 'o prugietto, che po' ffa, addò truvà 'e ccose",
+       "tooltip-n-portal": "Descrizione d''o prugietto, che putite fà e addò putite truvà 'e ccose",
        "tooltip-n-currentevents": "Ascìa 'e nfurmaziune ncopp' 'e fatte succiesse mo mmo",
-       "tooltip-n-recentchanges": "Ennece dde urdeme cagnamiénte d' 'o sito",
-       "tooltip-n-randompage": "Na paggena qualsiase",
-       "tooltip-n-help": "Paggena 'e ajùto",
-       "tooltip-t-whatlinkshere": "'Na lista 'e tutte e paggene ca song cullegate a chista",
+       "tooltip-n-recentchanges": "Ennece 'e ll'urdeme cagnamiente d''o sito",
+       "tooltip-n-randompage": "Careca 'na paggena qualonca",
+       "tooltip-n-help": "Paggena 'e ajuto",
+       "tooltip-t-whatlinkshere": "Ennece 'e tutte e paggene ca so' cullegate a chesta",
        "tooltip-t-recentchangeslinked": "Urdeme cagnamiénte dde paggene ca cullegano a chesta",
        "tooltip-feed-rss": "RSS feed pe sta pàggena",
        "tooltip-feed-atom": "Atom feed pe sta pàggena",
        "tooltip-t-contributions": "Lista dde contributte fatte 'a {{GENDER:$1|chist'utente}}",
        "tooltip-t-emailuser": "Manna 'nu email a {{GENDER:$1|chist'utente}}",
        "tooltip-t-info": "Cchiù nfurmaziune ncopp'a sta paggena",
-       "tooltip-t-upload": "Carreca file",
-       "tooltip-t-specialpages": "Lista 'e tutte e paggene speciale",
-       "tooltip-t-print": "Vversione pe stampà 'a chesta paggena",
+       "tooltip-t-upload": "Careca cchiù fiùre",
+       "tooltip-t-specialpages": "Lista 'e tutte 'e paggene speciale",
+       "tooltip-t-print": "Verzione p''a stampa 'e chesta paggena",
        "tooltip-t-permalink": "Jonta permanente a chesta vversione dda paggena",
        "tooltip-ca-nstab-main": "Vire 'a paggena 'e contenuto",
        "tooltip-ca-nstab-user": "Vire 'a paggena utente",
        "pageinfo-hidden-categories": "{{PLURAL:$1|Categurìa annascunnuta|Categurìe annascunnute}} ($1)",
        "pageinfo-templates": "Template {{PLURAL:$1|appennuto|appennute}} ($1)",
        "pageinfo-transclusions": "{{PLURAL:$1|Paggena appennuta|Paggene appennute}} ncopp'a ($1)",
-       "pageinfo-toolboxlink": "Nfurmaziune d' 'a paggena",
+       "pageinfo-toolboxlink": "'Nfurmazzione d''a paggena",
        "pageinfo-redirectsto": "Reindirizza a",
        "pageinfo-redirectsto-info": "nfurmaziune",
        "pageinfo-contentpage": "Cuntata comme na paggena 'e cuntenute",
        "feedback-thanks": "Grazie! 'O feedback vuosto s'è mpizzato dint' 'a paggena \"[$2 $1]\".",
        "feedback-thanks-title": "Ve ringraziammo!",
        "feedback-useragent": "Aggente utente:",
-       "searchsuggest-search": "Truova dint'a {{SITENAME}}",
+       "searchsuggest-search": "Cerca dint''a {{SITENAME}}",
        "searchsuggest-containing": "tène...",
        "api-error-badtoken": "Errore interno: 'O token nun è buono.",
        "api-error-emptypage": "'A criazione 'e paggene nuove abbacante nun è permessa.",
index e2ff083..69a3d87 100644 (file)
        "perfcached": "Følgende data er en tidligere kopi og ikke nødvendigvis den siste versjonen i databasen. Maksimalt {{PLURAL:$1|ett resultat|$1 resultater}} er {{PLURAL:$1|tilgjengelig|tilgjengelige}} som tidligere kopier.",
        "perfcachedts": "Listen ble sist oppdatert $1. Maksimalt {{PLURAL:$4|ett resultat|$4 resultater}} vises.",
        "querypage-no-updates": "Oppdateringer for denne siden er slått av. Data her blir ikke gjenoppfrisket.",
+       "querypage-updates-periodical": "Oppdateringer for denne siden kjøres periodisk.",
        "viewsource": "Vis kilde",
        "viewsource-title": "Vis kilden til $1",
        "actionthrottled": "Handlingsgrense overskredet",
index 91f6f1e..76e678e 100644 (file)
        "view-foreign": "Bekyken up $1",
        "edit": "Bewarken",
        "edit-local": "Lokale beschrieving bewarken",
-       "create": "Anmaken",
+       "create": "Upstellen",
        "create-local": "Lokale beskryving tovogen",
        "delete": "Vordsmyten",
        "undelete_short": "$1 {{PLURAL:$1|versy|versys}} weaderümmeplaatsen",
        "protectedpagetext": "Disse syde is beveiligd. Bewarken of andere handelingen binnet neet möägelik.",
        "viewsourcetext": "Jy künnet de brontekst van disse syde bewarken en bekyken.",
        "viewyourtext": "Jy künnet <strong>juw bewarkingen</strong> an de brontekst van disse syde bekyken en kopieren.",
-       "protectedinterface": "Up disse syde steyt tekst dee gebruked wördt vöär systeemteksten van disse wiki, en is beveiligd üm misbruuk te vöärkommen. Bruuk [https://translatewiki.net/ translatewiki.net], et lokaliseringsprojekt vöär MediaWiki, üm oaversetingen vöär alle wikis to te vogen of te wysigen.",
+       "protectedinterface": "Up disse syde steyt tekst dee gebruked wördt vöär systeemteksten van disse wiki, en is beveiligd üm misbruuk te vöärkommen. Gebruuk [https://translatewiki.net/ translatewiki.net], et lokaliseringsprojekt vöär MediaWiki, üm oaversetingen vöär alle wikis to te vogen of te wysigen.",
        "editinginterface": "<strong>Wårsküwing:</strong> jy bewarket een syde dee teksten gebruukt vöär de gebrukersümgeaving van de programmatuur. \nWat jy up disse syde wysigen is van invlööd up de gebrukersümgeaving van andere gebrukers van disse wiki.",
        "translateinterface": "Üm oaversettingen vöär alle wikis to te vogen of te wysigen, kün jy [https://translatewiki.net/ translatewiki.net] gebruken, et lokaliseringsprojekt vöär MediaWiki.",
        "cascadeprotected": "Disse syde is beveiligd ümdat et vöärkümt in de volgende {{PLURAL:$1|syde|syden}}, dee beveiligd {{PLURAL:$1|is|binnet}} mid de \"kaskade\"-opty:\n$2",
        "resettokens-done": "Tokens ongedaonmaken.",
        "resettokens-resetbutton": "Ekeuzen tokens ongedaonmaken",
        "summary": "Samenvatting:",
-       "subject": "Onderwarp:",
+       "subject": "Underwarp:",
        "minoredit": "kleine wysiging",
        "watchthis": "Volg disse syde",
        "savearticle": "Syde uutgeaven",
        "savechanges": "Wysigingen uutgeaven",
        "publishpage": "Zied uutbrengen",
        "publishchanges": "Wysigingen uutgeaven",
-       "preview": "Naokieken",
+       "preview": "Nåkyken",
        "showpreview": "Bewarking nåkyken",
        "showdiff": "Verskil bekyken",
        "blankarticle": "<strong>Waorschuwing:</strong> de zied die'j anmaken willen is leeg.\nA'j noen weer op \"$1\" klikken, dan wördt de zied an-emaakt zonder enige inhoud.",
        "accmailtitle": "Wachtwoord is verstuurd.",
        "accmailtext": "Der is n willekeurig wachtwoord veur [[User talk:$1|$1]] verstuurd naor $2. t Kan ewiezigd wörden op de zied ''[[Special:ChangePassword|wachtwoord wiezigen]]'' naoda'j an-emeld bin.",
        "newarticle": "(Niej)",
-       "newarticletext": "Disse syde besteyt noch neet.\nIn et veld hyrunder kün jy wat skryven üm disse syde an te maken (meyr informaty vind jy up de [$1 hülpsyde]).\nAs jy hyr per ungelük terechtekommen binnet bruuk dan de knoppe '''vöärige''' üm terügge te gån.",
+       "newarticletext": "Disse syde besteyt noch neet.\nIn et veld hyrunder kün jy wat skryven üm disse syde an te maken (meyr informaty vind jy up de [$1 hülpsyde]).\nAs jy hyr per ungelük terechtekommen binnet gebruuk dan de knoppe '''vöärige''' üm terügge te gån.",
        "anontalkpagetext": "----\n<em>Disse oaverlegsyde höyrt by een anonyme gebruker dee noch geen gebrukersname hevt, of et neet bruukt.</em>\nDårümme gebruken wy et IP-adresse ter identifikaty. Een IP-adresse kan döär meyrere lüde gebruked wörden. As jy een anonyme gebruker binnet, en et gevööl hebbet dat jy berichten kryget dee neet vöär ju bedoold binnet [[Special:CreateAccount|skryv ju eigen dan in]] of [[Special:UserLogin|meld ju eigen an]] üm verwarring mid andere anonyme gebrukers in de tokumst te vöärkommen.''",
        "noarticletext": "Der steyt nun geen tekst up disse syde.\nJy künnet [[Special:Search/{{PAGENAME}}|de titel upsöken]] in andere syden,\n<span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} söken in de logboken],\nof [{{fullurl:{{FULLPAGENAME}}|action=edit}} disse syde anmaken]</span>.",
        "noarticletext-nopermission": "Up disse syde steyt geen tekst.\nJy künnet [[Special:Search/{{PAGENAME}}|söken nå disse term]] in andere syden of\n<span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} de logboken döärsöken]</span>, mär jy hebbet geen rechten üm disse syde an te maken.",
        "missing-revision": "De versie #$1 van de zied \"{{FULLPAGENAME}} besteet niet.\n\nDit kömp meestentieds deur t volgen van n verouwerde verwiezing naor n zied die vortedaon is.\nWaorschienlik ku'j der meer gegevens over vienen in t [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} vortdologboek].",
        "userpage-userdoesnotexist": "Je bewarken n gebrukerszied van n gebruker die niet besteet (gebruker \"<nowiki>$1</nowiki>\"). Kiek effen nao o'j disse zied wel anmaken/bewarken willen.",
-       "userpage-userdoesnotexist-view": "Gebruker \"$1\" steet hier niet in-eschreven",
+       "userpage-userdoesnotexist-view": "Gebruker \"$1\" steyt hyr neet inskreaven",
        "blocked-notice-logextract": "Disse gebruker is op t moment eblokkeerd.\nDe leste regel uut t blokkeerlogboek steet hieronder as referensie:",
        "clearyourcache": "<strong>Upmarking:</strong> nå et seakeren, sül jy lichtkans et tüskengehöägen van juw webkyker mütten leadigen üm de wysigingen te seen.\n* <strong>Firefox / Safari:</strong> hold <em>Shift</em> indrükked terwyl jy up <em>Herladen</em> klikket, of drük up <em>Ctrl-F5</em> of <em>Ctrl-R</em> (<em>⌘-R</em> up een Mac)\n* <strong>Google Chrome:</strong> drük up <em>Ctrl-Shift-R</em> (<em>⌘-Shift-R</em> up een Mac)\n* <strong>Internet Explorer:</strong> hold <em>Ctrl</em> indrükked terwyl jy up <em>Herladen</em> klikket, of drük up <em>Ctrl-F5</em>\n* <strong>Opera:</strong> gå nå <em>Menü → Instellingen</em> (<em>Opera → Vöärköären</em> up een Mac) en dan nå <em>Privaatheid & beveiliging → Söökgeskydenisse wisken → Tydelike afbealdingen en bestanden</em>.",
        "usercssyoucanpreview": "'''Tip:''' gebruuk de knoppe \"{{int:showpreview}}\" um joew nieje css/js nao te kieken veurda'j t opslaon.",
        "userinvalidconfigtitle": "'''Waorschuwing:''' der is gien uutvoering mit de naam \"$1\". Vergeet niet dat joew eigen .css- en .js-ziejen beginnen mit n kleine letter, bv. \"{{ns:user}}:Naam/'''v'''ector\" in plaotse van \"{{ns:user}}:Naam/'''V'''ector.css\".",
        "updated": "(Bewark)",
        "note": "'''Opmarking:'''",
-       "previewnote": "<strong>Denk derüm dat dit allinnig een nåkyksyde is.</strong>\nJuw wysigingen binnet noch neet seakerd!",
+       "previewnote": "<strong>Denk derümme dat dit allinnig een nåkyksyde is.</strong>\nJuw wysigingen binnet noch neet vastlegd!",
        "continue-editing": "Gå nå et bewarkingsveld",
        "previewconflict": "Disse versie löt zien hoe de tekste in t bovenste veld deruut kömp te zien a'j de tekste opslaon.",
        "session_fail_preview": "'''De bewarking kan niet verwarkt wörden wegens n verlies an data.'''\nProbeer t laoter weer.\nAs t probleem dan nog steeds veurkömp, probeer dan [[Special:UserLogout|opniej an te melden]].",
        "editing": "Bewarken: $1",
        "creating": "Anmaken: $1",
        "editingsection": "Bewarken: $1 (deylsyde)",
-       "editingcomment": "Bewarken: $1 (niej onderwarp)",
+       "editingcomment": "Bewarken: $1 (ny underwarp)",
        "editconflict": "Tegelieke bewörken: $1",
        "explainconflict": "'''NB:''' n aander hef disse zied ewiezigd naoda'j an disse bewarking begunnen bin.\nt Bovenste bewarkingsveld löt de zied zien zo as t noen is.\nDaoronder (bie \"Wiezigingen\") staon de verschillen tussen joew versie en de op-esleugen zied.\nHelemaole onderan (bie \"Joew tekste\") steet nog n bewarkingsveld mit joew versie.\nJe zullen je eigen wiezigingen in de nieje tekste in mutten passen.\n'''Allinnig''' de tekste in t bovenste veld wörden beweerd a'j noen kiezen veur \"$1\".",
        "yourtext": "Joew tekste",
        "permissionserrorstext": "Je maggen of kunnen dit niet doon. De {{PLURAL:$1|reden|redens}} daorveur {{PLURAL:$1|is|bin}}:",
        "permissionserrorstext-withaction": "Jy hebbet geen rechten üm $2, mid de volgende {{PLURAL:$1|readen|readenen}}:",
        "recreate-moveddeleted-warn": "'''Waorschuwing: je maken n zied an die eerder al vortedaon is.'''\n\nBedenk eerst of t neudig is um disse zied veerder te bewarken.\nVeur de dudelikheid steet hieronder  t vortdologboek en t herneumlogboek veur disse zied:",
-       "moveddeleted-notice": "Disse syde is vordn.\nHyrunder steyt de informaty uut et vortsmytlogbook, et beveiligingslogbook, en et hernöömlogbook.",
+       "moveddeleted-notice": "Disse syde is vordsmeaten.\nHyrunder steyt de informaty uut et vortsmytlogbook, et beveiligingslogbook, en et hernöömlogbook.",
        "log-fulllog": "t Hele logboek bekieken",
        "edit-hook-aborted": "De bewarking is aofebreuken deur n hook.\nDer is gien reden op-egeven.",
        "edit-gone-missing": "De zied kon niet bie-ewörken wörden.\nt Lik derop as of t vortedaon is.",
        "undo-success": "De bewarking kan weerummedreid wörden. Kiek de vergelieking hieronder nao um der wisse van de ween dat alles goed is, en slao de de zied op um de bewarking weerumme te dreien.",
        "undo-failure": "De wieziging kon niet weerummedreid wörden umdat t ondertussen awweer ewiezigd is.",
        "undo-norev": "De bewarking kon niet weerummedreid wörden, umdat t niet besteet of vortedaon is.",
-       "undo-summary": "Versie $1 van [[Special:Contributions/$2|$2]] ([[User talk:$2|overleg]]) weerummedreid",
+       "undo-nochange": "Et likt derup dat de bewarking al weaderümmedraid is.",
+       "undo-summary": "Versy $1 van [[Special:Contributions/$2|$2]] ([[User talk:$2|oaverleg]]) weaderümmedraid",
        "undo-summary-username-hidden": "Versie $1 deur n verbörgen gebruker weerummedreid",
        "cantcreateaccount-text": "t Anmaken van gebrukers van dit IP-adres (<b>$1</b>) is eblokkeerd deur [[User:$3|$3]].\n\nDe deur $3 op-egeven reden is ''$2''",
        "viewpagelogs": "Bekyk logboken vöär disse syde",
        "last": "lätste",
        "page_first": "eerste",
        "page_last": "leste",
-       "histlegend": "Verklaoring aofkortingen: (noen) = verschil mit de op-esleugen versie, (veurige) = verschil mit de veurige versie, K = kleine wieziging",
+       "histlegend": "Verskillenselekty: selekteer de te vergelyken versys en drük up ENTER of up de knoppe underan.<br />\nVerklåring afkortingen: <strong>({{int:cur}})</strong> = verskil mid de aktuele versy, <strong>({{int:last}})</strong> = verskil mid de vöärgånde versy, <strong>{{int:minoreditletter}}</strong> = kleine wysiging.",
        "history-fieldset-title": "Versys filteren",
        "history-show-deleted": "Allinnig vortedaon",
-       "histfirst": "Eerste",
-       "histlast": "Leste",
+       "histfirst": "oldste",
+       "histlast": "nyste",
        "historysize": "({{PLURAL:$1|1 byte|$1 bytes}})",
        "historyempty": "leadig",
        "history-feed-title": "Wiezigingsoverzichte",
        "rev-suppressed-diff-view": "Eén van de bewarkingen veur de verschillen die'j op-evreugen hebben, is '''onderdrokt'''.\nJe kunnen disse verschillen bekieken. Misschien steet der over in t [{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGENAMEE}}}} logboek mit onderdrokten versies].",
        "rev-delundel": "bekyken/verbargen",
        "rev-showdeleted": "bekiek",
-       "revisiondelete": "Wiezigingen vortdoon/herstellen",
+       "revisiondelete": "Versys vordsmyten en weaderümmesetten",
        "revdelete-nooldid-title": "Gien doelversie",
        "revdelete-nooldid-text": "Je hebben gien versie an-egeven waor disse aksie op uutevoerd mut wörden.",
        "revdelete-no-file": "t Op-egeven bestaand besteet niet.",
        "difference-title-multipage": "Verschil tussen ziejen \"$1\" en \"$2\"",
        "difference-multipage": "(Verschil tussen ziejen)",
        "lineno": "Regel $1:",
-       "compareselectedversions": "Vergeliek de ekeuzen versies",
+       "compareselectedversions": "Vergelyk de köäsen versys",
        "showhideselectedversions": "Ekeuzen versies bekieken/verbargen",
        "editundo": "weaderümmedraien",
        "diff-empty": "(Gien verschil)",
        "difference-missing-revision": "{{PLURAL:$2|Eén versie|$2 versies}} van disse verschillen ($1) {{PLURAL:$2|is|bin}} niet evunnen.\n\nDit kömp meestentieds deur t volgen van n verouwerde verwiezing naor n zied die vortedaon is.\nWaorschienlik ku'j der meer gegevens over vienen in t [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} vortdologboek].",
        "searchresults": "Söökresultaten",
        "searchresults-title": "Söökresultaten vöär \"$1\"",
-       "titlematches": "Overeenkomst mit t onderwarp",
+       "titlematches": "Oavereynkumst mid et underwarp",
        "textmatches": "Overeenkomst mit teksten",
        "notextmatches": "Gien overeenstemming",
        "prevn": "vöärige {{PLURAL:$1|$1}}",
        "nextn-title": "{{PLURAL:$1|Volgend resultaat|Volgende $1 resultaten}}",
        "shown-title": "Låt $1 {{PLURAL:$1|resultaat|resultaten}} per syde seen",
        "viewprevnext": "($1 {{int:pipe-separator}} $2) ($3) bekyken.",
-       "searchmenu-exists": "'''Der is n zied mit de naam \"[[:$1]]\" op disse wiki.'''",
+       "searchmenu-exists": "<strong>Der is een syde mid de name \"[[:$1]]\" up disse wiki.</strong> {{PLURAL:$2|0=|See ouk de andere söökresultaten.}}",
        "searchmenu-new": "<strong>De syde \"[[:$1]]\" up disse wiki anmaken!</strong> \n{{PLURAL:$2|0=|See ouk de syde mid juw söökresultaten.|See ouk de lyste mid vünden söökresultaten.}}",
        "searchprofile-articles": "Artikels",
        "searchprofile-images": "Multimedia",
        "searchprofile-everything-tooltip": "Alle inhold döärsöken (ouk oaverlegsyden)",
        "searchprofile-advanced-tooltip": "Söken in de angeaven naamruumden",
        "search-result-size": "$1 ({{PLURAL:$2|1 woord|$2 woorden}})",
-       "search-result-category-size": "{{PLURAL:$1|1 kategorielid|$1 kategorielejen}} ({{PLURAL:$2|1 onderkategorie|$2 onderkategorieën}}, {{PLURAL:$3|1 bestaand|$3 bestaanden}})",
+       "search-result-category-size": "{{PLURAL:$1|1 kategorylid|$1 kategoryleaden}} ({{PLURAL:$2|1 underkategory|$2 underkategoryen}}, {{PLURAL:$3|1 bestand|$3 bestanden}})",
        "search-redirect": "(döärverwysing vanaf $1)",
        "search-section": "(underwarp $1)",
        "search-file-match": "(kümt oavereyne mid de inhold van et bestand)",
        "prefs-watchlist-edits-max": "Maximale antal: 1.000",
        "prefs-watchlist-token": "Volgliestesleutel",
        "prefs-misc": "Overig",
-       "prefs-resetpass": "Wachtwoord wiezigen",
+       "prefs-resetpass": "Wachtwoord wysigen",
        "prefs-changeemail": "Netpostadres wiezigen of vorthaolen",
        "prefs-setemail": "Stel n netpostadres in",
        "prefs-email": "Instellingen veur netpost",
        "yourlanguage": "Taal / språke:",
        "yourvariant": "Taalvariaant veur inhoud:",
        "prefs-help-variant": "Joew veurkeursvariaant of -spelling um de inhoudsziejen van disse wiki in weer te geven.",
-       "yournick": "Alias veur ondertekeningen",
+       "yournick": "Nye handteykening:",
        "prefs-help-signature": "Reaksies op de overlegziejen mutten ondertekend wörden mit \"<nowiki>~~~~</nowiki>\", dit wörden dan ummezet in joew ondertekening mit daorbie de daotum en tied van de bewarking.",
        "badsig": "Ongeldige haandtekening; HTML naokieken.",
        "badsiglength": "Joew haandtekening is te lang.\nt Mut minder as {{PLURAL:$1|letter|letters}} hebben.",
        "prefs-help-email-required": "Hier he'w n netpostadres veur neudig.",
        "prefs-info": "Basisinformaty",
        "prefs-i18n": "Språkinstellingen",
-       "prefs-signature": "Ondertekening",
+       "prefs-signature": "Handteykening",
        "prefs-dateformat": "Daotumopmaak:",
        "prefs-timeoffset": "Tiedsverschil",
        "prefs-advancedediting": "Algemene opsies",
        "userrights-conflict": "Konflikt bie t wiezigen van gebrukersrechten! Kiek joew wiezigingen nao en bevestig t.",
        "group": "Groep:",
        "group-user": "gebrukers",
-       "group-autoconfirmed": "an-emelde gebrukers",
+       "group-autoconfirmed": "bevästigde gebrukers",
        "group-bot": "bots",
        "group-sysop": "beheerders",
-       "group-bureaucrat": "burokraoten",
+       "group-interface-admin": "tüskenvlakbeheyrders",
+       "group-bureaucrat": "bürokraten",
        "group-suppress": "toezichthouwers",
        "group-all": "(alles)",
        "group-user-member": "{{GENDER:$1|gebruker}}",
        "group-autoconfirmed-member": "{{GENDER:$1|autobevestigden gebruker}}",
        "group-bot-member": "{{GENDER:$1|bot}}",
        "group-sysop-member": "{{GENDER:$1|beheerder}}",
+       "group-interface-admin-member": "{{GENDER:$1|tüskenvlakbeheyrder}}",
        "group-bureaucrat-member": "{{GENDER:$1|burokraot}}",
        "group-suppress-member": "{{GENDER:$1|toezichthouwer}}",
        "grouppage-user": "{{ns:project}}:Gebrukers",
        "grouppage-autoconfirmed": "{{ns:project}}:An-emelde gebrukers",
        "grouppage-bot": "{{ns:project}}:Bots",
        "grouppage-sysop": "{{ns:project}}:Beheerder",
+       "grouppage-interface-admin": "{{ns:project}}:Tüskenvlakbeheyrder",
        "grouppage-bureaucrat": "{{ns:project}}:Beheerder",
        "grouppage-suppress": "{{ns:project}}:Toezicht",
        "right-read": "Ziejen bekieken",
        "right-nominornewtalk": "Kleine bewarkingen an n overlegzied leien niet tot n melding 'nieje berichten'",
        "right-apihighlimits": "Hoge API-limieten gebruken",
        "right-writeapi": "Bewarken via de API",
-       "right-delete": "Ziejen vortdoon",
+       "right-delete": "Syden vordsmyten",
        "right-bigdelete": "Ziejen mit n grote geschiedenisse vortdoon",
-       "right-deletelogentry": "Bepaolde logboekregels vortdoon en weerummeplaotsen",
+       "right-deletelogentry": "Bepålde logbookregels vordsmyten en weaderümmeplaatsen",
        "right-deleterevision": "Versies van ziejen verbargen",
        "right-deletedhistory": "Vortedaone versies bekieken, zonder te kunnen zien wat der vortedaon is",
        "right-deletedtext": "Bekiek vortedaone tekste en wiezigingen tussen vortedaone versies",
        "rightslog": "Gebrukersrechtenlogboek",
        "rightslogtext": "Dit is n logboek mit veraanderingen van gebrukersrechten",
        "action-read": "disse zied lezen",
-       "action-edit": "disse zied bewarken",
+       "action-edit": "disse syde bewarken",
        "action-createpage": "disse zied anmaken",
        "action-createtalk": "disse overlegzied anmaken",
        "action-createaccount": "disse gebrukerskonto anmaken",
        "action-reupload-shared": "n aander bestaand over dit bestaand uut de edeelden mediadatabanke hinne zetten.",
        "action-upload_by_url": "dit bestaand vanaof n webadres oplaojen",
        "action-writeapi": "de schrief-API bewarken",
-       "action-delete": "disse zied vortdoon",
-       "action-deleterevision": "disse versie vortdoon",
+       "action-delete": "disse syde vordsmyten",
+       "action-deleterevision": "vord te smyten versys",
        "action-deletedhistory": "de vortedaone versies van disse zied bekieken",
        "action-browsearchive": "vortedaone ziejen zeuken",
        "action-undelete": "disse zied weerummeplaotsen",
        "recentchanges": "Lätste wysigingen",
        "recentchanges-legend": "Optys vöär lätste wysigingen",
        "recentchanges-summary": "Up disse syde kün jy de lätste wysigingen van disse wiki bekyken.",
-       "recentchanges-noresult": "Der waren in disse periode gien wiezigingen die an de kriteria voldoon.",
+       "recentchanges-noresult": "Der waren in disse periode geen wysigingen dee an de kriteria voldoot.",
        "recentchanges-feed-description": "Zeuk naor de alderleste wiezingen op disse wiki in disse voer.",
        "recentchanges-label-newpage": "Mid disse bewarking is een nye syde maked",
        "recentchanges-label-minor": "Dit is een kleine wysiging",
        "rcfilters-restore-default-filters": "Standardfilters weerummezetten",
        "rcfilters-clear-all-filters": "Alle filters vortdoon",
        "rcfilters-show-new-changes": "Låt nyste wysigingen seen",
-       "rcfilters-search-placeholder": "Filter wysigingen (bruuk et menü of söök up filtername)",
+       "rcfilters-search-placeholder": "Filter wysigingen (gebruuk et menü of söök up filtername)",
        "rcfilters-filterlist-feedbacklink": "Låt uns weaten wat jy van disse (nye) filterhülpmiddels vinden",
        "rcfilters-highlightbutton-title": "Resultaten markeren",
        "rcfilters-highlightmenu-title": "Kies n kleur",
        "rcshowhidebots-show": "bekyken",
        "rcshowhidebots-hide": "verbargen",
        "rcshowhideliu": "$1 registreerde gebrukers",
-       "rcshowhideliu-show": "Bekiek",
+       "rcshowhideliu-show": "Bekyk",
        "rcshowhideliu-hide": "verbargen",
        "rcshowhideanons": "$1 anonyme gebrukers",
        "rcshowhideanons-show": "bekyken",
        "upload-permitted": "Toe-estaone bestaandstypes: $1.",
        "upload-preferred": "An-ewezen bestaandstypes: $1.",
        "upload-prohibited": "Verbeujen bestaandstypes: $1.",
-       "uploadlogpage": "Logboek mit nieje bestaanden",
+       "uploadlogpage": "Logbook mid nye bestanden",
        "uploadlogpagetext": "Hieronder steet n lieste mit bestaanden die net niej bin.\nZie de [[Special:NewFiles|uutstalling mit media]] veur n overzicht.",
        "filename": "Bestaandsnaam",
        "filedesc": "Beskryving",
        "zip-unsupported": "t Bestaand is n ZIP-bestaand dat gebruukmaak van ZIP-meugelikheen die MediaWiki niet ondersteunt.\nDe veiligheid kan niet nao-ekeken wörden.",
        "uploadstash": "Verbörgen bestaanden",
        "uploadstash-summary": "Disse zied gif toegang tot bestaanden die op-estuurd bin of nog op-estuurd wörden mer nog niet beschikbaor emaakt bin op de wiki. Disse bestaanden bin allinnig zichtbaor veur de gebruker die ze opstuurt.",
-       "uploadstash-clear": "Verbörgen bestaanden vortdoon",
+       "uploadstash-clear": "Verbörgen bestanden vordsmyten",
        "uploadstash-nofiles": "Der bin gien verbörgen bestaanden.",
        "uploadstash-badtoken": "t Uutvoeren van de haandeling is mislokt. Dit kömp waorschienlik deurdat joew bewarkingsreferensies verleupen bin. Probeer t opniej.",
        "uploadstash-errclear": "t Vortdoon van de bestaanden is mislokt.",
        "file-anchor-link": "Bestand",
        "filehist": "Bestandsgeskydenisse",
        "filehist-help": "Klik up een dåtum/tyd üm et bestand te seen so as et destyds was.",
-       "filehist-deleteall": "alles vortdoon",
-       "filehist-deleteone": "disse vortdoon",
-       "filehist-revert": "weerummedreien",
+       "filehist-deleteall": "alles vordsmyten",
+       "filehist-deleteone": "vordsmyten",
+       "filehist-revert": "weaderümmedraien",
        "filehist-current": "aktueel",
        "filehist-datetime": "Dåtum/tyd",
        "filehist-thumb": "Miniatuurafbealding",
        "filerevert-submit": "Weerummedreien",
        "filerevert-success": "<span class=\"plainlinks\">'''[[Media:$1|$1]]''' is weerummedreid naor de [$4 versie op $2, $3]</span>.",
        "filerevert-badversion": "Der is gien veurige lokale versie van dit bestaand mit de op-egeven tied.",
-       "filedelete": "$1 vortdoon",
-       "filedelete-legend": "Bestaand vortdoon",
+       "filedelete": "$1 vordsmyten",
+       "filedelete-legend": "Bestand vordsmyten",
        "filedelete-intro": "Je doon t bestaand '''[[Media:$1|$1]]''' noen vort samen mit de geschiedenisse dervan.",
        "filedelete-intro-old": "Je bin de versie van '''[[Media:$1|$1]]''' van [$4 $3, $2] vort an t doon.",
        "filedelete-comment": "Reden:",
-       "filedelete-submit": "Vortdoon",
+       "filedelete-submit": "Vordsmyten",
        "filedelete-success": "'''$1''' is vortedaon.",
        "filedelete-success-old": "De versie van '''[[Media:$1|$1]]''' van $3, $2 is vortedaon.",
        "filedelete-nofile": "'''$1''' besteet niet.",
        "filedelete-nofile-old": "Der is gien versie van '''$1''' in t archief mit de an-egeven eigenschappen.",
        "filedelete-otherreason": "Aandere reden:",
        "filedelete-reason-otherlist": "Aandere reden",
-       "filedelete-reason-dropdown": "*Veulveurkoemende redens veur t vortdoon van ziejen\n** Auteursrechtenschending\n** Dit bestaand he'w dubbel",
-       "filedelete-edit-reasonlist": "Reden veur t vortdoon bewarken",
+       "filedelete-reason-dropdown": "*Algemeyne readenen vöär vordsmyten\n** Autöörsrechtenschending\n** Dubbel bestand",
+       "filedelete-edit-reasonlist": "Readenen vöär et vordsmyten bewarken",
        "filedelete-maintenance": "t Vortdoon en weerummeplaotsen kan noen effen niet umda-w bezig bin mit onderhoud.",
        "filedelete-maintenance-title": "Kan bestaand niet vortdoon",
        "mimesearch": "Zeuken op MIME-type",
        "brokenredirects": "Ebreuken deurverwiezingen",
        "brokenredirectstext": "Disse deurverwiezingen verwiezen naor n niet-bestaonde zied.",
        "brokenredirects-edit": "bewark",
-       "brokenredirects-delete": "vortdoon",
+       "brokenredirects-delete": "vordsmyten",
        "withoutinterwiki": "Ziejen zonder verwiezingen naor aandere talen",
        "withoutinterwiki-summary": "De volgende ziejen verwiezen niet naor versies in n aandere taal.",
        "withoutinterwiki-legend": "Veurvoegsel",
        "notargettext": "Je hebben niet op-egeven veur welke zied je disse funksie bekieken willen.",
        "nopagetitle": "Doelzied besteet niet",
        "nopagetext": "De zied die'j herneumen willen besteet niet.",
-       "pager-newer-n": "{{PLURAL:$1|1 niejere|$1 niejere}}",
+       "pager-newer-n": "{{PLURAL:$1|1 nyere|$1 nyere}}",
        "pager-older-n": "{{PLURAL:$1|1 oldere|$1 oldere}}",
        "suppress": "Toezicht",
        "querypage-disabled": "Disse spesiale zied is uutezet um prestasieredens.",
        "specialloguserlabel": "Uutvoerende gebruker:",
        "speciallogtitlelabel": "Dool (sydname of {{ns:user}}:gebrükersname vöär gebrüker):",
        "log": "Logboken",
-       "all-logs-page": "Alle publieke logboeken",
+       "all-logs-page": "Alle publike logboken",
        "alllogstext": "Dit is t kombinasielogboek van {{SITENAME}}.\nJe kunnen oek kiezen veur bepaolde logboeken en filteren op gebruker (heufdlettergeveulig) en titel (heufdlettergeveulig).",
        "logempty": "Der steet gien passende informasie in t logboek.",
        "log-title-wildcard": "Zeuk naor titels die beginnen mit disse tekste:",
        "showhideselectedlogentries": "Ekeuzen logboekregels laoten zien of verbargen",
-       "allpages": "Alle ziejen",
+       "allpages": "Alle syden",
        "nextpage": "Volgende zied ($1)",
        "prevpage": "Veurige zied ($1)",
        "allpagesfrom": "Laot ziejen zien vanaof:",
        "listgrouprights-addgroup-all": "Kan gebrukers bie alle groepen zetten",
        "listgrouprights-removegroup-all": "Kan gebrukers uut alle groepen haolen",
        "listgrouprights-addgroup-self": "Kan {{PLURAL:$2|groep|groepen}} bie de eigen gebruker doon: $1",
-       "listgrouprights-removegroup-self": "Kan {{PLURAL:$2|groep|groepen}} vortdoon van eigen gebruker: $1",
+       "listgrouprights-removegroup-self": "{{PLURAL:$2|Grup|Gruppen}} vordsmyten uut de eigen gebrukerskonto: $1",
        "listgrouprights-addgroup-self-all": "Kan alle groepen bie de eigen gebruker doon",
        "listgrouprights-removegroup-self-all": "Kan alle groepen vortdoon van eigen gebruker",
        "trackingcategories": "Volgkategorieën",
        "email-legend": "n Bericht sturen naor n aandere gebruker van {{SITENAME}}",
        "emailfrom": "Van:",
        "emailto": "An:",
-       "emailsubject": "Onderwarp:",
+       "emailsubject": "Underwarp:",
        "emailmessage": "Bericht:",
        "emailsend": "Versturen",
        "emailccme": "Stuur mien n kopie van dit bericht.",
        "removedwatchtext": "De zied \"[[:$1]]\" is van [[Special:Watchlist|joew volglieste]] aofehaold.",
        "watch": "Volgen",
        "watchthispage": "Volg disse zied",
-       "unwatch": "Niet volgen",
+       "unwatch": "Neet volgen",
        "unwatchthispage": "Niet volgen",
        "notanarticle": "Gien artikel",
        "notvisiblerev": "Bewarking is vortedaon",
        "enotif_body": "Huj $WATCHINGUSERNAME,\n\n$PAGEINTRO $NEWPAGE\n\nSamenvatting van de wieziging: $PAGESUMMARY $PAGEMINOREDIT\n\nKontaktgevevens van de auteur:\nNetpost: $PAGEEDITOR_EMAIL\nWiki: $PAGEEDITOR_WIKI\n\nJe kriegen veerder gien berichten, behalven a'j disse zied bezeuken terwiel je an-emeld bin. Op joew volglieste ku'j veur alle ziejen die'j volgen de waorschuwingsinstellingen deraof haolen.\n\nGroeten van t {{SITENAME}}-waorschuwingssysteem.\n\n--\nJe kunnen joew netpostinstellingen wiezigen op:\n{{canonicalurl:{{#special:Preferences}}}}\n\nJe kunnen de volgliestinstellingen wiezigen op:\n{{canonicalurl:{{#special:EditWatchlist}}}}\n\nJe kunnen de zied van joew volglieste aofhaolen deur op de volgende verwiezing te klikken:\n$UNWATCHURL\n\nOpmarkingen en veerdere hulpe:\n$HELPPAGE",
        "created": "an-emaakt",
        "changed": "ewiezigd",
-       "deletepage": "Vortdoon",
+       "deletepage": "Syde vordsmyten",
        "confirm": "Bevestigen",
        "excontent": "De tekste was: '$1'",
        "excontentauthor": "De tekste was: '$1' (zied an-emaakt deur: [[Special:Contributions/$2|$2]])",
        "exbeforeblank": "vöärdat disse syde leadigmaked wördde stünd hyr: '$1'",
-       "delete-confirm": "\"$1\" vortdoon",
-       "delete-legend": "Vortdoon",
-       "historywarning": "'''Waorschuwing''': de zied die'j vortdoon willen, hef $1 {{PLURAL:$1|versie|versies}}:",
+       "delete-confirm": "\"$1\" vordsmyten",
+       "delete-legend": "Vordsmyten",
+       "historywarning": "<strong>Wårsküwing:</strong> de syde dee jy vordsmyten willet, hevt $1 {{PLURAL:$1|versy|versys}}:",
        "historyaction-submit": "Bekiek",
        "confirmdeletetext": "Je staon op t punt n zied en de geschiedenisse dervan vort te doon.\nBevestig hieronder dat dit inderdaod de bedoeling is, da'j de gevolgen begriepen en dat t akkedeert mit t [[{{MediaWiki:Policy-url}}|beleid]].",
        "actioncomplete": "Uutevoerd",
        "deletecomment": "Reden:",
        "deleteotherreason": "Aandere/extra reden:",
        "deletereasonotherlist": "Aandere reden",
-       "deletereason-dropdown": "* Redens veur t vortdoon van ziejen\n** Spam\n** Vandalisme\n** Schending van auteursrechten\n** Op verzeuk van de auteur\n** Ebreuken deurverwiezing",
+       "deletereason-dropdown": "* Algemeyne readenen vöär vordsmyten\n** Späm\n** Vandalisme\n** Auteursrechtenschending\n** Up versöök van de autöör\n** Bröäken döärverwysing",
        "delete-edit-reasonlist": "Redens veur t vortdoon bewarken",
        "delete-toobig": "Disse zied hef n lange bewarkingsgeschiedenisse, meer as $1 {{PLURAL:$1|versie|versies}}.\nt Vortdoon van dit soort ziejen is mit rechten bepark um t per ongelok versteuren van de warking van {{SITENAME}} te veurkoemen.",
        "delete-warning-toobig": "Disse zied hef n lange bewarkingsgeschiedenisse, meer as $1 {{PLURAL:$1|versie|versies}}.\nWoart je: t vortdoon van disse zied kan de warking van de databanke van {{SITENAME}} versteuren.\nWees veurzichtig",
        "cantrollback": "De wiezigingen konnen niet hersteld wörden; der is mer 1 auteur.",
        "alreadyrolled": "Kan de leste wieziging van de zied [[:$1]] deur [[User:$2|$2]] ([[User talk:$2|Overleg]]{{int:pipe-separator}}[[Special:Contributions/$2|{{int:contribslink}}]]); niet weerummedreien.\nn Aander hef disse zied al bewarkt of hersteld naor n eerdere versie.\n\nDe leste bewarking op disse zied is edaon deur [[User:$3|$3]] ([[User talk:$3|Overleg]]{{int:pipe-separator}}[[Special:Contributions/$3|{{int:contribslink}}]]).",
        "editcomment": "De bewarkingssamenvatting was: <em>$1</em>.",
-       "revertpage": "Wiezigingen deur [[Special:Contributions/$2|$2]] hersteld tot de versie nao de leste wieziging deur [[User:$1|$1]]",
+       "revertpage": "Wysigingen döär [[Special:Contributions/$2|$2]] ([[User talk:$2|oaverleg]]) weaderümmedraid tot de lätste versy van [[User:$1|$1]]",
        "revertpage-nouser": "Wiezigingen deur n verbörgen gebruker weerummedreid naor de leste versie deur {{GENDER:$1|[[User:$1|$1]]}}",
        "rollback-success": "Wiezigingen van $1; weerummedreid naor de leste versie van $2.",
        "sessionfailure-title": "Sessiefout",
        "sessionfailure": "Der is n probleem mit joew anmeldsessie. De aksie is stop-ezet uut veurzörg tegen n beveiligingsrisico (dat besteet uut t meugelike \"kraken\" van disse sessie). Gao weerumme naor de veurige zied, laoj disse zied opniej en probeer t nog es.",
        "protectlogpage": "Beveiligingslogbook",
        "protectlogtext": "Hieronder staon de leste wiezigingen veur t blokkeren en vriegeven van artikels en ziejen.\nZie de [[Special:ProtectedPages|lieste mit ziejen die beveiligd bin]] veur t hele overzicht.",
-       "protectedarticle": "[[$1]] is beveiligd",
+       "protectedarticle": "hevt [[$1]] beveiligd",
        "modifiedarticleprotection": "beveiligingsnivo van \"[[$1]]\"  ewiezigd",
        "unprotectedarticle": "hef de beveiliging van \"[[$1]]\" deraof ehaold",
        "movedarticleprotection": "hef de beveiligingsinstellingen over-ezet van \"[[$2]]\" naor \"[[$1]]\"",
        "protect-locked-dblock": "Beveiligingsnivo's kunnen effen niet ewiezigd wörden umdat de databanke noen beveiligd is.\nHier staon de instellingen zo as ze noen bin veur de zied '''$1''':",
        "protect-locked-access": "Je hebben gien rechten um t beveilingsnivo van ziejen te wiezigen.\nHier staon de instellingen zo as ze noen bin veur de zied '''$1''':",
        "protect-cascadeon": "Disse zied wördt beveiligd, umdat t op-eneumen is in de volgende {{PLURAL:$1|zied|ziejen}} die beveiligd {{PLURAL:$1|is|bin}} mit de kaskadeopsie. Wiezigingen in t beveiligingsnivo van disse zied hebben gien invleud op de kaskadebeveiliging.",
-       "protect-default": "Veur alle gebrukers",
+       "protect-default": "Alle gebrukers tostån",
        "protect-fallback": "Allinnig gebrukers mit t recht \"$1\" toestaon",
        "protect-level-autoconfirmed": "Allinnig automaties bevestigden gebrukers toestaon",
        "protect-level-sysop": "Allinnig beheerders toestaon",
        "pagesize": "(byte)",
        "restriction-edit": "Bewark",
        "restriction-move": "Herneum",
-       "restriction-create": "Anmaken",
+       "restriction-create": "Upstellen",
        "restriction-upload": "Bestaand opsturen",
        "restriction-level-sysop": "helemaole beveiligd",
        "restriction-level-autoconfirmed": "semibeveiligd",
        "tooltip-namespace_association": "Vink dit vakjen an um ouk de oaverleg- en underwarpnaamruumde in te slüten dee by de selekteerde naamruumde höyret.",
        "blanknamespace": "(Höyvdnaamruumde)",
        "contributions": "{{GENDER:$1|Brukersbydragen}}",
-       "contributions-title": "Biedragen van $1",
+       "contributions-title": "Bydragen van $1",
        "mycontris": "Bydragen",
        "anoncontribs": "Bydragen",
-       "contribsub2": "Veur {{GENDER:$3|$1}} ($2)",
+       "contribsub2": "Vöär {{GENDER:$3|$1}} ($2)",
        "nocontribs": "Gien wiezigingen evunnen die an de estelde criteria voldoon.",
-       "uctop": "leste wieziging",
+       "uctop": "lätste wysiging",
        "month": "Månd:",
        "year": "Vanaf jår (en eyrer):",
-       "sp-contributions-blocklog": "blokkeerlogboek",
+       "sp-contributions-blocklog": "blokkeerlogbook",
        "sp-contributions-deleted": "vortedaone gebrukersbiedragen",
-       "sp-contributions-uploads": "nieje bestaanden",
-       "sp-contributions-logs": "logboeken",
+       "sp-contributions-uploads": "nye bestanden",
+       "sp-contributions-logs": "logboken",
        "sp-contributions-talk": "oaverleg",
        "sp-contributions-userrights": "gebrukersrechtenbeheer",
        "sp-contributions-blocked-notice": "Disse gebruker is op t moment eblokkeerd.\nDe leste regel uut t blokkeerlogboek steet hieronder as referensie:",
        "sp-contributions-blocked-notice-anon": "Dit IP-adres is eblokkeerd.\nDe leste regel uut t blokkeerlogboek steet as referensie",
-       "sp-contributions-search": "Zeuken naor biedragen",
-       "sp-contributions-username": "IP-adres of gebrukersnaam:",
-       "sp-contributions-toponly": "Allinnig de niejste versie laoten zien",
-       "sp-contributions-newonly": "Allinnig nieje ziejen laoten zien",
-       "sp-contributions-submit": "Zeuk",
+       "sp-contributions-search": "Söken nå bydragen",
+       "sp-contributions-username": "IP-adres of gebrukersname:",
+       "sp-contributions-toponly": "Allinnig de nyste versy låten seen",
+       "sp-contributions-newonly": "Allinnig nye syden låten seen",
+       "sp-contributions-submit": "Söken",
        "whatlinkshere": "Verwysingen hyrhinne",
        "whatlinkshere-title": "Syden dee nå \"$1\" verwyset",
        "whatlinkshere-page": "Syde:",
        "linkshere": "De volgende syden verwysen nå <strong>$2</strong>:",
-       "nolinkshere": "Gien enkele zied verwis naor '''$2'''.",
+       "nolinkshere": "Geen enkele syde verwist nå '''$2'''.",
        "nolinkshere-ns": "Gien enkele zied verwis naor '''$2''' in de ekeuzen naamruumte.",
        "isredirect": "döärverwysing",
        "istemplate": "invoogd as mal",
        "ipbenableautoblock": "De IP-adressen van disse gebruker vanzelf blokkeren",
        "ipbsubmit": "adres blokkeren",
        "ipbother": "Aandere tied",
-       "ipboptions": "2 uren:2 hours,1 dag:1 day,3 dagen:3 days,1 weke:1 week,2 weken:2 weeks,1 maond:1 month,3 maonden:3 months,6 maonden:6 months,1 jaor:1 year,onbeparkt:infinite",
+       "ipboptions": "2 üren:2 hours,1 dag:1 day,3 dagen:3 days,1 weake:1 week,2 weaken:2 weeks,1 månd:1 month,3 månden:3 months,6 månden:6 months,1 jår:1 year,unbegrensed:infinite",
        "ipbhidename": "Verbarg de gebrukersnaam in bewarkingen en liesten",
        "ipbwatchuser": "Gebrukerszied en overlegzied op volglieste zetten",
        "ipb-disableusertalk": "Veurkoemen dat disse gebruker tiejens de blokkering de eigen overlegzied kan bewarken",
        "ipusubmit": "Blokkering deraof haolen",
        "unblocked": "[[User:$1|$1]] is edeblokeerd",
        "unblocked-range": "$1 is edeblokkeerd",
-       "unblocked-id": "Blokkering $1 is op-eheven",
+       "unblocked-id": "Blokkade $1 is upheaven",
        "blocklist": "Gebrukers die eblokkeerd bin",
        "ipblocklist": "Gebrukers die eblokkeerd bin",
        "ipblocklist-legend": "n Eblokkeerden gebruker zeuken",
        "contribslink": "bydragen",
        "emaillink": "netpostbericht sturen",
        "autoblocker": "Vanzelf eblokkeerd umdat t IP-adres overenekömp mit t IP-adres van [[User:$1|$1]], die eblokkeerd is mit as reden: \"$2\"",
-       "blocklogpage": "Blokkeerlogboek",
+       "blocklogpage": "Blokkeerlogbook",
        "blocklog-showlog": "Disse gebruker is al eerder eblokkeerd.\nt Blokkeerlogboek steet hieronder as referensie:",
        "blocklog-showsuppresslog": "Disse gebruker is al eerder eblokkeerd en wele bewarkingen van disse gebruker bin verbörgen.\nt Logboek mit onderdrokten versies steet hieronder as referensie:",
-       "blocklogentry": "hef \"[[$1]]\"  eblokkeerd veur $2 $3",
+       "blocklogentry": "hevt \"[[$1]]\" blokkeerd mid as vervaltyd $2 $3",
        "reblock-logentry": "hef de instellingen veur de blokkering van [[$1]] ewiezigd t Löp noen of over $2 $3",
        "blocklogtext": "Hier zie'j n lieste van de leste blokkeringen en deblokkeringen. Automatiese blokkeringen en deblokkeringen koemen niet in t logboek te staon. Zie de [[Special:BlockList|blokkeerlieste]] veur de lieste van adressen die noen eblokkeerd bin.",
        "unblocklogentry": "blokkering van $1 is op-eheven",
        "tooltip-ca-undelete": "Haal n inhoald van disse ziede oet n emmer",
        "tooltip-ca-move": "Disse syde hernömen",
        "tooltip-ca-watch": "Voog disse syde to an juw volglyste",
-       "tooltip-ca-unwatch": "Smiet disse ziede van oewe voalglieste",
+       "tooltip-ca-unwatch": "Smyt disse syde van juw volglyste",
        "tooltip-search": "{{SITENAME}} döärsöken",
        "tooltip-search-go": "Gå nå een syde mid eksakt disse name as et besteyt",
        "tooltip-search-fulltext": "Söök nå syden wår disse tekst in steyt",
        "tooltip-ca-nstab-template": "Mal bekyken",
        "tooltip-ca-nstab-help": "Loat de hölpbladziede zeen",
        "tooltip-ca-nstab-category": "Låt de kategorysyde seen",
-       "tooltip-minoredit": "Markeer as n klaene wieziging",
+       "tooltip-minoredit": "Markeer as een kleine wysiging",
        "tooltip-save": "Wysigingen seakeren",
-       "tooltip-preview": "Bekyk juw wysigingen. Bruuk dit vöärdat jy seakeret.",
+       "tooltip-preview": "Bekyk een vöärbeald van juw wysigingen. Gebruuk dit vöärdat jy seakeret.",
        "tooltip-diff": "Låt seen welke wysigingen jy in de tekst maked hebbet.",
-       "tooltip-compareselectedversions": "Bekiek de verschillen tussen de ekeuzen versies.",
-       "tooltip-watch": "Voog disse ziede to an oew volglieste",
+       "tooltip-compareselectedversions": "De verskillen tüsken de twey köäsen versys van disse syde bekyken.",
+       "tooltip-watch": "Voog disse syde to an juw volglyste",
        "tooltip-watchlistedit-normal-submit": "Ziejen vortdoon",
        "tooltip-watchlistedit-raw-submit": "Volglieste biewarken",
        "tooltip-recreate": "Disse ziede opniej anmaken, ondanks t feit dat t vortdoan is.",
        "tooltip-upload": "Bestaanden opsturen",
        "tooltip-rollback": "\"Weaderümmedraien\" drait mid eyn klik de bewarking(en) van de lätste gebruker up disse syde terügge.",
-       "tooltip-undo": "As jy up \"weaderümmedraien\" klikket geyt et bewarkingsveld lös en kün jy een vöärige versy weaderümmesetten. Jy künnet in de bewarkingssamenvatting een readen upgeaven.",
+       "tooltip-undo": "\"Weaderümmedraien\" maakt disse bewarking ungedån en oapent et bewarkingsveld. Hyr kan in de bewarkingssamenvatting een readen upgeaven wörden.",
        "tooltip-preferences-save": "Vuurkeuren opsloan",
        "tooltip-summary": "Voor een korte samenvatting in",
        "interlanguage-link-title": "$1 – $2",
        "spam_blanking": "Alle wiezigingen mit n verwiezing naor $1 wörden vortehaold",
        "spam_deleting": "In alle versies staon verwiezingen naor $1. Zied vortedaon",
        "simpleantispam-label": "Antispamkontrole.\nHyr <strong>niks</strong> invüllen!",
-       "pageinfo-title": "Informasie over \"$1\"",
+       "pageinfo-title": "Informaty oaver \"$1\"",
        "pageinfo-not-current": "Disse gegevens bin allinnig beschikbaor veur disse versie.",
        "pageinfo-header-basic": "Basisinformaty",
        "pageinfo-header-edits": "Bewarkingsgeschiedenisse",
-       "pageinfo-header-restrictions": "Ziedbeveiliging",
+       "pageinfo-header-restrictions": "Sydbeveiliging",
        "pageinfo-header-properties": "Ziedeigenschappen",
        "pageinfo-display-title": "Weeregeven ziednaam",
        "pageinfo-default-sort": "Standard sorteerwieze",
-       "pageinfo-length": "Ziedlengte (in bytes)",
+       "pageinfo-length": "Sydlängde (in bytes)",
        "pageinfo-article-id": "Zied-ID",
-       "pageinfo-language": "Taal veur de zied",
+       "pageinfo-language": "Språke vöär de syde",
        "pageinfo-content-model": "Ziedinhoudsmodel",
-       "pageinfo-robot-policy": "Indexering deur bots",
+       "pageinfo-robot-policy": "Indeksering döär bots",
        "pageinfo-robot-index": "Toe-estaon",
        "pageinfo-robot-noindex": "Niet toe-estaon",
-       "pageinfo-watchers": "Antal ziedvolgers",
+       "pageinfo-watchers": "Antal sydvolgers",
        "pageinfo-few-watchers": "Minder as {{PLURAL:$1|één volger|$1 volgers}}",
-       "pageinfo-redirects-name": "t Antal deurverwiezingen naor disse zied",
+       "pageinfo-redirects-name": "Antal döärverwysingen nå disse syde",
        "pageinfo-subpages-name": "Onderziejen van disse zied",
        "pageinfo-subpages-value": "$1 ($2 {{PLURAL:$2|deurverwiezing|deurverwiezingen}}; $3 {{PLURAL:$3|niet-deurverwiezing|niet-deurverwiezingen}})",
        "pageinfo-firstuser": "Gebruker die de zied an-emaakt hef",
        "patrol-log-page": "Markeerlogboek",
        "patrol-log-header": "In dit logboek staon de versies die op nao-ekeken ezet bin.",
        "deletedrevision": "Vortedaone ouwe versie $1.",
-       "filedeleteerror-short": "Fout bie t vortdoon van bestaand: $1",
+       "filedeleteerror-short": "Faut by et vordsmyten van bestand: $1",
        "filedeleteerror-long": "Der waren fouten bie t vortdoon van t bestaand:\n\n$1",
        "filedelete-missing": "t Bestaand \"$1\" kan niet vortedaon wörden, umdat t niet besteet.",
        "filedelete-old-unregistered": "De an-egeven bestaandsversie \"$1\" steet niet in de databanke.",
        "tag-mw-removed-redirect": "Döärverwysing vordedån",
        "tag-mw-changed-redirect-target": "Döärverwysingsdool ewysigd",
        "tag-mw-blank": "Leadigmaked",
+       "tag-mw-undo": "Weaderümmedraid",
        "tags-title": "Etiket",
        "tags-intro": "Op disse zied staon de etiketten waormee de programmatuur elke bewarking kan markeren, en de betekenisse dervan.",
        "tags-tag": "Etiketnaam",
        "tags-active-no": "Nee",
        "tags-edit": "bewarking",
        "tags-hitcount": "$1 {{PLURAL:$1|wieziging|wiezigingen}}",
+       "tags-create-submit": "Upstellen",
        "comparepages": "Ziejen vergelieken",
        "compare-page1": "Zied 1",
        "compare-page2": "Zied 2",
        "htmlform-no": "Nee",
        "htmlform-yes": "Ja",
        "htmlform-chosen-placeholder": "Kies n opsie",
-       "logentry-delete-delete": "$1 hevt de syde $3 {{GENDER:$2|vorddån}}",
+       "logentry-delete-delete": "$1 hevt de syde $3 {{GENDER:$2|vordsmeaten}}",
+       "logentry-delete-delete_redir": "$1 hevt de döärverwysing $3 {{GENDER:$2|vordsmeaten}} döär et te oaverskryven",
        "logentry-delete-restore": "$1 {{GENDER:$2|hevt}} de syde $3 ($4) weaderümmesetted",
        "logentry-delete-event": "$1 hef de zichtbaorheid van {{PLURAL:$5|n logboekregel|$5 logboekregels}} van $3 {{GENDER:$2|ewiezigd}}: $4",
        "logentry-delete-revision": "$1 hef de zichtbaorheid van {{PLURAL:$5|een versie|$5 versies}} van de zied $3 {{GENDER:$2|ewiezigd}}: $4",
        "logentry-move-move_redir": "$1 hevt de syde $3 {{GENDER:$2|hernöömd}} nå $4 oaver een döärverwysing hinne",
        "logentry-move-move_redir-noredirect": "$1 hevt de syde $3 {{GENDER:$2|hernöömd}} nå $4 oaver een döärverwysing hinne sunder een döärverwysing achter te låten",
        "logentry-patrol-patrol": "$1 hef versie $4 van de zied $3 op {{GENDER:$2|nao-ekeken}} ezet",
-       "logentry-patrol-patrol-auto": "$1 hef versie $4 van de zied $3 automaties op {{GENDER:$2|nao-ekeken}} ezet",
+       "logentry-patrol-patrol-auto": "$1 {{GENDER:$2|hevt}} versy $4 van de syde $3 automatisk up {{GENDER:$2|nåkeaken}} setted",
        "logentry-newusers-newusers": "Gebruker $1 is {{GENDER:$2|an-emaakt}}",
        "logentry-newusers-create": "Brukerskonto $1 is {{GENDER:$2|anmaked}}",
        "logentry-newusers-create2": "Gebruker $3 is {{GENDER:$2|an-emaakt}} an-emaakt deur $1",
        "feedback-error2": "Fout: de bewarking is mislokt",
        "feedback-error3": "Fout: gien reaksie van de API",
        "feedback-message": "Bericht:",
-       "feedback-subject": "Onderwarp:",
+       "feedback-subject": "Underwarp:",
        "feedback-submit": "Opslaon",
        "feedback-thanks": "Bedankt! Joew kommentaar is op de zied \"[$2 $1]\" ezet.",
        "searchsuggest-search": "{{SITENAME}} döärsöken",
index c67bab3..6594f93 100644 (file)
        "group-user": "gebruikers",
        "group-autoconfirmed": "autobevestigde gebruikers",
        "group-bot": "bots",
-       "group-sysop": "beheerders",
+       "group-sysop": "beheyrders",
        "group-interface-admin": "interfacemoderatoren",
        "group-bureaucrat": "bureaucraten",
        "group-suppress": "toezichthouders",
index eb628a8..0642995 100644 (file)
        "createaccountmail": "ߓߍ߲߬ߛߋ߲߬ߡߊ߬ ߕߊߡߌ߲ߞߊ߲ ߕߎ߬ߡߊ߬ߞߎ߲߬ߡߊ ߟߊߓߊ߯ߙߊ߫ ߞߊ߬ ߓߊ߲߫ ߞߵߊ߬ ߗߋ߫ ߢߎߡߍߙߋ߲߫ ߞߏ߲ߘߏ߫ ߓߟߏߡߊߞߊ߬ߣߍ߲ ߡߊ߬.",
        "createaccountmail-help": "ߊ߬ ߕߍ߫ ߛߐ߲߬ ߠߊߓߊ߯ߙߊ߫ ߟߊ߫߸ ߞߊ߬ ߡߐ߰ ߜߘߍ߫ ߟߊ߫ ߖߊ߬ߕߋ߬ߘߊ ߛߌ߲ߘߌ߫߸ ߣߴߌ ߡߊ߫ ߕߊ߬ߡߌ߲߬ߞߊ߲ ߞߊ߬ߙߊ߲߬.",
        "createacct-realname": "ߕߐ߮ ߓߘߍ (ߛߎߥߊ߲ߘߟߌ)",
-       "createacct-reason": "ß\8a߬ ß\9bß\8aß\93ß\8eß«",
+       "createacct-reason": "ß\8a߬ ß\9eß\8e߲߭",
        "createacct-reason-ph": "ߡߎ߲߬ߠߊ߫ ߌ ߦߋ߫ ߖߊ߬ߕߋ߬ߘߊ߰ ߜߘߍ߫ ߛߌ߲ߘߌ߫ ߟߊ߫",
        "createacct-reason-help": "ߗߋߛߓߍ ߦߌ߬ߘߊ߬ ߖߊ߬ߕߋ߬ߘߊ ߛߌ߲ߘߟߌ ߘߊ߲ߖߐ ߘߐ߫",
        "createacct-submit": "ߖߊ߬ߕߋ߬ߘߊ ߘߏ߫ ߘߊߦߟߍ߬",
        "newarticle": "(ߞߎߘߊ)",
        "newarticletext": "ߌ ߓߘߊ߫ ߛߘߌ߬ߜߋ߲ ߘߏ߫ ߟߊߓߊ߬ߕߏ߬ ߞߐߜߍ ߘߏ߫ ߘߐ߫߸ ߡߍ߲ ߕߴߦߋ߲߬ ߡߎߣߎ߲߬.\nߣߵߌ ߦߴߊ߬ ߝߍ߫ ߞߊ߬ ߞߐߜߍ ߘߏ߫ ߟߊߘߊ߲߫߸ ߛߓߍߟߌ ߘߊߡߌ߬ߣߊ߬ ߘߎ߰ߟߊ߬ߘߐ߫ ߞߏ߲ߘߏ ߘߐ߫ (ߞߊ߬ [$1 ߘߍ߬ߡߍ߲߬ߠߌ߲ ߞߐߜߍ] ߦߋ߫߸ ߖߐ߲߬ߛߊ߬ ߌ ߘߌ߫ ߞߌ߬ߓߊ߬ߙߏ߬ ߖߐ߲ߖߐ߲ ߛߐ߬ߘߐ߲߬). ߣߵߌ ߘߏ߲߬ ߞߍ߫ ߘߊ߫ ߦߊ߲߬ ߝߎ߬ߕߎ߲߬ߕߌ߬ ߓߟߏߡߊ߬߸ ߌ ߟߊ߫ ߛߏ߲߯ߓߊߟߊ߲ <strong>back</strong> ߛߐ߲߬ߞߌ߲߫.",
        "anontalkpagetext": "----\n<em>ߓߊ߬ߘߏ߬ ߞߐߜߍ ߣߌ߲߬ ߦߋ߫ ߟߊߓߊ߯ߙߟߊ߫ ߟߐ߲ߓߊߟߌ ߟߋ߬ ߓߟߏ߫ ߡߍ߲ ߡߊ߫ ߖߊ߬ߕߋ߬ߘߊ߬ ߛߌ߲ߘߌ߫ ߡߎߣߎ߲߬ ߥߟߴߊ߬ ߕߍ߫ ߖߊ߬ߕߋ߬ߘߊ ߏ߬ ߟߊߓߊ߯ߙߊ߫ ߟߊ߫;</em>\nߏ߬ ߞߏߛߐ߲߬ ߊ߲ ߞߊ߫ ߞߊ߲߫ ߞߵߊ߬ ߟߊ߫ ߓߡ (ߓߟߐߟߐ ߡߛߍ߬ߞߍ߬ߡߛߍߞߍ) ߛߊ߲߬ߓߊ߬ߕߐ߮ ߟߊߓߊ߯ߙߴߊ߬ ߡߊߟߐ߲߫ ߞߊߡߊ߬߸ ߟߊߓߊ߯ߙߟߊ߫ ߛߌߦߊߡߊ߲߫ ߓߴߛߋ߫ ߞߊ߬ ߘߍ߬ ߓߡ ߛߊ߲߬ߓߊ߬ߕߐ߮ ߣߌ߲߬ ߢߐ߲߰ ߠߊ߫.\nߣߴߌ ߞߍ߫ ߘߊ߫ ߟߊߓߊ߯ߙߟߊ߫ ߡߊߝߟߌ߬ߣߍ߲߫ ߘߌ߫ ߞߵߊ߬ ߛߏ߬ߓߌ߬ ߞߏ߫ ߌ ߟߊ߫ ߞߊ߲߬ߞߎߡߊ ߟߎ߬ ߕߴߌ ߕߊ߫ ߘߌ߫ ߊ߬ ߘߌ߫ ߟߐ߬ ߌ ߡߊ߬ ߌߞߘߐ߫߸ ߌ ߖߏ߫ ߞߊ߬ [[Special:CreateAccount|ߖߊ߬ߕߋ߬ߘߊ ߘߏ߫ ߘߊߦߟߍ߬]] ߥߟߊ߫ [[Special:UserLogin|ߞߊ߬ ߘߏ߲߬ߕߐ߰ߟߊ߬ߘߏ߲ ߞߍ߫]] ߖߐ߲߬ߛߊ߫ ߟߏ߲ߘߐ߬ ߓߊߛߌ߯ߓߊߟߌߦߊ ߘߌ߫ ߡߟߊ߫ ߟߊߓߊ߯ߙߟߊ߫ ߡߊߟߐ߲ߓߊߟߌ߫ ߜߘߍ ߟߎ߬ ߓߟߏ߫.",
-       "noarticletext": "ß\9bß\93ß\8dß\9fß\8cß« ß\9bß\8cß« ß\95ß\8dß« ß\9eß\90ß\9cß\8d ß£ß\8c߲߭ ß\9eß\8a߲߬ ß\95ß\8b߲߫. ß\8c ß\98ß\8cß« ß\9bß\8bß« ß\9eß\90ß\9cß\8d ß£ß\8c߲߬ \n [[Special:Search/{{PAGENAME}}|search for this page title]] ß\95ß\90ß® ß¢ß\8cߣß\8c߲߫ ß ß\8aß« ß\9eß\90ß\9cß\8d ß\95ß\90ß­ ß\9fß\8e߬ ß\98ß\90ß«߸  \n<span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} search the related logs],\nor [{{fullurl:{{FULLPAGENAME}}|action=edit}} create this page]</span>.",
+       "noarticletext": "ß\9bß\93ß\8dß\9fß\8cß« ß\9bß\8cß« ß\95ß\8dß« ß\9eß\90ß\9cß\8d ß£ß\8c߲߭ ß\9eß\8a߲߬ ß\95ß\8b߲߬. ß\8c ß\98ß\8cß« ß\9bß\8bß« ß\9eß\90ß\9cß\8d ß£ß\8c߲߬.\n[[Special:Search/{{PAGENAME}}|search for this page title]] ß\95ß\90ß® ß¢ß\8cߣß\8c߲߫ ß ß\8aß« ß\9eß\90ß\9cß\8d ß\95ß\90ß­ ß\9fß\8e߬ ß¢ß\8aß\9dß\8d߬߸  \n<span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} search the related logs],\nor [{{fullurl:{{FULLPAGENAME}}|action=edit}} create this page]</span>.",
        "noarticletext-nopermission": "ߛߓߍߟߌ߫ ߛߌ߫ ߕߍ߫ ߞߐߜߍ ߣߌ߲߭ ߞߊ߲߬ ߕߋ߲߫.\nߌ ߘߌ߫ ߛߋ߫ [[Special:Search/{{PAGENAME}}|search for this page title]] ߢߌߣߌ߲߫ ߠߊ߫ ߞߐߜߍ ߕߐ߭ ߟߎ߬ ߘߐ߫߸ ߥߟߊ߫ <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} search the related logs]</span> ߞߏ߬ߣߌ߲߬ ߘߌ߬ߢߍ߬ ߞߍߣߍ߲߫ ߕߴߌ ߡߊ߬ ߞߐߜߍ߫ ߣߌ߲߬ ߠߊߞߊ߭ ߘߐ߫.",
        "userpage-userdoesnotexist": "ߖߊ߬ߕߋ߬ߘߊ߬ ߟߊߓߊ߯ߙߕߊ \"$1\" ߛߌ߲ߘߌߣߍ߲߫ ߕߍ߫. \nߝߛߍ߬ߝߛߍ߬ߟߌ ߞߍ߫߸ ߣߴߌ ߦߴߊ߬ ߝߍ߬ ߞߊ߬ ߞߐߜߍ ߣߌ߲߬ ߛߌ߲ߘߌ߫/ߡߊߦߟߍ߬ߡߊ߲߫.",
        "userpage-userdoesnotexist-view": "ߟߊ߬ߓߊ߰ߙߊ߬ ߖߊߕߋߘߊ \"$1\" ߟߊߞߎ߲߬ߘߎ߬ߣߍ߲߫ ߕߍ߫.",
        "group-autoconfirmed": "ߟߊ߬ߓߊ߰ߙߊ߬ߟߊ߬ ߞߍߒߖߘߍߦߋ߫ ߟߊߛߙߋߦߊߣߍ߲",
        "group-bot": "ߓߏߕ",
        "group-sysop": "ߞߎ߲߬ߠߊ߬ߛߌ߰ߟߊ",
+       "group-interface-admin": "ߢߐ߲߯ߕߍߞߣߍ ߓߟߏߓߌߟߊߢߐ߲߯ߞߊ߲ ߠߎ߬",
        "group-bureaucrat": "ߛߓߍߘߟߊߡߐ߮",
        "group-suppress": "ߛߎ߬ߔߙߋߛߐ߬",
        "group-all": "(ߊ߬ ߓߍ߯)",
        "group-autoconfirmed-member": "{{GENDER:$1|ߞߍߒߖߘߍߦߋ߫ ߟߊߛߙߋߦߊߟߌ ߟߊ߬ߓߊ߰ߙߊ߬ߟߊ}}",
        "group-bot-member": "{{GENDER:$1|ߓߏߕ}}",
        "group-sysop-member": "{{GENDER:$1|ߟߊ߬ߓߊ߰ߙߊ߬ߟߊ}}",
+       "group-interface-admin-member": "{{GENDER:$1|ߢߐ߲߯ߕߍߞߣߍ ߟߊ߬ߓߊ߰ߙߊ߬ߟߊ}}",
        "group-bureaucrat-member": "{{GENDER:$1|ߛߓߍߘߟߊߡߐ߮}}",
        "group-suppress-member": "{{GENDER:$1|ߖߏ߰ߛߟߌ߬ ߣߐ}}",
        "grouppage-user": "{{ns:project}}: ߟߊ߬ߓߊ߰ߙߊ߬ߟߊ",
        "recentchanges-label-unpatrolled": "ߡߊ߬ߦߟߍ߬ߡߊ߲߬ߠߌ߲ ߣߌ߲߬ ߡߊ߫ ߓߍ߬ߙߍ߲߬ߓߍ߬ߙߍ߲߬ ߡߎߣߎ߲߬",
        "recentchanges-label-plusminus": "ߞߐߜߍ ߢߊ߲ߞߊ߲ ߓߘߊ߫ ߡߊߦߟߍ߬ߡߊ߲߫ ߞߵߊ߬ ߝߌ߬ߘߊ߲ ߦߙߌߞߊ ߣߌ߲߬ ߘߌ߫",
        "recentchanges-legend-heading": "<strong>ߡߊ߬ߛߙߋ:</strong>",
-       "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (ߣß\8c߲߬ ß\9dߣß\8aß« ß¦ß\8bß« \n[[Special:NewPages|list of new pages]])",
+       "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (ߣß\8c߲߬ ß\9dߣß\8aß« ß\93ߴߦß\8b߲߬ [[Special:NewPages|list of new pages]])",
        "recentchanges-submit": "ߊ߬ ߦߌ߬ߘߊ߬",
        "rcfilters-tag-remove": "$1 ߛߋ߲߬ߓߐ߫",
        "rcfilters-legend-heading": "<strong>ߟߊ߬ߘߛߏ߬ߟߌ ߛߙߍߘߍ</strong>",
        "confirm-mcrundo-title": "ߡߊ߬ߦߟߍ߬ߡߊ߲߬ߠߌ߲ ߓߐ߫ ߊ߬ ߡߊ߬",
        "mcrundofailed": "ߓߐߒߡߊߟߌ ߓߘߊ߫ ߗߌߙߏ߲߫",
        "mcrundo-missingparam": "ߢߌ߬ߣߊ߬ ߓߘߊ߫ ߞߍ߫ ߟߊ߬ߓߍ߲߬ߢߐ߲߰ߡߊ ߡߊߢߌ߬ߣߌ߲߬ߞߊ߬ߣߍ߲ ߞߐ߫ ߡߞߊ߬ߛߌ߬ߟߌ ߘߐ߫",
-       "parentheses-start": "⸜",
-       "parentheses-end": "⸝",
        "quotation-marks": "\"$1\"",
        "imgmultipageprev": "ߞߐߜߍ ߢߍߕߊ",
        "imgmultipagenext": "ߞߐߜߍ ߣߊ߬ߕߐ ←",
index d235fec..5d631a7 100644 (file)
        "perfcached": "Poniższe dane są kopią z pamięci podręcznej i mogą być nieaktualne. W pamięci podręcznej {{PLURAL:$1|znajduje|znajdują|znajduje}} się maksymalnie {{PLURAL:$1|jeden wynik|$1 wyniki|$1 wyników}}.",
        "perfcachedts": "Poniższe dane są kopią z pamięci podręcznej. Ostatnia aktualizacja odbyła się o $1. W pamięci podręcznej {{PLURAL:$4|znajduje|znajdują|znajduje}} się maksymalnie {{PLURAL:$4|jeden wynik|$4 wyniki|$4 wyników}}.",
        "querypage-no-updates": "Uaktualnienia dla tej strony są obecnie wyłączone. Znajdujące się tutaj dane nie zostaną odświeżone.",
+       "querypage-updates-periodical": "Aktualizacje tej strony wykonywane są cyklicznie.",
        "viewsource": "Tekst źródłowy",
        "viewsource-title": "Tekst źródłowy strony $1",
        "actionthrottled": "Akcja wstrzymana",
index 55ab67b..5e47a99 100644 (file)
        "perfcached": "Os seguintes dados encontram-se armazenados na ''cache'' e podem não estar atualizados. No máximo {{PLURAL:$1|um resultado está disponível|$1 resultados estão disponíveis}} na ''cache''.",
        "perfcachedts": "Os seguintes dados encontram-se armazenados no ''cache'' e foram atualizados as $1. No máximo {{PLURAL:$4|um resultado está disponível|$4 resultados estão disponíveis}} no ''cache''.",
        "querypage-no-updates": "Momentaneamente as atualizações para esta página estão desativadas. Por enquanto, os dados aqui presentes não poderão ser atualizados.",
+       "querypage-updates-periodical": "As atualizações para esta página são executadas periodicamente.",
        "viewsource": "Ver código-fonte",
        "viewsource-title": "Exibir código-fonte para $1",
        "actionthrottled": "Ação controlada",
index afbfd94..4fa60a2 100644 (file)
        "perfcached": "Like {{msg-mw|perfcachedts}} but used when we do not know how long ago page was cached (unlikely to happen).\n\nParameters:\n* $1 - the max result cut off ($wgQueryCacheLimit)",
        "perfcachedts": "Used on pages that list page lists for which the displayed data is cached. Parameters:\n* $1 - a time stamp (date and time combined)\n* $2 - a date (optional)\n* $3 - a time (optional)\n* $4 - the cut off limit for cached results ($wgQueryCacheLimit). If there are more then this many results for the query, only the first $4 of those will be listed on the page. Usually $4 is about 1000.",
        "querypage-no-updates": "Text on some special pages, e.g. [[Special:FewestRevisions]].",
+       "querypage-updates-periodical": "Text on some special pages which are configurated with a periodical run of a maintenance script.\n\nSee also {{msg-mw|querypage-no-updates}}.",
        "viewsource": "The text displayed in place of the {{msg-mw|Edit}} tab when the user has no permission to edit the page.\n\nSee also:\n* {{msg-mw|Viewsource}}\n* {{msg-mw|Accesskey-ca-viewsource}}\n* {{msg-mw|Tooltip-ca-viewsource}}\n{{Identical|View source}}",
        "viewsource-title": "Page title shown when trying to edit a protected page. Parameters:\n* $1 - the name of the page",
        "actionthrottled": "This is the title of an error page. Read it in combination with {{msg-mw|actionthrottledtext}}.",
        "recentchanges-label-unpatrolled": "Tooltip for {{msg-mw|unpatrolledletter}}",
        "recentchanges-label-plusminus": "Legend item for plus/minus.\n\nPreceded by legend example {{msg-mw|Recentchanges-legend-plusminus}}.",
        "recentchanges-legend-heading": "Used as a heading for legend box on [[Special:RecentChanges]] and [[Special:Watchlist]].\n{{Identical|Legend}}",
-       "recentchanges-legend-newpage": "{{doc-important|Do not translate <code>Special:NewPages</code>.}}\nUsed as legend on [[Special:RecentChanges]] and [[Special:Watchlist]].\n\nRefers to {{msg-mw|Recentchanges-label-newpage}}.",
+       "recentchanges-legend-newpage": "{{doc-important|Do not translate <code>Special:NewPages</code>.}} (But ''do'' translate \"list of new pages\".)\n\nUsed as legend on [[Special:RecentChanges]] and [[Special:Watchlist]].\n\nRefers to {{msg-mw|Recentchanges-label-newpage}}.",
        "recentchanges-legend-minor": "Used as legend on [[Special:RecentChanges]] and [[Special:Watchlist]].\n\nRefers to {{msg-mw|Recentchanges-label-minor}}.",
        "recentchanges-legend-bot": "Used as legend on [[Special:RecentChanges]] and [[Special:Watchlist]].\n\nRefers to {{msg-mw|Recentchanges-label-bot}}.",
        "recentchanges-legend-unpatrolled": "Used as legend on [[Special:RecentChanges]] and [[Special:Watchlist]].\n\nRefers to {{msg-mw|Recentchanges-label-unpatrolled}}.",
        "version-poweredby-credits": "Message shown on [[Special:Version]]. Parameters:\n* $1 - the current year\n* $2 - a list of selected MediaWiki authors",
        "version-poweredby-others": "Used at the end of {{msg-mw|version-poweredby-credits}} on [[Special:Version]]. First, there's a long list of selected MediaWiki authors, then a comma and then this translation, which is supposed to credit the many other people than developer helping with MediaWiki.\n{{Identical|Other}}",
        "version-poweredby-translators": "Used as label for a link to [[Translating:MediaWiki/Credits]].\n\nPreceded by {{msg-mw|version-poweredby-others}} and {{msg-mw|and}}.\n\nUsed at the end of {{msg-mw|version-poweredby-credits}} on [[Special:Version]].",
+       "version-poweredby-various": "Shown on [[Special:Version]] as an author name if the extension or skin (etc.) credits contain only <code>...</code> which is used to indicate various (unknown or unspecified) authors. See also {{msg-mw|version-poweredby-others}}, which is used when an extension or a skin contains code by various named and unnamed contributors.",
        "version-credits-summary": "Summary of the [[Special:Version/Credits]] sub page, which lists all developers etc. who contributed to MediaWiki. Shown at the top.",
        "version-license-info": "[[wikipedia:GNU GPL|GNU GPL]] notice shown at [[Special:Version]]. See //www.gnu.org/licenses/old-licenses/gpl-2.0-translations.html for available translations.",
        "version-software": "Message shown on [[Special:Version]].\nThis message is followed by the list of installed software (MediaWiki, PHP and MySQL).",
index d3475a5..256a9f2 100644 (file)
        "perfcached": "Следующие данные были взяты из кэша и могут быть устаревшими. В кэше хранится не более $1 {{PLURAL:$1|записи|записей}}.",
        "perfcachedts": "Данные взяты из кэша; последний раз он обновлялся в $1. В кэше хранится не более {{PLURAL:$4|1=одной записи|$4 записи|$4 записей}}.",
        "querypage-no-updates": "Обновление этой страницы сейчас отключено.\nПредставленные здесь данные не будут обновляться.",
+       "querypage-updates-periodical": "Обновления для этой страницы выполняются периодически.",
        "viewsource": "Просмотр кода",
        "viewsource-title": "Просмотр кода страницы $1",
        "actionthrottled": "Ограничение по скорости",
index 756ee8a..c065f99 100644 (file)
        "perfcached": "Sledeći podaci su keširani i mogu biti zastareli. Keš sadrži najviše {{PLURAL:$1|jedan rezultat|$1 rezultata|$1 rezultata}}.",
        "perfcachedts": "Sledeći podaci su keširani, a poslednji put su ažurirani $2 u $3. Keš sadrži najviše {{PLURAL:$4|jedan rezultat|$4 rezultata|$4 rezultata}}.",
        "querypage-no-updates": "Ažuriranje ove stranice je isključeno.\nPodaci koji se ovdje nalaze neće biti biti ažurirani.",
+       "querypage-updates-periodical": "Podnove na ovu stranicu se pokretaju povremeno.",
        "viewsource": "Izvor/Извор",
        "viewsource-title": "Prikaz izvora stranice $1",
        "actionthrottled": "Akcija je usporena",
index d9be5c2..8370f01 100644 (file)
        "perfcached": "Navedeni podatki so shranjeni v predpomnilniku in morda niso popolnoma posodobljeni. V predpomnilniku {{PLURAL:$1|je|sta|so|je}} na razpolago največ $1 {{PLURAL:$1|rezultat|rezultata|rezultate|rezultatov}}.",
        "perfcachedts": "Prikazani podatki so shranjeni v predpomnilniku in so bili zadnjič osveženi $1. V predpomnilniku {{PLURAL:$4|je|sta|so|je}} na razpolago največ $4 {{PLURAL:$4|rezultat|rezultata|rezultate|rezultatov}}.",
        "querypage-no-updates": "Posodobitve za to stran so trenutno onemogočene. Tukajšnji podatki se v kratkem ne bodo osvežili.",
+       "querypage-updates-periodical": "Posodobitve za to stran se poganjajo periodično.",
        "viewsource": "Izvorno besedilo",
        "viewsource-title": "Ogled vira $1",
        "actionthrottled": "Dejanje zaustavljeno",
index 9c65b81..f28ce2d 100644 (file)
        "createaccountmail": "Користи привремену, насумичну лозинку и пошаљи је на наведену е-адресу",
        "createaccountmail-help": "Може се користити да се некоме отвори налог без сазнања лозинке.",
        "createacct-realname": "Право име (опционално)",
-       "createacct-reason": "Разлог",
+       "createacct-reason": "Разлог (јавно се бележи)",
        "createacct-reason-ph": "Зашто отварате још један налог",
        "createacct-reason-help": "Порука која се приказује у дневнику отварања налога",
        "createacct-submit": "Отвори налог",
index af8170c..3dacfee 100644 (file)
        "createaccountmail": "Använd ett tillfälligt slumpvis valt lösenord och skicka det till den angivna e-postadressen",
        "createaccountmail-help": "Kan användas för att skapa ett konto åt en annan person utan att kunna lösenordet.",
        "createacct-realname": "Riktigt namn (valfritt)",
-       "createacct-reason": "Orsak",
+       "createacct-reason": "Orsak (loggas offentligt)",
        "createacct-reason-ph": "Varför du skapar ett annat konto",
        "createacct-reason-help": "Meddelande som visas i loggen för skapade konton",
        "createacct-submit": "Skapa ditt konto",
        "listfiles-userdoesnotexist": "Användarkontot \"$1\" är inte registrerat.",
        "imgfile": "fil",
        "listfiles": "Fillista",
+       "listfiles_subpage": "Uppladdningar av $1",
        "listfiles_thumb": "Miniatyrbild",
        "listfiles_date": "Datum",
        "listfiles_name": "Namn",
        "mycustomjsredirectprotected": "Du har inte behörighet att redigera denna JavaScript-sida eftersom det är en omdirigering och leder inte någonstans inom din användarnamnrymd.",
        "easydeflate-invaliddeflate": "Innehåll som tillhandahålls är inte helt komprimerat",
        "unprotected-js": "Av säkerhetsskäl kan inte JavaScript läsas in från oskyddade sidor. Skapa endast JavaScript i namnrymden MediaWiki: eller som en användarundersida.",
-       "userlogout-continue": "Vill du logga ut?"
+       "userlogout-continue": "Vill du logga ut?",
+       "rest-prefix-mismatch": "Den begärda sökvägen ($1) fanns inte inuti rotsökvägen för REST API ($2)",
+       "rest-wrong-method": "Den begärda metoden ($1) var inte {{PLURAL:$3|den tillåtna metoden för denna sökväg|en av de tillåtna metoderna för denna sökväg}} ($2)",
+       "rest-no-match": "Den begärda relativa sökvägen ($1) matchade inte några kända hanterare"
 }
index 14aba57..d0f0c1d 100644 (file)
@@ -25,8 +25,8 @@
                        "Vlad5250"
                ]
        },
-       "tog-underline": "Podsztrychniyniy linkōw:",
-       "tog-hideminor": "Schŏw drobne pōmiany we niydŏwno pōmiynianych",
+       "tog-underline": "Podkryślynie linkōw:",
+       "tog-hideminor": "Skryj małe edycyje we ôstatnich zmianach",
        "tog-hidepatrolled": "Schŏw przichwŏlōne pōmiany we niydŏwno pōmiynianych",
        "tog-newpageshidepatrolled": "Schŏw przichwŏlōne zajty na wykŏzie nowych zajtōw",
        "tog-extendwatchlist": "We ôbserwowanych pokazuj wszyjske zmiany, a niy ino ôstatnie",
        "create-local": "Wkludź lokalny ôpis",
        "delete": "Skasuj",
        "undelete_short": "Wćep nazod {{PLURAL:$1|jedna wersyjo|$1 wersyje|$1 wersyji}}",
-       "viewdeleted_short": "{{PLURAL:$1|jedna wyćepano wersyjo|$1 wyćepane wersyje|$1 wyćepanych wersyjůw}}",
+       "viewdeleted_short": "{{PLURAL:$1|jednã skasowanõ wersyjõ|$1 skasowane wersyje|$1 skasowanych wersyji}}",
        "protect": "Zawrzij",
        "protect_change": "půmjyń",
        "unprotect": "Uodymkńij",
        "collapsible-expand": "Pokŏż",
        "thisisdeleted": "Pokŏzać abo stworzić zaś $1?",
        "viewdeleted": "Uobejrzij $1",
-       "restorelink": "{{PLURAL:$1|jedna wyćepano wersyjo|$1 wyćepane wersyje|$1 wyćepanych wersyjůw}}",
+       "restorelink": "{{PLURAL:$1|jednã skasowanõ wersyjõ|$1 skasowane wersyje|$1 skasowanych wersyji}}",
        "feedlinks": "Kanały:",
        "feed-invalid": "Ńywłaściwy typ kanałů informacyjnygo.",
        "feed-unavailable": "Kanoły informacyjne ńy sům dostympne",
        "viewsourcetext": "Możesz ôglōndać i kopiować zdrzōdło tyj strōny.",
        "viewyourtext": "We tekst zdrzůduowy tyj zajty możno dali filować, idźe go tyż kopjować.",
        "protectedinterface": "Na tyj zajće znojduje śe tekst interfejsu uoprogramowańo, bestůż uůna je zawarto uod sprowjańo. Coby doćepnůńć abo sprowjić tůmaczyńa wszyskich serwerůw, użyj [https://translatewiki.net/ translatewiki.net], průjyktu lokalizacyji MediaWiki.",
-       "editinginterface": "''''Dej pozůr:''' Sprowjosz zajta, na keryj je tekst interfejsu uoprogramowańo. Pomjyńyńa na tyj zajće zmjyńům wyglůnd interfejsu lo inkszych użytkowńikůw. Coby doćepnůńć abo sprowjić tůmaczyńa, użyj [https://translatewiki.net/wiki/Main_Page?setlang=szl translatewiki.net].",
+       "editinginterface": "<strong>Pozōr:</strong> Edytujesz strōnã, co je używanŏ do definiowaniŏ interfejsu ôprogramowaniŏ. Zmiany na tyj strōnie bydōm mieć wpływ na wyglōnd interfesu używŏcza u wszyjskich inkszych używŏczōw na tyj wiki.",
        "cascadeprotected": "Ta zajta je chrōniōnŏ ôd edycyje, skuli tego co je ôna wkludzōnŏ do {{PLURAL:$1|nastympujōncyj zajty, kerŏ ôstała ôchrōniōnŏ|nastympujōncych zajtach, kere ôstały ôchrōniōne}} ze załōnczōnōm ôpcyjōm erbowaniŏ:\n$2",
        "namespaceprotected": "Ńy mosz uprowńyń, coby sprowjać zajty we raumje mjan '''$1'''.",
        "customcssprotected": "Ńy mosz uprawńyń do sprowjańo tyj zajty, bo na ńij sům uosobiste sztalowańo inkszego użytkowńika.",
        "nouserspecified": "Musisz podać miano ôd używŏcza.",
        "login-userblocked": "Tyn sprowjorz mo zawarte sprowjyńa. Ńy idźe śe zalogować.",
        "wrongpassword": "Wkludzōny login abo hasło sōm felerne.\nSprōbuj zaś.",
-       "wrongpasswordempty": "Hasło kere żeś podou je uostawjůne blank. Naszkryflej je jeszcze roz.",
-       "passwordtooshort": "Hasło kere żeś podoł je felerne abo za krůtke.\nHasło muśi mjeć przinojmńij {{PLURAL:$1|1 buchsztaba|$1 buchsztabůw}} a być inksze uod mjana użytkowńika.",
+       "wrongpasswordempty": "Wkludzōne hasło je prōzne.\nSprōbuj zaś.",
+       "passwordtooshort": "Hasło musi mieć aby {{PLURAL:$1|znak|znaki|znakōw}}.",
        "password-name-match": "Hasło mo być inksze atoli mjano używocza.",
        "password-login-forbidden": "Używanie tego miana ôd używŏcza i hasła było zakŏzane.",
        "mailmypassword": "Wyczyść hasło",
        "emailauthenticated": "Twůj ausdruk e-brifa zostoł powjerzitelńůny $2 uo $3.",
        "emailnotauthenticated": "Twůj adres e-brifa ńy je powjerzitelńůny. Půniższe funkcyje poczty ńy dźołajům.",
        "noemailprefs": "Muśisz podać adres e-brifa, coby te funkcyje dźołały.",
-       "emailconfirmlink": "Potwjyrdź swůj adres e-brifa",
+       "emailconfirmlink": "Potwiyrdź swoja adresa e-mail",
        "invalidemailaddress": "E-brif ńy bydźe zaakceptůwany skiż tygo co jigo format ńy spełńo formalnych wymagań. Prosza naszkryflać poprowny adres e-brifa abo wyczyśćić pole.",
        "cannotchangeemail": "Ńy możno pomjyńyc ausdruku e-mail.",
        "emaildisabled": "Ta zajta ńy je mogebna posyłać e-brify.",
        "createacct-another-realname-tip": "Wszkryflańy twojigo mjana a nazwiska ńy je końyczne.\nKej bydźesz chćoł je podoć, bydům użyte, coby dokůmyntowoć Twoje autorstwo.",
        "pt-login": "Wloguj sie",
        "pt-login-button": "Wloguj sie",
+       "pt-login-continue-button": "Kōntynuuj logowanie",
        "pt-createaccount": "Twōrz nowe kōnto",
        "pt-userlogout": "Ôdloguj sie",
        "php-mail-error-unknown": "Ńyznany feler we funkcyji mail()",
        "resetpass_header": "Zmiyń hasło kōnta",
        "oldpassword": "Stare hasło",
        "newpassword": "Nowe hasło",
-       "retypenew": "Naszkryflej jeszcze roz nowe hasło:",
+       "retypenew": "Wkludź hasło na nowo:",
        "resetpass_submit": "Nasztaluj hasło a zaloguj",
        "changepassword-success": "Twoje hasło zostoło půmyślńy půmjyńone!",
        "botpasswords": "Hasła bota",
        "resetpass-wrong-oldpass": "Felerne tymczasowe abo aktualne hasło.\nMożliwe co właśńy zmjyńiłżeś swoje hasło abo poprosiłżeś uo nowe tymczasowe hasło.",
        "resetpass-temp-password": "Tymczasowe hasło:",
        "resetpass-abort-generic": "Půmjyńańe hasła uostoła zatrzimane bez rozszyrzyńe.",
+       "resetpass-validity": "Twoje hasło je niynŏleżne: $1\n\nNasztaluj nowe hasło, żeby sie zalogować.",
        "passwordreset": "Wysnŏż hasło",
        "passwordreset-disabled": "No tyj wiki zamkńynto resytowańy hasył.",
        "passwordreset-username": "Miano ôd używŏcza:",
        "revdelete-concurrent-change": "Feler przi modyfikacyji elymyntu ze $2 $1: Wyglōndŏ na to, że jego status bōł zmiyniōny ôd kogoś w czasie Twojij roboty.\nWejzdrzij do regestu.",
        "revdelete-only-restricted": "Ńy do śe ukryć tajli $2, $1 przed administracyjom. Wybjer jydnom ze uopcyji.",
        "revdelete-reason-dropdown": "* Kůmyntorze lo wyćepańa\n** NPA\n** Prywatność",
-       "revdelete-otherreason": "Inkszy/dodatkowy powůd:",
+       "revdelete-otherreason": "Inkszy/ekstra powōd:",
        "revdelete-reasonotherlist": "Inkszy powůd",
        "revdelete-edit-reasonlist": "Sprowjańe powodůw wyćepańo zajty",
        "revdelete-offender": "Autor wersyji:",
        "filerevert-badversion": "Ńy ma sam popředńij lokalnyj wersyji tygo plika s podanům datům.",
        "filedelete": "Wyćepańe $1",
        "filedelete-legend": "Wyćep plik",
-       "filedelete-intro": "Wyćepuješ '''[[Media:$1|$1]]'''.",
+       "filedelete-intro": "Chcesz skasować zbiōr '''[[Media:$1|$1]]''' społym ze jego cołkōm historyjōm.",
        "filedelete-intro-old": "Wyćepuješ wersyja plika '''[[Media:$1|$1]]''' s datům [$4 $3, $2].",
-       "filedelete-comment": "Čymu:",
+       "filedelete-comment": "Powōd:",
        "filedelete-submit": "Wyćep",
        "filedelete-success": "Wyćepano plik '''$1'''.",
        "filedelete-success-old": "Wyćepano plik '''[[Media:$1|$1]]''' we wersyje ze $3, $2.",
        "enotif_body": "Drogi/o $WATCHINGUSERNAME,\n\nzajta $PAGETITLE we {{GRAMMAR:MS.lp|{{SITENAME}}}} zostoua $CHANGEDORCREATED $PAGEEDITDATE bez užytkowńika $PAGEEDITOR. Uobejřij na zajće $PAGETITLE_URL aktualno wersja.\n\n$NEWPAGE\n\nOpis pomjyńeńa: $PAGESUMMARY $PAGEMINOREDIT\n\nSkůntaktuj śe s autorym:\ne-brif: $PAGEEDITOR_EMAIL\nwiki: $PAGEEDITOR_WIKI\n\nW připadku kolejnych půmjyńań nowe powjadůmjyńo ńy bydům wysuane, dopůki ńy uodwjydziš tyi zajty.\nMožeš tyž zresetować wšyjstke flagi powjadůmjyń na swojej liśće zajtůw, na kere dowoš pozůr.\n\n\tWjadůmość systymu powjadůmjyń {{GRAMMAR:D.lp|{{SITENAME}}}}\n\n--\nKejbyś chćou půmjyńić štalowańo swojej listy zajtůw, na kere dowoš pozůr, uodwjydź\n{{canonicalurl:{{#special:EditWatchlist}}}}\n\nPomoc:\n$HELPPAGE",
        "created": "utwořono",
        "changed": "pomjyńono",
-       "deletepage": "Wyćep artikel",
-       "confirm": "Potwjyrdź",
+       "deletepage": "Skasuj artykuł",
+       "confirm": "Potwiyrdź",
        "excontent": "zawartość zajty „$1”",
        "excontentauthor": "treść: „$1” (jedyny aůtor: [[Special:Contributions/$2|$2]])",
        "exbeforeblank": "zawartość przed ôprōzniyniym: „$1”",
        "dellogpagetext": "To je lista uostatńo wykůnanych wyćepań.",
        "deletionlog": "regest skasowań",
        "reverted": "Prziwrōcōnŏ poprzedniõ wersyjõ",
-       "deletecomment": "Čymu:",
+       "deletecomment": "Powōd:",
        "deleteotherreason": "Inkšy powůd:",
-       "deletereasonotherlist": "Inkszy powůd",
+       "deletereasonotherlist": "Inkszy powÅ\8dd",
        "deletereason-dropdown": "* Nojczynstsze prziczyny wyćepańa\n** Prośba autora\n** Naruszyńy praw autorskych\n** Wandalizm",
        "delete-edit-reasonlist": "Sprowjańe listy powodůw wyćepańo zajty",
-       "delete-toobig": "Ta zajta mo fest dugo historyja sprowjyń, wjyncyj jak $1 {{PLURAL:$1|půmjyńańy|půmjyńańo|půmjyńań}}.\nJeij wyćepańy mogło by spowodować zakłucyńo we dźołańu {{GRAMMAR:D.lp|{{SITENAME}}}} a bez tůż zostało uograńiczůne.",
-       "delete-warning-toobig": "Ta zajta mo fest dugo historia sprowjyń, wjyncy kej $1 {{PLURAL:$1|půmjyńeńe|půmjyńańo|půmjyńań}}.\nDej pozůr, bo jei wyćepańe może spowodować zakłůcyńo w pracy {{GRAMMAR:D.lp|{{SITENAME}}}}.",
+       "delete-toobig": "Te strōna mŏ dugõ historyjõ edycyji, bez $1 {{PLURAL:$1|wersyjõ|wersyje|wersyji}}.\nKasowanie takich strōn je ôgraniczōne, żeby ôchrōnić {{GRAMMAR:D.lp|{{SITENAME}}}} przed przipadkowym zeszterowaniym.",
+       "delete-warning-toobig": "Ta strōna mŏ dugõ historyjõ edycyji, bez $1 {{PLURAL:$1|wersyjŏ|wersyje|wersyji}}.\nSkasowanie jij może zeszterować ôperacyje bazy danych {{GRAMMAR:D.lp|{{SITENAME}}}}; postympuj pozornie.",
        "rollback": "Wycofej sprowjyńe",
        "rollbacklink": "cŏfej",
        "rollbacklinkcount": "cŏfnij $1 {{PLURAL:$1|edycyjõ|edycyje|edycyji}}",
        "movedarticleprotection": "przekludzůno sztalowańa zabezpjeczyńo s „[[$2]]” ku „[[$1]]”",
        "protect-title": "Zmiana poziōmu zawarciŏ „$1”",
        "prot_1movedto2": "[[$1]] přećepano do [[$2]]",
-       "protect-legend": "Potwjyrdź zawarće",
-       "protectcomment": "Čymu:",
+       "protect-legend": "Potwiyrdź zawarcie",
+       "protectcomment": "Powōd:",
        "protectexpiry": "Wygasŏ:",
-       "protect_expiry_invalid": "Čas wygaśńjyńćo je zuy.",
+       "protect_expiry_invalid": "Czas wygaśniyńciŏ je niynŏleżny.",
        "protect_expiry_old": "Čas wygaśńjyńćo je w downiej ńiž terozki.",
        "protect-text": "Sam możesz ôbejzdrzeć i zmiynić poziōmy zawarciŏ strōny <strong>$1</strong>.",
        "protect-locked-blocked": "Ńy možeš půmjyńać poźůmůw zawarćo kej žeś sům je zawarty uod sprowjyń. Terozki štalowańa dla zajty '''$1''' to:",
        "protect-cascadeon": "Ta zajta je zawarto od pomjyńań, po takjymu, co jei užywo {{PLURAL:$1|ta zajta, kero je zawarto|nastympůjůnce zajty, kere zostauy zawarte}} a opcyjo dźedźičyńo je zaůončono. Možeš pomjyńyć poziům zawarcia tyi zajty, ale dlo dźedźičyńo zawarcia to ńy mo wpuywu.",
        "protect-default": "Przizwolōne wszyjskim",
        "protect-fallback": "Wymago pozwolynjo \"$1\"",
-       "protect-level-autoconfirmed": "Blokuj nowe a ńyregistrowane używocze",
-       "protect-level-sysop": "Ino admini",
-       "protect-summary-cascade": "dźedźičyńy",
+       "protect-level-autoconfirmed": "Przizwōl ino autōmatycznie potwiyrdzōnym używŏczōm",
+       "protect-level-sysop": "Przizwōl ino administratorōm",
+       "protect-summary-cascade": "erbowanie",
        "protect-expiring": "wygaso $1 (UTC)",
-       "protect-expiry-indefinite": "na zowdy",
+       "protect-expiry-indefinite": "na dycki",
        "protect-cascade": "Zawrzij strōny, co sōm wrażōne do tyj strōny (erbowanie zawarciŏ)",
        "protect-cantedit": "Ńy možeš pomjyńyć poziůmu zawarća tyi zajty, po takiymu, co uona je dlo Ćebje zawarto uod pomjyńańa.",
-       "protect-othertime": "Inkszy uokres:",
-       "protect-othertime-op": "inkszy uokres",
+       "protect-othertime": "Inkszy czas:",
+       "protect-othertime-op": "inkszy czas",
        "protect-existing-expiry": "Czas wygaśńyńćo nasztalowany terozki: $2 uo $3",
        "protect-existing-expiry-infinity": "Czas wygaśniyńciŏ: niyskōńczōny",
-       "protect-otherreason": "Inkszy/dodatkowy powůd:",
+       "protect-otherreason": "Inkszy/ekstra powōd:",
        "protect-otherreason-op": "inkszy/dodatkowy powůd",
        "protect-dropdown": "*Nojczynstsze powody zawarćo uod sprowjyń\n** Czynste wandalizmy\n** Czynste spamowańy\n** Wojna edycyjno\n** Wygupy",
        "protect-edit-reasonlist": "Edytuj powody zawarciŏ",
-       "protect-expiry-options": "2 godźiny:2 hours,1 dźyń:1 day,3 dńi:3 days,1 tydźyń:1 week,2 tygodńy:2 weeks,1 mjeśůnc:1 month,3 mjeśůnce:3 months,6 mjeśency:6 months,1 rok:1 year,ńyskůńčůny:infińite",
+       "protect-expiry-options": "1 godzina:1 hour,1 dziyń:1 day,1 tydziyń:1 week,2 tydnie:2 weeks,1 miesiōnc:1 month,3 miesiōnce:3 months,6 miesiyncy:6 months,1 rok:1 year,do ôdwołaniŏ:infinite",
        "restriction-type": "Pozwolyńy:",
        "restriction-level": "Poziōm:",
        "minimum-size": "Minimalnŏ srogość",
        "undeletepage": "Pokož a odtwůř wyćepńjynte zajty",
        "undeletepagetitle": "'''Půńižej znojdujům śe wyćepane wersyje zajty  [[:$1]]'''.",
        "viewdeletedpage": "Pokož wyćepńjynte zajty",
-       "undeletepagetext": "{{PLURAL:$1|Nastympujůnco zajta uosroła wyćepano, nale jeij|Nastympujůnce $1 zajty uostoły wyćepane, nale jejich}} kopja dalij znojdujy śe we archiwum. Aechiwum roz za kedy trza uoczyszczać.",
+       "undeletepagetext": "{{PLURAL:$1|Ta strōna była skasowanŏ, ale jeji kopijõ duch je|Te $1 strōny były skasowane, ale jejich kopije durch sōm|Te $1 strōn było skasowanych, ale jejich kopije durch sōm}} we archiwum i idzie {{PLURAL:$1|jã|je}} prziwrōcić. Archiwum trzeba czas ôd czasu ôprōzniać.",
        "undelete-fieldset-title": "Wćepywańy nazod wersyji",
        "undeleteextrahelp": "Jak chcesz wćepać nazod couko zajta, pozostaw wszyjstke pola ńyzaznaczůne a naćiś '''Uodtwůrz'''.\nAby wybrać tajlowe uodtworzyńy noleży zaznaczyć '''Uodtwůrz'''.\nNaćiśńyńće '''Wyczyść''' usůńy wszyjstke zaznaczyńo a wyczyśći pole kůmyntorza.",
        "undeleterevisions": "$1 {{PLURAL:$1|zarchiwizowano wersyja|zarchiwizowane wersyje|zarchiwizowanych wersyji}}",
        "undelete-search-box": "Šnupej za wyćepńjyntymi zajtami",
        "undelete-search-prefix": "Strōny, co sie zaczynajōm ôd:",
        "undelete-search-submit": "Šnupej",
-       "undelete-no-results": "Å\83y znejdźono wskazanych zajtůw we archiwum wyÄ\87epanych.",
+       "undelete-no-results": "Å»Å\8fdne strÅ\8dny we archiwum skasowanych niy Ã´dpowiadajÅ\8dm zapytaniu.",
        "undelete-filename-mismatch": "Ńy idźe wćepać nazod wersyji plika z datům $1: ńyzgodność mjana plika",
        "undelete-bad-store-key": "Ńy idźe wćepać nazod wersyji plika z datům $1: před wyćepańem brakowouo plika.",
        "undelete-cleanup-error": "Wystůmpiu feler při wyćepywańu ńyužywanygo archiwalnygo plika „$1”.",
        "blockip": "Zawrzij sprowjorza",
        "blockiptext": "Tyn formularz służy do zawjerańo sprowjyń spod uokreślůnygo adresu IP abo kůnkretnymu użytkowńikowi.\nZawjerać noleży jydyńy po to, by zapobjec wandalizmům, zgodńy ze [[{{MediaWiki:Policy-url}}|przijyntymi reglůma]].\nPodej powůd (np. umjeszczajůnc mjana zajtůw, na kerych dopuszczůno śe wandalizmu).",
        "ipaddressorusername": "Adres IP abo mjano użytkowńika",
-       "ipbreason": "Čymu:",
+       "ipbreason": "Powōd:",
        "ipbreason-dropdown": "*Nojczynstsze powody zawjerańo uod sprawjyń\n** Ataki na inkszych użytkowńikůw\n** Naruszyńy praw autorskych\n** Ńydozwolůne mjano użytkowńika\n** Open proxy/Tor\n** Spamowańy\n** Ůsuwańy treśći zajtůw\n** Wprowadzańy fołszywych informacyji\n** Wulgaryzmy\n** Wypisywańy gůpot na zajtach",
        "ipbcreateaccount": "Ńy dozwůl utwožyć kůnta",
        "ipbemailban": "Zawrzij mogebność wysůłańo e-brifůw",
        "ipbenableautoblock": "Zawřij uostatńi adres IP tygo užytkowńika i autůmatyčńy wšyjstke kolejne, s kerych bydźe průbowou sprowjać zajty",
        "ipbsubmit": "Zablokuj tego używŏcza",
-       "ipbother": "Ikszy czas",
+       "ipbother": "Inkszy czas",
        "ipboptions": "2 godziny:2 hours,1 dziyń:1 day,3 dni:3 days,1 tydziyń:1 week,2 tydnie:2 weeks,1 miesiōnc:1 month,3 miesiōnce:3 months,6 miesiyncy:6 months,1 rok:1 year,na dycki:infinite",
        "ipbhidename": "Schrůń mjano użytkowńika/adres IP w rejerze zawarć, na liśće aktywnych zawarć i liśće użytkowńikůw",
        "ipbwatchuser": "Ôbserwuj włŏsnõ strōnã i strōnã dyskusyje ôd tego używŏcza",
        "lockfilenotwritable": "Ńy idźe naškreflać plika zawarća bazy danych.\nZawjerańy i uodmykańy bazy danych wymogo coby plik můgu być naškreflany bez web serwer.",
        "databasenotlocked": "Baza danych ńy je zawarto.",
        "move-page": "Przećep $1",
-       "move-page-legend": "Przećiś artikel",
+       "move-page-legend": "Przeniyś artykuł",
        "movepagetext": "Przi půmocy formularza půńiżej możesz půmjyńyć mjano zajty i przećepnůńć jej gyszichta. Pod downym mjanym uostańe śa zajta przekerowujůnca. Zajty adresowane na stare mjano uostanům jak bůły.\n\nJak śe na to decydujesz, sprowdź, eli ńy je to [[Special:DoubleRedirects|podwůjne]] abo [[Special:BrokenRedirects|złomane przekerowańy]].\nUodpowjadosz za to, coby linki wjodły ku prawym artiklům!\n\nZajta '''ńy''' bydźe przećepano, jak:\n*je pusto i ńy bůła sprowjano\n*je zajtům przekerowujůncą\n*zajta uo takym mjane już sam je\n\n'''DEJ POZŮR!'''\nTo może być drastyczno abo ńyprzewidywalno zmjano, jak przećepńysz jako popularno zajta. Bydź pewny, aże wjesz co robiysz, ńim klikńysz knefel \"przećep\"!",
        "movepagetalktext": "Uodpowiednio zajta godki, jeśli jest, bydzie přećepano automatyčńe, pod warůnkiem, že:\n*ńy přećepuješ zajty do inkšy přestřeńy mjan\n*ńy ma sam zajty godki o takiym mjańe\nW takiych razach tekst godki třa přećepać, a jak třeba to i pouůnčyć z tym co juž sam jest, rynčńe. Abo možeš sie namyślić i nie přećepywać wcale (\"checkbox\" půnižyi).",
        "movenologintext": "Muśyš być zarejerowanym i [[Special:UserLogin|zalůgowanym]] užytkowńikym coby můc přećepnůńć zajta.",
        "cant-move-to-user-page": "Ńy mosz uprowńyń coby przekludźić zajta na plac kaj je zajta użytkowńika (wyjůntkym sům podzajty użytkowńika).",
        "newtitle": "Nowy titel:",
        "move-watch": "Dej pozůr",
-       "movepagebtn": "Przećiś artikel",
+       "movepagebtn": "Przeniyś artykuł",
        "pagemovedsub": "Przećiśńyńće je fertig",
        "movepage-moved": "'''\"$1\" przećiśńjynto ku \"$2\"'''",
        "articleexists": "Artikel ze takym mjanym już je, abo mjano je złe.\nWybjer inksze mjano.",
        "imagetypemismatch": "Nowe rozšeřyńe mjana plika je inkšego typu kej jygo zawartość",
        "imageinvalidfilename": "Mjano plika docelowygo je felerne",
        "fix-double-redirects": "Poprow przekerowańa kere adresujům ku uoryginalnymu titlowi zajty",
-       "move-leave-redirect": "Uostow przekerowańy pode dotychczasowym titlem",
+       "move-leave-redirect": "Ôstŏw przekerowanie",
        "export": "Eksport strōn",
        "exporttext": "Možeš wyeksportować treść i historja sprowjyń jednyj zajty abo zestawu zajtůw we formaće XML.\nWyeksportowane informacyje možna půźńij zaimportować do inkšej wiki, dźouajůncyj na uoprůgramowańu MediaWiki, kořistajůnc ze [[Special:Import|zajty importu]].\n\nWyeksportowańy wjelu zajtůw wymogo wpisańo půńižej titli zajtůw, po jednym titlu we wjeršu a uokreślyńo čy mo zostać wyeksportowano bježůnco čy wšyjstke wersyje zajty s uopisůma sprawjyń abo tyž ino bježůnca wersyjo s uopisym uostatńygo sprawjyńo.\n\nMožeš tyž užyć linku, np.[[{{#Special:Export}}/{{MediaWiki:Mainpage}}]] do zajty „[[{{MediaWiki:Mainpage}}]]”.",
        "exportcuronly": "Ino bježůnco wersyjo, bes historji",
        "pageinfo-toolboxlink": "Informacyjŏ ô strōnie",
        "pageinfo-contentpage": "Rachowanŏ za strōna zawartości",
        "pageinfo-contentpage-yes": "Ja",
-       "markaspatrolleddiff": "uoznoč sprawjyńy kej „sprawdzůne”",
-       "markaspatrolledtext": "Uoznoč tyn artikel kej „sprawdzůny”",
+       "markaspatrolleddiff": "ôznŏcz za sprawdzōne",
+       "markaspatrolledtext": "Ôznŏcz tã strōnã za sprawdzōnõ",
        "markedaspatrolled": "Sprawdzůne",
        "markedaspatrolledtext": "Ta wersyjo zostoua uoznačůna kej „sprawdzůno”.",
        "rcpatroldisabled": "Wůuůnčůno fůnkcjůnalność patrolowańo we půmjyńanych na uostatku",
        "watchlistedit-normal-title": "Sprowjej lista zajtůw na kere dowom pozůr",
        "watchlistedit-normal-legend": "Wyćep zajty s listy artikli na kere dowoš pozůr",
        "watchlistedit-normal-explain": "Půńiżyj mosz lista artikli na kere dowosz pozůr.\nCoby wyćepać z ńij jako zajta, zaznocz pole przi ńij i naćiś knefel „{{int:Watchlistedit-normal-submit}}”.\nMożesz tyż skorzistać ze [[Special:EditWatchlist/raw|tekstowygo sprowjorza listy artikli na kere dowosz pozůr]].",
-       "watchlistedit-normal-submit": "Wyćep s listy",
+       "watchlistedit-normal-submit": "Skasuj tytuły",
        "watchlistedit-normal-done": "{{PLURAL:$1|Była skasowanŏ jedna strōna|Były skasowane $1 strōny|Było skasowanych $1 strōn}} ze twojij listy ôbserwowanych:",
        "watchlistedit-raw-title": "Tekstowy edytor listy artikli na kere dowosz pozůr",
        "watchlistedit-raw-legend": "Tekstowy edytor listy artikli na kere dowoš pozůr",
        "version": "Wersjo",
        "version-extensions": "Zainstalowane rozšeřyńa",
        "version-specialpages": "Szpecjalne zajty",
-       "version-parserhooks": "Haki analizatora składńi (yng. parser hooks)",
+       "version-parserhooks": "Hŏki syntaktycznego analizatora",
        "version-variables": "Zmjynne",
        "version-other": "Inksze",
        "version-mediahandlers": "Wtyčki uobsůgi medjůw",
index ced033d..b4e4623 100644 (file)
        "faq": "ಸಾಮಾನ್ಯವಾದ್ ಕೇನುನ ಪ್ರಶ್ನೆಲು",
        "actions": "ಕ್ರಿಯೆಲು",
        "namespaces": "ಪುದರ್-ಜಾಗೆಲು",
-       "variants": "ವಿವಿಧ ರೂಪೊಲು",
+       "variants": "ಬà³\87ತà³\86 à²¬à³\87ತà³\86 ರೂಪೊಲು",
        "navigation-heading": "ಸಂಚಾರೊದ ಮೆನು",
        "errorpagetitle": "ದೋಷ",
        "returnto": "$1ಗ್ ಪಿರಪೋಲೆ.",
        "mainpage-description": "ಮುಖ್ಯ ಪುಟ",
        "policy-url": "Project:ಕಾರ್ಯನೀತಿ",
        "portal": "ಸಮುದಾಯೊ ಪುಟೊ",
-       "portal-url": "Project:ಸಮುದಾಯ ಪುಟೊ",
+       "portal-url": "Project:ಸಮುದಾಯ ಪುಟೊ",
        "privacy": "ಕಾಸಗಿ ಕಾರ್ಯೊನೀತಿ",
        "privacypage": "Project:ಕಾಸಗಿ ಕಾರ್ಯೊನೀತಿ",
        "badaccess": "ಅನುಮತಿ ದೋಷ",
        "nstab-project": "ಯೋಜನೆ ಪುಟೊ",
        "nstab-image": "ಫೈಲ್",
        "nstab-mediawiki": "ಸಂದೇಶ",
-       "nstab-template": "à²\9fà³\86à²\82ಪà³\8dಲà³\86ಟ್",
+       "nstab-template": "à²\9fà³\86à²\82ಪà³\8dಲà³\87ಟ್",
        "nstab-help": "ಸಹಾಯ ಪುಟ",
        "nstab-category": "ವರ್ಗೊ",
        "mainpage-nstab": "ಮುಖ್ಯ ಪುಟ",
        "notloggedin": "ಲಾಗಿನ್ ಆತ್‘ಜ್ಜರ್",
        "userlogin-noaccount": "ಈರೆನ ಖಾತೆ ಇಜ್ಜೇ?",
        "userlogin-joinproject": "{{SITENAME}}ಗ್ ಸೇರ್ಲೆ",
-       "createaccount": "ಪà³\8aಸ à²\96ಾತೆ ಸುರು ಮಲ್ಪುಲೆ",
+       "createaccount": "ಪà³\8aಸ à²\95ಾತೆ ಸುರು ಮಲ್ಪುಲೆ",
        "userlogin-resetpassword-link": "ಇರೆನೆ ಪ್ರವೇಸೊ ಪದೊನು ಮರತ್ತ್‌‌ದರೆ?",
        "userlogin-helplink2": "ಲಾಗಿನ್ ಆಯೆರೆ ಸಹಾಯೊ",
        "userlogin-loggedin": "ಈರ್ ಅದಗನೆ {{GENDER:$1|$1}}ಆದ್ ಉಳಪ್ರವೇಶ ಮಲ್ದರ್.ಬೇತೆ ಬಳಕೆದಾರೆ ಆದ್ ಉಳಪ್ರವೇಶೊಗು ತಿರ್ತುದ ಪ್ರಪತ್ರೊನು ಬಳಸುಲೆ.",
        "rc-old-title": "ಸುರುಟು \"$1\" ಪನ್ಪಿ ಪುದರ್‌ಡ್ ಉಂಡಾತ್ಂಡ್",
        "recentchangeslinked": "ಸಂಬಂದೊ ಉಪ್ಪುನಂಚಿನ ಬದಲಾವಣೆಲು",
        "recentchangeslinked-feed": "ಸಂಬಂಧ ಉಪ್ಪುನಂಚಿನ ಬದಲಾವಣೆಲು",
-       "recentchangeslinked-toolbox": "ಸà²\82ಬà²\82ದà³\8a à²\89ಪ್ಪುನಂಚಿನ ಬದಲಾವಣೆಲು",
+       "recentchangeslinked-toolbox": "ಸಮà³\8dಮà²\82ದà³\8a à²\87ಪ್ಪುನಂಚಿನ ಬದಲಾವಣೆಲು",
        "recentchangeslinked-title": "\"$1\" ಪುಟೊಕು ಸಂಬಂದಿತಿನ ಬದಲಾವಣೆಲು",
        "recentchangeslinked-summary": "ಒಂಜಿ ನಿರ್ದಿಸ್ಟೊ ಪುಟೊರ್ದು ಸಂಪರ್ಕೊ ಉಪ್ಪುನ ಪುಟೊಕುಲೆಗ್ (ಅತ್ತಂಡ ನಿರ್ದಿಸ್ಟೊ ವರ್ಗೊಗು ಸೇರ್ದಿನ ಸದಸ್ಯೆರೆಗ್) ಇಂಚಿಪ ಮಲ್ತಿನಂಚಿನ ಬದಲಾವಣೆಲೆನ್ ತಿರ್ತ್ ಪಟ್ಟಿ ಮಲ್ತ್‌ದ್ಂಡ್.\n[[Special:Watchlist|ಇರೆನ ವೀಕ್ಷಣೆ ಪಟ್ಟಿಡ್]] ಉಪ್ಪುನ ಪುಟೊಕುಲು ''ದಪ್ಪ ಅಕ್ಷರೊಡು\" ಉಂಡು.",
        "recentchangeslinked-page": "ಪುಟೊತ ಪುದರ್:",
        "tooltip-invert": "ಆಯ್ತಿ ಪುದರ್-ಜಾಗೆದುಲಯಿದ (ಬೊಕ್ಕ ಆಯ್ತಿತ್ತ್ಂಡ, ಸಂಬಂಧ ಪಟ್ಟಿನ ಪುದರ್-ಜಾಗೆದಲಾ) ಪುಟೊಕುಲೆನ ಬದಲಾವಣೆನ್ ದೆಂಗಾಯೆರೆ ಈ ಪೆಟ್ಟಿಗೆನ್ ಆಯ್ಪುಲೆ",
        "namespace_association": "ಸಂಬಂದೊ ಪಟ್ಟಿನ ಪುದರ್-ಜಾಗೆ",
        "tooltip-namespace_association": "ಆಯ್ತಿ ಪುದರ್-ಜಾಗೆಗ್ ಸಂಬಂಧ ಪಟ್ಟಿನ ಪಾತೆರ ಅತ್ತಾಂಡ ವಿಸಯದ ಪುದರ್-ಜಾಗೆನ್ಲಾ ಒಟ್ಟುಗು ಸೇರಾಯೆರೆ ಈ ಪೆಟ್ಟಿಗೆನ್ ಆಯ್ಪುಲೆ",
-       "blanknamespace": "(ಮà³\81à²\96à³\8dಯ)",
+       "blanknamespace": "(ಮà³\81à²\95à³\8dಯà³\8a)",
        "contributions": "{{GENDER:$1|ಸದಸ್ಯೆರ್ನ}} ಕಾಣಿಕೆಲು",
        "contributions-title": "$1 ಗ್ ಸದಸ್ಯೆರ್ನ ಕಾಣಿಕೆ",
        "mycontris": "ಎನ್ನ ಕಾನಿಕೆಲು",
        "importlogpage": "ಆಮದು ದಾಕಲೆ",
        "tooltip-pt-userpage": "{{GENDER:|ಇರೆನ ಸದಸ್ಯ}} ಪುಟೊ",
        "tooltip-pt-mytalk": "{{GENDER:|ಎನ್ನ}} ಚರ್ಚೆತಾ ಪುಟೊ",
-       "tooltip-pt-preferences": "{{GENDER:|à²\87ರà³\86ನ}} à²\87ಷà³\8dà²\9fà³\8aಲು",
+       "tooltip-pt-preferences": "{{GENDER:|à²\87ರà³\86ನ}} à²\86ಯà³\8dà²\95à³\86ಲು",
        "tooltip-pt-watchlist": "ಈರ್ ಬದಲಾವಣೆಗಾದ್ ನಿಗಾ ದೀತಿನಂಚಿನ ಪುಟೊಲೆನ ಪಟ್ಟಿ",
        "tooltip-pt-mycontris": "{{GENDER:|ಎನ್ನ}} ಕಾನಿಕೆಲೆನ ಪಟ್ಟಿ",
        "tooltip-pt-login": "ಈರ್ ಲಾಗಿನ್ ಆವೊಡುಂದು ಕೇನೊಂದುಲ್ಲೊ, ಆಂಡ ಉಂದು ದಾಲ ಕಡ್ಡಾಯ ಅತ್ತ್.",
        "tooltip-n-currentevents": "ಇತ್ತೆದ ಆಪುಪೋಪುನ ಬಗೆಟ್ ದುಂಬುದ ಮಾಹಿತಿ ದೆತೊನ್ಲೆ",
        "tooltip-n-recentchanges": "ವಿಕಿಡ್ ದುಂಬುದ ಒಂತೆ ಸಮಯೊಡ್ ಆತಿನಂಚಿನ ಬದಲಾವಣೆಲೆನ ಪಟ್ಟಿ",
        "tooltip-n-randompage": "ಇಚ್ಚೆದ ಪುಟೊ ಒಂಜೆನ್ ತೋಜಾವು",
-       "tooltip-n-help": "à²\87à²\82ದà³\86ತ à²¬à²\97à³\86à²\9fà³\8d à²¤à³\86ರà³\86ಯೊನುನ ಜಾಗೆ",
+       "tooltip-n-help": "à²\87à²\82ದà³\86ತ à²¬à²\97à³\86à²\9fà³\8d à²¤à³\86ರಿಯೊನುನ ಜಾಗೆ",
        "tooltip-t-whatlinkshere": "ಇಡೆಗ್ ಕೊಂಡಿ ಕೊರ್ಪುನಂಚಿನ ಪೂರ ವಿಕಿ ಪುಟೊಕುಲೆನ ಪಟ್ಟಿ",
        "tooltip-t-recentchangeslinked": "ಈ ಪುಟೊಡ್ದ್ ಸಂಪರ್ಕೊ ಉಪ್ಪುನಂಚಿನ ಪುಟೊಟು ಇಂಚಿಪೊದ ಬದಲಾವಣೆಲು",
        "tooltip-feed-rss": "ಈ ಪುಟೊಗು ಆರ್.ಎಸ್.ಎಸ್ ಫೀಡ್",
        "pageinfo-protect-cascading-yes": "ಅಂದ್",
        "pageinfo-category-pages": "ಪುಟೊಕುಲೆ ಸಂಕ್ಯೆ",
        "patrol-log-page": "ಪರೀಕ್ಷಣಾ ದಾಕಲೆ",
-       "previousdiff": "← ದುಂಬುದ ಸಂಪದನೆ",
+       "previousdiff": "â\86\90 à²¦à³\81à²\82ಬà³\81ದ à²¸à²\82ಪಾದನà³\86",
        "nextdiff": "ಬುಕ್ಕೊದ ಸಂಪದನೆ →",
        "thumbsize": "ಕಿರುನೋಟದ ಗಾತ್ರೊ:",
        "widthheightpage": "$1 × $2, $3 {{PLURAL:$3|ಪುಟೊ|ಪುಟೊಕುಲು}}",
index ec025df..15b8981 100644 (file)
        "tog-useeditwarning": "Bir düzenleme sayfasından değişiklikleri kaydetmeden ayrılırken beni uyar",
        "tog-prefershttps": "Oturum açıkken her zaman güvenli bir bağlantı kullan",
        "tog-showrollbackconfirmation": "Geri alma bağlantısına tıkladığınızda bir onay istemi gösterin",
+       "tog-requireemail": "Şifre sıfırlamaları için e-posta iste",
        "underline-always": "Her zaman",
        "underline-never": "Hiçbir zaman",
        "underline-default": "Görünüm ya da tarayıcı varsayılanı",
        "perfcached": "Aşağıdaki veriler önbellekten alınmıştır ve güncel olmayabilir. Önbellekte en fazla {{PLURAL:$1|bir sonuç|$1 sonuç}} mevcut.",
        "perfcachedts": "Aşağıdaki veri önbelleklenmiştir, son güncelleme tarihi: $1. Önbellekte en fazla {{PLURAL:$1|bir sonuç|$4 sonuç}} mevcut.",
        "querypage-no-updates": "Şu an bu sayfa için güncellemeler devre dışı bırakıldı. Buradaki veri hemen yenilenmeyecektir.",
+       "querypage-updates-periodical": "Bu sayfa için güncellemeler periyodik olarak yürütülmektedir.",
        "viewsource": "Kaynağı gör",
        "viewsource-title": "$1 sayfasının kaynağını görüntüle",
        "actionthrottled": "Eylem kısılmıştır",
        "createaccountmail": "Geçici bir rastgele parola kullanabilir ve bu parolayı belirtilen e-posta adresine gönderebilirsiniz",
        "createaccountmail-help": "Parolayı öğrenmeden başka bir kişi için hesap oluşturmak amacıyla kullanılabilir.",
        "createacct-realname": "Gerçek adı (isteğe bağlı)",
-       "createacct-reason": "Gerekçe",
+       "createacct-reason": "Sebep (halk açık)",
        "createacct-reason-ph": "Neden başka bir hesap oluşturuyorsunuz",
        "createacct-reason-help": "Hesap oluşturma günlüğünde gösterilen mesaj",
        "createacct-submit": "Hesabınızı oluşturun",
        "sectioneditnotsupported-title": "Bölüm değiştirmesi desteklenmiyor",
        "sectioneditnotsupported-text": "Bölüm değiştirmesi bu sayfada desteklenmiyor.",
        "modeleditnotsupported-title": "Düzenleme desteklenmemektedir",
+       "modeleditnotsupported-text": "$1 içerik modeli için düzenleme desteklenmiyor.",
        "permissionserrors": "İzin hatası",
        "permissionserrorstext": "Aşağıdaki {{PLURAL:$1|sebep|sebepler}}den dolayı, bunu yapmaya yetkiniz yok:",
        "permissionserrorstext-withaction": "Aşağıdaki {{PLURAL:$1|neden|nedenler}}den dolayı $2 yetkiniz yok:",
        "prefs-help-email": "E-posta adresi isteğe bağlıdır; ancak parolanızı unutmanız durumunda parola sıfırlamak için gerekecektir.",
        "prefs-help-email-others": "Ayrıca kullanıcı sayfanızdaki bir bağlantı yoluyla diğer kullanıcıların size e-posta atmasına izin vermeyi seçebilirsiniz.\nDiğer kullanıcılar sizinle bu yolla iletişime geçtiğinde e-posta adresiniz açıklanmaz.",
        "prefs-help-email-required": "E-posta adresi gerekmektedir.",
+       "prefs-help-requireemail": "İşaretliyse, yalnızca sıfırlama yapan kişi bu hesap için hem kullanıcı adı hem de e-posta sağladıysa, şifre sıfırlama e-postaları gönderir.",
        "prefs-info": "Temel bilgiler",
        "prefs-i18n": "Uluslararasılaştırma",
        "prefs-signature": "İmza",
        "listfiles-userdoesnotexist": "\"$1\" kullanıcı hesabı kayıtlı değil.",
        "imgfile": "dosya",
        "listfiles": "Dosya listesi",
+       "listfiles_subpage": "$1 tarafından yüklendi",
        "listfiles_thumb": "Küçük resim",
        "listfiles_date": "Tarih",
        "listfiles_name": "Ad",
index 8d9092c..7a188a9 100644 (file)
@@ -5,7 +5,8 @@
                        "ОйЛ",
                        "לערי ריינהארט",
                        "아라",
-                       "Fitoschido"
+                       "Fitoschido",
+                       "Amire80"
                ]
        },
        "tog-underline": "Заалһиг татасллһн:",
index 6709950..3e98c65 100644 (file)
        "diff-multi-manyusers": "(由$2位更多用戶所做嘅$1個中途修訂冇顯示到)",
        "searchresults": "搵嘢結果",
        "search-filter-title-prefix": "只喺標題係「$1」開頭嘅版度搜索",
-       "search-filter-title-prefix-reset": "搵所有版",
+       "search-filter-title-prefix-reset": "搵所有版",
        "searchresults-title": "對\"$1\"嘅搵嘢結果",
        "titlematches": "頁面標題符合",
        "textmatches": "頁面文字符合",
index 5d75381..fa877cf 100644 (file)
        "showdiff": "显示更改",
        "blankarticle": "<strong>警告</strong>:您创建的页面是空白的。如果您再次点击“$1”,您将真的创建没有任何内容的页面。",
        "anoneditwarning": "<strong>警告:</strong>您没有登录。如果您做出任意编辑,您的IP地址将会公开可见。如果您<strong>[$1 登录]</strong>或<strong>[$2 创建]</strong>一个账户,您的编辑将归属于您的用户名,且将享受其他好处。",
-       "anonpreviewwarning": "<em>您没有登录。保存将您的IP地址记录至此页面的编辑历史中。</em>",
+       "anonpreviewwarning": "您没有登录。保存将您的IP地址记录至此页面的编辑历史中。",
        "missingsummary": "<strong>提示:</strong>您没有提供编辑摘要。如果您再次点击“$1”,您的编辑将不带摘要保存。",
        "selfredirect": "<strong>警告:</strong>您正在将此页面重定向至它自己。您可能指定了错误的重定向目标,或者您正在编辑错误的页面。如果您再次点击“$1”,重定向仍将被创建。",
        "missingcommenttext": "请输入一段评论。",
index 49b362f..db7a0fa 100644 (file)
        "perfcached": "以下為快取資料,可能不是最新的。 快取資料最多可儲存 {{PLURAL:$1|1 筆結果|$1 筆結果}}。",
        "perfcachedts": "以下為快取資料,最後更新時間為 $1。快取資料最多可儲存 {{PLURAL:$4|1 筆結果|$4 筆結果}}。",
        "querypage-no-updates": "目前已停用此頁面的更新功能。\n在此頁面的資料不會被立即更新。",
+       "querypage-updates-periodical": "此頁面的更新為定期運作。",
        "viewsource": "檢視原始碼",
        "viewsource-title": "檢視 $1 的原始碼",
        "actionthrottled": "已限制動作",
        "showdiff": "顯示變更",
        "blankarticle": "<strong>警告:</strong>您正在建立的頁面是空白的。\n如果您再按一下\"$1\",將建立沒有任何內容的頁面。",
        "anoneditwarning": "<strong>警告:</strong>您尚未登入。 若您進行任何的編輯您的 IP 位置將會被公開。 若您 <strong>[$1 登入]</strong> 或 <strong>[$2 建立帳號]</strong>,您的編輯將會以您的使用者名稱標示,擁有其他優點。",
-       "anonpreviewwarning": "<em>您尚未登入。儲存頁面會將您的 IP 位址記錄在此頁面的編輯歷史中。</em>",
+       "anonpreviewwarning": "您尚未登入。儲存頁面會將您的 IP 位址記錄在此頁面的編輯歷史中。",
        "missingsummary": "<strong>提醒:</strong>您未填寫編輯摘要。\n若您再點選 \"$1\" 一次,將略過摘要直接儲存您的編輯。",
        "selfredirect": "<strong>警告:</strong> 您正建立連結至自己的重新導向。\n您可能指定錯要重新導向的目標頁面或者編輯錯頁面。\n若您再點選 \"$1\" 一次,將會繼續建立重新導向。",
        "missingcommenttext": "請輸入一段評論。",
        "editingold": "<strong>警告:您目前正編輯頁面的舊修訂版本。</strong>若您儲存,在此修訂之後變更的任何內容將會遺失。",
        "unicode-support-fail": "看起來您的瀏覽器不支援Unicode。需要Unicode才能編輯頁面,所以您的編輯無法儲存。",
        "yourdiff": "差異",
-       "copyrightwarning": "請注意,所有於 {{SITENAME}} 所做的貢獻會依據 $2 授權條款發佈 (詳情請見 $1)。\n若您不希望您的著作被任意修改與散佈,請勿在此發表文章。<br />\n您同時向我們保証在此的著作內容是您自行撰寫,或是取自不受版權保護的公開領域或自由資源。\n<strong>請勿在未經授權的情況下發表文章!</strong>",
-       "copyrightwarning2": "請注意,所有於{{SITENAME}}所做的貢獻可能會被其他貢獻者編輯,修改或刪除。\n若您不希望您的著作被任意修改與散佈,請勿在此發表文章。<br />\n您同時向我們保証在此的著作內容是您自行撰寫,或是取自不受版權保護的公開領域或自由資源(詳情請見 $1)。\n<strong>請勿在未經授權的情況下發表文章!</strong>",
+       "copyrightwarning": "請注意,所有於{{SITENAME}}所做的貢獻會依據$2授權條款發佈(詳情請見$1)。若您不希望您的著作被任意修改與散佈,請勿在此發表文章。<br />\n您同時向我們保證在此的著作內容是您自行撰寫,或是取自不受版權保護的公開領域或自由資源。<strong>請勿在未經授權的情況下發表文章!</strong>",
+       "copyrightwarning2": "請注意,所有於{{SITENAME}}所做的貢獻可能會被其他貢獻者編輯,修改或刪除。若您不希望您的著作被任意修改與散佈,請勿在此發表文章。<br />\n您同時向我們保證在此的著作內容是您自行撰寫,或是取自不受版權保護的公開領域或自由資源(詳情請見 $1)。<strong>請勿在未經授權的情況下發表文章!</strong>",
        "editpage-cannot-use-custom-model": "此頁面的內容模型不能被修改。",
        "longpageerror": "<strong>錯誤:您所送出的文字內容共有 {{PLURAL:$1|1 KB|$1 KB}},已超出系統上限 {{PLURAL:$2|1 KB|$2 KB}}。</strong>\n\n無法儲存。",
        "readonlywarning": "<strong>警告:資料庫已被鎖定以進行維護,因此無法儲存您目前所做的編輯動作。</strong>\n您可先複製您的文字並貼上到文字檔案中儲存,稍後再儲存您編輯。\n\n鎖定資料庫的系統管理員有以下說明:$1",
        "datedefault": "預設值",
        "prefs-labs": "實驗中的功能",
        "prefs-user-pages": "使用者頁面",
-       "prefs-personal": "用戶資料",
+       "prefs-personal": "使用者基本資料",
        "prefs-rc": "近期變更",
        "prefs-watchlist": "監視清單",
        "prefs-editwatchlist": "編輯監視清單",
diff --git a/maintenance/archives/patch-archive-ar_comment_id.sql b/maintenance/archives/patch-archive-ar_comment_id.sql
new file mode 100644 (file)
index 0000000..cb7b8a7
--- /dev/null
@@ -0,0 +1,3 @@
+ALTER TABLE /*_*/archive
+  ALTER COLUMN ar_comment SET DEFAULT '',
+  ADD COLUMN ar_comment_id bigint unsigned NOT NULL DEFAULT 0 AFTER ar_comment;
index c8bf958..bbe7810 100644 (file)
@@ -1,7 +1,7 @@
 --
 -- patch-comment-table.sql
 --
--- T166732. Add a `comment` table and various columns (and temporary tables) to reference it.
+-- T166732. Add a `comment` table.
 
 CREATE TABLE /*_*/comment (
   comment_id bigint unsigned NOT NULL PRIMARY KEY AUTO_INCREMENT,
@@ -10,50 +10,3 @@ CREATE TABLE /*_*/comment (
   comment_data BLOB
 ) /*$wgDBTableOptions*/;
 CREATE INDEX /*i*/comment_hash ON /*_*/comment (comment_hash);
-
-CREATE TABLE /*_*/revision_comment_temp (
-  revcomment_rev int unsigned NOT NULL,
-  revcomment_comment_id bigint unsigned NOT NULL,
-  PRIMARY KEY (revcomment_rev, revcomment_comment_id)
-) /*$wgDBTableOptions*/;
-CREATE UNIQUE INDEX /*i*/revcomment_rev ON /*_*/revision_comment_temp (revcomment_rev);
-
-CREATE TABLE /*_*/image_comment_temp (
-  imgcomment_name varchar(255) binary NOT NULL,
-  imgcomment_description_id bigint unsigned NOT NULL,
-  PRIMARY KEY (imgcomment_name, imgcomment_description_id)
-) /*$wgDBTableOptions*/;
-CREATE UNIQUE INDEX /*i*/imgcomment_name ON /*_*/image_comment_temp (imgcomment_name);
-
-ALTER TABLE /*_*/revision
-  ALTER COLUMN rev_comment SET DEFAULT '';
-
-ALTER TABLE /*_*/archive
-  ALTER COLUMN ar_comment SET DEFAULT '',
-  ADD COLUMN ar_comment_id bigint unsigned NOT NULL DEFAULT 0 AFTER ar_comment;
-
-ALTER TABLE /*_*/ipblocks
-  ALTER COLUMN ipb_reason SET DEFAULT '',
-  ADD COLUMN ipb_reason_id bigint unsigned NOT NULL DEFAULT 0 AFTER ipb_reason;
-
-ALTER TABLE /*_*/image
-  ALTER COLUMN img_description SET DEFAULT '';
-
-ALTER TABLE /*_*/oldimage
-  ALTER COLUMN oi_description SET DEFAULT '',
-  ADD COLUMN oi_description_id bigint unsigned NOT NULL DEFAULT 0 AFTER oi_description;
-
-ALTER TABLE /*_*/filearchive
-  ADD COLUMN fa_deleted_reason_id bigint unsigned NOT NULL DEFAULT 0 AFTER fa_deleted_reason,
-  ALTER COLUMN fa_description SET DEFAULT '',
-  ADD COLUMN fa_description_id bigint unsigned NOT NULL DEFAULT 0 AFTER fa_description;
-
-ALTER TABLE /*_*/recentchanges
-  ADD COLUMN rc_comment_id bigint unsigned NOT NULL DEFAULT 0 AFTER rc_comment;
-
-ALTER TABLE /*_*/logging
-  ADD COLUMN log_comment_id bigint unsigned NOT NULL DEFAULT 0 AFTER log_comment;
-
-ALTER TABLE /*_*/protected_titles
-  ALTER COLUMN pt_reason SET DEFAULT '',
-  ADD COLUMN pt_reason_id bigint unsigned NOT NULL DEFAULT 0 AFTER pt_reason;
diff --git a/maintenance/archives/patch-filearchive-fa_description_id.sql b/maintenance/archives/patch-filearchive-fa_description_id.sql
new file mode 100644 (file)
index 0000000..93ddd50
--- /dev/null
@@ -0,0 +1,4 @@
+ALTER TABLE /*_*/filearchive
+  ADD COLUMN fa_deleted_reason_id bigint unsigned NOT NULL DEFAULT 0 AFTER fa_deleted_reason,
+  ALTER COLUMN fa_description SET DEFAULT '',
+  ADD COLUMN fa_description_id bigint unsigned NOT NULL DEFAULT 0 AFTER fa_description;
diff --git a/maintenance/archives/patch-image-img_description-default.sql b/maintenance/archives/patch-image-img_description-default.sql
new file mode 100644 (file)
index 0000000..43d54dc
--- /dev/null
@@ -0,0 +1,2 @@
+ALTER TABLE /*_*/image
+  ALTER COLUMN img_description SET DEFAULT '';
diff --git a/maintenance/archives/patch-image_comment_temp-table.sql b/maintenance/archives/patch-image_comment_temp-table.sql
new file mode 100644 (file)
index 0000000..f873c91
--- /dev/null
@@ -0,0 +1,6 @@
+CREATE TABLE /*_*/image_comment_temp (
+  imgcomment_name varchar(255) binary NOT NULL,
+  imgcomment_description_id bigint unsigned NOT NULL,
+  PRIMARY KEY (imgcomment_name, imgcomment_description_id)
+) /*$wgDBTableOptions*/;
+CREATE UNIQUE INDEX /*i*/imgcomment_name ON /*_*/image_comment_temp (imgcomment_name);
diff --git a/maintenance/archives/patch-ipblocks-ipb_reason_id.sql b/maintenance/archives/patch-ipblocks-ipb_reason_id.sql
new file mode 100644 (file)
index 0000000..8816a7f
--- /dev/null
@@ -0,0 +1,3 @@
+ALTER TABLE /*_*/ipblocks
+  ALTER COLUMN ipb_reason SET DEFAULT '',
+  ADD COLUMN ipb_reason_id bigint unsigned NOT NULL DEFAULT 0 AFTER ipb_reason;
diff --git a/maintenance/archives/patch-logging-log_comment_id.sql b/maintenance/archives/patch-logging-log_comment_id.sql
new file mode 100644 (file)
index 0000000..0032900
--- /dev/null
@@ -0,0 +1,2 @@
+ALTER TABLE /*_*/logging
+  ADD COLUMN log_comment_id bigint unsigned NOT NULL DEFAULT 0 AFTER log_comment;
diff --git a/maintenance/archives/patch-oldimage-oi_description_id.sql b/maintenance/archives/patch-oldimage-oi_description_id.sql
new file mode 100644 (file)
index 0000000..be24a80
--- /dev/null
@@ -0,0 +1,3 @@
+ALTER TABLE /*_*/oldimage
+  ALTER COLUMN oi_description SET DEFAULT '',
+  ADD COLUMN oi_description_id bigint unsigned NOT NULL DEFAULT 0 AFTER oi_description;
diff --git a/maintenance/archives/patch-protected_titles-pt_reason_id.sql b/maintenance/archives/patch-protected_titles-pt_reason_id.sql
new file mode 100644 (file)
index 0000000..02efd2f
--- /dev/null
@@ -0,0 +1,3 @@
+ALTER TABLE /*_*/protected_titles
+  ALTER COLUMN pt_reason SET DEFAULT '',
+  ADD COLUMN pt_reason_id bigint unsigned NOT NULL DEFAULT 0 AFTER pt_reason;
diff --git a/maintenance/archives/patch-recentchanges-rc_comment_id.sql b/maintenance/archives/patch-recentchanges-rc_comment_id.sql
new file mode 100644 (file)
index 0000000..38bff08
--- /dev/null
@@ -0,0 +1,2 @@
+ALTER TABLE /*_*/recentchanges
+  ADD COLUMN rc_comment_id bigint unsigned NOT NULL DEFAULT 0 AFTER rc_comment;
diff --git a/maintenance/archives/patch-rename-mysql-user_newtalk-indexes.sql b/maintenance/archives/patch-rename-mysql-user_newtalk-indexes.sql
new file mode 100644 (file)
index 0000000..3177b4d
--- /dev/null
@@ -0,0 +1,10 @@
+-- T233240: The indexes on `user_newtalk` may be named `un_user_id`/`un_user_ip`
+-- or `user_id`/`user_ip`. At least it won't be both or mixed. Rename them to
+-- the former.
+
+-- Do not use the /*i*/ hack here!
+ALTER TABLE /*_*/user_newtalk
+       DROP INDEX user_id,
+       DROP INDEX user_ip,
+       ADD INDEX un_user_id (user_id),
+       ADD INDEX un_user_ip (user_ip);
diff --git a/maintenance/archives/patch-revision-rev_comment-default.sql b/maintenance/archives/patch-revision-rev_comment-default.sql
new file mode 100644 (file)
index 0000000..2beedcc
--- /dev/null
@@ -0,0 +1,2 @@
+ALTER TABLE /*_*/revision
+  ALTER COLUMN rev_comment SET DEFAULT '';
diff --git a/maintenance/archives/patch-revision_comment_temp-table.sql b/maintenance/archives/patch-revision_comment_temp-table.sql
new file mode 100644 (file)
index 0000000..689e5d5
--- /dev/null
@@ -0,0 +1,6 @@
+CREATE TABLE /*_*/revision_comment_temp (
+  revcomment_rev int unsigned NOT NULL,
+  revcomment_comment_id bigint unsigned NOT NULL,
+  PRIMARY KEY (revcomment_rev, revcomment_comment_id)
+) /*$wgDBTableOptions*/;
+CREATE UNIQUE INDEX /*i*/revcomment_rev ON /*_*/revision_comment_temp (revcomment_rev);
index 243a3b3..4b91815 100644 (file)
@@ -1,7 +1,7 @@
 --
 -- patch-comment-table.sql
 --
--- T166732. Add a `comment` table, and temporary tables to reference it.
+-- T166732. Add a `comment` table
 
 CREATE SEQUENCE comment_comment_id_seq;
 CREATE TABLE comment (
@@ -11,17 +11,3 @@ CREATE TABLE comment (
        comment_data TEXT
 );
 CREATE INDEX comment_hash ON comment (comment_hash);
-
-CREATE TABLE revision_comment_temp (
-       revcomment_rev        INTEGER NOT NULL,
-       revcomment_comment_id INTEGER NOT NULL,
-       PRIMARY KEY (revcomment_rev, revcomment_comment_id)
-);
-CREATE UNIQUE INDEX revcomment_rev ON revision_comment_temp (revcomment_rev);
-
-CREATE TABLE image_comment_temp (
-       imgcomment_name       TEXT NOT NULL,
-       imgcomment_description_id INTEGER NOT NULL,
-       PRIMARY KEY (imgcomment_name, imgcomment_description_id)
-);
-CREATE UNIQUE INDEX imgcomment_name ON image_comment_temp (imgcomment_name);
diff --git a/maintenance/postgres/archives/patch-image_comment_temp-table.sql b/maintenance/postgres/archives/patch-image_comment_temp-table.sql
new file mode 100644 (file)
index 0000000..be7bb82
--- /dev/null
@@ -0,0 +1,6 @@
+CREATE TABLE image_comment_temp (
+       imgcomment_name       TEXT NOT NULL,
+       imgcomment_description_id INTEGER NOT NULL,
+       PRIMARY KEY (imgcomment_name, imgcomment_description_id)
+);
+CREATE UNIQUE INDEX imgcomment_name ON image_comment_temp (imgcomment_name);
diff --git a/maintenance/postgres/archives/patch-revision_comment_temp-table.sql b/maintenance/postgres/archives/patch-revision_comment_temp-table.sql
new file mode 100644 (file)
index 0000000..cbfaa06
--- /dev/null
@@ -0,0 +1,6 @@
+CREATE TABLE revision_comment_temp (
+       revcomment_rev        INTEGER NOT NULL,
+       revcomment_comment_id INTEGER NOT NULL,
+       PRIMARY KEY (revcomment_rev, revcomment_comment_id)
+);
+CREATE UNIQUE INDEX revcomment_rev ON revision_comment_temp (revcomment_rev);
diff --git a/maintenance/sqlite/archives/patch-archive-ar_comment_id.sql b/maintenance/sqlite/archives/patch-archive-ar_comment_id.sql
new file mode 100644 (file)
index 0000000..d06b81c
--- /dev/null
@@ -0,0 +1,46 @@
+BEGIN;
+
+DROP TABLE IF EXISTS /*_*/archive_tmp;
+CREATE TABLE /*_*/archive_tmp (
+  ar_id int unsigned NOT NULL PRIMARY KEY AUTO_INCREMENT,
+  ar_namespace int NOT NULL default 0,
+  ar_title varchar(255) binary NOT NULL default '',
+  ar_text mediumblob NOT NULL,
+  ar_comment varbinary(767) NOT NULL default '',
+  ar_comment_id bigint unsigned NOT NULL DEFAULT 0,
+  ar_user int unsigned NOT NULL default 0,
+  ar_user_text varchar(255) binary NOT NULL,
+  ar_timestamp binary(14) NOT NULL default '',
+  ar_minor_edit tinyint NOT NULL default 0,
+  ar_flags tinyblob NOT NULL,
+  ar_rev_id int unsigned,
+  ar_text_id int unsigned,
+  ar_deleted tinyint unsigned NOT NULL default 0,
+  ar_len int unsigned,
+  ar_page_id int unsigned,
+  ar_parent_id int unsigned default NULL,
+  ar_sha1 varbinary(32) NOT NULL default '',
+  ar_content_model varbinary(32) DEFAULT NULL,
+  ar_content_format varbinary(64) DEFAULT NULL
+) /*$wgDBTableOptions*/;
+
+INSERT OR IGNORE INTO /*_*/archive_tmp (
+       ar_id, ar_namespace, ar_title, ar_text, ar_comment, ar_user, ar_user_text,
+       ar_timestamp, ar_minor_edit, ar_flags, ar_rev_id, ar_text_id, ar_deleted,
+       ar_len, ar_page_id, ar_parent_id, ar_sha1, ar_content_model,
+       ar_content_format)
+  SELECT
+       ar_id, ar_namespace, ar_title, ar_text, ar_comment, ar_user, ar_user_text,
+       ar_timestamp, ar_minor_edit, ar_flags, ar_rev_id, ar_text_id, ar_deleted,
+       ar_len, ar_page_id, ar_parent_id, ar_sha1, ar_content_model,
+       ar_content_format
+  FROM /*_*/archive;
+
+DROP TABLE /*_*/archive;
+ALTER TABLE /*_*/archive_tmp RENAME TO /*_*/archive;
+CREATE INDEX /*i*/name_title_timestamp ON /*_*/archive (ar_namespace,ar_title,ar_timestamp);
+CREATE INDEX /*i*/ar_usertext_timestamp ON /*_*/archive (ar_user_text,ar_timestamp);
+CREATE INDEX /*i*/ar_revid ON /*_*/archive (ar_rev_id);
+
+COMMIT;
+
diff --git a/maintenance/sqlite/archives/patch-comment-table.sql b/maintenance/sqlite/archives/patch-comment-table.sql
deleted file mode 100644 (file)
index d74c3a6..0000000
+++ /dev/null
@@ -1,280 +0,0 @@
---
--- patch-comment-table.sql
---
--- T166732. Add a `comment` table and various columns (and temporary tables) to reference it.
--- Sigh, sqlite, such trouble just to change the default value of a column.
-
-CREATE TABLE /*_*/comment (
-  comment_id bigint unsigned NOT NULL PRIMARY KEY AUTO_INCREMENT,
-  comment_hash INT NOT NULL,
-  comment_text BLOB NOT NULL,
-  comment_data BLOB
-) /*$wgDBTableOptions*/;
-CREATE INDEX /*i*/comment_hash ON /*_*/comment (comment_hash);
-
-CREATE TABLE /*_*/revision_comment_temp (
-  revcomment_rev int unsigned NOT NULL,
-  revcomment_comment_id bigint unsigned NOT NULL,
-  PRIMARY KEY (revcomment_rev, revcomment_comment_id)
-) /*$wgDBTableOptions*/;
-CREATE UNIQUE INDEX /*i*/revcomment_rev ON /*_*/revision_comment_temp (revcomment_rev);
-
-CREATE TABLE /*_*/image_comment_temp (
-  imgcomment_name varchar(255) binary NOT NULL,
-  imgcomment_description_id bigint unsigned NOT NULL,
-  PRIMARY KEY (imgcomment_name, imgcomment_description_id)
-) /*$wgDBTableOptions*/;
-CREATE UNIQUE INDEX /*i*/imgcomment_name ON /*_*/image_comment_temp (imgcomment_name);
-
-ALTER TABLE /*_*/recentchanges
-  ADD COLUMN rc_comment_id bigint unsigned NOT NULL DEFAULT 0;
-
-ALTER TABLE /*_*/logging
-  ADD COLUMN log_comment_id bigint unsigned NOT NULL DEFAULT 0;
-
-BEGIN;
-
-DROP TABLE IF EXISTS /*_*/revision_tmp;
-CREATE TABLE /*_*/revision_tmp (
-  rev_id int unsigned NOT NULL PRIMARY KEY AUTO_INCREMENT,
-  rev_page int unsigned NOT NULL,
-  rev_text_id int unsigned NOT NULL,
-  rev_comment varbinary(767) NOT NULL default '',
-  rev_user int unsigned NOT NULL default 0,
-  rev_user_text varchar(255) binary NOT NULL default '',
-  rev_timestamp binary(14) NOT NULL default '',
-  rev_minor_edit tinyint unsigned NOT NULL default 0,
-  rev_deleted tinyint unsigned NOT NULL default 0,
-  rev_len int unsigned,
-  rev_parent_id int unsigned default NULL,
-  rev_sha1 varbinary(32) NOT NULL default '',
-  rev_content_model varbinary(32) DEFAULT NULL,
-  rev_content_format varbinary(64) DEFAULT NULL
-) /*$wgDBTableOptions*/ MAX_ROWS=10000000 AVG_ROW_LENGTH=1024;
-
-INSERT OR IGNORE INTO /*_*/revision_tmp (
-       rev_id, rev_page, rev_text_id, rev_comment, rev_user, rev_user_text,
-       rev_timestamp, rev_minor_edit, rev_deleted, rev_len, rev_parent_id,
-       rev_sha1, rev_content_model, rev_content_format)
- SELECT
-       rev_id, rev_page, rev_text_id, rev_comment, rev_user, rev_user_text,
-       rev_timestamp, rev_minor_edit, rev_deleted, rev_len, rev_parent_id,
-       rev_sha1, rev_content_model, rev_content_format
-  FROM /*_*/revision;
-
-DROP TABLE /*_*/revision;
-ALTER TABLE /*_*/revision_tmp RENAME TO /*_*/revision;
-CREATE INDEX /*i*/rev_page_id ON /*_*/revision (rev_page, rev_id);
-CREATE INDEX /*i*/rev_timestamp ON /*_*/revision (rev_timestamp);
-CREATE INDEX /*i*/page_timestamp ON /*_*/revision (rev_page,rev_timestamp);
-CREATE INDEX /*i*/user_timestamp ON /*_*/revision (rev_user,rev_timestamp);
-CREATE INDEX /*i*/usertext_timestamp ON /*_*/revision (rev_user_text,rev_timestamp);
-CREATE INDEX /*i*/page_user_timestamp ON /*_*/revision (rev_page,rev_user,rev_timestamp);
-
-COMMIT;
-
-BEGIN;
-
-DROP TABLE IF EXISTS /*_*/archive_tmp;
-CREATE TABLE /*_*/archive_tmp (
-  ar_id int unsigned NOT NULL PRIMARY KEY AUTO_INCREMENT,
-  ar_namespace int NOT NULL default 0,
-  ar_title varchar(255) binary NOT NULL default '',
-  ar_text mediumblob NOT NULL,
-  ar_comment varbinary(767) NOT NULL default '',
-  ar_comment_id bigint unsigned NOT NULL DEFAULT 0,
-  ar_user int unsigned NOT NULL default 0,
-  ar_user_text varchar(255) binary NOT NULL,
-  ar_timestamp binary(14) NOT NULL default '',
-  ar_minor_edit tinyint NOT NULL default 0,
-  ar_flags tinyblob NOT NULL,
-  ar_rev_id int unsigned,
-  ar_text_id int unsigned,
-  ar_deleted tinyint unsigned NOT NULL default 0,
-  ar_len int unsigned,
-  ar_page_id int unsigned,
-  ar_parent_id int unsigned default NULL,
-  ar_sha1 varbinary(32) NOT NULL default '',
-  ar_content_model varbinary(32) DEFAULT NULL,
-  ar_content_format varbinary(64) DEFAULT NULL
-) /*$wgDBTableOptions*/;
-
-INSERT OR IGNORE INTO /*_*/archive_tmp (
-       ar_id, ar_namespace, ar_title, ar_text, ar_comment, ar_user, ar_user_text,
-       ar_timestamp, ar_minor_edit, ar_flags, ar_rev_id, ar_text_id, ar_deleted,
-       ar_len, ar_page_id, ar_parent_id, ar_sha1, ar_content_model,
-       ar_content_format)
-  SELECT
-       ar_id, ar_namespace, ar_title, ar_text, ar_comment, ar_user, ar_user_text,
-       ar_timestamp, ar_minor_edit, ar_flags, ar_rev_id, ar_text_id, ar_deleted,
-       ar_len, ar_page_id, ar_parent_id, ar_sha1, ar_content_model,
-       ar_content_format
-  FROM /*_*/archive;
-
-DROP TABLE /*_*/archive;
-ALTER TABLE /*_*/archive_tmp RENAME TO /*_*/archive;
-CREATE INDEX /*i*/name_title_timestamp ON /*_*/archive (ar_namespace,ar_title,ar_timestamp);
-CREATE INDEX /*i*/ar_usertext_timestamp ON /*_*/archive (ar_user_text,ar_timestamp);
-CREATE INDEX /*i*/ar_revid ON /*_*/archive (ar_rev_id);
-
-COMMIT;
-
-BEGIN;
-
-DROP TABLE IF EXISTS ipblocks_tmp;
-CREATE TABLE /*_*/ipblocks_tmp (
-  ipb_id int NOT NULL PRIMARY KEY AUTO_INCREMENT,
-  ipb_address tinyblob NOT NULL,
-  ipb_user int unsigned NOT NULL default 0,
-  ipb_by int unsigned NOT NULL default 0,
-  ipb_by_text varchar(255) binary NOT NULL default '',
-  ipb_reason varbinary(767) NOT NULL default '',
-  ipb_reason_id bigint unsigned NOT NULL DEFAULT 0,
-  ipb_timestamp binary(14) NOT NULL default '',
-  ipb_auto bool NOT NULL default 0,
-  ipb_anon_only bool NOT NULL default 0,
-  ipb_create_account bool NOT NULL default 1,
-  ipb_enable_autoblock bool NOT NULL default '1',
-  ipb_expiry varbinary(14) NOT NULL default '',
-  ipb_range_start tinyblob NOT NULL,
-  ipb_range_end tinyblob NOT NULL,
-  ipb_deleted bool NOT NULL default 0,
-  ipb_block_email bool NOT NULL default 0,
-  ipb_allow_usertalk bool NOT NULL default 0,
-  ipb_parent_block_id int default NULL
-) /*$wgDBTableOptions*/;
-
-INSERT OR IGNORE INTO /*_*/ipblocks_tmp (
-       ipb_id, ipb_address, ipb_user, ipb_by, ipb_by_text, ipb_reason,
-       ipb_timestamp, ipb_auto, ipb_anon_only, ipb_create_account,
-       ipb_enable_autoblock, ipb_expiry, ipb_range_start, ipb_range_end,
-       ipb_deleted, ipb_block_email, ipb_allow_usertalk, ipb_parent_block_id)
-  SELECT
-       ipb_id, ipb_address, ipb_user, ipb_by, ipb_by_text, ipb_reason,
-       ipb_timestamp, ipb_auto, ipb_anon_only, ipb_create_account,
-       ipb_enable_autoblock, ipb_expiry, ipb_range_start, ipb_range_end,
-       ipb_deleted, ipb_block_email, ipb_allow_usertalk, ipb_parent_block_id
-  FROM /*_*/ipblocks;
-
-DROP TABLE /*_*/ipblocks;
-ALTER TABLE /*_*/ipblocks_tmp RENAME TO /*_*/ipblocks;
-CREATE UNIQUE INDEX /*i*/ipb_address ON /*_*/ipblocks (ipb_address(255), ipb_user, ipb_auto, ipb_anon_only);
-CREATE INDEX /*i*/ipb_user ON /*_*/ipblocks (ipb_user);
-CREATE INDEX /*i*/ipb_range ON /*_*/ipblocks (ipb_range_start(8), ipb_range_end(8));
-CREATE INDEX /*i*/ipb_timestamp ON /*_*/ipblocks (ipb_timestamp);
-CREATE INDEX /*i*/ipb_expiry ON /*_*/ipblocks (ipb_expiry);
-CREATE INDEX /*i*/ipb_parent_block_id ON /*_*/ipblocks (ipb_parent_block_id);
-
-COMMIT;
-
-BEGIN;
-
-DROP TABLE IF EXISTS /*_*/image_tmp;
-CREATE TABLE /*_*/image_tmp (
-  img_name varchar(255) binary NOT NULL default '' PRIMARY KEY,
-  img_size int unsigned NOT NULL default 0,
-  img_width int NOT NULL default 0,
-  img_height int NOT NULL default 0,
-  img_metadata mediumblob NOT NULL,
-  img_bits int NOT NULL default 0,
-  img_media_type ENUM("UNKNOWN", "BITMAP", "DRAWING", "AUDIO", "VIDEO", "MULTIMEDIA", "OFFICE", "TEXT", "EXECUTABLE", "ARCHIVE", "3D") default NULL,
-  img_major_mime ENUM("unknown", "application", "audio", "image", "text", "video", "message", "model", "multipart", "chemical") NOT NULL default "unknown",
-  img_minor_mime varbinary(100) NOT NULL default "unknown",
-  img_description varbinary(767) NOT NULL default '',
-  img_user int unsigned NOT NULL default 0,
-  img_user_text varchar(255) binary NOT NULL,
-  img_timestamp varbinary(14) NOT NULL default '',
-  img_sha1 varbinary(32) NOT NULL default ''
-) /*$wgDBTableOptions*/;
-
-INSERT OR IGNORE INTO /*_*/image_tmp (
-       img_name, img_size, img_width, img_height, img_metadata, img_bits,
-       img_media_type, img_major_mime, img_minor_mime, img_description, img_user,
-       img_user_text, img_timestamp, img_sha1)
-  SELECT
-       img_name, img_size, img_width, img_height, img_metadata, img_bits,
-       img_media_type, img_major_mime, img_minor_mime, img_description, img_user,
-       img_user_text, img_timestamp, img_sha1
-  FROM /*_*/image;
-
-DROP TABLE /*_*/image;
-ALTER TABLE /*_*/image_tmp RENAME TO /*_*/image;
-CREATE INDEX /*i*/img_user_timestamp ON /*_*/image (img_user,img_timestamp);
-CREATE INDEX /*i*/img_usertext_timestamp ON /*_*/image (img_user_text,img_timestamp);
-CREATE INDEX /*i*/img_size ON /*_*/image (img_size);
-CREATE INDEX /*i*/img_timestamp ON /*_*/image (img_timestamp);
-CREATE INDEX /*i*/img_sha1 ON /*_*/image (img_sha1(10));
-CREATE INDEX /*i*/img_media_mime ON /*_*/image (img_media_type,img_major_mime,img_minor_mime);
-
-COMMIT;
-
-BEGIN;
-
-DROP TABLE IF EXISTS /*_*/oldimage_tmp;
-CREATE TABLE /*_*/oldimage_tmp (
-  oi_name varchar(255) binary NOT NULL default '',
-  oi_archive_name varchar(255) binary NOT NULL default '',
-  oi_size int unsigned NOT NULL default 0,
-  oi_width int NOT NULL default 0,
-  oi_height int NOT NULL default 0,
-  oi_bits int NOT NULL default 0,
-  oi_description varbinary(767) NOT NULL default '',
-  oi_description_id bigint unsigned NOT NULL DEFAULT 0,
-  oi_user int unsigned NOT NULL default 0,
-  oi_user_text varchar(255) binary NOT NULL,
-  oi_timestamp binary(14) NOT NULL default '',
-  oi_metadata mediumblob NOT NULL,
-  oi_media_type ENUM("UNKNOWN", "BITMAP", "DRAWING", "AUDIO", "VIDEO", "MULTIMEDIA", "OFFICE", "TEXT", "EXECUTABLE", "ARCHIVE", "3D") default NULL,
-  oi_major_mime ENUM("unknown", "application", "audio", "image", "text", "video", "message", "model", "multipart", "chemical") NOT NULL default "unknown",
-  oi_minor_mime varbinary(100) NOT NULL default "unknown",
-  oi_deleted tinyint unsigned NOT NULL default 0,
-  oi_sha1 varbinary(32) NOT NULL default ''
-) /*$wgDBTableOptions*/;
-
-INSERT OR IGNORE INTO /*_*/oldimage_tmp (
-       oi_name, oi_archive_name, oi_size, oi_width, oi_height, oi_bits,
-       oi_description, oi_user, oi_user_text, oi_timestamp, oi_metadata,
-       oi_media_type, oi_major_mime, oi_minor_mime, oi_deleted, oi_sha1)
-  SELECT
-       oi_name, oi_archive_name, oi_size, oi_width, oi_height, oi_bits,
-       oi_description, oi_user, oi_user_text, oi_timestamp, oi_metadata,
-       oi_media_type, oi_major_mime, oi_minor_mime, oi_deleted, oi_sha1
-  FROM /*_*/oldimage;
-
-DROP TABLE /*_*/oldimage;
-ALTER TABLE /*_*/oldimage_tmp RENAME TO /*_*/oldimage;
-CREATE INDEX /*i*/oi_usertext_timestamp ON /*_*/oldimage (oi_user_text,oi_timestamp);
-CREATE INDEX /*i*/oi_name_timestamp ON /*_*/oldimage (oi_name,oi_timestamp);
-CREATE INDEX /*i*/oi_name_archive_name ON /*_*/oldimage (oi_name,oi_archive_name(14));
-CREATE INDEX /*i*/oi_sha1 ON /*_*/oldimage (oi_sha1(10));
-
-COMMIT;
-
--- filearchive is done in patch-filearchive-fa_description_id.sql
-
-BEGIN;
-
-DROP TABLE IF EXISTS /*_*/protected_titles_tmp;
-CREATE TABLE /*_*/protected_titles_tmp (
-  pt_namespace int NOT NULL,
-  pt_title varchar(255) binary NOT NULL,
-  pt_user int unsigned NOT NULL,
-  pt_reason varbinary(767) default '',
-  pt_reason_id bigint unsigned NOT NULL DEFAULT 0,
-  pt_timestamp binary(14) NOT NULL,
-  pt_expiry varbinary(14) NOT NULL default '',
-  pt_create_perm varbinary(60) NOT NULL
-) /*$wgDBTableOptions*/;
-
-INSERT OR IGNORE INTO /*_*/protected_titles_tmp (
-       pt_namespace, pt_title, pt_user, pt_reason, pt_timestamp, pt_expiry, pt_create_perm)
-  SELECT
-       pt_namespace, pt_title, pt_user, pt_reason, pt_timestamp, pt_expiry, pt_create_perm
-  FROM /*_*/protected_titles;
-
-DROP TABLE /*_*/protected_titles;
-ALTER TABLE /*_*/protected_titles_tmp RENAME TO /*_*/protected_titles;
-CREATE UNIQUE INDEX /*i*/pt_namespace_title ON /*_*/protected_titles (pt_namespace,pt_title);
-CREATE INDEX /*i*/pt_timestamp ON /*_*/protected_titles (pt_timestamp);
-
-COMMIT;
diff --git a/maintenance/sqlite/archives/patch-image-img_description-default.sql b/maintenance/sqlite/archives/patch-image-img_description-default.sql
new file mode 100644 (file)
index 0000000..b810ed5
--- /dev/null
@@ -0,0 +1,40 @@
+BEGIN;
+
+DROP TABLE IF EXISTS /*_*/image_tmp;
+CREATE TABLE /*_*/image_tmp (
+  img_name varchar(255) binary NOT NULL default '' PRIMARY KEY,
+  img_size int unsigned NOT NULL default 0,
+  img_width int NOT NULL default 0,
+  img_height int NOT NULL default 0,
+  img_metadata mediumblob NOT NULL,
+  img_bits int NOT NULL default 0,
+  img_media_type ENUM("UNKNOWN", "BITMAP", "DRAWING", "AUDIO", "VIDEO", "MULTIMEDIA", "OFFICE", "TEXT", "EXECUTABLE", "ARCHIVE", "3D") default NULL,
+  img_major_mime ENUM("unknown", "application", "audio", "image", "text", "video", "message", "model", "multipart", "chemical") NOT NULL default "unknown",
+  img_minor_mime varbinary(100) NOT NULL default "unknown",
+  img_description varbinary(767) NOT NULL default '',
+  img_user int unsigned NOT NULL default 0,
+  img_user_text varchar(255) binary NOT NULL,
+  img_timestamp varbinary(14) NOT NULL default '',
+  img_sha1 varbinary(32) NOT NULL default ''
+) /*$wgDBTableOptions*/;
+
+INSERT OR IGNORE INTO /*_*/image_tmp (
+       img_name, img_size, img_width, img_height, img_metadata, img_bits,
+       img_media_type, img_major_mime, img_minor_mime, img_description, img_user,
+       img_user_text, img_timestamp, img_sha1)
+  SELECT
+       img_name, img_size, img_width, img_height, img_metadata, img_bits,
+       img_media_type, img_major_mime, img_minor_mime, img_description, img_user,
+       img_user_text, img_timestamp, img_sha1
+  FROM /*_*/image;
+
+DROP TABLE /*_*/image;
+ALTER TABLE /*_*/image_tmp RENAME TO /*_*/image;
+CREATE INDEX /*i*/img_user_timestamp ON /*_*/image (img_user,img_timestamp);
+CREATE INDEX /*i*/img_usertext_timestamp ON /*_*/image (img_user_text,img_timestamp);
+CREATE INDEX /*i*/img_size ON /*_*/image (img_size);
+CREATE INDEX /*i*/img_timestamp ON /*_*/image (img_timestamp);
+CREATE INDEX /*i*/img_sha1 ON /*_*/image (img_sha1(10));
+CREATE INDEX /*i*/img_media_mime ON /*_*/image (img_media_type,img_major_mime,img_minor_mime);
+
+COMMIT;
diff --git a/maintenance/sqlite/archives/patch-ipblocks-ipb_reason_id.sql b/maintenance/sqlite/archives/patch-ipblocks-ipb_reason_id.sql
new file mode 100644 (file)
index 0000000..b1079fc
--- /dev/null
@@ -0,0 +1,47 @@
+BEGIN;
+
+DROP TABLE IF EXISTS ipblocks_tmp;
+CREATE TABLE /*_*/ipblocks_tmp (
+  ipb_id int NOT NULL PRIMARY KEY AUTO_INCREMENT,
+  ipb_address tinyblob NOT NULL,
+  ipb_user int unsigned NOT NULL default 0,
+  ipb_by int unsigned NOT NULL default 0,
+  ipb_by_text varchar(255) binary NOT NULL default '',
+  ipb_reason varbinary(767) NOT NULL default '',
+  ipb_reason_id bigint unsigned NOT NULL DEFAULT 0,
+  ipb_timestamp binary(14) NOT NULL default '',
+  ipb_auto bool NOT NULL default 0,
+  ipb_anon_only bool NOT NULL default 0,
+  ipb_create_account bool NOT NULL default 1,
+  ipb_enable_autoblock bool NOT NULL default '1',
+  ipb_expiry varbinary(14) NOT NULL default '',
+  ipb_range_start tinyblob NOT NULL,
+  ipb_range_end tinyblob NOT NULL,
+  ipb_deleted bool NOT NULL default 0,
+  ipb_block_email bool NOT NULL default 0,
+  ipb_allow_usertalk bool NOT NULL default 0,
+  ipb_parent_block_id int default NULL
+) /*$wgDBTableOptions*/;
+
+INSERT OR IGNORE INTO /*_*/ipblocks_tmp (
+       ipb_id, ipb_address, ipb_user, ipb_by, ipb_by_text, ipb_reason,
+       ipb_timestamp, ipb_auto, ipb_anon_only, ipb_create_account,
+       ipb_enable_autoblock, ipb_expiry, ipb_range_start, ipb_range_end,
+       ipb_deleted, ipb_block_email, ipb_allow_usertalk, ipb_parent_block_id)
+  SELECT
+       ipb_id, ipb_address, ipb_user, ipb_by, ipb_by_text, ipb_reason,
+       ipb_timestamp, ipb_auto, ipb_anon_only, ipb_create_account,
+       ipb_enable_autoblock, ipb_expiry, ipb_range_start, ipb_range_end,
+       ipb_deleted, ipb_block_email, ipb_allow_usertalk, ipb_parent_block_id
+  FROM /*_*/ipblocks;
+
+DROP TABLE /*_*/ipblocks;
+ALTER TABLE /*_*/ipblocks_tmp RENAME TO /*_*/ipblocks;
+CREATE UNIQUE INDEX /*i*/ipb_address ON /*_*/ipblocks (ipb_address(255), ipb_user, ipb_auto, ipb_anon_only);
+CREATE INDEX /*i*/ipb_user ON /*_*/ipblocks (ipb_user);
+CREATE INDEX /*i*/ipb_range ON /*_*/ipblocks (ipb_range_start(8), ipb_range_end(8));
+CREATE INDEX /*i*/ipb_timestamp ON /*_*/ipblocks (ipb_timestamp);
+CREATE INDEX /*i*/ipb_expiry ON /*_*/ipblocks (ipb_expiry);
+CREATE INDEX /*i*/ipb_parent_block_id ON /*_*/ipblocks (ipb_parent_block_id);
+
+COMMIT;
diff --git a/maintenance/sqlite/archives/patch-logging-log_comment_id.sql b/maintenance/sqlite/archives/patch-logging-log_comment_id.sql
new file mode 100644 (file)
index 0000000..784a88d
--- /dev/null
@@ -0,0 +1,2 @@
+ALTER TABLE /*_*/logging
+  ADD COLUMN log_comment_id bigint unsigned NOT NULL DEFAULT 0;
diff --git a/maintenance/sqlite/archives/patch-oldimage-oi_description_id.sql b/maintenance/sqlite/archives/patch-oldimage-oi_description_id.sql
new file mode 100644 (file)
index 0000000..c0191a7
--- /dev/null
@@ -0,0 +1,41 @@
+BEGIN;
+
+DROP TABLE IF EXISTS /*_*/oldimage_tmp;
+CREATE TABLE /*_*/oldimage_tmp (
+  oi_name varchar(255) binary NOT NULL default '',
+  oi_archive_name varchar(255) binary NOT NULL default '',
+  oi_size int unsigned NOT NULL default 0,
+  oi_width int NOT NULL default 0,
+  oi_height int NOT NULL default 0,
+  oi_bits int NOT NULL default 0,
+  oi_description varbinary(767) NOT NULL default '',
+  oi_description_id bigint unsigned NOT NULL DEFAULT 0,
+  oi_user int unsigned NOT NULL default 0,
+  oi_user_text varchar(255) binary NOT NULL,
+  oi_timestamp binary(14) NOT NULL default '',
+  oi_metadata mediumblob NOT NULL,
+  oi_media_type ENUM("UNKNOWN", "BITMAP", "DRAWING", "AUDIO", "VIDEO", "MULTIMEDIA", "OFFICE", "TEXT", "EXECUTABLE", "ARCHIVE", "3D") default NULL,
+  oi_major_mime ENUM("unknown", "application", "audio", "image", "text", "video", "message", "model", "multipart", "chemical") NOT NULL default "unknown",
+  oi_minor_mime varbinary(100) NOT NULL default "unknown",
+  oi_deleted tinyint unsigned NOT NULL default 0,
+  oi_sha1 varbinary(32) NOT NULL default ''
+) /*$wgDBTableOptions*/;
+
+INSERT OR IGNORE INTO /*_*/oldimage_tmp (
+       oi_name, oi_archive_name, oi_size, oi_width, oi_height, oi_bits,
+       oi_description, oi_user, oi_user_text, oi_timestamp, oi_metadata,
+       oi_media_type, oi_major_mime, oi_minor_mime, oi_deleted, oi_sha1)
+  SELECT
+       oi_name, oi_archive_name, oi_size, oi_width, oi_height, oi_bits,
+       oi_description, oi_user, oi_user_text, oi_timestamp, oi_metadata,
+       oi_media_type, oi_major_mime, oi_minor_mime, oi_deleted, oi_sha1
+  FROM /*_*/oldimage;
+
+DROP TABLE /*_*/oldimage;
+ALTER TABLE /*_*/oldimage_tmp RENAME TO /*_*/oldimage;
+CREATE INDEX /*i*/oi_usertext_timestamp ON /*_*/oldimage (oi_user_text,oi_timestamp);
+CREATE INDEX /*i*/oi_name_timestamp ON /*_*/oldimage (oi_name,oi_timestamp);
+CREATE INDEX /*i*/oi_name_archive_name ON /*_*/oldimage (oi_name,oi_archive_name(14));
+CREATE INDEX /*i*/oi_sha1 ON /*_*/oldimage (oi_sha1(10));
+
+COMMIT;
diff --git a/maintenance/sqlite/archives/patch-protected_titles-pt_reason_id.sql b/maintenance/sqlite/archives/patch-protected_titles-pt_reason_id.sql
new file mode 100644 (file)
index 0000000..793144c
--- /dev/null
@@ -0,0 +1,26 @@
+BEGIN;
+
+DROP TABLE IF EXISTS /*_*/protected_titles_tmp;
+CREATE TABLE /*_*/protected_titles_tmp (
+  pt_namespace int NOT NULL,
+  pt_title varchar(255) binary NOT NULL,
+  pt_user int unsigned NOT NULL,
+  pt_reason varbinary(767) default '',
+  pt_reason_id bigint unsigned NOT NULL DEFAULT 0,
+  pt_timestamp binary(14) NOT NULL,
+  pt_expiry varbinary(14) NOT NULL default '',
+  pt_create_perm varbinary(60) NOT NULL
+) /*$wgDBTableOptions*/;
+
+INSERT OR IGNORE INTO /*_*/protected_titles_tmp (
+       pt_namespace, pt_title, pt_user, pt_reason, pt_timestamp, pt_expiry, pt_create_perm)
+  SELECT
+       pt_namespace, pt_title, pt_user, pt_reason, pt_timestamp, pt_expiry, pt_create_perm
+  FROM /*_*/protected_titles;
+
+DROP TABLE /*_*/protected_titles;
+ALTER TABLE /*_*/protected_titles_tmp RENAME TO /*_*/protected_titles;
+CREATE UNIQUE INDEX /*i*/pt_namespace_title ON /*_*/protected_titles (pt_namespace,pt_title);
+CREATE INDEX /*i*/pt_timestamp ON /*_*/protected_titles (pt_timestamp);
+
+COMMIT;
diff --git a/maintenance/sqlite/archives/patch-recentchanges-rc_comment_id.sql b/maintenance/sqlite/archives/patch-recentchanges-rc_comment_id.sql
new file mode 100644 (file)
index 0000000..55bf9b5
--- /dev/null
@@ -0,0 +1,2 @@
+ALTER TABLE /*_*/recentchanges
+  ADD COLUMN rc_comment_id bigint unsigned NOT NULL DEFAULT 0;
diff --git a/maintenance/sqlite/archives/patch-revision-rev_comment-default.sql b/maintenance/sqlite/archives/patch-revision-rev_comment-default.sql
new file mode 100644 (file)
index 0000000..0194079
--- /dev/null
@@ -0,0 +1,40 @@
+BEGIN;
+
+DROP TABLE IF EXISTS /*_*/revision_tmp;
+CREATE TABLE /*_*/revision_tmp (
+  rev_id int unsigned NOT NULL PRIMARY KEY AUTO_INCREMENT,
+  rev_page int unsigned NOT NULL,
+  rev_text_id int unsigned NOT NULL,
+  rev_comment varbinary(767) NOT NULL default '',
+  rev_user int unsigned NOT NULL default 0,
+  rev_user_text varchar(255) binary NOT NULL default '',
+  rev_timestamp binary(14) NOT NULL default '',
+  rev_minor_edit tinyint unsigned NOT NULL default 0,
+  rev_deleted tinyint unsigned NOT NULL default 0,
+  rev_len int unsigned,
+  rev_parent_id int unsigned default NULL,
+  rev_sha1 varbinary(32) NOT NULL default '',
+  rev_content_model varbinary(32) DEFAULT NULL,
+  rev_content_format varbinary(64) DEFAULT NULL
+) /*$wgDBTableOptions*/ MAX_ROWS=10000000 AVG_ROW_LENGTH=1024;
+
+INSERT OR IGNORE INTO /*_*/revision_tmp (
+       rev_id, rev_page, rev_text_id, rev_comment, rev_user, rev_user_text,
+       rev_timestamp, rev_minor_edit, rev_deleted, rev_len, rev_parent_id,
+       rev_sha1, rev_content_model, rev_content_format)
+ SELECT
+       rev_id, rev_page, rev_text_id, rev_comment, rev_user, rev_user_text,
+       rev_timestamp, rev_minor_edit, rev_deleted, rev_len, rev_parent_id,
+       rev_sha1, rev_content_model, rev_content_format
+  FROM /*_*/revision;
+
+DROP TABLE /*_*/revision;
+ALTER TABLE /*_*/revision_tmp RENAME TO /*_*/revision;
+CREATE INDEX /*i*/rev_page_id ON /*_*/revision (rev_page, rev_id);
+CREATE INDEX /*i*/rev_timestamp ON /*_*/revision (rev_timestamp);
+CREATE INDEX /*i*/page_timestamp ON /*_*/revision (rev_page,rev_timestamp);
+CREATE INDEX /*i*/user_timestamp ON /*_*/revision (rev_user,rev_timestamp);
+CREATE INDEX /*i*/usertext_timestamp ON /*_*/revision (rev_user_text,rev_timestamp);
+CREATE INDEX /*i*/page_user_timestamp ON /*_*/revision (rev_page,rev_user,rev_timestamp);
+
+COMMIT;
index 37625cf..3741959 100644 (file)
@@ -556,10 +556,27 @@ class CheckStorage {
 
                // Find text row again
                $dbr = wfGetDB( DB_REPLICA );
-               $oldId = $dbr->selectField( 'revision', 'rev_text_id', [ 'rev_id' => $id ], __METHOD__ );
+               global $wgMultiContentRevisionSchemaMigrationStage;
+               if ( $wgMultiContentRevisionSchemaMigrationStage & SCHEMA_COMPAT_READ_OLD ) {
+                       $oldId = $dbr->selectField( 'revision', 'rev_text_id', [ 'rev_id' => $id ], __METHOD__ );
+               } else {
+                       $res = $dbr->selectRow(
+                               [ 'slots', 'content' ],
+                               [ 'content_address' ],
+                               [ 'slot_revision_id' => $id ],
+                               __METHOD__,
+                               [],
+                               [ 'content' => [ 'INNER JOIN', [ 'content_id = slot_content_id' ] ] ]
+                       );
+                       // @phan-suppress-next-line PhanAccessMethodInternal
+                       $blobStore = MediaWikiServices::getInstance()
+                               ->getBlobStoreFactory()
+                               ->newSqlBlobStore();
+                       $oldId = $blobStore->getTextIdFromAddress( $res->content_address );
+               }
+
                if ( !$oldId ) {
                        echo "Missing revision row for rev_id $id\n";
-
                        return;
                }
 
index b6aa626..c4779b9 100644 (file)
@@ -239,6 +239,10 @@ class CompressOld extends Maintenance {
                        /** @var ExternalStoreDB $storeObj */
                        $storeObj = $esFactory->getStore( 'DB' );
                }
+               // @phan-suppress-next-line PhanAccessMethodInternal
+               $blobStore = MediaWikiServices::getInstance()
+                       ->getBlobStoreFactory()
+                       ->newSqlBlobStore();
 
                # Get all articles by page_id
                if ( !$maxPageId ) {
@@ -370,8 +374,12 @@ class CompressOld extends Maintenance {
                                for ( $j = 0; $j < $thisChunkSize && $chunk->isHappy(); $j++ ) {
                                        $oldid = $revs[$i + $j]->old_id;
 
-                                       # Get text
-                                       $text = Revision::getRevisionText( $revs[$i + $j] );
+                                       # Get text. We do not need the full `extractBlob` since the query is built
+                                       # to fetch non-externalstore blobs.
+                                       $text = $blobStore->decompressData(
+                                               $revs[$i + $j]->old_text,
+                                               explode( ',', $revs[$i + $j]->old_flags )
+                                       );
 
                                        if ( $text === false ) {
                                                $this->error( "\nError, unable to get text in old_id $oldid" );
diff --git a/maintenance/storage/fixT22757.php b/maintenance/storage/fixT22757.php
deleted file mode 100644 (file)
index 61f1177..0000000
+++ /dev/null
@@ -1,335 +0,0 @@
-<?php
-/**
- * Script to fix T22757.
- *
- * 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
- * @ingroup Maintenance ExternalStorage
- */
-
-require_once __DIR__ . '/../Maintenance.php';
-
-/**
- * Maintenance script to fix T22757.
- *
- * @ingroup Maintenance ExternalStorage
- */
-class FixT22757 extends Maintenance {
-       public $batchSize = 10000;
-       public $mapCache = [];
-       public $mapCacheSize = 0;
-       public $maxMapCacheSize = 1000000;
-
-       function __construct() {
-               parent::__construct();
-               $this->addDescription( 'Script to fix T22757 assuming that blob_tracking is intact' );
-               $this->addOption( 'dry-run', 'Report only' );
-               $this->addOption( 'start', 'old_id to start at', false, true );
-       }
-
-       function execute() {
-               $dbr = $this->getDB( DB_REPLICA );
-               $dbw = $this->getDB( DB_MASTER );
-
-               $dryRun = $this->getOption( 'dry-run' );
-               if ( $dryRun ) {
-                       print "Dry run only.\n";
-               }
-
-               $startId = $this->getOption( 'start', 0 );
-               $numGood = 0;
-               $numFixed = 0;
-               $numBad = 0;
-
-               $totalRevs = $dbr->selectField( 'text', 'MAX(old_id)', '', __METHOD__ );
-
-               // In MySQL 4.1+, the binary field old_text has a non-working LOWER() function
-               $lowerLeft = 'LOWER(CONVERT(LEFT(old_text,22) USING latin1))';
-
-               while ( true ) {
-                       print "ID: $startId / $totalRevs\r";
-
-                       $res = $dbr->select(
-                               'text',
-                               [ 'old_id', 'old_flags', 'old_text' ],
-                               [
-                                       'old_id > ' . intval( $startId ),
-                                       'old_flags LIKE \'%object%\' AND old_flags NOT LIKE \'%external%\'',
-                                       "$lowerLeft = 'o:15:\"historyblobstub\"'",
-                               ],
-                               __METHOD__,
-                               [
-                                       'ORDER BY' => 'old_id',
-                                       'LIMIT' => $this->batchSize,
-                               ]
-                       );
-
-                       if ( !$res->numRows() ) {
-                               break;
-                       }
-
-                       $secondaryIds = [];
-                       $stubs = [];
-
-                       foreach ( $res as $row ) {
-                               $startId = $row->old_id;
-
-                               // Basic sanity checks
-                               $obj = unserialize( $row->old_text );
-                               if ( $obj === false ) {
-                                       print "{$row->old_id}: unrecoverable: cannot unserialize\n";
-                                       ++$numBad;
-                                       continue;
-                               }
-
-                               if ( !is_object( $obj ) ) {
-                                       print "{$row->old_id}: unrecoverable: unserialized to type " .
-                                               gettype( $obj ) . ", possible double-serialization\n";
-                                       ++$numBad;
-                                       continue;
-                               }
-
-                               if ( strtolower( get_class( $obj ) ) !== 'historyblobstub' ) {
-                                       print "{$row->old_id}: unrecoverable: unexpected object class " .
-                                               get_class( $obj ) . "\n";
-                                       ++$numBad;
-                                       continue;
-                               }
-
-                               // Process flags
-                               $flags = explode( ',', $row->old_flags );
-                               if ( in_array( 'utf-8', $flags ) || in_array( 'utf8', $flags ) ) {
-                                       $legacyEncoding = false;
-                               } else {
-                                       $legacyEncoding = true;
-                               }
-
-                               // Queue the stub for future batch processing
-                               $id = intval( $obj->mOldId );
-                               $secondaryIds[] = $id;
-                               $stubs[$row->old_id] = [
-                                       'legacyEncoding' => $legacyEncoding,
-                                       'secondaryId' => $id,
-                                       'hash' => $obj->mHash,
-                               ];
-                       }
-
-                       $secondaryIds = array_unique( $secondaryIds );
-
-                       if ( !count( $secondaryIds ) ) {
-                               continue;
-                       }
-
-                       // Run the batch query on blob_tracking
-                       $res = $dbr->select(
-                               'blob_tracking',
-                               '*',
-                               [
-                                       'bt_text_id' => $secondaryIds,
-                               ],
-                               __METHOD__
-                       );
-                       $trackedBlobs = [];
-                       foreach ( $res as $row ) {
-                               $trackedBlobs[$row->bt_text_id] = $row;
-                       }
-
-                       // Process the stubs
-                       foreach ( $stubs as $primaryId => $stub ) {
-                               $secondaryId = $stub['secondaryId'];
-                               if ( !isset( $trackedBlobs[$secondaryId] ) ) {
-                                       // No tracked blob. Work out what went wrong
-                                       $secondaryRow = $dbr->selectRow(
-                                               'text',
-                                               [ 'old_flags', 'old_text' ],
-                                               [ 'old_id' => $secondaryId ],
-                                               __METHOD__
-                                       );
-                                       if ( !$secondaryRow ) {
-                                               print "$primaryId: unrecoverable: secondary row is missing\n";
-                                               ++$numBad;
-                                       } elseif ( $this->isUnbrokenStub( $stub, $secondaryRow ) ) {
-                                               // Not broken yet, and not in the tracked clusters so it won't get
-                                               // broken by the current RCT run.
-                                               ++$numGood;
-                                       } elseif ( strpos( $secondaryRow->old_flags, 'external' ) !== false ) {
-                                               print "$primaryId: unrecoverable: secondary gone to {$secondaryRow->old_text}\n";
-                                               ++$numBad;
-                                       } else {
-                                               print "$primaryId: unrecoverable: miscellaneous corruption of secondary row\n";
-                                               ++$numBad;
-                                       }
-                                       unset( $stubs[$primaryId] );
-                                       continue;
-                               }
-                               $trackRow = $trackedBlobs[$secondaryId];
-
-                               // Check that the specified text really is available in the tracked source row
-                               $url = "DB://{$trackRow->bt_cluster}/{$trackRow->bt_blob_id}/{$stub['hash']}";
-                               $text = ExternalStore::fetchFromURL( $url );
-                               if ( $text === false ) {
-                                       print "$primaryId: unrecoverable: source text missing\n";
-                                       ++$numBad;
-                                       unset( $stubs[$primaryId] );
-                                       continue;
-                               }
-                               if ( md5( $text ) !== $stub['hash'] ) {
-                                       print "$primaryId: unrecoverable: content hashes do not match\n";
-                                       ++$numBad;
-                                       unset( $stubs[$primaryId] );
-                                       continue;
-                               }
-
-                               // Find the page_id and rev_id
-                               // The page is probably the same as the page of the secondary row
-                               $pageId = intval( $trackRow->bt_page );
-                               if ( !$pageId ) {
-                                       $revId = $pageId = 0;
-                               } else {
-                                       $revId = $this->findTextIdInPage( $pageId, $primaryId );
-                                       if ( !$revId ) {
-                                               // Actually an orphan
-                                               $pageId = $revId = 0;
-                                       }
-                               }
-
-                               $newFlags = $stub['legacyEncoding'] ? 'external' : 'external,utf-8';
-
-                               if ( !$dryRun ) {
-                                       // Reset the text row to point to the original copy
-                                       $this->beginTransaction( $dbw, __METHOD__ );
-                                       $dbw->update(
-                                               'text',
-                                               // SET
-                                               [
-                                                       'old_flags' => $newFlags,
-                                                       'old_text' => $url
-                                               ],
-                                               // WHERE
-                                               [ 'old_id' => $primaryId ],
-                                               __METHOD__
-                                       );
-
-                                       // Add a blob_tracking row so that the new reference can be recompressed
-                                       // without needing to run trackBlobs.php again
-                                       $dbw->insert( 'blob_tracking',
-                                               [
-                                                       'bt_page' => $pageId,
-                                                       'bt_rev_id' => $revId,
-                                                       'bt_text_id' => $primaryId,
-                                                       'bt_cluster' => $trackRow->bt_cluster,
-                                                       'bt_blob_id' => $trackRow->bt_blob_id,
-                                                       'bt_cgz_hash' => $stub['hash'],
-                                                       'bt_new_url' => null,
-                                                       'bt_moved' => 0,
-                                               ],
-                                               __METHOD__
-                                       );
-                                       $this->commitTransaction( $dbw, __METHOD__ );
-                               }
-
-                               print "$primaryId: resolved to $url\n";
-                               ++$numFixed;
-                       }
-               }
-
-               print "\n";
-               print "Fixed: $numFixed\n";
-               print "Unrecoverable: $numBad\n";
-               print "Good stubs: $numGood\n";
-       }
-
-       function findTextIdInPage( $pageId, $textId ) {
-               $ids = $this->getRevTextMap( $pageId );
-               return $ids[$textId] ?? null;
-       }
-
-       function getRevTextMap( $pageId ) {
-               if ( !isset( $this->mapCache[$pageId] ) ) {
-                       // Limit cache size
-                       while ( $this->mapCacheSize > $this->maxMapCacheSize ) {
-                               $key = key( $this->mapCache );
-                               $this->mapCacheSize -= count( $this->mapCache[$key] );
-                               unset( $this->mapCache[$key] );
-                       }
-
-                       $dbr = $this->getDB( DB_REPLICA );
-                       $map = [];
-                       $res = $dbr->select( 'revision',
-                               [ 'rev_id', 'rev_text_id' ],
-                               [ 'rev_page' => $pageId ],
-                               __METHOD__
-                       );
-                       foreach ( $res as $row ) {
-                               $map[$row->rev_text_id] = $row->rev_id;
-                       }
-                       $this->mapCache[$pageId] = $map;
-                       $this->mapCacheSize += count( $map );
-               }
-
-               return $this->mapCache[$pageId];
-       }
-
-       /**
-        * This is based on part of HistoryBlobStub::getText().
-        * Determine if the text can be retrieved from the row in the normal way.
-        * @param array $stub
-        * @param stdClass $secondaryRow
-        * @return bool
-        */
-       function isUnbrokenStub( $stub, $secondaryRow ) {
-               $flags = explode( ',', $secondaryRow->old_flags );
-               $text = $secondaryRow->old_text;
-               if ( in_array( 'external', $flags ) ) {
-                       $url = $text;
-                       Wikimedia\suppressWarnings();
-                       list( /* $proto */, $path ) = explode( '://', $url, 2 );
-                       Wikimedia\restoreWarnings();
-
-                       if ( $path == "" ) {
-                               return false;
-                       }
-                       $text = ExternalStore::fetchFromURL( $url );
-               }
-               if ( !in_array( 'object', $flags ) ) {
-                       return false;
-               }
-
-               if ( in_array( 'gzip', $flags ) ) {
-                       $obj = unserialize( gzinflate( $text ) );
-               } else {
-                       $obj = unserialize( $text );
-               }
-
-               if ( !is_object( $obj ) ) {
-                       // Correct for old double-serialization bug.
-                       $obj = unserialize( $obj );
-               }
-
-               if ( !is_object( $obj ) ) {
-                       return false;
-               }
-
-               $obj->uncompress();
-               $text = $obj->getItem( $stub['hash'] );
-
-               return $text !== false;
-       }
-}
-
-$maintClass = FixT22757::class;
-require_once RUN_MAINTENANCE_IF_MAIN;
index 9f20e67..0068046 100644 (file)
@@ -22,6 +22,7 @@
  * @ingroup Maintenance ExternalStorage
  */
 
+use MediaWiki\Storage\SqlBlobStore;
 use Wikimedia\Rdbms\IMaintainableDatabase;
 use MediaWiki\Logger\LegacyLogger;
 use MediaWiki\MediaWikiServices;
@@ -63,18 +64,20 @@ class RecompressTracked {
        public $numProcs = 1;
        public $numBatches = 0;
        public $pageBlobClass, $orphanBlobClass;
-       public $replicaPipes, $replicaProcs, $prevReplicaId;
+       public $childPipes, $childProcs, $prevChildId;
        public $copyOnly = false;
        public $isChild = false;
-       public $replicaId = false;
+       public $childId = false;
        public $noCount = false;
        public $debugLog, $infoLog, $criticalLog;
        /** @var ExternalStoreDB */
        public $store;
+       /** @var SqlBlobStore */
+       private $blobStore;
 
        private static $optionsWithArgs = [
                'procs',
-               'replica-id',
+               'child-id',
                'debug-log',
                'info-log',
                'critical-log'
@@ -85,7 +88,7 @@ class RecompressTracked {
                'procs' => 'numProcs',
                'copy-only' => 'copyOnly',
                'child' => 'isChild',
-               'replica-id' => 'replicaId',
+               'child-id' => 'childId',
                'debug-log' => 'debugLog',
                'info-log' => 'infoLog',
                'critical-log' => 'criticalLog',
@@ -114,12 +117,16 @@ class RecompressTracked {
                $this->store = $esFactory->getStore( 'DB' );
                if ( !$this->isChild ) {
                        $GLOBALS['wgDebugLogPrefix'] = "RCT M: ";
-               } elseif ( $this->replicaId !== false ) {
-                       $GLOBALS['wgDebugLogPrefix'] = "RCT {$this->replicaId}: ";
+               } elseif ( $this->childId !== false ) {
+                       $GLOBALS['wgDebugLogPrefix'] = "RCT {$this->childId}: ";
                }
                $this->pageBlobClass = function_exists( 'xdiff_string_bdiff' ) ?
                        DiffHistoryBlob::class : ConcatenatedGzipHistoryBlob::class;
                $this->orphanBlobClass = ConcatenatedGzipHistoryBlob::class;
+               // @phan-suppress-next-line PhanAccessMethodInternal
+               $this->blobStore = MediaWikiServices::getInstance()
+                       ->getBlobStoreFactory()
+                       ->newSqlBlobStore();
        }
 
        function debug( $msg ) {
@@ -145,8 +152,8 @@ class RecompressTracked {
 
        function logToFile( $msg, $file ) {
                $header = '[' . date( 'd\TH:i:s' ) . '] ' . wfHostname() . ' ' . posix_getpid();
-               if ( $this->replicaId !== false ) {
-                       $header .= "({$this->replicaId})";
+               if ( $this->childId !== false ) {
+                       $header .= "({$this->childId})";
                }
                $header .= ' ' . WikiMap::getCurrentWikiDbDomain()->getId();
                LegacyLogger::emit( sprintf( "%-50s %s\n", $header, $msg ), $file );
@@ -184,10 +191,10 @@ class RecompressTracked {
                }
 
                $this->syncDBs();
-               $this->startReplicaProcs();
+               $this->startChildProcs();
                $this->doAllPages();
                $this->doAllOrphans();
-               $this->killReplicaProcs();
+               $this->killChildProcs();
        }
 
        /**
@@ -217,12 +224,12 @@ class RecompressTracked {
         * This necessary because text recompression is slow: loading, compressing and
         * writing are all slow.
         */
-       function startReplicaProcs() {
+       function startChildProcs() {
                $wiki = WikiMap::getWikiIdFromDbDomain( WikiMap::getCurrentWikiDbDomain() );
 
                $cmd = 'php ' . Shell::escape( __FILE__ );
                foreach ( self::$cmdLineOptionMap as $cmdOption => $classOption ) {
-                       if ( $cmdOption == 'replica-id' ) {
+                       if ( $cmdOption == 'child-id' ) {
                                continue;
                        } elseif ( in_array( $cmdOption, self::$optionsWithArgs ) && isset( $this->$classOption ) ) {
                                $cmd .= " --$cmdOption " . Shell::escape( $this->$classOption );
@@ -234,7 +241,7 @@ class RecompressTracked {
                        ' --wiki ' . Shell::escape( $wiki ) .
                        ' ' . Shell::escape( ...$this->destClusters );
 
-               $this->replicaPipes = $this->replicaProcs = [];
+               $this->childPipes = $this->childProcs = [];
                for ( $i = 0; $i < $this->numProcs; $i++ ) {
                        $pipes = [];
                        $spec = [
@@ -243,28 +250,28 @@ class RecompressTracked {
                                [ 'file', 'php://stderr', 'w' ]
                        ];
                        Wikimedia\suppressWarnings();
-                       $proc = proc_open( "$cmd --replica-id $i", $spec, $pipes );
+                       $proc = proc_open( "$cmd --child-id $i", $spec, $pipes );
                        Wikimedia\restoreWarnings();
                        if ( !$proc ) {
-                               $this->critical( "Error opening replica DB process: $cmd" );
+                               $this->critical( "Error opening child process: $cmd" );
                                exit( 1 );
                        }
-                       $this->replicaProcs[$i] = $proc;
-                       $this->replicaPipes[$i] = $pipes[0];
+                       $this->childProcs[$i] = $proc;
+                       $this->childPipes[$i] = $pipes[0];
                }
-               $this->prevReplicaId = -1;
+               $this->prevChildId = -1;
        }
 
        /**
         * Gracefully terminate the child processes
         */
-       function killReplicaProcs() {
-               $this->info( "Waiting for replica DB processes to finish..." );
+       function killChildProcs() {
+               $this->info( "Waiting for child processes to finish..." );
                for ( $i = 0; $i < $this->numProcs; $i++ ) {
-                       $this->dispatchToReplica( $i, 'quit' );
+                       $this->dispatchToChild( $i, 'quit' );
                }
                for ( $i = 0; $i < $this->numProcs; $i++ ) {
-                       $status = proc_close( $this->replicaProcs[$i] );
+                       $status = proc_close( $this->childProcs[$i] );
                        if ( $status ) {
                                $this->critical( "Warning: child #$i exited with status $status" );
                        }
@@ -273,24 +280,24 @@ class RecompressTracked {
        }
 
        /**
-        * Dispatch a command to the next available replica DB.
-        * This may block until a replica DB finishes its work and becomes available.
+        * Dispatch a command to the next available child process.
+        * This may block until a child process finishes its work and becomes available.
         * @param array|string ...$args
         */
        function dispatch( ...$args ) {
-               $pipes = $this->replicaPipes;
+               $pipes = $this->childPipes;
                $x = [];
                $y = [];
                $numPipes = stream_select( $x, $pipes, $y, 3600 );
                if ( !$numPipes ) {
-                       $this->critical( "Error waiting to write to replica DBs. Aborting" );
+                       $this->critical( "Error waiting to write to child process. Aborting" );
                        exit( 1 );
                }
                for ( $i = 0; $i < $this->numProcs; $i++ ) {
-                       $replicaId = ( $i + $this->prevReplicaId + 1 ) % $this->numProcs;
-                       if ( isset( $pipes[$replicaId] ) ) {
-                               $this->prevReplicaId = $replicaId;
-                               $this->dispatchToReplica( $replicaId, $args );
+                       $childId = ( $i + $this->prevChildId + 1 ) % $this->numProcs;
+                       if ( isset( $pipes[$childId] ) ) {
+                               $this->prevChildId = $childId;
+                               $this->dispatchToChild( $childId, $args );
 
                                return;
                        }
@@ -300,14 +307,14 @@ class RecompressTracked {
        }
 
        /**
-        * Dispatch a command to a specified replica DB
-        * @param int $replicaId
+        * Dispatch a command to a specified child process
+        * @param int $childId
         * @param array|string $args
         */
-       function dispatchToReplica( $replicaId, $args ) {
+       function dispatchToChild( $childId, $args ) {
                $args = (array)$args;
                $cmd = implode( ' ', $args );
-               fwrite( $this->replicaPipes[$replicaId], "$cmd\n" );
+               fwrite( $this->childPipes[$childId], "$cmd\n" );
        }
 
        /**
@@ -531,7 +538,7 @@ class RecompressTracked {
                                }
                                $lastTextId = $row->bt_text_id;
                                // Load the text
-                               $text = Revision::getRevisionText( $row );
+                               $text = $this->blobStore->expandBlob( $row->old_text, $row->old_flags );
                                if ( $text === false ) {
                                        $this->critical( "Error loading {$row->bt_rev_id}/{$row->bt_text_id}" );
                                        continue;
@@ -685,7 +692,7 @@ class RecompressTracked {
                );
 
                foreach ( $res as $row ) {
-                       $text = Revision::getRevisionText( $row );
+                       $text = $this->blobStore->expandBlob( $row->old_text, $row->old_flags );
                        if ( $text === false ) {
                                $this->critical( "Error: cannot load revision text for old_id={$row->old_id}" );
                                continue;
index 5d756e8..7e57f67 100644 (file)
@@ -42,12 +42,13 @@ class UpdateSpecialPages extends Maintenance {
        }
 
        public function execute() {
-               global $wgQueryCacheLimit, $wgDisableQueryPageUpdate;
+               global $wgQueryCacheLimit;
 
                $dbw = $this->getDB( DB_MASTER );
 
                $this->doSpecialPageCacheUpdates( $dbw );
 
+               $disabledQueryPages = QueryPage::getDisabledQueryPages( $this->getConfig() );
                foreach ( QueryPage::getPages() as $page ) {
                        list( , $special ) = $page;
                        $limit = $page[2] ?? null;
@@ -59,7 +60,7 @@ class UpdateSpecialPages extends Maintenance {
                        }
 
                        if ( !$this->hasOption( 'override' )
-                               && $wgDisableQueryPageUpdate && in_array( $special, $wgDisableQueryPageUpdate )
+                               && isset( $disabledQueryPages[$special] )
                        ) {
                                $this->output( sprintf( "%-30s [QueryPage] disabled\n", $special ) );
                                continue;
index 0b0e485..9354435 100644 (file)
@@ -1690,6 +1690,7 @@ return [
                ],
        ],
        'mediawiki.page.watch.ajax' => [
+               'targets' => [ 'desktop', 'mobile' ],
                'scripts' => 'resources/src/mediawiki.page.watch.ajax.js',
                'dependencies' => [
                        'mediawiki.api',
index 00ff2c9..c479c2d 100644 (file)
@@ -178,7 +178,6 @@ $wgAutoloadClasses += [
        'MediaWiki\Tests\Revision\RevisionSlotsTest' => "$testDir/phpunit/includes/Revision/RevisionSlotsTest.php",
        'MediaWiki\Tests\Revision\RevisionRecordTests' => "$testDir/phpunit/includes/Revision/RevisionRecordTests.php",
        'MediaWiki\Tests\Revision\RevisionStoreDbTestBase' => "$testDir/phpunit/includes/Revision/RevisionStoreDbTestBase.php",
-       'MediaWiki\Tests\Revision\PreMcrSchemaOverride' => "$testDir/phpunit/includes/Revision/PreMcrSchemaOverride.php",
        'MediaWiki\Tests\Revision\RevisionStoreRecordTest' => "$testDir/phpunit/includes/Revision/RevisionStoreRecordTest.php",
 
        # tests/phpunit/languages
index 27cbed5..a82c064 100644 (file)
@@ -1465,7 +1465,7 @@ abstract class MediaWikiIntegrationTestCase extends PHPUnit\Framework\TestCase {
                        $db->_originalTablePrefix = $oldPrefix;
 
                        $lb = MediaWikiServices::getInstance()->getDBLoadBalancer();
-                       $lb->setTempTablesOnlyMode( self::$useTemporaryTables, $lb->getLocalDomainID() );
+                       $lb->setTempTablesOnlyMode( self::$useTemporaryTables, $db->getDomainID() );
                }
 
                return true;
diff --git a/tests/phpunit/includes/Revision/NoContentModelRevisionStoreDbTest.php b/tests/phpunit/includes/Revision/NoContentModelRevisionStoreDbTest.php
deleted file mode 100644 (file)
index 51cfc63..0000000
+++ /dev/null
@@ -1,202 +0,0 @@
-<?php
-
-namespace MediaWiki\Tests\Revision;
-
-use Revision;
-
-/**
- * Tests RevisionStore against the pre-MCR, pre-ContentHandler DB schema.
- *
- * @covers \MediaWiki\Revision\RevisionStore
- *
- * @group RevisionStore
- * @group Storage
- * @group Database
- * @group medium
- */
-class NoContentModelRevisionStoreDbTest extends RevisionStoreDbTestBase {
-
-       use PreMcrSchemaOverride;
-
-       protected function getContentHandlerUseDB() {
-               return false;
-       }
-
-       protected function revisionToRow( Revision $rev, $options = [ 'page', 'user', 'comment' ] ) {
-               $row = parent::revisionToRow( $rev, $options );
-
-               $row->rev_text_id = (string)$rev->getTextId();
-
-               return $row;
-       }
-
-       public function provideGetArchiveQueryInfo() {
-               yield [
-                       [
-                               'tables' => [ 'archive' ],
-                               'fields' => array_merge(
-                                       $this->getDefaultArchiveFields(),
-                                       [
-                                               'ar_comment_text' => 'ar_comment',
-                                               'ar_comment_data' => 'NULL',
-                                               'ar_comment_cid' => 'NULL',
-                                               'ar_user_text' => 'ar_user_text',
-                                               'ar_user' => 'ar_user',
-                                               'ar_actor' => 'NULL',
-                                       ]
-                               ),
-                               'joins' => [],
-                       ]
-               ];
-       }
-
-       public function provideGetQueryInfo() {
-               yield [
-                       [],
-                       [
-                               'tables' => [ 'revision' ],
-                               'fields' => array_merge(
-                                       $this->getDefaultQueryFields(),
-                                       $this->getCommentQueryFields(),
-                                       $this->getActorQueryFields()
-                               ),
-                               'joins' => [],
-                       ]
-               ];
-               yield [
-                       [ 'page' ],
-                       [
-                               'tables' => [ 'revision', 'page' ],
-                               'fields' => array_merge(
-                                       $this->getDefaultQueryFields(),
-                                       $this->getCommentQueryFields(),
-                                       $this->getActorQueryFields(),
-                                       [
-                                               'page_namespace',
-                                               'page_title',
-                                               'page_id',
-                                               'page_latest',
-                                               'page_is_redirect',
-                                               'page_len',
-                                       ]
-                               ),
-                               'joins' => [
-                                       'page' => [ 'JOIN', [ 'page_id = rev_page' ] ],
-                               ],
-                       ]
-               ];
-               yield [
-                       [ 'user' ],
-                       [
-                               'tables' => [ 'revision', 'user' ],
-                               'fields' => array_merge(
-                                       $this->getDefaultQueryFields(),
-                                       $this->getCommentQueryFields(),
-                                       $this->getActorQueryFields(),
-                                       [
-                                               'user_name',
-                                       ]
-                               ),
-                               'joins' => [
-                                       'user' => [ 'LEFT JOIN', [ 'rev_user != 0', 'user_id = rev_user' ] ],
-                               ],
-                       ]
-               ];
-               yield [
-                       [ 'text' ],
-                       [
-                               'tables' => [ 'revision', 'text' ],
-                               'fields' => array_merge(
-                                       $this->getDefaultQueryFields(),
-                                       $this->getCommentQueryFields(),
-                                       $this->getActorQueryFields(),
-                                       [
-                                               'old_text',
-                                               'old_flags',
-                                       ]
-                               ),
-                               'joins' => [
-                                       'text' => [ 'JOIN', [ 'rev_text_id=old_id' ] ],
-                               ],
-                       ]
-               ];
-       }
-
-       public function provideGetSlotsQueryInfo() {
-               $db = wfGetDB( DB_REPLICA );
-
-               yield [
-                       [],
-                       [
-                               'tables' => [
-                                       'slots' => 'revision',
-                               ],
-                               'fields' => array_merge(
-                                       [
-                                               'slot_revision_id' => 'slots.rev_id',
-                                               'slot_content_id' => 'NULL',
-                                               'slot_origin' => 'slots.rev_id',
-                                               'role_name' => $db->addQuotes( SlotRecord::MAIN ),
-                                       ]
-                               ),
-                               'joins' => [],
-                       ]
-               ];
-               yield [
-                       [ 'content' ],
-                       [
-                               'tables' => [
-                                       'slots' => 'revision',
-                               ],
-                               'fields' => array_merge(
-                                       [
-                                               'slot_revision_id' => 'slots.rev_id',
-                                               'slot_content_id' => 'NULL',
-                                               'slot_origin' => 'slots.rev_id',
-                                               'role_name' => $db->addQuotes( SlotRecord::MAIN ),
-                                               'content_size' => 'slots.rev_len',
-                                               'content_sha1' => 'slots.rev_sha1',
-                                               'content_address' =>
-                                                       $db->buildConcat( [ $db->addQuotes( 'tt:' ), 'slots.rev_text_id' ] ),
-                                               'model_name' => 'NULL',
-                                       ]
-                               ),
-                               'joins' => [],
-                       ]
-               ];
-       }
-
-       public function provideNewMutableRevisionFromArray() {
-               foreach ( parent::provideNewMutableRevisionFromArray() as $case ) {
-                       yield $case;
-               }
-
-               yield 'Basic array, with page & id' => [
-                       [
-                               'id' => 2,
-                               'page' => 1,
-                               'text_id' => 2,
-                               'timestamp' => '20171017114835',
-                               'user_text' => '111.0.1.2',
-                               'user' => 0,
-                               'minor_edit' => false,
-                               'deleted' => 0,
-                               'len' => 46,
-                               'parent_id' => 1,
-                               'sha1' => 'rdqbbzs3pkhihgbs8qf2q9jsvheag5z',
-                               'comment' => 'Goat Comment!',
-                       ]
-               ];
-       }
-
-       /**
-        * Conditions to use together with getSlotsQueryInfo() when selecting slot rows for a given
-        * revision.
-        *
-        * @return array
-        */
-       protected function getSlotRevisionConditions( $revId ) {
-               return [ 'rev_id' => $revId ];
-       }
-
-}
diff --git a/tests/phpunit/includes/Revision/PreMcrRevisionStoreDbTest.php b/tests/phpunit/includes/Revision/PreMcrRevisionStoreDbTest.php
deleted file mode 100644 (file)
index 468ab60..0000000
+++ /dev/null
@@ -1,102 +0,0 @@
-<?php
-
-namespace MediaWiki\Tests\Revision;
-
-use InvalidArgumentException;
-use MediaWiki\Revision\RevisionRecord;
-use Revision;
-use WikitextContent;
-
-/**
- * Tests RevisionStore against the pre-MCR DB schema.
- *
- * @covers \MediaWiki\Revision\RevisionStore
- *
- * @group RevisionStore
- * @group Storage
- * @group Database
- * @group medium
- */
-class PreMcrRevisionStoreDbTest extends RevisionStoreDbTestBase {
-
-       use PreMcrSchemaOverride;
-
-       protected function revisionToRow( Revision $rev, $options = [ 'page', 'user', 'comment' ] ) {
-               $row = parent::revisionToRow( $rev, $options );
-
-               $row->rev_text_id = (string)$rev->getTextId();
-               $row->rev_content_format = (string)$rev->getContentFormat();
-               $row->rev_content_model = (string)$rev->getContentModel();
-
-               return $row;
-       }
-
-       protected function assertRevisionExistsInDatabase( RevisionRecord $rev ) {
-               // Legacy schema is still being written
-               $this->assertSelect(
-                       [ 'revision', 'text' ],
-                       [ 'count(*)' ],
-                       [ 'rev_id' => $rev->getId(), 'rev_text_id > 0' ],
-                       [ [ 1 ] ],
-                       [],
-                       [ 'text' => [ 'JOIN', [ 'rev_text_id = old_id' ] ] ]
-               );
-
-               parent::assertRevisionExistsInDatabase( $rev );
-       }
-
-       public function provideInsertRevisionOn_failures() {
-               foreach ( parent::provideInsertRevisionOn_failures() as $case ) {
-                       yield $case;
-               }
-
-               yield 'slot that is not main slot' => [
-                       [
-                               'content' => [
-                                       'main' => new WikitextContent( 'Chicken' ),
-                                       'lalala' => new WikitextContent( 'Duck' ),
-                               ],
-                               'comment' => $this->getRandomCommentStoreComment(),
-                               'timestamp' => '20171117010101',
-                               'user' => true,
-                       ],
-                       new InvalidArgumentException( 'Only the main slot is supported' )
-               ];
-       }
-
-       public function provideNewMutableRevisionFromArray() {
-               foreach ( parent::provideNewMutableRevisionFromArray() as $case ) {
-                       yield $case;
-               }
-
-               yield 'Basic array, with page & id' => [
-                       [
-                               'id' => 2,
-                               'page' => 1,
-                               'text_id' => 2,
-                               'timestamp' => '20171017114835',
-                               'user_text' => '111.0.1.2',
-                               'user' => 0,
-                               'minor_edit' => false,
-                               'deleted' => 0,
-                               'len' => 46,
-                               'parent_id' => 1,
-                               'sha1' => 'rdqbbzs3pkhihgbs8qf2q9jsvheag5z',
-                               'comment' => 'Goat Comment!',
-                               'content_format' => 'text/x-wiki',
-                               'content_model' => 'wikitext',
-                       ]
-               ];
-       }
-
-       /**
-        * Conditions to use together with getSlotsQueryInfo() when selecting slot rows for a given
-        * revision.
-        *
-        * @return array
-        */
-       protected function getSlotRevisionConditions( $revId ) {
-               return [ 'rev_id' => $revId ];
-       }
-
-}
diff --git a/tests/phpunit/includes/Revision/PreMcrSchemaOverride.php b/tests/phpunit/includes/Revision/PreMcrSchemaOverride.php
deleted file mode 100644 (file)
index 1fe2d6f..0000000
+++ /dev/null
@@ -1,54 +0,0 @@
-<?php
-
-namespace MediaWiki\Tests\Revision;
-
-use Wikimedia\Rdbms\IMaintainableDatabase;
-use MediaWiki\DB\PatchFileLocation;
-
-/**
- * Trait providing schema overrides that allow tests to run against the pre-MCR database schema.
- */
-trait PreMcrSchemaOverride {
-
-       use PatchFileLocation;
-       use McrSchemaDetection;
-
-       /**
-        * @return int
-        */
-       protected function getMcrMigrationStage() {
-               return MIGRATION_OLD;
-       }
-
-       /**
-        * @return string[]
-        */
-       protected function getMcrTablesToReset() {
-               return [];
-       }
-
-       /**
-        * @return array[]
-        */
-       protected function getSchemaOverrides( IMaintainableDatabase $db ) {
-               $overrides = [
-                       'scripts' => [],
-                       'drop' => [],
-                       'create' => [],
-                       'alter' => [],
-               ];
-
-               if ( $this->hasMcrTables( $db ) ) {
-                       $overrides['drop'] = [ 'slots', 'content', 'slot_roles', 'content_models', ];
-                       $overrides['scripts'][] = $this->getSqlPatchPath( $db, '/drop-mcr-tables', __DIR__ );
-               }
-
-               if ( !$this->hasPreMcrFields( $db ) ) {
-                       $overrides['alter'][] = 'revision';
-                       $overrides['scripts'][] = $this->getSqlPatchPath( $db, '/create-pre-mcr-fields', __DIR__ );
-               }
-
-               return $overrides;
-       }
-
-}
index 949b664..0196c5d 100644 (file)
@@ -172,29 +172,6 @@ class RevisionQueryInfoTest extends MediaWikiTestCase {
                                ],
                        ]
                ];
-               yield 'pre-MCR, no model' => [
-                       [
-                               'wgContentHandlerUseDB' => false,
-                               'wgMultiContentRevisionSchemaMigrationStage' => SCHEMA_COMPAT_OLD,
-                       ],
-                       [
-                               'tables' => [
-                                       'archive',
-                                       'actor_ar_user' => 'actor',
-                                       'comment_ar_comment' => 'comment',
-                               ],
-                               'fields' => array_merge(
-                                       $this->getArchiveQueryFields( true ),
-                                       $this->getNewActorQueryFields( 'ar' ),
-                                       $this->getNewCommentQueryFields( 'ar' )
-                               ),
-                               'joins' => [
-                                       'comment_ar_comment'
-                                               => [ 'JOIN', 'comment_ar_comment.comment_id = ar_comment_id' ],
-                                       'actor_ar_user' => [ 'JOIN', 'actor_ar_user.actor_id = ar_actor' ],
-                               ],
-                       ]
-               ];
        }
 
        public function provideQueryInfo() {
@@ -397,238 +374,6 @@ class RevisionQueryInfoTest extends MediaWikiTestCase {
                                ],
                        ]
                ];
-               yield 'pre-MCR' => [
-                       [
-                               'wgContentHandlerUseDB' => true,
-                               'wgMultiContentRevisionSchemaMigrationStage' => SCHEMA_COMPAT_OLD,
-                       ],
-                       [],
-                       [
-                               'tables' => [
-                                       'revision',
-                                       'temp_rev_comment' => 'revision_comment_temp',
-                                       'comment_rev_comment' => 'comment',
-                                       'temp_rev_user' => 'revision_actor_temp',
-                                       'actor_rev_user' => 'actor',
-                               ],
-                               'fields' => array_merge(
-                                       $this->getRevisionQueryFields( true ),
-                                       $this->getContentHandlerQueryFields( 'rev' ),
-                                       $this->getNewActorQueryFields( 'rev', true ),
-                                       $this->getNewCommentQueryFields( 'rev' )
-                               ),
-                               'joins' => [
-                                       'temp_rev_comment' => [ 'JOIN', 'temp_rev_comment.revcomment_rev = rev_id' ],
-                                       'comment_rev_comment'
-                                               => [ 'JOIN', 'comment_rev_comment.comment_id = temp_rev_comment.revcomment_comment_id' ],
-                                       'temp_rev_user' => [ 'JOIN', 'temp_rev_user.revactor_rev = rev_id' ],
-                                       'actor_rev_user' => [ 'JOIN', 'actor_rev_user.actor_id = temp_rev_user.revactor_actor' ],
-                               ],
-                       ]
-               ];
-               yield 'pre-MCR, page, user' => [
-                       [
-                               'wgContentHandlerUseDB' => true,
-                               'wgMultiContentRevisionSchemaMigrationStage' => SCHEMA_COMPAT_OLD,
-                       ],
-                       [ 'page', 'user' ],
-                       [
-                               'tables' => [
-                                       'revision', 'page', 'user',
-                                       'temp_rev_comment' => 'revision_comment_temp',
-                                       'comment_rev_comment' => 'comment',
-                                       'temp_rev_user' => 'revision_actor_temp',
-                                       'actor_rev_user' => 'actor',
-                               ],
-                               'fields' => array_merge(
-                                       $this->getRevisionQueryFields( true ),
-                                       $this->getContentHandlerQueryFields( 'rev' ),
-                                       $this->getPageQueryFields(),
-                                       $this->getUserQueryFields(),
-                                       $this->getNewActorQueryFields( 'rev', true ),
-                                       $this->getNewCommentQueryFields( 'rev' )
-                               ),
-                               'joins' => [
-                                       'page' => [ 'JOIN', [ 'page_id = rev_page' ] ],
-                                       'user' => [ 'LEFT JOIN', [
-                                               'actor_rev_user.actor_user != 0',
-                                               'user_id = actor_rev_user.actor_user',
-                                       ] ],
-                                       'temp_rev_comment' => [ 'JOIN', 'temp_rev_comment.revcomment_rev = rev_id' ],
-                                       'comment_rev_comment'
-                                               => [ 'JOIN', 'comment_rev_comment.comment_id = temp_rev_comment.revcomment_comment_id' ],
-                                       'temp_rev_user' => [ 'JOIN', 'temp_rev_user.revactor_rev = rev_id' ],
-                                       'actor_rev_user' => [ 'JOIN', 'actor_rev_user.actor_id = temp_rev_user.revactor_actor' ],
-                               ],
-                       ]
-               ];
-               yield 'pre-MCR, no model' => [
-                       [
-                               'wgContentHandlerUseDB' => false,
-                               'wgMultiContentRevisionSchemaMigrationStage' => SCHEMA_COMPAT_OLD,
-                       ],
-                       [],
-                       [
-                               'tables' => [
-                                       'revision',
-                                       'temp_rev_comment' => 'revision_comment_temp',
-                                       'comment_rev_comment' => 'comment',
-                                       'temp_rev_user' => 'revision_actor_temp',
-                                       'actor_rev_user' => 'actor',
-                               ],
-                               'fields' => array_merge(
-                                       $this->getRevisionQueryFields( true ),
-                                       $this->getNewActorQueryFields( 'rev', true ),
-                                       $this->getNewCommentQueryFields( 'rev' )
-                               ),
-                               'joins' => [
-                                       'temp_rev_comment' => [ 'JOIN', 'temp_rev_comment.revcomment_rev = rev_id' ],
-                                       'comment_rev_comment'
-                                               => [ 'JOIN', 'comment_rev_comment.comment_id = temp_rev_comment.revcomment_comment_id' ],
-                                       'temp_rev_user' => [ 'JOIN', 'temp_rev_user.revactor_rev = rev_id' ],
-                                       'actor_rev_user' => [ 'JOIN', 'actor_rev_user.actor_id = temp_rev_user.revactor_actor' ],
-                               ],
-                       ],
-               ];
-               yield 'pre-MCR, no model, page' => [
-                       [
-                               'wgContentHandlerUseDB' => false,
-                               'wgMultiContentRevisionSchemaMigrationStage' => SCHEMA_COMPAT_OLD,
-                       ],
-                       [ 'page' ],
-                       [
-                               'tables' => [
-                                       'revision', 'page',
-                                       'temp_rev_comment' => 'revision_comment_temp',
-                                       'comment_rev_comment' => 'comment',
-                                       'temp_rev_user' => 'revision_actor_temp',
-                                       'actor_rev_user' => 'actor',
-                               ],
-                               'fields' => array_merge(
-                                       $this->getRevisionQueryFields( true ),
-                                       $this->getPageQueryFields(),
-                                       $this->getNewActorQueryFields( 'rev', true ),
-                                       $this->getNewCommentQueryFields( 'rev' )
-                               ),
-                               'joins' => [
-                                       'page' => [ 'JOIN', [ 'page_id = rev_page' ], ],
-                                       'temp_rev_comment' => [ 'JOIN', 'temp_rev_comment.revcomment_rev = rev_id' ],
-                                       'comment_rev_comment'
-                                               => [ 'JOIN', 'comment_rev_comment.comment_id = temp_rev_comment.revcomment_comment_id' ],
-                                       'temp_rev_user' => [ 'JOIN', 'temp_rev_user.revactor_rev = rev_id' ],
-                                       'actor_rev_user' => [ 'JOIN', 'actor_rev_user.actor_id = temp_rev_user.revactor_actor' ],
-                               ],
-                       ],
-               ];
-               yield 'pre-MCR, no model, user' => [
-                       [
-                               'wgContentHandlerUseDB' => false,
-                               'wgMultiContentRevisionSchemaMigrationStage' => SCHEMA_COMPAT_OLD,
-                       ],
-                       [ 'user' ],
-                       [
-                               'tables' => [
-                                       'revision', 'user',
-                                       'temp_rev_comment' => 'revision_comment_temp',
-                                       'comment_rev_comment' => 'comment',
-                                       'temp_rev_user' => 'revision_actor_temp',
-                                       'actor_rev_user' => 'actor',
-                               ],
-                               'fields' => array_merge(
-                                       $this->getRevisionQueryFields( true ),
-                                       $this->getUserQueryFields(),
-                                       $this->getNewActorQueryFields( 'rev', true ),
-                                       $this->getNewCommentQueryFields( 'rev' )
-                               ),
-                               'joins' => [
-                                       'user' => [ 'LEFT JOIN', [
-                                               'actor_rev_user.actor_user != 0',
-                                               'user_id = actor_rev_user.actor_user',
-                                       ] ],
-                                       'temp_rev_comment' => [ 'JOIN', 'temp_rev_comment.revcomment_rev = rev_id' ],
-                                       'comment_rev_comment'
-                                               => [ 'JOIN', 'comment_rev_comment.comment_id = temp_rev_comment.revcomment_comment_id' ],
-                                       'temp_rev_user' => [ 'JOIN', 'temp_rev_user.revactor_rev = rev_id' ],
-                                       'actor_rev_user' => [ 'JOIN', 'actor_rev_user.actor_id = temp_rev_user.revactor_actor' ],
-                               ],
-                       ],
-               ];
-               yield 'pre-MCR, no model, text' => [
-                       [
-                               'wgContentHandlerUseDB' => false,
-                               'wgMultiContentRevisionSchemaMigrationStage' => SCHEMA_COMPAT_OLD,
-                       ],
-                       [ 'text' ],
-                       [
-                               'tables' => [
-                                       'revision', 'text',
-                                       'temp_rev_comment' => 'revision_comment_temp',
-                                       'comment_rev_comment' => 'comment',
-                                       'temp_rev_user' => 'revision_actor_temp',
-                                       'actor_rev_user' => 'actor',
-                               ],
-                               'fields' => array_merge(
-                                       $this->getRevisionQueryFields( true ),
-                                       $this->getTextQueryFields(),
-                                       $this->getNewActorQueryFields( 'rev', true ),
-                                       $this->getNewCommentQueryFields( 'rev' )
-                               ),
-                               'joins' => [
-                                       'text' => [ 'JOIN', [ 'rev_text_id=old_id' ] ],
-                                       'temp_rev_comment' => [ 'JOIN', 'temp_rev_comment.revcomment_rev = rev_id' ],
-                                       'comment_rev_comment'
-                                               => [ 'JOIN', 'comment_rev_comment.comment_id = temp_rev_comment.revcomment_comment_id' ],
-                                       'temp_rev_user' => [ 'JOIN', 'temp_rev_user.revactor_rev = rev_id' ],
-                                       'actor_rev_user' => [ 'JOIN', 'actor_rev_user.actor_id = temp_rev_user.revactor_actor' ],
-                               ],
-                       ],
-               ];
-               yield 'pre-MCR, no model, text, page, user' => [
-                       [
-                               'wgContentHandlerUseDB' => false,
-                               'wgMultiContentRevisionSchemaMigrationStage' => SCHEMA_COMPAT_OLD,
-                       ],
-                       [ 'text', 'page', 'user' ],
-                       [
-                               'tables' => [
-                                       'revision', 'page', 'user', 'text',
-                                       'temp_rev_comment' => 'revision_comment_temp',
-                                       'comment_rev_comment' => 'comment',
-                                       'temp_rev_user' => 'revision_actor_temp',
-                                       'actor_rev_user' => 'actor',
-                               ],
-                               'fields' => array_merge(
-                                       $this->getRevisionQueryFields( true ),
-                                       $this->getPageQueryFields(),
-                                       $this->getUserQueryFields(),
-                                       $this->getTextQueryFields(),
-                                       $this->getNewActorQueryFields( 'rev', true ),
-                                       $this->getNewCommentQueryFields( 'rev' )
-                               ),
-                               'joins' => [
-                                       'page' => [
-                                               'JOIN',
-                                               [ 'page_id = rev_page' ],
-                                       ],
-                                       'user' => [
-                                               'LEFT JOIN',
-                                               [
-                                                       'actor_rev_user.actor_user != 0',
-                                                       'user_id = actor_rev_user.actor_user',
-                                               ],
-                                       ],
-                                       'text' => [
-                                               'JOIN',
-                                               [ 'rev_text_id=old_id' ],
-                                       ],
-                                       'temp_rev_comment' => [ 'JOIN', 'temp_rev_comment.revcomment_rev = rev_id' ],
-                                       'comment_rev_comment'
-                                               => [ 'JOIN', 'comment_rev_comment.comment_id = temp_rev_comment.revcomment_comment_id' ],
-                                       'temp_rev_user' => [ 'JOIN', 'temp_rev_user.revactor_rev = rev_id' ],
-                                       'actor_rev_user' => [ 'JOIN', 'actor_rev_user.actor_id = temp_rev_user.revactor_actor' ],
-                               ],
-                       ],
-               ];
        }
 
        public function provideSlotsQueryInfo() {
@@ -805,54 +550,6 @@ class RevisionQueryInfoTest extends MediaWikiTestCase {
                                'joins' => [],
                        ]
                ];
-               yield 'pre-MCR' => [
-                       [
-                               'wgMultiContentRevisionSchemaMigrationStage'
-                                       => SCHEMA_COMPAT_OLD,
-                       ],
-                       [],
-                       [
-                               'tables' => [
-                                       'revision',
-                               ],
-                               'fields' => array_merge(
-                                       [
-                                               'slot_revision_id' => 'rev_id',
-                                               'slot_content_id' => 'NULL',
-                                               'slot_origin' => 'rev_id',
-                                               'role_name' => $db->addQuotes( SlotRecord::MAIN ),
-                                       ]
-                               ),
-                               'joins' => [],
-                       ]
-               ];
-               yield 'pre-MCR, content' => [
-                       [
-                               'wgMultiContentRevisionSchemaMigrationStage'
-                                       => SCHEMA_COMPAT_OLD,
-                       ],
-                       [ 'content' ],
-                       [
-                               'tables' => [
-                                       'revision',
-                               ],
-                               'fields' => array_merge(
-                                       [
-                                               'slot_revision_id' => 'rev_id',
-                                               'slot_content_id' => 'NULL',
-                                               'slot_origin' => 'rev_id',
-                                               'role_name' => $db->addQuotes( SlotRecord::MAIN ),
-                                               'content_size' => 'rev_len',
-                                               'content_sha1' => 'rev_sha1',
-                                               'content_address' =>
-                                                       $db->buildConcat( [ $db->addQuotes( 'tt:' ), 'rev_text_id' ] ),
-                                               'rev_text_id' => 'rev_text_id',
-                                               'model_name' => 'rev_content_model',
-                                       ]
-                               ),
-                               'joins' => [],
-                       ]
-               ];
        }
 
        /**
index 99332d2..d42ab16 100644 (file)
@@ -33,7 +33,7 @@ class RevisionStoreFactoryTest extends \MediaWikiIntegrationTestCase {
                        $this->getHashWANObjectCache(),
                        $this->getMockCommentStore(),
                        ActorMigration::newMigration(),
-                       MIGRATION_OLD,
+                       MIGRATION_NEW,
                        new NullLogger(),
                        true
                );
@@ -44,8 +44,6 @@ class RevisionStoreFactoryTest extends \MediaWikiIntegrationTestCase {
                yield [ true ];
                yield [ false ];
                yield [ 'somewiki' ];
-               yield [ 'somewiki', MIGRATION_OLD , false ];
-               yield [ 'somewiki', MIGRATION_NEW , true ];
        }
 
        /**
@@ -54,7 +52,7 @@ class RevisionStoreFactoryTest extends \MediaWikiIntegrationTestCase {
         */
        public function testGetRevisionStore(
                $dbDomain,
-               $mcrMigrationStage = MIGRATION_OLD,
+               $mcrMigrationStage = MIGRATION_NEW,
                $contentHandlerUseDb = true
        ) {
                $lbFactory = $this->getMockLoadBalancerFactory();
index 83872e3..e74eabb 100644 (file)
@@ -3,37 +3,26 @@
 namespace MediaWiki\Tests\Revision;
 
 use CommentStore;
-use HashBagOStuff;
 use InvalidArgumentException;
-use Language;
 use MediaWiki\MediaWikiServices;
 use MediaWiki\Revision\RevisionAccessException;
 use MediaWiki\Revision\RevisionStore;
 use MediaWiki\Revision\SlotRoleRegistry;
-use MediaWiki\Revision\SlotRecord;
 use MediaWiki\Storage\SqlBlobStore;
 use Wikimedia\Rdbms\ILoadBalancer;
 use Wikimedia\Rdbms\MaintainableDBConnRef;
 use MediaWikiTestCase;
 use MWException;
-use Title;
 use WANObjectCache;
 use Wikimedia\Rdbms\IDatabase;
 use Wikimedia\Rdbms\LoadBalancer;
 use Wikimedia\TestingAccessWrapper;
-use WikitextContent;
 
 /**
  * Tests RevisionStore
  */
 class RevisionStoreTest extends MediaWikiTestCase {
 
-       private function useTextId() {
-               global $wgMultiContentRevisionSchemaMigrationStage;
-
-               return (bool)( $wgMultiContentRevisionSchemaMigrationStage & SCHEMA_COMPAT_READ_OLD );
-       }
-
        /**
         * @param LoadBalancer $loadBalancer
         * @param SqlBlobStore $blobStore
@@ -120,9 +109,7 @@ class RevisionStoreTest extends MediaWikiTestCase {
 
        public function provideSetContentHandlerUseDB() {
                return [
-                       // ContentHandlerUseDB can be true of false pre migration.
-                       [ false, SCHEMA_COMPAT_OLD, false ],
-                       [ true, SCHEMA_COMPAT_OLD, false ],
+                       // ContentHandlerUseDB can be true or false pre migration.
                        // During and after migration it can not be false...
                        [ false, SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_OLD, true ],
                        [ false, SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_NEW, true ],
@@ -436,134 +423,8 @@ class RevisionStoreTest extends MediaWikiTestCase {
                $store->getTitle( 1, 2, RevisionStore::READ_NORMAL );
        }
 
-       public function provideNewRevisionFromRow_legacyEncoding_applied() {
-               yield 'windows-1252, old_flags is empty' => [
-                       'windows-1252',
-                       'en',
-                       [
-                               'old_flags' => '',
-                               'old_text' => "S\xF6me Content",
-                       ],
-                       'Söme Content'
-               ];
-
-               yield 'windows-1252, old_flags is null' => [
-                       'windows-1252',
-                       'en',
-                       [
-                               'old_flags' => null,
-                               'old_text' => "S\xF6me Content",
-                       ],
-                       'Söme Content'
-               ];
-       }
-
-       /**
-        * @dataProvider provideNewRevisionFromRow_legacyEncoding_applied
-        *
-        * @covers \MediaWiki\Revision\RevisionStore::newRevisionFromRow
-        */
-       public function testNewRevisionFromRow_legacyEncoding_applied( $encoding, $locale, $row, $text ) {
-               if ( !$this->useTextId() ) {
-                       $this->markTestSkipped( 'No longer applicable with MCR schema' );
-               }
-
-               $cache = new WANObjectCache( [ 'cache' => new HashBagOStuff() ] );
-               $services = MediaWikiServices::getInstance();
-               $lb = $services->getDBLoadBalancer();
-               $access = $services->getExternalStoreAccess();
-
-               $blobStore = new SqlBlobStore( $lb, $access, $cache );
-
-               $blobStore->setLegacyEncoding( $encoding, Language::factory( $locale ) );
-
-               $store = $this->getRevisionStore( $lb, $blobStore, $cache );
-
-               $record = $store->newRevisionFromRow(
-                       $this->makeRow( $row ),
-                       0,
-                       Title::newFromText( __METHOD__ . '-UTPage' )
-               );
-
-               $this->assertSame( $text, $record->getContent( SlotRecord::MAIN )->serialize() );
-       }
-
-       /**
-        * @covers \MediaWiki\Revision\RevisionStore::newRevisionFromRow
-        */
-       public function testNewRevisionFromRow_legacyEncoding_ignored() {
-               if ( !$this->useTextId() ) {
-                       $this->markTestSkipped( 'No longer applicable with MCR schema' );
-               }
-
-               $row = [
-                       'old_flags' => 'utf-8',
-                       'old_text' => 'Söme Content',
-               ];
-
-               $cache = new WANObjectCache( [ 'cache' => new HashBagOStuff() ] );
-               $services = MediaWikiServices::getInstance();
-               $lb = $services->getDBLoadBalancer();
-               $access = $services->getExternalStoreAccess();
-
-               $blobStore = new SqlBlobStore( $lb, $access, $cache );
-               $blobStore->setLegacyEncoding( 'windows-1252', Language::factory( 'en' ) );
-
-               $store = $this->getRevisionStore( $lb, $blobStore, $cache );
-
-               $record = $store->newRevisionFromRow(
-                       $this->makeRow( $row ),
-                       0,
-                       Title::newFromText( __METHOD__ . '-UTPage' )
-               );
-               $this->assertSame( 'Söme Content', $record->getContent( SlotRecord::MAIN )->serialize() );
-       }
-
-       private function makeRow( array $array ) {
-               $row = $array + [
-                               'rev_id' => 7,
-                               'rev_page' => 5,
-                               'rev_timestamp' => '20110101000000',
-                               'rev_user_text' => 'Tester',
-                               'rev_user' => 17,
-                               'rev_minor_edit' => 0,
-                               'rev_deleted' => 0,
-                               'rev_len' => 100,
-                               'rev_parent_id' => 0,
-                               'rev_sha1' => 'deadbeef',
-                               'rev_comment_text' => 'Testing',
-                               'rev_comment_data' => '{}',
-                               'rev_comment_cid' => 111,
-                               'page_namespace' => 0,
-                               'page_title' => 'TEST',
-                               'page_id' => 5,
-                               'page_latest' => 7,
-                               'page_is_redirect' => 0,
-                               'page_len' => 100,
-                               'user_name' => 'Tester',
-                       ];
-
-               if ( $this->useTextId() ) {
-                       $row += [
-                               'rev_content_format' => CONTENT_FORMAT_TEXT,
-                               'rev_content_model' => CONTENT_MODEL_TEXT,
-                               'rev_text_id' => 11,
-                               'old_id' => 11,
-                               'old_text' => 'Hello World',
-                               'old_flags' => 'utf-8',
-                       ];
-               } elseif ( !isset( $row['content'] ) && isset( $array['old_text'] ) ) {
-                       $row['content'] = [
-                               'main' => new WikitextContent( $array['old_text'] ),
-                       ];
-               }
-
-               return (object)$row;
-       }
-
        public function provideMigrationConstruction() {
                return [
-                       [ SCHEMA_COMPAT_OLD, false ],
                        [ SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_OLD, false ],
                        [ SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_NEW, false ],
                        [ SCHEMA_COMPAT_NEW, false ],
diff --git a/tests/phpunit/includes/RevisionNoContentModelDbTest.php b/tests/phpunit/includes/RevisionNoContentModelDbTest.php
deleted file mode 100644 (file)
index f19bc52..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-<?php
-
-use MediaWiki\Tests\Revision\PreMcrSchemaOverride;
-
-/**
- * Tests Revision against the pre-MCR, pre ContentHandler DB schema.
- *
- * @covers Revision
- *
- * @group Revision
- * @group Storage
- * @group ContentHandler
- * @group Database
- * @group medium
- */
-class RevisionNoContentModelDbTest extends RevisionDbTestBase {
-
-       use PreMcrSchemaOverride;
-
-       protected function getContentHandlerUseDB() {
-               return false;
-       }
-
-       public function provideGetTextId() {
-               yield [ [], null ];
-
-               $row = (object)[
-                       'rev_id' => 7,
-                       'rev_page' => 1, // should match actual page id
-                       'rev_text_id' => 789,
-                       'rev_timestamp' => '20180101000000',
-                       'rev_len' => 7,
-                       'rev_minor_edit' => 0,
-                       'rev_deleted' => 0,
-                       'rev_parent_id' => 0,
-                       'rev_sha1' => 'deadbeef',
-                       'rev_comment' => 'some comment',
-                       'rev_comment_text' => 'some comment',
-                       'rev_comment_data' => '{}',
-                       'rev_user' => 17,
-                       'rev_user_text' => 'some user',
-               ];
-
-               yield [ $row, 789 ];
-       }
-
-       public function provideGetRevisionText() {
-               yield [
-                       [ 'text' ]
-               ];
-       }
-
-}
diff --git a/tests/phpunit/includes/RevisionPreMcrDbTest.php b/tests/phpunit/includes/RevisionPreMcrDbTest.php
deleted file mode 100644 (file)
index 444c150..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-<?php
-
-use MediaWiki\Tests\Revision\PreMcrSchemaOverride;
-
-/**
- * Tests Revision against the pre-MCR DB schema.
- *
- * @covers Revision
- *
- * @group Revision
- * @group Storage
- * @group ContentHandler
- * @group Database
- * @group medium
- */
-class RevisionPreMcrDbTest extends RevisionDbTestBase {
-
-       use PreMcrSchemaOverride;
-
-       protected function getContentHandlerUseDB() {
-               return true;
-       }
-
-       public function provideGetTextId() {
-               yield [ [], null ];
-
-               $row = (object)[
-                       'rev_id' => 7,
-                       'rev_page' => 1, // should match actual page id
-                       'rev_text_id' => 789,
-                       'rev_timestamp' => '20180101000000',
-                       'rev_len' => 7,
-                       'rev_minor_edit' => 0,
-                       'rev_deleted' => 0,
-                       'rev_parent_id' => 0,
-                       'rev_sha1' => 'deadbeef',
-                       'rev_comment' => 'some comment',
-                       'rev_comment_text' => 'some comment',
-                       'rev_comment_data' => '{}',
-                       'rev_user' => 17,
-                       'rev_user_text' => 'some user',
-               ];
-
-               yield [ $row, 789 ];
-       }
-
-       public function provideGetRevisionText() {
-               yield [
-                       [ 'text' ]
-               ];
-       }
-}
index 3a3f5f1..1606275 100644 (file)
@@ -2,6 +2,7 @@
 
 use Wikimedia\Rdbms\DBQueryError;
 use Wikimedia\TestingAccessWrapper;
+use Wikimedia\Timestamp\ConvertibleTimestamp;
 
 /**
  * @group API
@@ -169,6 +170,10 @@ class ApiMainTest extends ApiTestCase {
        }
 
        public function testAddRequestedFieldsCurTimestamp() {
+               // Fake timestamp for better testability, CI can sometimes take
+               // unreasonably long to run the simple test request here.
+               $reset = ConvertibleTimestamp::setFakeTime( '20190102030405' );
+
                $req = new FauxRequest( [
                        'action' => 'query',
                        'meta' => 'siteinfo',
@@ -177,7 +182,7 @@ class ApiMainTest extends ApiTestCase {
                $api = new ApiMain( $req );
                $api->execute();
                $timestamp = $api->getResult()->getResultData()['curtimestamp'];
-               $this->assertLessThanOrEqual( 1, abs( strtotime( $timestamp ) - time() ) );
+               $this->assertSame( '2019-01-02T03:04:05Z', $timestamp );
        }
 
        public function testAddRequestedFieldsResponseLangInfo() {
index dce1a5f..7f5ee0c 100644 (file)
@@ -665,17 +665,13 @@ class ApiQuerySiteinfoTest extends ApiTestCase {
        }
 
        public function testContinuation() {
-               // We make lots and lots of URL protocols that are each 100 bytes
+               // Use $wgUrlProtocols to forge the size of the API query
                global $wgAPIMaxResultSize, $wgUrlProtocols;
 
-               $this->setMwGlobals( 'wgUrlProtocols', [] );
+               $protocol = 'foo://';
 
-               // Just under the limit
-               $chunks = $wgAPIMaxResultSize / 100 - 1;
-
-               for ( $i = 0; $i < $chunks; $i++ ) {
-                       $wgUrlProtocols[] = substr( str_repeat( "$i ", 50 ), 0, 100 );
-               }
+               $this->setMwGlobals( 'wgUrlProtocols', [ $protocol ] );
+               $this->setMwGlobals( 'wgAPIMaxResultSize', strlen( $protocol ) );
 
                $res = $this->doApiRequest( [
                        'action' => 'query',
index 31929d3..4e062ed 100644 (file)
@@ -85,9 +85,9 @@ class CategoryMembershipChangeTest extends MediaWikiLangTestCase {
                $this->assertEquals( self::$pageName, self::$lastNotifyArgs[4]->getPrefixedText() );
                $this->assertSame( 0, self::$lastNotifyArgs[5] );
                $this->assertSame( 0, self::$lastNotifyArgs[6] );
-               $this->assertEquals( null, self::$lastNotifyArgs[7] );
+               $this->assertNull( self::$lastNotifyArgs[7] );
                $this->assertEquals( 1, self::$lastNotifyArgs[8] );
-               $this->assertEquals( null, self::$lastNotifyArgs[9] );
+               $this->assertSame( '', self::$lastNotifyArgs[9] );
                $this->assertSame( 0, self::$lastNotifyArgs[10] );
        }
 
@@ -105,9 +105,9 @@ class CategoryMembershipChangeTest extends MediaWikiLangTestCase {
                $this->assertEquals( self::$pageName, self::$lastNotifyArgs[4]->getPrefixedText() );
                $this->assertSame( 0, self::$lastNotifyArgs[5] );
                $this->assertSame( 0, self::$lastNotifyArgs[6] );
-               $this->assertEquals( null, self::$lastNotifyArgs[7] );
+               $this->assertNull( self::$lastNotifyArgs[7] );
                $this->assertEquals( 1, self::$lastNotifyArgs[8] );
-               $this->assertEquals( null, self::$lastNotifyArgs[9] );
+               $this->assertSame( '', self::$lastNotifyArgs[9] );
                $this->assertSame( 0, self::$lastNotifyArgs[10] );
        }
 
@@ -126,7 +126,7 @@ class CategoryMembershipChangeTest extends MediaWikiLangTestCase {
                $this->assertEquals( self::$pageName, self::$lastNotifyArgs[4]->getPrefixedText() );
                $this->assertEquals( self::$pageRev->getParentId(), self::$lastNotifyArgs[5] );
                $this->assertEquals( $revision->getId(), self::$lastNotifyArgs[6] );
-               $this->assertEquals( null, self::$lastNotifyArgs[7] );
+               $this->assertNull( self::$lastNotifyArgs[7] );
                $this->assertSame( 0, self::$lastNotifyArgs[8] );
                $this->assertEquals( '127.0.0.1', self::$lastNotifyArgs[9] );
                $this->assertSame( 0, self::$lastNotifyArgs[10] );
@@ -147,7 +147,7 @@ class CategoryMembershipChangeTest extends MediaWikiLangTestCase {
                $this->assertEquals( self::$pageName, self::$lastNotifyArgs[4]->getPrefixedText() );
                $this->assertEquals( self::$pageRev->getParentId(), self::$lastNotifyArgs[5] );
                $this->assertEquals( $revision->getId(), self::$lastNotifyArgs[6] );
-               $this->assertEquals( null, self::$lastNotifyArgs[7] );
+               $this->assertNull( self::$lastNotifyArgs[7] );
                $this->assertSame( 0, self::$lastNotifyArgs[8] );
                $this->assertEquals( '127.0.0.1', self::$lastNotifyArgs[9] );
                $this->assertSame( 0, self::$lastNotifyArgs[10] );
index cd7cc10..fc1c42d 100644 (file)
@@ -390,7 +390,7 @@ just a test"
                $this->assertEquals( 'hello world.', $wikitext,
                        'Wikitext passed to hook was not as expected'
                );
-               $this->assertEquals( null, $redirectTarget, 'Redirect seen in hook was not null' );
+               $this->assertNull( $redirectTarget, 'Redirect seen in hook was not null' );
                $this->assertEquals( $title, $options->getRedirectTarget(),
                        'ParserOptions\' redirectTarget was changed'
                );
@@ -417,8 +417,7 @@ just a test"
                        $redirectTarget->getFullText(),
                        'Redirect seen in hook was not the expected title'
                );
-               $this->assertEquals(
-                       null,
+               $this->assertNull(
                        $options->getRedirectTarget(),
                        'ParserOptions\' redirectTarget was changed'
                );
index f00499f..c018744 100644 (file)
@@ -412,7 +412,7 @@ class LBFactoryTest extends MediaWikiTestCase {
                $cpIndex = null;
                $cp->shutdown( null, 'sync', $cpIndex );
 
-               $this->assertEquals( null, $cpIndex, "CP write index retained" );
+               $this->assertNull( $cpIndex, "CP write index retained" );
 
                $this->assertEquals( '45e93a9c215c031d38b7c42d8e4700ca', $cp->getClientId() );
        }
index 981b4ad..a542936 100644 (file)
@@ -434,7 +434,7 @@ class LoadBalancerTest extends MediaWikiTestCase {
                $lb = $this->newSingleServerLocalLoadBalancer();
 
                $i = $lb->getWriterIndex();
-               $this->assertEquals( null, $lb->getAnyOpenConnection( $i ) );
+               $this->assertFalse( $lb->getAnyOpenConnection( $i ) );
 
                $conn1 = $lb->getConnection( $i );
                $this->assertNotEquals( null, $conn1 );
@@ -446,7 +446,7 @@ class LoadBalancerTest extends MediaWikiTestCase {
                $this->assertFalse( $conn2->getFlag( DBO_TRX ) );
 
                if ( $lb->getServerAttributes( $i )[Database::ATTR_DB_LEVEL_LOCKING] ) {
-                       $this->assertEquals( null,
+                       $this->assertFalse(
                                $lb->getAnyOpenConnection( $i, $lb::CONN_TRX_AUTOCOMMIT ) );
                        $this->assertEquals( $conn1,
                                $lb->getConnection(
index 7bc7918..9a7b1e2 100644 (file)
@@ -923,32 +923,129 @@ class FileBackendTest extends MediaWikiTestCase {
                return $cases;
        }
 
-       public function testDoQuickOperations() {
+       /**
+        * @dataProvider provider_quickOperations
+        */
+       public function testDoQuickOperations(
+               $files, $createOps, $copyOps, $moveOps, $overSelfOps, $deleteOps, $batchSize
+       ) {
                $this->backend = $this->singleBackend;
-               $this->doTestDoQuickOperations();
+               $this->doTestDoQuickOperations(
+                       $files, $createOps, $copyOps, $moveOps, $overSelfOps, $deleteOps, $batchSize
+               );
                $this->tearDownFiles();
 
                $this->backend = $this->multiBackend;
-               $this->doTestDoQuickOperations();
+               $this->doTestDoQuickOperations(
+                       $files, $createOps, $copyOps, $moveOps, $overSelfOps, $deleteOps, $batchSize
+               );
                $this->tearDownFiles();
        }
 
-       private function doTestDoQuickOperations() {
+       private function doTestDoQuickOperations(
+               $files, $createOps, $copyOps, $moveOps, $overSelfOps, $deleteOps, $batchSize
+       ) {
                $backendName = $this->backendClass();
 
+               foreach ( $files as $path ) {
+                       $status = $this->prepare( [ 'dir' => dirname( $path ) ] );
+                       $this->assertGoodStatus( $status,
+                               "Preparing $path succeeded without warnings ($backendName)." );
+               }
+
+               foreach ( array_chunk( $createOps, $batchSize ) as $batchOps ) {
+                       $this->assertGoodStatus(
+                               $this->backend->doQuickOperations( $batchOps ),
+                               "Creation of source files succeeded ($backendName)."
+                       );
+               }
+               foreach ( $files as $file ) {
+                       $this->assertTrue(
+                               $this->backend->fileExists( [ 'src' => $file ] ),
+                               "File $file exists."
+                       );
+               }
+
+               foreach ( array_chunk( $copyOps, $batchSize ) as $batchOps ) {
+                       $this->assertGoodStatus(
+                               $this->backend->doQuickOperations( $batchOps ),
+                               "Quick copy of source files succeeded ($backendName)."
+                       );
+               }
+               foreach ( $files as $file ) {
+                       $this->assertTrue(
+                               $this->backend->fileExists( [ 'src' => "$file-2" ] ),
+                               "File $file-2 exists."
+                       );
+               }
+
+               foreach ( array_chunk( $moveOps, $batchSize ) as $batchOps ) {
+                       $this->assertGoodStatus(
+                               $this->backend->doQuickOperations( $batchOps ),
+                               "Quick move of source files succeeded ($backendName)."
+                       );
+               }
+               foreach ( $files as $file ) {
+                       $this->assertTrue(
+                               $this->backend->fileExists( [ 'src' => "$file-3" ] ),
+                               "File $file-3 move in."
+                       );
+                       $this->assertFalse(
+                               $this->backend->fileExists( [ 'src' => "$file-2" ] ),
+                               "File $file-2 moved away."
+                       );
+               }
+
+               foreach ( array_chunk( $overSelfOps, $batchSize ) as $batchOps ) {
+                       $this->assertGoodStatus(
+                               $this->backend->doQuickOperations( $batchOps ),
+                               "Quick copy/move of source files over themselves succeeded ($backendName)."
+                       );
+               }
+               foreach ( $files as $file ) {
+                       $this->assertTrue(
+                               $this->backend->fileExists( [ 'src' => $file ] ),
+                               "File $file still exists after copy/move over self."
+                       );
+               }
+
+               foreach ( array_chunk( $deleteOps, $batchSize ) as $batchOps ) {
+                       $this->assertGoodStatus(
+                               $this->backend->doQuickOperations( $batchOps ),
+                               "Quick deletion of source files succeeded ($backendName)."
+                       );
+               }
+               foreach ( $files as $file ) {
+                       $this->assertFalse( $this->backend->fileExists( [ 'src' => $file ] ),
+                               "File $file purged." );
+                       $this->assertFalse( $this->backend->fileExists( [ 'src' => "$file-3" ] ),
+                               "File $file-3 purged." );
+               }
+       }
+
+       function provider_quickOperations() {
                $base = self::baseStorePath();
                $files = [
                        "$base/unittest-cont1/e/fileA.a",
                        "$base/unittest-cont1/e/fileB.a",
                        "$base/unittest-cont1/e/fileC.a"
                ];
-               $createOps = $copyOps = $moveOps = $deleteOps = [];
+
+               $createOps = $copyOps = $moveOps = $overSelfOps = $deleteOps = [];
                foreach ( $files as $path ) {
-                       $status = $this->prepare( [ 'dir' => dirname( $path ) ] );
-                       $this->assertGoodStatus( $status,
-                               "Preparing $path succeeded without warnings ($backendName)." );
-                       $createOps[] = [ 'op' => 'create', 'dst' => $path, 'content' => mt_rand( 0, 50000 ) ];
+                       $createOps[] = [ 'op' => 'create', 'dst' => $path, 'content' => 52525 ];
+                       $createOps[] = [ 'op' => 'create', 'dst' => "$path-x", 'content' => 832 ];
+                       $createOps[] = [ 'op' => 'null' ];
+
                        $copyOps[] = [ 'op' => 'copy', 'src' => $path, 'dst' => "$path-2" ];
+                       $copyOps[] = [
+                               'op' => 'copy',
+                               'src' => "$path-nothing",
+                               'dst' => "$path-nowhere",
+                               'ignoreMissingSource' => true
+                       ];
+                       $copyOps[] = [ 'op' => 'null' ];
+
                        $moveOps[] = [ 'op' => 'move', 'src' => "$path-2", 'dst' => "$path-3" ];
                        $moveOps[] = [
                                'op' => 'move',
@@ -956,6 +1053,11 @@ class FileBackendTest extends MediaWikiTestCase {
                                'dst' => "$path-nowhere",
                                'ignoreMissingSource' => true
                        ];
+                       $moveOps[] = [ 'op' => 'null' ];
+
+                       $overSelfOps[] = [ 'op' => 'copy', 'src' => $path, 'dst' => $path ];
+                       $overSelfOps[] = [ 'op' => 'move', 'src' => $path, 'dst' => $path ];
+
                        $deleteOps[] = [ 'op' => 'delete', 'src' => $path ];
                        $deleteOps[] = [ 'op' => 'delete', 'src' => "$path-3" ];
                        $deleteOps[] = [
@@ -963,56 +1065,14 @@ class FileBackendTest extends MediaWikiTestCase {
                                'src' => "$path-gone",
                                'ignoreMissingSource' => true
                        ];
-               }
-               $deleteOps[] = [ 'op' => 'null' ];
-
-               $this->assertGoodStatus(
-                       $this->backend->doQuickOperations( $createOps ),
-                       "Creation of source files succeeded ($backendName)." );
-               foreach ( $files as $file ) {
-                       $this->assertTrue( $this->backend->fileExists( [ 'src' => $file ] ),
-                               "File $file exists." );
-               }
-
-               $this->assertGoodStatus(
-                       $this->backend->doQuickOperations( $copyOps ),
-                       "Quick copy of source files succeeded ($backendName)." );
-               foreach ( $files as $file ) {
-                       $this->assertTrue( $this->backend->fileExists( [ 'src' => "$file-2" ] ),
-                               "File $file-2 exists." );
+                       $deleteOps[] = [ 'op' => 'null' ];
                }
 
-               $this->assertGoodStatus(
-                       $this->backend->doQuickOperations( $moveOps ),
-                       "Quick move of source files succeeded ($backendName)." );
-               foreach ( $files as $file ) {
-                       $this->assertTrue( $this->backend->fileExists( [ 'src' => "$file-3" ] ),
-                               "File $file-3 move in." );
-                       $this->assertFalse( $this->backend->fileExists( [ 'src' => "$file-2" ] ),
-                               "File $file-2 moved away." );
-               }
-
-               $this->assertGoodStatus(
-                       $this->backend->quickCopy( [ 'src' => $files[0], 'dst' => $files[0] ] ),
-                       "Copy of file {$files[0]} over itself succeeded ($backendName)." );
-               $this->assertTrue( $this->backend->fileExists( [ 'src' => $files[0] ] ),
-                       "File {$files[0]} still exists." );
-
-               $this->assertGoodStatus(
-                       $this->backend->quickMove( [ 'src' => $files[0], 'dst' => $files[0] ] ),
-                       "Move of file {$files[0]} over itself succeeded ($backendName)." );
-               $this->assertTrue( $this->backend->fileExists( [ 'src' => $files[0] ] ),
-                       "File {$files[0]} still exists." );
-
-               $this->assertGoodStatus(
-                       $this->backend->doQuickOperations( $deleteOps ),
-                       "Quick deletion of source files succeeded ($backendName)." );
-               foreach ( $files as $file ) {
-                       $this->assertFalse( $this->backend->fileExists( [ 'src' => $file ] ),
-                               "File $file purged." );
-                       $this->assertFalse( $this->backend->fileExists( [ 'src' => "$file-3" ] ),
-                               "File $file-3 purged." );
-               }
+               return [
+                       [ $files, $createOps, $copyOps, $moveOps, $overSelfOps, $deleteOps, 1 ],
+                       [ $files, $createOps, $copyOps, $moveOps, $overSelfOps, $deleteOps, 2 ],
+                       [ $files, $createOps, $copyOps, $moveOps, $overSelfOps, $deleteOps, 100 ]
+               ];
        }
 
        /**
@@ -1567,11 +1627,11 @@ class FileBackendTest extends MediaWikiTestCase {
 
                $tmpFile = $this->backend->getLocalCopy( [
                        'src' => "$base/unittest-cont1/not-there" ] );
-               $this->assertEquals( null, $tmpFile, "Local copy of not existing file is null ($backendName)." );
+               $this->assertNull( $tmpFile, "Local copy of not existing file is null ($backendName)." );
 
                $tmpFile = $this->backend->getLocalReference( [
                        'src' => "$base/unittest-cont1/not-there" ] );
-               $this->assertEquals( null, $tmpFile, "Local ref of not existing file is null ($backendName)." );
+               $this->assertNull( $tmpFile, "Local ref of not existing file is null ($backendName)." );
        }
 
        /**
@@ -2484,7 +2544,7 @@ class FileBackendTest extends MediaWikiTestCase {
                        "Scoped locking of files succeeded with OK status ($backendName)." );
 
                ScopedLock::release( $sl );
-               $this->assertEquals( null, $sl,
+               $this->assertNull( $sl,
                        "Scoped unlocking of files succeeded ($backendName)." );
                $this->assertEquals( [], $status->getErrors(),
                        "Scoped unlocking of files succeeded ($backendName)." );
index 79d5788..66b04ad 100644 (file)
@@ -130,14 +130,15 @@ class StringUtilsTest extends PHPUnit\Framework\TestCase {
         * @param strin $input
         * @param bool $expected
         * @dataProvider provideRegexps
-        * @covers StringUtils::isValidRegex
+        * @covers StringUtils::isValidPCRERegex
         */
-       public function testIsValidRegex( $input, $expected ) {
-               $this->assertSame( $expected, StringUtils::isValidRegex( $input ) );
+       public function testIsValidPCRERegex( $input, $expected ) {
+               $this->assertSame( $expected, StringUtils::isValidPCRERegex( $input ) );
        }
 
        /**
-        * Data provider for testValidRegex
+        * Data provider for testIsValidPCRERegex
+        * @return array
         */
        public static function provideRegexps() {
                return [
index 7c4c9bf..0c084e0 100644 (file)
@@ -128,6 +128,32 @@ class WANObjectCacheTest extends PHPUnit\Framework\TestCase {
                $this->assertFalse( $this->cache->get( $key ), "Stale set() value ignored" );
        }
 
+       /**
+        * @covers WANObjectCache::getWithSetCallback
+        */
+       public function testProcessCacheTTL() {
+               $cache = $this->cache;
+               $mockWallClock = 1549343530.2053;
+               $cache->setMockTime( $mockWallClock );
+
+               $key = "mykey-" . wfRandomString();
+
+               $hits = 0;
+               $callback = function ( $oldValue, &$ttl, &$setOpts ) use ( &$hits ) {
+                       ++$hits;
+                       return 42;
+               };
+
+               $cache->getWithSetCallback( $key, 100, $callback, [ 'pcTTL' => 5 ] );
+               $cache->delete( $key, $cache::HOLDOFF_NONE ); // clear persistent cache
+               $cache->getWithSetCallback( $key, 100, $callback, [ 'pcTTL' => 5 ] );
+               $this->assertEquals( 1, $hits, "Value process cached" );
+
+               $mockWallClock += 6;
+               $cache->getWithSetCallback( $key, 100, $callback, [ 'pcTTL' => 5 ] );
+               $this->assertEquals( 2, $hits, "Value expired in process cache" );
+       }
+
        /**
         * @covers WANObjectCache::getWithSetCallback
         */
@@ -381,8 +407,8 @@ class WANObjectCacheTest extends PHPUnit\Framework\TestCase {
                $v = $cache->getWithSetCallback(
                        $key, 30, $checkFunc, [ 'staleTTL' => 50 ] + $extOpts );
                $this->assertEquals( 'xxx1', $v, "Value returned" );
-               $this->assertEquals( false, $oldValReceived, "Callback got no stale value" );
-               $this->assertEquals( null, $oldAsOfReceived, "Callback got no stale value" );
+               $this->assertFalse( $oldValReceived, "Callback got no stale value" );
+               $this->assertNull( $oldAsOfReceived, "Callback got no stale value" );
 
                $mockWallClock += 40;
                $v = $cache->getWithSetCallback(
@@ -397,8 +423,8 @@ class WANObjectCacheTest extends PHPUnit\Framework\TestCase {
                        $key, 30, $checkFunc, [ 'staleTTL' => 50 ] + $extOpts );
                $this->assertEquals( 'xxx3', $v, "Value still returned after expired" );
                $this->assertEquals( 3, $wasSet, "Value recalculated while expired" );
-               $this->assertEquals( false, $oldValReceived, "Callback got no stale value" );
-               $this->assertEquals( null, $oldAsOfReceived, "Callback got no stale value" );
+               $this->assertFalse( $oldValReceived, "Callback got no stale value" );
+               $this->assertNull( $oldAsOfReceived, "Callback got no stale value" );
 
                $mockWallClock = ( $priorTime - $cache::HOLDOFF_TTL - 1 );
                $wasSet = 0;
@@ -414,8 +440,8 @@ class WANObjectCacheTest extends PHPUnit\Framework\TestCase {
                );
                $this->assertEquals( 'xxx1', $v, "Value returned" );
                $this->assertEquals( 1, $wasSet, "Value computed" );
-               $this->assertEquals( false, $oldValReceived, "Callback got no stale value" );
-               $this->assertEquals( null, $oldAsOfReceived, "Callback got no stale value" );
+               $this->assertFalse( $oldValReceived, "Callback got no stale value" );
+               $this->assertNull( $oldAsOfReceived, "Callback got no stale value" );
 
                $mockWallClock += $cache::TTL_HOUR; // some time passes
                $v = $cache->getWithSetCallback(
@@ -1473,7 +1499,7 @@ class WANObjectCacheTest extends PHPUnit\Framework\TestCase {
                $this->assertEquals( $valueV2, $v, "Value returned" );
                $this->assertEquals( 1, $wasSet, "Value regenerated" );
                $this->assertEquals( false, $priorValue, "Old value not given due to old format" );
-               $this->assertEquals( null, $priorAsOf, "Old value not given due to old format" );
+               $this->assertNull( $priorAsOf, "Old value not given due to old format" );
 
                $wasSet = 0;
                $v = $cache->getWithSetCallback( $key, 30, $funcV2, $verOpts + $extOpts );
index 1c076ca..7feaa93 100644 (file)
@@ -428,4 +428,46 @@ class ProtectLogFormatterTest extends LogFormatterTestCase {
        public function testMoveProtLogDatabaseRows( $row, $extra ) {
                $this->doTestLogFormatter( $row, $extra );
        }
+
+       public function provideGetActionLinks() {
+               yield [
+                       [ 'protect' ],
+                       true
+               ];
+               yield [
+                       [],
+                       false
+               ];
+       }
+
+       /**
+        * @param string[] $permissions
+        * @param bool $shouldMatch
+        * @dataProvider provideGetActionLinks
+        * @covers ProtectLogFormatter::getActionLinks
+        */
+       public function testGetActionLinks( array $permissions, $shouldMatch ) {
+               RequestContext::resetMain();
+               $user = $this->getTestUser()->getUser();
+               $this->overrideUserPermissions( $user, $permissions );
+               $row = $this->expandDatabaseRow( [
+                       'type' => 'protect',
+                       'action' => 'unprotect',
+                       'comment' => 'unprotect comment',
+                       'namespace' => NS_MAIN,
+                       'title' => 'ProtectPage',
+                       'params' => [],
+               ], false );
+               $context = new RequestContext();
+               $context->setUser( $user );
+               $formatter = LogFormatter::newFromRow( $row );
+               $formatter->setContext( $context );
+               if ( $shouldMatch ) {
+                       $this->assertStringMatchesFormat(
+                               '%Aaction=protect%A', $formatter->getActionLinks() );
+               } else {
+                       $this->assertStringNotMatchesFormat(
+                               '%Aaction=protect%A', $formatter->getActionLinks() );
+               }
+       }
 }
diff --git a/tests/phpunit/includes/page/PageArchivePreMcrTest.php b/tests/phpunit/includes/page/PageArchivePreMcrTest.php
deleted file mode 100644 (file)
index 4c95579..0000000
+++ /dev/null
@@ -1,80 +0,0 @@
-<?php
-
-use MediaWiki\MediaWikiServices;
-use MediaWiki\Revision\SlotRecord;
-use MediaWiki\Storage\SqlBlobStore;
-use MediaWiki\Tests\Revision\PreMcrSchemaOverride;
-
-/**
- * Test class for page archiving, using the pre-MCR schema.
- *
- * @group ContentHandler
- * @group Database
- * ^--- important, causes temporary tables to be used instead of the real database
- *
- * @group medium
- * ^--- important, causes tests not to fail with timeout
- */
-class PageArchivePreMcrTest extends PageArchiveTestBase {
-
-       use PreMcrSchemaOverride;
-
-       protected function getExpectedArchiveRows() {
-               /** @var SqlBlobStore $blobStore */
-               $blobStore = MediaWikiServices::getInstance()->getBlobStore();
-
-               return [
-                       [
-                               'ar_minor_edit' => '0',
-                               'ar_user' => null,
-                               'ar_user_text' => $this->ipEditor,
-                               'ar_actor' => (string)User::newFromName( $this->ipEditor, false )->getActorId( $this->db ),
-                               'ar_len' => '11',
-                               'ar_deleted' => '0',
-                               'ar_rev_id' => strval( $this->ipRev->getId() ),
-                               'ar_timestamp' => $this->db->timestamp( $this->ipRev->getTimestamp() ),
-                               'ar_sha1' => '0qdrpxl537ivfnx4gcpnzz0285yxryy',
-                               'ar_page_id' => strval( $this->ipRev->getPageId() ),
-                               'ar_comment_text' => 'just a test',
-                               'ar_comment_data' => null,
-                               'ar_comment_cid' => '2',
-                               'ar_content_format' => null,
-                               'ar_content_model' => null,
-                               'ts_tags' => null,
-                               'ar_id' => '2',
-                               'ar_namespace' => '0',
-                               'ar_title' => 'PageArchiveTest_thePage',
-                               'ar_text_id' => (string)$blobStore->getTextIdFromAddress(
-                                       $this->ipRev->getSlot( SlotRecord::MAIN )->getAddress()
-                               ),
-                               'ar_parent_id' => strval( $this->ipRev->getParentId() ),
-                       ],
-                       [
-                               'ar_minor_edit' => '0',
-                               'ar_user' => (string)$this->getTestUser()->getUser()->getId(),
-                               'ar_user_text' => $this->getTestUser()->getUser()->getName(),
-                               'ar_actor' => (string)$this->getTestUser()->getUser()->getActorId(),
-                               'ar_len' => '7',
-                               'ar_deleted' => '0',
-                               'ar_rev_id' => strval( $this->firstRev->getId() ),
-                               'ar_timestamp' => $this->db->timestamp( $this->firstRev->getTimestamp() ),
-                               'ar_sha1' => 'pr0s8e18148pxhgjfa0gjrvpy8fiyxc',
-                               'ar_page_id' => strval( $this->firstRev->getPageId() ),
-                               'ar_comment_text' => 'testing',
-                               'ar_comment_data' => null,
-                               'ar_comment_cid' => '1',
-                               'ar_content_format' => null,
-                               'ar_content_model' => null,
-                               'ts_tags' => null,
-                               'ar_id' => '1',
-                               'ar_namespace' => '0',
-                               'ar_title' => 'PageArchiveTest_thePage',
-                               'ar_text_id' => (string)$blobStore->getTextIdFromAddress(
-                                       $this->firstRev->getSlot( SlotRecord::MAIN )->getAddress()
-                               ),
-                               'ar_parent_id' => '0',
-                       ],
-               ];
-       }
-
-}
diff --git a/tests/phpunit/includes/page/WikiPageNoContentModelDbTest.php b/tests/phpunit/includes/page/WikiPageNoContentModelDbTest.php
deleted file mode 100644 (file)
index 6f8d363..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-<?php
-
-use MediaWiki\Tests\Revision\PreMcrSchemaOverride;
-
-/**
- * Tests WikiPage against the pre-MCR, pre ContentHandler DB schema.
- *
- * @covers WikiPage
- *
- * @group WikiPage
- * @group Storage
- * @group ContentHandler
- * @group Database
- * @group medium
- */
-class WikiPageNoContentModelDbTest extends WikiPageDbTestBase {
-
-       use PreMcrSchemaOverride;
-
-       protected function getContentHandlerUseDB() {
-               return false;
-       }
-
-       public function testGetDeletionUpdates() {
-               $mainContent1 = new WikitextContent( '' );
-
-               $title = Title::makeTitle( $this->getDefaultWikitextNS(), __METHOD__ );
-               $page = new WikiPage( $title );
-               $page = $this->createPage(
-                       $page,
-                       [ 'main' => $mainContent1 ]
-               );
-
-               $dataUpdates = $page->getDeletionUpdates( $page->getRevisionRecord() );
-               $this->assertNotEmpty( $dataUpdates );
-
-               $updateNames = array_map( function ( $du ) {
-                       return isset( $du->_name ) ? $du->_name : get_class( $du );
-               }, $dataUpdates );
-
-               $this->assertContains( LinksDeletionUpdate::class, $updateNames );
-       }
-
-}
diff --git a/tests/phpunit/includes/page/WikiPagePreMcrDbTest.php b/tests/phpunit/includes/page/WikiPagePreMcrDbTest.php
deleted file mode 100644 (file)
index 028beca..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-<?php
-
-use MediaWiki\Tests\Revision\PreMcrSchemaOverride;
-
-/**
- * Tests WikiPage against the pre-MCR DB schema.
- *
- * @covers WikiPage
- *
- * @group WikiPage
- * @group Storage
- * @group ContentHandler
- * @group Database
- * @group medium
- */
-class WikiPagePreMcrDbTest extends WikiPageDbTestBase {
-
-       use PreMcrSchemaOverride;
-
-       protected function getContentHandlerUseDB() {
-               return true;
-       }
-
-       /**
-        * @covers WikiPage::getContentModel
-        */
-       public function testGetContentModel() {
-               $page = $this->createPage(
-                       __METHOD__,
-                       "some text",
-                       CONTENT_MODEL_JAVASCRIPT
-               );
-
-               $page = new WikiPage( $page->getTitle() );
-               $this->assertEquals( CONTENT_MODEL_JAVASCRIPT, $page->getContentModel() );
-       }
-
-       /**
-        * @covers WikiPage::getContentHandler
-        */
-       public function testGetContentHandler() {
-               $page = $this->createPage(
-                       __METHOD__,
-                       "some text",
-                       CONTENT_MODEL_JAVASCRIPT
-               );
-
-               $page = new WikiPage( $page->getTitle() );
-               $this->assertEquals( JavaScriptContentHandler::class, get_class( $page->getContentHandler() ) );
-       }
-
-}
index 72390ac..f11a2a2 100644 (file)
@@ -85,7 +85,7 @@ class RangeChronologicalPagerTest extends MediaWikiLangTestCase {
         */
        public function testGetDateRangeCondInvalid( $start, $end ) {
                $pager = $this->getMockForAbstractClass( RangeChronologicalPager::class );
-               $this->assertEquals( null, $pager->getDateRangeCond( $start, $end ) );
+               $this->assertNull( $pager->getDateRangeCond( $start, $end ) );
        }
 
        public function getDateRangeCondInvalidProvider() {
index c748e2c..6039bd2 100644 (file)
@@ -26,10 +26,10 @@ class ResourceLoaderContextTest extends PHPUnit\Framework\TestCase {
                // Request parameters
                $this->assertEquals( [], $ctx->getModules() );
                $this->assertEquals( 'qqx', $ctx->getLanguage() );
-               $this->assertEquals( false, $ctx->getDebug() );
-               $this->assertEquals( null, $ctx->getOnly() );
+               $this->assertFalse( $ctx->getDebug() );
+               $this->assertNull( $ctx->getOnly() );
                $this->assertEquals( 'fallback', $ctx->getSkin() );
-               $this->assertEquals( null, $ctx->getUser() );
+               $this->assertNull( $ctx->getUser() );
                $this->assertNull( $ctx->getContentOverrideCallback() );
 
                // Misc
@@ -67,11 +67,11 @@ class ResourceLoaderContextTest extends PHPUnit\Framework\TestCase {
                        $ctx->getModules(),
                        [ 'foo', 'foo.quux', 'foo.baz', 'foo.bar', 'baz.quux' ]
                );
-               $this->assertEquals( false, $ctx->getDebug() );
+               $this->assertFalse( $ctx->getDebug() );
                $this->assertEquals( 'zh', $ctx->getLanguage() );
                $this->assertEquals( 'styles', $ctx->getOnly() );
                $this->assertEquals( 'fallback', $ctx->getSkin() );
-               $this->assertEquals( null, $ctx->getUser() );
+               $this->assertNull( $ctx->getUser() );
 
                // Misc
                $this->assertEquals( 'ltr', $ctx->getDirection() );
index 9bbf14d..0c3512a 100644 (file)
@@ -718,9 +718,9 @@ mw.loader.register([
         * @dataProvider provideRegistrations
         */
        public function testRegistrationsMinified( $modules ) {
-               $this->setMwGlobals( 'wgResourceLoaderDebug', false );
-
-               $context = $this->getResourceLoaderContext();
+               $context = $this->getResourceLoaderContext( [
+                       'debug' => 'false',
+               );
                $rl = $context->getResourceLoader();
                $rl->register( $modules );
                $module = new ResourceLoaderStartUpModule();
@@ -743,7 +743,9 @@ mw.loader.register([
         * @dataProvider provideRegistrations
         */
        public function testRegistrationsUnminified( $modules ) {
-               $context = $this->getResourceLoaderContext();
+               $context = $this->getResourceLoaderContext( [
+                       'debug' => 'true',
+               ] );
                $rl = $context->getResourceLoader();
                $rl->register( $modules );
                $module = new ResourceLoaderStartUpModule();
index be11d53..99f4347 100644 (file)
@@ -518,13 +518,14 @@ END
                        'wrap' => true,
                        'styles' => [], 'templates' => [], 'messages' => new XmlJsCode( '{}' ), 'packageFiles' => [],
                ];
-               ResourceLoader::clearCache();
-               $this->setMwGlobals( 'wgResourceLoaderDebug', true );
-
                $rl = TestingAccessWrapper::newFromClass( ResourceLoader::class );
+               $context = new ResourceLoaderContext( new EmptyResourceLoader(), new FauxRequest( [
+                       'debug' => 'true',
+               ] ) );
                $this->assertEquals(
                        $case['expected'],
                        $rl->makeLoaderImplementScript(
+                               $context,
                                $case['name'],
                                ( $case['wrap'] && is_string( $case['scripts'] ) )
                                        ? new XmlJsCode( $case['scripts'] )
@@ -543,7 +544,9 @@ END
        public function testMakeLoaderImplementScriptInvalid() {
                $this->setExpectedException( MWException::class, 'Invalid scripts error' );
                $rl = TestingAccessWrapper::newFromClass( ResourceLoader::class );
+               $context = new ResourceLoaderContext( new EmptyResourceLoader(), new FauxRequest() );
                $rl->makeLoaderImplementScript(
+                       $context,
                        'test', // name
                        123, // scripts
                        null, // styles
@@ -557,6 +560,9 @@ END
         * @covers ResourceLoader::makeLoaderRegisterScript
         */
        public function testMakeLoaderRegisterScript() {
+               $context = new ResourceLoaderContext( new EmptyResourceLoader(), new FauxRequest( [
+                       'debug' => 'true',
+               ] ) );
                $this->assertEquals(
                        'mw.loader.register([
     [
@@ -564,7 +570,7 @@ END
         "1234567"
     ]
 ]);',
-                       ResourceLoader::makeLoaderRegisterScript( [
+                       ResourceLoader::makeLoaderRegisterScript( $context, [
                                [ 'test.name', '1234567' ],
                        ] ),
                        'Nested array parameter'
@@ -600,7 +606,7 @@ END
         "return true;"
     ]
 ]);',
-                       ResourceLoader::makeLoaderRegisterScript( [
+                       ResourceLoader::makeLoaderRegisterScript( $context, [
                                [ 'test.foo', '100' , [], null, null ],
                                [ 'test.bar', '200', [ 'test.unknown' ], null ],
                                [ 'test.baz', '300', [ 'test.quux', 'test.foo' ], null ],
@@ -614,31 +620,28 @@ END
         * @covers ResourceLoader::makeLoaderSourcesScript
         */
        public function testMakeLoaderSourcesScript() {
+               $context = new ResourceLoaderContext( new EmptyResourceLoader(), new FauxRequest( [
+                       'debug' => 'true',
+               ] ) );
                $this->assertEquals(
                        'mw.loader.addSource({
     "local": "/w/load.php"
 });',
-                       ResourceLoader::makeLoaderSourcesScript( 'local', '/w/load.php' )
-               );
-               $this->assertEquals(
-                       'mw.loader.addSource({
-    "local": "/w/load.php"
-});',
-                       ResourceLoader::makeLoaderSourcesScript( [ 'local' => '/w/load.php' ] )
+                       ResourceLoader::makeLoaderSourcesScript( $context, [ 'local' => '/w/load.php' ] )
                );
                $this->assertEquals(
                        'mw.loader.addSource({
     "local": "/w/load.php",
     "example": "https://example.org/w/load.php"
 });',
-                       ResourceLoader::makeLoaderSourcesScript( [
+                       ResourceLoader::makeLoaderSourcesScript( $context, [
                                'local' => '/w/load.php',
                                'example' => 'https://example.org/w/load.php'
                        ] )
                );
                $this->assertEquals(
                        'mw.loader.addSource([]);',
-                       ResourceLoader::makeLoaderSourcesScript( [] )
+                       ResourceLoader::makeLoaderSourcesScript( $context, [] )
                );
        }
 
index 33bc29f..3eb7498 100644 (file)
@@ -376,7 +376,7 @@ class CookieSessionProviderTest extends MediaWikiTestCase {
                ] );
 
                $request = new \FauxRequest();
-               $this->assertEquals( null, $provider->suggestLoginUsername( $request ) );
+               $this->assertNull( $provider->suggestLoginUsername( $request ) );
 
                $request->setCookies( [
                        'xUserName' => 'Example',
index 5e208ac..0cca53b 100644 (file)
@@ -47,7 +47,7 @@ class FauxResponseTest extends \MediaWikiUnitTestCase {
                        'expire' => $expire,
                ];
 
-               $this->assertEquals( null, $this->response->getCookie( 'xkey' ), 'Non-existing cookie' );
+               $this->assertNull( $this->response->getCookie( 'xkey' ), 'Non-existing cookie' );
                $this->response->setCookie( 'key', 'val', $expire, [
                        'prefix' => 'x',
                        'path' => '/path',
@@ -67,7 +67,7 @@ class FauxResponseTest extends \MediaWikiUnitTestCase {
         * @covers FauxResponse::header
         */
        public function testHeader() {
-               $this->assertEquals( null, $this->response->getHeader( 'Location' ), 'Non-existing header' );
+               $this->assertNull( $this->response->getHeader( 'Location' ), 'Non-existing header' );
 
                $this->response->header( 'Location: http://localhost/' );
                $this->assertEquals(
index bd54d50..efa0564 100644 (file)
@@ -71,8 +71,7 @@ class ChangesListFilterGroupTest extends \MediaWikiUnitTestCase {
                        $group->getFilter( 'foo' )->getName()
                );
 
-               $this->assertEquals(
-                       null,
+               $this->assertNull(
                        $group->getFilter( 'bar' )
                );
        }
index 17487ac..6566e14 100644 (file)
@@ -42,7 +42,7 @@ class DiffOpTest extends \MediaWikiUnitTestCase {
                $this->assertEquals( 'foo', $obj->getClosing( 0 ) );
                $this->assertEquals( 'bar', $obj->getClosing( 1 ) );
                $this->assertEquals( 'baz', $obj->getClosing( 2 ) );
-               $this->assertEquals( null, $obj->getClosing( 3 ) );
+               $this->assertNull( $obj->getClosing( 3 ) );
        }
 
        /**
index f3a7ae4..e8562cf 100644 (file)
@@ -38,7 +38,7 @@ class LanguageCodeTest extends MediaWikiUnitTestCase {
        public function testReplaceDeprecatedCodes() {
                $this->assertEquals( 'gsw', LanguageCode::replaceDeprecatedCodes( 'als' ) );
                $this->assertEquals( 'gsw', LanguageCode::replaceDeprecatedCodes( 'gsw' ) );
-               $this->assertEquals( null, LanguageCode::replaceDeprecatedCodes( null ) );
+               $this->assertNull( LanguageCode::replaceDeprecatedCodes( null ) );
        }
 
        /**
index b6e1d3a..7b2b299 100644 (file)
@@ -104,7 +104,7 @@ class SessionUnitTest extends MediaWikiUnitTestCase {
                $this->assertEquals( 'zero', $session->get( 0 ) );
                $this->assertFalse( $backend->dirty );
 
-               $this->assertEquals( null, $session->get( 'null' ) );
+               $this->assertNull( $session->get( 'null' ) );
                $this->assertEquals( 'default', $session->get( 'null', 'default' ) );
                $this->assertFalse( $backend->dirty );
 
@@ -165,7 +165,7 @@ class SessionUnitTest extends MediaWikiUnitTestCase {
                $this->assertFalse( $backend->dirty );
 
                $logger->setCollect( true );
-               $this->assertEquals( null, $session['null'] );
+               $this->assertNull( $session['null'] );
                $logger->setCollect( false );
                $this->assertFalse( $backend->dirty );
                $this->assertSame( [
index 72a89dd..541d24d 100644 (file)
@@ -41,6 +41,9 @@ exports.config = {
        // See http://webdriver.io/guide/services/sauce.html
        // and https://github.com/bermi/sauce-connect-launcher#advanced-usage
        services: process.env.SAUCE_ACCESS_KEY ? [ 'sauce' ] : [],
+       user: process.env.SAUCE_USERNAME,
+       key: process.env.SAUCE_ACCESS_KEY,
+       sauceConnect: true,
 
        // ==================
        // Test Files