Merge "installer: Avoid <doclink/> hack for 'config-sidebar' rendering"
authorjenkins-bot <jenkins-bot@gerrit.wikimedia.org>
Mon, 8 Jul 2019 23:53:10 +0000 (23:53 +0000)
committerGerrit Code Review <gerrit@wikimedia.org>
Mon, 8 Jul 2019 23:53:10 +0000 (23:53 +0000)
167 files changed:
RELEASE-NOTES-1.34
api.php
autoload.php
composer.json
includes/Html.php
includes/OutputPage.php
includes/ReadOnlyMode.php
includes/Revision/RevisionStore.php
includes/Revision/SlotRecord.php
includes/SiteStatsInit.php
includes/actions/DeleteAction.php
includes/actions/EditAction.php
includes/actions/HistoryAction.php
includes/actions/ProtectAction.php
includes/actions/RenderAction.php
includes/actions/UnprotectAction.php
includes/actions/ViewAction.php
includes/api/i18n/pt.json
includes/api/i18n/zh-hant.json
includes/block/AbstractBlock.php
includes/changetags/ChangeTags.php
includes/db/MWLBFactory.php
includes/filerepo/FileRepo.php
includes/filerepo/ForeignAPIRepo.php
includes/filerepo/file/LocalFile.php
includes/htmlform/HTMLForm.php
includes/htmlform/HTMLFormField.php
includes/htmlform/fields/HTMLCheckMatrix.php
includes/htmlform/fields/HTMLFormFieldWithButton.php
includes/installer/i18n/ru.json
includes/jobqueue/JobQueueGroup.php
includes/jobqueue/JobRunner.php
includes/language/Message.php
includes/libs/Xhprof.php
includes/libs/lockmanager/FSLockManager.php
includes/libs/mime/MSCompoundFileReader.php
includes/libs/objectcache/BagOStuff.php
includes/libs/objectcache/CachedBagOStuff.php
includes/libs/objectcache/IExpiringStore.php
includes/libs/objectcache/IStoreKeyEncoder.php [new file with mode: 0644]
includes/libs/objectcache/MultiWriteBagOStuff.php
includes/libs/objectcache/ReplicatedBagOStuff.php
includes/libs/objectcache/WANObjectCache.php
includes/libs/rdbms/database/DBConnRef.php
includes/libs/rdbms/database/Database.php
includes/libs/rdbms/database/IDatabase.php
includes/libs/rdbms/lbfactory/ILBFactory.php
includes/libs/rdbms/lbfactory/LBFactory.php
includes/libs/rdbms/loadbalancer/ILoadBalancer.php
includes/libs/rdbms/loadbalancer/LoadBalancer.php
includes/objectcache/SqlBagOStuff.php
includes/page/ImagePage.php
includes/page/WikiFilePage.php
includes/resourceloader/MessageBlobStore.php
includes/resourceloader/ResourceLoaderLanguageDataModule.php
includes/resourceloader/ResourceLoaderSkinModule.php
includes/site/DBSiteStore.php
includes/specials/SpecialUnblock.php
includes/specials/SpecialUndelete.php
includes/watcheditem/WatchedItemQueryService.php
languages/data/Names.php
languages/i18n/ar.json
languages/i18n/ban.json
languages/i18n/bcc.json
languages/i18n/be-tarask.json
languages/i18n/br.json
languages/i18n/ca.json
languages/i18n/ce.json
languages/i18n/ckb.json
languages/i18n/cs.json
languages/i18n/diq.json
languages/i18n/et.json
languages/i18n/exif/lrc.json
languages/i18n/fa.json
languages/i18n/fi.json
languages/i18n/fr.json
languages/i18n/gl.json
languages/i18n/he.json
languages/i18n/hyw.json
languages/i18n/is.json
languages/i18n/ja.json
languages/i18n/km.json
languages/i18n/lrc.json
languages/i18n/min.json
languages/i18n/ms.json
languages/i18n/my.json
languages/i18n/nl.json
languages/i18n/nqo.json
languages/i18n/pcd.json
languages/i18n/pl.json
languages/i18n/pt-br.json
languages/i18n/pt.json
languages/i18n/qqq.json
languages/i18n/ru.json
languages/i18n/sdc.json
languages/i18n/sh.json
languages/i18n/sk.json
languages/i18n/sl.json
languages/i18n/su.json
languages/i18n/sv.json
languages/i18n/tr.json
languages/i18n/tru.json
languages/i18n/trv.json
languages/i18n/zh-hans.json
languages/i18n/zh-hant.json
maintenance/Maintenance.php
maintenance/benchmarks/benchmarkCSSMin.php
maintenance/benchmarks/benchmarkJSMinPlus.php
maintenance/benchmarks/benchmarkJavaScriptMinifier.php
maintenance/mwdoc-filter.php
maintenance/populateContentTables.php
maintenance/populateRevisionSha1.php
maintenance/purgeModuleDeps.php
mw-config/config.js
opensearch_desc.php
package-lock.json
package.json
phpunit.xml.dist
resources/Resources.php
resources/src/jquery.tablesorter/jquery.tablesorter.js
resources/src/jquery/jquery.confirmable.js
resources/src/jquery/jquery.makeCollapsible.js
resources/src/jquery/jquery.suggestions.js
resources/src/mediawiki.action/mediawiki.action.history.js
resources/src/mediawiki.action/mediawiki.action.view.metadata.js
resources/src/mediawiki.htmlform.checker.js
resources/src/mediawiki.htmlform/cloner.js
resources/src/mediawiki.page.watch.ajax.js
resources/src/mediawiki.rcfilters/ui/ChangesListWrapperWidget.js
resources/src/mediawiki.rcfilters/ui/FilterTagMultiselectWidget.js
resources/src/mediawiki.searchSuggest/searchSuggest.js
resources/src/mediawiki.special.import.js
resources/src/mediawiki.special.preferences.ooui/confirmClose.js
resources/src/mediawiki.special.unwatchedPages/unwatchedPages.js
resources/src/mediawiki.special.watchlist/watchlist.js
resources/src/mediawiki.toc/toc.js
resources/src/mediawiki.util.js
resources/src/mediawiki.widgets/MediaSearch/mw.widgets.MediaSearchWidget.js
resources/src/mediawiki.widgets/mw.widgets.DateInputWidget.js
resources/src/startup/profiler.js
tests/phpunit/includes/HtmlTest.php
tests/phpunit/includes/OutputPageTest.php
tests/phpunit/includes/Permissions/PermissionManagerTest.php
tests/phpunit/includes/Revision/SlotRecordTest.php
tests/phpunit/includes/TitlePermissionTest.php
tests/phpunit/includes/db/LoadBalancerTest.php
tests/phpunit/includes/json/FormatJsonTest.php
tests/phpunit/includes/libs/mime/MSCompoundFileReaderTest.php [deleted file]
tests/phpunit/includes/libs/rdbms/database/DatabaseSQLTest.php
tests/phpunit/includes/parser/SanitizerTest.php
tests/phpunit/tests/MediaWikiTestCaseTest.php
tests/phpunit/unit/includes/json/FormatJsonUnitTest.php [new file with mode: 0644]
tests/phpunit/unit/includes/libs/mime/MSCompoundFileReaderTest.php [new file with mode: 0644]
tests/phpunit/unit/includes/parser/SanitizerUnitTest.php [new file with mode: 0644]
tests/qunit/suites/resources/jquery/jquery.makeCollapsible.test.js
tests/qunit/suites/resources/jquery/jquery.tablesorter.test.js
tests/qunit/suites/resources/mediawiki.special/mediawiki.special.recentchanges.test.js
tests/qunit/suites/resources/mediawiki/mediawiki.toc.test.js
tests/qunit/suites/resources/mediawiki/mediawiki.util.test.js
tests/selenium/.eslintrc.json
tests/selenium/pageobjects/history.page.js
tests/selenium/specs/page.js
tests/selenium/specs/rollback.js
tests/selenium/specs/user.js
tests/selenium/wdio-mediawiki/Api.js
tests/selenium/wdio-mediawiki/RunJobs.js
tests/selenium/wdio.conf.js

index 3223948..5e49fc7 100644 (file)
@@ -263,6 +263,8 @@ because of Phabricator reports.
 * ResourceLoader no longer creates the 'mw.legacy' placeholder object. It has
   been unused since 1.16 and was deprecated in 1.22. To deprecate a property
   in JavaScript, use mw.log.deprecate() instead.
+* The 'user.groups' module, deprecated in 1.28, was removed.
+  Use the 'user' module instead.
 * …
 
 === Deprecations in 1.34 ===
diff --git a/api.php b/api.php
index db9de75..0fb674b 100644 (file)
--- a/api.php
+++ b/api.php
@@ -61,10 +61,9 @@ $wgTitle = Title::makeTitle( NS_SPECIAL, 'Badtitle/dummy title for API calls set
 RequestContext::getMain()->setTitle( $wgTitle );
 
 try {
-       /* Construct an ApiMain with the arguments passed via the URL. What we get back
-        * is some form of an ApiMain, possibly even one that produces an error message,
-        * but we don't care here, as that is handled by the constructor.
-        */
+       // Construct an ApiMain with the arguments passed via the URL. What we get back
+       // is some form of an ApiMain, possibly even one that produces an error message,
+       // but we don't care here, as that is handled by the constructor.
        $processor = new ApiMain( RequestContext::getMain(), true );
 
        // Last chance hook before executing the API
index 5eadf79..218c244 100644 (file)
@@ -659,6 +659,7 @@ $wgAutoloadLocalClasses = [
        'IP' => __DIR__ . '/includes/libs/IP.php',
        'IPTC' => __DIR__ . '/includes/media/IPTC.php',
        'IRCColourfulRCFeedFormatter' => __DIR__ . '/includes/rcfeed/IRCColourfulRCFeedFormatter.php',
+       'IStoreKeyEncoder' => __DIR__ . '/includes/libs/objectcache/IStoreKeyEncoder.php',
        'IcuCollation' => __DIR__ . '/includes/collation/IcuCollation.php',
        'IdentityCollation' => __DIR__ . '/includes/collation/IdentityCollation.php',
        'ImageBuilder' => __DIR__ . '/maintenance/rebuildImages.php',
index 07f62e2..f7b72f5 100644 (file)
                        "composer lint",
                        "composer phpcs"
                ],
-               "phpunit": "vendor/bin/phpunit",
-               "phpunit:unit": "vendor/bin/phpunit --colors=always --testsuite=unit",
-               "phpunit:integration": "vendor/bin/phpunit --colors=always --testsuite=integration",
-               "phpunit:coverage": "php -d zend_extensions=xdebug.so vendor/bin/phpunit --testsuite=unit --exclude-group Dump,Broken,ParserFuzz,Stub"
+               "phpunit": "phpunit",
+               "phpunit:unit": "phpunit --colors=always --testsuite=core:unit,extensions:unit,skins:unit",
+               "phpunit:integration": "phpunit --colors=always --testsuite=core:integration,extensions:integration,skins:integration",
+               "phpunit:coverage": "phpunit --testsuite=core:unit --exclude-group Dump,Broken"
        },
        "config": {
                "optimize-autoloader": true,
index ebaff76..d0f9fc6 100644 (file)
@@ -831,27 +831,25 @@ class Html {
         * @return array
         */
        public static function namespaceSelectorOptions( array $params = [] ) {
-               $options = [];
-
                if ( !isset( $params['exclude'] ) || !is_array( $params['exclude'] ) ) {
                        $params['exclude'] = [];
                }
 
-               if ( isset( $params['all'] ) ) {
-                       // add an option that would let the user select all namespaces.
-                       // Value is provided by user, the name shown is localized for the user.
-                       $options[$params['all']] = wfMessage( 'namespacesall' )->text();
-               }
                if ( $params['in-user-lang'] ?? false ) {
                        global $wgLang;
                        $lang = $wgLang;
                } else {
                        $lang = MediaWikiServices::getInstance()->getContentLanguage();
                }
-               // Add all namespaces as options
-               $options += $lang->getFormattedNamespaces();
 
                $optionsOut = [];
+               if ( isset( $params['all'] ) ) {
+                       // add an option that would let the user select all namespaces.
+                       // Value is provided by user, the name shown is localized for the user.
+                       $optionsOut[$params['all']] = wfMessage( 'namespacesall' )->text();
+               }
+               // Add all namespaces as options
+               $options = $lang->getFormattedNamespaces();
                // Filter out namespaces below 0 and massage labels
                foreach ( $options as $nsId => $nsName ) {
                        if ( $nsId < NS_MAIN || in_array( $nsId, $params['exclude'] ) ) {
index 28e0a31..e78cd7b 100644 (file)
@@ -3012,6 +3012,7 @@ class OutputPage extends ContextSource {
         * @return string The doctype, opening "<html>", and head element.
         */
        public function headElement( Skin $sk, $includeStyle = true ) {
+               $config = $this->getConfig();
                $userdir = $this->getLanguage()->getDir();
                $sitedir = MediaWikiServices::getInstance()->getContentLanguage()->getDir();
 
@@ -3026,7 +3027,7 @@ class OutputPage extends ContextSource {
                        $this->setHTMLTitle( $this->msg( 'pagetitle', $this->getPageTitle() )->inContentLanguage() );
                }
 
-               if ( !Html::isXmlMimeType( $this->getConfig()->get( 'MimeType' ) ) ) {
+               if ( !Html::isXmlMimeType( $config->get( 'MimeType' ) ) ) {
                        // Add <meta charset="UTF-8">
                        // This should be before <title> since it defines the charset used by
                        // text including the text inside <title>.
@@ -3044,18 +3045,15 @@ class OutputPage extends ContextSource {
                $pieces = array_merge( $pieces, array_values( $this->getHeadLinksArray() ) );
                $pieces = array_merge( $pieces, array_values( $this->mHeadItems ) );
 
+               // This library is intended to run on older browsers that MediaWiki no longer
+               // supports as Grade A. For these Grade C browsers, we provide an experience
+               // using only HTML and CSS. Where standards-compliant browsers are able to style
+               // unknown HTML elements without issue, old IE ignores these styles.
+               // The html5shiv library fixes that.
                // Use an IE conditional comment to serve the script only to old IE
+               $shivUrl = $config->get( 'ResourceBasePath' ) . '/resources/lib/html5shiv/html5shiv.js';
                $pieces[] = '<!--[if lt IE 9]>' .
-                       ResourceLoaderClientHtml::makeLoad(
-                               new ResourceLoaderContext(
-                                       $this->getResourceLoader(),
-                                       new FauxRequest( [] )
-                               ),
-                               [ 'html5shiv' ],
-                               ResourceLoaderModule::TYPE_SCRIPTS,
-                               [ 'raw' => '1', 'sync' => '1' ],
-                               $this->getCSPNonce()
-                       ) .
+                       Html::linkedScript( $shivUrl, $this->getCSPNonce() ) .
                        '<![endif]-->';
 
                $pieces[] = Html::closeElement( 'head' );
@@ -3712,43 +3710,54 @@ class OutputPage extends ContextSource {
         */
        protected function buildExemptModules() {
                $chunks = [];
-               // Things that go after the ResourceLoaderDynamicStyles marker
-               $append = [];
 
-               // We want site, private and user styles to override dynamically added styles from
-               // general modules, but we want dynamically added styles to override statically added
-               // style modules. So the order has to be:
-               // - page style modules (formatted by ResourceLoaderClientHtml::getHeadHtml())
-               // - dynamically loaded styles (added by mw.loader before ResourceLoaderDynamicStyles)
-               // - ResourceLoaderDynamicStyles marker
-               // - site/private/user styles
+               // Requirements:
+               // - Within modules provided by the software (core, skin, extensions),
+               //   styles from skin stylesheets should be overridden by styles
+               //   from modules dynamically loaded with JavaScript.
+               // - Styles from site-specific, private, and user modules should override
+               //   both of the above.
+               //
+               // The effective order for stylesheets must thus be:
+               // 1. Page style modules, formatted server-side by ResourceLoaderClientHtml.
+               // 2. Dynamically-loaded styles, inserted client-side by mw.loader.
+               // 3. Styles that are site-specific, private or from the user, formatted
+               //    server-side by this function.
+               //
+               // The 'ResourceLoaderDynamicStyles' marker helps JavaScript know where
+               // point #2 is.
 
                // Add legacy styles added through addStyle()/addInlineStyle() here
                $chunks[] = implode( '', $this->buildCssLinksArray() ) . $this->mInlineStyles;
 
-               $chunks[] = Html::element(
-                       'meta',
-                       [ 'name' => 'ResourceLoaderDynamicStyles', 'content' => '' ]
-               );
-
+               // Things that go after the ResourceLoaderDynamicStyles marker
+               $append = [];
                $separateReq = [ 'site.styles', 'user.styles' ];
                foreach ( $this->rlExemptStyleModules as $group => $moduleNames ) {
-                       // Combinable modules
-                       $chunks[] = $this->makeResourceLoaderLink(
-                               array_diff( $moduleNames, $separateReq ),
-                               ResourceLoaderModule::TYPE_STYLES
-                       );
-
-                       foreach ( array_intersect( $moduleNames, $separateReq ) as $name ) {
-                               // These require their own dedicated request in order to support "@import"
-                               // syntax, which is incompatible with concatenation. (T147667, T37562)
-                               $chunks[] = $this->makeResourceLoaderLink( $name,
+                       if ( $moduleNames ) {
+                               $append[] = $this->makeResourceLoaderLink(
+                                       array_diff( $moduleNames, $separateReq ),
                                        ResourceLoaderModule::TYPE_STYLES
                                );
+
+                               foreach ( array_intersect( $moduleNames, $separateReq ) as $name ) {
+                                       // These require their own dedicated request in order to support "@import"
+                                       // syntax, which is incompatible with concatenation. (T147667, T37562)
+                                       $append[] = $this->makeResourceLoaderLink( $name,
+                                               ResourceLoaderModule::TYPE_STYLES
+                                       );
+                               }
                        }
                }
+               if ( $append ) {
+                       $chunks[] = Html::element(
+                               'meta',
+                               [ 'name' => 'ResourceLoaderDynamicStyles', 'content' => '' ]
+                       );
+                       $chunks = array_merge( $chunks, $append );
+               }
 
-               return self::combineWrappedStrings( array_merge( $chunks, $append ) );
+               return self::combineWrappedStrings( $chunks );
        }
 
        /**
index 1a09290..d0da10e 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 
-use Wikimedia\Rdbms\LoadBalancer;
+use Wikimedia\Rdbms\ILoadBalancer;
 
 /**
  * A service class for fetching the wiki's current read-only mode.
@@ -12,10 +12,10 @@ class ReadOnlyMode {
        /** @var ConfiguredReadOnlyMode */
        private $configuredReadOnly;
 
-       /** @var LoadBalancer */
+       /** @var ILoadBalancer */
        private $loadBalancer;
 
-       public function __construct( ConfiguredReadOnlyMode $cro, LoadBalancer $loadBalancer ) {
+       public function __construct( ConfiguredReadOnlyMode $cro, ILoadBalancer $loadBalancer ) {
                $this->configuredReadOnly = $cro;
                $this->loadBalancer = $loadBalancer;
        }
index f269afe..ec1c08c 100644 (file)
@@ -63,7 +63,7 @@ use Wikimedia\Rdbms\Database;
 use Wikimedia\Rdbms\DBConnRef;
 use Wikimedia\Rdbms\IDatabase;
 use Wikimedia\Rdbms\ILoadBalancer;
-use Wikimedia\Rdbms\ResultWrapper;
+use Wikimedia\Rdbms\IResultWrapper;
 
 /**
  * Service for looking up page revisions.
@@ -1638,7 +1638,7 @@ class RevisionStore
         * Factory method for SlotRecords based on known slot rows.
         *
         * @param int $revId The revision to load slots for.
-        * @param object[]|ResultWrapper $slotRows
+        * @param object[]|IResultWrapper $slotRows
         * @param int $queryFlags
         * @param Title $title
         *
index 064f7a4..7465f79 100644 (file)
@@ -539,6 +539,11 @@ class SlotRecord {
                try {
                        $sha1 = $this->getStringField( 'content_sha1' );
                } catch ( IncompleteRevisionException $ex ) {
+                       $sha1 = null;
+               }
+
+               // Compute if missing. Missing could mean null or empty.
+               if ( $sha1 === null || $sha1 === '' ) {
                        $format = $this->hasField( 'format_name' )
                                ? $this->getStringField( 'format_name' )
                                : null;
index e97db2d..932e1c3 100644 (file)
@@ -191,7 +191,7 @@ class SiteStatsInit {
 
        /**
         * @param int $index
-        * @param string[] $groups
+        * @param string[]|string $groups
         * @return IDatabase
         */
        private static function getDB( $index, $groups = [] ) {
index 6bed59a..6fcb1c8 100644 (file)
@@ -1,9 +1,5 @@
 <?php
 /**
- * Handle page deletion
- *
- * Copyright © 2012 Timo Tijhof
- *
  * 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
@@ -20,7 +16,6 @@
  *
  * @file
  * @ingroup Actions
- * @author Timo Tijhof
  */
 
 /**
index f0bc8bf..df48f88 100644 (file)
@@ -1,9 +1,5 @@
 <?php
 /**
- * action=edit handler
- *
- * Copyright © 2012 Timo Tijhof
- *
  * 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
  *
  * @file
  * @ingroup Actions
- * @author Timo Tijhof
  */
 
 /**
- * Page edition handler
+ * Page edition handler (action=edit)
  *
  * This is a wrapper that will call the EditPage class or a custom editor from an extension.
  *
index b1d5a50..4df2f56 100644 (file)
@@ -22,7 +22,7 @@
  */
 
 use MediaWiki\MediaWikiServices;
-use Wikimedia\Rdbms\ResultWrapper;
+use Wikimedia\Rdbms\IResultWrapper;
 use Wikimedia\Rdbms\FakeResultWrapper;
 
 /**
@@ -313,7 +313,7 @@ class HistoryAction extends FormlessAction {
         * @param int $limit The limit number of revisions to get
         * @param int $offset
         * @param int $direction Either self::DIR_PREV or self::DIR_NEXT
-        * @return ResultWrapper
+        * @return IResultWrapper
         */
        function fetchRevisions( $limit, $offset, $direction ) {
                // Fail if article doesn't exist.
index 2e9e093..5c0e2b0 100644 (file)
@@ -1,9 +1,5 @@
 <?php
 /**
- * action=protect handler
- *
- * Copyright © 2012 Timo Tijhof
- *
  * 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
  *
  * @file
  * @ingroup Actions
- * @author Timo Tijhof
  */
 
 /**
- * Handle page protection
+ * Handle page protection (action=protect)
  *
  * This is a wrapper that will call Article::protect().
  *
index 16e407f..0dfbeda 100644 (file)
@@ -1,9 +1,5 @@
 <?php
 /**
- * Handle action=render
- *
- * Copyright © 2012 Timo Tijhof
- *
  * 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
@@ -20,7 +16,6 @@
  *
  * @file
  * @ingroup Actions
- * @author Timo Tijhof
  */
 
 /**
index 0757e88..4b8e6fc 100644 (file)
@@ -1,9 +1,5 @@
 <?php
 /**
- * action=unprotect handler
- *
- * Copyright © 2012 Timo Tijhof
- *
  * 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
  *
  * @file
  * @ingroup Actions
- * @author Timo Tijhof
  */
 
 /**
- * Handle page unprotection
+ * Handle page unprotection (action=unprotect)
  *
  * This is a wrapper that will call Article::unprotect().
  *
index 134b8a4..72d92c3 100644 (file)
@@ -1,9 +1,5 @@
 <?php
 /**
- * An action that views article content
- *
- * Copyright © 2012 Timo Tijhof
- *
  * 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
@@ -20,7 +16,6 @@
  *
  * @file
  * @ingroup Actions
- * @author Timo Tijhof
  */
 
 /**
index f85840b..029a6dc 100644 (file)
        "apihelp-query-param-indexpageids": "Incluir uma secção adicional de identificadores de página que lista todos os identificadores de página devolvidos.",
        "apihelp-query-param-export": "Exportar as revisões atuais de todas as páginas fornecidas ou geradas.",
        "apihelp-query-param-exportnowrap": "Devolver o XML de exportação sem envolvê-lo num resultado XML (o mesmo formato que [[Special:Export]]). Só pode ser usado com $1export.",
+       "apihelp-query-param-exportschema": "Ao exportar, fazê-lo para a versão fornecida do formato da exportação XML. Só pode ser usado com <var>$1export</var>.",
        "apihelp-query-param-iwurl": "Indica se deve ser obtido o URL completo quando o título é uma hiperligação interwikis.",
        "apihelp-query-param-rawcontinue": "Devolver os dados em bruto de <samp>query-continue</samp> para continuar.",
        "apihelp-query-example-revisions": "Obter [[Special:ApiHelp/query+siteinfo|informação do sítio]] e as [[Special:ApiHelp/query+revisions|revisões]] da página <kbd>Main Page</kbd>.",
        "api-help-param-templated-var-first": "<var>&#x7B;$1&#x7D;</var> no nome do parâmetro deve ser substituído com os valores de <var>$2</var>",
        "api-help-param-templated-var": "<var>&#x7B;$1&#x7D;</var> com valores de <var>$2</var>",
        "api-help-datatypes-header": "Tipo de dados",
-       "api-help-datatypes": "O formato de entrada para o MediaWiki deve ser UTF-8, normalizado de acordo com a norma NFC. O MediaWiki pode converter outros tipos de entrada, mas esta conversão pode originar a falha de algumas operações (tais como as [[Special:ApiHelp/edit|edições]] com verificações MD5).\n\nAlguns tipos de parâmetros nos pedidos à API necessitam de mais explicações:\n;boolean\n:Os parâmetros boolianos funcionam como as caixas de seleção HTML: se o parâmetro for especificado, independentemente do seu valor, é considerado verdadeiro. Para um valor falso, omitir o parâmetro completo.\n;timestamp\n:As datas e horas podem ser especificadas em vários formatos. É recomendado o formato ISO 8601. Todas as horas estão em UTC, qualquer inclusão do fuso horário é ignorada.\n:* Data e hora ISO 8601, <kbd><var>2001</var>-<var>01</var>-<var>15</var>T<var>14</var>:<var>56</var>:<var>00</var>Z</kbd> (pontuação e <kbd>Z</kbd> são opcionais)\n:* Data e hora ISO 8601 com segundos fracionários (estes são ignorados), <kbd><var>2001</var>-<var>01</var>-<var>15</var>T<var>14</var>:<var>56</var>:<var>00</var>.<var>00001</var>Z</kbd> (traços, dois pontos e <kbd>Z</kbd> são opcionais)\n:* Formato do MediaWiki, <kbd><var>2001</var><var>01</var><var>15</var><var>14</var><var>56</var><var>00</var></kbd>\n:* Formato numérico genérico, <kbd><var>2001</var>-<var>01</var>-<var>15</var> <var>14</var>:<var>56</var>:<var>00</var></kbd> (fuso horário opcional <kbd>GMT</kbd>, <kbd>+<var>##</var></kbd>, ou <kbd>-<var>##</var></kbd> são ignorados)\n:* Formato EXIF, <kbd><var>2001</var>:<var>01</var>:<var>15</var> <var>14</var>:<var>56</var>:<var>00</var></kbd>\n:*Formato RFC 2822 (o fuso horário pode ser omitido), <kbd><var>Mon</var>, <var>15</var> <var>Jan</var> <var>2001</var> <var>14</var>:<var>56</var>:<var>00</var></kbd>\n:* Formato RFC 850 (o fuso horário pode ser omitido), <kbd><var>Monday</var>, <var>15</var>-<var>Jan</var>-<var>2001</var> <var>14</var>:<var>56</var>:<var>00</var></kbd>\n:* Formato C ctime, <kbd><var>Mon</var> <var>Jan</var> <var>15</var> <var>14</var>:<var>56</var>:<var>00</var> <var>2001</var></kbd>\n:* Segundos desde 1970-01-01T00:00:00Z como um inteiro de 1 a 13 algarismos (excluindo <kbd>0</kbd>)\n:* O texto <kbd>now</kbd>\n;separador alternativo de valores múltiplos\n:Os parâmetros que aceitam vários valores são normalmente fornecidos com os valores separados por uma barra vertical (''pipe''), por exemplo <kbd>parâmetro=valor1|valor2</kbd> ou <kbd>parâmetro=valor1%7Cvalor2</kbd>. Se um valor contém a barra vertical, use como separador o U+001F (Separador de Unidades) ''e'' prefixe o valor com U+001F, isto é, <kbd>parâmetro=%1Fvalor1%1Fvalor2</kbd>.",
+       "api-help-datatypes": "O formato de entrada para o MediaWiki deve ser UTF-8, normalizado de acordo com a norma NFC. O MediaWiki pode converter outros tipos de entrada, mas esta conversão pode originar a falha de algumas operações (tais como as [[Special:ApiHelp/edit|edições]] com verificações MD5).\n\nAlguns tipos de parâmetros nos pedidos à API necessitam de mais explicações:\n;boolean\n:Os parâmetros boolianos funcionam como as caixas de seleção HTML: se o parâmetro for especificado, independentemente do seu valor, é considerado verdadeiro. Para um valor falso, omitir o parâmetro completo.\n;timestamp\n:As datas e horas podem ser especificadas em vários formatos;  para obter detalhes, consulte [[mw:Special:MyLanguage/Timestamp|os formatos de entrada da biblioteca Timestamp documentados em mediawiki.org]].  É recomendado o formato de data e hora ISO 8601: <kbd><var>2001</var>-<var>01</var>-<var>15</var>T<var>14</var>:<var>56</var>:<var>00</var>Z</kbd>. Adicionalmente, pode ser usado o texto <kbd>now</kbd> para especificar a data e hora atuais.\n;separador alternativo de valores múltiplos\n:Os parâmetros que aceitam vários valores são normalmente fornecidos com os valores separados por uma barra vertical (''pipe''), por exemplo <kbd>parâmetro=valor1|valor2</kbd> ou <kbd>parâmetro=valor1%7Cvalor2</kbd>. Se um valor contém a barra vertical, use como separador o U+001F (Separador de Unidades) ''e'' prefixe o valor com U+001F, isto é, <kbd>parâmetro=%1Fvalor1%1Fvalor2</kbd>.",
        "api-help-templatedparams-header": "Parâmetros modelados",
        "api-help-templatedparams": "Os parâmetros modelados usam-se nos casos em que um módulo da API necessita de um valor para cada valor de um outro parâmetro. Por exemplo, se existisse um módulo da API para encomendar fruta, poderia ter um parâmetro <var>frutas</var> para especificar as frutas que estão a ser encomendadas e um parâmetro modelado <var>quantidade-de-{fruta}</var> para especificar quanto de cada fruta. Um cliente da API que pretenda 1 maçã, 5 bananas e 20 morangos pode então fazer um pedido como <kbd>frutas=maçãs|bananas|morangos&quantidade-de-maçãs=1&quantidade-de-bananas=5&quantidade-de-morangos=20</kbd>.",
        "api-help-param-type-limit": "Tipo: inteiro ou <kbd>max</kbd>",
index 9647675..1bdac01 100644 (file)
        "apihelp-query-param-indexpageids": "包含一個列出所有回傳頁面 ID 的額外 pageids 段落 。",
        "apihelp-query-param-export": "匯出所有指定或已產生頁面的目前修訂。",
        "apihelp-query-param-exportnowrap": "回傳不包裹在 XML 結果裡的匯出 XML(與 [[Special:Export]] 格式相同)。僅能與 $1export 一起使用。",
+       "apihelp-query-param-exportschema": "指名在匯出時 XML 傾印格式的特定版本。僅能以 <var>$1export</var> 來使用。",
        "apihelp-query-param-iwurl": "若標題是跨 wiki 連結,是否取得完整的 URL。",
        "apihelp-query-param-rawcontinue": "回傳原始的 <samp>query-continue</samp> 資料來繼續。",
        "apihelp-query-example-revisions": "索取 <kbd>Main Page</kbd> 的[[Special:ApiHelp/query+siteinfo|站台資訊]]與[[Special:ApiHelp/query+revisions|修訂]]。",
        "apihelp-query+langlinks-param-dir": "列出時所採用的方向。",
        "apihelp-query+langlinks-param-inlanguagecode": "用於本地化語言名稱的語言代碼。",
        "apihelp-query+langlinks-example-simple": "從頁面 <kbd>Main Page</kbd> 取得跨語言連結。",
+       "apihelp-query+languageinfo-summary": "回傳有關可用語言的資訊。",
+       "apihelp-query+languageinfo-extended-description": "若在一次請求中索取資訊耗費時間太長,可套用 [[mw:API:Query#Continuing queries|Continuation]]。",
+       "apihelp-query+languageinfo-param-prop": "替各語言所要取得的資訊。",
+       "apihelp-query+languageinfo-paramvalue-prop-code": "語言代碼。(此代碼是 MediaWiki 指定,與其它標準部份相同。)",
        "apihelp-query+languageinfo-paramvalue-prop-bcp47": "BCP-47 語言代碼。",
+       "apihelp-query+languageinfo-paramvalue-prop-dir": "語言的書寫方向(<code>ltr</code> 或 <code>rtl</code>)。",
        "apihelp-query+languageinfo-paramvalue-prop-autonym": "語言的本語稱呼,也就是該語言用自己語言本身寫出的名稱。",
+       "apihelp-query+languageinfo-paramvalue-prop-name": "在由 <var>lilang</var> 參數所指定語言裡的語言名稱,如有需要可套用語言遞補。",
+       "apihelp-query+languageinfo-paramvalue-prop-fallbacks": "替此語言設置的遞補語言之語言代碼。「en」不包括在內含的最後遞補(但一些語言可明確地指定「en」為最後遞補)。",
+       "apihelp-query+languageinfo-paramvalue-prop-variants": "由此語言所支援的變體語言代碼。",
+       "apihelp-query+languageinfo-param-code": "所應要回傳的語言該語言代碼,或是以 <code>*</code> 來表示為全部語言。",
        "apihelp-query+languageinfo-example-simple": "取得所有支援語言的語言代碼。",
        "apihelp-query+languageinfo-example-autonym-name-de": "取得所有支援語言的本語稱呼和德語名稱。",
+       "apihelp-query+languageinfo-example-fallbacks-variants-oc": "取得遞補語言與奧克語的變體。",
+       "apihelp-query+languageinfo-example-bcp47-dir": "取得 BCP-47 語言代碼與所有支援語言的書寫方向。",
        "apihelp-query+links-summary": "回傳指定頁面的所有連結。",
        "apihelp-query+links-param-namespace": "僅顯示在這些命名空間的連結。",
        "apihelp-query+links-param-limit": "要回傳的連結數量。",
        "api-help-param-templated-var-first": "在參數名稱裡的 <var>&#x7B;$1&#x7D;</var> 應替換成 <var>$2</var> 的值",
        "api-help-param-templated-var": "<var>&#x7B;$1&#x7D;</var> 與 <var>$2</var> 的值",
        "api-help-datatypes-header": "資料類型",
-       "api-help-datatypes": "è\87³MediaWikiç\9a\84輸å\85¥å\80¼æ\87\89ç\82ºNFCæ¨\99æº\96å\8c\96ç\9a\84UTF-8ã\80\82MediaWikiå\8f¯ä»¥å\98\97試è½\89æ\8f\9bå\85¶ä»\96輸å\85¥å\80¼ï¼\8cä½\86é\80\99å\8f¯è\83½å°\8eè\87´ä¸\80äº\9bæ\93\8dä½\9c失æ\95\97ï¼\88ä¾\8bå¦\82é\99\84帶MD5檢æ\9f¥ç\9a\84[[Special:ApiHelp/edit|編輯]]ï¼\89ã\80\82\n\nä¸\80äº\9bå\9c¨APIè«\8bæ±\82中ç\9a\84å\8f\83æ\95¸é¡\9eå\9e\8bé\9c\80è¦\81æ\9b´é\80²ä¸\80步解é\87\8bï¼\9a\n;boolean\n:å¸\83æ\9e\97å\8f\83æ\95¸ç\94¢ç\94\9fä½\9cç\94¨å°±å\83\8fHTMLè¤\87é\81¸æ¡\86ä¸\80樣ï¼\9aå¦\82æ\9e\9cå\8f\83æ\95¸è¢«æ\8c\87å®\9aï¼\8cç\84¡è«\96ä½\95å\80¼é\83½è¢«è¦\96ç\82ºç\9c\9fï¼\88trueï¼\89ã\80\82å¦\82æ\9e\9cè¦\81å\81\87å\80¼ï¼\88falseï¼\89ï¼\8cå\89\87å¿\85é \88ç\9c\81ç\95¥å\8f\83æ\95¸ã\80\82\n;timestamp\n:æ\99\82é\96\93æ\88³è¨\98å\8f¯è¢«æ\8c\87å®\9aç\82ºå¤\9a種格å¼\8fã\80\82æ\8e¨è\8d\90使ç\94¨ISO 8601æ\97¥æ\9c\9få\92\8cæ\99\82é\96\93æ¨\99æº\96ã\80\82æ\89\80æ\9c\89æ\99\82é\96\93ç\82ºUTCæ\99\82é\96\93ï¼\8cå\8c\85å\90«ç\9a\84ä»»ä½\95æ\99\82å\8d\80é\83½æ\9c\83被忽ç\95¥ã\80\82\n:* ISO 8601æ\97¥æ\9c\9få\92\8cæ\99\82é\96\93ï¼\8c<kbd><var>2001</var>-<var>01</var>-<var>15</var>T<var>14</var>:<var>56</var>:<var>00</var>Z</kbd>ï¼\88æ¨\99é»\9eå\92\8c<kbd>Z</kbd>ç\82ºé\81¸ç\94¨ï¼\89\n:* å¸¶å°\8fæ\95¸ç§\92ï¼\88æ\9c\83被忽ç\95¥ï¼\89ç\9a\84ISO 8601æ\97¥æ\9c\9få\92\8cæ\99\82é\96\93ï¼\8c<kbd><var>2001</var>-<var>01</var>-<var>15</var>T<var>14</var>:<var>56</var>:<var>00</var>.<var>00001</var>Z</kbd>ï¼\88ç ´æ\8a\98è\99\9fã\80\81å\86\92è\99\9få\92\8c<kbd>Z</kbd>ç\82ºé\81¸ç\94¨ï¼\89\n:* MediaWikiæ ¼å¼\8fï¼\8c<kbd><var>2001</var><var>01</var><var>15</var><var>14</var><var>56</var><var>00</var></kbd>\n:* ä¸\80è\88¬æ\95¸å­\97æ ¼å¼\8fï¼\8c<kbd><var>2001</var>-<var>01</var>-<var>15</var> <var>14</var>:<var>56</var>:<var>00</var></kbd>ï¼\88<kbd>GMT</kbd>ã\80\81<kbd>+<var>##</var></kbd>æ\88\96<kbd>-<var>##</var></kbd>ç\9a\84é\81¸ç\94¨æ\99\82å\8d\80æ\9c\83被忽ç\95¥ï¼\89\n:* EXIFæ ¼å¼\8fï¼\8c<kbd><var>2001</var>:<var>01</var>:<var>15</var> <var>14</var>:<var>56</var>:<var>00</var></kbd>\n:* RFC 2822æ ¼å¼\8fï¼\88æ\99\82å\8d\80å\8f¯ç\9c\81ç\95¥ï¼\89ï¼\8c<kbd><var>Mon</var>, <var>15</var> <var>Jan</var> <var>2001</var> <var>14</var>:<var>56</var>:<var>00</var></kbd>\n:* RFC 850æ ¼å¼\8fï¼\88æ\99\82å\8d\80å\8f¯ç\9c\81ç\95¥ï¼\89ï¼\8c<kbd><var>Monday</var>, <var>15</var>-<var>Jan</var>-<var>2001</var> <var>14</var>:<var>56</var>:<var>00</var></kbd>\n:* C ctimeæ ¼å¼\8fï¼\8c<kbd><var>Mon</var> <var>Jan</var> <var>15</var> <var>14</var>:<var>56</var>:<var>00</var> <var>2001</var></kbd>\n:* å¾\9e1970-01-01T00:00:00Zé\96\8bå§\8bç\9a\84ç§\92æ\95¸ï¼\8cä½\9cç\82º1å\88°13ä½\8dæ\95¸ç\9a\84æ\95´æ\95¸ï¼\88é\99¤äº\86<kbd>0</kbd>ï¼\89\n:* å­\97串<kbd>now</kbd>\n;æ\9b¿ä»£å¤\9aå\80¼å\88\86é\9a\94符è\99\9f\n:使ç\94¨å¤\9aå\80\8bå\80¼ç\9a\84å\8f\83æ\95¸é\80\9a常æ\9c\83è\88\87å\9e\82ç\9b´ç·\9a符è\99\9fï¼\88|ï¼\89å\88\86é\9a\94ç\9a\84å\80¼ä¸\80èµ·æ\8f\90交ï¼\8cä¾\8bå¦\82<kbd>param=value1|value2</kbd>æ\88\96<kbd>param=value1%7Cvalue2</kbd>ã\80\82å¦\82æ\9e\9cå\80¼å¿\85é \88å\8c\85å\90«å\9e\82ç\9b´ç·\9a符è\99\9fï¼\8c使ç\94¨U+001Fï¼\88å\96®ä½\8då\88\86é\9a\94符è\99\9fï¼\89ä½\9cç\82ºå\88\86é\9a\94符è\99\9fï¼\8c''並ä¸\94''å\9c¨å\80¼å\89\8då\8a å\89\8d綴U+001Fï¼\8cä¾\8bå¦\82<kbd>param=%1Fvalue1%1Fvalue2</kbd>。",
+       "api-help-datatypes": "輸å\85¥è\87³ MediaWiki ç\9a\84å\80¼æ\87\89ç\82º NFC æ¨\99æº\96å\8c\96ç\9a\84 UTF-8ã\80\82MediaWiki å\8f¯ä»¥å\98\97試è½\89æ\8f\9bå\85¶ä»\96輸å\85¥å\80¼ï¼\8cä½\86é\80\99å\8f¯è\83½å°\8eè\87´ä¸\80äº\9bæ\93\8dä½\9c失æ\95\97ï¼\88ä¾\8bå¦\82é\99\84帶 MD5 æª¢æ\9f¥ç\9a\84[[Special:ApiHelp/edit|編輯]]ï¼\89ã\80\82\n\nä¸\80äº\9bå\9c¨ API è«\8bæ±\82中ç\9a\84å\8f\83æ\95¸é¡\9eå\9e\8bé\9c\80è¦\81æ\9b´é\80²ä¸\80步解é\87\8bï¼\9a\n;boolean\n:å¸\83æ\9e\97å\8f\83æ\95¸ç\94¢ç\94\9fä½\9cç\94¨å°±å\83\8fHTMLè¤\87é\81¸æ¡\86ä¸\80樣ï¼\9aå¦\82æ\9e\9cå\8f\83æ\95¸è¢«æ\8c\87å®\9aï¼\8cç\84¡è«\96ä½\95å\80¼é\83½è¢«è¦\96ç\82ºç\9c\9fï¼\88trueï¼\89ã\80\82å¦\82æ\9e\9cè¦\81å\81\87å\80¼ï¼\88falseï¼\89ï¼\8cå\89\87å¿\85é \88ç\9c\81ç\95¥å\8f\83æ\95¸ã\80\82\n;timestamp\n:æ\99\82é\96\93æ\88³è¨\98å\8f¯è¢«æ\8c\87å®\9aç\82ºå¤\9a種格å¼\8fã\80\82è«\8bæ\9f¥ç\9c\8bå\9c¨ mediawiki.org ä¸\8aç\9a\84[[mw:Special:MyLanguage/Timestamp|æ\99\82é\96\93æ\88³è¨\98å\87½å¼\8f庫輸å\85¥æ ¼å¼\8fæ\96\87件]]ä¾\86ç\8d²å¾\97æ\9b´å¤\9a詳細å\85§å®¹ã\80\82æ\8e¨è\8d\90使ç\94¨ ISO 8601 æ\97¥æ\9c\9få\92\8cæ\99\82é\96\93æ¨\99æº\96ï¼\88ä¾\8bï¼\9akbd><var>2001</var>-<var>01</var>-<var>15</var>T<var>14</var>:<var>56</var>:<var>00</var>Z</kbd>ï¼\89ã\80\82å\8f¦å¤\96ï¼\8cå­\97串 <kbd>now</kbd> å\8f¯ç\94¨ä¾\86代表ç\82ºç\9b®å\89\8dæ\99\82é\96\93ç\9a\84æ\99\82é\96\93æ\88³è¨\98ã\80\82\n;æ\9b¿ä»£å¤\9aå\80¼å\88\86é\9a\94符è\99\9f\n:使ç\94¨å¤\9aå\80\8bå\80¼ç\9a\84å\8f\83æ\95¸é\80\9a常æ\9c\83è\88\87å\9e\82ç\9b´ç·\9a符è\99\9fï¼\88|ï¼\89å\88\86é\9a\94ç\9a\84å\80¼ä¸\80èµ·æ\8f\90交ï¼\8cä¾\8bå¦\82 <kbd>param=value1|value2</kbd>æ\88\96<kbd>param=value1%7Cvalue2</kbd>ã\80\82å¦\82æ\9e\9cå\80¼å¿\85é \88å\8c\85å\90«å\9e\82ç\9b´ç·\9a符è\99\9fï¼\8c使ç\94¨ U+001Fï¼\88å\96®ä½\8då\88\86é\9a\94符è\99\9fï¼\89ä½\9cç\82ºå\88\86é\9a\94符è\99\9fï¼\8c''並ä¸\94''å\9c¨å\80¼å\89\8då\8a å\89\8d綴 U+001Fï¼\8cä¾\8bå¦\82ï¼\9a<kbd>param=%1Fvalue1%1Fvalue2</kbd>。",
        "api-help-templatedparams-header": "模板參數",
        "api-help-templatedparams": "模板參數可支援當 API 模組需要替某些參數值給予值的情況。舉例來說,如果有個用來請求水果的 API 模組,可能會有一個用來指定水果的 <var>fruits</var> 參數,以及用來指定有多少顆水果的模板參數 <var>{fruit}-quantity</var>。若一個 API 客戶端想要 1 顆蘋果、5 條香蕉、以及 20 粒草莓時,可以做出像是 <kbd>fruits=apples|bananas|strawberries&apples-quantity=1&bananas-quantity=5&strawberries-quantity=20</kbd> 這樣的請求。",
        "api-help-param-type-limit": "類型:整數或<kbd>max</kbd>",
index 0357f8d..d24a2a5 100644 (file)
@@ -513,10 +513,13 @@ abstract class AbstractBlock {
         * @return array
         */
        public function getBlockErrorParams( IContextSource $context ) {
+               $lang = $context->getLanguage();
+
                $blocker = $this->getBlocker();
                if ( $blocker instanceof User ) { // local user
                        $blockerUserpage = $blocker->getUserPage();
-                       $link = "[[{$blockerUserpage->getPrefixedText()}|{$blockerUserpage->getText()}]]";
+                       $blockerText = $lang->embedBidi( $blockerUserpage->getText() );
+                       $link = "[[{$blockerUserpage->getPrefixedText()}|{$blockerText}]]";
                } else { // foreign user
                        $link = $blocker;
                }
@@ -528,19 +531,18 @@ abstract class AbstractBlock {
 
                /* $ip returns who *is* being blocked, $intended contains who was meant to be blocked.
                 * This could be a username, an IP range, or a single IP. */
-               $intended = $this->getTarget();
-               $lang = $context->getLanguage();
+               $intended = (string)$this->getTarget();
 
                return [
                        $link,
                        $reason,
                        $context->getRequest()->getIP(),
-                       $this->getByName(),
+                       $lang->embedBidi( $this->getByName() ),
                        // TODO: SystemBlock replaces this with the system block type. Clean up
                        // error params so that this is not necessary.
                        $this->getId(),
                        $lang->formatExpiry( $this->getExpiry() ),
-                       (string)$intended,
+                       $lang->embedBidi( $intended ),
                        $lang->userTimeAndDate( $this->getTimestamp(), $context->getUser() ),
                ];
        }
index 14b53d3..40f7180 100644 (file)
@@ -149,7 +149,13 @@ class ChangeTags {
                $msg = $context->msg( "tag-$tag" );
                if ( !$msg->exists() ) {
                        // No such message
-                       return new RawMessage( '$1', [ Message::plaintextParam( $tag ) ] );
+                       return ( new RawMessage( '$1', [ Message::plaintextParam( $tag ) ] ) )
+                               // HACK MessageLocalizer doesn't have a way to set the right language on a RawMessage,
+                               // so extract the language from $msg and use that.
+                               // The language doesn't really matter, but we need to set it to avoid requesting
+                               // the user's language from session-less entry points (T227233)
+                               ->inLanguage( $msg->getLanguage() );
+
                }
                if ( $msg->isDisabled() ) {
                        // The message exists but is disabled, hide the tag.
index 27695cc..3d404d3 100644 (file)
@@ -70,6 +70,7 @@ abstract class MWLBFactory {
         * @param BagOStuff $mainStash
         * @param WANObjectCache $wanCache
         * @return array
+        * @internal For use with service wiring
         */
        public static function applyDefaultConfig(
                array $lbConf,
@@ -152,8 +153,11 @@ abstract class MWLBFactory {
                        $serversCheck = [ $lbConf['serverTemplate'] ] ?? [];
                }
 
-               self::assertValidServerConfigs( $serversCheck, $options->get( 'DBname' ),
-                       $options->get( 'DBprefix' ) );
+               self::assertValidServerConfigs(
+                       $serversCheck,
+                       $options->get( 'DBname' ),
+                       $options->get( 'DBprefix' )
+               );
 
                $lbConf = self::injectObjectCaches( $lbConf, $srvCace, $mainStash, $wanCache );
 
@@ -164,7 +168,7 @@ abstract class MWLBFactory {
         * @return array
         */
        private static function getDbTypesWithSchemas() {
-               return [ 'postgres', 'msssql' ];
+               return [ 'postgres', 'mssql' ];
        }
 
        /**
@@ -328,6 +332,7 @@ abstract class MWLBFactory {
         *
         * @param array $config (e.g. $wgLBFactoryConf)
         * @return string Class name
+        * @internal For use with service wiring
         */
        public static function getLBFactoryClass( array $config ) {
                // For configuration backward compatibility after removing
@@ -365,13 +370,9 @@ abstract class MWLBFactory {
        /**
         * @param LBFactory $lbFactory
         * @param string $dbType 'mysql', 'sqlite', etc.
+        * @internal For use with service wiring
         */
        public static function setSchemaAliases( LBFactory $lbFactory, $dbType ) {
-               if ( $dbType instanceof Config ) {
-                       // Before 1.34 this took a whole Config just to get $dbType
-                       wfDeprecated( __METHOD__ . ' with Config argument', '1.34' );
-                       $dbType = $dbType->get( 'DBtype' );
-               }
                if ( $dbType === 'mysql' ) {
                        /**
                         * When SQLite indexes were introduced in r45764, it was noted that
@@ -398,6 +399,7 @@ abstract class MWLBFactory {
        /**
         * Log a database deprecation warning
         * @param string $msg Deprecation message
+        * @internal For use with service wiring
         */
        public static function logDeprecation( $msg ) {
                global $wgDevelopmentWarnings;
index 51cef81..cbbffe4 100644 (file)
@@ -121,13 +121,13 @@ class FileRepo {
        /** @var bool Whether all zones should be private (e.g. private wiki repo) */
        protected $isPrivate;
 
-       /** @var array callable Override these in the base class */
+       /** @var callable Override these in the base class */
        protected $fileFactory = [ UnregisteredLocalFile::class, 'newFromTitle' ];
-       /** @var array callable|bool Override these in the base class */
+       /** @var callable|false Override these in the base class */
        protected $oldFileFactory = false;
-       /** @var array callable|bool Override these in the base class */
+       /** @var callable|false Override these in the base class */
        protected $fileFactoryKey = false;
-       /** @var array callable|bool Override these in the base class */
+       /** @var callable|false Override these in the base class */
        protected $oldFileFactoryKey = false;
 
        /** @var string URL of where to proxy thumb.php requests to.
@@ -230,7 +230,7 @@ class FileRepo {
        /**
         * Check if a single zone or list of zones is defined for usage
         *
-        * @param array $doZones Only do a particular zones
+        * @param string[]|string $doZones Only do a particular zones
         * @throws MWException
         * @return Status
         */
@@ -734,7 +734,7 @@ class FileRepo {
        /**
         * Make an url to this repo
         *
-        * @param string $query Query string to append
+        * @param string|string[] $query Query string to append
         * @param string $entry Entry point; defaults to index
         * @return string|bool False on failure
         */
@@ -1739,7 +1739,7 @@ class FileRepo {
        /**
         * Create a new good result
         *
-        * @param null|string $value
+        * @param null|mixed $value
         * @return Status
         */
        public function newGood( $value = null ) {
index 2c6f296..8ff8143 100644 (file)
@@ -184,7 +184,7 @@ class ForeignAPIRepo extends FileRepo {
 
        /**
         * @param array $query
-        * @return string
+        * @return array|null
         */
        function fetchImageQuery( $query ) {
                global $wgLanguageCode;
index d7d6bf7..54fc251 100644 (file)
@@ -25,6 +25,7 @@ use Wikimedia\AtEase\AtEase;
 use MediaWiki\Logger\LoggerFactory;
 use Wikimedia\Rdbms\Database;
 use Wikimedia\Rdbms\IDatabase;
+use Wikimedia\Rdbms\IResultWrapper;
 use MediaWiki\MediaWikiServices;
 
 /**
@@ -99,7 +100,7 @@ class LocalFile extends File {
        /** @var int Number of line to return by nextHistoryLine() (constructor) */
        private $historyLine;
 
-       /** @var int Result of the query for the file's history (nextHistoryLine) */
+       /** @var IResultWrapper|null Result of the query for the file's history (nextHistoryLine) */
        private $historyRes;
 
        /** @var string Major MIME type */
index 99e387a..a7cef3c 100644 (file)
@@ -184,6 +184,7 @@ class HTMLForm extends ContextSource {
        protected $mFieldTree = [];
        protected $mShowReset = false;
        protected $mShowSubmit = true;
+       /** @var string[] */
        protected $mSubmitFlags = [ 'primary', 'progressive' ];
        protected $mShowCancel = false;
        protected $mCancelTarget;
index ff805d8..590b9e7 100644 (file)
@@ -367,7 +367,7 @@ abstract class HTMLFormField {
         * or the input's default value if it has not been set.
         *
         * @param WebRequest $request
-        * @return string The value
+        * @return mixed The value
         */
        public function loadDataFromRequest( $request ) {
                if ( $request->getCheck( $this->mName ) ) {
@@ -653,7 +653,7 @@ abstract class HTMLFormField {
 
        /**
         * Get a FieldLayout (or subclass thereof) to wrap this field in when using OOUI output.
-        * @param string $inputField
+        * @param OOUI\Widget $inputField
         * @param array $config
         * @return OOUI\FieldLayout|OOUI\ActionFieldLayout
         */
@@ -1032,7 +1032,7 @@ abstract class HTMLFormField {
         * Recursively forces values in an array to strings, because issues arise
         * with integer 0 as a value.
         *
-        * @param array $array
+        * @param array|string $array
         * @return array|string
         */
        public static function forceToStringRecursive( $array ) {
index 8ce3c83..8e51858 100644 (file)
@@ -196,7 +196,7 @@ class HTMLCheckMatrix extends HTMLFormField implements HTMLNestedFilterable {
         * line above the options in the case of a checkbox matrix, i.e. it's always
         * a "vertical-label".
         *
-        * @param string $value The value to set the input to
+        * @param string|array $value The value to set the input to
         *
         * @return string Complete HTML table row
         */
index be8f7d8..4372cd1 100644 (file)
@@ -18,7 +18,7 @@ class HTMLFormFieldWithButton extends HTMLFormField {
        /** @var string $mButtonType Value for the button in this field */
        protected $mButtonValue;
 
-       /** @var string $mButtonType Value for the button in this field */
+       /** @var string[] $mButtonType Value for the button in this field */
        protected $mButtonFlags = [ 'progressive' ];
 
        public function __construct( $info ) {
index 82923e5..4943e72 100644 (file)
@@ -79,7 +79,7 @@
        "config-unicode-pure-php-warning": "'''Внимание!''': [https://php.net/manual/en/book.intl.php PHP intl расширение] недоступно для нормализации Юникода, будет использоваться медленная реализация на чистом PHP.\nЕсли ваш сайт работает под высокой нагрузкой, вам следует больше узнать о [https://www.mediawiki.org/wiki/Special:MyLanguage/Unicode_normalization_considerations нормализации Юникода].",
        "config-unicode-update-warning": "'''Предупреждение''': установленная версия обёртки нормализации Юникода использует старую версию библиотеки [http://site.icu-project.org/ проекта ICU].\nВы должны [https://www.mediawiki.org/wiki/Special:MyLanguage/Unicode_normalization_considerations обновить версию], если хотите полноценно использовать Юникод.",
        "config-no-db": "Не удалось найти подходящие драйвера баз данных! Вам необходимо установить драйвера базы данных для PHP.\n{{PLURAL:$2|Поддерживается следующий тип|Поддерживаются следующие типы}} баз данных: $1.\n\nЕсли вы скомпилировали PHP сами, перенастройте его с включением клиента баз данных, например, с помощью <code>./configure --with-mysqli</code>.\nЕсли вы установили PHP из пакетов Debian или Ubuntu, то вам также необходимо установить, например, пакет <code>php-mysql</code>.",
-       "config-outdated-sqlite": "'''Предупреждение''': у Вас установлен SQLite  $1, версия которого ниже требуемой $2 . SQLite будет недоступен.",
+       "config-outdated-sqlite": "<strong>Предупреждение</strong>: у Вас установлен SQLite $2, версия которого ниже требуемой $1. SQLite будет недоступен.",
        "config-no-fts3": "'''Внимание''': SQLite собран без модуля [//sqlite.org/fts3.html FTS3] — поиск не будет работать для этой базы данных.",
        "config-pcre-old": "'''Фатальная ошибка:''' требуется PCRE версии $1 или более поздняя.\nВаш исполняемый файл PHP связан с PCRE версии $2.\n[https://www.mediawiki.org/wiki/Manual:Errors_and_symptoms/PCRE Подробнее].",
        "config-pcre-no-utf8": "'''Фатальная ошибка'''. Модуль PCRE для PHP, похоже, собран без поддержки PCRE_UTF8.\nMediaWiki требует поддержки UTF-8 для корректной работы.",
index 2937d01..756724e 100644 (file)
@@ -271,10 +271,10 @@ class JobQueueGroup {
        /**
         * Acknowledge that a job was completed
         *
-        * @param Job $job
+        * @param RunnableJob $job
         * @return void
         */
-       public function ack( Job $job ) {
+       public function ack( RunnableJob $job ) {
                $this->get( $job->getType() )->ack( $job );
        }
 
@@ -282,10 +282,10 @@ class JobQueueGroup {
         * Register the "root job" of a given job into the queue for de-duplication.
         * This should only be called right *after* all the new jobs have been inserted.
         *
-        * @param Job $job
+        * @param RunnableJob $job
         * @return bool
         */
-       public function deduplicateRootJob( Job $job ) {
+       public function deduplicateRootJob( RunnableJob $job ) {
                return $this->get( $job->getType() )->deduplicateRootJob( $job );
        }
 
index 454f694..21d8c7e 100644 (file)
@@ -23,7 +23,7 @@
 
 use MediaWiki\MediaWikiServices;
 use MediaWiki\Logger\LoggerFactory;
-use Liuggio\StatsdClient\Factory\StatsdDataFactory;
+use Liuggio\StatsdClient\Factory\StatsdDataFactoryInterface;
 use Psr\Log\LoggerAwareInterface;
 use Psr\Log\LoggerInterface;
 use Wikimedia\ScopedCallback;
@@ -265,13 +265,13 @@ class JobRunner implements LoggerAwareInterface {
        }
 
        /**
-        * @param Job $job
+        * @param RunnableJob $job
         * @param LBFactory $lbFactory
-        * @param StatsdDataFactory $stats
+        * @param StatsdDataFactoryInterface $stats
         * @param float $popTime
         * @return array Map of status/error/timeMs
         */
-       private function executeJob( Job $job, LBFactory $lbFactory, $stats, $popTime ) {
+       private function executeJob( RunnableJob $job, LBFactory $lbFactory, $stats, $popTime ) {
                $jType = $job->getType();
                $msg = $job->toString() . " STARTING";
                $this->logger->debug( $msg, [
@@ -367,11 +367,11 @@ class JobRunner implements LoggerAwareInterface {
        }
 
        /**
-        * @param Job $job
+        * @param RunnableJob $job
         * @return int Seconds for this runner to avoid doing more jobs of this type
         * @see $wgJobBackoffThrottling
         */
-       private function getBackoffTimeToWait( Job $job ) {
+       private function getBackoffTimeToWait( RunnableJob $job ) {
                $throttling = $this->config->get( 'JobBackoffThrottling' );
 
                if ( !isset( $throttling[$job->getType()] ) || $job instanceof DuplicateJob ) {
@@ -526,11 +526,11 @@ class JobRunner implements LoggerAwareInterface {
         * $wgJobSerialCommitThreshold for more.
         *
         * @param LBFactory $lbFactory
-        * @param Job $job
+        * @param RunnableJob $job
         * @param string $fnameTrxOwner
         * @throws DBError
         */
-       private function commitMasterChanges( LBFactory $lbFactory, Job $job, $fnameTrxOwner ) {
+       private function commitMasterChanges( LBFactory $lbFactory, RunnableJob $job, $fnameTrxOwner ) {
                $syncThreshold = $this->config->get( 'JobSerialCommitThreshold' );
 
                $time = false;
index 0b3113f..12007fa 100644 (file)
@@ -20,6 +20,8 @@
  * @file
  * @author Niklas Laxström
  */
+
+use MediaWiki\Logger\LoggerFactory;
 use MediaWiki\MediaWikiServices;
 
 /**
@@ -856,7 +858,7 @@ class Message implements MessageSpecifier, Serializable {
        public function toString( $format = null ) {
                if ( $format === null ) {
                        $ex = new LogicException( __METHOD__ . ' using implicit format: ' . $this->format );
-                       \MediaWiki\Logger\LoggerFactory::getInstance( 'message-format' )->warning(
+                       LoggerFactory::getInstance( 'message-format' )->warning(
                                $ex->getMessage(), [ 'exception' => $ex, 'format' => $this->format, 'key' => $this->key ] );
                        $format = $this->format;
                }
@@ -1206,7 +1208,7 @@ class Message implements MessageSpecifier, Serializable {
                                if ( !is_scalar( $param ) ) {
                                        $param = serialize( $param );
                                }
-                               \MediaWiki\Logger\LoggerFactory::getInstance( 'Bug58676' )->warning(
+                               LoggerFactory::getInstance( 'Bug58676' )->warning(
                                        'Invalid parameter for message "{msgkey}": {param}',
                                        [
                                                'exception' => new Exception,
index 8175427..a1ddfd0 100644 (file)
@@ -77,6 +77,8 @@ class Xhprof {
                                'tideways_disable',
                                'tideways_xhprof_disable'
                        ] );
+               } else {
+                       return null;
                }
        }
 
@@ -84,6 +86,7 @@ class Xhprof {
         * Call the first available function from $functions.
         * @param array $functions
         * @param array $args
+        * @return mixed
         * @throws Exception
         */
        protected static function callAny( array $functions, array $args = [] ) {
index 019029c..c00b041 100644 (file)
@@ -124,9 +124,13 @@ class FSLockManager extends LockManager {
                        } else {
                                Wikimedia\suppressWarnings();
                                $handle = fopen( $this->getLockPath( $path ), 'a+' );
-                               if ( !$handle ) { // lock dir missing?
-                                       mkdir( $this->lockDir, 0777, true );
-                                       $handle = fopen( $this->getLockPath( $path ), 'a+' ); // try again
+                               if ( !$handle && !is_dir( $this->lockDir ) ) {
+                                       // Create the lock directory in case it is missing
+                                       if ( mkdir( $this->lockDir, 0777, true ) ) {
+                                               $handle = fopen( $this->getLockPath( $path ), 'a+' ); // try again
+                                       } else {
+                                               $this->logger->error( "Cannot create directory '{$this->lockDir}'." );
+                                       }
                                }
                                Wikimedia\restoreWarnings();
                        }
index aea0a02..8afaa38 100644 (file)
@@ -333,7 +333,7 @@ class MSCompoundFileReader {
                                continue;
                        }
 
-                       $name = iconv( 'UTF-16', 'UTF-8', substr( $entry['name_raw'], 0, $entry['name_length'] - 2 ) );
+                       $name = iconv( 'UTF-16LE', 'UTF-8', substr( $entry['name_raw'], 0, $entry['name_length'] - 2 ) );
 
                        $clsid = $this->decodeClsid( $entry['clsid'] );
                        if ( $type == self::TYPE_ROOT && isset( self::$mimesByClsid[$clsid] ) ) {
index 7759947..00bf57d 100644 (file)
@@ -61,7 +61,7 @@ use Wikimedia\WaitConditionLoop;
  *
  * @ingroup Cache
  */
-abstract class BagOStuff implements IExpiringStore, LoggerAwareInterface {
+abstract class BagOStuff implements IExpiringStore, IStoreKeyEncoder, LoggerAwareInterface {
        /** @var array[] Lock tracking */
        protected $locks = [];
        /** @var int ERR_* class constant */
@@ -655,11 +655,12 @@ abstract class BagOStuff implements IExpiringStore, LoggerAwareInterface {
         * @param string $date The reference date in MW format
         * @param callable|bool $progressCallback Optional, a function which will be called
         *     regularly during long-running operations with the percentage progress
-        *     as the first parameter.
+        *     as the first parameter. [optional]
+        * @param int $limit Maximum number of keys to delete [default: INF]
         *
         * @return bool Success, false if unimplemented
         */
-       public function deleteObjectsExpiringBefore( $date, $progressCallback = false ) {
+       public function deleteObjectsExpiringBefore( $date, $progressCallback = false, $limit = INF ) {
                // stub
                return false;
        }
index 8892f73..0bdd349 100644 (file)
@@ -82,9 +82,9 @@ class CachedBagOStuff extends HashBagOStuff {
                $this->backend->setDebug( $bool );
        }
 
-       public function deleteObjectsExpiringBefore( $date, $progressCallback = false ) {
-               parent::deleteObjectsExpiringBefore( $date, $progressCallback );
-               return $this->backend->deleteObjectsExpiringBefore( $date, $progressCallback );
+       public function deleteObjectsExpiringBefore( $date, $progressCallback = false, $limit = INF ) {
+               parent::deleteObjectsExpiringBefore( $date, $progressCallback, $limit );
+               return $this->backend->deleteObjectsExpiringBefore( $date, $progressCallback, $limit );
        }
 
        public function makeKeyInternal( $keyspace, $args ) {
index 61a4c61..1566c07 100644 (file)
@@ -17,7 +17,6 @@
  *
  * @file
  * @ingroup Cache
- * @author 2015 Timo Tijhof
  */
 
 /**
diff --git a/includes/libs/objectcache/IStoreKeyEncoder.php b/includes/libs/objectcache/IStoreKeyEncoder.php
new file mode 100644 (file)
index 0000000..da0686e
--- /dev/null
@@ -0,0 +1,27 @@
+<?php
+
+/**
+ * Generic interface for object stores with key encoding methods.
+ *
+ * @ingroup Cache
+ * @since 1.34
+ */
+interface IStoreKeyEncoder {
+       /**
+        * Make a global cache key.
+        *
+        * @param string $class Key class
+        * @param string|null $component [optional] Key component (starting with a key collection name)
+        * @return string Colon-delimited list of $keyspace followed by escaped components of $args
+        */
+       public function makeGlobalKey( $class, $component = null );
+
+       /**
+        * Make a cache key, scoped to this instance's keyspace.
+        *
+        * @param string $class Key class
+        * @param string|null $component [optional] Key component (starting with a key collection name)
+        * @return string Colon-delimited list of $keyspace followed by escaped components of $args
+        */
+       public function makeKey( $class, $component = null );
+}
index e832734..7ca04ee 100644 (file)
@@ -208,18 +208,10 @@ class MultiWriteBagOStuff extends BagOStuff {
                return $this->caches[0]->unlock( $key );
        }
 
-       /**
-        * Delete objects expiring before a certain date.
-        *
-        * Succeed if any of the child caches succeed.
-        * @param string $date
-        * @param bool|callable $progressCallback
-        * @return bool
-        */
-       public function deleteObjectsExpiringBefore( $date, $progressCallback = false ) {
+       public function deleteObjectsExpiringBefore( $date, $progressCallback = false, $limit = INF ) {
                $ret = false;
                foreach ( $this->caches as $cache ) {
-                       if ( $cache->deleteObjectsExpiringBefore( $date, $progressCallback ) ) {
+                       if ( $cache->deleteObjectsExpiringBefore( $date, $progressCallback, $limit ) ) {
                                $ret = true;
                        }
                }
index f79c1ff..6fac0ad 100644 (file)
@@ -108,7 +108,7 @@ class ReplicatedBagOStuff extends BagOStuff {
                return $this->writeStore->unlock( $key );
        }
 
-       public function deleteObjectsExpiringBefore( $date, $progressCallback = false ) {
+       public function deleteObjectsExpiringBefore( $date, $progressCallback = false, $limit = INF ) {
                return $this->writeStore->deleteObjectsExpiringBefore( $date, $progressCallback );
        }
 
index 1d8662a..2487920 100644 (file)
@@ -113,7 +113,7 @@ use Psr\Log\NullLogger;
  * @ingroup Cache
  * @since 1.26
  */
-class WANObjectCache implements IExpiringStore, LoggerAwareInterface {
+class WANObjectCache implements IExpiringStore, IStoreKeyEncoder, LoggerAwareInterface {
        /** @var BagOStuff The local datacenter cache */
        protected $cache;
        /** @var MapCacheLRU[] Map of group PHP instance caches */
index c8e31df..2cc2c90 100644 (file)
@@ -5,8 +5,23 @@ namespace Wikimedia\Rdbms;
 use InvalidArgumentException;
 
 /**
- * Helper class to handle automatically marking connections as reusable (via RAII pattern)
- * as well handling deferring the actual network connection until the handle is used
+ * Helper class used for automatically marking an IDatabase connection as reusable (once it no
+ * longer matters which DB domain is selected) and for deferring the actual network connection
+ *
+ * This uses an RAII-style pattern where calling code is expected to keep the returned reference
+ * handle as a function variable that falls out of scope when no longer needed. This avoids the
+ * need for matching reuseConnection() calls for every "return" statement as well as the tedious
+ * use of try/finally.
+ *
+ * @par Example:
+ * @code
+ *     function getRowData() {
+ *         $conn = $this->lb->getConnectedRef( DB_REPLICA );
+ *         $row = $conn->select( ... );
+ *         return $row ? (array)$row : false;
+ *         // $conn falls out of scope and $this->lb->reuseConnection() gets called
+ *     }
+ * @endcode
  *
  * @ingroup Database
  * @since 1.22
@@ -28,7 +43,7 @@ class DBConnRef implements IDatabase {
 
        /**
         * @param ILoadBalancer $lb Connection manager for $conn
-        * @param Database|array $conn Database or (server index, query groups, domain, flags)
+        * @param IDatabase|array $conn Database or (server index, query groups, domain, flags)
         * @param int $role The type of connection asked for; one of DB_MASTER/DB_REPLICA
         * @internal This method should not be called outside of LoadBalancer
         */
@@ -634,15 +649,15 @@ class DBConnRef implements IDatabase {
                return $this->__call( __FUNCTION__, func_get_args() );
        }
 
-       public function commit( $fname = __METHOD__, $flush = '' ) {
+       public function commit( $fname = __METHOD__, $flush = self::FLUSHING_ONE ) {
                return $this->__call( __FUNCTION__, func_get_args() );
        }
 
-       public function rollback( $fname = __METHOD__, $flush = '' ) {
+       public function rollback( $fname = __METHOD__, $flush = self::FLUSHING_ONE ) {
                return $this->__call( __FUNCTION__, func_get_args() );
        }
 
-       public function flushSnapshot( $fname = __METHOD__ ) {
+       public function flushSnapshot( $fname = __METHOD__, $flush = self::FLUSHING_ONE ) {
                return $this->__call( __FUNCTION__, func_get_args() );
        }
 
index 92b9471..e3c15fb 100644 (file)
@@ -270,7 +270,7 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
         */
        final public function initConnection() {
                if ( $this->isOpen() ) {
-                       throw new LogicException( __METHOD__ . ': already connected.' );
+                       throw new LogicException( __METHOD__ . ': already connected' );
                }
                // Establish the connection
                $this->doInitConnection();
@@ -294,7 +294,7 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                                $this->connectionParams['tablePrefix']
                        );
                } else {
-                       throw new InvalidArgumentException( "No database user provided." );
+                       throw new InvalidArgumentException( "No database user provided" );
                }
        }
 
@@ -541,7 +541,7 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
 
        public function dbSchema( $schema = null ) {
                if ( strlen( $schema ) && $this->getDBname() === null ) {
-                       throw new DBUnexpectedError( $this, "Cannot set schema to '$schema'; no database set." );
+                       throw new DBUnexpectedError( $this, "Cannot set schema to '$schema'; no database set" );
                }
 
                $old = $this->currentDomain->getSchema();
@@ -726,7 +726,7 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
 
        public function setFlag( $flag, $remember = self::REMEMBER_NOTHING ) {
                if ( ( $flag & self::DBO_IGNORE ) ) {
-                       throw new UnexpectedValueException( "Modifying DBO_IGNORE is not allowed." );
+                       throw new UnexpectedValueException( "Modifying DBO_IGNORE is not allowed" );
                }
 
                if ( $remember === self::REMEMBER_PRIOR ) {
@@ -737,7 +737,7 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
 
        public function clearFlag( $flag, $remember = self::REMEMBER_NOTHING ) {
                if ( ( $flag & self::DBO_IGNORE ) ) {
-                       throw new UnexpectedValueException( "Modifying DBO_IGNORE is not allowed." );
+                       throw new UnexpectedValueException( "Modifying DBO_IGNORE is not allowed" );
                }
 
                if ( $remember === self::REMEMBER_PRIOR ) {
@@ -875,7 +875,7 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                                        $levels = $this->flatAtomicSectionList();
                                        $exception = new DBUnexpectedError(
                                                $this,
-                                               __METHOD__ . ": atomic sections $levels are still open."
+                                               __METHOD__ . ": atomic sections $levels are still open"
                                        );
                                } elseif ( $this->trxAutomatic ) {
                                        // Only the connection manager can commit non-empty DBO_TRX transactions
@@ -884,7 +884,7 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                                                $exception = new DBUnexpectedError(
                                                        $this,
                                                        __METHOD__ .
-                                                       ": mass commit/rollback of peer transaction required (DBO_TRX set)."
+                                                       ": mass commit/rollback of peer transaction required (DBO_TRX set)"
                                                );
                                        }
                                } else {
@@ -892,14 +892,14 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                                        // back, even if empty.
                                        $exception = new DBUnexpectedError(
                                                $this,
-                                               __METHOD__ . ": transaction is still open (from {$this->trxFname})."
+                                               __METHOD__ . ": transaction is still open (from {$this->trxFname})"
                                        );
                                }
 
                                if ( $this->trxEndCallbacksSuppressed ) {
                                        $exception = $exception ?: new DBUnexpectedError(
                                                $this,
-                                               __METHOD__ . ': callbacks are suppressed; cannot properly commit.'
+                                               __METHOD__ . ': callbacks are suppressed; cannot properly commit'
                                        );
                                }
 
@@ -929,7 +929,7 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                        $fnames = $this->pendingWriteAndCallbackCallers();
                        if ( $fnames ) {
                                throw new RuntimeException(
-                                       "Transaction callbacks are still pending:\n" . implode( ', ', $fnames )
+                                       "Transaction callbacks are still pending: " . implode( ', ', $fnames )
                                );
                        }
                }
@@ -947,7 +947,7 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
         */
        final protected function assertHasConnectionHandle() {
                if ( !$this->isOpen() ) {
-                       throw new DBUnexpectedError( $this, "DB connection was already closed." );
+                       throw new DBUnexpectedError( $this, "DB connection was already closed" );
                }
        }
 
@@ -961,7 +961,7 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                if ( $this->getLBInfo( 'replica' ) === true ) {
                        throw new DBReadOnlyRoleError(
                                $this,
-                               'Write operations are not allowed on replica database connections.'
+                               'Write operations are not allowed on replica database connections'
                        );
                }
                $reason = $this->getReadOnlyReason();
@@ -1401,7 +1401,7 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
        private function assertQueryIsCurrentlyAllowed( $sql, $fname ) {
                $verb = $this->getQueryVerb( $sql );
                if ( $verb === 'USE' ) {
-                       throw new DBUnexpectedError( $this, "Got USE query; use selectDomain() instead." );
+                       throw new DBUnexpectedError( $this, "Got USE query; use selectDomain() instead" );
                }
 
                if ( $verb === 'ROLLBACK' ) { // transaction/savepoint
@@ -1411,7 +1411,7 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                if ( $this->trxStatus < self::STATUS_TRX_OK ) {
                        throw new DBTransactionStateError(
                                $this,
-                               "Cannot execute query from $fname while transaction status is ERROR.",
+                               "Cannot execute query from $fname while transaction status is ERROR",
                                [],
                                $this->trxStatusCause
                        );
@@ -1552,7 +1552,7 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
         */
        public function reportQueryError( $error, $errno, $sql, $fname, $ignore = false ) {
                if ( $ignore ) {
-                       $this->queryLogger->debug( "SQL ERROR (ignored): $error\n" );
+                       $this->queryLogger->debug( "SQL ERROR (ignored): $error" );
                } else {
                        $exception = $this->getQueryExceptionAndLog( $error, $errno, $sql, $fname );
 
@@ -1580,7 +1580,7 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                                'trace' => ( new RuntimeException() )->getTraceAsString()
                        ] )
                );
-               $this->queryLogger->debug( "SQL ERROR: " . $error . "\n" );
+               $this->queryLogger->debug( "SQL ERROR: " . $error . "" );
                if ( $this->wasQueryTimeout( $error, $errno ) ) {
                        $e = new DBQueryTimeoutError( $this, $error, $errno, $sql, $fname );
                } elseif ( $this->wasConnectionError( $errno ) ) {
@@ -1813,7 +1813,7 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                        // functions. Discourage use of such queries to encourage compatibility.
                        call_user_func(
                                $this->deprecationLogger,
-                               __METHOD__ . ": aggregation used with a locking SELECT ($fname)."
+                               __METHOD__ . ": aggregation used with a locking SELECT ($fname)"
                        );
                }
 
@@ -2010,7 +2010,7 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                        } elseif ( count( $var ) == 1 ) {
                                $column = $var[0] ?? reset( $var );
                        } else {
-                               throw new DBUnexpectedError( $this, __METHOD__ . ': got multiple columns.' );
+                               throw new DBUnexpectedError( $this, __METHOD__ . ': got multiple columns' );
                        }
                } else {
                        $column = $var;
@@ -2380,7 +2380,7 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                if ( $name instanceof Subquery ) {
                        throw new DBUnexpectedError(
                                $this,
-                               __METHOD__ . ': got Subquery instance when expecting a string.'
+                               __METHOD__ . ': got Subquery instance when expecting a string'
                        );
                }
 
@@ -2401,7 +2401,7 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                # surrounded by symbols which may be considered word breaks.
                if ( preg_match( '/(^|\s)(DISTINCT|JOIN|ON|AS)(\s|$)/i', $name ) !== 0 ) {
                        $this->queryLogger->warning(
-                               __METHOD__ . ": use of subqueries is not supported this way.",
+                               __METHOD__ . ": use of subqueries is not supported this way",
                                [ 'trace' => ( new RuntimeException() )->getTraceAsString() ]
                        );
 
@@ -2524,12 +2524,12 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                } elseif ( $table instanceof Subquery ) {
                        $quotedTable = (string)$table;
                } else {
-                       throw new InvalidArgumentException( "Table must be a string or Subquery." );
+                       throw new InvalidArgumentException( "Table must be a string or Subquery" );
                }
 
                if ( $alias === false || $alias === $table ) {
                        if ( $table instanceof Subquery ) {
-                               throw new InvalidArgumentException( "Subquery table missing alias." );
+                               throw new InvalidArgumentException( "Subquery table missing alias" );
                        }
 
                        return $quotedTable;
@@ -3162,8 +3162,10 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
 
        public function limitResult( $sql, $limit, $offset = false ) {
                if ( !is_numeric( $limit ) ) {
-                       throw new DBUnexpectedError( $this,
-                               "Invalid non-numeric limit passed to limitResult()\n" );
+                       throw new DBUnexpectedError(
+                               $this,
+                               "Invalid non-numeric limit passed to " . __METHOD__
+                       );
                }
                // This version works in MySQL and SQLite. It will very likely need to be
                // overridden for most other RDBMS subclasses.
@@ -3370,7 +3372,7 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
 
        final public function onTransactionResolution( callable $callback, $fname = __METHOD__ ) {
                if ( !$this->trxLevel() ) {
-                       throw new DBUnexpectedError( $this, "No transaction is active." );
+                       throw new DBUnexpectedError( $this, "No transaction is active" );
                }
                $this->trxEndCallbacks[] = [ $callback, $fname, $this->currentAtomicSectionId() ];
        }
@@ -3416,7 +3418,7 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
 
        final public function onAtomicSectionCancel( callable $callback, $fname = __METHOD__ ) {
                if ( !$this->trxLevel() || !$this->trxAtomicLevels ) {
-                       throw new DBUnexpectedError( $this, "No atomic section is open (got $fname)." );
+                       throw new DBUnexpectedError( $this, "No atomic section is open (got $fname)" );
                }
                $this->trxSectionCancelCallbacks[] = [ $callback, $fname, $this->currentAtomicSectionId() ];
        }
@@ -3552,7 +3554,7 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
         */
        public function runOnTransactionIdleCallbacks( $trigger ) {
                if ( $this->trxLevel() ) { // sanity
-                       throw new DBUnexpectedError( $this, __METHOD__ . ': a transaction is still open.' );
+                       throw new DBUnexpectedError( $this, __METHOD__ . ': a transaction is still open' );
                }
 
                if ( $this->trxEndCallbacksSuppressed ) {
@@ -3809,7 +3811,7 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
 
        final public function endAtomic( $fname = __METHOD__ ) {
                if ( !$this->trxLevel() || !$this->trxAtomicLevels ) {
-                       throw new DBUnexpectedError( $this, "No atomic section is open (got $fname)." );
+                       throw new DBUnexpectedError( $this, "No atomic section is open (got $fname)" );
                }
 
                // Check if the current section matches $fname
@@ -3820,7 +3822,7 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                if ( $savedFname !== $fname ) {
                        throw new DBUnexpectedError(
                                $this,
-                               "Invalid atomic section ended (got $fname but expected $savedFname)."
+                               "Invalid atomic section ended (got $fname but expected $savedFname)"
                        );
                }
 
@@ -3845,7 +3847,7 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                $fname = __METHOD__, AtomicSectionIdentifier $sectionId = null
        ) {
                if ( !$this->trxLevel() || !$this->trxAtomicLevels ) {
-                       throw new DBUnexpectedError( $this, "No atomic section is open (got $fname)." );
+                       throw new DBUnexpectedError( $this, "No atomic section is open (got $fname)" );
                }
 
                $excisedIds = [];
@@ -3887,7 +3889,7 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                        if ( $savedFname !== $fname ) {
                                throw new DBUnexpectedError(
                                        $this,
-                                       "Invalid atomic section ended (got $fname but expected $savedFname)."
+                                       "Invalid atomic section ended (got $fname but expected $savedFname)"
                                );
                        }
 
@@ -3914,7 +3916,7 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                                $this->trxStatus = self::STATUS_TRX_ERROR;
                                $this->trxStatusCause = new DBUnexpectedError(
                                        $this,
-                                       "Uncancelable atomic section canceled (got $fname)."
+                                       "Uncancelable atomic section canceled (got $fname)"
                                );
                        }
                } finally {
@@ -3945,24 +3947,24 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
        final public function begin( $fname = __METHOD__, $mode = self::TRANSACTION_EXPLICIT ) {
                static $modes = [ self::TRANSACTION_EXPLICIT, self::TRANSACTION_INTERNAL ];
                if ( !in_array( $mode, $modes, true ) ) {
-                       throw new DBUnexpectedError( $this, "$fname: invalid mode parameter '$mode'." );
+                       throw new DBUnexpectedError( $this, "$fname: invalid mode parameter '$mode'" );
                }
 
                // Protect against mismatched atomic section, transaction nesting, and snapshot loss
                if ( $this->trxLevel() ) {
                        if ( $this->trxAtomicLevels ) {
                                $levels = $this->flatAtomicSectionList();
-                               $msg = "$fname: Got explicit BEGIN while atomic section(s) $levels are open.";
+                               $msg = "$fname: Got explicit BEGIN while atomic section(s) $levels are open";
                                throw new DBUnexpectedError( $this, $msg );
                        } elseif ( !$this->trxAutomatic ) {
-                               $msg = "$fname: Explicit transaction already active (from {$this->trxFname}).";
+                               $msg = "$fname: Explicit transaction already active (from {$this->trxFname})";
                                throw new DBUnexpectedError( $this, $msg );
                        } else {
-                               $msg = "$fname: Implicit transaction already active (from {$this->trxFname}).";
+                               $msg = "$fname: Implicit transaction already active (from {$this->trxFname})";
                                throw new DBUnexpectedError( $this, $msg );
                        }
                } elseif ( $this->getFlag( self::DBO_TRX ) && $mode !== self::TRANSACTION_INTERNAL ) {
-                       $msg = "$fname: Implicit transaction expected (DBO_TRX set).";
+                       $msg = "$fname: Implicit transaction expected (DBO_TRX set)";
                        throw new DBUnexpectedError( $this, $msg );
                }
 
@@ -4008,7 +4010,7 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
        final public function commit( $fname = __METHOD__, $flush = self::FLUSHING_ONE ) {
                static $modes = [ self::FLUSHING_ONE, self::FLUSHING_ALL_PEERS, self::FLUSHING_INTERNAL ];
                if ( !in_array( $flush, $modes, true ) ) {
-                       throw new DBUnexpectedError( $this, "$fname: invalid flush parameter '$flush'." );
+                       throw new DBUnexpectedError( $this, "$fname: invalid flush parameter '$flush'" );
                }
 
                if ( $this->trxLevel() && $this->trxAtomicLevels ) {
@@ -4016,7 +4018,7 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                        $levels = $this->flatAtomicSectionList();
                        throw new DBUnexpectedError(
                                $this,
-                               "$fname: Got COMMIT while atomic sections $levels are still open."
+                               "$fname: Got COMMIT while atomic sections $levels are still open"
                        );
                }
 
@@ -4026,17 +4028,17 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                        } elseif ( !$this->trxAutomatic ) {
                                throw new DBUnexpectedError(
                                        $this,
-                                       "$fname: Flushing an explicit transaction, getting out of sync."
+                                       "$fname: Flushing an explicit transaction, getting out of sync"
                                );
                        }
                } elseif ( !$this->trxLevel() ) {
                        $this->queryLogger->error(
-                               "$fname: No transaction to commit, something got out of sync." );
+                               "$fname: No transaction to commit, something got out of sync" );
                        return; // nothing to do
                } elseif ( $this->trxAutomatic ) {
                        throw new DBUnexpectedError(
                                $this,
-                               "$fname: Expected mass commit of all peer transactions (DBO_TRX set)."
+                               "$fname: Expected mass commit of all peer transactions (DBO_TRX set)"
                        );
                }
 
@@ -4089,7 +4091,7 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                ) {
                        throw new DBUnexpectedError(
                                $this,
-                               "$fname: Expected mass rollback of all peer transactions (DBO_TRX set)."
+                               "$fname: Expected mass rollback of all peer transactions (DBO_TRX set)"
                        );
                }
 
@@ -4151,13 +4153,32 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                }
        }
 
-       public function flushSnapshot( $fname = __METHOD__ ) {
-               if ( $this->writesOrCallbacksPending() || $this->explicitTrxActive() ) {
+       public function flushSnapshot( $fname = __METHOD__, $flush = self::FLUSHING_ONE ) {
+               if ( $this->explicitTrxActive() ) {
+                       // Committing this transaction would break callers that assume it is still open
+                       throw new DBUnexpectedError(
+                               $this,
+                               "$fname: Cannot flush snapshot; " .
+                               "explicit transaction '{$this->trxFname}' is still open"
+                       );
+               } elseif ( $this->writesOrCallbacksPending() ) {
                        // This only flushes transactions to clear snapshots, not to write data
                        $fnames = implode( ', ', $this->pendingWriteAndCallbackCallers() );
                        throw new DBUnexpectedError(
                                $this,
-                               "$fname: Cannot flush snapshot because writes are pending ($fnames)."
+                               "$fname: Cannot flush snapshot; " .
+                               "writes from transaction {$this->trxFname} are still pending ($fnames)"
+                       );
+               } elseif (
+                       $this->trxLevel() &&
+                       $this->getTransactionRoundId() &&
+                       $flush !== self::FLUSHING_INTERNAL &&
+                       $flush !== self::FLUSHING_ALL_PEERS
+               ) {
+                       $this->queryLogger->warning(
+                               "$fname: Expected mass snapshot flush of all peer transactions " .
+                               "in the explicit transactions round '{$this->getTransactionRoundId()}'",
+                               [ 'trace' => ( new RuntimeException() )->getTraceAsString() ]
                        );
                }
 
@@ -4413,7 +4434,7 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                Wikimedia\restoreWarnings();
 
                if ( $fp === false ) {
-                       throw new RuntimeException( "Could not open \"{$filename}\".\n" );
+                       throw new RuntimeException( "Could not open \"{$filename}\"" );
                }
 
                if ( !$fname ) {
@@ -4630,7 +4651,8 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                        $fnames = implode( ', ', $this->pendingWriteAndCallbackCallers() );
                        throw new DBUnexpectedError(
                                $this,
-                               "$fname: Cannot flush pre-lock snapshot because writes are pending ($fnames)."
+                               "$fname: Cannot flush pre-lock snapshot; " .
+                               "writes from transaction {$this->trxFname} are still pending ($fnames)"
                        );
                }
 
@@ -4669,7 +4691,7 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
 
        final public function lockTables( array $read, array $write, $method ) {
                if ( $this->writesOrCallbacksPending() ) {
-                       throw new DBUnexpectedError( $this, "Transaction writes or callbacks still pending." );
+                       throw new DBUnexpectedError( $this, "Transaction writes or callbacks still pending" );
                }
 
                if ( $this->tableLocksHaveTransactionScope() ) {
@@ -4794,7 +4816,7 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                if ( !$this->conn ) {
                        throw new DBUnexpectedError(
                                $this,
-                               'DB connection was already closed or the connection dropped.'
+                               'DB connection was already closed or the connection dropped'
                        );
                }
 
@@ -4827,8 +4849,8 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
         */
        public function __clone() {
                $this->connLogger->warning(
-                       "Cloning " . static::class . " is not recommended; forking connection:\n" .
-                       ( new RuntimeException() )->getTraceAsString()
+                       "Cloning " . static::class . " is not recommended; forking connection",
+                       [ 'trace' => ( new RuntimeException() )->getTraceAsString() ]
                );
 
                if ( $this->isOpen() ) {
@@ -4856,7 +4878,7 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
         */
        public function __sleep() {
                throw new RuntimeException( 'Database serialization may cause problems, since ' .
-                       'the connection is not restored on wakeup.' );
+                       'the connection is not restored on wakeup' );
        }
 
        /**
@@ -4864,13 +4886,13 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
         */
        public function __destruct() {
                if ( $this->trxLevel() && $this->trxDoneWrites ) {
-                       trigger_error( "Uncommitted DB writes (transaction from {$this->trxFname})." );
+                       trigger_error( "Uncommitted DB writes (transaction from {$this->trxFname})" );
                }
 
                $danglingWriters = $this->pendingWriteAndCallbackCallers();
                if ( $danglingWriters ) {
                        $fnames = implode( ', ', $danglingWriters );
-                       trigger_error( "DB transaction writes or callbacks still pending ($fnames)." );
+                       trigger_error( "DB transaction writes or callbacks still pending ($fnames)" );
                }
 
                if ( $this->conn ) {
index ad6d4d2..3b9d1af 100644 (file)
@@ -1944,7 +1944,7 @@ interface IDatabase {
         *
         * @throws DBError
         */
-       public function commit( $fname = __METHOD__, $flush = '' );
+       public function commit( $fname = __METHOD__, $flush = self::FLUSHING_ONE );
 
        /**
         * Rollback a transaction previously started using begin().
@@ -1966,7 +1966,7 @@ interface IDatabase {
         * @throws DBError
         * @since 1.23 Added $flush parameter
         */
-       public function rollback( $fname = __METHOD__, $flush = '' );
+       public function rollback( $fname = __METHOD__, $flush = self::FLUSHING_ONE );
 
        /**
         * Commit any transaction but error out if writes or callbacks are pending
@@ -1977,10 +1977,20 @@ interface IDatabase {
         * useful to call on a replica DB after waiting on replication to catch up to the master.
         *
         * @param string $fname Calling function name
+        * @param string $flush Flush flag, set to situationally valid IDatabase::FLUSHING_*
+        *   constant to disable warnings about explicitly committing implicit transactions,
+        *   or calling commit when no transaction is in progress.
+        *
+        *   This will trigger an exception if there is an ongoing explicit transaction.
+        *
+        *   Only set the flush flag if you are sure that these warnings are not applicable,
+        *   and no explicit transactions are open.
+        *
         * @throws DBError
         * @since 1.28
+        * @since 1.34 Added $flush parameter
         */
-       public function flushSnapshot( $fname = __METHOD__ );
+       public function flushSnapshot( $fname = __METHOD__, $flush = self::FLUSHING_ONE );
 
        /**
         * Convert a timestamp in one of the formats accepted by wfTimestamp()
index 35c9539..812064a 100644 (file)
@@ -180,6 +180,8 @@ interface ILBFactory {
        /**
         * Commit all replica DB transactions so as to flush any REPEATABLE-READ or SSI snapshot
         *
+        * This is useful for getting rid of stale data from an implicit transaction round
+        *
         * @param string $fname Caller name
         */
        public function flushReplicaSnapshots( $fname = __METHOD__ );
index e20f6de..d94d24d 100644 (file)
@@ -234,6 +234,12 @@ abstract class LBFactory implements ILBFactory {
        }
 
        public function flushReplicaSnapshots( $fname = __METHOD__ ) {
+               if ( $this->trxRoundId !== false && $this->trxRoundId !== $fname ) {
+                       $this->queryLogger->warning(
+                               "$fname: transaction round '{$this->trxRoundId}' still running",
+                               [ 'trace' => ( new RuntimeException() )->getTraceAsString() ]
+                       );
+               }
                $this->forEachLBCallMethod( 'flushReplicaSnapshots', [ $fname ] );
        }
 
@@ -249,7 +255,7 @@ abstract class LBFactory implements ILBFactory {
                if ( $this->trxRoundId !== false ) {
                        throw new DBTransactionError(
                                null,
-                               "$fname: transaction round '{$this->trxRoundId}' already started."
+                               "$fname: transaction round '{$this->trxRoundId}' already started"
                        );
                }
                $this->trxRoundId = $fname;
@@ -264,7 +270,7 @@ abstract class LBFactory implements ILBFactory {
                if ( $this->trxRoundId !== false && $this->trxRoundId !== $fname ) {
                        throw new DBTransactionError(
                                null,
-                               "$fname: transaction round '{$this->trxRoundId}' still running."
+                               "$fname: transaction round '{$this->trxRoundId}' still running"
                        );
                }
                /** @noinspection PhpUnusedLocalVariableInspection */
@@ -456,8 +462,10 @@ abstract class LBFactory implements ILBFactory {
 
        public function getEmptyTransactionTicket( $fname ) {
                if ( $this->hasMasterChanges() ) {
-                       $this->queryLogger->error( __METHOD__ . ": $fname does not have outer scope.\n" .
-                               ( new RuntimeException() )->getTraceAsString() );
+                       $this->queryLogger->error(
+                               __METHOD__ . ": $fname does not have outer scope",
+                               [ 'trace' => ( new RuntimeException() )->getTraceAsString() ]
+                       );
 
                        return null;
                }
@@ -467,8 +475,10 @@ abstract class LBFactory implements ILBFactory {
 
        final public function commitAndWaitForReplication( $fname, $ticket, array $opts = [] ) {
                if ( $ticket !== $this->ticket ) {
-                       $this->perfLogger->error( __METHOD__ . ": $fname does not have outer scope.\n" .
-                               ( new RuntimeException() )->getTraceAsString() );
+                       $this->perfLogger->error(
+                               __METHOD__ . ": $fname does not have outer scope",
+                               [ 'trace' => ( new RuntimeException() )->getTraceAsString() ]
+                       );
 
                        return false;
                }
@@ -476,7 +486,7 @@ abstract class LBFactory implements ILBFactory {
                // The transaction owner and any caller with the empty transaction ticket can commit
                // so that getEmptyTransactionTicket() callers don't risk seeing DBTransactionError.
                if ( $this->trxRoundId !== false && $fname !== $this->trxRoundId ) {
-                       $this->queryLogger->info( "$fname: committing on behalf of {$this->trxRoundId}." );
+                       $this->queryLogger->info( "$fname: committing on behalf of {$this->trxRoundId}" );
                        $fnameEffective = $this->trxRoundId;
                } else {
                        $fnameEffective = $fname;
@@ -530,11 +540,13 @@ abstract class LBFactory implements ILBFactory {
                } elseif ( $this->memStash instanceof EmptyBagOStuff ) {
                        // No where to store any DB positions and wait for them to appear
                        $this->chronProt->setEnabled( false );
-                       $this->replLogger->info( 'Cannot use ChronologyProtector with EmptyBagOStuff.' );
+                       $this->replLogger->info( 'Cannot use ChronologyProtector with EmptyBagOStuff' );
                }
 
-               $this->replLogger->debug( __METHOD__ . ': using request info ' .
-                       json_encode( $this->requestInfo, JSON_PRETTY_PRINT ) );
+               $this->replLogger->debug(
+                       __METHOD__ . ': request info ' .
+                       json_encode( $this->requestInfo, JSON_PRETTY_PRINT )
+               );
 
                return $this->chronProt;
        }
@@ -726,7 +738,7 @@ abstract class LBFactory implements ILBFactory {
 
        public function setRequestInfo( array $info ) {
                if ( $this->chronProt ) {
-                       throw new LogicException( 'ChronologyProtector already initialized.' );
+                       throw new LogicException( 'ChronologyProtector already initialized' );
                }
 
                $this->requestInfo = $info + $this->requestInfo;
index b086beb..8b4ace6 100644 (file)
@@ -23,6 +23,7 @@
 namespace Wikimedia\Rdbms;
 
 use Exception;
+use LogicException;
 use InvalidArgumentException;
 
 /**
@@ -85,6 +86,8 @@ interface ILoadBalancer {
 
        /** @var string Domain specifier when no specific database needs to be selected */
        const DOMAIN_ANY = '';
+       /** @var bool The generic query group (bool gives b/c with 1.33 method signatures) */
+       const GROUP_GENERIC = false;
 
        /** @var int DB handle should have DBO_TRX disabled and the caller will leave it as such */
        const CONN_TRX_AUTOCOMMIT = 1;
@@ -100,25 +103,26 @@ interface ILoadBalancer {
         * Construct a manager of IDatabase connection objects
         *
         * @param array $params Parameter map with keys:
-        *  - servers : Required. Array of server info structures.
-        *  - localDomain: A DatabaseDomain or domain ID string.
-        *  - loadMonitor : Name of a class used to fetch server lag and load.
+        *  - servers : List of server info structures
+        *  - localDomain: A DatabaseDomain or domain ID string
+        *  - loadMonitor : Name of a class used to fetch server lag and load
         *  - readOnlyReason : Reason the master DB is read-only if so [optional]
         *  - waitTimeout : Maximum time to wait for replicas for consistency [optional]
         *  - maxLag: Try to avoid DB replicas with lag above this many seconds [optional]
         *  - srvCache : BagOStuff object for server cache [optional]
         *  - wanCache : WANObjectCache object [optional]
         *  - chronologyCallback: Callback to run before the first connection attempt [optional]
+        *  - defaultGroup: Default query group; the generic group if not specified [optional]
         *  - hostname : The name of the current server [optional]
-        *  - cliMode: Whether the execution context is a CLI script. [optional]
-        *  - profiler : Class name or instance with profileIn()/profileOut() methods. [optional]
-        *  - trxProfiler: TransactionProfiler instance. [optional]
-        *  - replLogger: PSR-3 logger instance. [optional]
-        *  - connLogger: PSR-3 logger instance. [optional]
-        *  - queryLogger: PSR-3 logger instance. [optional]
-        *  - perfLogger: PSR-3 logger instance. [optional]
-        *  - errorLogger : Callback that takes an Exception and logs it. [optional]
-        *  - deprecationLogger: Callback to log a deprecation warning. [optional]
+        *  - cliMode: Whether the execution context is a CLI script [optional]
+        *  - profiler : Class name or instance with profileIn()/profileOut() methods [optional]
+        *  - trxProfiler: TransactionProfiler instance [optional]
+        *  - replLogger: PSR-3 logger instance [optional]
+        *  - connLogger: PSR-3 logger instance [optional]
+        *  - queryLogger: PSR-3 logger instance [optional]
+        *  - perfLogger: PSR-3 logger instance [optional]
+        *  - errorLogger : Callback that takes an Exception and logs it [optional]
+        *  - deprecationLogger: Callback to log a deprecation warning [optional]
         *  - roundStage: STAGE_POSTCOMMIT_* class constant; for internal use [optional]
         *  - ownerId: integer ID of an LBFactory instance that manages this instance [optional]
         * @throws InvalidArgumentException
@@ -159,9 +163,9 @@ interface ILoadBalancer {
         * Subsequent calls with the same $group will not need to make new connection attempts
         * since the acquired connection for each group is preserved.
         *
-        * @param string|bool $group Query group, or false for the generic group
-        * @param string|bool $domain Domain ID, or false for the current domain
-        * @throws DBError
+        * @param string|bool $group Query group or false for the generic group
+        * @param string|bool $domain DB domain ID or false for the local domain
+        * @throws DBError If no live handle can be obtained
         * @return bool|int|string
         */
        public function getReaderIndex( $group = false, $domain = false );
@@ -204,7 +208,8 @@ interface ILoadBalancer {
         * Get any open connection to a given server index, local or foreign
         *
         * Use CONN_TRX_AUTOCOMMIT to only look for connections opened with that flag.
-        * Avoid the use of begin() or startAtomic() on any such connections.
+        * Avoid the use of transaction methods like IDatabase::begin() or IDatabase::startAtomic()
+        * on any such connections.
         *
         * @param int $i Server index or DB_MASTER/DB_REPLICA
         * @param int $flags Bitfield of CONN_* class constants
@@ -213,95 +218,136 @@ interface ILoadBalancer {
        public function getAnyOpenConnection( $i, $flags = 0 );
 
        /**
-        * Get a connection handle by server index
-        *
-        * The CONN_TRX_AUTOCOMMIT flag is ignored for databases with ATTR_DB_LEVEL_LOCKING
-        * (e.g. sqlite) in order to avoid deadlocks. ILoadBalancer::getServerAttributes()
-        * can be used to check such flags beforehand.
-        *
-        * If the caller uses $domain or sets CONN_TRX_AUTOCOMMIT in $flags, then it must
-        * also call ILoadBalancer::reuseConnection() on the handle when finished using it.
-        * In all other cases, this is not necessary, though not harmful either.
-        * Avoid the use of begin() or startAtomic() on any such connections.
+        * Get a live handle for a real or virtual (DB_MASTER/DB_REPLICA) server index
+        *
+        * The server index, $i, can be one of the following:
+        *   - DB_REPLICA: a server index will be selected by the load balancer based on read
+        *      weight, connectivity, and replication lag. Note that the master server might be
+        *      configured with read weight. If $groups is empty then it means "the generic group",
+        *      in which case all servers defined with read weight will be considered. Additional
+        *      query groups can be configured, having their own list of server indexes and read
+        *      weights. If a query group list is provided in $groups, then each recognized group
+        *      will be tried, left-to-right, until server index selection succeeds or all groups
+        *      have been tried, in which case the generic group will be tried.
+        *   - DB_MASTER: the master server index will be used; the same as getWriterIndex().
+        *      The value of $groups should be [] when using this server index.
+        *   - Specific server index: a positive integer can be provided to use the server with
+        *      that index. An error will be thrown in no such server index is recognized. This
+        *      server selection method is usually only useful for internal load balancing logic.
+        *      The value of $groups should be [] when using a specific server index.
+        *
+        * Handles acquired by this method, getConnectionRef(), getLazyConnectionRef(), and
+        * getMaintenanceConnectionRef() use the same set of shared connection pools. Callers that
+        * get a *local* DB domain handle for the same server will share one handle for all of those
+        * callers using CONN_TRX_AUTOCOMMIT (via $flags) and one handle for all of those callers not
+        * using CONN_TRX_AUTOCOMMIT. Callers that get a *foreign* DB domain handle (via $domain) will
+        * share any handle that has the right CONN_TRX_AUTOCOMMIT mode and is already on the right
+        * DB domain. Otherwise, one of the "free for reuse" handles will be claimed or a new handle
+        * will be made if there are none.
+        *
+        * Handle sharing is particularly useful when callers get local DB domain (the default),
+        * transaction round aware (the default), DB_MASTER handles. All such callers will operate
+        * within a single database transaction as a consequence. Handle sharing is also useful when
+        * callers get local DB domain (the default), transaction round aware (the default), samely
+        * query grouped (the default), DB_REPLICA handles. All such callers will operate within a
+        * single database transaction as a consequence.
+        *
+        * Calling functions that use $domain must call reuseConnection() once the last query of the
+        * function is executed. This lets the load balancer share this handle with other callers
+        * requesting connections on different database domains.
+        *
+        * Use CONN_TRX_AUTOCOMMIT to use a separate pool of only auto-commit handles. This flag
+        * is ignored for databases with ATTR_DB_LEVEL_LOCKING (e.g. sqlite) in order to avoid
+        * deadlocks. getServerAttributes() can be used to check such attributes beforehand. Avoid
+        * using IDatabase::begin() and IDatabase::commit() on such handles. If it is not possible
+        * to avoid using methods like IDatabase::startAtomic() and IDatabase::endAtomic(), callers
+        * should at least make sure that the atomic sections are closed on failure via try/catch
+        * and IDatabase::cancelAtomic().
+        *
+        * @see ILoadBalancer::reuseConnection()
+        * @see ILoadBalancer::getServerAttributes()
         *
         * @param int $i Server index (overrides $groups) or DB_MASTER/DB_REPLICA
-        * @param array|string|bool $groups Query group(s), or false for the generic reader
-        * @param string|bool $domain Domain ID, or false for the current domain
+        * @param string[]|string $groups Query group(s) or [] to use the default group
+        * @param string|bool $domain DB domain ID or false for the local domain
         * @param int $flags Bitfield of CONN_* class constants
-        *
-        * @note This method throws DBAccessError if ILoadBalancer::disable() was called
-        *
-        * @throws DBError If any error occurs that prevents the yielding of a (live) IDatabase
-        * @return IDatabase|bool This returns false on failure if CONN_SILENCE_ERRORS is set
+        * @return IDatabase|bool Live connection handle or false on failure
+        * @throws DBError If no live handle can be obtained and CONN_SILENCE_ERRORS is not set
+        * @throws DBAccessError If disable() was previously called
         */
        public function getConnection( $i, $groups = [], $domain = false, $flags = 0 );
 
        /**
-        * Mark a foreign connection as being available for reuse under a different DB domain
+        * Mark a live handle as being available for reuse under a different database domain
+        *
+        * This mechanism is reference-counted, and must be called the same number of times as
+        * getConnection() to work. Never call this on handles acquired via getConnectionRef(),
+        * getLazyConnectionRef(), and getMaintenanceConnectionRef(), as they already manage
+        * the logic of calling this method when they fall out of scope in PHP.
         *
-        * This mechanism is reference-counted, and must be called the same number of times
-        * as getConnection() to work.
+        * @see ILoadBalancer::getConnection()
         *
         * @param IDatabase $conn
-        * @throws InvalidArgumentException
+        * @throws LogicException
         */
        public function reuseConnection( IDatabase $conn );
 
        /**
-        * Get a database connection handle reference
-        *
-        * The handle's methods simply wrap those of a Database handle
+        * Get a live database handle reference for a real or virtual (DB_MASTER/DB_REPLICA) server index
         *
         * The CONN_TRX_AUTOCOMMIT flag is ignored for databases with ATTR_DB_LEVEL_LOCKING
-        * (e.g. sqlite) in order to avoid deadlocks. ILoadBalancer::getServerAttributes()
+        * (e.g. sqlite) in order to avoid deadlocks. getServerAttributes()
         * can be used to check such flags beforehand. Avoid the use of begin() or startAtomic()
         * on any CONN_TRX_AUTOCOMMIT connections.
         *
         * @see ILoadBalancer::getConnection() for parameter information
         *
         * @param int $i Server index or DB_MASTER/DB_REPLICA
-        * @param array|string|bool $groups Query group(s), or false for the generic reader
-        * @param string|bool $domain Domain ID, or false for the current domain
+        * @param string[]|string $groups Query group(s) or [] to use the default group
+        * @param string|bool $domain DB domain ID or false for the local domain
         * @param int $flags Bitfield of CONN_* class constants (e.g. CONN_TRX_AUTOCOMMIT)
         * @return DBConnRef
         */
        public function getConnectionRef( $i, $groups = [], $domain = false, $flags = 0 );
 
        /**
-        * Get a database connection handle reference without connecting yet
+        * Get a database handle reference for a real or virtual (DB_MASTER/DB_REPLICA) server index
         *
-        * The handle's methods simply wrap those of a Database handle
+        * The handle's methods simply proxy to those of an underlying IDatabase handle which
+        * takes care of the actual connection and query logic.
         *
         * The CONN_TRX_AUTOCOMMIT flag is ignored for databases with ATTR_DB_LEVEL_LOCKING
-        * (e.g. sqlite) in order to avoid deadlocks. ILoadBalancer::getServerAttributes()
+        * (e.g. sqlite) in order to avoid deadlocks. getServerAttributes()
         * can be used to check such flags beforehand. Avoid the use of begin() or startAtomic()
         * on any CONN_TRX_AUTOCOMMIT connections.
         *
         * @see ILoadBalancer::getConnection() for parameter information
         *
         * @param int $i Server index or DB_MASTER/DB_REPLICA
-        * @param array|string|bool $groups Query group(s), or false for the generic reader
-        * @param string|bool $domain Domain ID, or false for the current domain
+        * @param string[]|string $groups Query group(s) or [] to use the default group
+        * @param string|bool $domain DB domain ID or false for the local domain
         * @param int $flags Bitfield of CONN_* class constants (e.g. CONN_TRX_AUTOCOMMIT)
         * @return DBConnRef
         */
        public function getLazyConnectionRef( $i, $groups = [], $domain = false, $flags = 0 );
 
        /**
-        * Get a maintenance database connection handle reference for migrations and schema changes
+        * Get a live database handle for a real or virtual (DB_MASTER/DB_REPLICA) server index
+        * that can be used for data migrations and schema changes
         *
-        * The handle's methods simply wrap those of a Database handle
+        * The handle's methods simply proxy to those of an underlying IDatabase handle which
+        * takes care of the actual connection and query logic.
         *
         * The CONN_TRX_AUTOCOMMIT flag is ignored for databases with ATTR_DB_LEVEL_LOCKING
-        * (e.g. sqlite) in order to avoid deadlocks. ILoadBalancer::getServerAttributes()
+        * (e.g. sqlite) in order to avoid deadlocks. getServerAttributes()
         * can be used to check such flags beforehand. Avoid the use of begin() or startAtomic()
         * on any CONN_TRX_AUTOCOMMIT connections.
         *
         * @see ILoadBalancer::getConnection() for parameter information
         *
         * @param int $i Server index or DB_MASTER/DB_REPLICA
-        * @param array|string|bool $groups Query group(s), or false for the generic reader
-        * @param string|bool $domain Domain ID, or false for the current domain
+        * @param string[]|string $groups Query group(s) or [] to use the default group
+        * @param string|bool $domain DB domain ID or false for the local domain
         * @param int $flags Bitfield of CONN_* class constants (e.g. CONN_TRX_AUTOCOMMIT)
         * @return MaintainableDBConnRef
         */
@@ -362,7 +408,7 @@ interface ILoadBalancer {
        public function getServerName( $i );
 
        /**
-        * Return the server info structure for a given index, or false if the index is invalid.
+        * Return the server info structure for a given index or false if the index is invalid.
         * @param int $i
         * @return array|bool
         * @since 1.31
@@ -544,7 +590,7 @@ interface ILoadBalancer {
 
        /**
         * @note This method will trigger a DB connection if not yet done
-        * @param string|bool $domain Domain ID, or false for the current domain
+        * @param string|bool $domain DB domain ID or false for the local domain
         * @return bool Whether the database for generic connections this request is highly "lagged"
         */
        public function getLaggedReplicaMode( $domain = false );
@@ -561,7 +607,7 @@ interface ILoadBalancer {
 
        /**
         * @note This method may trigger a DB connection if not yet done
-        * @param string|bool $domain Domain ID, or false for the current domain
+        * @param string|bool $domain DB domain ID or false for the local domain
         * @param IDatabase|null $conn DB master connection; used to avoid loops [optional]
         * @return string|bool Reason the master is read-only or false if it is not
         */
@@ -607,7 +653,7 @@ interface ILoadBalancer {
         * May attempt to open connections to replica DBs on the default DB. If there is
         * no lag, the maximum lag will be reported as -1.
         *
-        * @param bool|string $domain Domain ID, or false for the default database
+        * @param bool|string $domain Domain ID or false for the default database
         * @return array ( host, max lag, index of max lagged host )
         */
        public function getMaxLag( $domain = false );
@@ -627,7 +673,9 @@ interface ILoadBalancer {
        /**
         * Wait for a replica DB to reach a specified master position
         *
-        * This will connect to the master to get an accurate position if $pos is not given
+        * If $conn is not a replica server connection, then this will return true.
+        * Otherwise, if $pos is not provided, this will connect to the master server
+        * to get an accurate position.
         *
         * @param IDatabase $conn Replica DB
         * @param DBMasterPos|bool $pos Master position; default: current position
index 44d526c..c1d7a0f 100644 (file)
@@ -28,6 +28,7 @@ use BagOStuff;
 use EmptyBagOStuff;
 use WANObjectCache;
 use ArrayUtils;
+use LogicException;
 use UnexpectedValueException;
 use InvalidArgumentException;
 use RuntimeException;
@@ -84,8 +85,10 @@ class LoadBalancer implements ILoadBalancer {
        private $loadMonitorConfig;
        /** @var string Alternate local DB domain instead of DatabaseDomain::getId() */
        private $localDomainIdAlias;
-       /** @var int */
+       /** @var int Amount of replication lag, in seconds, that is considered "high" */
        private $maxLag;
+       /** @var string|bool The query group list to be used by default */
+       private $defaultGroup;
 
        /** @var string Current server name */
        private $hostname;
@@ -101,11 +104,11 @@ class LoadBalancer implements ILoadBalancer {
        /** @var array[] Map of (name => callable) */
        private $trxRecurringCallbacks = [];
 
-       /** @var Database DB connection object that caused a problem */
+       /** @var Database Connection handle that caused a problem */
        private $errorConnection;
-       /** @var int The generic (not query grouped) replica DB index */
+       /** @var int The generic (not query grouped) replica server index */
        private $genericReadIndex = -1;
-       /** @var int[] The group replica DB indexes keyed by group */
+       /** @var int[] The group replica server indexes keyed by group */
        private $readIndexByGroup = [];
        /** @var bool|DBMasterPos Replication sync position or false if not set */
        private $waitForPos;
@@ -113,9 +116,9 @@ class LoadBalancer implements ILoadBalancer {
        private $laggedReplicaMode = false;
        /** @var bool Whether the generic reader fell back to a lagged replica DB */
        private $allReplicasDownMode = false;
-       /** @var string The last DB selection or connection error */
+       /** @var string The last DB domain selection or connection error */
        private $lastError = 'Unknown error';
-       /** @var string|bool Reason the LB is read-only or false if not */
+       /** @var string|bool Reason this instance is read-only or false if not */
        private $readOnlyReason = false;
        /** @var int Total number of new connections ever made with this instance */
        private $connectionCounter = 0;
@@ -124,16 +127,13 @@ class LoadBalancer implements ILoadBalancer {
        /** @var bool Whether any connection has been attempted yet */
        private $connectionAttempted = false;
 
-       /** @var int|null An integer ID of the managing LBFactory instance or null */
+       /** @var int|null Integer ID of the managing LBFactory instance or null if none */
        private $ownerId;
-       /** @var string|bool String if a requested DBO_TRX transaction round is active */
+       /** @var string|bool Explicit DBO_TRX transaction round active or false if none */
        private $trxRoundId = false;
        /** @var string Stage of the current transaction round in the transaction round life-cycle */
        private $trxRoundStage = self::ROUND_CURSORY;
 
-       /** @var string|null */
-       private $defaultGroup = null;
-
        /** @var int Warn when this many connection are held */
        const CONN_HELD_WARN_THRESHOLD = 10;
 
@@ -244,7 +244,7 @@ class LoadBalancer implements ILoadBalancer {
                        }
                }
 
-               $this->defaultGroup = $params['defaultGroup'] ?? null;
+               $this->defaultGroup = $params['defaultGroup'] ?? self::GROUP_GENERIC;
                $this->ownerId = $params['ownerId'] ?? null;
        }
 
@@ -274,6 +274,30 @@ class LoadBalancer implements ILoadBalancer {
                return (string)$domain;
        }
 
+       /**
+        * @param string[]|string|bool $groups Query group list or false for the default
+        * @param int $i Specific server index or DB_MASTER/DB_REPLICA
+        * @return string[]|bool[] Query group list
+        */
+       private function resolveGroups( $groups, $i ) {
+               if ( $groups === false ) {
+                       $resolvedGroups = [ $this->defaultGroup ];
+               } elseif ( is_string( $groups ) ) {
+                       $resolvedGroups = [ $groups ];
+               } elseif ( is_array( $groups ) ) {
+                       $resolvedGroups = $groups ?: [ $this->defaultGroup ];
+               } else {
+                       throw new InvalidArgumentException( "Invalid query groups provided" );
+               }
+
+               if ( $groups && $i > 0 ) {
+                       $groupList = implode( ', ', $groups );
+                       throw new LogicException( "Got query groups ($groupList) with a server index (#$i)" );
+               }
+
+               return $resolvedGroups;
+       }
+
        /**
         * @param int $flags
         * @return bool
@@ -399,43 +423,42 @@ class LoadBalancer implements ILoadBalancer {
        }
 
        /**
-        * @param int $i
-        * @param array $groups
+        * Get the server index to use for a specified server index and query group list
+        *
+        * @param int $i Specific server index or DB_MASTER/DB_REPLICA
+        * @param string[]|bool[] $groups Resolved query group list (non-empty)
         * @param string|bool $domain
-        * @return int The index of a specific server (replica DBs are checked for connectivity)
+        * @return int A specific server index (replica DBs are checked for connectivity)
         */
-       private function getConnectionIndex( $i, $groups, $domain ) {
-               // Check one "group" per default: the generic pool
-               $defaultGroups = $this->defaultGroup ? [ $this->defaultGroup ] : [ false ];
-
-               $groups = ( $groups === false || $groups === [] )
-                       ? $defaultGroups
-                       : (array)$groups;
-
+       private function getConnectionIndex( $i, array $groups, $domain ) {
                if ( $i === self::DB_MASTER ) {
                        $i = $this->getWriterIndex();
                } elseif ( $i === self::DB_REPLICA ) {
-                       # Try to find an available server in any the query groups (in order)
+                       // Find an available server in any of the query groups (in order)
                        foreach ( $groups as $group ) {
                                $groupIndex = $this->getReaderIndex( $group, $domain );
                                if ( $groupIndex !== false ) {
-                                       $i = $groupIndex;
+                                       $i = $groupIndex; // group connection succeeded
                                        break;
                                }
                        }
+               } elseif ( !isset( $this->servers[$i] ) ) {
+                       throw new UnexpectedValueException( "Invalid server index index #$i" );
                }
 
-               # Operation-based index
                if ( $i === self::DB_REPLICA ) {
-                       $this->lastError = 'Unknown error'; // reset error string
-                       # Try the general server pool if $groups are unavailable.
-                       $i = ( $groups === [ false ] )
-                               ? false // don't bother with this if that is what was tried above
-                               : $this->getReaderIndex( false, $domain );
-                       # Couldn't find a working server in getReaderIndex()?
+                       // No specific server was yet found
+                       $this->lastError = 'Unknown error'; // set here in case of worse failure
+                       // Either make one last connection attempt or give up
+                       $i = in_array( $this->defaultGroup, $groups, true )
+                               // Connection attempt already included the default query group; give up
+                               ? false
+                               // Connection attempt was for other query groups; try the default one
+                               : $this->getReaderIndex( $this->defaultGroup, $domain );
+
                        if ( $i === false ) {
+                               // Still coundn't find a working non-zero read load server
                                $this->lastError = 'No working replica DB server: ' . $this->lastError;
-                               // Throw an exception
                                $this->reportConnectionError();
                                return null; // unreachable due to exception
                        }
@@ -456,7 +479,7 @@ class LoadBalancer implements ILoadBalancer {
                        return $index;
                }
 
-               if ( $group !== false ) {
+               if ( $group !== self::GROUP_GENERIC ) {
                        // Use the server weight array for this load group
                        if ( isset( $this->groupLoads[$group] ) ) {
                                $loads = $this->groupLoads[$group];
@@ -492,7 +515,7 @@ class LoadBalancer implements ILoadBalancer {
                // Cache the reader index for future DB_REPLICA handles
                $this->setExistingReaderIndex( $group, $i );
                // Record whether the generic reader index is in "lagged replica DB" mode
-               if ( $group === false && $laggedReplicaMode ) {
+               if ( $group === self::GROUP_GENERIC && $laggedReplicaMode ) {
                        $this->laggedReplicaMode = true;
                }
 
@@ -509,7 +532,7 @@ class LoadBalancer implements ILoadBalancer {
         * @return int Server index or -1 if none was chosen
         */
        protected function getExistingReaderIndex( $group ) {
-               if ( $group === false ) {
+               if ( $group === self::GROUP_GENERIC ) {
                        $index = $this->genericReadIndex;
                } else {
                        $index = $this->readIndexByGroup[$group] ?? -1;
@@ -529,7 +552,7 @@ class LoadBalancer implements ILoadBalancer {
                        throw new UnexpectedValueException( "Cannot set a negative read server index" );
                }
 
-               if ( $group === false ) {
+               if ( $group === self::GROUP_GENERIC ) {
                        $this->genericReadIndex = $index;
                } else {
                        $this->readIndexByGroup[$group] = $index;
@@ -704,7 +727,9 @@ class LoadBalancer implements ILoadBalancer {
                $i = ( $i === self::DB_MASTER ) ? $this->getWriterIndex() : $i;
                $autocommit = ( ( $flags & self::CONN_TRX_AUTOCOMMIT ) == self::CONN_TRX_AUTOCOMMIT );
 
+               $conn = false;
                foreach ( $this->conns as $connsByServer ) {
+                       // Get the connection array server indexes to inspect
                        if ( $i === self::DB_REPLICA ) {
                                $indexes = array_keys( $connsByServer );
                        } else {
@@ -712,18 +737,47 @@ class LoadBalancer implements ILoadBalancer {
                        }
 
                        foreach ( $indexes as $index ) {
-                               foreach ( $connsByServer[$index] as $conn ) {
-                                       if ( !$conn->isOpen() ) {
-                                               continue; // some sort of error occured?
-                                       }
-                                       if ( !$autocommit || $conn->getLBInfo( 'autoCommitOnly' ) ) {
-                                               return $conn;
-                                       }
+                               $conn = $this->pickAnyOpenConnection( $connsByServer[$index], $autocommit );
+                               if ( $conn ) {
+                                       break;
                                }
                        }
                }
 
-               return false;
+               if ( $conn ) {
+                       $this->enforceConnectionFlags( $conn, $flags );
+               }
+
+               return $conn;
+       }
+
+       /**
+        * @param IDatabase[] $candidateConns
+        * @param bool $autocommit Whether to only look for auto-commit connections
+        * @return IDatabase|false An appropriate open connection or false if none found
+        */
+       private function pickAnyOpenConnection( $candidateConns, $autocommit ) {
+               $conn = false;
+
+               foreach ( $candidateConns as $candidateConn ) {
+                       if ( !$candidateConn->isOpen() ) {
+                               continue; // some sort of error occured?
+                       } elseif (
+                               $autocommit &&
+                               (
+                                       // Connection is transaction round aware
+                                       !$candidateConn->getLBInfo( 'autoCommitOnly' ) ||
+                                       // Some sort of error left a transaction open?
+                                       $candidateConn->trxLevel()
+                               )
+                       ) {
+                               continue; // some sort of error left a transaction open?
+                       }
+
+                       $conn = $candidateConn;
+               }
+
+               return $conn;
        }
 
        /**
@@ -823,12 +877,7 @@ class LoadBalancer implements ILoadBalancer {
        }
 
        public function getConnection( $i, $groups = [], $domain = false, $flags = 0 ) {
-               if ( !is_int( $i ) ) {
-                       throw new InvalidArgumentException( "Cannot connect without a server index" );
-               } elseif ( $groups && $i > 0 ) {
-                       throw new InvalidArgumentException( "Got query groups with server index #$i" );
-               }
-
+               $groups = $this->resolveGroups( $groups, $i );
                $domain = $this->resolveDomainID( $domain );
                $flags = $this->sanitizeConnectionFlags( $flags );
                $masterOnly = ( $i === self::DB_MASTER || $i === $this->getWriterIndex() );
@@ -896,7 +945,7 @@ class LoadBalancer implements ILoadBalancer {
                        // Database instance to this method. Any caller passing in a DBConnRef is broken.
                        $this->connLogger->error(
                                __METHOD__ . ": got DBConnRef instance.\n" .
-                               ( new RuntimeException() )->getTraceAsString() );
+                               ( new LogicException() )->getTraceAsString() );
 
                        return;
                }
@@ -1154,14 +1203,9 @@ class LoadBalancer implements ILoadBalancer {
         * Test if the specified index represents an open connection
         *
         * @param int $index Server index
-        * @private
         * @return bool
         */
        private function isOpen( $index ) {
-               if ( !is_int( $index ) ) {
-                       return false;
-               }
-
                return (bool)$this->getAnyOpenConnection( $index );
        }
 
index 39d0353..2ef94c4 100644 (file)
@@ -46,7 +46,9 @@ class SqlBagOStuff extends BagOStuff {
        /** @var int */
        protected $lastExpireAll = 0;
        /** @var int */
-       protected $purgePeriod = 100;
+       protected $purgePeriod = 10;
+       /** @var int */
+       protected $purgeLimit = 100;
        /** @var int */
        protected $shards = 1;
        /** @var string */
@@ -77,12 +79,13 @@ class SqlBagOStuff extends BagOStuff {
         *                  when a cluster is replicated to another site (with different host names)
         *                  but each server has a corresponding replica in the other cluster.
         *
-        *   - purgePeriod: The average number of object cache requests in between
+        *   - purgePeriod: The average number of object cache writes in between
         *                  garbage collection operations, where expired entries
         *                  are removed from the database. Or in other words, the
         *                  reciprocal of the probability of purging on any given
-        *                  request. If this is set to zero, purging will never be
-        *                  done.
+        *                  write. If this is set to zero, purging will never be done.
+        *
+        *   - purgeLimit:  Maximum number of rows to purge at once.
         *
         *   - tableName:   The table name to use, default is "objectcache".
         *
@@ -135,6 +138,9 @@ class SqlBagOStuff extends BagOStuff {
                if ( isset( $params['purgePeriod'] ) ) {
                        $this->purgePeriod = intval( $params['purgePeriod'] );
                }
+               if ( isset( $params['purgeLimit'] ) ) {
+                       $this->purgeLimit = intval( $params['purgeLimit'] );
+               }
                if ( isset( $params['tableName'] ) ) {
                        $this->tableName = $params['tableName'];
                }
@@ -270,8 +276,6 @@ class SqlBagOStuff extends BagOStuff {
                        $keysByTable[$serverIndex][$tableName][] = $key;
                }
 
-               $this->garbageCollect(); // expire old entries if any
-
                $dataRows = [];
                foreach ( $keysByTable as $serverIndex => $serverKeys ) {
                        try {
@@ -617,7 +621,7 @@ class SqlBagOStuff extends BagOStuff {
                        // Disabled
                        return;
                }
-               // Only purge on one in every $this->purgePeriod requests.
+               // Only purge on one in every $this->purgePeriod writes
                if ( $this->purgePeriod !== 1 && mt_rand( 0, $this->purgePeriod - 1 ) ) {
                        return;
                }
@@ -625,7 +629,11 @@ class SqlBagOStuff extends BagOStuff {
                // Avoid repeating the delete within a few seconds
                if ( $now > ( $this->lastExpireAll + 1 ) ) {
                        $this->lastExpireAll = $now;
-                       $this->expireAll();
+                       $this->deleteObjectsExpiringBefore(
+                               wfTimestamp( TS_MW, $now ),
+                               false,
+                               $this->purgeLimit
+                       );
                }
        }
 
@@ -633,15 +641,15 @@ class SqlBagOStuff extends BagOStuff {
                $this->deleteObjectsExpiringBefore( wfTimestampNow() );
        }
 
-       /**
-        * Delete objects from the database which expire before a certain date.
-        * @param string $timestamp
-        * @param bool|callable $progressCallback
-        * @return bool
-        */
-       public function deleteObjectsExpiringBefore( $timestamp, $progressCallback = false ) {
+       public function deleteObjectsExpiringBefore(
+               $timestamp,
+               $progressCallback = false,
+               $limit = INF
+       ) {
                /** @noinspection PhpUnusedLocalVariableInspection */
                $silenceScope = $this->silenceTransactionProfiler();
+
+               $count = 0;
                for ( $serverIndex = 0; $serverIndex < $this->numServers; $serverIndex++ ) {
                        $db = null;
                        try {
@@ -661,7 +669,8 @@ class SqlBagOStuff extends BagOStuff {
                                                        [ 'keyname', 'exptime' ],
                                                        $conds,
                                                        __METHOD__,
-                                                       [ 'LIMIT' => 100, 'ORDER BY' => 'exptime' ] );
+                                                       [ 'LIMIT' => 100, 'ORDER BY' => 'exptime' ]
+                                               );
                                                if ( $rows === false || !$rows->numRows() ) {
                                                        break;
                                                }
@@ -684,9 +693,14 @@ class SqlBagOStuff extends BagOStuff {
                                                                'exptime < ' . $db->addQuotes( $dbTimestamp ),
                                                                'keyname' => $keys
                                                        ],
-                                                       __METHOD__ );
+                                                       __METHOD__
+                                               );
+                                               $count += $db->affectedRows();
+                                               if ( $count >= $limit ) {
+                                                       return true;
+                                               }
 
-                                               if ( $progressCallback ) {
+                                               if ( is_callable( $progressCallback ) ) {
                                                        if ( intval( $totalSeconds ) === 0 ) {
                                                                $percent = 0;
                                                        } else {
@@ -710,6 +724,7 @@ class SqlBagOStuff extends BagOStuff {
                                return false;
                        }
                }
+
                return true;
        }
 
index 12cfe83..16b83d1 100644 (file)
@@ -29,7 +29,7 @@ use Wikimedia\Rdbms\ResultWrapper;
  * @ingroup Media
  */
 class ImagePage extends Article {
-       /** @var File */
+       /** @var File|false */
        private $displayImg;
 
        /** @var FileRepo */
@@ -801,7 +801,7 @@ EOT
        }
 
        /**
-        * @param string $target
+        * @param string|string[] $target
         * @param int $limit
         * @return ResultWrapper
         */
index 013dd75..acd506b 100644 (file)
@@ -29,13 +29,13 @@ use Wikimedia\Rdbms\FakeResultWrapper;
  * @ingroup Media
  */
 class WikiFilePage extends WikiPage {
-       /** @var File */
+       /** @var File|false */
        protected $mFile = false;
-       /** @var LocalRepo */
+       /** @var LocalRepo|null */
        protected $mRepo = null;
        /** @var bool */
        protected $mFileLoaded = false;
-       /** @var array */
+       /** @var array|null */
        protected $mDupes = null;
 
        public function __construct( $title ) {
index 74d0616..457648a 100644 (file)
@@ -1,7 +1,5 @@
 <?php
 /**
- * Message blobs storage used by ResourceLoader.
- *
  * 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
@@ -20,7 +18,6 @@
  * @file
  * @author Roan Kattouw
  * @author Trevor Parscal
- * @author Timo Tijhof
  */
 
 use MediaWiki\MediaWikiServices;
index f718e5f..7a7ab89 100644 (file)
@@ -1,7 +1,5 @@
 <?php
 /**
- * ResourceLoader module for populating language specific data.
- *
  * 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
@@ -19,7 +17,6 @@
  *
  * @file
  * @author Santhosh Thottingal
- * @author Timo Tijhof
  */
 
 /**
index 2dd6c17..0f33666 100644 (file)
@@ -1,7 +1,5 @@
 <?php
 /**
- * ResourceLoader module for skin stylesheets.
- *
  * 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
  * http://www.gnu.org/copyleft/gpl.html
  *
  * @file
- * @author Timo Tijhof
  */
 
+/**
+ * ResourceLoader module for skin stylesheets.
+ */
 class ResourceLoaderSkinModule extends ResourceLoaderFileModule {
        /**
         * All skins are assumed to be compatible with mobile
index b2403ce..bb6a6b3 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 
-use Wikimedia\Rdbms\LoadBalancer;
+use Wikimedia\Rdbms\ILoadBalancer;
 
 /**
  * Represents the site configuration of a wiki.
@@ -38,7 +38,7 @@ class DBSiteStore implements SiteStore {
        protected $sites = null;
 
        /**
-        * @var LoadBalancer
+        * @var ILoadBalancer
         */
        private $dbLoadBalancer;
 
@@ -48,9 +48,9 @@ class DBSiteStore implements SiteStore {
         * @todo inject some kind of connection manager that is aware of the target wiki,
         * instead of injecting a LoadBalancer.
         *
-        * @param LoadBalancer $dbLoadBalancer
+        * @param ILoadBalancer $dbLoadBalancer
         */
-       public function __construct( LoadBalancer $dbLoadBalancer ) {
+       public function __construct( ILoadBalancer $dbLoadBalancer ) {
                $this->dbLoadBalancer = $dbLoadBalancer;
        }
 
index c7e2a37..31c277a 100644 (file)
@@ -56,6 +56,7 @@ class SpecialUnblock extends SpecialPage {
 
                $this->setHeaders();
                $this->outputHeader();
+               $this->addHelpLink( 'Help:Blocking users' );
 
                $out = $this->getOutput();
                $out->setPageTitle( $this->msg( 'unblockip' ) );
index 05c622a..95563d2 100644 (file)
@@ -187,7 +187,7 @@ class SpecialUndelete extends SpecialPage {
                if ( $this->mTimestamp !== '' ) {
                        $this->showRevision( $this->mTimestamp );
                } elseif ( $this->mFilename !== null && $this->mTargetObj->inNamespace( NS_FILE ) ) {
-                       $file = new ArchivedFile( $this->mTargetObj, '', $this->mFilename );
+                       $file = new ArchivedFile( $this->mTargetObj, 0, $this->mFilename );
                        // Check if user is allowed to see this file
                        if ( !$file->exists() ) {
                                $out->addWikiMsg( 'filedelete-nofile', $this->mFilename );
@@ -651,7 +651,7 @@ class SpecialUndelete extends SpecialPage {
                $out = $this->getOutput();
                $lang = $this->getLanguage();
                $user = $this->getUser();
-               $file = new ArchivedFile( $this->mTargetObj, '', $this->mFilename );
+               $file = new ArchivedFile( $this->mTargetObj, 0, $this->mFilename );
                $out->addWikiMsg( 'undelete-show-file-confirm',
                        $this->mTargetObj->getText(),
                        $lang->userDate( $file->getTimestamp(), $user ),
index b134bfe..f6ad623 100644 (file)
@@ -4,7 +4,7 @@ use MediaWiki\Linker\LinkTarget;
 use MediaWiki\User\UserIdentity;
 use Wikimedia\Assert\Assert;
 use Wikimedia\Rdbms\IDatabase;
-use Wikimedia\Rdbms\LoadBalancer;
+use Wikimedia\Rdbms\ILoadBalancer;
 
 /**
  * Class performing complex database queries related to WatchedItems.
@@ -53,7 +53,7 @@ class WatchedItemQueryService {
        const SORT_DESC = 'DESC';
 
        /**
-        * @var LoadBalancer
+        * @var ILoadBalancer
         */
        private $loadBalancer;
 
@@ -70,7 +70,7 @@ class WatchedItemQueryService {
        private $watchedItemStore;
 
        public function __construct(
-               LoadBalancer $loadBalancer,
+               ILoadBalancer $loadBalancer,
                CommentStore $commentStore,
                ActorMigration $actorMigration,
                WatchedItemStoreInterface $watchedItemStore
index d7d5eec..8a1d2a7 100644 (file)
@@ -295,7 +295,7 @@ class Names {
                'mh' => 'Ebon', # Marshallese
                'mhr' => 'олык марий', # Eastern Mari
                'mi' => 'Māori', # Maori
-               'min' => 'Baso Minangkabau', # Minangkabau
+               'min' => 'Minangkabau', # Minangkabau
                'mk' => 'македонски', # Macedonian
                'ml' => 'മലയാളം', # Malayalam
                'mn' => 'монгол', # Halh Mongolian (Cyrillic) (ISO 639-3: khk)
index 2d2d3f1..adead9a 100644 (file)
        "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": "يُرجَى تحديد تفضيلات كتم الصوت لـ{{BIDI:[[User:$1]]}}.",
index bf8f203..0ce63b5 100644 (file)
@@ -11,7 +11,9 @@
                        "아라",
                        "Carma citrawati",
                        "Joseagush",
-                       "Wandering ant"
+                       "Wandering ant",
+                       "Kadek Ayu Sulastri",
+                       "Luh Gede Krismayanti"
                ]
        },
        "tog-underline": "Garis ring beten pranala:",
        "and": "&#32;miwah",
        "faq": "FAQ (pitaken sane jagi katakonang)",
        "actions": "Parilaksana",
-       "namespaces": "Genah peséngan",
+       "namespaces": "Genah wastan",
        "variants": "Varian",
        "navigation-heading": "Menu navigasi",
        "errorpagetitle": "Kaiwangan",
        "view-foreign": "Cingak ring $1",
        "edit": "Uah",
        "create": "Karyanin",
+       "create-local": "Icénin daging sané marupa paparan lokal",
        "delete": "Usap",
        "viewdeleted_short": "Cingak {{PLURAL:$1|siki uahan sané kausapin|$1 uahan sané kausapin}}",
        "protect": "Saib",
        "aboutsite": "Indik {{SITENAME}}",
        "aboutpage": "Project:Indik",
        "copyrightpage": "{{ns:project}}:hak cipta",
-       "currentevents": "kawentenane mangkin",
-       "currentevents-url": "Project:kawentenane mangkin",
+       "currentevents": "Kawéntenané mangkin",
+       "currentevents-url": "Project:Kawéntenané mangkin",
        "disclaimers": "Tulak",
        "disclaimerpage": "Project:Tulak lumrah",
        "edithelp": "Wantuan indik nguah",
        "nstab-user": "Kaca sang anganggé",
        "nstab-special": "Kaca kusus",
        "nstab-project": "Kaca proyék",
-       "nstab-image": "Berkas",
+       "nstab-image": "Depukan",
        "nstab-template": "Cétakan",
        "nstab-help": "Kaca wantuan",
        "nstab-category": "Kategori",
        "userlogin-yourpassword-ph": "Dagingin kruna sandi jero",
        "createacct-yourpassword-ph": "Dagingin kruna sandi",
        "yourpasswordagain": "jumunin kruna sandi",
+       "createacct-yourpasswordagain": "Mastiang kruna kunci",
        "createacct-yourpasswordagain-ph": "Dagingin malih kruna sandi",
+       "userlogin-remembermypassword": "Banggayang mangda tetep ngranjing",
        "cannotlogin-title": "Nénten prasida manjing log",
        "cannotloginnow-title": "Mangkin nénten prasida manjing log",
        "login": "Manjing log",
        "userlogin-joinproject": "Nyarengin {{SITENAME}}",
        "createaccount": "Karyanin akun",
        "userlogin-helplink2": "Wantuan indik manjing log",
+       "createacct-emailoptional": "Alamat email (becikang kadagingin)",
        "createacct-email-ph": "Dagingin alamat email jero",
        "createacct-submit": "Karyanin akun jero",
        "createacct-benefit-heading": "{{SITENAME}} kakaryanin olih anak sakadi jero.",
        "loginlanguagelabel": "Basa: $1",
        "pt-login": "Manjing log",
        "pt-login-button": "Manjing log",
-       "pt-createaccount": "Karyanin akun",
+       "pt-createaccount": "Ngaryanin akun",
        "pt-userlogout": "Medal log",
        "botpasswords-label-create": "Ngae",
        "botpasswords-label-cancel": "Buungan",
        "nowiki_sample": "lebuang teks sane nenten jagi keformat ring driki",
        "nowiki_tip": "campahang format wiki",
        "image_tip": "cantumin pupulan",
-       "media_tip": "pranala pupulan-pupulan",
+       "media_tip": "Pranala depukan",
        "sig_tip": "tanda tangan ida dane sareng tanda waktu",
        "hr_tip": "garis horizontal",
        "summary": "Ringkesan:",
        "noarticletext-nopermission": "mangkin nenten wenten teks ring lembar puniki. ida dane prasida [[Special:Search/{{PAGENAME}}|ngarereh murda anggen lembar puniki]] ring lembar-lembar sane lianan, <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} ngarereh log sane mapaiketan], utawi [{{fullurl:{{FULLPAGENAME}}|action=edit}} ngubah lembar puniki]</span>.",
        "userpage-userdoesnotexist-view": "Akun sang anganggé \"$1\" nénten madaptar.",
        "previewnote": "\"elingang yening puniki wantah sane lintang.\" Panguwahan ida dane durung kasimpen!",
+       "continue-editing": "Magingsir ka genah ngauwah",
        "editing": "Nguahin $1",
        "creating": "Makarya $1",
        "editingsection": "Nguahin $1 (pahan)",
        "lineno": "Carik $1:",
        "compareselectedversions": "bandingang penguwahan sane kapilih",
        "editundo": "nguliang",
+       "diff-empty": "(Nénten wénten sané malianan)",
        "searchresults": "asil pangrereh",
        "searchresults-title": "asil pangrereh anggen \"$1\"",
        "prevn": "{{PLURAL:$1|$1}} sadurungnyané",
        "searchprofile-everything": "Samian",
        "searchprofile-advanced": "lanturane",
        "searchprofile-articles-tooltip": "Rereh ring $1",
-       "searchprofile-images-tooltip": "Rereh berkas",
+       "searchprofile-images-tooltip": "Rereh depukan",
        "searchprofile-everything-tooltip": "pangrereh ring samian isi (taler lembar wecana)",
-       "searchprofile-advanced-tooltip": "pangrereh ring genah pesengan sane kasinahang",
+       "searchprofile-advanced-tooltip": "Rereh ring genah wastan sané kapilih",
        "search-result-size": "$1 ({{PLURAL:$2|1 kruna|$2 kruna}})",
        "search-result-category-size": "{{PLURAL:$1|1 krama|$1 krama}}({{PLURAL:$2|1  subgolongan|$2 subgolongan}}, {{PLURAL:$3|1 pupulan|$3 pupulan}})",
        "search-redirect": "(gingsiran saking $1)",
        "search-section": "(pahan $1)",
+       "search-file-match": "(anut ring daging depukan)",
        "search-suggest": "minab sane kearsaang $1",
        "searchrelated": "paiketan",
        "searchall": "samian",
+       "search-showingresults": "{{PLURAL:$4|Asil <strong>$1</strong> of <strong>$3</strong>|Asil-asil <strong>$1 – $2</strong> saking <strong>$3</strong>}}",
        "search-nonefound": "nenten wenten asil sane caklek ring arsa",
+       "powersearch-ns": "Rereh ring genah wastan:",
        "mypreferences": "Preferensi",
        "prefs-user-pages": "Kaca sang anganggé",
        "saveprefs": "Raksa",
        "prefs-editing": "Nguahin",
+       "prefs-namespaces": "Genah wastan",
        "youremail": "E-mail",
        "yourrealname": "pesengan sujati",
        "gender-male": "Dané nguahin kaca wiki",
        "recentchanges": "Uahan sané mangkin",
        "recentchanges-legend": "Opsi uahan sané mangkin",
        "recentchanges-summary": "Track uahan sané mangkin ring wikiné indik kaca puniki.",
+       "recentchanges-noresult": "Nénten wénten uahan ring galahnyané puniki sané anut sareng praciri puniki.",
        "recentchanges-feed-description": "molihang pagentosan anyar ring wiki ring \"umpan\" puniki",
        "recentchanges-label-newpage": "Uahan puniki makarya kaca anyar",
        "recentchanges-label-minor": "Punika uahan alit",
        "recentchanges-label-bot": "penguwahan puniki kalaksanayang antuk bot",
        "recentchanges-label-unpatrolled": "Uahan puniki durung kapatroli",
+       "recentchanges-legend-heading": "<strong>Legenda:</strong>",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (taler cingak [[Special:NewPages|bacakan kaca anyar]])",
        "recentchanges-submit": "Sinahang",
        "rcfilters-activefilters-show": "Sinahang",
        "recentchangeslinked-summary": "lembar kautamayang puniki ngicenin kepahan penguwahan kaping untat ring lembar-lembar sana mapaiket. Lembar sane [[Special:Watchlist|ida dane iwasin]] mapinget antuk sesuratan tebel",
        "recentchangeslinked-page": "Peséngan kaca:",
        "recentchangeslinked-to": "Sinahang uahan saking kaca-kaca sané linked kaca puniki",
-       "upload": "Unggahang berkas",
+       "upload": "Unggahang depukan",
        "uploadlogpage": "Log unggahan",
        "filedesc": "Ringkesan",
        "savefile": "Raksa berkas",
        "license": "kepahan lugra",
        "license-header": "kepahan lugra",
        "listfiles-delete": "usap",
-       "imgfile": "pupulan",
-       "listfiles": "Bacakan berkas",
-       "file-anchor-link": "pupulan",
+       "imgfile": "depukan",
+       "listfiles": "Bacakan depukan",
+       "file-anchor-link": "Depukan",
        "filehist": "Babad berkas",
        "filehist-help": "klik ring pinanggal/galah anggen nyingakin pupulan niki rikala punika",
        "filehist-deleteall": "usap samian",
        "filehist-user": "Sang anganggé",
        "filehist-dimensions": "ukuran",
        "filehist-comment": "tureksa",
-       "imagelinks": "Panganggén berkas",
-       "linkstoimage": "nyarengin {{PLURAL:$1|pranala|$1pranala}} ring pupulan puniki",
+       "imagelinks": "Panganggén depukan",
+       "linkstoimage": "{{PLURAL:$1|Kaca|$1 kaca}} ring sor puniki nganggén depukan puniki:",
        "nolinkstoimage": "Nénten wénten kaca sané nganggén berkas puniki.",
-       "sharedupload-desc-here": "pupulan puniki mawit saking $1 lan minab kaanggen olih proyek-proyek sane lianan. Deskripsi saking [$2 lebar deskripsinyane] kaarahin ring ungkur puniki",
+       "sharedupload-desc-here": "Depukan puniki mawit saking $1 lan minab kaanggén olih proyék-proyék sané lianan. Déskripsinnyané ring [$2 kaca déskripsi depukannyané] kaarahin ring ungkur puniki.",
+       "filepage-nofile": "Nentén wénten berkas sané mamurda sakadi punika",
        "shared-repo-name-wikimediacommons": "Wikimedia Commons",
-       "upload-disallowed-here": "Jero nénten dados numpuk berkas puniki.",
+       "upload-disallowed-here": "Jero nénten dados numpuk depukan puniki.",
        "filedelete": "Usap $1",
        "filedelete-submit": "Usap",
        "filedelete-success": "<strong>$1</strong> sampun kausapin.",
        "move": "Gingsirang",
        "pager-newer-n": "{{PLURAL:$1|1 lewih anyar|$1 lewih anyar}}",
        "pager-older-n": "{{PLURAL:$1|1 lewih suwe|$1 lewih anyar}}",
+       "apisandbox-multivalue-all-namespaces": "$1 (Genah wastan makasami)",
        "booksources": "Wit buku",
        "booksources-search-legend": "Rereh wit buku",
        "booksources-search": "Rereh",
        "all-logs-page": "Makasami log publik",
        "allpages": "Makasami kaca",
        "allarticles": "Makasami kaca",
+       "allinnamespace": "Makasami kaca (genah wastan $1)",
        "allpagessubmit": "lanturang",
+       "allpages-bad-ns": "{{SITENAME}} nénten madué genah wastan \"$1\".",
+       "allpages-hide-redirects": "Ngengkebang pagingsirian",
        "categories": "Golongan",
        "categories-submit": "Sinahang",
        "deletedcontributions": "Pituut sang anganggé sané kausapin",
+       "linksearch-ns": "Genah wastan:",
        "linksearch-line": "$1 masambung saking $2",
        "listusers-submit": "Sinahang",
        "listgrouprights-members": "kepahan krama",
        "watchlist-submit": "Sinahang",
        "wlshowhideminor": "uahan alit",
        "watchlist-options": "milih kepahan peninjo",
+       "enotif_reset": "Cihnayang makasami kaca sané sampun karauhin",
        "enotif_subject_deleted": "Kaca {{SITENAME}} $1 sampun {{GENDER:$2|kausap}} $2",
        "enotif_body_intro_deleted": "Kaca{{SITENAME}} $1 sampun {{GENDER:$2|kausapin}} ring $PAGEEDITDATE olih $2, cingak $3.",
        "deletepage": "Usap kaca",
        "undeletelink": "cingak/uliang",
        "undeleteviewlink": "cingak",
        "undelete-search-title": "Rereh kaca sané kausapin",
-       "namespace": "Genah pesengan",
+       "namespace": "Genah wastan:",
        "invert": "uliang pilihan",
        "tooltip-invert": "Centang kotak puniki mangdané ngengkebang lembar sané kauwah ring genah wastan sané kapilih (miwah genah wastan sané mapaiketan yéning kacentang)",
+       "namespace_association": "Genah wasta sané mapaiketan",
+       "tooltip-namespace_association": "Céntang kotak puniki anggén nagingin genah wasta pabligbagan utawi subjék sané mapaiketan sareng genah wasta sané kapilih",
        "blanknamespace": "(Utama)",
        "contributions": "Pituut {{GENDER:$1|sang anganggé}}",
        "contributions-title": "Pituut sang anganggé $1",
        "whatlinkshere-hideredirs": "$1 pangalihan",
        "whatlinkshere-hidetrans": "$1 transklusi",
        "whatlinkshere-hidelinks": "$1 pranala",
-       "whatlinkshere-hideimages": "$1 pranala pupulan",
+       "whatlinkshere-hideimages": "$1 pranala berkas",
        "whatlinkshere-filters": "Panyaring",
        "ipboptions": "2 jam:2 hours,1 dina:1 day,3 dina:3 days,1 minggu:1 week,2 minggu:2 weeks,1 sasih:1 month,3 sasih:3 months,6 sasih:6 months,1 taun:1 year,tanpa wates:infinite",
        "ipb-pages-label": "Kaca",
+       "ipb-namespaces-label": "Genah wastan",
        "block-prevent-edit": "Nguahin",
        "ipblocklist": "ngempetin sane nganggo",
+       "infiniteblock": "Nénten kawates",
        "blocklist-nousertalk": "tan prasida nguahin kaca pabligbagan praragan",
        "blocklist-editing-page": "kaca",
+       "blocklist-editing-ns": "genah wastan",
        "blocklink": "ngempetin",
        "unblocklink": "ngicalang kaempetan",
        "change-blocklink": "gentosin empetin",
        "tooltip-feed-atom": "\"atom feed\" anggen lembar puniki",
        "tooltip-t-contributions": "Bacakan pituut olih {{GENDER:$1|sang anganggé puniki}}",
        "tooltip-t-emailuser": "Ngirim surel majeng ring {{GENDER:$1|penganggo puniki}}",
-       "tooltip-t-upload": "ngunggahang file",
+       "tooltip-t-upload": "Unggahang depukan",
        "tooltip-t-specialpages": "Bacakan makasami kaca kusus",
        "tooltip-t-print": "Vérsi cétak kaca puniki",
        "tooltip-t-permalink": "Pranala ajeg kaanggen ngubah lembar puniki",
        "tooltip-ca-nstab-user": "Cingak kaca sang anganggé",
        "tooltip-ca-nstab-special": "puniki lembar sane pinih utama sane nenten prasida kauwah",
        "tooltip-ca-nstab-project": "Cingak kaca proyek",
-       "tooltip-ca-nstab-image": "Cingak kaca berkas",
+       "tooltip-ca-nstab-image": "Cingak kaca depukannyané",
        "tooltip-ca-nstab-template": "Cingak citakan",
        "tooltip-ca-nstab-help": "Cingak kaca wantuan",
        "tooltip-ca-nstab-category": "Cingak kaca kategori",
        "pageinfo-header-edits": "Babad uahan",
        "pageinfo-header-restrictions": "Saiban kaca",
        "pageinfo-display-title": "Edengang judul",
+       "pageinfo-namespace": "Genah wastan",
        "pageinfo-article-id": "ID kaca",
+       "pageinfo-language": "Basa ring daging kaca",
+       "pageinfo-content-model": "Modél antuk daging kaca",
        "pageinfo-robot-index": "Kalugra",
        "pageinfo-robot-noindex": "Tan kalugra",
+       "pageinfo-watchers": "Akéh nomér sané negdeg kaca",
+       "pageinfo-redirects-name": "Akéh nomer sané magingsir ka kaca puniki",
+       "pageinfo-subpages-name": "Kapahan kaca saking kaca puniki",
        "pageinfo-firstuser": "Sang makarya kaca",
+       "pageinfo-firsttime": "Galah ritatkala ngripta kaca",
+       "pageinfo-lastuser": "Panguwah sané pinih anyar",
+       "pageinfo-lasttime": "Galah antuk uwahan sané pinih anyar",
+       "pageinfo-edits": "Akéh nomer sané kauwah",
+       "pageinfo-authors": "Akéh nomer makasami antuk panyurat sané lianan",
+       "pageinfo-recent-edits": "Akéh nomer sané kauwah (ring $1 sané sampun lintang)",
+       "pageinfo-recent-authors": "Akéh nomer antuk panyurat sané lianan",
        "pageinfo-toolboxlink": "Pidarta kaca",
+       "pageinfo-contentpage": "Kapeték dados kaca daging",
        "pageinfo-contentpage-yes": "Inggih",
        "previousdiff": "← Uahan sadurungnyané",
        "nextdiff": "Uahan sané pinih anyar →",
        "widthheightpage": "$1 × $2, $3 {{PLURAL:$3|kaca}}",
-       "file-info-size": "$1x$2 piksel, ukuran pupulan: $3, tipe MIME:$4",
+       "file-info-size": "$1x$2 piksel, ukuran depukan: $3, tipe MIME:$4",
        "file-nohires": "tan kasayagaang ukuran sane lewih ageng",
        "svg-long-desc": "pupulan SVG, nominal $1 × $2 piksel, geden pupulan: $3",
-       "show-big-image": "pupulan sujati",
+       "show-big-image": "Depukan sujati",
        "show-big-image-preview": "agengnyané pratuduh:$1",
        "show-big-image-other": "{{PLURAL:$2|Resolusi}} iianan: $1.",
        "show-big-image-size": "$1 × $2 piksel",
        "namespacesall": "samian",
        "monthsall": "samian",
        "imgmultipagenext": "kaca salanturnyané →",
+       "imgmultigo": "Ngrereh",
        "imgmultigoto": "Nuju kaca $1",
        "table_pager_next": "Kaca salanturnyané",
        "table_pager_prev": "Kaca sadurungnyané",
+       "watchlisttools-clear": "Ngicalang pupulan sané sampun karauhin",
        "watchlisttools-view": "Cingak uahan sane relevan",
        "watchlisttools-edit": "Cingak miwah uah bacakan pantauan",
        "watchlisttools-raw": "Uah kepahan paninjo mentah",
        "signature": "[[{{ns:user}}:$1|$2]] ([[{{ns:user_talk}}:$1|pabligbagan]])",
        "duplicate-defaultsort": "pingetan: sereg pangurutan lingga \"$2\" nyampahang sereg pangurutan lingga sadurunge \"$1\"",
        "version-specialpages": "Kaca kusus",
+       "redirect-submit": "Nglanturang",
        "redirect-lookup": "Rereh:",
        "redirect-value": "Aji:",
        "redirect-user": "ID sang anganggé",
        "redirect-page": "ID kaca",
        "redirect-revision": "Uahan kaca",
+       "redirect-file": "Wastan berkas",
        "specialpages": "Kaca kusus",
        "external_image_whitelist": "#banggiang baris niki sapunapi kawentenanne<pre>\n#anggen fragmen akspresi reguler (wantah kepahan ring kekelaih//) ring sor puniki\n#fragmen-fragmen puniki jagi kaadungang sareng URL saking gambar-gambar eksternal (sane kasambungang langsung)\n#fragmen sane adung jagi katampilang dados gambar, sisanne wantah dados pranala kewanten\n#baris sane kakawitin antuk # jagi kadadosang baris komentar\n#niki nenten ngabinayang aksara ageng lan alit\n#genahang samian fragmen ekspresi reguler ring sor baris puniki. banggiang baris niki sapunapi kawentennane</pre>",
        "tag-filter": "filter [[Special:Tags|tag]]:",
        "tags-active-no": "Nénten",
        "tags-edit": "uah",
        "tags-delete": "usap",
+       "tags-hitcount": "$1 {{PLURAL:$1|uahan}}",
        "tags-delete-title": "Usap tag",
        "compare-page2": "Kaca 2",
        "logentry-delete-delete": "$1 {{GENDER:$2|ngusapin}} kaca $3",
+       "revdelete-content-hid": "dagingnyané kaengkebang",
        "logentry-move-move": "$1 {{GENDER:$2|ngingsirang}} kaca $3 ring $4",
        "logentry-newusers-create": "Akun sang anganggé $1 {{GENDER:$2|kakaryanin}}",
        "logentry-newusers-autocreate": "Akun sang anganggé $1 {{GENDER:$2|kakaryanin}} otomatis",
index dbd4460..7ca94c7 100644 (file)
@@ -23,6 +23,7 @@
        "tog-hideminor": "ھوردݔں ٹگلاں پناہ کن",
        "tog-hidepatrolled": "ته نوکین تغییرات اصلاحاتی که گردگ بیتگن پناه کن",
        "tog-newpageshidepatrolled": "تاکاتے کہ گندگ بیتگ اَنت پناہ کن",
+       "tog-hidecategorization": "تاکانء تراشوانء پناہ کنگ",
        "tog-extendwatchlist": "چارگ لیستءَ مزن کن کہ دراھیگݔں گندگ بہ بَنت",
        "tog-usenewrc": "گروپء تاک ءُ چارگ لیستء ٹگلاں",
        "tog-numberheadings": "سرگالاں وتاوت ترتیپ کن",
@@ -32,6 +33,7 @@
        "tog-watchdefault": "منی ٹگل داتگݔں تاک ءُ پایلان چارگ لیستءَ ھۏر کن",
        "tog-watchmoves": "منی سُرݔنتگݔں تاک ءُ پایلان چارگ لیستءَ ھۏر کن",
        "tog-watchdeletion": "منی پاک کتگݔں تاک ءُ پایلان چارگ لیستءَ ھۏر کن",
+       "tog-watchuploads": "نۏکݔں پایلانء ھۏر کنگ مہ منی چارگء لیست‌ئا",
        "tog-watchrollback": "آ تاکاں کہ چھر داتگن منی  چارگ لیستءَ ھۏر کن",
        "tog-minordefault": "دراھیگݔں ٹگلاں پݔسری پئیما کن",
        "tog-previewontop": "بازبین پیش دار پیش چه جعبه اصلاح",
        "virus-scanfailed": "اسکن پروش وارت(کد $1)",
        "virus-unknownscanner": "ناشناسین آنتی ویروس:",
        "logouttext": "''' شما انیگء در شُت ات'''\nبزان که تانکه شمئی بروزرء چیرداتگین هافظه پهک مبیت، لهتئ چه تاکان ممکن انت رندا هم هنچوش پیش دارگ ببنت که انگار شما لاگین کتگ ات.",
+       "logout-failed": "ھنیگءَ نہ تۏن اِت در بئ اِت:",
        "welcomeuser": "وشاتک ات $1!",
        "welcomecreation-msg": "نۏکی شمئی ساب جۏڈ کنگ بیتہ.\nمہ شمۏش اِت کہ وتی [[Special:Preferences|واھشتاں {{SITENAME}}]] ٹگل بہ دئ اِت.",
        "yourname": "کار زوروکی نام:",
        "createacct-reason-ph": "پرچا شما ادگر نوکین اکانتء اڈ کن ات",
        "createacct-submit": "وتی اکانتء اڈ کن ات",
        "createacct-another-submit": "سابے جۏڈݔن",
+       "createacct-continue-submit": "سابءَ جۏڑݔنگء دامدار",
+       "createacct-another-continue-submit": "سابء جۏڑݔنگء دامدار",
        "createacct-benefit-heading": "{{SITENAME}} شهسانی واسته هنچوش که شمئیء اڈ بیتگ",
        "createacct-benefit-body1": "$1 {{PLURAL:$1|ٹگل|ٹگلاں}}",
        "createacct-benefit-body2": "{{PLURAL:$1|تاک|تاکان}}",
        "createacct-benefit-body3": "{{PLURAL:$1|هوار بیتگ}} نوکین",
        "badretype": "کلماتی رمزی که شما وارد کتگیت یک نهنت.",
+       "usernameinprogress": "یک سابے گۏں اے کارزورۏکی ناما جۏڑݔنگ بیت،کمے سَبر بہ کن اِت۔",
        "userexists": "ائ یوزرنامء که لکتگ ات پیسریگء کارمرز بیتگ انت.\nدزبندی انت ادگر نامء بزیریت.",
        "loginerror": "حطا ورود",
        "createacct-error": "ارور مان اکانتء اڈ کنگء",
        "createaccounterror": "پر ائ اکانتء اڈ کتن امکان نه انت: $1",
        "nocookiesnew": "حساب کاربر شر بوت بله شما وارد نه بیتگیت ته.\n{{SITENAME}} چه کوکی په ورود کابران استفاده کنت.\nشما کوکی غیر فعال کتت.\nلطفا آییآ فعال کنیت رندا گون وتی نوکین نام کاربری و کلمه رمز وارد بیت.",
-       "nocookieslogin": "{{SITENAME}} په ورود کابران چه کوکی استفاده کنت.\nشمی کوکی غیر فعالنت.\nلطفا آییا فعال کنیت و دگه  سعی کنیت.",
+       "nocookieslogin": "{{SITENAME}} پہ مان بییگء واستا چہ کوکی‌ئا کارءَ گیرت.\nشمئی بروزرء کوکی بَند اِنت.\nبروزرء کوکی‌ئاں چالو کن اِت دنکہ بہ تۏن اِت مان بئ اِت.",
        "nocookiesfornew": "اکانت اڈ نبیت، پرچا که ما نتوانت آئی منبعء رء تأیید کنین.\nپکا بزان ات که کوکی‌هان فعال انت، رندا پیجء چه نوک رلود کن ات و دوبارگ بچکاس ات.",
        "noname": "شما یک معتبرین نام کاربر مشخص نه کتت.",
        "loginsuccesstitle": "مان بیت اِت",
        "createaccount-title": "شرکتن حساب په {{SITENAME}}",
        "createaccount-text": "یکی یک حساب په شمی آدرس ایمیل ته  {{SITENAME}} گون نام ($4)  \"$2\"، گون کلمه رمز \"$3\" شرکتت.\nشما بایدن وارد بیت و وتی کلمه رمز الان عوض کنیت.\n\nشما شاید ای پیام شموشیت اگه ای ای حساب گون حطا شر بوتت.",
        "login-throttled": "شما انیگ پر لاگین کتنء چنت بار جهد کتگ ات. دزبندی انت پیسر چه پدایین جهدء $1 موه بداریت.",
-       "login-abort-generic": "Ø´Ù\85ئÛ\8c Ù\84اگÛ\8cÙ\86Ø¡ Ù¾Ú©Ø§ Ù\86بیت - Aborted",
+       "login-abort-generic": "Ø´Ù\85ئÛ\8c Ù\85اÙ\86 Ø¨Û\8cÛ\8cÚ¯ Ù\86Û\81 بیت - Aborted",
        "login-migrated-generic": "شمی کاربرین حساب منتکل بوته ، و شمی کاربری نام دیگه ای ویکی تا وجود نداریت .",
        "loginlanguagelabel": "زبان: $1",
        "suspicious-userlogout": "شمئی لوٹ پر در شتن چه سیستمء رد بوت پرچا که چوش که پیداگ انت ائ لوٹ چه هرابین بروزر یانکه پراکسیء راهیگ بیتگ انت.",
        "createacct-another-realname-tip": "اصلیگین نام ایهتیاری انت.\nاگان آئرا بلک ات رهشونء درگتء پر شمئی سیاهگان چه اصلیگین نام کارمرز بیت انت.",
        "pt-login": "لاگین",
        "pt-login-button": "لاگین",
+       "pt-login-continue-button": "مان بییگء دامدار",
        "pt-createaccount": "اکانتء اڈ بکن",
        "pt-userlogout": "در بییگ",
        "php-mail-error-unknown": "نامالومین ارور مان تابع  mail()‎ پی‌اچ‌پی",
        "newpassword": "نوکین کلمه رمز:",
        "retypenew": "کلمه رمز دگه بنویس",
        "resetpass_submit": "تنظیم کلمه رمز و ورود",
-       "changepassword-success": "شمئی پسورد پر درستیء ٹگل بیت!",
+       "changepassword-success": "شمئی گالگوَز ٹگلݔنگ بیت!",
        "changepassword-throttled": "شما انیگ پر لاگین کتنء چنت بار جهد کتگ ات. دزبندی انت پیسر چه پدایین جهدء $1 موه بداریت.",
+       "botpasswords": "رباتء گالگوَزاں",
        "botpasswords-label-create": "جوڑ کورتین",
        "botpasswords-label-update": "پہ رۏچ",
        "botpasswords-label-cancel": "بجَگ",
        "botpasswords-label-delete": "کۏر کنگ",
        "botpasswords-label-resetpassword": "گالگوَزءِ پاک کنگ",
        "resetpass_forbidden": "کلمات رمز نه توننت عوض بنت.",
+       "resetpass_forbidden-reason": "گالگوَز ٹگلݔنگءَ نہ بیت",
        "resetpass-no-info": "په مستقیمین دسترسی په ای صفحه شما بایدن وارد سایت بیت",
        "resetpass-submit-loggedin": "عوض کتن کلمه رمز",
        "resetpass-submit-cancel": "کنسیل",
        "media_tip": "لینک فایل",
        "sig_tip": "شمی امضا گون مهر زمان",
        "hr_tip": "خط افقی",
-       "summary": "خلاصه:",
+       "summary": "کمݔں:",
        "subject": "موضوع/سرخط:",
        "minoredit": "ای شی یک هوردین اصلاحیت",
-       "watchthis": "اÛ\8c ØµÙ\81Ø­Ù\87 Ø¨چار",
+       "watchthis": "اÛ\92 ØªØ§Ú©Ø§ Ø¨Û\81 چار",
        "savearticle": "تاکدیمِ ذخیره کورتین",
        "preview": "دیستین",
        "showpreview": "بازبین پیش دار",
        "edit_form_incomplete": "<strong>لهتی چه ادیت فرمء بهران پر سرورء نرستگ انت؛ پکا بزان ات که شمئی ادیتان پکا انت و رندء چدوبارگ جهد کن ات</strong>",
        "editing": "$1 ء ٹگلݔنگ",
        "creating": "اڈ کتن $1",
-       "editingsection": "اصلاح $1(بخش)",
+       "editingsection": "$1(چُنڈ)ء ٹگلݔنگ",
        "editingcomment": "$1 (نۏکݔن چُنڈ) تگلݔنگ",
        "editconflict": "جنگ ورگ اصلاح: $1",
        "explainconflict": "کسی دگه ای صفحه یا عوض کتت چه وهدی که شما اصلاح آیء شروع کتء.\nبالادی ناحیه متن شامل متن صفحه همی داب که هنگت هست.\nشمی تغییرات ته جهلیگین ناحیه متن جاه کیت.\nشما بایدن وتی تغییرات آن گون هنوکین متن چن و بند کنیت.\n'''فقط''' ناحیه بالادی متن وهدی که شما دکمه  \"$1\" ذخیره بنت.",
        "permissionserrorstext-withaction": "شما را اجازت په $2, په خاطر جهلیگین {{PLURAL:$1|دلیل|دلایل}}:",
        "recreate-moveddeleted-warn": "هوژاری: شما یک صفحه ای دگه شرکنگیت که پیشتر حذف بوتت.'''\n\nشما بایدن توجه کنیت که ادامه اصلاح ای صفحه درستنت.\nآمار حذف و جاه په جاهی ای صفحه په شمی حاطرء ادان هستن:",
        "moveddeleted-notice": "ای صفحه حذف بوتت.\nپه مراجعه جهل گور آمار حذف و جاه په جاهی پی ای صفحه اتکگت.",
-       "log-fulllog": "چارگ کل سیاهگ",
+       "log-fulllog": "دراھیگݔں سیاھگء چارگ",
        "edit-hook-aborted": "اصلاح گون قلاب بند بوت.\nتوضیحی ای باره ی دهگ نه بوتت.",
        "edit-gone-missing": "نه تونیت صفحهء په روچی کنت.\nچوش که جاه کیت آیی حذف بوتگت.",
        "edit-conflict": "جنگ اصلاحی",
        "nextrevision": "نوکین بازبینی→",
        "currentrevisionlink": "هنوکین بازبینی",
        "cur": "هنو",
-       "next": "بعدÛ\8c",
+       "next": "اÝ\94دگÛ\81",
        "last": "اهری",
        "page_first": "اولین",
        "page_last": "اهرین",
        "search-suggest": "شما را منظور ات: $1",
        "search-interwiki-caption": "پروژه آن گوهار",
        "search-interwiki-default": "نتایج چه $1 :",
-       "search-interwiki-more": "(گیشتر)",
-       "search-interwiki-more-results": "گݔشتر",
+       "search-interwiki-more": "(گݔشتِر)",
+       "search-interwiki-more-results": "گݔشترݔں نتیجہ",
        "search-relatedarticle": "مربوطین",
        "searchrelated": "مربوط",
        "searchall": "کل",
        "recentchangeslinked-page": "تاکدیمِ نام:",
        "recentchangeslinked-to": "پیش دار تغییرات په صفحاتی که لینک بوتگنت به جاه داتگین صفحه",
        "upload": "آپلود کتن فایل",
-       "uploadbtn": "آپلود فایل",
+       "uploadbtn": "پایلء آپلود",
        "reuploaddesc": "کنسل آپلودء و ترر په فرم آپلود",
        "upload-tryagain": "فایلء ٹگا وارتگین توضیحاتء راهیگ بکن ات",
        "uploadnologin": "وارد نهیت",
        "uploadlogpage": "آپلود ورودان",
        "uploadlogpagetext": "جهلء یک لیست چه نوکترین آپلودان قایل هست.\n[[Special:NewFiles|گالری نوکین فایلان]]",
        "filename": "نام فایل",
-       "filedesc": "خلاصه",
-       "fileuploadsummary": "خلاصه:",
+       "filedesc": "کمݔں",
+       "fileuploadsummary": "پائلء باروا:",
        "filereuploadsummary": "تغییرات فایل:",
        "filestatus": "وضعیت حق کپی:",
        "filesource": "منبع:",
        "logempty": "هچ آیتم هم دپ ته آمار",
        "log-title-wildcard": "بگرد عناوین که گون ای متن شروع بنت",
        "allpages": "کل صفحات",
-       "nextpage": "صفحه ی بعدی ($1)",
+       "nextpage": "($1)ء اݔدگہ تاک",
        "prevpage": " ($1)پیشگین صفحه",
        "allpagesfrom": "پیش در صفحات شروع بنت ته:",
        "allpagesto": "پیش بدار صفحاتی که هلنت گون:",
        "istemplate": "همراهی",
        "isimage": "لینک عکس",
        "whatlinkshere-prev": "{{PLURAL:$1|پیشگین|پیشگین $1}}",
-       "whatlinkshere-next": "{{PLURAL:$1|بعدÛ\8c|بعدÛ\8c $1}}",
+       "whatlinkshere-next": "{{PLURAL:$1|اÝ\94دگÛ\81|اÝ\94دگÛ\81 $1}}",
        "whatlinkshere-links": "← لینکان",
        "whatlinkshere-hideredirs": "$1 غیر مستقیم",
        "whatlinkshere-hidetrans": "$1 بین اضاف",
        "namespacesall": "کل",
        "monthsall": "کل",
        "confirmemail": "آدرس ایمیل تایید کن",
-       "confirmemail_noemail": "Ø´Ù\85ا Û\8cÚ© Ù\85عتبرÛ\8cÙ\86 Ø¢Ø¯Ø±Ø³ Ø§Û\8cÙ\85Û\8cÙ\84 ØªÙ\86ظÛ\8cÙ\85 Ù\86Ù\87 Ú©ØªØª Ù\86Ù\87 Ù\88تÛ\8c [[Special:Preferences|ترجÛ\8cحات Ú©Ø§Ø±Ø¨Ø±]].",
+       "confirmemail_noemail": "Ø´Ù\85ا Û\8cÚ© Ù¾Ø¯Ù\84Ý\94Úº Ø§Û\8cÙ\85ئÛ\8cÙ\84Û\92 Ø³Ù¾Øª Ù\86Û\81 Ú©Ù\8fتگ Ú©Û\81 Ù\85ا Ø¨Û\81 ØªÛ\8fÙ\86 Ø§Ù\90Ù\86ت Ú¯Û\8fÚº Ø´Ù\85ا Ø±Ø§Ø¨ØªÛ\81 Ø¨Û\81 Ú©Ù\86 Ø§Ù\90Ù\86ت[[Special:Preferences|کارزÙ\88رÛ\8fÚ©Ø¡ Ù\88اھشتاں]].",
        "confirmemail_text": "{{SITENAME}} لوٹیت که شما وتی آدرس ایمیلء تایید کنید پیش چه شی که سرویسان ایمیلی استفاده کنیت.\nای جهلی دکمه فعال کن تا یک ایمیل تایید په شمی آدرس دیم دنت.\nای ایمیل شامل یک لینکیت که کد همراه داریت;\nته وتی بروزر لینک پچ کن تا شمی آدرس ایمیل تایید بیت",
        "confirmemail_pending": "یک کد تایید پیش تر په شما ایمیل بوتت;\nاگر شما نوکی وتی حسابء شرکتت، شما بلکین چند دقیقه صبر کنیت تا آی برسیت پیش چه شی که یک نوکین درخواست په نوکین کتن کنیت.",
        "confirmemail_send": "یک کد تایید ایمیل کن",
        "semicolon-separator": "؛&#32;",
        "colon-separator": ":&#32;",
        "imgmultipageprev": "← پیشگین صفحه",
-       "imgmultipagenext": "صÙ\81Ø­Ù\87 Ø¨Ø¹Ø¯Û\8c →",
+       "imgmultipagenext": "اÝ\94دگÛ\81 ØªØ§Ú© →",
        "imgmultigo": "برا!",
        "imgmultigoto": "برو به صفحه  $1",
        "ascending_abbrev": "بالادی",
        "descending_abbrev": "جهلادی",
-       "table_pager_next": "صÙ\81Ø­Ù\87 Ø¨Ø¹Ø¯Û\8c",
+       "table_pager_next": "اÝ\94دگÛ\81 ØªØ§Ú©",
        "table_pager_prev": "پیشگین صفحه",
        "table_pager_first": "اولی صفحه",
        "table_pager_last": "اهری صفحه",
index 49db072..47645a3 100644 (file)
        "edit-error-short": "Памылка: $1",
        "edit-error-long": "Памылкі:\n\n$1",
        "specialmute": "Заглушаныя ўдзельнікі",
-       "specialmute-success": "Ð\92аÑ\88Ñ\8bÑ\8f Ð½Ð°Ð»Ð°Ð´Ñ\8b Ð·Ð°Ð³Ð»Ñ\83Ñ\88Ñ\8dнÑ\8cнÑ\8f Ð±Ñ\8bлÑ\96 Ð¿Ð°Ñ\81Ñ\8cпÑ\8fÑ\85ова Ð°Ð±Ð½Ð¾Ñ\9eленÑ\8bÑ\8f. Ð\93лÑ\8fдзÑ\96Ñ\86е Ñ\9eÑ\81Ñ\96Ñ\85 Ð·Ð°Ð³Ð»Ñ\83Ñ\88анÑ\8bÑ\85 Ñ\83дзелÑ\8cнÑ\96каÑ\9e Ð½Ð° Ñ\81Ñ\82аÑ\80онÑ\86Ñ\8b [[Special:Preferences]].",
+       "specialmute-success": "Ð\92аÑ\88Ñ\8bÑ\8f Ð½Ð°Ð»Ð°Ð´Ñ\8b Ð·Ð°Ð³Ð»Ñ\83Ñ\88Ñ\8dнÑ\8cнÑ\8f Ð±Ñ\8bлÑ\96 Ð°Ð±Ð½Ð¾Ñ\9eленÑ\8bÑ\8f. Ð\93лÑ\8fдзÑ\96Ñ\86е Ñ\9eÑ\81Ñ\96Ñ\85 Ð·Ð°Ð³Ð»Ñ\83Ñ\88анÑ\8bÑ\85 Ñ\83дзелÑ\8cнÑ\96каÑ\9e Ð½Ð° Ñ\81Ñ\82аÑ\80онÑ\86Ñ\8b [[Special:Preferences|ваÑ\88Ñ\8bÑ\85 Ð½Ð°Ð»Ð°Ð´Ð°Ñ\9e]].",
        "specialmute-submit": "Пацьвердзіць",
        "specialmute-label-mute-email": "Заглушыць лісты электроннай пошты ад гэтага ўдзельніка",
        "specialmute-header": "Калі ласка, абярыце вашыя налады заглушэньня для {{BIDI:[[User:$1]]}}.",
        "specialmute-error-invalid-user": "Запытанае імя ўдзельніка ня можа быць знойдзенае.",
        "specialmute-error-email-blacklist-disabled": "Заглушэньне ўдзельнікам магчымасьці дасылаць вам лісты электроннай поштай ня ўключанае.",
+       "specialmute-error-email-preferences": "Вы мусіце пацьвердзіць ваш адрас электроннай пошты перад тым, як зможаце заглушыць удзельніка. Вы можаце зрабіць гэта ў [[Special:Preferences|наладах]].",
+       "specialmute-email-footer": "Для кіраваньня наладамі электроннай пошты для {{BIDI:$2}}, калі ласка, наведайце <$1>.",
+       "specialmute-login-required": "Калі ласка, увайдзіце, каб зьмяніць вашыя налады заглушэньня.",
        "revid": "вэрсія $1",
        "pageid": "Ідэнтыфікатар старонкі $1",
        "interfaceadmin-info": "$1\n\nДазволы на рэдагаваньне агульнасайтавых CSS/JS/JSON-файлаў былі нядаўна вылучаныя з права <code>editinterface</code>. Калі вы не разумееце, чаму атрымліваеце гэтую памылку, глядзіце [[mw:MediaWiki_1.32/interface-admin]].",
index c4aa322..bbaf678 100644 (file)
        "history-fieldset-title": "Silañ an adweladennoù",
        "history-show-deleted": "Stumm diverket hepken",
        "histfirst": "koshañ",
-       "histlast": "nevezañ",
+       "histlast": "nevesañ",
        "historysize": "({{PLURAL:$1|$1 okted|$1 okted}})",
        "historyempty": "goullo",
        "history-feed-title": "Istor ar c'hemmoù",
index faa4581..461ad0a 100644 (file)
        "autoblockedtext": "La vostra adreça IP ha estat blocada automàticament perquè va ser usada per un usuari actualment blocat. Aquest usuari va ser blocat per l'{{GENDER:$1|administrador|administradora}} $1. El motiu donat per al blocatge és aquest:\n\n:<em>$2</em>\n\n* Inici del blocatge: $8\n* Final del blocatge: $6\n* Usuari blocat: $7\n\nPodeu contactar l'usuari $1 o algun altre dels [[{{MediaWiki:Grouppage-sysop}}|administradors]] per a discutir el blocatge.\n\nRecordeu que per a poder usar l'opció «{{int:emailuser}}» haureu d'haver validat una adreça de correu electrònic a les vostres [[Special:Preferences|preferències]].\n\nEl número d'identificació de la vostra adreça IP és $3, i l'ID del blocatge és #$5. Si us plau, incloeu aquestes dades en totes les consultes que feu.",
        "systemblockedtext": "El vostre nom d'usuari o adreça IP ha estat blocada automàticament pel MediaWiki.\nEl motiu donat és:\n\n:<em>$2</em>\n\n* Inici del blocatge: $8\n* Caducitat del blocatge: $6\n* Destinatari del blocatge: $7\n\nLa vostra adreça IP actual és $3.\nAfegiu les dades de més amunt en qualsevol consulta que feu al respecte.",
        "blockednoreason": "no s'ha donat cap motiu",
+       "blockedtext-composite-reason": "Hi ha diferents blocatges associats al vostre compte i/o adreça IP",
        "whitelistedittext": "Heu de $1 per modificar pàgines.",
        "confirmedittext": "Heu de confirmar la vostra adreça electrònica abans de poder modificar les pàgines. Definiu i valideu la vostra adreça electrònica a través de les vostres [[Special:Preferences|preferències d'usuari]].",
        "nosuchsectiontitle": "No es pot trobar la secció",
        "action-changetags": "afegeix i elimina etiquetes a les revisions i les entrades de registre individuals",
        "action-deletechangetags": "eliminar etiquetes des de la base de dades",
        "action-purge": "purga la pàgina",
+       "action-blockemail": "blocar un usuari per tal que no enviï correu",
+       "action-bot": "ser tractat com un procés automatitzat",
+       "action-editprotected": "modificar pàgines protegides com «{{int:protect-level-sysop}}»",
+       "action-editsemiprotected": "modificar pàgines protegides com «{{int:protect-level-autoconfirmed}}»",
        "action-editinterface": "editar la interfície d'usuari",
+       "action-editusercss": "modificar els fitxers CSS d'altres usuaris",
+       "action-edituserjson": "modificar els fitxers JSON d'altres usuaris",
+       "action-edituserjs": "modificar els fitxers JavaScript d'altres usuaris",
+       "action-editsitecss": "modificar el CSS del lloc web",
+       "action-editsitejson": "modificar el JSON del lloc web",
+       "action-editsitejs": "modificar el JavaScript del lloc web",
+       "action-editmyusercss": "modificar els vostres propis fitxers CSS",
+       "action-editmyuserjson": "modificar els vostres propis fitxers JSON",
+       "action-editmyuserjs": "modificar els vostres propis fitxers JavaScript",
+       "action-viewsuppressed": "mostrar revisions amagades de qualsevol usuari",
+       "action-hideuser": "blocar un nom d'usuari, amagant-lo del públic",
        "action-unblockself": "desblocar-se un mateix",
        "nchanges": "$1 {{PLURAL:$1|canvi|canvis}}",
        "enhancedrc-since-last-visit": "$1 {{PLURAL:$1|des de la darrera visita}}",
        "mycontris": "Contribucions",
        "anoncontribs": "Contribucions",
        "contribsub2": "Per a {{GENDER:$3|$1}} ($2)",
+       "contributions-subtitle": "Per a {{GENDER:$3|$1}}",
        "contributions-userdoesnotexist": "El compte d'usuari «$1» no està registrat.",
        "negative-namespace-not-supported": "No es permeten espais de noms amb valors negatius.",
        "nocontribs": "No s’ha trobat cap canvi que encaixés amb aquests criteris.",
        "pageinfo-category-subcats": "ombre de subcategories",
        "pageinfo-category-files": "Nombre d'arxius",
        "pageinfo-user-id": "ID d'usuari",
+       "pageinfo-file-hash": "Valor de resum",
        "pageinfo-view-protect-log": "Mostra el registre de protecció d'aquesta pàgina.",
        "markaspatrolleddiff": "Marca com a supervisat",
        "markaspatrolledtext": "Marca la pàgina com a supervisada",
        "htmlform-date-invalid": "El valor que heu especificat no és una data reconeguda. Proveu d'utilitzar el format AAAA-MM-DD.",
        "htmlform-time-invalid": "El valor que heu especificat no és una hora reconeguda. Proveu d'utilitzar el format HH:MM:SS.",
        "htmlform-datetime-invalid": "El valor que heu especificat no és una data i hora reconeguda. Proveu d'utilitzar el format AAAA-MM-DD HH:MM:SS.",
+       "htmlform-datetime-toolow": "El valor que heu especificat és anterior a la data i hora més antiga permeses, $1.",
+       "htmlform-datetime-toohigh": "El valor que heu especificat és posterior a la data i hora permeses, $1.",
        "htmlform-title-badnamespace": "[[:$1]] no es troba en l'espai de noms \"{{ns:$2}}\".",
        "htmlform-title-not-creatable": "\"$1\" és un títol de pàgina no editable",
        "htmlform-title-not-exists": "$1 no existeix.",
        "authprovider-resetpass-skip-help": "Omet el restabliment de contrasenya.",
        "authform-nosession-login": "L’autenticació fou exitosa, però el vostre navegador no pot «recordar» haver iniciat la sessió.\n\n$1",
        "authform-nosession-signup": "S’ha creat el compte, però el vostre navegador no pot «recordar» haver iniciat la sessió.\n\n$1",
+       "authform-notoken": "Hi manca el testimoni",
+       "authform-wrongtoken": "Testimoni incorrecte",
        "specialpage-securitylevel-not-allowed-title": "No permès",
        "specialpage-securitylevel-not-allowed": "Ho sentim, no podeu utilitzar la pàgina perquè no es pot verificar la vostra identitat.",
        "authpage-cannot-login": "No s'ha pogut iniciar la sessió.",
        "restrictionsfield-label": "Intervals d'IP permesos:",
        "edit-error-short": "Error: $1",
        "edit-error-long": "Errors:\n\n$1",
+       "specialmute": "Silencia",
        "specialmute-submit": "Confirma",
+       "specialmute-label-mute-email": "Silencia el correu electrònic d'aquest usuari",
        "specialmute-error-invalid-user": "No s’ha trobat el nom d’usuari que heu indicat.",
+       "specialmute-error-email-preferences": "Heu de confirmar l'adreça electrònica abans de poder silenciar un usuari. Podeu fer-ho des de [[Special:Preferences]].",
+       "specialmute-login-required": "Inicieu una sessió per canviar les preferències de silenciament.",
        "revid": "revisió $1",
        "pageid": "ID de pàgina $1",
        "rawhtml-notallowed": "No és possible fer servir les etiquetes &lt;html&gt; fora de les pàgines normals.",
index dd37d6d..448ddb8 100644 (file)
        "revdelete-offender": "АгӀона версин автор:",
        "suppressionlog": "Хьулдаран тептар",
        "mergehistory": "Нисдарийн истори цхьаьнатохар",
+       "mergehistory-header": "ХӀокху агӀонца таро ю шина агӀона истори вовшахтоха.\nТешна хила, хӀокху хийцамо истори талхор цахилар.",
        "mergehistory-box": "Шин агӀона нисдарийн истори цхьаьнатохар:",
-       "mergehistory-from": "Дуьххьарлера агӀоно",
+       "mergehistory-from": "ДӀайолалун агӀо:",
        "mergehistory-into": "Ӏалашонан агӀо:",
        "mergehistory-list": "Цхьаьнатухуш долу нисдарийн истори",
        "mergehistory-go": "Гайта цхьаьнатухуш долу нисдарш",
        "undelete-search-title": "ДӀаяхна агӀонаш лахар",
        "undelete-search-box": "ДӀаяхна агӀонаш лахар",
        "undelete-search-prefix": "Гайта агӀонаш йолалуш йолу тӀера:",
+       "undelete-search-full": "Гайта агӀонийн цӀерш, чулацам:",
        "undelete-search-submit": "Лахар",
        "undelete-no-results": "Архив чохь йогӀуш агӀонаш цакарий.",
        "undelete-error": "АгӀо меттахӀоттаяран гӀалат",
        "export-addns": "ТӀетоха",
        "export-download": "Кховда де файл сана Ӏалашдан",
        "export-templates": "Латадé кепаш",
+       "export-manual": "Куьйга тӀетоха агӀонаш:",
        "allmessages": "ГӀирса хаамаш",
        "allmessagesname": "Хаам",
        "allmessagesdefault": "Ӏадйитаран кепаца йоза",
        "tags-edit-reason": "Бахьана:",
        "tags-edit-nooldid-title": "Ӏалашонан верси билгалйина яц",
        "comparepages": "АгӀонаш юстар",
-       "compare-page1": "Ð\94Ñ\83Ñ\8cÑ\85Ñ\85Ñ\8cаÑ\80алера агӀо",
+       "compare-page1": "Ð¥Ñ\8cалÑ\85ара агӀо",
        "compare-page2": "ШолгӀа агӀо",
-       "compare-rev1": "Ð\94Ñ\83Ñ\8cÑ\85Ñ\85Ñ\8cаÑ\80алера верси",
+       "compare-rev1": "Ð¥Ñ\8cалÑ\85ара верси",
        "compare-rev2": "ШолгӀа верси",
        "compare-submit": "Юста",
        "compare-invalid-title": "Ахьа язйина йолу цӀе ца магайо.",
        "passwordpolicies-policy-passwordcannotmatchusername": "Пароль декъашхочун цӀерах тера хила ца еза",
        "passwordpolicies-policy-passwordcannotmatchblacklist": "Пароль Ӏаьржачу могӀаман юкъахь йолучарех тера хила ца еза",
        "passwordpolicies-policy-maximalpasswordlength": "Пароль $1 {{PLURAL:$1|символал}} йоца хила ца еза",
-       "passwordpolicies-policy-passwordcannotbepopular": "Пароль дукха {{PLURAL:$1|лелош йолчарех хила ца еза}}"
+       "passwordpolicies-policy-passwordcannotbepopular": "Пароль дукха {{PLURAL:$1|лелош йолчарех хила ца еза}}",
+       "passwordpolicies-policy-passwordnotinlargeblacklist": "Пароль цхьанайогӀуш хила цаеза 100 000 дукха лелош йолучу паролашца.",
+       "passwordpolicies-policyflag-suggestchangeonlogin": "болхболича чекхбаккха хийцам"
 }
index 99edfcb..72b1763 100644 (file)
        "returnto": "بگەڕێوە بۆ $1.",
        "tagline": "لە {{SITENAME}}",
        "help": "یارمەتی",
+       "help-mediawiki": "یارمەتی دەربارەی میدیاویکی",
        "search": "گەڕان",
        "searchbutton": "بگەڕێ",
        "go": "بڕۆ",
        "mypreferencesprotected": "دەسەڵاتی دەستکارییکردنی هەڵبژاردنەکانی خۆتت نییە.",
        "ns-specialprotected": "پەڕە تایبەتەکان دەستکاری ناکرێن.",
        "titleprotected": "ئەم سەرناوە پارێزراوە لە دروستکران لە لایەن [[User:$1|$1]].\nھۆکاری ئەمە بریتیە لە <em>$2</em>.",
+       "invalidtitle": "ناونیشانی نادروست",
        "invalidtitle-knownnamespace": "سەردێڕی نادروست بە بۆشایی ناوی «$2» و دەقی «$3»",
        "invalidtitle-unknownnamespace": "سەردێڕی هەڵە لەگەڵ ناوەبۆشایی نەناسراوی ژمارە $1 و دەقی \"$2\"",
        "exception-nologin": "لەژوورەوە نیت",
        "virus-scanfailed": "سکەن ئەنجام نەدرا(کۆد $1)",
        "virus-unknownscanner": "دژەڤایرس نەناسراوە:",
        "logouttext": "'''ئێستا چوویتە دەرەوە.'''\n\nئاگادار بە ھەتا ئەو کاتەی کەشی وێبگەڕەکەت پاک دەکەیتەوە، لەوانەیە ھەندێک لە پەڕەکان وا پێشان بدرێن کە ھێشتا لە ژوورەوە بیت.",
+       "logging-out-notify": "دەکرێیتەوە دەرەوە، تکایە چاوەڕێ بکە.",
+       "logout-failed": "ناتوانیت لە ئێستادا بچیتە دەرەوە: $1",
        "cannotlogoutnow-title": "ناتوانیت لە ئێستادا بچیتە دەرەوە",
        "cannotlogoutnow-text": "توانای چوونە دەرەوەت نییە لەکاتی بەکارھێنانی $1",
        "welcomeuser": "بەخێربێیت، $1!",
        "invalid-content-data": "دراوەی ناوەرۆکی نادروست",
        "content-not-allowed-here": "«$1» ڕێگە پێنەدراوە لەسەر پەڕەی [[:$2]]",
        "editwarning-warning": "بەجێھێشتنی ئەم لاپەڕەیە دەبێتە هۆی لە‌دەستدانی هەموو ئەو گۆڕانکاریانەی کە ئەنجامت داون. ئەگەر لە ژوورەوەیت، دەتوانیت ئەم ئاگادارییە لابەریت لە ھەڵبژاردەی بەکارھێنەرت.",
+       "slot-name-main": "سەرەکی",
        "content-model-wikitext": "ویکیدەق",
        "content-model-text": "دەقی ساکار",
        "content-model-javascript": "جاڤاسکریپت",
        "action-viewmywatchlist": "دیتنی پێرستی چاودێریت",
        "action-viewmyprivateinfo": "زانیارییە تایبەتییەکانت ببینە",
        "action-editmyprivateinfo": "دەستکاری زانیارییە تایبەتییەکانت بکە",
+       "action-deletechangetags": "سڕینەوەی تاگەکان لە بنکەدراوەکەدا",
        "action-purge": "پاکسازی ئەم پەڕەیە بکە",
        "nchanges": "$1 {{PLURAL:$1|گۆڕانکاری}}",
        "enhancedrc-since-last-visit": "$1 لە ماوەی دوایین سەردانەوە",
        "deleteprotected": "تۆ ناتوانیت ئەم پەڕەیە بسڕیتەوە لەبەرئەوەی پارێزراوە.",
        "deleting-backlinks-warning": "'''ئاگاداری:''' [[Special:WhatLinksHere/{{FULLPAGENAME}}|پەڕەکانی تر]] بەم پەڕەیەی دەتەوێ بیسڕییەوە بەستەر دراوە.",
        "rollback": "گەڕاندنەوەی دەستکارییەکان",
+       "rollback-confirmation-no": "پاشگەزبوونەوە",
        "rollbacklink": "گەڕاندنەوە",
        "rollbacklinkcount": "گەڕاندنەوەی $1 {{PLURAL:$1|دەستکاری}}",
        "rollbacklinkcount-morethan": "گەڕاندنەوەی زۆرتر لە $1 {{PLURAL:$1|دەستکاری}}",
        "tags-create-no-name": "پێویستە ئامژە بە ناوی تاگ بدەیت.",
        "tags-create-invalid-chars": "تاگەکان نابێت بۆر (<code>،</code>) یان سلاش (<code>/</code>)یان تێدابێت.",
        "tags-delete-reason": "هۆکار:",
+       "tags-activate-reason": "ھۆکار:",
        "comparepages": "پەڕەکان ھەڵسەنگێنە",
        "compare-page1": "پەڕەی ١",
        "compare-page2": "پەڕەی ٢",
index a4b4b79..babd4a1 100644 (file)
        "systemblockedtext": "Vaše IP adresa byla automaticky zablokována softwarem MediaWiki.\nUdaný důvod blokování:\n\n:<em>$2</em>\n\n* Začátek blokování: $8\n* Konec blokování: $6\n* Původně blokovaný uživatel: $7\n\nVaše současná IP adresa je $3.\nProsíme, uveďte tyto údaje při komunikaci se správci.",
        "blockednoreason": "důvod nebyl zadán",
        "blockedtext-composite": "<strong>Vaše uživatelské jméno nebo IP adresa byla zablokována.</strong>\n\nUdaný důvod blokování:\n\n:<em>$2</em>\n\n* Začátek blokování: $8\n* Konec nejdelšího blokování: $6\n\nVaše současná IP adresa je $3.\nProsíme, uveďte tyto údaje při komunikaci se správci.",
+       "blockedtext-composite-reason": "Na váš účet a/nebo vaši IP adresu se vztahuje více blokování.",
        "whitelistedittext": "Pro editaci se musíte $1.",
        "confirmedittext": "Pro editaci stránek je vyžadováno potvrzení vaší e-mailové adresy.\nNa stránce [[Special:Preferences|nastavení]] zadejte a nechte potvrdit svou e-mailovou adresu.",
        "nosuchsectiontitle": "Sekce nenalezena",
index f25543d..126680d 100644 (file)
        "userrights-viewusergroup": "Grubanê {{GENDER:$1|karberi}} bıvêne",
        "saveusergroups": "Grubanê {{GENDER:$1|karberi}} qeyd bıke",
        "userrights-groupsmember": "Ezayê:",
-       "userrights-groupsmember-auto": "Ezao daxıl/ezaa daxıle ê:",
+       "userrights-groupsmember-auto": "Gum biyaye ezayiye:",
        "userrights-groups-help": "şıma şenê grubanê nê karberi/na karbere, oyo/aya ke tede, bıvurnê:\n* qutiya ke nışankerdiya, mocnena ke karber/e na grube de yo/de ya.\n* qutiya ke nışankerdiye niya, mocnena ke karber/ na grube de niyo/niya.\n* Yew estare * mocneno ke, gruba ke şıma kerda ra ser (daxıl kerda), şıma nêşenê wedarê/hewa dê ya ki dêmlaşta/tersê cı.",
        "userrights-reason": "Sebeb:",
        "userrights-no-interwiki": "Heqa şıma çıniya ke heqanê karberanê Wikipediyanê binan sero bıgureyê.",
index f447601..e8e9086 100644 (file)
        "autoblockedtext": "Sinu IP-aadress blokeeriti automaatselt, sest seda kasutas teine kasutaja, kelle $1 blokeeris.\nPõhjendus on järgmine:\n\n:<em>$2</em>\n\n* Blokeeringu algus: $8\n* Blokeeringu lõpp: $6\n* Sooviti blokeerida: $7\n\nKüsimuse arutamiseks võid pöörduda kasutaja $1 või mõne teise [[{{MediaWiki:Grouppage-sysop}}|administraatori]] poole.\n\nPane tähele, et sa ei saa kasutada funktsiooni \"{{int:emailuser}}\", kui [[Special:Preferences|konto eelistustes]] pole määratud kehtivat e-posti aadressi või kui sul on keelatud seda funktsiooni kasutada.\n\nSinu praegune IP-aadress on $3 ja blokeeringu number #$5. Palun lisa need andmed kõigile järelpärimistele, mida kavatsed teha.",
        "systemblockedtext": "MediaWiki tarkvara on sinu kasutajanime või IP-aadressi automaatselt blokeerinud.\nToodud on järgmine põhjus:\n\n:<em>$2</em>\n\n* Blokeerimisaeg: $8\n* Blokeeringu aegumistähtaeg: $6\n* Sooviti blokeerida: $7\n\nSinu praegune IP-aadress on $3.\nLisa need andmed kõigile järelepärimistele, mida kavatsed teha.",
        "blockednoreason": "põhjendust ei ole kirja pandud",
+       "blockedtext-composite": "<strong>Sinu kasutajanimi või IP-aadress on blokeeritud.</strong>\n\nÄra on toodud järgmine põhjus:\n\n:<em>$2</em>.\n\n* Blokeeringu algus: $8\n* Pikima blokeeringu aegumistähtaeg: $6\n\nSinu praegune IP-aadress on $3.\nPalun lisa need andmed kõigile järelepärimistele, mida kavatsed teha.",
+       "blockedtext-composite-reason": "Sinu IP-aadressi ja/või kasutajanime suhtes on kehtestatud mitu blokeeringut",
        "whitelistedittext": "Lehekülgede toimetamiseks pead $1.",
        "confirmedittext": "Lehekülgi ei saa toimetada enne e-posti aadressi kinnitamist.\nPalun määra ja kinnita e-posti aadress [[Special:Preferences|eelistuste leheküljel]].",
        "nosuchsectiontitle": "Sellist alaosa pole",
        "rev-delundel": "muuda nähtavust",
        "rev-showdeleted": "näita",
        "revisiondelete": "Redaktsioonide kustutamine või taastamine",
-       "revdelete-nooldid-title": "Sellist redaktsiooni pole.",
+       "revdelete-nooldid-title": "Sellist redaktsiooni pole",
        "revdelete-nooldid-text": "Sa pole valinud selle toimingu jaoks ühtegi sihtredaktsiooni, valitud redaktsioon puudub või püüad peita viimast redaktsiooni.",
        "revdelete-no-file": "Faili ei ole.",
        "revdelete-show-file-confirm": "Kas oled kindel, et soovid häha faili \"<nowiki>$1</nowiki>\" kustutatud redaktsiooni, mis tehti $2 kell $3?",
        "passwordpolicies-policyflag-suggestchangeonlogin": "soovita muutmist sisselogimisel",
        "easydeflate-invaliddeflate": "Ette antud sisu ei ole õigesti vähendatud",
        "unprotected-js": "Turvalisuse huvides ei saa JavaScripti laadida kaitsmata lehekülgedelt. Palun koosta JavaScripti ainult nimeruumis MediaWiki või kasutajate nimeruumi alamleheküljel.",
-       "userlogout-continue": "Kui soovid välja logida, siis palun [$1 mine väljalogimise leheküljele]."
+       "userlogout-continue": "Kas soovid välja logida?"
 }
index 43c77e8..c9a6fc8 100644 (file)
        "exif-iimcategory-edu": "آموختاری",
        "exif-iimcategory-evn": "زئشت گه",
        "exif-iimcategory-hth": "تن آزایی",
-       "exif-iimcategory-hum": "حاستنی انسانی",
+       "exif-iimcategory-hum": "هاستنی اْنسانی",
        "exif-iimcategory-lab": "کار",
        "exif-iimcategory-lif": "گواردن زئشت و شادی کردن",
        "exif-iimcategory-pol": "سیاستا",
index 5f0f2c9..486c908 100644 (file)
        "revdelete-unsuppress": "حذف محدودیت‌ها در بازبینی‌های ترمیم‌شده",
        "revdelete-log": "دلیل:",
        "revdelete-submit": "اعمال بر {{PLURAL:$1|نسخهٔ|نسخه‌های}} انتخاب شده",
-       "revdelete-success": "پیدایی بازنگری، روزآمد شد.",
+       "revdelete-success": "پیدایی نسخه، روزآمد شد.",
        "revdelete-failure": "'''پیدایی نسخه‌ها قابل به روز کردن نیست:'''\n$1",
        "logdelete-success": "تغییر پیدایی مورد انجام شد.",
        "logdelete-failure": "'''پیدایی سیاهه‌ها قابل تنظیم نیست:'''\n$1",
index afd803e..80c17e0 100644 (file)
        "autoblockedtext": "IP-osoitteesi on estetty automaattisesti, koska sitä on käyttänyt toinen käyttäjä, jonka on estänyt ylläpitäjä $1.\nAnnettu syy on:\n\n:<em>$2</em>\n\n* Eston alkamisaika: $8\n* Eston päättymisaika: $6\n* Kohde: $7\n\nVoit keskustella ylläpitäjän $1 tai toisen [[{{MediaWiki:Grouppage-sysop}}|ylläpitäjän]] kanssa estosta.\n\nHuomaa, ettet voi lähettää sähköpostia {{GRAMMAR:genitive|{{SITENAME}}}} kautta, ellet ole asettanut olemassa olevaa sähköpostiosoitetta [[Special:Preferences|asetuksissa]] tai jos esto on asetettu koskemaan myös sähköpostin lähettämistä.\n\nIP-osoitteesi on $3 ja estotunnus on #$5.\nLiitä kaikki yllä olevat tiedot mahdollisiin kyselyihisi.",
        "systemblockedtext": "Käyttäjätunnuksesi tai IP-osoitteesi on automaattisesti estetty MediaWikin toimesta.\nAnnettu syy on:\n\n:<em>$2</em>\n\n* Start of block: $8\n* Expiration of block: $6\n* Intended blockee: $7\n\nTämänhetkinen IP-osoitteesi on $3.\nOle hyvä ja liitä kaikki yllä olevat tiedot mahdollisiin kyselyihisi.",
        "blockednoreason": "(syytä ei annettu)",
+       "blockedtext-composite": "<strong>Käyttäjätunnuksesi tai IP-osoitteesi on estetty.</strong>\n\nAnnettu syy on:\n\n:<em>$2</em>.\n\n* Esto alkoi: $8\n* Pisin esto vanhentuu: $6\n\nTämänhetkinen IP-osoitteesi on $3.\nOle hyvä ja liitä kaikki yllä olevat tiedot mahdollisiin kyselyihisi.",
        "whitelistedittext": "Sinun täytyy $1, jotta voisit muokata sivuja.",
        "confirmedittext": "Et voi muokata sivuja, ennen kuin olet varmentanut sähköpostiosoitteesi. Voit tehdä varmennuksen [[Special:Preferences|asetussivulla]].",
        "nosuchsectiontitle": "Pyydettyä osiota ei ole",
        "blocklink": "estä",
        "unblocklink": "poista esto",
        "change-blocklink": "muuta estoa",
+       "empty-username": "(käyttäjää ei saatavissa)",
        "contribslink": "muokkaukset",
        "emaillink": "lähetä sähköpostia",
        "autoblocker": "Olet automaattisesti estetty, koska jaat IP-osoitteen käyttäjän [[User:$1|$1]] kanssa. \nKäyttäjän $1 saaman eston syy on: ”$2”.",
        "restrictionsfield-help": "Yksi IP-osoite tai CIDR-alue per rivi. Ottaaksesi kaiken käyttöön, käytä:<pre>0.0.0.0/0\n::/0</pre>",
        "edit-error-short": "Virhe: $1",
        "edit-error-long": "Virheet:\n\n$1",
+       "specialmute": "Vaimenna",
+       "specialmute-success": "Vaimennusasetuksesi on päivitetty. Näet kaikki vaimennetut käyttäjät [[Special:Preferences|asetuksistasi]].",
+       "specialmute-submit": "Vahvista",
+       "specialmute-label-mute-email": "Vaimenna sähköpostit tältä käyttäjältä",
+       "specialmute-header": "Valitse vaimennusasetuksesi käyttäjälle {{BIDI:[[User:$1]]}}.",
+       "specialmute-error-invalid-user": "Pyydettyä käyttäjänimeä ei löydy.",
+       "specialmute-error-email-blacklist-disabled": "Sähköpostin lähettämistä käyttäjiltä ei ole vaimennettu.",
+       "specialmute-error-email-preferences": "Sinun täytyy vahvistaa sähköpostiosoitteesi ennen kuin voit vaimentaa käyttäjän. Voit tehdä sen sivulta [[Special:Preferences]].",
+       "specialmute-email-footer": "Hallitaksesi sähköpostiasetuksia käyttäjälle {{BIDI:$2}}, käy sivulla <$1>.",
+       "specialmute-login-required": "Kirjaudu sisään muuttaaksesi vaimentamisasetuksiasi.",
        "revid": "versio $1",
        "pageid": "sivun tunnistenumero $1",
        "interfaceadmin-info": "$1\n\nSivustonlaajuisten CSS/JS/JSON-tiedostojen muokkaamisoikeus erotettiin äskettäin <code>editinterface</code>-oikeudesta. Jos et ymmärrä, miksi saat tämän virheen, katso [[mw:MediaWiki_1.32/interface-admin]].",
index 862e281..698d3b5 100644 (file)
        "edit-error-short": "Erreur : $1",
        "edit-error-long": "Erreurs :\n\n$1",
        "specialmute": "Muet",
-       "specialmute-success": "Vos préférences de mise en sourdine on bien été mises à jour. Voyez tous les utilisateurs impliqués dans [[Special:Preferences]].",
+       "specialmute-success": "Vos préférences de mise en sourdine on été mises à jour. Voyez tous les utilisateurs impliqués dans [[Special:Preferences|vos préférences]].",
        "specialmute-submit": "Confirmer",
        "specialmute-label-mute-email": "Mettre en sourdine les courriels de cet utilisateur",
        "specialmute-header": "Veuillez sélectionner vos préférences de mise en sourdine pour {{BIDI:[[User:$1]]}}.",
index 46b48e2..7fc5b45 100644 (file)
        "autoblockedtext": "O seu enderezo IP foi bloqueado automaticamente porque foi empregado por outro usuario que foi bloqueado por $1.\nA razón que deu foi a seguinte:\n\n:<em>$2</em>\n\n* Inicio do bloqueo: $8\n* Caducidade do bloqueo: $6\n* Pretendeuse bloquear: $7\n\nPode contactar con $1 ou con calquera outro [[{{MediaWiki:Grouppage-sysop}}|administrador]] para discutir este bloqueo.\n\nTeña en conta que non pode empregar a característica \"{{int:emailuser}}\" a non ser que dispoña dun enderezo electrónico válido rexistrado nas súas [[Special:Preferences|preferencias de usuario]] e e que o seu uso non fose bloqueado.\n\nO seu enderezo IP actual é $3 e o ID do bloqueo é #$5.\nPor favor, inclúa eses datos nas consultas que faga.",
        "systemblockedtext": "O seu nome de usuario ou enderezo IP foi bloqueado automaticamente polo sistema MediaWiki.\nO motivo do bloqueo é:\n\n:<em>$2</em>\n\n* Comezo do bloqueo: $8\n* Expiración do bloqueo: $6\n* Destinatario do bloqueo: $7\n\nO seu enderezo IP actual é $3.\nPor favor, inclúa todos estes detalles en calquera consulta que realice.",
        "blockednoreason": "non se deu ningunha razón",
+       "blockedtext-composite": "<strong>O seu nome de usuario ou enderezo IP foron bloqueados.</strong>\n\nO motivo dado é:\n\n:<em>$2</em>.\n\n* Comezo do bloqueo: $8\n* Remate do bloqueo máis longo: $6\n\nO seu enderezo IP actual é $3.\nPor favor, inclúa todos os detalles de arriba en calquera contacto sobre este asunto.",
+       "blockedtext-composite-reason": "Existen varios bloqueos contra a súa conta ou enderezo IP",
        "whitelistedittext": "Debe $1 para poder editar páxinas.",
        "confirmedittext": "Debe confirmar o correo electrónico antes de comezar a editar. Por favor, configure e dea validez ao correo mediante as súas [[Special:Preferences|preferencias de usuario]].",
        "nosuchsectiontitle": "Non se pode atopar a sección",
        "action-unblockself": "desbloquearse a si mesmo",
        "action-noratelimit": "non estar afectado polos límites de frecuencia",
        "action-reupload-own": "sobrescribir ficheiros existentes cargados por un mesmo",
+       "action-nominornewtalk": "non lanzar o aviso de mensaxes novas ó facer edicións menores en páxinas de conversa",
        "action-markbotedits": "marcar as reversións como edicións de bot",
        "action-patrolmarks": "ver as marcas de vixilancia de cambios recentes",
        "action-override-export-depth": "exportar páxinas, incluídas aquelas ligadas ata unha profundidade de 5",
        "restrictionsfield-help": "Un único enderezo IP ou rango CIDR por liña. Para habilitalos todos, utiliceː\n<pre>0.0.0.0/0\n::/0</pre>",
        "edit-error-short": "Erro: $1",
        "edit-error-long": "Erros:\n\n$1",
+       "specialmute": "Silenciar",
+       "specialmute-success": "As súas preferencias de silenciamento foron actualizadas. Ver todos os usuarios silenciados en [[Special:Preferences]].",
+       "specialmute-submit": "Confirmar",
+       "specialmute-label-mute-email": "Silenciar os correos electrónicos deste usuario",
+       "specialmute-header": "Por favor, seleccione as súas preferencias de silenciamento para {{BIDI:[[User:$1]]}}.",
+       "specialmute-error-invalid-user": "Non se atopou o nome de usuario indicado.",
+       "specialmute-error-email-blacklist-disabled": "O silenciamento de usuario para impedir que lle envíen correos electrónicos non está activado.",
+       "specialmute-error-email-preferences": "Debe confirmar o seu enderezo de correo electrónico antes de poder silenciar a un usuario. Pode facelo en [[Special:Preferences]].",
+       "specialmute-email-footer": "Para xestionar as preferencias de correo electrónico de {{BIDI:$2}}, por favor,  visite <$1>.",
+       "specialmute-login-required": "Por favor, inicie sesión para alterar as súas preferencias de silenciamento.",
        "revid": "revisión $1",
        "pageid": "identificador de páxina $1",
        "interfaceadmin-info": "$1\n\nOs permisos para editar os ficheiros CSS/JS/JSON globais separáronse recentemente do dereito <code>editinterface</code>. Se non comprende porqué está vendo este erro, vexa [[mw:MediaWiki_1.32/interface-admin]].",
        "passwordpolicies-policyflag-suggestchangeonlogin": "suxerir cambio ó iniciar sesión",
        "easydeflate-invaliddeflate": "O contido fornecido non está debidamente comprimido",
        "unprotected-js": "Por motivos de seguridade non se pode cargar JavaScript desde páxinas non protexidas. Por favor, cree só JavaScript no espazo de nomes MediaWiki ou como subpáxina de usuario",
-       "userlogout-continue": "Se quere pechar a sesión, por favor, [$1 continúe á páxina de peche de sesión]."
+       "userlogout-continue": "Quere rematar a sesión?"
 }
index 5389289..491c771 100644 (file)
        "edit-error-short": "שגיאה: $1",
        "edit-error-long": "שגיאות:\n\n$1",
        "specialmute": "השתקה",
+       "specialmute-success": "העדפות ההשתקה שלך עודכנו. ר' את כל המשתמשים המושתקים ב[[Special:Preferences|העדפות שלך]].",
+       "specialmute-submit": "אישור",
+       "specialmute-label-mute-email": "להשתיק דואר אלקטרוני מהמשתמש הזה",
+       "specialmute-header": "נא לבחור את העדפות ההשתקה שלך עבור {{BIDI:[[User:$1]]}}.",
+       "specialmute-error-invalid-user": "שם המשתמש המבוקש לא נמצא.",
+       "specialmute-error-email-blacklist-disabled": "השתקת משתמשים משליחת דואר אלקטרוני אליך אינה מופעלת.",
+       "specialmute-error-email-preferences": "יש לאמת את כתובת הדואר האלקטרוני שלך לפני שתהיה לך אפשרות להשתיק משתמש. אפשר לעשות זאת מהדף [[Special:Preferences]].",
+       "specialmute-email-footer": "כדי לנהל את ההעדפות עבור {{BIDI:$2}} נא לבקר בדף <$1>.",
+       "specialmute-login-required": "נא להיכנס לחשבון כדי לשבות את העדפות ההשתקה שלך.",
        "revid": "גרסה $1",
        "pageid": "מזהה דף $1",
        "interfaceadmin-info": "$1\n\nההרשאות לעריכת קובצי CSS/JS/JSON של האתר כולו הופרדו לאחרונה מההרשאה <code>editinterface</code>. אם לא ברור לך מדוע קיבלת את הודעת השגיאה הזאת, ר' [[mw:MediaWiki_1.32/interface-admin]].",
index b05a311..e5d0156 100644 (file)
        "group-sysop": "Վարիչներ",
        "group-interface-admin": "Թեքնիկական hամակարգողներ",
        "group-sysop-member": "{{GENDER:$1|վարիչ}}",
+       "group-interface-admin-member": "{{GENDER:$1|թեքնիկական hամակարգող}}",
        "grouppage-bot": "{{ns:project}}:Մեքենայիկներ",
        "grouppage-sysop": "{{ns:project}}:Վարիչներ",
        "right-writeapi": "API գիրի օգտագործումը",
        "pageinfo-contentpage-yes": "Այո",
        "pageinfo-protect-cascading-yes": "Այո",
        "patrol-log-page": "Հսկողութեան տեղեկատետր",
+       "confirm-markpatrolled-button": "Լաւ",
        "previousdiff": "← Նախորդ խմբագրում",
        "nextdiff": "Յաջորդ խմբագրում →",
        "widthheightpage": "$1 × $2, $3 {{PLURAL:$3|էջ}}",
        "metadata-fields": "Այս գիրին մէջ նշուած պատկերի անդրտուեալներու դաշտերը պիտի երեւին պատկերի էջին վրայ երբ անդրտուեալներու աղիւսակը ծալլուի։\nՄիւսները ակամայ կը մնան թաքուն։\n* make\n* model\n* datetimeoriginal\n* exposuretime\n* fnumber\n* isospeedratings\n* focallength\n* artist\n* copyright\n* imagedescription\n* gpslatitude\n* gpslongitude\n* gpsaltitude",
        "namespacesall": "բոլոր",
        "monthsall": "բոլոր",
+       "confirm_purge_button": "Լաւ",
        "imgmultipagenext": "յաջորդ էջը →",
        "imgmultigo": "Անցնի՛լ",
        "imgmultigoto": "Անցնիլ $1 էջը",
index 8fdd0d7..a8c88a5 100644 (file)
        "history": "Breytingaskrá síðu",
        "history_short": "Breytingaskrá",
        "history_small": "breytingaskrá",
-       "updatedmarker": "uppfært frá síðustu heimsókn minni",
+       "updatedmarker": "uppfært frá síðustu heimsókn þinni",
        "printableversion": "Prentvæn útgáfa",
        "permalink": "Varanlegur tengill",
        "print": "Prenta",
        "page_first": "fyrsta",
        "page_last": "síðasta",
        "histlegend": "Mismunarval: merktu við einvalshnappanna fyrir þær útgáfur sem á að bera saman og styddu svo á færsluhnappinn.<br />\nSkýringartexti: (nú) = skoðanamunur á núverandi útgáfu,\n(síðast) = skoðanamunur á undanfarandi útgáfu, M = minniháttar breyting.",
-       "history-fieldset-title": "Skoða breytingaskrá",
+       "history-fieldset-title": "Sía breytingar",
        "history-show-deleted": "Eingöngu eyddar breytingar",
        "histfirst": "elstu",
        "histlast": "nýjustu",
        "historysize": "({{PLURAL:$1|1 bæti|$1 bæti}})",
-       "historyempty": "(tóm)",
+       "historyempty": "tóm",
        "history-feed-title": "Breytingaskrá",
        "history-feed-description": "Breytingaskrá fyrir þessa síðu á wiki-síðunni",
        "history-feed-item-nocomment": "$1 á $2",
        "right-reupload-own": "Yfirrita fyrirliggjandi skrár sem að ég hlóð inn sjálf(ur)",
        "right-reupload-shared": "Hunsa skrár á sameiginlegu myndasafni staðbundið",
        "right-upload_by_url": "Hlaða inn skrám af vefslóð",
-       "right-purge": "Hreinsa skyndiminni síðu án staðfestingar",
+       "right-purge": "Hreinsa skyndiminni vefþjónsins fyrir síðuna",
        "right-autoconfirmed": "Sneiða hjá takmörkunum vistfanga",
        "right-bot": "Eru meðhöndlaðir eins og sjálfvirk aðgerð",
        "right-nominornewtalk": "Ekki láta minniháttar breytingar á spjallsíðum kveða upp áminningu um ný skilaboð",
        "rcfilters-savedqueries-already-saved": "Þessar síur hafa þegar verið vistaðar. Breyttu þínum stillingum til þess að búa til nýja vistaða síu.",
        "rcfilters-restore-default-filters": "Endurreisa sjálfgefnar síur",
        "rcfilters-clear-all-filters": "Hreinsa allar síur",
-       "rcfilters-show-new-changes": "Skoða nýjustu breytingarnar",
+       "rcfilters-show-new-changes": "Skoða nýjustu breytingar síðan $1",
        "rcfilters-search-placeholder": "Sía breytingar (notaðu valmyndina eða leitaðu að síuheiti)",
        "rcfilters-invalid-filter": "Ógild sía",
        "rcfilters-empty-filter": "Engar virkar síur. Öll framlög eru sýnileg.",
        "delete-confirm": "Eyða „$1“",
        "delete-legend": "Eyða",
        "historywarning": "<strong>Viðvörun:</strong> Síðan sem þú ert um það bil að eyða hefur breytingaskrá með $1 {{PLURAL:$1|breytingu|breytingum}}:",
-       "historyaction-submit": "Birta",
+       "historyaction-submit": "Birta breytingar",
        "confirmdeletetext": "Þú ert um það bil að eyða síðu ásamt breytingaskrá hennar.\nStaðfestu það að þú ætlir að gera svo, það að þú skiljir afleiðingarnar, og að þú sért að gera þetta í samræmi við [[{{MediaWiki:Policy-url}}|samþykktir]].",
        "actioncomplete": "Aðgerð lokið",
        "actionfailed": "Aðgerð mistókst",
        "blocklist-editing-page": "síður",
        "blocklist-editing-ns": "nafnrými",
        "ipblocklist-empty": "Bannlistinn er tómur.",
-       "ipblocklist-no-results": "Umbeðið vistfang eða notandanafn er ekki í banni.",
+       "ipblocklist-no-results": "Engin samsvarandi bönn fundust fyrir umbeðið vistfang eða notandanafn.",
        "blocklink": "banna",
        "unblocklink": "afbanna",
        "change-blocklink": "breyta bönnun",
        "autosumm-replace": "Skipti út innihaldi með „$1“",
        "autoredircomment": "Tilvísun á [[$1]]",
        "autosumm-removed-redirect": "Fjarlægði endurbeiningu á [[$1]]",
+       "autosumm-changed-redirect-target": "Breytti tilvísun frá [[$1]] til [[$2]]",
        "autosumm-new": "Ný síða: $1",
        "autosumm-newblank": "Bjó til tóma síðu",
        "size-bytes": "$1 {{PLURAL:$1|bæt|bæti}}",
        "logentry-rights-autopromote": "$1 fékk sjálfvirkt {{GENDER:$2|aukin}} réttindi frá $4 til $5",
        "logentry-upload-upload": "$1 {{GENDER:$2|hlóð inn}} $3",
        "logentry-upload-overwrite": "$1 {{GENDER:$2|hlóð inn}} nýrri útgáfu af $3",
-       "logentry-upload-revert": "$1 {{GENDER:$2|hlóð inn}} $3",
+       "logentry-upload-revert": "$1 {{GENDER:$2|tók til baka}} $3 til eldri útgáfu",
        "log-name-managetags": "Breytingaskrá yfir sýsl með merki",
        "logentry-managetags-create": "$1 {{GENDER:$2|bjó til}} merkið \"$4\"",
        "rightsnone": "(engum)",
index 0276645..7879fce 100644 (file)
@@ -96,7 +96,8 @@
                        "고솜",
                        "Wat",
                        "Puntti ja",
-                       "マツムシ"
+                       "マツムシ",
+                       "神樂坂秀吉"
                ]
        },
        "tog-underline": "リンクの下線:",
        "search-interwiki-more-results": "結果をさらに取得",
        "search-relatedarticle": "関連",
        "searchrelated": "関連",
-       "searchall": "すべて",
+       "searchall": "て",
        "showingresults": "<strong>$2</strong> 件目以降の最大 {{PLURAL:$1|<strong>$1</strong> 件の結果}}を表示しています。",
        "showingresultsinrange": "<strong>$2</strong> 件目から<strong>$3</strong> 件目までの範囲内で最大 {{PLURAL:$1|<strong>$1</strong> 件の結果}}を表示しています。",
        "search-showingresults": "{{PLURAL:$4|<strong>$3</strong> 件中の <strong>$1</strong> 件目|<strong>$3</strong> 件中の <strong>$1</strong> 件目から <strong>$2</strong> 件目}}",
        "powersearch-ns": "名前空間を指定して検索:",
        "powersearch-togglelabel": "チェックを入れる:",
        "powersearch-toggleall": "すべて",
-       "powersearch-togglenone": "すべて外す",
+       "powersearch-togglenone": "て外す",
        "powersearch-remember": "この選択を今後の検索のために記憶させる",
        "search-external": "外部検索",
        "searchdisabled": "{{SITENAME}}の検索機能は無効化されています。\nさしあたってはGoogleなどで検索できます。\nただし外部の検索エンジンの索引にある{{SITENAME}}のコンテンツは古い場合があります。",
index 370d98e..f5ca1fe 100644 (file)
@@ -18,7 +18,8 @@
                        "Macofe",
                        "Dcljr",
                        "Aefgh39622",
-                       "Vlad5250"
+                       "Vlad5250",
+                       "Y.snsqr"
                ]
        },
        "tog-underline": "គូសបន្ទាត់ក្រោម​តំណភ្ជាប់៖",
        "hist": "ប្រវត្តិ",
        "hide": "លាក់",
        "show": "បង្ហាញ",
-       "minoreditletter": "តិច",
+       "minoreditletter": "ត",
        "newpageletter": "ថ្មី",
-       "boteditletter": "យន្ត",
+       "boteditletter": "យ",
        "rc-change-size": "$1",
        "rc-change-size-new": "$1 {{PLURAL:$1|បៃ|បៃ}} បន្ទាប់ពីបន្លាស់ប្ដូរ",
        "newsectionsummary": "/* $1 */ ផ្នែកថ្មី",
        "rc-old-title": "បង្កើតឡើងដំបូងដោយ «$1»",
        "recentchangeslinked": "បន្លាស់ប្ដូរពាក់ព័ន្ធ",
        "recentchangeslinked-feed": "បន្លាស់ប្ដូរពាក់ព័ន្ធ",
-       "recentchangeslinked-toolbox": "បន្លាស់ប្ដូរពាក់ព័ន្ធ",
+       "recentchangeslinked-toolbox": "á\9e\94á\9e\93á\9f\92á\9e\9bá\9e¶á\9e\9fá\9f\8bá\9e\94á\9f\92á\9e\8aá\9e¼á\9e\9aá\9e\8aá\9f\82á\9e\9bá\9e\96á\9e¶á\9e\80á\9f\8bá\9e\96á\9f\90á\9e\93á\9f\92á\9e\92",
        "recentchangeslinked-title": "បន្លាស់ប្ដូរ​ពាក់ព័ន្ធនឹង «$1»",
        "recentchangeslinked-summary": "នេះជាបញ្ជីបន្លាស់ប្ដូរនានា ដែលត្រូវបានធ្វើឡើងនៅលើទំព័រទាំងឡាយ ដែលមានតំណភ្ជាប់ពីទំព័រកំណត់មួយ(ឬ មានតំណភ្ជាប់ទៅទំព័រ ដែលមានក្នុងចំណាត់ថ្នាក់ក្រុមណាមួយ) នាពេលថ្មីៗនេះ ។ ទំព័រ​នានាក្នុង[[Special:Watchlist|បញ្ជីតាមដាន​របស់អ្នក]]ត្រូវបានសរសេរជា '''អក្សរដិត''' ។",
        "recentchangeslinked-page": "ឈ្មោះទំព័រ៖",
        "tooltip-t-contributions": "បញ្ជីនៃការរួមចំណែករបស់{{GENDER:$1|អ្នកប្រើប្រាស់នេះ}}",
        "tooltip-t-emailuser": "ផ្ញើអ៊ីមែលទៅកាន់{{GENDER:$1|អ្នកប្រើប្រាស់នេះ}}",
        "tooltip-t-info": "ព័ត៌មានបន្ថែមអំពីទំព័រនេះ",
-       "tooltip-t-upload": "á\9e¯á\9e\80á\9e\9fá\9e¶á\9e\9aá\9e\95á\9f\92á\9e\91á\9e»á\9e\80ឡើង",
-       "tooltip-t-specialpages": "á\9e\94á\9e\89á\9f\92á\9e\87á\9e¸á\9e\91á\9f\86á\9e\96á\9f\90á\9e\9aá\9e\96á\9e·á\9e\9fá\9f\81á\9e\9fá\9f\97á\9e\91á\9e¶á\9f\86á\9e\84á\9e\98á\9e¼á\9e\9b",
+       "tooltip-t-upload": "á\9e\95á\9f\92á\9e\91á\9e»á\9e\80á\9e¯á\9e\80á\9e\9fá\9e¶á\9e\9aឡើង",
+       "tooltip-t-specialpages": "á\9e\94á\9e\89á\9f\92á\9e\87á\9e¸á\9e\93á\9f\83á\9e\91á\9f\86á\9e\96á\9f\90á\9e\9aá\9e\96á\9e·á\9e\9fá\9f\81á\9e\9fá\9e\91á\9e¶á\9f\86á\9e\84á\9e¢á\9e\9fá\9f\8b",
        "tooltip-t-print": "ទម្រង់សម្រាប់បោះពុម្ភរបស់ទំព័រនេះ",
        "tooltip-t-permalink": "តំណភ្ជាប់អចិន្ត្រៃយ៍ដែលភ្ជាប់មកកំណែនៃទំព័រនេះ",
        "tooltip-ca-nstab-main": "មើលទំព័រមាតិកា",
index 2a90040..c8c8e15 100644 (file)
        "cantcreateaccount-text": "هساو دۏرس بیٱ ڤا اؽ تیرنشوݩ آی پی(<strong>$1</strong>) ڤ دٱس اؽ [[کاریار:$3|$3]] قلف بیٱ.\n\n\nدلیل دئه بیه وا $3 ها د<em>$2</em>",
        "cantcreateaccount-range-text": "حساو دروس بیه وا تیرنشون آی پی که د پوشینه <strong>$1</strong> ، که وه ئم مینونه دار تیرنشون آی پی شما ئم هئ(<strong>$4</strong>)، وه دس [[کاریار:$3|$3]]قلف بیه.\n\nدلیل دئه بیه وا $3، \"$2\" ئه.",
        "viewpagelogs": "ساٛلٛ پهرستنومٱیا اؽ بٱلگٱ بٱکؽت",
-       "nohistory": "Ù\87Û\8cÚ\86 Ù\88Û\8cرگار Ù\88Û\8cراÛ\8cشتÛ\8c Ø¯ Ø§Û\8c Ø¨Ù\84Ú¯Ù\87 Ù\86ئ.",
-       "currentrev": "آخرین دوواره دیئن",
+       "nohistory": "Ù\87Û\8cÚ\98 Ú¤Û\8cرگار Ú¤Û\8cراÛ\8cشتÛ\8c Ø¯ Ø§Ø½ Ø¨Ù±Ù\84Ú¯Ù± Ù\86ؽ.",
+       "currentrev": "آخری دوئارٱ دیئن",
        "currentrev-asof": "آخری ڤانری چی $1",
        "revisionasof": "دوئرٱ دیئن $1",
        "revision-info": "دوئارٱ ساٛلٛ بیٱ چی $1 ڤا $2",
        "cur": "تازٱ بۊ",
        "next": "نئهایی",
        "last": "دمایی",
-       "page_first": "أڤئلی",
-       "page_last": "آخئر",
+       "page_first": "ٱڤلی",
+       "page_last": "آخر",
        "histlegend": "اْنتخاب فٱرخدار:جٱڤٱیا رادیو ناْ سی دوئارٱ دیئن ۉ ڤارسی نشوݩ دار بٱکؽت ۉ یا ری رٱتن کلٛیک بٱکؽت .<br />\nتۉسیف نڤیسٱ: '''({{int:cur}})''' = ڤا آخری دوئارٱ دیئن فٱرخ دارٱ '''({{ int:last}})'''= ڤا دوئارٱ دیئن ٱنجوم داٛئنی فٱرخ دارٱ  '''{{int:minoreditletter}}''' =ڤیرایش کوچک.",
        "history-fieldset-title": "ڤیرگار دوئارٱ نیٱری",
        "history-show-deleted": "فقط پاكسا بيه",
        "histfirst": "قاٛیمی تریݩ",
        "histlast": "ایسنی تریݩ",
-       "historysize": "({{PLURAL:$1|1 بایت|$1 بایتیا}})",
+       "historysize": "({{PLURAL:$1|1 بایت|$1 بایتؽا}})",
        "historyempty": "(حالی)",
        "history-feed-title": "ڤیرگار دوئارٱ دیئن",
        "history-feed-description": "دوئارٱ دیئن ڤیرگار سی بٱلگٱ د ڤیکی",
        "history-feed-item-nocomment": "$1 د\n$2",
-       "history-feed-empty": "بÙ\84Ú¯Ù\87 Ø­Ø§Ø³ØªÙ\87 Ø¨Û\8cÙ\87 Ù\88جÙ\88د Ù\86ارÙ\87.\nشاÛ\8cت Ù\88Ù\87 Ø¯ Ù\88Û\8cÚ©Û\8c Ù¾Ø§Ú©Ø³Ø§ Ø¨Û\8cÙ\87Ø\8c Û\8cا Ù\86Ù\88Ù\85Ø´ Ø¢Ù\84شت Ø¨Û\8cÙ\87.\nسÛ\8c Ø¨Ù\84Ú¯Û\8cا Ù\85رتÙ\88Ø· ØªØ§Ø²Ù\87 [[Ù\88Û\8cجÙ\87:Ù¾Û\8c Ø¬Ù\88رÛ\8c|Ù¾Û\8c Ø¬Ù\88رÛ\8c Ø¯ Ù\88Û\8cÚ©Û\8c]] Ú©Ù\88ششت Ø¨Ú©Û\8cد.",
-       "history-edit-tags": "Ú¤Û\8cراÛ\8cئشت Ú©Ø§Ø±Û\8c Ú¤Ø§Ù\86ئÛ\8cأرÛ\8cا Ú¯Ù\88Ù\84ئ Ú¤Ù\88رÚ\86Û\8c Ø¨Û\8cÛ\8cÛ\95",
-       "rev-deleted-comment": "(ویرایشت چکسته جا وه جا بیه)",
-       "rev-deleted-user": "(نوم کاروری جا وه جا بیه)",
-       "rev-deleted-event": "(انجوم گر پهرستنومه جا وه جا بیه)",
-       "rev-deleted-user-contribs": "[نوم کاریاری یا تیرنشون آی پی جا وه جا بیه - چیا قام بیه د ور هوم یاریانه ویرایشت بکید]",
-       "rev-deleted-text-permission": "وانئری ای بلگه <strong>پاکسا بیه</strong>.\nجزئیات هان د  [{{fullurl:{{#Special:Log}}/پاکسا کردن|بلگه={{نوم کامل بلگه}}}} پهرستنومه پاکساکردن].",
-       "rev-suppressed-text-permission": "وانئری بلگه <strong>پاکساگری</strong>.\nجزئیات هان د  [{{fullurl:{{#Special:Log}}/پاکساگری کردن|بلگه={{نوم کامل بلگه}}}} پهرستنومه پاکساگری کردن].",
-       "rev-deleted-text-unhide": "وانئری ای بلگه <strong>پاکسا بیه</strong>.\nجزئیات هان د  [{{fullurl:{{#Special:Log}}/پاکسا کردن|بلگه={{نوم کامل بلگه}}}} پهرستنومه پاکساکردن].\nشما  هنی تونیت [$1ای وانئری نه بونیت] ار بهاییت.",
-       "rev-suppressed-text-unhide": "وانئری بلگه <strong>پاکساگری</strong>.\nجزئیات هان د  [{{fullurl:{{#Special:Log}}/پاکساگری کردن|بلگه={{نوم کامل بلگه}}}} پهرستنومه پاکساگری کردن].\nشما  هنی تونیت [$1ای وانئری نه بونیت] ار بهاییت.",
-       "rev-deleted-text-view": "وانئری ای بلگه <strong>پاکسا بیه</strong>.\nجزئیات هان د  [{{fullurl:{{#Special:Log}}/پاکسا کردن|بلگه={{نوم کامل بلگه}}}} پهرستنومه پاکساکردن].",
-       "rev-suppressed-text-view": "وانئری بلگه <strong>پاکساگری</strong>.\nجزئیات هان د  [{{fullurl:{{#Special:Log}}/پاکساگری کردن|بلگه={{نوم کامل بلگه}}}} پهرستنومه پاکساگری کردن].",
-       "rev-deleted-no-diff": "شما نمی تونیت ای فرخ نه بونیت سی یه که یه گل د وانئریا <strong>پاکسا بیه</strong>.\nجزئیات هان د  [{{fullurl:{{#Special:Log}}/پاکساگری کردن|بلگه={{نوم کامل بلگه}}}} پهرستنومه پاکساگری کردن].",
-       "rev-suppressed-no-diff": "شما نمی تونیت ای فرخ نه بونیت سی یه که یه گل د وانئریا <strong>پاکسا بیه</strong>.",
-       "rev-deleted-unhide-diff": "وانئری ای بلگه <strong>پاکسا بیه</strong>.\nجزئیات هان د  [{{fullurl:{{#Special:Log}}/پاکسا کردن|بلگه={{نوم کامل بلگه}}}} پهرستنومه پاکساکردن].\nشما  هنی تونیت [$1ای وانئری نه بونیت] ار بهاییت.",
-       "rev-suppressed-unhide-diff": "وانئری ای بلگه <strong>پاکساگری بیه</strong>.\nجزئیات هان د  [{{fullurl:{{#Special:Log}}/پاکساگری کردن|بلگه={{نوم کامل بلگه}}}} پهرستنومه پاکساگری کردن].\nشما  هنی تونیت [$1ای وانئری نه بونیت] ار بهاییت.",
-       "rev-deleted-diff-view": "وانئری ای بلگه <strong>پاکسا بیه</strong>.\nجزئیات هان د  [{{fullurl:{{#Special:Log}}/پاکسا کردن|بلگه={{نوم کامل بلگه}}}} پهرستنومه پاکساکردن].",
-       "rev-suppressed-diff-view": "وانئری بلگه <strong>پاکساگری</strong>.\nجزئیات هان د  [{{fullurl:{{#Special:Log}}/پاکساگری کردن|بلگه={{نوم کامل بلگه}}}} پهرستنومه پاکساگری کردن].",
+       "history-feed-empty": "بٱÙ\84Ú¯Ù± Ù\87استٱ Ø¨Û\8cÙ± Ú¤Ù\88جÛ\8aد Ù\86ارٱ.\nشاÛ\8cٱد Ú¤Ù± Ø¯ Ú¤Û\8cÚ©Û\8c Ù¾Ø§Ú©Ø³Ø§ Ø¨Û\8cÙ±Ø\8c Û\8cا Ù\86Ù\88Ù\85Ø´ Ø¢Ù\84شت Ø¨Û\8cÙ±.\nسÛ\8c Ø¨Ù±Ù\84Ú¯Û\8cا Ù\85Ù\88رتٱبت ØªØ§Ø²Ù± [[Ú¤Û\8cÚ\98Ù±:پاÙ\9b Ø¬Û\8aرÛ\8c|پاÙ\9b Ø¬Û\8aرÛ\8c Ø¯ Ú¤Û\8cÚ©Û\8c]] ØªÙ±Ù\81رٱ Ø¨Ù±Ú©Ø½Øª.",
+       "history-edit-tags": "Ú¤Û\8cراÛ\8cØ´ Ú©Ø§Ø±Û\8c Ú¤Ø§Ù\86Û\8cٱرÛ\8cا Ú¯Ù\84Ù\9bٱڤرÚ\86Û\8c Ø¨Û\8cÙ±",
+       "rev-deleted-comment": "(ڤیرایش چکسٱ جا ڤ جا بیٱ)",
+       "rev-deleted-user": "(نوم کاریاری جا ڤ جا بیٱ)",
+       "rev-deleted-event": "(ٱنجوم گر پهرستنومٱ جا ڤ جا بیٱ)",
+       "rev-deleted-user-contribs": "[نوم کاریاری یا تیرنشوݩ آی پی جا ڤ جا بیٱ - چیا قام بیٱ د ڤٱر هوم یاریانٱ ڤیرایش بٱکؽت]",
+       "rev-deleted-text-permission": "ڤانری اؽ بٱلگٱ <strong>پاکسا بیٱ</strong>.\nجۏزییات هان د  [{{fullurl:{{#Special:Log}}/پاکسا کردن|بٱلگٱ={{نوم کامل بٱلگٱ}}}} پهرستنومٱ پاکساکردن].",
+       "rev-suppressed-text-permission": "ڤانری بٱلگٱ <strong>پاکساگری</strong>.\nجۏزییات هان د  [{{fullurl:{{#Special:Log}}/پاکساگری کردن|بٱلگٱ={{نوم کامل بٱلگٱ}}}} پهرستنومٱ پاکساگری کردن].",
+       "rev-deleted-text-unhide": "ڤانری اؽ بٱلگٱ <strong>پاکسا بیه</strong>.\nجۏزییات هان د  [{{fullurl:{{#Special:Log}}/پاکسا کردن|بٱلگٱ={{نوم کامل بٱلگٱ}}}} پهرستنومٱ پاکساکردن].\nشما  هنی مؽتونؽت [$1اؽ ڤانری ناْ بونؽت] ٱر بهایؽت.",
+       "rev-suppressed-text-unhide": "ڤانری بٱلگٱ <strong>پاکساگری</strong>.\nجۏزییات هان د  [{{fullurl:{{#Special:Log}}/پاکساگری کردن|بٱلگٱ={{نوم کامل بٱلگٱ}}}} پهرستنومٱ پاکساگری کردن].\nشما هنی مؽتونؽت [$1اؽ ڤانری ناْ بونؽت] ٱر بهایؽت.",
+       "rev-deleted-text-view": "ڤانری اؽ بٱلگٱ <strong>پاکسا بیه</strong>.\nجۏزییات هان د  [{{fullurl:{{#Special:Log}}/پاکسا کردن|بٱلگٱ={{نوم کامل بٱلگٱ}}}} پهرستنومٱ پاکساکردن].",
+       "rev-suppressed-text-view": "ڤانری بٱلگٱ <strong>پاکساگری</strong>.\nجۏزییات هان د  [{{fullurl:{{#Special:Log}}/پاکساگری کردن|بٱلگٱ={{نوم کامل بٱلگٱ}}}} پهرستنومٱ پاکساگری کردن].",
+       "rev-deleted-no-diff": "شما نمؽ تونؽت اؽ فٱرخ ناْ بونؽت سی یٱ کاْ یٱکؽ د ڤانریا <strong>پاکسا بیٱ</strong>.\nجۏزییات هان د  [{{fullurl:{{#Special:Log}}/پاکساگری کردن|بٱلگٱ={{نوم کامل بٱلگٱ}}}} پهرستنومٱ پاکساگری کردن].",
+       "rev-suppressed-no-diff": "شما نمؽ تونؽت اؽ فٱرخ ناْ بونؽت سی یٱ کاْ یٱکؽ د ڤانریا <strong>پاکسا بیٱ</strong>.",
+       "rev-deleted-unhide-diff": "ڤانری اؽ بٱلگٱ <strong>پاکسا بیٱ</strong>.\nجۏزییات هان د  [{{fullurl:{{#Special:Log}}/پاکسا کردن|بٱلگٱ={{نوم کامل بٱلگٱ}}}} پهرستنومٱ پاکساکردن].\nشما هنی مؽتونؽت [$1اؽ ڤانری ناْ بونؽت] ٱر بهایؽت.",
+       "rev-suppressed-unhide-diff": "ڤانری اؽ بٱلگٱ <strong>پاکساگری بیٱ</strong>.\nجۏزییات هان د  [{{fullurl:{{#Special:Log}}/پاکساگری کردن|بٱلگٱ={{نوم کامل بٱلگٱ}}}} پهرستنومه پاکساگری کردن].\nشما هنی مؽتونؽت [$1اؽ ڤانری ناْ بونؽت] ٱر بهایؽت.",
+       "rev-deleted-diff-view": "ڤانری اؽ بٱلگٱ <strong>پاکسا بیٱ</strong>.\nجزئیات هان د  [{{fullurl:{{#Special:Log}}/پاکسا کردن|=\nبٱلگٱ{{نوم کامل بٱلگٱ}}}} پهرستنومٱ پاکساکردن].",
+       "rev-suppressed-diff-view": "ڤانری بٱلگٱ <strong>پاکساگری</strong>.\nجۏزییات هان د  [{{fullurl:{{#Special:Log}}/پاکساگری کردن|بٱلگٱ={{نوم کامل بٱلگٱ}}}} پهرستنومٱ پاکساگری کردن].",
        "rev-delundel": "آلشت هال ۉ بار ديئن",
-       "rev-showdeleted": "Ù\86ئشÙ\88Ù\99 Ø¯Ø£ئن",
-       "revisiondelete": "پاکسا Ú©Ø±Ø¯Ù\86/زÙ\86Ù\87 Ú©Ø±Ø¯Ù\86 Ù\88اÙ\86ئریا",
-       "revdelete-nooldid-title": "وانیری تمارزی بیه نامعتوره",
-       "revdelete-nooldid-text": "شما وانئریا حاسنی نه سی انجوم دئن ای کار ره ون تیاری نکردیته، یا وانئریا تیارگر بیه وجود نارن، یا یه که شما میهایت وانئری ایسنی نه قام بکیت.",
-       "revdelete-no-file": "جانیا تیار بیه وجود ناره.",
-       "revdelete-show-file-confirm": "شما د دل میهایت که وانئری پاکسا بیه ای جانیا نه بونیت \"<nowiki>$1</nowiki>\" د $2 تا $3؟",
-       "revdelete-show-file-submit": "هأری",
-       "revdelete-selected-text": "{{PLURAL:$1|ڤانئیأری گول گئر بییە|ڤانئیأریا گول گئر بییە}} د [[:$2]]:",
-       "revdelete-selected-file": "{{PLURAL:$1|ڤانئیأری گول گئر بییە جانیا|ڤانئیأریا گول گئر بییە جانیا}} د [[:$2]]:",
-       "logdelete-selected": "{{PLURAL:$1|پئھرئستنوٙمە روخ ڤأن گول گئر بییە|پئھرئستنوٙمە روخ ڤأنیا گول گئر بییە}}:",
-       "revdelete-text-text": "وانئریا پاکسا بیه هنی د بلگه ویرگار دیاری می کن،اما به شیا مینونه یاشو د مین خلک دیار نیئن.",
-       "revdelete-text-file": "وانئریا پاکسا بیه هنی د بلگه ویرگار دیاری می کن،اما به شیا مینونه یاشو د مین خلک دیار نیئن.",
-       "logdelete-text": "وانئریا پاکسا بیه هنی د بلگه ویرگار دیاری می کن،اما به شیا مینونه یاشو د مین خلک دیار نیئن.",
-       "revdelete-text-others": "دیوونداریا هنی می تونن د مینونه یا قام بیه دسرسی داشتوئن و ونه د نو زنه بکن، مه ر محدودیتیا اضافی میزوکاری بان.",
-       "revdelete-confirm": "لطفن بکید پشت راسی بکیت که میهایت ای کار نه انجوم بیئت، و یه دل بایت که شما نتیجه یا ای کار نه فئمستیته و ای کار نه  مطاوق وا  [[{{MediaWiki:Policy-url}}|the policy]].انجوم می ئیت",
+       "rev-showdeleted": "Ù\86Ø´Ù\88Ý© Ø¯Ø§Ù\9bئن",
+       "revisiondelete": "پاکسا Ú©Ø±Ø¯Ù\86/زÙ\86Ù± Ú©Ø±Ø¯Ù\86 Ú¤Ø§Ù\86ریا",
+       "revdelete-nooldid-title": "ڤانیری تمارزی بیٱ ناموعتٱبرٱ",
+       "revdelete-nooldid-text": "شما ڤانریا هاستنی ناْ سی ٱنجوم داٛئن اؽ کار رٱ ڤٱن دؽاری نٱکردؽتٱ، یا ڤانریا تیارگر بیٱ ڤوجۊد نارٱن، یا یٱ کاْ شما مؽهایت ڤانری ایسنی ناْ قایم بٱکؽت.",
+       "revdelete-no-file": "جانؽا تیار بیٱ ڤوجۊد نارٱ.",
+       "revdelete-show-file-confirm": "شما د دل مؽهایت کاْ ڤانری پاکسا بیٱ اؽ جانؽا ناْ باٛینؽت \"<nowiki>$1</nowiki>\" د $2 تا $3؟",
+       "revdelete-show-file-submit": "عٱ",
+       "revdelete-selected-text": "{{PLURAL:$1|ڤانیٱری گول گر بیٱ|ڤانیٱریا گول گر بینٱ}} د [[:$2]]:",
+       "revdelete-selected-file": "{{PLURAL:$1|ڤانیٱری گول گر بیٱ جانؽا|ڤانیٱریا گول گر بیٱ جانؽا}} د [[:$2]]:",
+       "logdelete-selected": "{{PLURAL:$1|پهرستنومٱ روخ ڤٱن گول گر بیٱ|پهرستنومٱ روخ ڤٱنؽا گول گر بیٱ}}:",
+       "revdelete-text-text": "ڤانریا پاکسا بیٱ هنی د بٱلگٱ ڤیرگار دؽاری مؽکٱن، ڤلی کوتؽا مینونٱیاشو د مؽن خٱلک دؽار نؽسن.",
+       "revdelete-text-file": "ڤانریا پاکسا بیٱ هنی د بٱلگٱ ڤیرگار دؽاری مؽکٱن، ڤلی کوتؽا مینونٱیاشو د مؽن خٱلک دؽار نؽسن.",
+       "logdelete-text": "ڤانریا پاکسا بیٱ هنی د بٱلگٱ ڤیرگار دؽاری مؽکٱن، ڤلی کوتؽا مینونٱیاشو د مؽن خٱلک دؽار نؽسن.",
+       "revdelete-text-others": "دیڤوندارؽا هنی مؽ تونٱن ڤ مینونٱیا قام بیٱ دٱسرسی داشتۊئٱن ۉ ڤٱناْ د نۊ زنٱ بٱکٱن، مگٱر مٱئدۊدؽیٱتؽا اْزافی میزوکاری بان.",
+       "revdelete-confirm": "لوتف بٱکؽت پشت راسی بٱکؽت کاْ مؽهایت اؽ کار ناْ ٱنجوم باٛیؽت، ۉ یاٛ دل بۊیؽت کاْ شما نٱتیجٱیا اؽ کار ناْ فٱمسؽتٱ ۉ اؽ کار ناْ موتابق ڤا  [[{{MediaWiki:Policy-url}}|the policy]].ٱنجوم ماٛیؽت.",
        "revdelete-suppress-text": "پاکساگری فقط با <strong>تئنا</strong> سی جایایی که هان د هار وه کار گرته بوئه:\n*دونسمنیایی که فره تنادارن\n*دونسمنیا نامناسو شخصی\n*: <em>تیرنشون حونه، شماره تیلیفون،رازینه زایاره ای و چیا تر</em>",
        "revdelete-legend": "میزونکاری محدودیتیا دیار بیین.",
        "revdelete-hide-text": "متن دوواره دیئن",
        "filetype-mime-mismatch": "دمادیس جانیا «$1.‎» وا نوع MIME وه($2) یکی نئ.",
        "filetype-badmime": "جانیایی که نوع MIME ونو $1 بوئه سی سوارکرد اجازه دار نیئن.",
        "filetype-bad-ie-mime": "نبوئه ای جانیانه سوار بکیت سی یه که اینترنت اکسپلورر ونه چی «$1» میشناسه، سی یه که وه یه گل جانیا ناصلادار و شات خطردار با.",
-       "filetype-unwanted-type": "'''«‎.‎$1»''' یÙ\87 Ú¯Ù\84 Ø¬Ø§Ù\86Û\8cا Ø­Ø§Ø³ØªÙ\86Û\8c Ù\86ئ.\n{{PLURAL:$3|جاÙ\86Û\8cا Ù\88رتÛ\8cÙ\87 Ú¯Ø±|جاÙ\86Û\8cاÛ\8cا Ù\88رتÛ\8cÙ\87 Ú¯Ø±}} Ø¯ Ø§Û\8c Ù\82رارÙ\86: $2 .",
+       "filetype-unwanted-type": "'''«‎.‎$1»''' یاÙ\9b Ø¬Ø§Ù\86ؽا Ù\87استÙ\86Û\8c Ù\86ؽ.\n{{PLURAL:$3|جاÙ\86ؽا Ú¤Ù±ØªÛ\8cٱگؽر|جاÙ\86ؽاÛ\8cا Ú¤Ù±Ø±ØªÛ\8cٱگر}} Ø¯ Ø§Ø½ Ù\82رارٱÙ\86: $2 .",
        "filetype-banned-type": "&lrm;'''\".$1\"''' {{PLURAL:$4|یه گل جانیا ناصلاداره|جانیایایی که صلادار نیئن}}.\n{{PLURAL:$3|جانیا صلادار|جانیایا صلادار}} د ای قرارن: $2.",
        "filetype-missing": "ای جانیا هیچ اضاف کردی ناره(چی \"جی پی جی\")",
        "empty-file": "جانیایی که دئی ته حالی بیه.",
        "backend-fail-internal": "خطا نادیاری د حامین دار اماییه «$1»  پیش اوما.",
        "backend-fail-contenttype": "دیارکرد نوع مینونه جانیا سی اماییه «$1» د انجومشیو بی.",
        "backend-fail-batchsize": "یه گل دسه مینونه دار $1 {{PLURAL:$1|انجومگری|انجومگری}} جانیا وه حامین اماییه دئه بیه؛ بیشترونه مجاز $2 {{PLURAL:$2|انجومگر|انجومگر}} ئه.",
-       "backend-fail-usable": "اÙ\85کاÙ\86 Ø­Ù\86Ù\86 Û\8cا Ù\86Û\8cسÙ\86Ù\86 Ø¬Ø§Ù\86Û\8cا $1 Ù\88جÙ\88د Ù\86اشت Ø³Û\8c Û\8cÙ\87 Ú©Ù\87 Ø±Û\8c ØªØ±Ø§Ø² Ø¯Ø³Ø±Ø³Û\8c Ø®Ù\88 Ù\86ئ Û\8cا Ù\84Ø´Ú©/اÙ\85اÛ\8cÛ\8cÙ\87 Ø¯Ø§Ø± Ø­Ø§Ø³ØªÙ\86Û\8c Ù\86Û\8cئش.",
+       "backend-fail-usable": "اÙ\92Ù\85کاÙ\86 Ú¤Ù±Ù\86Ù\86 Û\8cا Ù\86Û\8cسٱÙ\86Ù\86 Ø¬Ø§Ù\86ؽا $1 Ú¤Ù\88جÛ\8aد Ù\86اشت Ø³Û\8c Û\8cÙ± Ú©Ø§Ù\92 Ø±Û\8cتراز Ø¯Ù±Ø³Ø±Ø³Û\8c Ø®Ù\88 Ù\86ؽ Û\8cا Ù\84Ù\9bØ´Ú©/Ø¢Ù\85اÛ\8cÙ± Ø¯Ø§Ø± Ù\87استÙ\86Û\8c Ù\86ؽسش.",
        "filejournal-fail-dbconnect": "امکان وصل بیئن د رسینه گا نوشتگه سی حامین داری د اماییه کاری «$1» وجود ناشت.",
        "filejournal-fail-dbquery": "امکان وصل بیئن د رسینه گا نوشتگه سی حامین داری د اماییه کاری «$1» وجود ناشت.",
        "lockmanager-notlocked": "نبوئه قلف $1 نه وا بکیت؛ سی یه که وه قلف نبیه.",
        "uncategorizedtemplates": "قالویا دسه بنی نبیه",
        "unusedcategories": "دسه یا استفاده نبیه",
        "unusedimages": "فایلیا استفاده نبیه",
-       "wantedcategories": "بÙ\84Ú¯Ù\87 Û\8cا Ø­استنی",
-       "wantedpages": "بÙ\84Ú¯Ù\87 Û\8cا Ø­استنی",
+       "wantedcategories": "بٱÙ\84Ú¯Ù±Û\8cا Ù\87استنی",
+       "wantedpages": "بٱÙ\84Ú¯Ù±Û\8cا Ù\87استنی",
        "wantedpages-summary": "نومگە بألگە یایی کئ نیئشوٙ ڤا بیشتئری ھومپئیڤأند د ڤئنوٙ،  ، ڤئ جوز بألگە یایی کئ فأقأط آلئشتکاری لا د ڤئنوٙنە دأرئن. سی یئ گئل نومگە د بألگە یایی کئ نیئشوٙ و آلئشتکاری لا د ڤئنوٙنە دارئن،[[{{#special:BrokenRedirects}}]] نە سئیل بأکیت.",
        "wantedpages-badtitle": "سرون نامعتور د کومله نتیجه یا:$1",
-       "wantedfiles": "فایلیا حاستنی",
+       "wantedfiles": "فایلٛؽا هاستنی",
        "wantedfiletext-cat": "جانیایا هاری وه کار گرته بوئن ولی وجود نارن. همچنو شایت جانیایا وه دری وا یه که ایچه هیئشون نومگه کاری بینه.هر گرینج مثبت دورویی  <del>خط مئوره.</del> به اضافه یه، بلگه یایی که که جانیایا بی وجودن نه د خوشو دارن د [[:$1]] نومگه کاری بینه.",
        "wantedfiletext-cat-noforeign": "جانیایا هاری وه کار گرته بوئن ولی نیئشو. اضافه وه یه بلگه یایی که جانیایا نادیار د خوشو دارن هان د [[:$1]].",
        "wantedfiletext-nocat": "جانیایا هاری که وه کار گرته بوئن نیئشو. همچنو شایت جانیا اماییه داریا خارجی وه شرطی که بان وه کار گرته بوئن. هر گرینج خو ولی الکی <del> خط مئوره. <del>",
        "wantedfiletext-nocat-noforeign": "جانیایا هاری وه کار گرته بوئن ولی نیئشو.",
-       "wantedtemplates": "قالویا حاستنی",
+       "wantedtemplates": "قالوؽا هاستنی",
        "mostlinked": "بلگه یا که بیشتر هوم پیوند بینه",
        "mostlinkedcategories": "دسه یایی که بیشتر هوم پیوند بیه",
        "mostlinkedtemplates": "چوئه یایی که بیشتر هوم پیوند بینه",
        "notargettitle": "رسینه جایی نئ",
        "notargettext": "شما بلگه یا کاریاری مقصدی سی انجوم دئن ای کنشت ریش انتخاو نکردیته.",
        "nopagetitle": "چنی بلگه ای نیئش",
-       "nopagetext": "بÙ\84Ú¯Ù\87 Ø­Ø§Ø³ØªÙ\86Û\8c Ú©Ù\87 Ø´Ù\85ا Ø¯Û\8cارÛ\8c Ú©Ø±Ø¯Û\8cتÙ\87 Ù\88جÙ\88د Ù\86ارÙ\87.",
+       "nopagetext": "بٱÙ\84Ú¯Ù± Ù\87استÙ\86Û\8c Ú©Ø§Ù\92 Ø´Ù\85ا Ø¯Ø½Ø§Ø±Û\8c Ú©Ø±Ø¯Ø½ØªÙ± Ú¤Ù\88جÛ\8aد Ù\86ارٱ.",
        "pager-newer-n": "{{PLURAL:$1|ڤانوئاتر 1ڤانوئاتر $1}}",
        "pager-older-n": "{{PLURAL:$1|گٱپسالتر 1|گٱپسالتر $1}}",
        "suppress": "پائیئن",
        "booksources-search-legend": "پاٛ جۊری سی سرچشمٱیا کتاو",
        "booksources-isbn": "آی اس بی ان:",
        "booksources-search": "پاٛ جۊری",
-       "booksources-text": "د Ù\87ار Ù\86Ù\88Ù\85Ú¯Ù\87 Ø§Û\8c Ø¯ Ù\87Ù\88Ù\85 Ù¾Û\8cÙ\88Ù\86دÛ\8cا Ø¯ Ø¯Û\8cارگÙ\87 Û\8cا Ù\87Ù\86Û\8c Ø§Ù\88Ù\85ائÙ\87 Ú©Ù\87 Ú©ØªØ§Ù\88Û\8cا Ù\86Ù\88 Ù\88 Ø¯Ø³ Ø¯Ù\88ئÙ\85 Ù\85Û\8c Ù\81رÙ\88Ø´Ù\86Ø\8c Ù\88 Ù\87Ù\85Ú\86Ù\86Ù\88 Ø´Ø§Û\8cت Ø¯Ù\88Ù\86سÙ\85Ù\86Û\8cا Ø¨Û\8cشترÛ\8c Ø±Ø§Ø¬Ø¹ Ù\88Ù\87 Ú©ØªØ§Ù\88 Ø­Ø§Ø³ØªÙ\86Û\8c Ø´Ù\85ا Ø¯Ø§Ø´ØªÙ\88ئن:",
+       "booksources-text": "د Ù\87ار Ù\86Ù\88Ù\85Ú¯Ù± Ø§Ø½ Ù\87Ù\88Ù\85 Ù¾Ø§Ù\9bÚ¤Ù±Ù\86ؽا Ø¯ Ø¯Ø½Ø§Ø±Ú¯Ù±Û\8cا Ù\87Ù\86Û\8c Ø§Ù\88Ù\85اÛ\8cÙ± Ú©Ø§Ù\92 Ú©ØªØ§Ù\88Û\8cا Ù\86Û\8a Û\89 Ø¯Ù±Ø³ Ø¯Û\8fئÙ\85 Ù\85ؽ Ù\81رÛ\8aشٱÙ\86Ø\8c Û\89 Ù\87Ù±Ù\85Ú\86Ù\86Ù\88 Ø´Ø§Û\8cٱد Ø¯Ù\88Ù\86سÙ\85Ù±Ù\86Û\8cا Ø¨Ø½Ø´ØªØ±Ø½ Ø±Ø§Ø¬Ø¹ Ú¤ Ú©ØªØ§Ù\88 Ù\87استÙ\86Û\8c Ø´Ù\85ا Ø¯Ø§Ø´ØªÛ\8aئٱن:",
        "booksources-invalid-isbn": "شازک که دئه بیه معتور نئ؛ وارسی خطایا د گات ؤرداشتن د سرچشمه اولی وه کار گرته بوئه.",
        "specialloguserlabel": "ٱنجومکار:",
        "speciallogtitlelabel": "هاستنی(داسون یا نوم کاریاری سی کاریار):",
        "cant-move-category-page": "شما صلا ینه که دسه یا نه ناریت.",
        "cant-move-to-category-page": "شما صلا ینه که یه بلگه نه بوریت وه بلگه دسه ناریت.",
        "newtitle": "سی سرون هنی:",
-       "move-watch": "دÛ\8cئÙ\86 Ø¨Ù\84Ú¯Ù\87 Ø³Ø±Ú\86Ø´Ù\85Ù\87 Ù\88 Ø¨Ù\84Ú¯Ù\87 Ø­استنی",
+       "move-watch": "دÛ\8cئÙ\86 Ø¨Ù±Ù\84Ú¯Ù± Ø³Ø±Ú\86Ø´Ù\85Ù± Û\89 Ø¨Ù±Ù\84Ú¯Ù± Ù\87استنی",
        "movepagebtn": "بٱلگٱ جا ڤ جا کو",
        "pagemovedsub": "د خوئی جا وه جا بیه",
        "movepage-moved": "<strong>\"$1\" جا وه جا بیه سی \"$2\"</strong>",
-       "movepage-moved-redirect": "یه گل واگردونی دروس بیه.",
+       "movepage-moved-redirect": "یاٛ ڤاگٱردونی دۏرس بیٱ.",
        "movepage-moved-noredirect": "د دروس کردن واگردونی جلوگری بیه.",
        "articleexists": "یه گل بلگه وا ای نوم د دماتر بیه، یا نومی که شما دئیه ته معتور نئ.\nلطف بکیت یه گل نوم هنی انتخاو بکیت.",
        "cantmove-titleprotected": "شما نمی تونیت بلگه نه بوریت وه ای تیرنشون، سی یه داسون تازه سی سازیاری پر و پیم کاری بیه.",
        "selfmove": "داسونؽا بٱلگٱ ٱڤٱل ۉ بٱلگٱ مٱقسٱد یٱکؽ هؽسن؛\nنمۊئٱ بٱلگٱناْ ڤ خوش جا ڤ جا کاری کرد.",
        "immobile-source-namespace": "نبوئه بلگه یا نه وه نومجا \"$1\" جا وه جا با",
        "immobile-target-namespace": "نبوئه بلگه یا نه وه نومجا \"$1\" جا وه جا با",
-       "immobile-target-namespace-iw": "هوم پیوند مینجاویکی حاستنی مجازی سی جا وه جا کردن بلگه نئ.",
+       "immobile-target-namespace-iw": "هوم پاٛڤٱن ؽنجاڤیکی هاستنی موجازؽ سی جا ڤ جا کردن بٱلگٱ نؽ.",
        "immobile-source-page": "ای بلگه جا وه جا کردنی نئ.",
        "immobile-target-page": "نبوئه وه ای مقصد چنی سرونی جا وه جا بوئه.",
-       "bad-target-model": "Ù\85Ù\82صد Ø­Ø§Ø³ØªÙ\86Û\8c Ù\85دÙ\84 Ù\85Û\8cÙ\86Ù\88Ù\86Ù\87 Ø¯Ø§Ø± Ù\81رخدارÛ\8c Ù\86Ù\87 Ù\88Ù\87 Ú©Ø§Ø± Ú¯Ø±ØªÙ\87. Ù\86بÙ\88ئÙ\87$1 Ù\86Ù\87 Ø¨Ú©Û\8cت Ù\88Ù\87 $2.",
+       "bad-target-model": "Ù\85Ù±Ù\82سٱد Ù\87استÙ\86Û\8c Ù\85Ù\88دÙ\84 Ù\85Û\8cÙ\86Ù\88Ù\86Ù± Ø¯Ø§Ø± Ù\81ٱرخدارؽ Ù\86اÙ\92 Ú¤ Ú©Ø§Ø± Ú¯Ø±ØªÙ±. Ù\86Ù\85Û\8aئٱ$1 Ù\86اÙ\92 Ø¨Ù±Ú©Ø½Øª Ú¤ $2.",
        "imagenocrossnamespace": "نبوئه جانیانه وه یه گل نومجا غیرجانیایی جا وه جا بکیت",
        "nonfile-cannot-move-to-file": "نبوئه جانیانه وه یه گل نومجا غیرجانیایی جا وه جا بکیت",
        "imagetypemismatch": "دماون جانیا تازه وا نوع وه سازگاری ناره",
        "imageinvalidfilename": "نوم جانیا هدف معتور نئ",
        "fix-double-redirects": "وه هنگوم سازی همه واگردونیایی که وه گوتار اصلی هشاره میکن",
-       "move-leave-redirect": "وه جا نیائن یه گل واگردونی",
+       "move-leave-redirect": "ڤ جا نیایئن یاٛ ڤاگٱردونی",
        "protectedpagemovewarning": "<strong>زئنار:ای بلگه سی یه پر و پیم بیه که کاریاریایی که دسرسی دیوونداری دارن فقط بتونن دش ویرایشت بکن.</strong>\nآخرین سیائه سی سرچشمه یا د هار اماییه کاری بیه:",
        "semiprotectedpagemovewarning": "<strong>د ویر داشتویت:</strong> ای بلگه سی یه که فقط کاریاریا ثوت نام کرده تونستون دش ویرایشت بکه ن پر و پیم بیه.\nآخرین پهرستنومه دئه بیه سی سرچشمه هار نها اماییه بیه:",
        "move-over-sharedrepo": "== جانیا هئیش ==\n[[:$1]] ها د یه گل اماییه جا بهربیه. جا وه جاکاری یه گل جانیا وه ای نوم باعث موئه که یه گل جانیا بهربیه باطل با.",
        "tags-edit-logentry-submit": "وه کار گرتن سردیسیا د {{PLURAL:$1|د ای پهرستنومه|پهرستنومه یا $1}}",
        "tags-edit-success": "آلشتکاریا وا خوش سرانجومی وه کار گرته بیین.",
        "tags-edit-failure": "نبوئه آلشتکاریا وه کار گرته بان.",
-       "tags-edit-nooldid-title": "وانیری حاستنی نامعتوره",
+       "tags-edit-nooldid-title": "ڤانیری هاستنی نامعتبٱرٱ",
        "tags-edit-nooldid-text": "شما یه گل وانئری دالکاری بیه سی یه که ای پیوندگر نه انجوم بیه تیار کاری نکردیته، یا وانئری که تیار کاری نبیه.",
        "tags-edit-none-selected": "لطف بکیت یه حداقل یه گل سردیسی سی اضاف کردن یا جا وه جاکاری انتخاو بکیت.",
        "comparepages": "کنار یک نیاین بلگه یا",
        "dberr-info": "(نبوئه وه رسینه جا:$1 دسرسی داشتوئیت)",
        "dberr-info-hidden": "(نبوئه د رسینه گا دسرسی داشت)",
        "htmlform-invalid-input": "یه قری مشگل ها د پاره یی د درینده یا شما.",
-       "htmlform-select-badoption": "ارزایشتی که دئیته یه گل گزینه حاستنی نئ.",
+       "htmlform-select-badoption": "ٱرزایشتؽ کاْ داٛیؽتٱ یاٛ گوزیٱ هاستنی نؽ.",
        "htmlform-int-invalid": "ارزایشتی که دئیته یه گل عدد صحیح نئ.",
        "htmlform-float-invalid": "ارزایشتی که دئیته یه گل عدد نئ.",
        "htmlform-int-toolow": "انازه یی که شما دئیته د کمترونه $1 فره کمتره.",
        "logentry-move-move": "$1 {{GENDER:$2|جا ڤ جا کردن}} بٱلگٱ $3 ناْ سی $4",
        "logentry-move-move-noredirect": "$1 بٱلگٱ $3 ناْ بؽ یٱ کاْ یاٛ ڤاگٱردونی داشتۊئٱ د $4 {{GENDER:$2|جا ڤ جا کاری کرد}}",
        "logentry-move-move_redir": "$1 بٱلگٱ $3 ناْ د $4 اْ ڤاگٱردونی بی {{GENDER:$2|جا ڤ جاکاری کرد}}",
-       "logentry-move-move_redir-noredirect": "$1 Ø¨Ù\84Ú¯Ù\87 $3 Ù\86Ù\87 Ø¨Û\8c Û\8cÙ\87 Ú©Ù\87 Û\8cÙ\87 Ú¯Ù\84 Ù\88اگردÙ\88Ù\86Û\8c Ø¯ $4 Ø¯Ø§Ø´ØªÙ\88ئÙ\87 Ú©Ù\87 Û\8cÙ\87 Ø®Ù\88Ø´ Ù\88اگردÙ\88Ù\86Û\8c Ø¨Û\8c {{GENDER:$2|جا Ù\88Ù\87 جاکاری کرد}}",
+       "logentry-move-move_redir-noredirect": "$1 Ø¨Ù±Ù\84Ú¯Ù± $3 Ù\86اÙ\92 Ø¨Ø½ Û\8cÙ± Ú©Ø§Ù\92 Û\8cاÙ\9b Ú¤Ø§Ú¯Ù±Ø±Ø¯Ù\88Ù\86Û\8c Ø¯ $4 Ø¯Ø§Ø´ØªÛ\8aئٱ Ú©Ø§Ù\92 Û\8cÙ± Ø®Ù\88Ø´ Ú¤Ø§Ú¯Ù±Ø±Ø¯Ù\88Ù\86Û\8c Ø¨Û\8c {{GENDER:$2|جا Ú¤ جاکاری کرد}}",
        "logentry-patrol-patrol": "$1 نسقه $4 بلگه $3 نه چی یه گل چی تیه نئری بیه {{GENDER:$2|نشودار کرد}}",
        "logentry-patrol-patrol-auto": "$1 نۏسخٱ $4 بٱلگٱ $3 ناْ ڤ هال ۉ بار خودٱنجوم چی یاٛ بٱلگٱ تیٱ نیر بیٱ {{GENDER:$2|نشودار کرد}}",
        "logentry-newusers-newusers": "حساو کاریاری $1 {{GENDER:$2|دروس بیه}}",
index 1f0dc81..de47550 100644 (file)
        "sunday": "Akaik",
        "monday": "Sinayan",
        "tuesday": "Salasa",
-       "wednesday": "Raba'a",
+       "wednesday": "Rabaa",
        "thursday": "Kamih",
        "friday": "Jumaik",
-       "saturday": "Sabtu",
+       "saturday": "Satu",
        "sun": "Min",
        "mon": "Sin",
        "tue": "Sal",
        "broken-file-category": "Laman jo gamba rusak",
        "about": "Perihal",
        "article": "Artikel",
-       "newwindow": "(bukak di jendela baru)",
+       "newwindow": "(bukak di jandela baru)",
        "cancel": "Batalkan",
        "moredotdotdot": "Lainnyo...",
        "morenotlisted": "Daftar ko mungkin indak langkok.",
        "edithelp": "Bantuan suntiangan",
        "helppage-top-gethelp": "Bantuan",
        "mainpage": "Palanta",
-       "mainpage-description": "Palanta",
+       "mainpage-description": "Laman Utamo",
        "policy-url": "Project:Kabijakan jo padoman",
        "portal": "Portal komunitas",
        "portal-url": "Project:Portal komunitas",
        "nstab-template": "Templat",
        "nstab-help": "Bantuan",
        "nstab-category": "Kategori",
-       "mainpage-nstab": "Palanta",
+       "mainpage-nstab": "Laman Utamo",
        "nosuchaction": "Indak ado tindakan tasabuik",
        "nosuchactiontext": "Tindakan nan diminta dek URL tasabuik indak valid. Sanak mungkin salah mangetikkan URL, atau mangikuik pautan nan salah. Iko mungkin manunjuakan adonyo suatu bug pado parangkaik lunak nan dipagunoan dek {{SITENAME}}.",
        "nosuchspecialpage": "Indak ado laman istimewa tasabuik",
        "yourpasswordagain": "Ulang baliak kato sandi:",
        "createacct-yourpasswordagain": "Konfirmasi kato sandi",
        "createacct-yourpasswordagain-ph": "Masuakan lai kato sandi",
-       "userlogin-remembermypassword": "Biakan ambo tetap masuak",
+       "userlogin-remembermypassword": "Padiaan ambo tatap masuak",
        "userlogin-signwithsecure": "Gunoan server aman",
        "cannotlogin-title": "Indak bisa masuak",
        "cannotlogin-text": "Indak mamungkinkan untuak masuak.",
        "previewerrortext": "Ado yang salah wakatu manunjuakan pratayang parubahan Sanak.",
        "blockedtitle": "Pangguno diblokir",
        "blocked-email-user": "<strong>Namo pangguno Sanak diblokir untuak mangirim surel. Sanak masih bisa manyuntiang halaman lain di wiki ko. </strong> Sanak bisa mancaliak parincian pamblokiran  pado [[Special:MyContributions|account contributions]].\n\nPamblokiran dilakuan dek $1.\n\nAlasannyo adolah <em>$2</em>.\n\n* Diblokir sajak: $8\n* Blokir kadaluarsa pado: $6\n* Sasaran pamblokiran: $7\n* ID pamblokiran #$5",
-       "blockedtext": "'''Namo pangguno atau alamaik IP Sanak alah kanai sakek.'''\n\nSakek dibuek dek $1.\nAlasan nan diagiahan adolah ''$2''.\n\n* Kanai sakek sajak: $8\n* Maso sakek habih pado: $6\n* Sasaran nan disakek: $7\n\nSanak dapek manghubungi $1 atau [[{{MediaWiki:Grouppage-sysop}}|panguruih lainnyo]] untuak mambicarokan hal iko.\n\nSanak indak dapek manggunoan fitua 'Kirim surel ka pangguna iko' kacuali Sanak alah mamasuakan alamaik surel nan sah di [[Special:Preferences|pangaturan akun]] dan Sanak indak sadang disakek untuak manggunoannyo.\n\nAlamaik IP Sanak adolah $3, dan ID panyakek adolah $5.\nTolong saratoan informasi di ateh pado satiok patanyaan nan Sanak buek.",
+       "blockedtext": "'''Namo pangguno atau alamaik IP Sanak alah kanai sakek.'''\n\nSakek dibuek dek $1.\nAlasan nan diagiahan adolah ''$2''.\n\n* Kanai sakek sajak: $8\n* Maso sakek habih pado: $6\n* Sasaran nan disakek: $7\n\nSanak dapek maubungi $1 atau [[{{MediaWiki:Grouppage-sysop}}|panguruih lainnyo]] untuak marundiangan hal ko.\n\nSanak indak dapek manggunoan fitur 'Kirim surel ka pangguno ko' kacuali Sanak alah mamasuakan alamaik surel nan sah di [[Special:Preferences|pangaturan akun]] dan Sanak indak sadang disakek untuak manggunoannyo.\n\nAlamaik IP Sanak adolah $3, dan ID panyakek adolah $5.\nTolong saratoan informasi di ateh pado satiok patanyoan nan Sanak buek.",
        "autoblockedtext": "Alamaik IP Sanak alah kanai sakek sacaro otomatis dek digunoan jo pangguno lain, nan sakek dek $1. Panyakek ko dibuek dek alasan:\n\n:''$2''\n\n* Kanai sakek sajak: $8\n* Maso sakek habih pado: $6\n* Sasaran nan disakek: $7\n\nSanak dapek mahubungi $1 atau [[{{MediaWiki:Grouppage-sysop}}|penguruih lainnya]] untuak mambicarokan hal iko.\n\nSanak indak dapek manggunoan fitua 'Kirim surel ka pangguna iko' kacuali Sanak alah mamasuakan alamaik surel nan sah di [[Special:Preferences|pangaturan akun]] dan Sanak indak sadang disakek untuak manggunoannyo.\n\nAlamaik IP Sanak adolah $3, dan ID panyakek adolah $5.\nTolong saratoan informasi di ateh pado satiok patanyaan nan Sanak buek.",
        "blockednoreason": "indak ado alasan nan diagiah.",
        "whitelistedittext": "Sanak musti $1 untuak manyuntiang laman.",
        "accmailtext": "Sabuah kato sandi acak untuak [[User talk:$1|$1]] alah dibuek dan dikiriman ka $2.\n\nKato sandi untuak akun baharu iko dapek diubah di laman ''[[Special:ChangePassword|pangubahan kato sandi]]'' satalah masuak log.",
        "newarticle": "(Baru)",
        "newarticletext": "Laman nan Sanak cari alun ado.\nUntuak mambuek laman tu, mulailah jo manulih dalam kotak di bawah (caliak [$1 laman bantuan] untuak informasi labiah lanjuik).\nJikok Sanak indak sangajo sampai ka laman ko, klik tombol '''back''' pado paramban web Sanak.",
-       "anontalkpagetext": "----''Iko adolah laman rundiang saurang pangguno anonim nan alun mambuek akun atau indak manggunoannyo.\nJadi, kami tapaso mamakai alamat IP nan takaik untuak mangenalinyo.\nJikok Sanak adolah pangguno anonim dan maraso mandapek komentar nan indak lamak nan ditujuan langsung kapado Sanak, cubolah [[Special:CreateAccount|mambuek akun]] atau [[Special:UserLogin|masuak log]] guno manghindari karancuan jo pangguno anonim lainnyo.''",
+       "anontalkpagetext": "----''Iko adolah laman rundiang surang pangguno anonim nan alun mambuek akun atau indak manggunoannyo.\nJadi, kami tapaso mamakai alamat IP nan takaik untuak mangenalinyo.\nJikok Sanak adolah pangguno anonim dan maraso mandapek komentar nan indak lamak nan ditujuan lansuang kapado Sanak, cubolah [[Special:CreateAccount|mambuek akun]] atau [[Special:UserLogin|masuak log]] guno maindari karancuan jo pangguno anonim lainnyo.''",
        "noarticletext": "Kini ko indak ado teks dalam laman ko.\nSanak dapek [[Special:Search/{{PAGENAME}}|malakukan pancarian untuak judul laman ko]] di laman lain, atau <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} mancahari log takaik] </span>, tapi Sanak indak punyo izin untuak mambuek laman ko.",
        "noarticletext-nopermission": "Kini ko indak ado teks dalam laman ko.\nSanak dapek [[Special:Search/{{PAGENAME}}|malakukan pancarian untuak judul laman ko]] di laman lain, atau <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} mancahari log takaik] </span>, tapi Sanak indak punyo izin untuak mambuek laman ko.",
        "missing-revision": "Revisi $1 di laman nan banamo \"{{FULLPAGENAME}}\" ko indak ado.\n\nHal iko biasonyo disababkan dek pautan sijarah nan alah kadaluarsa ka laman nan alah diapuih.\nRinciannyo dapek dicaliak di [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} log pangapuihan].",
        "permissionserrorstext": "Sanak indak ado hak untuak malakuannyo dek {{PLURAL:$1|alasan}} barikuik:",
        "permissionserrorstext-withaction": "Sanak indak punyo hak akses untuak $2, dek {{PLURAL:$1|alasan}} barikuik:",
        "contentmodelediterror": "Sanak indak dapek manyuntiang revisi ko karano isi model <code>$1</code>, beda dari isi model laman kini <code>$2</code>.",
-       "recreate-moveddeleted-warn": "'''Ingek: Sanak mambuek ulang suatu laman nan alah dihapuih.'''\n\nHarap ditimbang apo rancak malanjuikan suntiangan Sanak.\nBarikuik ko log pangapuihan jo pamindahan dari laman ko:",
+       "recreate-moveddeleted-warn": "'''Ingek: Sanak mambuek ulang suatu laman nan alah dihapuih.'''\n\nArok dipatimbangkan lai rancak malanjuikan suntiangan Sanak.\nBarikuik ko log pangapuihan jo pamindahan dari laman ko:",
        "moveddeleted-notice": "Laman ko alah dihapuih.\nSabagai referensi, barikuik adolah log pangapuihan jo pamindahannyo.",
        "moveddeleted-notice-recent": "Maaf, halaman ko baru sajo dihapuih (dalam rantang wakatu 24 jam). Log panghapuiah, palinduangan, jo pamindahan halaman tu tasadio di bawah sabagai referensi.",
        "log-fulllog": "Liek saluruah log",
        "revisionasof": "Revisi pado $1",
        "revision-info": "Revisi sajak $1 dek $2",
        "previousrevision": "← Revisi sabalunnyo",
-       "nextrevision": "Revisi selanjuiknyo →",
+       "nextrevision": "Revisi salanjuiknyo →",
        "currentrevisionlink": "Revisi tabaru",
        "cur": "kini",
        "next": "lanjuik",
        "page_first": "awal",
        "page_last": "akhia",
        "histlegend": "Bandiangan piliahan: Tandoi revisi untuak mambandiangan dan takan enter atau tombol di bawah.<br />\nContoh: '''({{int:cur}})''' = bedo jo versi tarakhia, '''({{int:last}})''' = bedo jo versi sabalunnyo, '''{{int:minoreditletter}}''' = suntiangan ketek.",
-       "history-fieldset-title": "Talusuri riwayaik",
+       "history-fieldset-title": "Sariang riwayaik",
        "history-show-deleted": "Hanyo nan dihapuih",
        "histfirst": "Nan paliang lamo",
        "histlast": "Nan paliang baru",
        "historysize": "({{PLURAL:$1|$1  bita}})",
        "historyempty": "(kosong)",
        "history-feed-title": "Riwayat revisi",
-       "history-feed-description": "Riwayat revisi laman ko di wiki",
+       "history-feed-description": "Riwayaik revisi laman ko di wiki",
        "history-feed-item-nocomment": "$1 pado $2",
        "history-feed-empty": "Laman nan dicari indak ado.\nMungkin alah dihapuih dari wiki, atau diagiah namo baru.\nCuba [[Special:Search|cari dulu]] untuak laman lain nan relevan.",
        "rev-deleted-comment": "(ringkasan suntiangan dihapuih)",
        "revertmerge": "Batal gabuang",
        "mergelogpagetext": "Di bawah ko daftar panggabuangan riwayaik laman ka laman nan lain.",
        "history-title": "Riwayaik revisi dari \"$1\"",
-       "difference-title": "Pabedoan antaro revisi dari \"$1\"",
+       "difference-title": "Pabedaan antaro revisi dari \"$1\"",
        "difference-title-multipage": "Pabedoan antaro laman \"$1\" jo \"$2\"",
        "difference-multipage": "(Pabedoan antaro laman)",
        "lineno": "Barih $1:",
        "compareselectedversions": "Bandiangan versi tapiliah",
        "showhideselectedversions": "Tunjuakan/suruakan versi tapiliah",
        "editundo": "batal",
-       "diff-empty": "(Indak ado pabedoan)",
+       "diff-empty": "(Indak ado pabedaan)",
        "diff-multi-sameuser": "({{PLURAL:$1|Ciek parubahan antaro|$1 parubahan antaro}} dek pangguno nan samo indak ditampilkan)",
        "diff-multi-otherusers": "({{PLURAL:$1|Ciek parubahan antaro|$1 parubahan antaro}} dek {{PLURAL:$2|ciek pangguno lain|$2 pangguno}} indak ditampilkan)",
        "searchresults": "Hasil pancarian",
        "searchprofile-articles-tooltip": "Cari di $1",
        "searchprofile-images-tooltip": "Cari untuak berkas",
        "searchprofile-everything-tooltip": "Cari kasadonyo (tamasuak laman rundiang)",
-       "searchprofile-advanced-tooltip": "Pacarian di ruang namo tatantu",
+       "searchprofile-advanced-tooltip": "Cari di ruang namo tatantu",
        "search-result-size": "$1 ({{PLURAL:$2|$2 kato}})",
        "search-result-category-size": "{{PLURAL:$1|$1 anggota}} ({{PLURAL:$2|$2 subkategori}}, {{PLURAL:$3|$3 berkas}})",
        "search-redirect": "(dialiahan dari $1)",
        "searchall": "sado",
        "showingresults": "Di bawah ko dikaluaan sampai {{PLURAL:$1|'''$1''' hasil}}, dimulai dari #'''$2'''.",
        "search-showingresults": "{{PLURAL:$4|Hasia <strong>$1</strong> dari <strong>$3</strong>|Hasia <strong>$1 - $2</strong> dari <strong>$3</strong>}}",
-       "search-nonefound": "Indak ado hasil nan cocok sasuai jo parmintaan",
+       "search-nonefound": "Indak ado hasil nan sasuai jo pamintaan",
        "powersearch-legend": "Pencarian lanjut",
        "powersearch-ns": "Mancari di ruangnamo:",
        "powersearch-togglelabel": "Piliah:",
        "recentchanges-label-minor": "Iko suntiangan ketek",
        "recentchanges-label-bot": "Suntiang ko dibuek dek bot",
        "recentchanges-label-unpatrolled": "Suntiangan ko alun dipatroli",
-       "recentchanges-label-plusminus": "Parubahan ukuran halaman dalam bita",
+       "recentchanges-label-plusminus": "Parubahan ukuran laman dalam bita",
        "recentchanges-legend-heading": "<strong>Katarangan:</strong>",
-       "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (caliak pulo [[Special:NewPages|daftar halaman nan baru]])",
+       "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (caliak pulo [[Special:NewPages|daftar laman nan baru]])",
        "rcnotefrom": "Di bawah iko adolah {{PLURAL:$5|parubahan|babagai parubahan}} sajak <strong>$3, $4</strong> (ditampilkan sampai <strong>$1</strong> parubahan).",
        "rclistfrom": "Tunjuakan parubahan baru mulai dari tanggal $3 $2",
        "rcshowhideminor": "$1 suntiangan ketek",
        "rcshowhidemine-show": "Tunjuakan",
        "rcshowhidemine-hide": "Suruakan",
        "rclinks": "Tunjuakkan $1 parubahan tabaru dalam $2 hari nan tarakhia",
-       "diff": "bedo",
+       "diff": "beda",
        "hist": "sijarah",
        "hide": "Suruakan",
        "show": "Tunjuakan",
        "minoreditletter": "k",
        "newpageletter": "B",
        "boteditletter": "b",
-       "rc-change-size-new": "$1 {{PLURAL:$1|byte|bita}} satalah parubahan",
+       "rc-change-size-new": "$1 {{PLURAL:$1|byte|bita}} salapeh parubahan",
        "rc-enhanced-expand": "Tampilkan rincian (paralu JavaScript)",
        "rc-enhanced-hide": "Suruakkan rincian",
        "rc-old-title": "awanyo dibuek jo judua \"$1\"",
        "recentchangeslinked-feed": "Parubahan takaik",
        "recentchangeslinked-toolbox": "Parubahan takaik",
        "recentchangeslinked-title": "Parubahan nan takaik jo \"$1\"",
-       "recentchangeslinked-summary": "Masuakkan namo halaman untuak mancaliak parubahan pado halaman nan taubuang dari atau pado halaman tu. (Untuak mancaliak laman nan manjadi anggota kategori itu, masuakkan {{ns:category}}:Namo kategori). Parubahan pado halaman nan ado pado [[Special:Watchlist|daftar pantauan Sanak]] batando <strong>pakek</strong>.",
+       "recentchangeslinked-summary": "Masuakkan namo laman untuak mancaliak parubahan pado laman nan taubuang dari atau pado laman tu. (Untuak mancaliak laman nan manjadi anggota kategori tu, masuakan {{ns:category}}:Namo kategori). Parubahan pado laman nan ado pado [[Special:Watchlist|daftar pantauan Sanak]] batando <strong>pakek</strong>.",
        "recentchangeslinked-page": "Namo laman:",
        "recentchangeslinked-to": "Tampilkan parubahan dari laman nan takaik jo laman nan ko",
        "upload": "Muek berkas",
        "upload-permitted": "Jenis berkas nan dipabuliahan: $1.",
        "upload-preferred": "Jenis berkas nan disaranan: $1.",
        "upload-prohibited": "Jenis berkas nan dilarang: $1.",
-       "uploadlogpage": "Log pangunggahan",
+       "uploadlogpage": "Log muek",
        "uploadlogpagetext": "Barikuik ko adolah daftar pangunggahan berkas tabaru. \nCaliak [[Special:NewFiles|galeri berkas baru]] untuak tampilan visual.",
        "filename": "Namo berkas",
        "filedesc": "Ikhtisar",
        "uploadnewversion-linktext": "Muek versi baru dari berkas ko",
        "shared-repo-from": "dari $1",
        "shared-repo": "repositori basamo",
-       "upload-disallowed-here": "Sanak indak dapaek manimpo berkas ko.",
+       "upload-disallowed-here": "Sanak indak dapek manimpo berkas ko.",
        "filerevert": "Baliakan $1",
        "filerevert-legend": "Baliakan berkas",
        "filerevert-intro": "Sanank ka mambaliakan berkas '''[[Media:$1|$1]]''' ka versi [$4 pado $3, $2].",
        "speciallogtitlelabel": "Target (judua atau {{ns:pangguno}}:namo pangguno untuak pangguno):",
        "log": "Log",
        "all-logs-page": "Sado log publik",
-       "alllogstext": "Gabuangan kasado log nan ado di {{SITENAME}}.\nSanak dapek mamiliah jinih log nan ado, namo pangguno (bedoan hurup ketek/gadang), atau judul laman (bedoan hurup ketek/gadang).",
+       "alllogstext": "Gabuangan kasado log nan ado di {{SITENAME}}.\nSanak dapek mamiliah jinih log nan ado, namo pangguno (bedoan hurup ketek/gadang), atau judul laman (bedaan hurup ketek/gadang).",
        "logempty": "Indak basobok entri log nan sasuai.",
        "log-title-wildcard": "Cari judul nan diawali jo teks ko",
        "showhideselectedlogentries": "Tunjuakan/Suruakan entri log tapiliah",
        "watchthispage": "Pantau laman ko",
        "unwatch": "Batal pantau",
        "unwatchthispage": "Batal pantau laman ko",
-       "watchlist-details": "Tadapek {{PLURAL:$1|$1 laman|$1 laman}} dalam daftar pantau Sanak (tamasuak laman rundiangnyo).",
+       "watchlist-details": "Ado {{PLURAL:$1|$1 laman}} dalam daftar pantau Sanak (tamasuak laman rundiangnyo).",
        "wlheader-showupdated": "Laman nan alah barubah sajak kunjuangan tarakhia Sanak ditunjuakan jo <strong>hurup taba</strong>",
        "wlnote": "Di bawah ko ado $1 {{PLURAL:$1|parubahan}} dalam {{PLURAL:$2|'''$2''' jam}} iko, sampai tanggal $3, pukua $4.",
        "wlshowlast": "Tunjuakan $1 jam parubahan dalam $2 hari tarakhia",
        "sp-contributions-blocked-notice-anon": "Alamaik IP ko tangah kanai sakek.\nEntri log sakek tabaru ado di bawah ko untuak referensi:",
        "sp-contributions-search": "Cari jariah",
        "sp-contributions-username": "Alamaik IP atau namo pangguno:",
-       "sp-contributions-toponly": "Hanyo manampilan suntiangan nan tarakhia",
+       "sp-contributions-toponly": "Anyo manampilan suntiangan nan tarakhia",
        "sp-contributions-newonly": "Hanyo manampilan suntiangan nan tarakhia",
        "sp-contributions-submit": "Cari",
        "whatlinkshere": "Pautan baliak",
        "autoblocker": "Sakek otomatih dek alamaik IP lah digunoan jo \"[[User:$1|$1]]\".\nAlasan disakek untuak $1 adolah \"''$2''\"",
        "blocklogpage": "Log sakek",
        "blocklogentry": "manyakek [[$1]] dalam maso $2 $3",
+       "reblock-logentry": "maubah panyakekan [[$1]] jo maso abih $2 $3",
        "blocklogtext": "Di bawah ko adolah log sakek jo palapehan sakek pado pangguno.\nAlamaik IP nan disakek sacaro otomatis indak tadapaik dalam daftar ko.\nCaliak [[Special:BlockList|daftar sakek]] untuak kasado pangguno nan kini kanai sakek.",
        "unblocklogentry": "lapeh sakek $1",
        "block-log-flags-anononly": "hanyo pangguno anonim",
        "tooltip-pt-mycontris": "Daftar jariah {{GENDER:|Sanak}}",
        "tooltip-pt-login": "Sanak disaranan untuak masuak log; walaupun indak wajib",
        "tooltip-pt-logout": "Kalua log",
-       "tooltip-pt-createaccount": "Sanak dianjuaan mambuek akun dan masuak log; walaupun hal iko indak aruih",
-       "tooltip-ca-talk": "Parudiangan tantang isi laman",
+       "tooltip-pt-createaccount": "Sanak disaranan mambuek akun dan masuak log; walaupun hal iko indak wajib",
+       "tooltip-ca-talk": "Parundiangan tantang isi laman",
        "tooltip-ca-edit": "Suntiang laman ko",
        "tooltip-ca-addsection": "Mulai bagian baru",
        "tooltip-ca-viewsource": "Laman ko dilinduangi.\nSanak hanyo buliah mancaliak sumbernyo sajo",
        "tooltip-ca-unprotect": "Tuka palinduangan laman ko",
        "tooltip-ca-delete": "Hapuih laman ko",
        "tooltip-ca-move": "Pindahkan laman ko",
-       "tooltip-ca-watch": "Tambahkan laman ko ka daftar pantau Sanak",
+       "tooltip-ca-watch": "Tambahan laman ko ka daftar pantau Sanak",
        "tooltip-ca-unwatch": "Kaluaan laman ko dari daftar pantau",
        "tooltip-search": "Cari {{SITENAME}}",
        "tooltip-search-go": "Cari laman jo namo nan samo jikok ado",
        "tooltip-search-fulltext": "Cari laman untuak teks ko",
-       "tooltip-p-logo": "Kunjuangi palanta",
-       "tooltip-n-mainpage": "Kunjuangi palanta",
-       "tooltip-n-mainpage-description": "Kunjuangi palanta",
+       "tooltip-p-logo": "Kunjuangi laman utamo",
+       "tooltip-n-mainpage": "Kunjuangi laman utamo",
+       "tooltip-n-mainpage-description": "Kunjuangi laman utamo",
        "tooltip-n-portal": "Tantang proyek, nan dapek Sanak buek, dima ka basobok",
        "tooltip-n-currentevents": "Cari informasi manganai latar balakang kajadian ko",
        "tooltip-n-recentchanges": "Daftar parubahan baru dalam wiki",
        "tooltip-t-upload": "Muek berkas",
        "tooltip-t-specialpages": "Daftar kasado laman istimewa",
        "tooltip-t-print": "Versi cetak dari laman ko",
-       "tooltip-t-permalink": "Pautan parmanen untuak revisi laman ko",
+       "tooltip-t-permalink": "Pautan permanen untuak revisi laman ko",
        "tooltip-ca-nstab-main": "Caliak isi laman",
        "tooltip-ca-nstab-user": "Caliak laman pangguno",
        "tooltip-ca-nstab-media": "Caliak laman media",
        "tooltip-save": "Simpan nan diubah",
        "tooltip-preview": "Caliak lu nan diubah, gunoan ko sabalun manyimpan",
        "tooltip-diff": "Caliak parubahan nan lah dibuek",
-       "tooltip-compareselectedversions": "Caliak pabedoan antaro duo revisi piliahan laman ko",
+       "tooltip-compareselectedversions": "Caliak pabedaan antaro duo revisi piliahan laman ko",
        "tooltip-watch": "Tambahkan laman ko ka daftar pantau",
        "tooltip-recreate": "Buek baliak laman walaupun sabananyo pernah dihapuih",
        "tooltip-upload": "Mulai mamuek",
-       "tooltip-rollback": "\"Baliakkan\" uruangkan suntiang laman ko pado kontribusi tarakhir dalam sakali klik",
+       "tooltip-rollback": "\"Baliakkan\" uruangan suntiang laman ko pado jariah tarakhir dalam sakali klik",
        "tooltip-undo": "\"Batalan\" uruangkan panyuntiangan iko jo mambukak bantuak suntiang dalam bantuak pratonton. Hal ko mamungkinkan manambahkan alasan pado kotak ringkasan.",
        "tooltip-preferences-save": "Simpan preferensi",
        "tooltip-summary": "Buek ringkasan pendek",
        "creditspage": "Panghargaan laman",
        "spam_blanking": "Sado revisi nan ado pautan ka $1, kosong",
        "spam_deleting": "Sado revisi nan ado pautan ka $1, dihapuih",
-       "simpleantispam-label": "Pamarisoan anti-spam.\n<strong>Jan</strong> diisi!",
+       "simpleantispam-label": "Pamaresoan anti-spam.\n<strong>Jan</strong> diisi!",
        "pageinfo-title": "Informasi untuak \"$1\"",
        "pageinfo-not-current": "Maaf, indak dapek mangagiahan informasi ko ka revisi lamo.",
        "pageinfo-header-basic": "Informasi dasar",
        "pageinfo-article-id": "ID Laman",
        "pageinfo-language": "Bahaso isi laman",
        "pageinfo-content-model": "Model isi laman",
-       "pageinfo-robot-policy": "Pembuekan indek dek robot",
+       "pageinfo-robot-policy": "Pambuatan indeks dek robot",
        "pageinfo-robot-index": "Dapek diindekskan",
        "pageinfo-robot-noindex": "Indak diijinan",
        "pageinfo-watchers": "Bara urang nan mambaco",
        "pageinfo-few-watchers": "Kurang dari $1 {{PLURAL:$1|pambaco}}",
-       "pageinfo-redirects-name": "Jumalah pangaliahan ka laman ko",
+       "pageinfo-redirects-name": "Jumlah pangaliahan ka laman ko",
        "pageinfo-subpages-name": "Sublaman dari laman ko",
        "pageinfo-subpages-value": "$1 ($2 {{PLURAL:$2|pangaliahan}}; $3 {{PLURAL:$3|bukan pangaliahan}})",
        "pageinfo-firstuser": "Pambuek laman",
        "pageinfo-toolboxlink": "Informasi laman",
        "pageinfo-redirectsto": "Dialiahkan ka",
        "pageinfo-redirectsto-info": "info",
-       "pageinfo-contentpage": "Dihituang sabagai laman konten",
+       "pageinfo-contentpage": "Dietong sabagai laman konten",
        "pageinfo-contentpage-yes": "Yo",
        "pageinfo-protect-cascading": "Palinduangan baruruik dari siko",
        "pageinfo-protect-cascading-yes": "Yo",
        "variantname-kk-tr": "kk-tr",
        "variantname-kk-cn": "kk-cn",
        "metadata": "Metadata",
-       "metadata-help": "Berkas ko ado informasi tambahan nan mungkin ditambahan dek kamera digital atau pemindai nan digunoan untuak mambuek atau mandigitalisasi berkas ko. Jikok berkas ko lah mangalami parubahan, rincian nan ado mungkin indak sacaro jaleh mancerminkan parubahan dari berkas tu.",
+       "metadata-help": "Berkas ko ado informasi tambahan nan mungkin ditambahan dek kamera digital atau pamindai nan digunoan untuak mambuek atau mandigitalisasi berkas ko. Jikok berkas ko lah mangalami parubahan, rincian nan ado mungkin indak sacaro jaleh mancaminan parubahan dari berkas tu.",
        "metadata-expand": "Tunjuakan rincian tambahan",
        "metadata-collapse": "Suruakan rincian tambahan",
-       "metadata-fields": "Tapak metadata gamba nan didata dalam pasan ko akan di masuakan pado tampilan laman gambar katiko tabel metadata disuruakkan. \nNan lainnyo akan tasuruak sacaro baku.\n* make\n* model\n* datetimeoriginal\n* exposuretime\n* fnumber\n* isospeedratings\n* focallength\n* artist\n* copyright\n* imagedescription\n* gpslatitude\n* gpslongitude\n* gpsaltitude",
+       "metadata-fields": "Tapak metadata gambar nan didata dalam pasan ko ka dimasuakan pado tampilan laman gambar katiko tabel metadata disuruakan. \nNan lainnyo ka tasuruak sacaro baku.\n* make\n* model\n* datetimeoriginal\n* exposuretime\n* fnumber\n* isospeedratings\n* focallength\n* artist\n* copyright\n* imagedescription\n* gpslatitude\n* gpslongitude\n* gpsaltitude",
        "namespacesall": "sadonyo",
        "monthsall": "sadonyo",
        "imgmultipagenext": "Laman salanjuiknyo →",
+       "imgmultigo": "Cari!",
+       "imgmultigoto": "Pai ka laman $1",
        "table_pager_limit_label": "Item per laman:",
        "table_pager_limit_submit": "Tuju",
        "autosumm-new": "←Mambuek laman baisi \"$1\"",
        "version-entrypoints-header-url": "URL",
        "version-entrypoints-articlepath": "[https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:$wgArticlePath Artikel path]",
        "version-entrypoints-scriptpath": "[https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:$wgScriptPath Skrip path]",
-       "redirect": "Pengaliahan badasa ID berkas, pangguno, laman, revisi, atau log",
-       "redirect-summary": "Laman istimewa ko baraliah ka berkas (sasuai namo berkasnya), laman (sasuai ID parubahannya), atau laman pangguno (sasuai ID numerik panggunonya). Panggunoan: [[{{#Special:Redirect}}/file/Example.jpg]], [[{{#Special:Redirect}}/revision/328429]], atau [[{{#Special:Redirect}}/user/101]].",
+       "redirect": "Pangaliahan badasa ID berkas, pangguno, laman, revisi, atau log",
+       "redirect-summary": "Laman istimewa ko baraliah ka berkas (sasuai namo berkasnyo), laman (sasuai ID parubahannya), atau laman pangguno (sasuai ID numerik panggunonya). Panggunoan: [[{{#Special:Redirect}}/file/Example.jpg]], [[{{#Special:Redirect}}/revision/328429]], atau [[{{#Special:Redirect}}/user/101]].",
        "redirect-submit": "Tuju",
        "redirect-lookup": "Pancarian:",
        "redirect-value": "Nilai",
        "tags": "Tag parubahan nan sah",
        "tag-filter": "[[Special:Tags|Tag]] sariang:",
        "tag-filter-submit": "Sariang",
-       "tag-list-wrapper": "[[Istimewa:Tags|{{PLURAL:$1|Tag|Tags}}]]: $2",
+       "tag-list-wrapper": "[[Istimewa:Tag|{{PLURAL:$1|Tag}}]]: $2",
        "tags-title": "Tag",
        "tags-intro": "Laman ko barisi daftar tag nan dapek ditandoi dek parangkaik lunak jo suntiangan dan maknanyo.",
        "tags-tag": "Namo tag",
        "compare-revision-not-exists": "Revisi nan dituju indak basobok.",
        "dberr-problems": "Maaf! Situs ko mangalami masalah teknis.",
        "htmlform-required": "Nilai ko diparaluan",
-       "logentry-delete-delete": "$1 {{GENDER:$2|mangapuih}} laman $3",
+       "logentry-delete-delete": "$1 {{GENDER:$2|maapuih}} laman $3",
        "logentry-delete-restore": "$1 {{GENDER:$2|mangambalian}} laman $3 ($4)",
        "logentry-delete-revision": "$1 {{GENDER:$2|mangubah}} tampilan dari {{PLURAL:$5|revisi|$5 revisi}} di laman $3: $4",
-       "revdelete-content-hid": "isi disambunyikan",
+       "revdelete-content-hid": "isi disuruakan",
        "logentry-move-move": "$1 {{GENDER:$2|mamindahan}} laman $3 ka $4",
        "logentry-move-move-noredirect": "$1 {{GENDER:$2|mamindahan}} laman $3 ka $4 tanpa mambuek pangaliahan",
        "logentry-move-move_redir": "$1 {{GENDER:$2|mamindahan}} laman $3 ka $4 maimpok pangaliahan lamo",
        "logentry-move-move_redir-noredirect": "$1 {{GENDER:$2|mamindahan}} laman $3 ka $4 maimpok pangaliahan lamo tanpa mambuek pangaliahan",
        "logentry-patrol-patrol": "$1 {{GENDER:$2|manandoi}} revisi $4 dari laman $3 tapatroli",
-       "logentry-patrol-patrol-auto": "$1 otomatih {{GENDER:$2|manandoi}} revisi $4 dari laman $3 tapatroli",
+       "logentry-patrol-patrol-auto": "$1 otomatis {{GENDER:$2|manandoi}} revisi $4 dari laman $3 tapatroli",
        "logentry-newusers-newusers": "Akun pangguno $1 alah {{GENDER:$2|dibuek}}",
        "logentry-newusers-create": "Akun pangguno $1 alah {{GENDER:$2|dibuek}}",
        "logentry-newusers-create2": "Akun pangguno $3 alah {{GENDER:$2|dibuek}} dek $1",
        "logentry-newusers-byemail": "Akun pangguno $3 alah {{GENDER:$2|dibuek}} dek $1 dan kato sandi alah dikirim jo surel",
-       "logentry-newusers-autocreate": "Akun pangguno $1 alah {{GENDER:$2|dibuek}} sacaro otomatih",
+       "logentry-newusers-autocreate": "Akun pangguno $1 alah {{GENDER:$2|dibuek}} sacaro otomatis",
        "logentry-rights-rights": "$1 {{GENDER:$2|maubah}} kaanggotaan kalompok $3 dari $4 manjadi $5",
        "logentry-rights-rights-legacy": "$1 {{GENDER:$2|maubah}} kaanggotaan kalompok $3",
        "logentry-upload-upload": "$1 {{GENDER:$2|mangunggah}} $3",
+       "logentry-upload-overwrite": "$1 {{GENDER:$2|maunggah}} versi baru dari $3",
        "rightsnone": "(indak ado)",
        "searchsuggest-search": "Cari {{SITENAME}}",
        "searchsuggest-containing": "Barisi...",
index c7e5cb1..5664207 100644 (file)
@@ -65,7 +65,7 @@
        "tog-watchlisthideminor": "Sembunyikan suntingan kecil daripada senarai pantau",
        "tog-watchlisthideliu": "Sembunyikan suntingan oleh pengguna yang telah log masuk daripada senarai pantau",
        "tog-watchlistreloadautomatically": "Muat semula senarai pantau secara automatik setiap kali penapis berubah (perlu JavaScript)",
-       "tog-watchlistunwatchlinks": "Tambah pautan terus untuk nyahpantau/pantau pada setiap tajuk dalam senarai pantau (JavaScript diperlukan oleh fungsi ini)",
+       "tog-watchlistunwatchlinks": "Tambah penanda pantau/bukan pantau terus ({{int:Watchlist-unwatch}}/{{int:Watchlist-unwatch-undo}}) ke halaman yang dipantau dengan perubahan (JavaScript diperlukan untuk kefungsian togol)",
        "tog-watchlisthideanons": "Sembunyikan suntingan oleh pengguna tanpa nama daripada senarai pantau",
        "tog-watchlisthidepatrolled": "Sembunyikan suntingan yang telah dironda daripada senarai pantau",
        "tog-watchlisthidecategorization": "Sorokkan pengkategorian laman",
@@ -75,6 +75,7 @@
        "tog-norollbackdiff": "Abaikan perbezaan selepas melakukan pengunduran suntingan.",
        "tog-useeditwarning": "Berikan saya amaran apabila saya meninggalkan sesebuah laman penyuntingan tanpa menyimpan perubahan",
        "tog-prefershttps": "Sentiasa gunakan sambungan terlindung apabila log masuk",
+       "tog-showrollbackconfirmation": "Tunjukkan prom pengesahan apabila mengklik pautan pengembalian",
        "underline-always": "Sentiasa",
        "underline-never": "Jangan",
        "underline-default": "Tetapan lalai kulit/pelayar",
        "may": "Mei",
        "jun": "Jun",
        "jul": "Jul",
-       "aug": "Ogs",
+       "aug": "Ogo",
        "sep": "Sep",
        "oct": "Okt",
        "nov": "Nov",
        "navigation-heading": "Menu pandu arah",
        "errorpagetitle": "Ralat",
        "returnto": "Kembali ke $1.",
-       "tagline": "Daripada {{SITENAME}}.",
+       "tagline": "Daripada {{SITENAME}}",
        "help": "Bantuan",
+       "help-mediawiki": "Bantuan tentang MediaWiki",
        "search": "Cari",
        "search-ignored-headings": " #<!-- jangan usik baris ini --> <pre>\n# Tajuk yang akan diabaikan oleh pencarian.\n# Suntingannya diperlakukan sebaik sahaja laman yang bertajuk ini diindekskan.\n# Anda boleh memaksakan pengindeksan semula laman dengan melakukan suntingan nol (null edit).\n# Sintaks adalah seperti berikut:\n#   * Semuanya dari aksara \"#\" ke hujung baris dikira komen.\n#   * Setiap baris tak kosong ialah tajuk yang setepatnya untuk diabaikan.\nRujukan\nPautan luar\nLihat juga\n #</pre> <!-- jangan usik baris ini -->",
        "searchbutton": "Cari",
        "history": "Sejarah laman",
        "history_short": "Sejarah",
        "history_small": "sejarah",
-       "updatedmarker": "dikemaskinikan sejak kunjungan terakhir saya",
+       "updatedmarker": "dikemaskinikan sejak kunjungan terakhir anda",
        "printableversion": "Versi boleh cetak",
        "permalink": "Pautan kekal",
        "print": "Cetak",
        "protect_change": "ubah",
        "unprotect": "Ubah perlindungan",
        "newpage": "Laman baru",
-       "talkpagelinktext": "Perbincangan",
+       "talkpagelinktext": "bincang",
        "specialpage": "Laman khas",
-       "personaltools": "Alatan peribadi",
+       "personaltools": "Alat peribadi",
        "talk": "Perbincangan",
        "views": "Rupa",
        "toolbox": "Peralatan",
        "redirectedfrom": "(Dilencongkan dari $1)",
        "redirectpagesub": "Laman lencongan",
        "redirectto": "Lencong ke:",
-       "lastmodifiedat": "Laman ini diubah buat kali terakhir pada $2, $1.",
+       "lastmodifiedat": "Laman ini kali terakhir disunting pada $2, $1.",
        "viewcount": "Laman ini telah dilihat {{PLURAL:$1|sekali|sebanyak $1 kali}}.",
        "protectedpage": "Laman dilindungi",
        "jumpto": "Lompat ke:",
        "copyrightpage": "{{ns:project}}:Hak cipta",
        "currentevents": "Hal semasa",
        "currentevents-url": "Project:Hal semasa",
-       "disclaimers": "Penolak tuntutan",
-       "disclaimerpage": "Project:Penolak tuntutan umum",
+       "disclaimers": "Penafian",
+       "disclaimerpage": "Project:Penafian umum",
        "edithelp": "Bantuan menyunting",
        "helppage-top-gethelp": "Bantuan",
        "mainpage": "Laman Utama",
        "mainpage-description": "Laman utama",
        "policy-url": "Project:Dasar",
        "portal": "Portal masyarakat",
-       "portal-url": "Project:Portal Masyarakat",
+       "portal-url": "Project:Portal masyarakat",
        "privacy": "Dasar privasi",
        "privacypage": "Project:Dasar privasi",
        "badaccess": "Ralat kebenaran",
        "page-atom-feed": "Suapan Atom \"$1\"",
        "feed-atom": "Atom",
        "feed-rss": "RSS",
-       "red-link-title": "$1 (tidak wujud)",
+       "red-link-title": "$1 (laman tidak wujud)",
        "sort-descending": "Menyusun secara menurun",
        "sort-ascending": "Menyusun secara menaik",
        "nstab-main": "Laman",
        "badarticleerror": "Tindakan ini tidak boleh dilaksanakan pada laman ini.",
        "cannotdelete": "Laman atau fail $1 tidak dapat dihapuskan.\nIa mungkin telah pun dihapuskan oleh orang lain.",
        "cannotdelete-title": "Laman \"$1\" tidak dapat dihapuskan",
+       "delete-scheduled": "Halaman \"$1\" dijadualkan untuk dihapus. Sila bersabar.",
        "delete-hook-aborted": "Penghapusan dibatalkan oleh penyangkuk.\nTiada sebab diberikan.",
        "no-null-revision": "Semakan nol baru untuk \"$1\" tidak dapat diwujudkan",
        "badtitle": "Tajuk tidak sah",
        "cascadeprotected": "Laman ini telah dilindungi daripada disunting kerana ia termasuk dalam {{PLURAL:$1|laman|laman-laman}} berikut, yang dilindungi dengan opsyen \"melata\" dipasang:\n$2",
        "namespaceprotected": "Anda tidak mempunyai keizinan untuk menyunting laman dalam ruang nama '''$1'''.",
        "customcssprotected": "Anda tidak dibenarkan menyunting laman JavaScript ini kerana ia mengandungi tetapan peribadi pengguna lain.",
+       "customjsonprotected": "Anda tidak dibenarkan menyunting laman JSON ini kerana ia mengandungi tetapan peribadi pengguna lain.",
        "customjsprotected": "Anda tidak dibenarkan menyunting laman JavaScript ini kerana ia mengandungi tetapan peribadi pengguna lain.",
+       "sitecssprotected": "Anda tiada mempunyai kebenaran untuk menyunting laman CSS ini kerana ia mungkin memberi kesan kepada semua pengunjung.",
+       "sitejsonprotected": "Anda tiada mempunyai kebenaran untuk menyunting laman JSON ini kerana ia mungkin memberi kesan kepada semua pengunjung.",
+       "sitejsprotected": "Anda tiada mempunyai kebenaran untuk menyunting laman JavaScript ini kerana ia mungkin memberi kesan kepada semua pengunjung.",
        "mycustomcssprotected": "Anda tiada kebenaran untuk menyunting halaman CSS ini.",
+       "mycustomjsonprotected": "Anda tiada mempunyai kebenaran untuk menyunting laman JSON ini.",
        "mycustomjsprotected": "Anda tiada kebenaran untuk menyunting halaman JavaScript ini.",
        "myprivateinfoprotected": "Anda tidak mempunyai kebenaran untuk menyunting maklumat peribadi anda.",
        "mypreferencesprotected": "Anda tidak mempunyai kebenaran untuk menyunting tetapan keutamaan anda.",
        "virus-scanfailed": "pengimbasan gagal (kod $1)",
        "virus-unknownscanner": "antivirus tidak dikenali:",
        "logouttext": "'''Anda telah log keluar.'''\n\nSila ingat bahawa sesetengah halaman mungkin masih dipaparkan seolah-olah anda masih log masuk hingga anda memadamkan cache pelayar anda.",
+       "logging-out-notify": "Anda sedang dilog keluar, sila tunggu.",
+       "logout-failed": "Tidak boleh melog keluar sekarang: $1",
        "cannotlogoutnow-title": "Tidak boleh melog keluar sekarang",
        "cannotlogoutnow-text": "Melog keluar tidak boleh dilakukan apabila menggunakan $1",
        "welcomeuser": "Selamat datang, $1!",
        "badretype": "Sila ulangi kata laluan dengan betul.",
        "usernameinprogress": "Pembukaan akaun untuk nama pengguna ini sudah sedang dijalankan. Sila tunggu.",
        "userexists": "Nama pengguna yang diisikan telah pun digunakan.\nSila pilih nama yang lain.",
+       "createacct-normalization": "Nama pengguna anda akan dilaraskan ke \"$2\" atas sebab had teknikal.",
        "loginerror": "Ralat log masuk",
        "createacct-error": "Ralat pembukaan akaun",
        "createaccounterror": "Tidak dapat mencipta akaun: $1",
        "wrongpasswordempty": "Kata laluan yang dimasukkan adalah kosong. Sila cuba lagi.",
        "passwordtooshort": "Kata laluan mestilah sekurang-kurangnya {{PLURAL:$1|1 aksara|$1 aksara}}.",
        "passwordtoolong": "Kata laluan tidak boleh melebihi $1 aksara.",
-       "passwordtoopopular": "Kata laluan yang biasa dipilih tidak boleh diguna. Sila pilih kata laluan yang lebih unik.",
+       "passwordtoopopular": "Kata laluan yang biasa dipilih tidak boleh digunakan. Sila pilih kata laluan yang lebih susah untuk diteka.",
+       "passwordinlargeblacklist": "Kata laluan yang dimasukkan terdapat dalam senarai kata laluan yang sangat umum digunakan. Sila pilih kata laluan yang lebih unik.",
        "password-name-match": "Kata laluan anda mesti berbeza daripada nama pengguna anda.",
        "password-login-forbidden": "Penggunaan nama pengguna dan kata laluan ini adalah dilarang.",
        "mailmypassword": "Set semula kata laluan",
        "passwordremindertitle": "Pengingat kata laluan daripada {{SITENAME}}",
-       "passwordremindertext": "Seseorang (mungkin anda, dari alamat IP $1) telah meminta kata laluan baru untuk {{SITENAME}} ($4). Kata laluan sementara baru untuk pengguna \"$2\" ialah \"$3\". Untuk menamatkan prosedur ini, anda perlu log masuk dan tetapkan kata laluan yang baru dengan segera. Kata laluan sementara anda akan luput dalam $5 hari.\n\nJika anda tidak membuat permintaan ini, atau anda telah pun mengingati semula kata laluan anda dan tidak mahu menukarnya, anda boleh mengabaikan pesanan ini dan terus menggunakan kata laluan yang sedia ada.",
+       "passwordremindertext": "Seseorang (dari alamat IP $1) telah meminta kata laluan baru untuk {{SITENAME}} ($4). Kata laluan sementara untuk pengguna \"$2\" telah dicipta dan ditetapkan ke \"$3\". Jika ini adalah niat anda, anda perlu melog masuk dan pilih kata laluan baru sekarang. Kata laluan sementara anda akan mansuh dalam {{PLURAL:$5|sehari|$5 hari}}.\n\nJika orang lain membuat permintaan ini, atau jika anda telah ingat kata laluan anda, dan anda tidak lagi mahu mengubahnya, anda boleh abaikan mesej ini dan terus menggunakan kata laluan lama anda.",
        "noemail": "Tiada alamat e-mel direkodkan bagi pengguna \"$1\".",
        "noemailcreate": "Anda perlu memberikan alamat e-mel sah",
        "passwordsent": "Kata laluan baru telah dikirim kepada alamat\ne-mel yang didaftarkan oleh \"$1\".\nSila log masuk semula setelah anda menerima e-mel tersebut.",
        "botpasswords-existing": "Kata laluan bot yang sedia ada",
        "botpasswords-createnew": "Buat kata laluan bot baru",
        "botpasswords-editexisting": "Ubah kata laluan bot yang sedia ada",
+       "botpasswords-label-needsreset": "(kata laluan perlu ditetapkan semula)",
        "botpasswords-label-appid": "Nama bot:",
        "botpasswords-label-create": "Cipta",
        "botpasswords-label-update": "Kemas kini",
        "botpasswords-restriction-failed": "Bot sekatan kata laluan menghalang log masuk ini.",
        "botpasswords-invalid-name": "Nama pengguna yang dinyatakan tidak mengandungi pemisah kata laluan bot (\"$1\").",
        "botpasswords-not-exist": "Pengguna \"$1\" tidak mempunyai kata laluan bot bernama \"$2\".",
+       "botpasswords-needs-reset": "Kata laluan bot untuk nama bot \"$1\" bagi {{GENDER:$2|pengguna}} \"$2\" mesti ditetapkan semula.",
+       "botpasswords-locked": "Anda tidak dapat melog masuk dengan kata laluan bot kerana akaun anda dikunci.",
        "resetpass_forbidden": "Kata laluan tidak boleh ditukar",
        "resetpass_forbidden-reason": "Kata-kata laluan tidak dapat diubah: $1",
        "resetpass-no-info": "Anda hendaklah log masuk terlebih dahulu untuk mencapai laman ini secara terus.",
        "resetpass-submit-loggedin": "Tukar kata laluan",
        "resetpass-submit-cancel": "Batalkan",
        "resetpass-wrong-oldpass": "Kata laluan sementara atau semasa tidak sah.\nAnda mungkin telah menukar kata laluan anda atau meminta kata laluan sementara yang baru.",
-       "resetpass-recycled": "Sila tukar kata laluan anda kepada yang lain daripada kata laluan semasa.",
+       "resetpass-recycled": "Sila tukar kata laluan anda kepada yang lain daripada kata laluan anda pada masa ini.",
        "resetpass-temp-emailed": "Anda telah log masuk dengan kod sementara yang dikirim secara e-mel.\nUntuk selesai log masuk, anda mesti menetapkan kata laluan yang baru di sini:",
        "resetpass-temp-password": "Kata laluan sementara:",
        "resetpass-abort-generic": "Penukaran kata laluan telah dihenti paksa oleh sambungan.",
        "resetpass-expired": "Kata laluan anda sudah tamat tempoh. Sila tetapkan kata laluan baru untuk log masuk.",
-       "resetpass-expired-soft": "Kata laluan anda sudah tamat tempoh dan perlu direset. Sila buat kata laluan baru sekarang, atau klik \"{{int:authprovider-resetpass-skip-label}}\" untuk reset di masa yang akan datang.",
-       "resetpass-validity-soft": "Kata laluan anda tidak sah: $1.\n\nSila buat kata laluan yang baru sekarang, atau klik \"{{int:authprovider-resetpass-skip-label}}\" untuk reset di masa yang akan datang.",
+       "resetpass-expired-soft": "Kata laluan anda telah mansuh dan perlu ditukar. Sila pilih kata laluan baru sekarang, atau klik \"{{int:authprovider-resetpass-skip-label}}\" untuk menukarnya nanti.",
+       "resetpass-validity": "Kata laluan anda tidak sah: $1\n\nSila tetapkan kata laluan baru untuk melog masuk.",
+       "resetpass-validity-soft": "Kata laluan anda tidak sah: $1.\n\nSila pilih kata laluan baru sekarang, atau klik \"{{int:authprovider-resetpass-skip-label}}\" untuk menukarnya nanti.",
        "passwordreset": "Set semula kata laluan",
        "passwordreset-text-one": "Lengkapkan borang ini untuk mengeset semula kata laluan anda.",
        "passwordreset-text-many": "{{PLURAL:$1|Isi salah satu ruangan berikut untuk menerima kata laluan sementara melalui e-mel.}}",
        "subject-preview": "Pralihat perkara:",
        "previewerrortext": "Ralat berlaku ketika cuba mempratayangkan hasil suntingan anda.",
        "blockedtitle": "Pengguna disekat",
-       "blockedtext": "<strong>Nama pengguna atau alamat IP anda telah disekat.</strong>\n\nSekatan ini dilakukan oleh $1.\nSebab yang telah diberikan ialah <em>$2</em>.\n\n* Sekatan mula: $8\n* Sekatan tamat: $6\n* Pengguna sasaran: $7\n\nAnda boleh hubungi $1 atau [[{{MediaWiki:Grouppage-sysop}}|penyelia]] yang lain untuk membincangkan sekatan ini.\n\nSila ambil perhatian bahawa anda tidak boleh menggunakan ciri \"kirim e-mel kepada pengguna ini\" kecuali sekiranya anda telah menetapkan alamat e-mel yang sah dalam [[Special:Preferences|keutamaan pengguna]] anda dan anda tidak disekat daripada menggunakannya.\n\nAlamat IP semasa anda ialah $3, dan ID sekatan ialah #$5.\nSila sertakan maklumat-maklumat di atas dalam sebarang pertanyaan yang anda membuat.",
-       "autoblockedtext": "Alamat IP anda telah disekat secara automatik kerana ia digunakan oleh pengguna lain yang disekat oleh $1.\nSebab yang dinyatakan ialah:\n\n:<em>$2</em>\n\n* Sekatan mula: $8\n* Sekatan tamat: $6\n* Pengguna sasaran: $7\n\nAnda boleh menghubungi $1 atau seorang [[{{MediaWiki:Grouppage-sysop}}|penyelia]] yang lain untuk membincangkan sekatan ini.\n\nSila ambil perhatian bahawa anda tidak boleh menggunakan ciri \"kirim e-mel kepada pengguna ini\" kecuali sekiranya anda telah menetapkan alamat e-mel yang sah dalam [[Special:Preferences|keutamaan pengguna]] anda dan anda tidak disekat daripada menggunakannya.\n\nAlamat IP semasa anda ialah $3, dan ID sekatan ialah #$5.\nSila sertakan maklumat-maklumat di atas dalam sebarang pertanyaan yang anda membuat.",
+       "blocked-email-user": "<strong>Nama pengguna anda telah disekat dari menghantar e-mel. Anda masih boleh menyunting halaman lain pada wiki ini.</strong> Anda boleh melihat butiran sekatan secara penuh di [[Special:MyContributions|sumbangan akaun]]\n\nSekatan dibuat oleh $1.\n\nSebab yang diberikan ialah <em>$2</em>.\n\n* Mula sekatan: $8\n* Tarikh mansuh sekatan: $6\n* Pengguna sasaran: $7\n* ID sekatan #$5",
+       "blockedtext-partial": "<strong>Nama pengguna atau alamat IP anda telah diekat dari membuat sebarang perubahan kepada laman ini. Anda masih boleh menyunting laman lain di wiki ini.</strong> Anda boleh lihat butiran sekatan secara penuh di [[Special:MyContributions|sumbangan akaun]].\n\nSekatan telah dibuat oleh $1.\n\nSebab yang diberikan ialah <em>$2</em>.\n\n* Mula sekatan: $8\n* Tarikh mansuh sekatan: $6\n* Pengguna sasaran: $7\n* ID sekatan #$5",
+       "blockedtext": "<strong>Nama pengguna atau alamat IP anda telah disekat.</strong>\n\nSekatan telah dibuat oleh $1.\nSebab yang diberikan ialah <em>$2</em>.\n\n* Mula sekatan: $8\n* Tarikh mansuh sekatan: $6\n* Pengguna sasaran: $7\n\nAnda boleh menghubungi $1 atau [[{{MediaWiki:Grouppage-sysop}}|penyelia]] yang lain untuk membincangkan sekatan tersebut.\n\nAnda tidak boleh menggunakan ciri \"{{int:emailuser}}\" kecuali alamat e-mel yang sah diperincikan dalam [[Special:Preferences|keutamaan pengguna]] anda dan anda tidak disekat dari menggunakannya.\n\nAlamat IP semasa anda ialah $3, dan ID sekatan ialah #$5.\nSila sertakan semua butiran di atas dalam sebarang pertanyaan yang anda buat.",
+       "autoblockedtext": "Alamat IP anda telah disekat secara automatik kerana ia telah digunakan oleh pengguna lain, yang telah disekat oleh $1.\nSebab yang diberikan ialah:\n\n:<em>$2</em>\n\n* Mula sekatan: $8\n* Tarikh mansuh sekatan: $6\n* Pengguna sasaran: $7\n\nAnda boleh menghubungi $1 atau salah seorang [[{{MediaWiki:Grouppage-sysop}}|penyelia]] yang lain untuk membincangkan sekatan tersebut.\n\nSila ambil perhatian bahawa anda tidak boleh menggunakan ciri \"{{int:emailuser}}\" kecuali anda mempunyai alamat e-mel yang sah yang didaftarkan dalam [[Special:Preferences|keutamaan pengguna]] anda dan anda tidak disekat dari menggunakannya.\n\nAlamat IP semasa anda ialah $3, dan ID sekatan ialah #$5.\nSila sertakan semua butiran di atas dalam sebarang pertanyaan yang anda buat.",
        "systemblockedtext": "Nama pengguna atau alamat IP anda telah diblok secara automatik oleh MediaWiki. Alasan diberikan ialah:\n\n:<em>$2</em>\n\n* Mula blok: $8\n* Luput blok: $6\n* Yang diblok yang dimaksudkan: $7\n\nAlamat IP anda sekarang ialah $3.\nSila sertakan butiran di atas dalam sebarang pertanyaan yang anda buat.",
        "blockednoreason": "tiada sebab diberikan",
+       "blockedtext-composite": "<strong>Nama pengguna atau alamat IP anda telah disekat.</strong>\n\nSebab yang diberikan ialah:\n\n:<em>$2</em>.\n\n* Mula sekatan: $8\n* Tarikh mansuh sekatan terpanjang: $6\n\nAlamat IP semasa anda ialah $3.\nSila sertakan semua butiran di atas dalam sebarang pertanyaan yang anda buat.",
+       "blockedtext-composite-reason": "Terdapat sekatan berganda terhadap akaun dan/atau alamat IP anda.",
        "whitelistedittext": "Anda hendaklah $1 terlebih dahulu untuk menyunting laman.",
        "confirmedittext": "Anda perlu mengesahkan alamat e-mel anda terlebih dahulu untuk menyunting mana-mana laman. Sila tetapkan dan sahkan alamat e-mel anda melalui [[Special:Preferences|laman keutamaan]].",
        "nosuchsectiontitle": "Tidak ada bahagian ini",
        "userpage-userdoesnotexist": "Akaun pengguna \"<nowiki>$1</nowiki>\" tidak berdaftar. Sila pastikan sama ada anda mahu mencipta/menyunting laman ini.",
        "userpage-userdoesnotexist-view": "Akaun pengguna \"$1\" tidak berdaftar.",
        "blocked-notice-logextract": "Pengguna ini sedang disekat.\nMasukan log sekatan terakhir disediakan di bawah sebagai rujukan:",
-       "clearyourcache": "'''Catatan:''' Selepas menyimpan laman ini, anda mungkin perlu membersihkan cache pelayar web anda terlebih dahulu untuk mengenakan perubahan.\n*'''Firefox/Safari:''' Tekan terus ''Shift'' sambil klik ''Reload'', atau tekan ''Ctrl+F5'' atau tekan ''Ctrl+R''  (''⌘+R'' bagi Mac)\n*'''Google Chrome:''' Tekan ''Ctrl+Shift+R''  (''⌘+Shift+R'' bagi Mac)\n*'''Internet Explorer:''' Tekan terus ''Ctrl'' sambil klik ''Refresh'', atau tekan ''Ctrl+F5''\n*'''Opera:''' Kosongkan cache di menu ''Tools → Preferences''",
+       "clearyourcache": "<strong>Catatan:</strong> Selepas menyimpan, ada mungkin perlu memintas cache pelayar anda untuk melihat perubahannya.\n* <strong>Firefox / Safari:</strong> Tahan <em>Shift</em> sambil mengklik <em>Reload</em>, atau tekan sama ada <em>Ctrl-F5</em> atau <em>Ctrl-R</em> (<em>⌘-R</em> pada Mac)\n* <strong>Google Chrome:</strong> Tekan <em>Ctrl-Shift-R</em> (<em>⌘-Shift-R</em> pada Mac)\n* <strong>Internet Explorer:</strong> Tahan <em>Ctrl</em> sambil mengklik <em>Refresh</em>, atau tekan <em>Ctrl-F5</em>\n* <strong>Opera:</strong> Pergi ke <em>Menu → Settings</em> (<em>Opera → Preferences</em> pada Mac) dan kemudian ke <em>Privacy & security → Clear browsing data → Cached images and files</em>.",
        "usercssyoucanpreview": "'''Petua:''' Gunakan butang \"{{int:showpreview}}\" untuk menguji CSS baru anda sebelum menyimpan.",
+       "userjsonyoucanpreview": "<strong>Petua:</strong> Gunakan butang \"{{int:showpreview}}\" untuk menguji JSON baru anda sebelum menyimpan.",
        "userjsyoucanpreview": "'''Petua:''' Gunakan butang \"{{int:showpreview}}\" untuk menguji JavaScript baru anda sebelum menyimpan.",
        "usercsspreview": "'''Ingat bahawa anda hanya sedang melihat pralihat CSS peribadi anda. Laman ini belum lagi disimpan!'''",
+       "userjsonpreview": "<strong>Ingat bahawa anda hanya menguji/mempralihat konfigurasi JSON pengguna anda. Ia belum lagi disimpan!</strong>",
        "userjspreview": "'''Ingat bahawa anda hanya menguji/melihat pralihat JavaScript anda, ia belum lagi disimpan!'''",
        "sitecsspreview": "'''Ingat bahawa anda cuma melihat pralihat CSS ini.'''\n'''Ia belum lagi disimpan!'''",
+       "sitejsonpreview": "<strong>Ingat bahawa anda hanya mempralihat konfigurasi JSON ini. Ia belum lagi disimpan!</strong>",
        "sitejspreview": "'''Ingat bahawa anda cuma mempralihat kod JavaScript ini.'''\n'''Ia belum lagi disimpan!'''",
-       "userinvalidconfigtitle": "'''Amaran:''' Rupa \"$1\" tidak wujud. Ingat bahawa laman tempahan .css dan .js menggunakan tajuk berhuruf kecil, contohnya {{ns:user}}:Anu/vector.css tidak sama dengan {{ns:user}}:Anu/Vector.css.",
+       "userinvalidconfigtitle": "<strong>Amaran:</strong> Tiada terdapat kulit \"$1\".\nLaman .css, .json, dan .js yang tersuai menggunakan tajuk huruf kecil, cth.  {{ns:user}}:Foo/vector.css dan bukannya {{ns:user}}:Foo/Vector.css.",
        "updated": "(Dikemas kini)",
        "note": "'''Catatan:'''",
        "previewnote": "'''Ingatlah bahawa ini hanya pralihat.'''\nPerubahan anda belum disimpan!",
        "continue-editing": "Pergi ke tempat menyunting",
        "previewconflict": "Paparan ini merupakan teks di bahagian atas dalam kotak sunting teks. Teks ini akan disimpan sekiranya anda memilih berbuat demikian.",
-       "session_fail_preview": "'''Kami tidak dapat memproses suntingan anda kerana kehilangan data sesi. Sila cuba lagi. Jika masalah ini berlanjutan, [[Special:UserLogout|log keluar]] dahulu, kemudian log masuk sekali lagi.'''",
-       "session_fail_preview_html": "'''Kami tidak dapat memproses suntingan anda kerana kehilangan data sesi.'''\n\n''Oleh sebab {{SITENAME}} membenarkan HTML mentah, ciri pralihat terpaksa disorokkan sebagai perlindungan daripada serangan JavaScript.''\n\n'''Jika ini ialah penyuntingan yang sah, sila cuba lagi. Jika masalah ini berlanjutan, [[Special:UserLogout|log keluar]] dahulu, kemudian log masuk sekali lagi.'''",
+       "session_fail_preview": "Maaf! Kami tidak dapat memproses suntingan anda disebabkan kehilangan data sesi.\n\nAnda mungkin telah dilog keluar. <strong>Sila sahkan bahawa anda masih melog masuk dan cuba lagi</strong>.\nJika masih tidak berjaya, cuba [[Special:UserLogout|log keluar]] dan log masuk semula, dan pastikan pelayar anda membenarkan kuki dari tapak ini.",
+       "session_fail_preview_html": "Maaf! Kami tidak dapat memproses suntingan anda disebabkan kehilangan data sesi.\n\n<em>Oleh kerana {{SITENAME}} mempunyai HTML mentah didayakan, pralihat disembunyikan sebagai pencegahan daripada serangan JavaScript.</em>\n\n<strong>Jika ini merupakan percubaan suntingan yang sah, sila cuba lagi.</strong>\nJika masih tidak berjaya, cuba [[Special:UserLogout|log keluar]] dan log masuk semula, dan pastikan pelayar anda membenarkan kuki dari tapak ini.",
        "token_suffix_mismatch": "'''Suntingan anda telah ditolak kerana pelanggan anda memusnahkan aksara tanda baca\ndalam token suntingan. Suntingan tersebut telah ditolak untuk menghalang kerosakan teks laman.\nHal ini kadangkala berlaku apabila anda menggunakan khidmat proksi tanpa nama berdasarkan web yang bermasalah.'''",
        "edit_form_incomplete": "'''Beberapa bahagian dari bentuk edit tidak mencapai pelayan, periksa bahawa suntingan anda utuh dan cuba lagi'.'''",
        "editing": "Menyunting $1",
        "yourtext": "Teks anda",
        "storedversion": "Versi yang disimpan",
        "editingold": "'''AMARAN: Anda sedang\nmenyunting sebuah semakan yang sudah ketinggalan zaman.\nJika anda menyimpannya, sebarang perubahan yang dibuat selepas tarikh semakan ini akan hilang.'''",
+       "unicode-support-fail": "Nampaknya pelayar anda tidak menyokong Unicode. Ini diperlukan untuk menyunting laman, jadi suntingan anda tidak disimpan.",
        "yourdiff": "Perbezaan",
        "copyrightwarning": "Sila ambil perhatian bahawa semua sumbangan kepada {{SITENAME}} akan dikeluarkan di bawah $2 (lihat $1 untuk butiran lanjut). Jika anda tidak mahu tulisan anda disunting sewenang-wenangnya oleh orang lain dan diedarkan secara bebas, maka jangan kirim di sini.<br />\nAnda juga berjanji bahawa ini ialah hasil kerja tangan anda sendiri, atau disalin daripada domain awam atau mana-mana sumber bebas lain.\n'''JANGAN KIRIM KARYA HAK CIPTA ORANG LAIN TANPA KEBENARAN!'''",
        "copyrightwarning2": "Sila ambil perhatian bahawa semua sumbangan terhadap {{SITENAME}} boleh disunting, diubah, atau dipadam oleh penyumbang lain. Jika anda tidak mahu tulisan anda disunting sewenang-wenangnya, maka jangan kirim di sini.<br />\nAnda juga berjanji bahawa ini ialah hasil kerja tangan anda sendiri, atau\ndisalin daripada domain awam atau mana-mana sumber bebas lain (lihat $1 untuk butiran lanjut).\n'''JANGAN KIRIM KARYA HAK CIPTA ORANG LAIN TANPA KEBENARAN!'''",
        "editpage-cannot-use-custom-model": "Model kandungan laman ini tidak boleh diubah.",
        "longpageerror": "'''Ralat: Teks yang anda serahkan itu panjangnya {{PLURAL:$1|1|$1}} kilobait, iaitu lebih panjang daripada had maksimum {{PLURAL:$2|1|$2}} kilobait.'''\nOleh itu, ia tidak boleh disimpan.",
-       "readonlywarning": "'''Amaran: Pangkalan data ini dikunci untuk tujuan penyelenggaraan , maka anda tidak akan dapat menyimpan suntingan anda buat sekarang.'''\nAnda boleh menyalin tampal teks anda pada fail teks dan menyimpannya untuk lain kali.\n\nPenyelia yang menguncinya memberikan penjelasan ini: $1",
+       "readonlywarning": "<strong>Amaran: Pangkalan data telah dikunci untuk penyelenggaraan, jadi anda tidak akan dapat menyimpan suntingan anda pada masa ini.</strong>\nAnda mungkin ingin menyalin dan menyisipkan teks anda ke dalam fail teks dan menyimpannya untuk kemudian.\n\nPenyelia sistem yang menguncinya menawarkan penjelasan berikut: $1",
        "protectedpagewarning": "'''Amaran: Laman ini telah dikunci supaya hanya mereka yang mempunyai keistimewaan penyelia boleh menyuntingnya.'''\nMasukan log terakhir ditunjukkan di bawah untuk rujukan:",
-       "semiprotectedpagewarning": "'''Nota:''' Laman ini telah dikunci agar hanya pengguna berdaftar sahaja boleh menyuntingnya.\nMasukan log terakhir ditunjukkan di bawah untuk rujukan:",
-       "cascadeprotectedwarning": "<strong>Amaran:</strong> Laman ini telah dikunci supaya hanya pengguna bertaraf penyelia boleh menyuntingnya kerana ia termasuk dalam {{PLURAL:$1|laman|laman-laman}} berikut yang dilindungi secara melata:",
+       "semiprotectedpagewarning": "<strong>Catatan:</strong> Laman ini telah dilindungi supaya hanya pengguna yang diautosahkan boleh menyuntingnya.\nKemasukan log terkini disediakan di bawah sebagai rujukan:",
+       "cascadeprotectedwarning": "<strong>Amaran:</strong> Laman ini telah dikunci supaya hanya pengguna dengan [[Special:ListGroupRights|hak-hak tertentu]] boleh menyuntingnya kerana ia ditransklusikan dalam {{PLURAL:$1|laman|laman-laman}} dilindungi cascade berikut:",
        "titleprotectedwarning": "'''Amaran: Laman ini telah dikunci hingga [[Special:ListGroupRights|hak-hak tertentu]] diperlukan untuk menciptanya.'''\nMasukan log terakhir ditunjukkan di bawah untuk rujukan:",
        "templatesused": "{{PLURAL:$1|Templat|Templat}} yang digunakan dalam laman ini:",
        "templatesusedpreview": "{{PLURAL:$1|Templat|Templat}} yang digunakan dalam pralihat ini:",
        "permissionserrors": "Ralat kebenaran",
        "permissionserrorstext": "Anda tidak mempunyai keizinan untuk berbuat demikian atas {{PLURAL:$1|sebab|sebab-sebab}} berikut:",
        "permissionserrorstext-withaction": "Anda tidak mempunyai keizinan untuk $2, atas {{PLURAL:$1|sebab|sebab-sebab}} berikut:",
-       "contentmodelediterror": "Anda tidak boleh menyunting semakan ini kerana model kandungannya ialah <code>$1</code> padahal model kandungan semasa laman ini ialah <code>$2</code>.",
+       "contentmodelediterror": "Anda tidak boleh menyunting semakan ini kerana model kandungannya ialah <code>$1</code>, yang berbeza dari model kandungan semasa laman <code>$2</code>.",
        "recreate-moveddeleted-warn": "'''Amaran: Anda sedang mencipta semula sebuah laman yang pernah dihapuskan.'''\n\nAnda harus mempertimbangkan perlunya menyunting laman ini.\nUntuk rujukan, yang berikut ialah log penghapusan bagi laman ini:",
        "moveddeleted-notice": "Laman ini telah dihapuskan.\nLog penghapusan, perlindungan dan pemindahan bagi laman ini dilampirkan di bawah untuk rujukan.",
-       "moveddeleted-notice-recent": "Maaf, laman ini baru-baru sahaja dihapuskan (dalam 24 jam yang lepas).\nLog penghapusan dan pemindahan untuk laman ini dinyatakan di bawah sebagai rujukan.",
+       "moveddeleted-notice-recent": "Maaf, laman ini baru sahaja dihapuskan (dalam 24 jam yang lepas).\nLog penghapusan, perlindungan dan pemindahan untuk laman ini dinyatakan di bawah sebagai rujukan.",
        "log-fulllog": "Lihat log lengkap",
        "edit-hook-aborted": "Suntingan anda telah dibatalkan oleh penyangkuk. Tiada sebab diberikan.",
        "edit-gone-missing": "Laman tersebut telah dihapuskan dan tidak dapat dikemaskinikan.",
        "edit-conflict": "Percanggahan penyuntingan.",
        "edit-no-change": "Suntingan anda diabaikan kerana tiada perubahan dibuat pada teks tersebut.",
+       "edit-slots-cannot-add": "{{PLURAL:$1|Slot|Slot-slot}} berikut tidak disokong di sini: $2.",
+       "edit-slots-cannot-remove": "{{PLURAL:$1|Slot|Slot-slot}} berikut diperlukan dan tidak boleh dibuang: $2.",
+       "edit-slots-missing": "{{PLURAL:$1|Slot|Slot-slot}} berikut hilang: $2.",
        "postedit-confirmation-created": "Halaman telah diwujudkan.",
        "postedit-confirmation-restored": "Halaman telah dipulihkan.",
        "postedit-confirmation-saved": "Suntingan anda telah disimpan.",
        "defaultmessagetext": "Teks mesej asal",
        "content-failed-to-parse": "Kandungan $2 tidak dapat dihuraikan untuk model $1: $3",
        "invalid-content-data": "Data kandungan tidak sah",
-       "content-not-allowed-here": "Kandungan \"$1\" tidak dibenarkan di halaman [[:$2]]",
+       "content-not-allowed-here": "Kandungan \"$1\" tidak dibenarkan di halaman [[:$2]] dalam slot \"$3\"",
        "editwarning-warning": "Meninggalkan laman ini mungkin akan menyebabkan sebarang perubahan yang telah anda lakukan hilang.\nJika anda sudah log masuk, anda boleh melumpuhkan amaran ini di bahagian \"{{int:prefs-editing}}\" dalam keutamaan anda.",
        "editpage-invalidcontentmodel-title": "Model kandungan tidak disokong",
        "editpage-invalidcontentmodel-text": "Model kandungan \"$1\" tidak disokong.",
        "content-model-css": "CSS",
        "content-json-empty-object": "Objek kosong",
        "content-json-empty-array": "Tatasusunan kosong",
+       "deprecated-self-close-category": "Laman menggunakan teg HTML tertutup sendiri yang tidak sah.",
+       "deprecated-self-close-category-desc": "Laman mengandungi teg HTML tertutup sendiri, seperti <code>&lt;b/></code> atau <code>&lt;span/></code>. Ragam mereka akan berubah tidak lama lagi kepada yang lebih konsisten dengan spesifikasi HTML5, supaya penggunaan mereka dalam teks wiki diusangkan.",
        "duplicate-args-warning": "<strong>Amaran:</strong> [[:$1]] sedang memanggil [[:$2]] dengan lebih daripada satu nilai untuk parameter \"$3\". Hanya nilai terakhir yang diberikan akan digunakan.",
        "duplicate-args-category": "Laman yang menggunakan argumen pendua dalam panggilan templat",
        "duplicate-args-category-desc": "Laman ini mengandungi panggilan templat yang menggunakan pendua argumen seperti <code><nowiki>{{foo|bar=1|bar=2}}</nowiki></code> atau <code><nowiki>{{foo|bar|1=baz}}</nowiki></code>.",
        "post-expand-template-argument-warning": "Amaran: Laman ini mengandungi sekurang-kurangnya satu argumen templat yang mempunyai saiz pengembangan yang terlalu besar.\nArgumen-argumen ini telah ditinggalkan.",
        "post-expand-template-argument-category": "Laman yang mengandungi templat dengan argumen yang tidak lengkap",
        "parser-template-loop-warning": "Gelung templat dikesan: [[$1]]",
+       "template-loop-category": "Laman dengan gelung templat",
+       "template-loop-category-desc": "Laman mengandungi gelung templat, iaitu templat yang memanggil dirinya sendiri secara rekursif.",
+       "template-loop-warning": "<strong>Amaran:</strong> Laman ini memanggil [[:$1]] yang menyebabkan gelung templat (panggilan rekursif yang tidak terbatas).",
        "parser-template-recursion-depth-warning": "Had pengulangan templat dilebihi ($1)",
        "language-converter-depth-warning": "Had kedalaman penukar bahasa dilepasi ($1)",
        "node-count-exceeded-category": "Laman yang melebihi had kiraan nod",
        "expansion-depth-exceeded-warning": "Laman terlebih dalam peluasan",
        "parser-unstrip-loop-warning": "Gelung unstrip dikesan",
        "unstrip-depth-warning": "Had rekursi unstrip dilampaui ($1)",
+       "unstrip-depth-category": "Laman di mana kedalaman unstrip telah melebihi hadnya",
+       "unstrip-size-warning": "Saiz unstrip melebihi hadnya ($1)",
+       "unstrip-size-category": "Laman di mana saiz unstrip melebihi hadnya",
        "converter-manual-rule-error": "Ralat dikesan dalam aturan penukaran bahasa manual",
        "undo-success": "Suntingan ini boleh dibatalkan. Sila semak perbandingan di bawah untuk mengesahkan bahawa anda betul-betul mahu melakukan tindakan ini, kemudian simpan perubahan tersebut.",
        "undo-failure": "Suntingan tersebut tidak boleh dibatalkan kerana terdapat suntingan pertengahan yang bercanggah.",
+       "undo-main-slot-only": "Suntingan tidak dapat dibalikkan kerana ia melibatkan kandungan di luar slot utama.",
        "undo-norev": "Suntingan tersebut tidak boleh dibatalkan kerana tidak wujud atau telah dihapuskan.",
        "undo-nochange": "Suntingan itu nampaknya sudah dibatalkan.",
        "undo-summary": "Membatalkan semakan $1 oleh [[Special:Contributions/$2|$2]] ([[User talk:$2|Perbincangan]])",
        "currentrev-asof": "Semakan semasa pada $1",
        "revisionasof": "Semakan pada $1",
        "revision-info": "Semakan $3 pada $1 oleh {{GENDER:$6|$2}}$7",
-       "previousrevision": "←Semakan sebelumnya",
+       "previousrevision": "← Semakan terdahulu",
        "nextrevision": "Semakan berikutnya→",
        "currentrevisionlink": "Semakan semasa",
        "cur": "kini",
        "page_first": "awal",
        "page_last": "akhir",
        "histlegend": "Pemilihan perbezaan: tandakan butang radio bagi versi-versi yang ingin dibandingkan dan tekan butang ''enter'' atau butang di bawah.<br />\nPetunjuk: (kini) = perbezaan dengan versi terkini,\n(akhir) = perbezaan dengan versi sebelumnya, K = suntingan kecil.",
-       "history-fieldset-title": "Cari semakan",
-       "history-show-deleted": "Dihapuskan sahaja",
+       "history-fieldset-title": "Tapis semakan",
+       "history-show-deleted": "Semakan yang dihapus sahaja",
        "histfirst": "terawal",
        "histlast": "terkini",
        "historysize": "($1 bait)",
-       "historyempty": "(kosong)",
+       "historyempty": "kosong",
        "history-feed-title": "Sejarah semakan",
        "history-feed-description": "Sejarah semakan bagi laman ini",
        "history-feed-item-nocomment": "$1 pada $2",
        "revdelete-unsuppress": "Buang batasan pada semakan yang dipulihkan",
        "revdelete-log": "Sebab:",
        "revdelete-submit": "Kenakan ke atas {{PLURAL:$1|versi|versi}} yang dipilih",
-       "revdelete-success": "'''Kebolehnampakan semakan berjaya ditetapkan.'''",
+       "revdelete-success": "Keterlihatan semakan dikemaskinikan.",
        "revdelete-failure": "'''Keterlihatan semakan tidak dapat dikemaskini:'''\n$1",
-       "logdelete-success": "Kebolehnampakan peristiwa ditetapkan.",
+       "logdelete-success": "Keterlihatan log ditetapkan.",
        "logdelete-failure": "'''Log nampak tidak dapat diset:'''\n$1",
        "revdel-restore": "Tukar kebolehnampakan",
        "pagehist": "Sejarah laman",
        "mergehistory-fail-bad-timestamp": "Cap masa tidak sah.",
        "mergehistory-fail-invalid-source": "Halaman asal tidak sah.",
        "mergehistory-fail-invalid-dest": "Halaman tujuan tidak sah.",
+       "mergehistory-fail-no-change": "Penggabungan sejarah tidak menggabungkan sebarang semakan. Sila semak semula parameter laman dan masa.",
+       "mergehistory-fail-permission": "Kebenaran tidak mencukupi untuk menggabungkan sejarah.",
+       "mergehistory-fail-self-merge": "Sumber dan laman sasaran adalah sama.",
+       "mergehistory-fail-timestamps-overlap": "Semakan sumber bertindih atau datang selepas semakan sasaran.",
        "mergehistory-fail-toobig": "Tidak dapat melakukan gabungan sejarah sebab lebih daripada had $1 semakan perlu dipindahkan.",
        "mergehistory-no-source": "Laman sumber $1 tidak wujud.",
        "mergehistory-no-destination": "Laman destinasi $1 tidak wujud.",
        "diff-multi-sameuser": "({{PLURAL:$1|Satu semakan pertengahan|$1 semakan pertengahan}} oleh pengguna yang sama tidak dipaparkan)",
        "diff-multi-otherusers": "({{PLURAL:$1|Satu semakan pertengahan|$1 semakan pertengahan}} oleh {{PLURAL:$2|seorang pengguna lain|$2 orang pengguna}} tidak dipaparkan)",
        "diff-multi-manyusers": "($1 {{PLURAL:$1|semakan pertengahan|semakan pertengahan}} oleh lebih daripada $2 {{PLURAL:$2|pengguna|pengguna}} tidak dipaparkan)",
+       "diff-paragraph-moved-tonew": "Perenggan dipindahkan. Klik untuk melompat ke lokasi baru.",
+       "diff-paragraph-moved-toold": "Perenggan dipindahkan. Klik untuk melompat ke lokasi lama.",
        "difference-missing-revision": "{{PLURAL:$2|Satu semakan|$2 semakan}} bagi perbezaan ini ($1) tidak ditemui.\n\nHal ini biasanya disebabkan oleh pautan perbezaan yang lapuk ke halaman yang sudah dihapuskan.\nButirannya boleh didapati di [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} log penghapusan].",
        "searchresults": "Hasil carian",
-       "searchresults-title": "Hasil carian \"$1\"",
+       "search-filter-title-prefix": "Hanya mencari dalam laman yang mana tajuknya bermula dengan \"$1\"",
+       "search-filter-title-prefix-reset": "Cari semua laman",
+       "searchresults-title": "Hasil carian untuk \"$1\"",
        "titlematches": "Padanan tajuk laman",
        "textmatches": "Padanan teks laman",
        "notextmatches": "Tiada teks laman yang sepadan",
        "search-external": "Carian luar",
        "searchdisabled": "Ciri pencarian dalam {{SITENAME}} dimatikan. Anda boleh mencari melalui Google. Sila ambil perhatian bahawa indeks dalam Google mungkin bukan yang terkini.",
        "search-error": "Berlakunya ralat ketika mencari: $1",
+       "search-warning": "Amaran telah muncul ketika mencari: $1",
        "preferences": "Keutamaan",
        "mypreferences": "Keutamaan",
        "prefs-edits": "Jumlah suntingan:",
        "prefs-editwatchlist-clear": "Kosongkan senarai pantau anda",
        "prefs-watchlist-days": "Had bilangan hari dalam senarai pantau:",
        "prefs-watchlist-days-max": "Maksimum $1 hari",
-       "prefs-watchlist-edits": "Had maksimum perubahan untuk ditunjukkan dalam senarai pantau penuh:",
+       "prefs-watchlist-edits": "Bilangan maksimum perubahan untuk dipaparkan dalam senarai pantau:",
        "prefs-watchlist-edits-max": "Had: 1000",
        "prefs-watchlist-token": "Token senarai pantau:",
+       "prefs-watchlist-managetokens": "Urus token",
        "prefs-misc": "Pelbagai",
        "prefs-resetpass": "Tukar kata laluan",
        "prefs-changeemail": "Tukar atau padamkan alamat e-mel",
        "stub-threshold-disabled": "Dimatikan",
        "recentchangesdays": "Bilangan hari dalam perubahan terkini:",
        "recentchangesdays-max": "(had $1 hari)",
-       "recentchangescount": "Bilangan suntingan yang dipaparkan mengikut tetapan asali:",
-       "prefs-help-recentchangescount": "Ini termasuklah perubahan terkini, sejarah laman dan log.",
-       "prefs-help-watchlist-token2": "Inilah kunci rahsia kepada suapan web senarai pantau anda.\nSesiapa yang mengetahuinya akan boleh membaca senarai pantau anda, jadi jangan kongsinya.\n[[Special:ResetTokens|Klik di sini jika anda perlu mengesetnya semula]].",
+       "recentchangescount": "Bilangan suntingan untuk dipaparkan dalam perubahan terkini, sejarah laman, dan dalam log, secara tersedia:",
+       "prefs-help-recentchangescount": "Bilangan maksimum: 1000",
+       "prefs-help-watchlist-token2": "Ini merupakan kunci rahsia kepada suapan web senarai pantau anda.\nSesiapa sahaja yang mengetahuinya akan dapat membaca senarai pantau anda, jadi jangan mengongsikannya.\nJika perlu, [[Special:ResetTokens|anda boleh menetapkannya semula]].",
+       "prefs-help-tokenmanagement": "Anda boleh melihat dan menetapkan semula kunci rahsia untuk akaun anda yang dapat mengakses suapan Web bagi senarai pantau anda. Sesiapa sahaja yang mengetahui kunci tersebut akan dapat membaca senarai pantau anda, oleh itu jangan mengongsikannya.",
        "savedprefs": "Keutamaan anda disimpan.",
-       "savedrights": "Hak pengguna {{GENDER:$1|$1}} telah disimpan.",
+       "savedrights": "Kumpulan pengguna {{GENDER:$1|$1}} telah disimpan.",
        "timezonelegend": "Zon waktu:",
        "localtime": "Waktu tempatan:",
        "timezoneuseserverdefault": "Gunakan tetapan sediaan wiki ($1)",
-       "timezoneuseoffset": "Lain-lain (nyatakan imbangan)",
+       "timezoneuseoffset": "Lain-lain (perincikan imbangan di bawah)",
+       "timezone-useoffset-placeholder": "Contoh nilai: \"-07:00\" atau \"01:00\"",
        "servertime": "Waktu pelayan:",
        "guesstimezone": "Gunakan tetapan pelayar saya",
        "timezoneregion-africa": "Afrika",
        "timezoneregion-europe": "Eropah",
        "timezoneregion-indian": "Lautan Hindi",
        "timezoneregion-pacific": "Lautan Pasifik",
-       "allowemail": "Benarkan e-mel daripada pengguna lain",
+       "allowemail": "Benarkan pengguna lain untuk mengemel saya.",
+       "email-allow-new-users-label": "Benarkan e-mel dari pengguna baharu.",
+       "email-blacklist-label": "Cegah pengguna tersebut dari mengemel saya:",
        "prefs-searchoptions": "Cari",
        "prefs-namespaces": "Ruang nama",
        "default": "asali",
        "prefs-files": "Fail",
        "prefs-custom-css": "CSS tempahan",
+       "prefs-custom-json": "JSON menurut pesanan",
        "prefs-custom-js": "JS tempahan",
-       "prefs-common-config": "CSS/JavaScript kongsi untuk semua rupa:",
+       "prefs-common-config": "CSS/JavaScript kongsi untuk semua kulit:",
        "prefs-reset-intro": "Anda boleh menggunakan laman ini untuk menetapkan semula keutamaan anda kepada tetapan asali.\nTindakan ini tidak boleh dibatalkan.",
        "prefs-emailconfirm-label": "Pengesahan e-mel:",
        "youremail": "E-mel:",
        "prefs-dateformat": "Format tarikh",
        "prefs-timeoffset": "Imbangan masa",
        "prefs-advancedediting": "Pilihan am",
+       "prefs-developertools": "Alat pembangun",
        "prefs-editor": "Penyunting",
        "prefs-preview": "Pralihat",
        "prefs-advancedrc": "Pilihan lanjutan",
        "prefs-advancedwatchlist": "Pilihan lanjutan",
        "prefs-displayrc": "Pilihan paparan",
        "prefs-displaywatchlist": "Pilihan paparan",
+       "prefs-changesrc": "Perubahan yang dipaparkan",
+       "prefs-changeswatchlist": "Perubahan yang dipaparkan",
+       "prefs-pageswatchlist": "Laman yang dipantau",
        "prefs-tokenwatchlist": "Token",
        "prefs-diffs": "Beza",
        "prefs-help-prefershttps": "Keutamaan inu akan berkuatkuasa pada lain kali anda log masuk.",
        "prefswarning-warning": "Anda telah mengubah suai keutamaan anda yang belum disimpan.\nJika anda meninggalkan laman ini tanpa mengklik \"$1\", keutamaan anda tidak akan disimpan.",
        "prefs-tabs-navigation-hint": "Petua: Anda boleh menggunakan kekunci anak panah kiri atau kanan untuk beralihan dari tab ke tab pada senarai tab.",
-       "userrights": "Pengurusan hak pengguna",
-       "userrights-lookup-user": "Urus kumpulan pengguna",
+       "userrights": "Hak pengguna",
+       "userrights-lookup-user": "Pilih seorang pengguna",
        "userrights-user-editname": "Masukkan nama pengguna:",
-       "editusergroup": "Sunting Kumpulan Pengguna",
+       "editusergroup": "Muat kumpulan pengguna",
        "editinguser": "Mengubah hak {{GENDER:$1|pengguna}} bagi <strong>[[User:$1|$1]]</strong> $2",
        "viewinguserrights": "Melihat hak {{GENDER:$1|pengguna}} bagi <strong>[[User:$1|$1]]</strong> $2",
-       "userrights-editusergroup": "Ubah kumpulan pengguna",
-       "saveusergroups": "Simpan Kumpulan Pengguna",
+       "userrights-editusergroup": "Sunting kumpulan {{GENDER:$1|pengguna}}",
+       "userrights-viewusergroup": "Lihat kumpulan {{GENDER:$1|pengguna}}",
+       "saveusergroups": "Simpan kumpulan {{GENDER:$1|pengguna}}",
        "userrights-groupsmember": "Ahli bagi:",
        "userrights-groupsmember-auto": "Ahli automatik bagi:",
-       "userrights-groups-help": "Anda boleh mengubah keahlian kumpulan bagi pengguna ini:\n* Petak yang bertanda bererti pengguna tersebut ialah ahli kumpulan itu.\n* Petak yang tidak bertanda bererti bahawa pengguna tersebut bukan ahli kumpulan itu.\n* Tanda bintang (*) menandakan bahawa anda tidak boleh melucutkan keahlian pengguna tersebut setelah anda melantiknya, dan begitulah sebaliknya.",
+       "userrights-groups-help": "Anda boleh mengubah keahlian kumpulan bagi pengguna ini:\n* Petak yang bertanda bererti pengguna tersebut ialah ahli kumpulan itu.\n* Petak yang tidak bertanda bererti bahawa pengguna tersebut bukan ahli kumpulan itu.\n* Tanda * menunjukkan bahawa anda tidak boleh melucutkan keahlian pengguna tersebut setelah anda melantiknya, atau sebaliknya.\n* Tanda # menunjukkan bahawa anda hanya boleh meletakkan waktu mansuh bagi keahlian kumpulan ini; anda tidak boleh membawanya ke hadapan.",
        "userrights-reason": "Sebab:",
        "userrights-no-interwiki": "Anda tidak mempunyai keizinan untuk mengubah hak-hak pengguna di wiki lain.",
        "userrights-nodatabase": "Pangkalan data $1 tiada atau bukan tempatan.",
        "userrights-changeable-col": "Kumpulan yang anda boleh ubah",
        "userrights-unchangeable-col": "Kumpulan yang anda tak boleh ubah",
        "userrights-irreversible-marker": "$1*",
+       "userrights-expiry-current": "Mansuh pada $1",
+       "userrights-expiry-none": "Tidak mansuh",
+       "userrights-expiry": "Mansuh pada:",
+       "userrights-expiry-existing": "Waktu mansuh sedia ada: $3, $2",
+       "userrights-expiry-othertime": "Waktu lain:",
+       "userrights-expiry-options": "1 hari:1 hari,1 minggu:1 minggu,1 bulan:1 bulan,3 bulan:3 bulan,6 bulan:6bulan,1 tahun:1 tahun",
+       "userrights-invalid-expiry": "Waktu mansuh bagi kumpulan \"$1\" tidak sah.",
+       "userrights-expiry-in-past": "Waktu mansuh untuk kumpulan \"$1\" sudah berlalu.",
+       "userrights-cannot-shorten-expiry": "Anda tidak dapat membawa ke hadapan waktu mansuh keahlian ke dalam kumpulan \"$1\". Hanya pengguna dengan kebenaran untuk menambah dan membuang kumpulan ini dapat membawa waktu mansuh ke hadapan.",
        "userrights-conflict": "Percanggahan perubahan hak pengguna! Sila semak dan sahkan perubahan anda.",
        "group": "Kumpulan:",
        "group-user": "Pengguna",
        "group-autoconfirmed": "Pengguna sah automatik",
        "group-bot": "Bot",
        "group-sysop": "Penyelia",
+       "group-interface-admin": "Penyelia antara muka",
        "group-bureaucrat": "Birokrat",
        "group-suppress": "Peredam",
        "group-all": "(semua)",
        "group-autoconfirmed-member": "{{GENDER:$1|pengguna sah automatik}}",
        "group-bot-member": "{{GENDER:$1|bot}}",
        "group-sysop-member": "{{GENDER:$1|penyelia}}",
+       "group-interface-admin-member": "{{GENDER:$1|penyelia antara muka}}",
        "group-bureaucrat-member": "{{GENDER:$1|birokrat}}",
        "group-suppress-member": "{{GENDER:$1|peredam}}",
        "grouppage-user": "{{ns:project}}:Pengguna",
        "grouppage-autoconfirmed": "{{ns:project}}:Pengguna yang disahkan secara automatik",
        "grouppage-bot": "{{ns:project}}:Bot",
        "grouppage-sysop": "{{ns:project}}:Penyelia",
+       "grouppage-interface-admin": "{{ns:project}}:Penyelia antara muka",
        "grouppage-bureaucrat": "{{ns:project}}:Birokrat",
        "grouppage-suppress": "{{ns:project}}:Peredam",
        "right-read": "Membaca laman",
-       "right-edit": "Menyunting laman",
+       "right-edit": "Sunting laman",
        "right-createpage": "Mencipta laman (selain laman perbincangan)",
        "right-createtalk": "Mencipta laman perbincangan",
        "right-createaccount": "Membuka akaun pengguna baru",
+       "right-autocreateaccount": "Log masuk secara automatik dengan akaun pengguna luar",
        "right-minoredit": "Menanda suntingan kecil",
        "right-move": "Memindahkan laman",
        "right-move-subpages": "Memindahkan laman berserta sublaman",
        "right-reupload-own": "Menulis ganti fail sedia ada yang dimuat naik sendiri",
        "right-reupload-shared": "Mengatasi fail di gedung media kongsi",
        "right-upload_by_url": "Memuat naik fail daripada alamat URL",
-       "right-purge": "Membersihkan cache bagi sesebuah laman tanpa pengesahan",
+       "right-purge": "Singkir cache tapak untuk laman",
        "right-autoconfirmed": "Terkecuali dari had kadar berasaskan IP",
        "right-bot": "Dianggap melakukan tugas-tugas automatik",
        "right-nominornewtalk": "Suntingan kecil pada laman perbincangan seseorang pengguna tidak menghidupkan isyarat pesanan baru untuk pengguna itu",
        "right-editusercss": "Menyunting fail CSS pengguna lain",
        "right-edituserjson": "Menyunting fail JSON pengguna lain",
        "right-edituserjs": "Menyunting fail JavaScript pengguna lain",
+       "right-editsitecss": "Sunting CSS di seluruh tapak",
+       "right-editsitejson": "Sunting JSON di seluruh tapak",
+       "right-editsitejs": "Sunting JavaScript di seluruh tapak",
        "right-editmyusercss": "Menyunting fail CSS pengguna sendiri",
        "right-editmyuserjson": "Menyunting fail JSON pengguna sendiri",
        "right-editmyuserjs": "Menyunting fail JavaScript pengguna sendiri",
        "right-siteadmin": "Mengunci dan membuka kunci pangkalan data",
        "right-override-export-depth": "Mengeksport laman termasuk laman dipaut sehingga kedalaman 5",
        "right-sendemail": "Mengirim e-mel kepada pengguna-pengguna lain",
-       "right-managechangetags": "Mencipta dan menghapuskan [[Special:Tags|teg]] dari pangkalan data",
+       "right-managechangetags": "Cipta dan (nyah)aktifkan [[Special:Tags|teg]]",
        "right-applychangetags": "Mengenakan [[Special:Tags|teg]] di samping suntingan seseorang",
        "right-changetags": "Menambah dan menggugurkan [[Special:Tags|teg]] yang dikenakan sembarangan pada semakan dan entri log individu",
+       "right-deletechangetags": "Hapus [[Special:Tags|teg]] dari pangkalan data",
+       "grant-generic": "\"$1\" berkas hak",
+       "grant-group-page-interaction": "Berinteraksi dengan laman",
+       "grant-group-file-interaction": "Berinteraksi dengan media",
+       "grant-group-watchlist-interaction": "Berinteraksi dengan senarai pantau anda",
        "grant-group-email": "Hantar e-mel",
+       "grant-group-high-volume": "Lakukan aktiviti dengan isi padu tinggi",
+       "grant-group-customization": "Tersuaian dan keutamaan",
+       "grant-group-administration": "Lakukan tindakan pentadbiran",
+       "grant-group-private-information": "Akses data peribadi tentang anda",
+       "grant-group-other": "Aktiviti lain",
+       "grant-blockusers": "Sekat dan nyahsekat pengguna",
        "grant-createaccount": "Cipta akaun",
        "grant-createeditmovepage": "Cipta, sunting dan pindah laman",
+       "grant-delete": "Padam laman, semakan, dan kemasukan log",
+       "grant-editinterface": "Sunting ruang nama MediaWiki dan JSON pengguna/di seluruh tapak",
+       "grant-editmycssjs": "Sunting CSS/JSON/JavaScript pengguna anda",
+       "grant-editmyoptions": "Sunting keutamaan pengguna anda dan konfigurasi JSON",
        "grant-editmywatchlist": "Sunting senarai pantau anda",
+       "grant-editsiteconfig": "Sunting CSS/JS di seluruh tapak dan pengguna",
        "grant-editpage": "Sunting laman sedia ada",
        "grant-editprotected": "Sunting laman yang dilindungi",
+       "grant-highvolume": "Penyuntingan dengan isi padu tinggi",
+       "grant-oversight": "Sembunyikan pengguna dan tahan semakan",
+       "grant-patrol": "Ronda perubahan kepada laman",
+       "grant-privateinfo": "Akses maklumat peribadi",
+       "grant-protect": "Lindungi dan nyahlindungi laman",
+       "grant-rollback": "Balikkan perubahan kepada laman",
        "grant-sendemail": "Hantar e-mel ke pengguna lain",
+       "grant-uploadeditmovefile": "Muat naik, gantikan, dan pindah fail",
        "grant-uploadfile": "Muat naik fail baru",
        "grant-basic": "Hak-hak asas",
+       "grant-viewdeleted": "Lihat fail dan laman yang dipadam",
+       "grant-viewmywatchlist": "Lihat senarai pantau anda",
+       "grant-viewrestrictedlogs": "Lihat kemasukan log terhad",
        "newuserlogpage": "Log akaun baru",
        "newuserlogpagetext": "Yang berikut ialah log penciptaan pengguna.",
        "rightslog": "Log hak pengguna",
        "action-createpage": "ciptakan laman ini",
        "action-createtalk": "ciptakan laman perbincangan ini",
        "action-createaccount": "mencipta akaun pengguna ini",
+       "action-autocreateaccount": "mencipta secara automatik akaun pengguna luar ini",
        "action-history": "melihat sejarah halaman ini",
        "action-minoredit": "menanda suntingan ini sebagai suntingan kecil",
        "action-move": "memindahkan laman ini",
        "action-upload_by_url": "memuat naik fail ini dari alamat URL",
        "action-writeapi": "menggunakan API tulis",
        "action-delete": "menghapuskan laman ini",
-       "action-deleterevision": "menghapuskan semakan ini",
-       "action-deletedhistory": "melihat sejarah yang telah dihapuskan bagi laman ini",
+       "action-deleterevision": "menghapuskan semakan",
+       "action-deletelogentry": "menghapuskan kemasukan log",
+       "action-deletedhistory": "melihat sejarah yang dihapus bagi laman",
+       "action-deletedtext": "melihat teks semakan yang dihapus",
        "action-browsearchive": "mencari laman-laman yang telah dihapuskan",
-       "action-undelete": "menyahhapuskan laman ini",
-       "action-suppressrevision": "menyemak semula dan memulihkan semakan tersembunyi ini",
+       "action-undelete": "menyahhapuskan laman",
+       "action-suppressrevision": "menyemak dan memulihkan semakan tersembunyi",
        "action-suppressionlog": "melihat log sulit ini",
        "action-block": "menyekat pengguna ini daripada menyunting",
        "action-protect": "mengubah aras perlindungan bagi laman ini",
        "action-userrights-interwiki": "mengubah hak pengguna dari wiki lain",
        "action-siteadmin": "mengunci atau membuka kunci pangkalan data wiki ini",
        "action-sendemail": "menghantar e-mel",
+       "action-editmyoptions": "menyunting keutamaan anda",
        "action-editmywatchlist": "menyunting senarai pantau sendiri",
        "action-viewmywatchlist": "melihat senarai pantau sendiri",
        "action-viewmyprivateinfo": "melihat maklumat peribadi sendiri",
        "action-editmyprivateinfo": "menyunting maklumat peribadi sendiri",
        "action-editcontentmodel": "menyunting model kandungan laman",
-       "action-managechangetags": "mencipta dan menghapuskan teg dari pangkalan data",
+       "action-managechangetags": "mencipta dan me(ng/nyah)aktifkan teg",
        "action-applychangetags": "mengenakan teg di samping suntingan anda",
        "action-changetags": "menambah dan menggugurkan teg yang dikenakan sembarangan pada semakan dan entri log individu",
+       "action-deletechangetags": "menghapuskan teg dari pangkalan data",
+       "action-purge": "menyingkir laman ini",
+       "action-apihighlimits": "menggunakan had yang lebih tinggi dalam pertanyaan API",
+       "action-autoconfirmed": "tidak terkesan oleh had kadar berasaskan IP",
+       "action-bigdelete": "menghapuskan laman dengan banyak sejarah",
+       "action-blockemail": "menyekat pengguna dari menghantar e-mel",
+       "action-bot": "dianggap sebagai proses automatik",
+       "action-editprotected": "menyunting laman yang dilindungi sebagai \"{{int:protect-level-sysop}}\"",
+       "action-editsemiprotected": "menyunting laman yang dilindungi sebagai \"{{int:protect-level-autoconfirmed}}\"",
+       "action-editinterface": "menyunting antara muka pengguna",
+       "action-editusercss": "menyunting fail CSS pengguna lain",
+       "action-edituserjson": "menyunting fail JSON pengguna lain",
+       "action-edituserjs": "menyunting fail JavaScript pengguna lain",
+       "action-editsitecss": "menyunting CSS di seluruh tapak",
+       "action-editsitejson": "menyunting JSON di seluruh tapak",
+       "action-editsitejs": "menyunting JavaScript di seluruh tapak",
+       "action-editmyusercss": "menyunting fail CSS pengguna anda sendiri",
+       "action-editmyuserjson": "menyunting fail JSON pengguna anda sendiri",
+       "action-editmyuserjs": "menyunting fail JavaScript pengguna anda sendiri",
+       "action-viewsuppressed": "melihat semakan yang tersembunyi dari mana-mana pengguna",
+       "action-hideuser": "menyekat nama pengguna, menyembunyikannya daripada orang ramai",
+       "action-ipblock-exempt": "memintas sekatan IP, sekatan automatik dan sekatan julat",
+       "action-unblockself": "menyahsekat diri sendiri",
+       "action-noratelimit": "tidak terkesan oleh had kadar",
+       "action-reupload-own": "menulis ganti fail sedia ada yang dimuat naik oleh diri sendiri",
+       "action-nominornewtalk": "tidak mempunyai suntingan kecil pada laman perbincangan mencetus prom pesanan baru",
+       "action-markbotedits": "menanda suntingan yang dibalikkan sebagai suntingan bot",
+       "action-patrolmarks": "melihat tanda rondaan perubahan terkini",
+       "action-override-export-depth": "mengeksport laman termasuk laman terpaut sehingga kedalaman 5",
+       "action-suppressredirect": "tidak mencipta lencongan dari laman sumber apabila memindah laman",
        "nchanges": "$1 perubahan",
        "enhancedrc-since-last-visit": "$1 {{PLURAL:$1|sejak lawatan terakhir}}",
        "enhancedrc-history": "sejarah",
        "recentchanges-legend": "Pilihan perubahan terkini",
        "recentchanges-summary": "Jejaki perubahan terkini dalam {{SITENAME}} pada laman ini.",
        "recentchanges-noresult": "Tiada perubahan dalam tempoh yang diberikan sepadan dengan kriteria ini.",
+       "recentchanges-timeout": "Masa pencarian ini telah habis. Anda mungkin ingin cuba parameter pencarian lain.",
+       "recentchanges-network": "Oleh sebab kesalahan teknikal, tiada hasil yang boleh dimuat. Sila cuba segarkan kembali laman.",
+       "recentchanges-notargetpage": "Masukkan nama laman di atas untuk melihat perubahan berkaitan laman tersebut.",
        "recentchanges-feed-description": "Jejaki perubahan terkini dalam {{SITENAME}} pada suapan ini.",
        "recentchanges-label-newpage": "Suntingan ini mencipta laman baru",
        "recentchanges-label-minor": "Ini ialah suntingan kecil",
        "recentchanges-label-plusminus": "Saiz laman telah berubah sebanyak jumlah bait ini",
        "recentchanges-legend-heading": "<strong>Petunjuk:</strong>",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (lihat juga [[Special:NewPages|senarai laman baru]])",
+       "recentchanges-submit": "Paparkan",
+       "rcfilters-tag-remove": "Keluarkan '$1'",
        "rcfilters-legend-heading": "<strong>Senarai singkatan:</strong>",
        "rcfilters-other-review-tools": "Alat semakan lain",
+       "rcfilters-group-results-by-page": "Kelompokkan hasil mengikut laman",
        "rcfilters-activefilters": "Penapis yang aktif",
+       "rcfilters-activefilters-hide": "Sorokkan",
+       "rcfilters-activefilters-show": "Paparkan",
+       "rcfilters-activefilters-hide-tooltip": "Sembunyikan kawasan penapis Aktif",
+       "rcfilters-activefilters-show-tooltip": "Paparkan kawasan penapis Aktif",
+       "rcfilters-advancedfilters": "Penapis lanjutan",
+       "rcfilters-limit-title": "Hasil untuk dipaparkan",
+       "rcfilters-limit-and-date-label": "$1 {{PLURAL:$1|perubahan}}, $2",
+       "rcfilters-date-popup-title": "Tempoh masa untuk pencarian",
+       "rcfilters-days-title": "Hari kebelakangan",
+       "rcfilters-hours-title": "Jam kebelakangan",
+       "rcfilters-days-show-days": "$1 {{PLURAL:$1|hari}}",
+       "rcfilters-days-show-hours": "$1 {{PLURAL:$1|jam}}",
+       "rcfilters-highlighted-filters-list": "Diserlahkan: $1",
+       "rcfilters-quickfilters": "Penapis yang disimpan",
+       "rcfilters-quickfilters-placeholder-title": "Belum ada penapis disimpan",
+       "rcfilters-quickfilters-placeholder-description": "Untuk menyimpan tetapan penapis dan dan menggunakannya kemudian, klik ikon penanda halaman di kawasan penapis Aktif, di bawah.",
        "rcfilters-savedqueries-defaultlabel": "Penapis yang disimpan",
+       "rcfilters-savedqueries-rename": "Namakan semula",
        "rcfilters-savedqueries-setdefault": "Tetapkan sebagai asali",
        "rcfilters-savedqueries-unsetdefault": "Gugurkan sebagai asali",
-       "rcfilters-savedqueries-remove": "Gugurkan",
+       "rcfilters-savedqueries-remove": "Hapuskan",
        "rcfilters-savedqueries-new-name-label": "Nama",
+       "rcfilters-savedqueries-new-name-placeholder": "Jelaskan tujuan penapis ini",
+       "rcfilters-savedqueries-apply-label": "Cipta penapis",
+       "rcfilters-savedqueries-apply-and-setdefault-label": "Cipta penapis tersedia",
+       "rcfilters-savedqueries-cancel-label": "Batalkan",
        "rcfilters-savedqueries-add-new-title": "Simpan tetapan penapis terkini",
-       "rcfilters-show-new-changes": "Lihat perubahan terkini",
+       "rcfilters-savedqueries-already-saved": "Penapis berikut sudah disimpan. Ubah tetapan anda untuk mencipta Penapis Tersimpan yang baru.",
+       "rcfilters-restore-default-filters": "Pulihkan penapis tersedia",
+       "rcfilters-clear-all-filters": "Kosongkan semua penapis",
+       "rcfilters-show-new-changes": "Lihat perubahan baru sejak $1",
        "rcfilters-search-placeholder": "Penapis perubahan (guna menu atau carian untuk menapis nama)",
+       "rcfilters-invalid-filter": "Penapis tidak sah",
+       "rcfilters-empty-filter": "Tiada penapis aktif. Semua sumbangan ditunjukkan.",
+       "rcfilters-filterlist-title": "Penapis",
+       "rcfilters-filterlist-whatsthis": "Bagaimana ianya berfungsi?",
+       "rcfilters-filterlist-feedbacklink": "Beritahu kami apa yang anda fikir tentang alat penapis ini",
+       "rcfilters-highlightbutton-title": "Serlahkan hasil",
+       "rcfilters-highlightmenu-title": "Pilih warna",
+       "rcfilters-highlightmenu-help": "Pilih warna untuk menyerlahkan sifat ini",
+       "rcfilters-filterlist-noresults": "Tiada penapis dijumpai",
+       "rcfilters-noresults-conflict": "Tiada hasil dijumpai kerana kriteria pencarian bercanggah",
+       "rcfilters-state-message-subset": "Penapis ini tiada mempunyai kesan kerana hasilnya termasuk dalam {{PLURAL:$2|penapis}} berikut, yang lebih luas (cuba serlahkan untuk membezakannya): $1",
+       "rcfilters-state-message-fullcoverage": "Memilih semua penapis dalam kumpulan ini sama seperti tiada memilih apapun, jadi penapis ini tiada mempunyai kesan. Kumpulan termasuk: $1",
+       "rcfilters-filtergroup-authorship": "Pengarang sumbangan",
+       "rcfilters-filter-editsbyself-label": "Perubahan oleh anda",
+       "rcfilters-filter-editsbyself-description": "Sumbangan anda sendiri.",
+       "rcfilters-filter-editsbyother-label": "Perubahan oleh orang lain",
+       "rcfilters-filter-editsbyother-description": "Semua perubahan kecuali milik anda.",
        "rcfilters-filtergroup-user-experience-level": "Pendaftaran dan pengalaman pengguna",
+       "rcfilters-filter-user-experience-level-registered-label": "Berdaftar",
+       "rcfilters-filter-user-experience-level-registered-description": "Penyunting yang melog masuk.",
        "rcfilters-filter-user-experience-level-unregistered-label": "Tidak terdaftar",
        "rcfilters-filter-user-experience-level-unregistered-description": "Penyunting yang tidak log masuk.",
+       "rcfilters-filter-user-experience-level-newcomer-label": "Pendatang baru",
+       "rcfilters-filter-user-experience-level-newcomer-description": "Penyunting berdaftar yang mempunyai kurang dari 10 suntingan atau aktiviti selama 4 hari.",
+       "rcfilters-filter-user-experience-level-learner-label": "Pelajar",
+       "rcfilters-filter-user-experience-level-learner-description": "Penyunting berdaftar yang pengalamannya berada di antara \"pengguna baru\" dan \"Pengguna berpengalaman.\"",
+       "rcfilters-filter-user-experience-level-experienced-label": "Pengguna berpengalaman",
+       "rcfilters-filter-user-experience-level-experienced-description": "Penyunting berdaftar dengan lebih dari 500 suntingan dan aktiviti selama 30 hari.",
+       "rcfilters-filtergroup-automated": "Sumbangan terautomasi",
+       "rcfilters-filter-bots-label": "Bot",
+       "rcfilters-filter-bots-description": "Suntingan yang dibuat dengan alat terautomasi.",
        "rcfilters-filter-humans-label": "Manusia (bukan bot)",
+       "rcfilters-filter-humans-description": "Suntingan yang dibuat oleh penyunting manusia.",
+       "rcfilters-filtergroup-reviewstatus": "Semak status",
+       "rcfilters-filter-reviewstatus-unpatrolled-description": "Suntingan yang tidak ditandai secara manual atau automatik sebagai dironda.",
+       "rcfilters-filter-reviewstatus-unpatrolled-label": "Tidak dirondai",
+       "rcfilters-filter-reviewstatus-manual-description": "Suntingan ditandai secara manual sebagai dironda.",
+       "rcfilters-filter-reviewstatus-manual-label": "Dironda secara manual",
+       "rcfilters-filter-reviewstatus-auto-description": "Suntingan oleh pengguna lanjutan yang mana sumbangannnya ditandai secara automatik sebagai dironda.",
+       "rcfilters-filter-reviewstatus-auto-label": "Dironda secara automatik",
+       "rcfilters-filtergroup-significance": "Kepentingan",
+       "rcfilters-filter-minor-label": "Suntingan kecil",
+       "rcfilters-filter-minor-description": "Suntingan yang mana penulis melabel sebagai suntingan kecil.",
+       "rcfilters-filter-major-label": "Suntingan bukan kecil",
+       "rcfilters-filter-major-description": "Suntingan bukan dilabel sebagai kecil.",
+       "rcfilters-filtergroup-watchlist": "Laman yang disenarai pantau",
+       "rcfilters-filter-watchlist-watched-label": "Dalam Senarai Pantau",
+       "rcfilters-filter-watchlist-watched-description": "Perubahan ke laman dalam Senarai Pantau anda.",
+       "rcfilters-filter-watchlist-watchednew-label": "Perubahan Senarai Pantau baru.",
+       "rcfilters-filter-watchlist-watchednew-description": "Perubahan ke laman Senarai Pantau yang anda belum kunjungi sejak perubahan berlaku.",
+       "rcfilters-filter-watchlist-notwatched-label": "Bukan dalam Senarai Pantau",
+       "rcfilters-filter-watchlist-notwatched-description": "Semuanya kecuali perubahan ke laman yang anda Senarai Pantau.",
+       "rcfilters-filtergroup-watchlistactivity": "Aktiviti senarai pantau",
+       "rcfilters-filter-watchlistactivity-unseen-label": "Perubahan yang tidak dilihat",
+       "rcfilters-filter-watchlistactivity-unseen-description": "Perubahan ke laman yang anda belum kunjungi sejak perubahan berlaku.",
+       "rcfilters-filter-watchlistactivity-seen-label": "Perubahan yang dilihat",
+       "rcfilters-filter-watchlistactivity-seen-description": "Perubahan ke laman yang anda telah kunjungi sejak perubahan berlaku.",
        "rcfilters-filtergroup-changetype": "Jenis perubahan",
        "rcfilters-filter-pageedits-label": "Suntingan laman",
        "rcfilters-filter-pageedits-description": "Suntingan kandungan wiki, perbincangan, huraian kategori…",
        "rcfilters-filter-newpages-label": "Penciptaan laman",
+       "rcfilters-filter-newpages-description": "Suntingan yang membuat laman baru.",
+       "rcfilters-filter-categorization-label": "Perubahan kategori",
+       "rcfilters-filter-categorization-description": "Rekod laman yang ditambah atau dikeluarkan dari kategori.",
        "rcfilters-filter-logactions-label": "Tindakan berlog",
        "rcfilters-filter-logactions-description": "Tindakan pentadbiran, pembuatan akaun, penghapusan halaman, muat naik…",
+       "rcfilters-hideminor-conflicts-typeofchange-global": "Penapis \"Suntingan kecil\" bercanggah dengan satu atau lebih Jenis penapis perubahan, kerana jenis perubahan tertentu tidak boleh ditetapkan sebagai \"kecil\". Penapis bercanggah ditandakan di kawasan penapis Aktif, di atas.",
+       "rcfilters-hideminor-conflicts-typeofchange": "Jenis perubahan tertentu tidak boleh ditetapkan sebagai \"kecil\", jadi penapis ini bercanggah dengan penapis Jenis Perubahan berikut: $1",
+       "rcfilters-typeofchange-conflicts-hideminor": "Penapis Jenis perubahan ini bercanggah dengan penapis \"Suntingan kecil\". Jenis perubahan tertentu tidak boleh ditetapkan sebagai \"kecil\".",
+       "rcfilters-filtergroup-lastrevision": "Semakan terkini",
+       "rcfilters-filter-lastrevision-label": "Semakan terkini",
+       "rcfilters-filter-lastrevision-description": "Hanya perubahan yang paling terkini pada laman.",
+       "rcfilters-filter-previousrevision-label": "Bukan semakan terkini",
+       "rcfilters-filter-previousrevision-description": "Semua perubahan yang bukan \"semakan terkini\".",
+       "rcfilters-filter-excluded": "Tidak dimasukkan",
+       "rcfilters-tag-prefix-namespace-inverted": "<strong>:bukan</strong> $1",
+       "rcfilters-exclude-button-off": "Kecualikan yang terpilih",
+       "rcfilters-exclude-button-on": "Kecuali yang terpilih",
+       "rcfilters-view-tags": "Suntingan yang diteg",
+       "rcfilters-view-namespaces-tooltip": "Tapis hasil mengikut ruang nama",
+       "rcfilters-view-tags-tooltip": "Tapis hasil menggunakan teg suntingan",
+       "rcfilters-view-return-to-default-tooltip": "Kembali ke menu penapis utama",
+       "rcfilters-view-tags-help-icon-tooltip": "Ketahui lebih lanjut tetang suntingan yang Diteg",
        "rcfilters-liveupdates-button": "Perubahan langsung",
+       "rcfilters-liveupdates-button-title-on": "Matikan pengemaskinian langsung",
+       "rcfilters-liveupdates-button-title-off": "Paparkan perubahan baru sebagaimana ia sedang berlaku",
+       "rcfilters-watchlist-markseen-button": "Tandai semua perubahan sebagai dilihat",
+       "rcfilters-watchlist-edit-watchlist-button": "Sunting senarai laman pantau anda",
+       "rcfilters-watchlist-showupdated": "Perubahan ke laman yang anda belum kunjungi sejak perubahan berlaku adalah <strong>ditebalkan</strong>, dengan penanda pepejal.",
+       "rcfilters-preference-label": "Gunakan antara muka bukan JavaScript",
+       "rcfilters-preference-help": "Muat PerubahanTerkini tanpa pencarian penapis atau menyerlahkan kefungsian.",
+       "rcfilters-watchlist-preference-label": "Gunakan antara muka bukan JavaScript",
+       "rcfilters-watchlist-preference-help": "Muat Senarai Pantau tanpa pencarian penapis atau menyerlahkan kefungsian.",
+       "rcfilters-filter-showlinkedfrom-label": "Tunjukkan perubahan pada laman yang dipautkan dari",
+       "rcfilters-filter-showlinkedfrom-option-label": "<strong>Laman dipautkan dari</strong> laman terpilih",
+       "rcfilters-filter-showlinkedto-label": "Tunjukkan perubahan pada laman yang berpaut ke",
+       "rcfilters-filter-showlinkedto-option-label": "<strong>Laman berpaut ke</strong> laman terpilih",
+       "rcfilters-target-page-placeholder": "Masukkan nama laman (atau kategori)",
        "rcnotefrom": "Yang berikut ialah {{PLURAL:$5|suntingan|suntingan-suntingan}} sejak <strong>$3, $4</strong> (selebihi <strong>$1</strong> dipaparkan).",
+       "rclistfromreset": "Tetapkan semula pilihan tarikh",
        "rclistfrom": "Paparkan perubahan sejak $3 $2",
        "rcshowhideminor": "$1 suntingan kecil",
        "rcshowhideminor-show": "Paparkan",
        "recentchangeslinked-page": "Nama laman:",
        "recentchangeslinked-to": "Paparkan perubahan pada laman yang mengandungi pautan ke laman yang diberikan",
        "recentchanges-page-added-to-category": "[[:$1]] ditambahkan kepada kategori",
-       "recentchanges-page-added-to-category-bundled": "[[:$1]] dan [[Special:WhatLinksHere/$1|{{PLURAL:$2|satu|$2}}]] lagi halaman ditambahkan kepada kategori",
+       "recentchanges-page-added-to-category-bundled": "[[:$1]] ditambah ke kategori, [[Special:WhatLinksHere/$1|laman ini termasuk dalam laman lain]]",
        "recentchanges-page-removed-from-category": "[[:$1]] digugurkan dari kategori",
-       "recentchanges-page-removed-from-category-bundled": "[[:$1]] dan {{PLURAL:$2|satu|$2}} lagi halaman digugurkan dari kategori",
+       "recentchanges-page-removed-from-category-bundled": "[[:$1]] dikeluarkan dari kategori, [[Special:WhatLinksHere/$1|laman ini termasuk dalam laman lain]]",
        "autochange-username": "Perubahan automatik MediaWiki",
        "upload": "Muat naik fail",
        "uploadbtn": "Muat naik fail",
        "reuploaddesc": "Kembali ke borang muat naik",
        "upload-tryagain": "Serahkan keterangan fail yang telah diubah",
+       "upload-tryagain-nostash": "Hantar fail yang dimuat naik semula dan keterangan yang diubah suai",
        "uploadnologin": "Belum log masuk",
        "uploadnologintext": "Anda mesti $1 untuk memuat naik fail.",
        "upload_directory_missing": "Direktori muat naik ($1) hilang dan tidak dapat dicipta oleh pelayan web.",
        "file-thumbnail-no": "Nama fail ini bermula dengan <strong>$1</strong>.\nBarangkali ia ialah sebuah imej yang telah dikecilkan <em>(gambar kenit)</em>.\nJika anda memiliki imej ini dalam leraian penuh, sila muat naik fail tersebut. Jika tidak, sila tukar nama fail ini.",
        "fileexists-forbidden": "Sebuah fail dengan nama ini telah pun wujud, dan tidak boleh ditulis ganti. Jika anda masih mahu memuat naik fail ini, sila berundur dan muat naik fail ini dengan nama lain. [[File:$1|thumb|center|$1]]",
        "fileexists-shared-forbidden": "Sebuah fail dengan nama ini telah pun wujud dalam gedung fail kongsi. Jika anda masih mahu memuat naik fail ini, sila kembali ke borang muat naik dan gunakan nama lain. [[File:$1|thumb|center|$1]]",
+       "fileexists-no-change": "Yang dimuat naik adalah pendua tepat versi semasa <strong>[[:$1]]</strong>.",
+       "fileexists-duplicate-version": "Yang dimuat naik ialah pendua tepat {{PLURAL:$2|versi lama}} <strong>[[:$1]]</strong>.",
        "file-exists-duplicate": "Fail ini ialah salinan bagi {{PLURAL:$1|fail|fail-fail}} berikut:",
        "file-deleted-duplicate": "Sebuah fail yang serupa dengan fail ini ([[:$1]]) telah pun dihapuskan sebelum ini. Anda seharusnya memeriksa sejarah penghapusan fail itu terlebih dahulu sebelum memuat naiknya sekali lagi.",
        "file-deleted-duplicate-notitle": "Satu fail yang seiras dengan fail ini telah dihapuskan dahulu, maka judulnya telah disekat. Anda harus meminta sesiapa yang boleh melihat data fail yang disekat untuk meneliti situasinya sebelum cuba memuat naiknya semula.",
        "uploadwarning": "Amaran muat naik",
        "uploadwarning-text": "Sila ubah keterangan fail di bawah dan cuba lagi.",
+       "uploadwarning-text-nostash": "Sila muat naik semula fail, ubah suai keterangan di bawah dan cuba lagi.",
        "savefile": "Simpan fail",
        "uploaddisabled": "Ciri muat naik dimatikan",
        "copyuploaddisabled": "Ciri muat naik melalui URL telah dilumpuhkan.",
        "php-uploaddisabledtext": "Pemuatnaikan fail PHP dilumpuhkan. Sila semak tetapan file_uploads.",
        "uploadscripted": "Fail ini mengandungi kod HTML atau skrip yang boleh disalahtafsirkan oleh pelayar web.",
        "upload-scripted-pi-callback": "Tidak dapat memuat naik fail yang mengandungi arahan pemprosesan hamparan XML.",
+       "upload-scripted-dtd": "Tidak dapat dimuat naik fail SVG yang mengandungi pengisytiharan DTD bukan piawai.",
        "uploaded-script-svg": "Terdapat elemen terskrip \"$1\" dalam fail SVG yang dimuat naik.",
        "uploaded-hostile-svg": "Terdapat CSS yang tidak selamat dalam elemen stail fail SVG yang dimuat naik.",
        "uploaded-event-handler-on-svg": "Penetapan atribut <i>event-handler</i> <code>$1=\"$2\"</code> tidak dibenarkan dalam fail SVG.",
-       "uploaded-href-unsafe-target-svg": "Terdapat href ke sasaran tak selamat <code>&lt;$1 $2=\"$3\"&gt;</code> dalam fail SVG yang dimuat naik.",
+       "uploaded-href-attribute-svg": "<a> unsur hanya boleh berpaut (href) ke data: (fail terbenam), http:// atau https://, atau sasaran serpihan (#, sama dokumen).  Untuk unsur lain, seperti <image>, hanya data: dan serpihan dibenarkan.  Cuba membenamkan imej apabila mengeksport SVG anda. Dijumpai <code>&lt;$1 $2=\"$3\"&gt;</code>.",
+       "uploaded-href-unsafe-target-svg": "Dijumpai href ke sasaran data: URI tidak selamat <code>&lt;$1 $2=\"$3\"&gt;</code> dalam fail SVG yang dimuat naik.",
        "uploaded-animate-svg": "Terdapat teg \"animate\" yang mungkin sedang mengubah href, menggunakan atribut \"from\" <code>&lt;$1 $2=\"$3\"&gt;</code> dalam fail SVG yang dimuat naik.",
        "uploaded-setting-event-handler-svg": "Dilarang menetapkan atribut <i>event-handler</i>, terdapat <code>&lt;$1 $2=\"$3\"&gt;</code> dalam fail SVG yang dimuat naik.",
        "uploaded-setting-href-svg": "Dilarang menggunakan teg \"set\" untuk menambahkan atribut \"href\" kepada elemen induk.",
        "upload-too-many-redirects": "URL ini mengandungi terlalu banyak lencongan",
        "upload-http-error": "Berlaku ralat HTTP: $1",
        "upload-copy-upload-invalid-domain": "Muat naik salin tidak terdapat dari domain ini.",
+       "upload-foreign-cant-upload": "Wiki ini tidak dikonfigurasikan untuk memuat naik ke repositori fail asing yang dipinta.",
+       "upload-foreign-cant-load-config": "Gagal memuat konfigurasi untuk pemuatan naik fail ke repositori fail asing.",
+       "upload-dialog-disabled": "Pemuatan naik fail menggunakan dialog ini dinyahaktifkan pada wiki ini.",
        "upload-dialog-title": "Muat naik fail",
        "upload-dialog-button-cancel": "Batalkan",
+       "upload-dialog-button-back": "Belakang",
        "upload-dialog-button-done": "Siap",
        "upload-dialog-button-save": "Simpan",
        "upload-dialog-button-upload": "Muat naik",
        "upload-form-label-infoform-title": "Butiran",
        "upload-form-label-infoform-name": "Nama",
+       "upload-form-label-infoform-name-tooltip": "Tajuk deskriptif unik untuk fail, yang akan berfungsi sebagai nama fail. Anda boleh menggunakan bahasa biasa dengan jarak. Jangan masukkan sambungan fail.",
        "upload-form-label-infoform-description": "Keterangan",
+       "upload-form-label-infoform-description-tooltip": "Terangkan secara ringkas segala yang ketara tentang kerja.\nUntuk foto, sebutkan perkara utama yang digambarkan, peristiwa, atau tempat.",
        "upload-form-label-usage-title": "Penggunaan",
        "upload-form-label-usage-filename": "Nama fail",
        "upload-form-label-own-work": "Ini ialah karya saya sendiri",
        "upload-form-label-infoform-categories": "Kategori",
        "upload-form-label-infoform-date": "Tarikh",
        "upload-form-label-own-work-message-generic-local": "Saya mengesahkan bahawa saya memuat naik fail ini dengan mengikut terma perkhidmatan dan dasar perlesenan di {{SITENAME}}.",
+       "upload-form-label-not-own-work-message-generic-local": "Jika anda tidak dapat memuat naik fail menurut dasar {{SITENAME}}, sila tutup dialog ini dan cuba kaedah lain.",
        "upload-form-label-not-own-work-local-generic-local": "Anda mungkin juga mahu mencuba [[Special:Upload|laman muat naik yang asal]].",
+       "upload-form-label-own-work-message-generic-foreign": "Saya faham bahawa saya memuat naik fail ini ke repositori yang dikongsi. Saya mengesahkan bahawa saya berbuat demikian mengikut syarat-syarat perkhidmatan dan dasar pelesenan di sana.",
+       "upload-form-label-not-own-work-message-generic-foreign": "Jika anda tidak dapat memuat naik fail ini menurut dasar repositori yang dikongsi tersebut, sila tutup dialog ini dan cuba kaedah lain.",
+       "upload-form-label-not-own-work-local-generic-foreign": "Anda juga mungkin berkeinginan untuk mencuba menggunakan [[Special:Upload|laman muat naik pada {{SITENAME}}]], jika fail ini oleh dimuat naik di sana menurut dasar mereka.",
        "backend-fail-stream": "Fail $1 tidak dapat distrimkan.",
        "backend-fail-backup": "Fail $1 tidak dapat disandarkan.",
        "backend-fail-notexists": "Fail $1 tidak wujud.",
        "backend-fail-read": "Fail $1 tidak dapat dibaca.",
        "backend-fail-create": "Fail $1 tidak dapat ditulis.",
        "backend-fail-maxsize": "Fail $1 tidak boleh ditulis kerana melebihi $2 bait.",
-       "backend-fail-readonly": "Backend storan \"$1\" kini dalam mod baca sahaja. Sebab yang diberikan ialah: \"$2\"",
+       "backend-fail-readonly": "Bahagian belakang simpanan \"$1\" hanya baca sahaja pada masa ini. Sebab diberikan: <em>$2</em>",
        "backend-fail-synced": "Fail \"$1\" berada dalam keadaan yang tidak sejajar dalam backend storan dalaman",
        "backend-fail-connect": "Tidak dapat bersambung dengan backend storan \"$1\".",
        "backend-fail-internal": "Berlakunya ralat yang tidak dikenali dalam backend storan \"$1\".",
        "lockmanager-fail-closelock": "Fail kunci untuk \"$1\" tidak dapat ditutup.",
        "lockmanager-fail-deletelock": "Fail kunci untuk \"$1\" tidak dapat dihapuskan.",
        "lockmanager-fail-acquirelock": "Kunci untuk \"$1\" tidak dapat diperoleh.",
-       "lockmanager-fail-openlock": "Fail kunci untuk \"$1\" tidak dapat dibuka.",
+       "lockmanager-fail-openlock": "Tidak dapat membukan fail kunci untuk \"$1\". Pastikan direktori muat naik anda dikonfigurasikan secara betul dan pelayar web anda mempunyai keizinan untuk menulis direktori tersebut. Lihat https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:$wgUploadDirectory untuk maklumat lanjut.",
        "lockmanager-fail-releaselock": "Kunci untuk \"$1\" tidak dapat dikeluarkan.",
        "lockmanager-fail-db-bucket": "Di baldi $1 tidak dapat dihubungi pangkalan data selak yang secukupnya.",
        "lockmanager-fail-db-release": "Selak-selak tidak dapat dikeluarkan di pangkalan data $1.",
        "uploadstash-summary": "Laman ini menyediakan capaian kepada fail-fail yang dimuat naik (atau sedang dimuat naik) tapi belum diterbitkan ke dalam wiki. Fail-fail ini tidak dapat dilihat oleh sesiapa melainkan pengguna yang memuatnaiknya.",
        "uploadstash-clear": "Bersihkan fail-fail sorokan",
        "uploadstash-nofiles": "Anda tiada sebarang fail sorokan.",
-       "uploadstash-badtoken": "Tindakan tadi tidak berjaya, mungkin kerana kelayakan menyunting anda telah luput. Cuba lagi.",
-       "uploadstash-errclear": "Gagal membersihkan fail-fail tersebut.",
+       "uploadstash-badtoken": "Melaksanakan tindakan tersebut gagal, mungkin kerana kelayakan penyuntingan anda mansuh. Sila cuba lagi.",
+       "uploadstash-errclear": "Penghapusan fail gagal.",
        "uploadstash-refresh": "Segarkan semula senarai fail",
+       "uploadstash-thumbnail": "lihat gambar kenit",
+       "uploadstash-exception": "Tidak dapat menyimpan muat naik dalam tempat sorokan ($1): \"$2\".",
+       "uploadstash-bad-path": "Laluan tidak wujud.",
+       "uploadstash-bad-path-invalid": "Laluan tidak sah.",
+       "uploadstash-bad-path-unknown-type": "Jenis \"$1\" tidak diketahui.",
+       "uploadstash-bad-path-unrecognized-thumb-name": "Nama gambar kecil tidak dikenali.",
+       "uploadstash-bad-path-no-handler": "Tiada pengendali dijumpai untuk mimik $1 bagi fail $2.",
+       "uploadstash-bad-path-bad-format": "Kunci \"$1\" bukan dalam format yang betul.",
+       "uploadstash-file-not-found": "Kunci \"$1\" tidak dijumpai dalam tempat sorokan.",
+       "uploadstash-file-not-found-no-thumb": "Tidak dapat mendapatkan gambar kecil.",
+       "uploadstash-file-not-found-no-local-path": "Tiada laluan tempatan untuk item terskala.",
+       "uploadstash-file-not-found-no-object": "Tidak dapat mencipta objek fail tempatan untuk gambar kenit.",
+       "uploadstash-file-not-found-no-remote-thumb": "Pengambilan gambar kecil gagal: $1\nURL = $2",
+       "uploadstash-file-not-found-missing-content-type": "Pengepala jenis kandungan hilang.",
+       "uploadstash-file-not-found-not-exists": "Tidak dapat mencari laluan, atau bukan fail biasa.",
+       "uploadstash-file-too-large": "Tidak dapat melayan fail yang lebih besar dari $1 bait.",
+       "uploadstash-not-logged-in": "Tiada pengguna melog masuk, fail setentunya milik pengguna.",
+       "uploadstash-wrong-owner": "Fail ini ($1) tidak dimiliki oleh pengguna semasa.",
+       "uploadstash-no-such-key": "Tiada kunci sepertinya ($1), tidak dapat dikeluarkan.",
+       "uploadstash-no-extension": "Sambungan nol.",
+       "uploadstash-zero-length": "Fail berkepanjangan kosong.",
        "invalid-chunk-offset": "Ofset ketulan tidak sah",
        "img-auth-accessdenied": "Capaian ditolak",
-       "img-auth-nopathinfo": "PATH_INFO tertinggal.\nPelayan anda tidak ditetapkan untuk menyampaikan maklumat ini.\nIa barangkali berdasarkan CGI dan tidak boleh menyokong img_auth.\nRujuk https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Image_Authorization",
+       "img-auth-nopathinfo": "Maklumat laluan hilang.\nPelayan anda mesti ditetapkan untuk melewati pembolehubah REQUEST_URI dan/atau PATH_INFO.\nJika ada, cuba mendayakan $wgUsePathInfo.\nLihat https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Image_Authorization.",
        "img-auth-notindir": "Laluan yang diminta tiada dalam direktori muat naik yang telah dikonfigurasikan.",
        "img-auth-badtitle": "Tajuk yang sah tidak dapat dibina daripada \"$1\".",
        "img-auth-nofile": "Fail \"$1\" tiada.",
        "http-timed-out": "Permintaan HTTP melebihi waktu tamat.",
        "http-curl-error": "Ralat mendapatkan URL: $1",
        "http-bad-status": "Berlaku masalah ketika permintaan HTTP: $1 $2",
+       "http-internal-error": "Ralat dalaman HTTP.",
        "upload-curl-error6": "URL tidak dapat dicapai",
        "upload-curl-error6-text": "URL yang dinyatakan tidak dapat dicapai. Sila pastikan bahawa URL dan tapak web tersebut hidup.",
        "upload-curl-error28": "Waktu henti muat naik",
        "listfiles_size": "Saiz",
        "listfiles_description": "Keterangan",
        "listfiles_count": "Versi",
-       "listfiles-show-all": "Masukkan versi lama imej",
+       "listfiles-show-all": "Masukkan versi lama fail",
        "listfiles-latestversion": "Versi semasa",
        "listfiles-latestversion-yes": "Ya",
        "listfiles-latestversion-no": "Tidak",
        "filerevert-submit": "Balikkan",
        "filerevert-success": "<span class=\"plainlinks\">'''[[Media:$1|$1]]''' telah dibalikkan kepada [$4 versi pada $3, $2].</span>",
        "filerevert-badversion": "Tiada versi tempatan bagi fail ini dengan cap waktu yang dinyatakan.",
+       "filerevert-identical": "Versi semasa fail sudah seiras dengan yang dipilih.",
        "filedelete": "Hapuskan $1",
        "filedelete-legend": "Hapuskan fail",
        "filedelete-intro": "Anda sudah hendak menghapuskan fail '''[[Media:$1|$1]]''' berserta semua sejarahnya.",
        "pageswithprop-legend": "Laman dengan sifat laman",
        "pageswithprop-text": "Halaman ini menyenaraikan halaman-halaman yang menggunakan sifat halaman yang tertentu.",
        "pageswithprop-prop": "Nama sifat:",
+       "pageswithprop-reverse": "Isih dalam urutan terbalik",
+       "pageswithprop-sortbyvalue": "Isih mengikut nilai sifat",
        "pageswithprop-submit": "Pergi",
        "pageswithprop-prophidden-long": "nilai sifat teks panjang tersorok ($1)",
        "pageswithprop-prophidden-binary": "nilai sifat binari tersorok ($1)",
        "doubleredirects": "Lencongan berganda",
        "doubleredirectstext": "Yang berikut ialah senarai laman yang melencong ke laman lencongan lain. Setiap baris mengandungi pautan ke laman lencongan pertama dan kedua, serta baris pertama bagi teks lencongan kedua, lazimnya merupakan laman sasaran \"sebenar\", yang sepatutnya ditujui oleh lencongan pertama.\nMasukan yang <del>dipotong</del> telah diselesaikan.",
        "double-redirect-fixed-move": "[[$1]] telah dipindahkan.\nIa dikemaskinikan secara automatik dan sekarang melencong ke [[$2]].",
-       "double-redirect-fixed-maintenance": "Membetulkan dwilecongan dari [[$1]] ke [[$2]] dalam kerja kemaskinian.",
+       "double-redirect-fixed-maintenance": "Membetulkan secara automatik lencongan berganda dari [[$1]] ke [[$2]] dalam kerja pengemaskinian.",
        "double-redirect-fixer": "Pembaiki lencongan",
        "brokenredirects": "Lencongan rosak",
        "brokenredirectstext": "Lencongan-lencongan berikut menuju ke laman yang tidak wujud:",
        "uncategorizedcategories": "Kategori tanpa kategori",
        "uncategorizedimages": "Imej tanpa kategori",
        "uncategorizedtemplates": "Templat tanpa kategori",
+       "uncategorized-categories-exceptionlist": "# Mengandungi senarai kategori, yang tidak boleh disebut di Special:UncategorizedCategories. Satu setiap baris, bermula dengan \"*\". Baris yang bermula dengan aksara lain (termasuk jarak putih) diabaikan. Gunakan \"#\" untuk ulasan.",
        "unusedcategories": "Kategori tidak digunakan",
        "unusedimages": "Imej tidak digunakan",
        "wantedcategories": "Kategori dikehendaki",
        "mostrevisions": "Rencana dengan semakan terbanyak",
        "prefixindex": "Indeks awalan",
        "prefixindex-namespace": "Semua laman dengan awalan (ruang nama $1)",
-       "prefixindex-strip": "Gugurkan awalan dalam senarai",
+       "prefixindex-submit": "Tunjukkan",
+       "prefixindex-strip": "Sembunyikan awalan dalam hasil",
        "shortpages": "Laman pendek",
        "longpages": "Laman panjang",
        "deadendpages": "Laman buntu",
        "deadendpagestext": "Laman-laman berikut tidak mengandungi pautan ke laman lain di {{SITENAME}}.",
        "protectedpages": "Laman dilindungi",
+       "protectedpages-filters": "Penapis:",
        "protectedpages-indef": "Perlindungan tanpa had sahaja",
        "protectedpages-summary": "Halaman ini menyenaraikan halaman-halaman sedia anda yang sedang dilindungi. Untuk senarai tajuk yang dilindungi dari pembukaan, rujuk [[{{#special:ProtectedTitles}}|{{int:protectedtitles}}]].",
        "protectedpages-cascade": "Perlindungan separa sahaja",
        "protectedpages-performer": "Pelindung",
        "protectedpages-params": "Parameter perlindungan",
        "protectedpages-reason": "Sebab",
+       "protectedpages-submit": "Laman paparan",
        "protectedpages-unknown-timestamp": "Tidak diketahui",
        "protectedpages-unknown-performer": "Pengguna tidak dikenali",
        "protectedtitles": "Tajuk dilindungi",
        "protectedtitles-summary": "Laman ini menyenaraikan tajuk-tajuk yang telah dilindungi daripada penciptaan. Untuk senarai semua laman sedia ada yang telah dilindungi, lihat [[{{#special:ProtectedPages}}|{{int:protectedpages}}]].",
        "protectedtitlesempty": "Tiada tajuk yang dilindungi yang sepadan dengan kriteria yang diberikan.",
+       "protectedtitles-submit": "Tajuk paparan",
        "listusers": "Senarai pengguna",
        "listusers-editsonly": "Hanya papar pengguna yang telah membuat suntingan",
+       "listusers-temporarygroupsonly": "Hanya tunjukkan pengguna dalam kumpulan pengguna sementara",
        "listusers-creationsort": "Susun mengikut tarikh penciptaan",
        "listusers-desc": "Susun dalam turutan menurun",
        "usereditcount": "$1 suntingan",
        "usercreated": "{{GENDER:$3|Dibuat}} pada $1, $2",
        "newpages": "Laman baru",
+       "newpages-submit": "Tunjukkan",
        "newpages-username": "Nama pengguna:",
        "ancientpages": "Laman lapuk",
        "move": "Pindahkan",
        "movethispage": "Pindahkan laman ini",
        "unusedimagestext": "Fail-fail berikut wujud tetapi tidak digunakan dalam mana-mana laman.\nSila ambil perhatian bahawa mungkin terdapat tapak web lain yang memaut ke fail ini menggunakan URL langsung, dan masih disenaraikan di sini walapun berada dalam kegunaan aktif.",
+       "unusedimagestext-categorizedimgisused": "Fail berikut wujud tetapi tidak terbenam dalam mana-mana laman. Imej yang dikategorikan dianggap sebagai terguna walaupun tidak terbenam dalam mana-mana laman.\nSila ambil perhatian bahawa laman web lain boleh dipautkan ke fail dengan URL terus, dan oleh itu masih mungkin disenaraikan di sini meskipun sedang aktif digunakan.",
        "unusedcategoriestext": "Laman-laman kategori berikut wujud walaupun tiada laman atau kategori lain menggunakannya.",
        "notargettitle": "Tiada sasaran",
        "notargettext": "Anda tidak menyatakan laman atau pengguna sebagai sasaran bagi tindakan ini.",
        "nopagetext": "Laman sasaran yang anda nyatakan tidak wujud.",
        "pager-newer-n": "{{PLURAL:$1|$1 berikutnya}}",
        "pager-older-n": "{{PLURAL:$1|$1 sebelumnya}}",
-       "suppress": "Kawalan",
+       "suppress": "Tahan",
        "querypage-disabled": "Laman khas ini dilumpuhkan atas sebab-sebab prestasi.",
        "apihelp": "Bantuan API",
        "apihelp-no-such-module": "Modul \"$1\" tidak dijumpai.",
        "apisandbox": "Kotak pasir API",
+       "apisandbox-jsonly": "JavaScript diperlukan untuk menggunakan kotak pasir API.",
        "apisandbox-api-disabled": "API dimatikan di tapak web ini.",
        "apisandbox-intro": "Gunakan laman ini untuk bereksperimen dengan '''API perkhidmatan sesawang MediaWiki'''.\nRujuk [https://www.mediawiki.org/wiki/API:Main_page dokumentasi API] untuk keterangan lanjut tentang penggunaan API.\nContoh: [https://www.mediawiki.org/wiki/API#A_simple_example dapatkan kandungan Laman Utama].  Pilih satu tindakan untuk melihat banyak lagi contoh.",
        "apisandbox-submit": "Buat permintaan",
        "apisandbox-reset": "Padamkan",
+       "apisandbox-retry": "Cuba semula",
+       "apisandbox-loading": "Memuat maklumat untuk modul API \"$1\"...",
+       "apisandbox-load-error": "Ralat berlaku ketika memuat maklumat untuk modul API \"$1\": $2.",
+       "apisandbox-no-parameters": "Modul API ini tiada mempunyai parameter.",
+       "apisandbox-helpurls": "Pautan bantuan",
        "apisandbox-examples": "Contoh",
+       "apisandbox-dynamic-parameters": "Parameter tambahan",
+       "apisandbox-dynamic-parameters-add-label": "Tambah parameter:",
+       "apisandbox-dynamic-parameters-add-placeholder": "Nama parameter",
+       "apisandbox-dynamic-error-exists": "Parameter bernama \"$1\" sudah wujud.",
+       "apisandbox-templated-parameter-reason": "[[Special:ApiHelp/main#main/templatedparams|Parameter tertemplat]] ini ditawarkan berdasarkan {{PLURAL:$1|nilai}} $2.",
+       "apisandbox-deprecated-parameters": "Parameter usang",
+       "apisandbox-fetch-token": "Isi token dengan automatik",
+       "apisandbox-add-multi": "Tambah",
+       "apisandbox-submit-invalid-fields-title": "Beberapa medan tidak sah",
+       "apisandbox-submit-invalid-fields-message": "Sila betulkan medan yang ditandai dan cuba lagi.",
        "apisandbox-results": "Hasil",
+       "apisandbox-sending-request": "Menghantar permintaan API...",
+       "apisandbox-loading-results": "Menerima hasil API...",
+       "apisandbox-results-error": "Ralat berlaku ketika memuat jawapan pertanyaan API: $1.",
+       "apisandbox-results-login-suppressed": "Permintaan ini telah diproses sebagai pengguna yang dilog keluar kerana ia boleh digunakan untuk memintas keselamatan Sama-Asal pelayar. Perhatikan bahawa pengendalian token automatik kotak pasir API tidak berfungsi dengan betul dengan permintaan tersebut, sila isi secara manual.",
+       "apisandbox-request-selectformat-label": "Tunjukkan data permintaan sebagai:",
+       "apisandbox-request-format-url-label": "Rentetan pertanyaan URL",
        "apisandbox-request-url-label": "URL permohonan:",
-       "apisandbox-request-time": "Waktu pemohonan: $1",
+       "apisandbox-request-json-label": "Minta JSON:",
+       "apisandbox-request-time": "Waktu permintaan: {{PLURAL:$1|$1 ms}}",
+       "apisandbox-results-fixtoken": "Betulkan token dan hantar semula",
+       "apisandbox-results-fixtoken-fail": "Gagal untuk mengambil token \"$1\".",
+       "apisandbox-alert-page": "Medan pada laman ini tidak sah.",
+       "apisandbox-alert-field": "Nilai medan ini tidak sah.",
+       "apisandbox-continue": "Teruskan",
+       "apisandbox-continue-clear": "Kosongkan",
+       "apisandbox-continue-help": "{{int:apisandbox-continue}} akan [https://www.mediawiki.org/wiki/API:Query#Continuing_queries meneruskan] permintaan terakhir; {{int:apisandbox-continue-clear}} akan mengosongkan parameter berkaitan sambungan.",
+       "apisandbox-param-limit": "Masukkan <kbd>maks</kbd> untuk menggunakan had maksimum.",
+       "apisandbox-multivalue-all-namespaces": "$1 (Semua ruang nama)",
+       "apisandbox-multivalue-all-values": "$1 (Semua nilai)",
        "booksources": "Sumber buku",
        "booksources-search-legend": "Cari sumber buku",
        "booksources-search": "Cari",
        "booksources-text": "Yang berikut ialah senarai pautan ke tapak web lain yang menjual buku baru dan terpakai,\nserta mungkin mempunyai maklumat lanjut mengenai buku yang anda cari:",
        "booksources-invalid-isbn": "ISBN yang dinyatakan tidak sah. Sila semak sekali lagi.",
+       "magiclink-tracking-rfc": "Laman menggunakan pautan ajaib RFC",
+       "magiclink-tracking-rfc-desc": "Laman ini menggunakan pautan ajaib RFC. Lihat [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Magic_links mediawiki.org] untuk mengetahui bagaimana melakukan penghijrahan.",
+       "magiclink-tracking-pmid": "Laman menggunakan pautan ajaib PMID",
+       "magiclink-tracking-pmid-desc": "Laman ini menggunakan pautan ajaib PMID. Lihat [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Magic_links mediawiki.org] untuk mengetahui bagaimana melakukan penghijrahan.",
+       "magiclink-tracking-isbn": "Laman menggunakan pautan ajaib ISBN",
+       "magiclink-tracking-isbn-desc": "Laman ini menggunakan pautan ajaib ISBN. Lihat [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Magic_links mediawiki.org] untuk mengetahui bagaimana melakukan penghijrahan.",
        "specialloguserlabel": "Pelaku:",
        "speciallogtitlelabel": "Sasaran (tajuk atau {{ns:user}}:nama pengguna):",
        "log": "Log",
+       "logeventslist-submit": "Tunjukkan",
+       "logeventslist-more-filters": "Tunjukkan log tambahan:",
+       "logeventslist-patrol-log": "Ronda log",
+       "logeventslist-tag-log": "Teg log",
        "all-logs-page": "Semua log awam",
        "alllogstext": "Yang berikut ialah gabungan bagi semua log yang ada bagi {{SITENAME}}. Anda boleh menapis senarai ini dengan memilih jenis log, nama pengguna (peka huruf besar), atau nama laman yang terjejas (juga peka huruf besar).",
        "logempty": "Tiada item yang sepadan dalam log.",
        "log-title-wildcard": "Cari semua tajuk yang bermula dengan teks ini",
        "showhideselectedlogentries": "Tunjukkan/sorokkan entri-entri log yang terpilih",
        "log-edit-tags": "Sunting teg-teg entri log terpilih",
+       "checkbox-select": "Pilih: $1",
+       "checkbox-all": "Semua",
+       "checkbox-none": "Tiada",
        "allpages": "Semua laman",
        "nextpage": "Halaman berikutnya ($1)",
        "prevpage": "Halaman sebelumnya ($1)",
        "tooltip-pt-preferences": "Keutamaan {{GENDER:|anda}}",
        "tooltip-pt-watchlist": "Senarai laman yang anda pantau",
        "tooltip-pt-mycontris": "Senarai sumbangan {{GENDER:|anda}}",
-       "tooltip-pt-login": "Walaupun tidak wajib, anda digalakkan supaya log masuk.",
+       "tooltip-pt-login": "Anda digalakkan untuk melog masuk; walau bagaimanapun, ianya tidak wajib.",
        "tooltip-pt-logout": "Log keluar",
-       "tooltip-pt-createaccount": "Anda digalakkan untuk membuka akaun dan log masuk; namun begitu ianya tidak diwajibkan",
+       "tooltip-pt-createaccount": "Anda digalakkan untuk membuka akaun dan melog masuk; walau bagaimanapun, ianya tidak wajib",
        "tooltip-ca-talk": "Perbincangan mengenai laman kandungan",
        "tooltip-ca-edit": "Sunting laman ini",
        "tooltip-ca-addsection": "Buka bahagian baru",
        "tooltip-ca-viewsource": "Laman ini dilindungi. Anda boleh melihat sumbernya.",
-       "tooltip-ca-history": "Versi-versi terdahulu bagi laman ini.",
+       "tooltip-ca-history": "Semakan terdahulu bagi laman ini",
        "tooltip-ca-protect": "Lindungi laman ini",
        "tooltip-ca-unprotect": "Ubah tahap perlindungan laman ini",
        "tooltip-ca-delete": "Hapuskan laman ini",
        "tooltip-ca-move": "Pindahkan laman ini",
        "tooltip-ca-watch": "Tambahkan laman ini ke dalam senarai pantau anda",
        "tooltip-ca-unwatch": "Buang laman ini daripada senarai pantau anda",
-       "tooltip-search": "Cari dalam {{SITENAME}}",
-       "tooltip-search-go": "Pergi ke laman dengan nama tepat ini, jika ada",
+       "tooltip-search": "Cari {{SITENAME}}",
+       "tooltip-search-go": "Pergi ke laman dengan nama tepat ini jika ada",
        "tooltip-search-fulltext": "Cari laman dengan teks ini",
        "tooltip-p-logo": "Kunjungi laman utama",
        "tooltip-n-mainpage": "Kunjungi Laman Utama",
        "tooltip-n-mainpage-description": "Kunjungi laman utama",
-       "tooltip-n-portal": "Maklumat mengenai projek ini",
+       "tooltip-n-portal": "Tentang projek, apa yang anda dapat lakukan, di mana untuk mencari sesuatu",
        "tooltip-n-currentevents": "Cari maklumat latar belakang mengenai peristiwa semasa",
-       "tooltip-n-recentchanges": "Senarai perubahan terkini dalam wiki ini.",
-       "tooltip-n-randompage": "Buka laman rawak",
+       "tooltip-n-recentchanges": "Senarai perubahan terkini dalam wiki",
+       "tooltip-n-randompage": "Muat laman rawak",
        "tooltip-n-help": "Tempat mencari jawapan",
-       "tooltip-t-whatlinkshere": "Senarai laman wiki yang mengandungi pautan ke laman ini",
-       "tooltip-t-recentchangeslinked": "Perubahan terkini bagi semua laman yang dipaut dari laman ini",
+       "tooltip-t-whatlinkshere": "Senarai semua laman wiki yang mengandungi pautan ke laman ini",
+       "tooltip-t-recentchangeslinked": "Perubahan terkini bagi laman yang dipaut dari laman ini",
        "tooltip-feed-rss": "Suapan RSS bagi laman ini",
        "tooltip-feed-atom": "Suapan Atom bagi laman ini",
        "tooltip-t-contributions": "Senarai sumbangan {{GENDER:$1|pengguna ini}}",
        "tooltip-t-emailuser": "Kirim e-mel kepada {{GENDER:$1|pengguna ini}}",
        "tooltip-t-info": "Maklumat lanjut mengenai laman ini",
-       "tooltip-t-upload": "Muat naik imej atau fail media",
-       "tooltip-t-specialpages": "Senarai laman khas",
+       "tooltip-t-upload": "Muat naik fail",
+       "tooltip-t-specialpages": "Senarai semua laman khas",
        "tooltip-t-print": "Versi boleh cetak bagi laman ini",
-       "tooltip-t-permalink": "Pautan kekal ke versi ini",
+       "tooltip-t-permalink": "Pautan kekal ke semakan laman ini",
        "tooltip-ca-nstab-main": "Lihat laman kandungan",
        "tooltip-ca-nstab-user": "Lihat laman pengguna",
        "tooltip-ca-nstab-media": "Lihat laman media",
-       "tooltip-ca-nstab-special": "Ini ialah laman khas yang tidak boleh disunting.",
+       "tooltip-ca-nstab-special": "Ini ialah laman khas, dan ia tidak boleh disunting",
        "tooltip-ca-nstab-project": "Lihat laman projek",
        "tooltip-ca-nstab-image": "Lihat laman imej",
        "tooltip-ca-nstab-mediawiki": "Lihat pesanan sistem",
        "feedback-thanks": "Terima kasih! Maklum balas anda telah dicatatkan pada laman \"[$2 $1]\".",
        "feedback-thanks-title": "Terima kasih!",
        "feedback-useragent": "Ejen pengguna:",
-       "searchsuggest-search": "Cari dalam {{SITENAME}}",
+       "searchsuggest-search": "Cari {{SITENAME}}",
        "searchsuggest-containing": "mengandungi...",
        "api-error-badtoken": "Ralat dalaman: token tak elok.",
        "api-error-emptypage": "Anda tidak dibenarkan membuat laman baru yang kosong.",
index 094937d..2410063 100644 (file)
        "emailccme": "ကျွန်ုပ်ပို့လိုက်သော အီးမေးကော်ပီကို ကျွန်ုပ်ထံ ပြန်ပို့ပါ။",
        "emailsent": "အီးမေးပို့လိုက်ပြီ",
        "emailsenttext": "သင့်အီးမေးမက်ဆေ့ကို ပို့လိုက်ပြီးပြီ ဖြစ်သည်။",
+       "emailuserfooter": "ဤအီးမေးလ်ကို $1 မှ {{GENDER:$2|$2}} သို့ {{SITENAME}}ပေါ်တွင် \"{{int:emailuser}}\" လုပ်ဆောင်ချက်ကိုအသုံးပြု၍ {{GENDER:$1|ပေးပို့ခဲ့သည်}}။ အကယ်၍ ဤအီးမေးလ်ကို {{GENDER:$2|သင်}}အကြောင်းပြန်ပါက {{GENDER:$2|သင်၏}}အီးမေးလ်သည် {{GENDER:$2|သင့်}}အီးမေးလ်လိပ်စာကို {{GENDER:$1|သူတို့}}ဆီ၌ဖော်ပြရင်း {{GENDER:$1|မူလပို့ပေးသူ}}ထံသို့ တိုက်ရိုက်ရောက်ရှိမည်ဖြစ်ပါသည်။",
        "usermessage-summary": "စနစ်စာတို ချန်ထားခြင်း။",
        "usermessage-editor": "စနစ်မက်ဆင်ဂျာ",
        "watchlist": "စောင့်ကြည့်စာရင်း",
index 23daede..34af306 100644 (file)
        "edit-error-short": "Fout: $1",
        "edit-error-long": "Fouten:\n\n$1",
        "specialmute": "Negeren",
-       "specialmute-success": "Het bijwerken van uw voorkeur voor het negeren is geslaagd. Bekijk een lijst met alle genegeerde gebruikers in [[Special:Preferences|uw voorkeuren]].",
+       "specialmute-success": "Uw voorkeuren voor het negeren zijn bijgewerkt. Bekijk een lijst met alle genegeerde gebruikers in [[Special:Preferences|uw voorkeuren]].",
        "specialmute-submit": "Bevestig",
        "specialmute-label-mute-email": "Negeer e-mails van deze gebruiker",
        "specialmute-header": "Selecteer uw voorkeur voor het negeren van {{BIDI:[[User:$1]]}}.",
index 19511ff..50b9aaf 100644 (file)
        "undo-failure": "ߡߊ߬ߦߟߍ߬ߡߊ߲߬ߠߌ߲ ߕߍ߫ ߣߊ߬ ߛߋ߫ ߟߊ߫ ߘߐߛߊ߬ ߟߊ߫߸ ߝߘߏ߬ߒ߬ߡߊ߬ߟߌ߬ ߡߊߦߟߍߡߊ߲ߠߌ߲ ߞߏߛߐ߲߬.",
        "viewpagelogs": "ߞߐߜߍ ߣߌ߲߬ ߜߊ߲߬ߞߎ߲߬ߠߌ߲ ߠߎ߬ ߦߋ߫",
        "nohistory": "ߡߊ߬ߦߟߍ߬ߡߊ߲߬ߠߌ߲ ߘߐ߬ߝߐ߬ ߛߌ߫ ߕߍ߫ ߞߐߜߍ ߣߌ߲߬ ߠߊ߫",
+       "currentrev": "ߡߊ߬ߛߊ߬ߦߌ߲߬ߠߌ߲ ߕߊ߬ߡߌ߲߬ߣߍ߲",
        "currentrev-asof": "$1 ߟߊ߫ ߡߊ߬ߦߟߍ߬ߡߊ߲߬ߠߌ߲ ߕߊ߬ߡߌ߲߬ߣߍ߲",
        "revisionasof": "ߊ߬ ߡߊߛߊ߬ߦߌ߲ ߦߊ߲߬ ߓߊ߫ 1$",
        "revision-info": "ߡߊ߬ߦߟߍ߬ߡߊ߲߬ߣߍ߲߫ $1 ߟߋ߬ ߓߟߏ߫ {{GENDER:$6|$2}}$7",
        "page_last": "ߟߊ߬ߓߊ߲",
        "histlegend": "ߝߘߏ߬ߢߐ߲߰ߡߊ ߡߊߡߌ߬ߘߊ: ߓߊߓߌߟߊߟߌ߫ ߞߏ߲ߘߏ ߡߊߡߌ߬ߘߊ߬ ߟߊߢߐ߲߯ߡߊ߫ ߞߊߡߊ߬߸ ߊ߬ ߣߌ߫ ߞߊ߬ ߟߊߢߐ߲߯ߡߊ߫ ߞߘߎ ߛߐ߲߬ߞߌ߲߫ ߊ߬ ߣߌ߫ ߓߊ߫ ߡߊߡߌ߬ߣߊ߬ߣߍ߲ ߕߍ߫ ߥߟߊ߫ ߞߎ߬ߘߎ ߡߍ߲ ߦߋ߫ ߘߎ߰ߟߊ߫. < br/> Legend: ({{int: cur}}) = ߓߐߢߐ߲߯ߡߊ ߡߍ߲ ߦߋ߫ ߕߋ߲߬ߕߋ߲߬ ߓߊ ߟߊ߫߸ ({{int: ߟߊߓߊ߲}}) = ߓߐߢߐ߲߯ߡߊ ߡߍ߲ ߦߋ߫ ߓߊ߫ ߕߊ߬ߡߌ߲߬ߣߍ߲ ߝߍ߬߸ {{int: ߢߟߊߞߎߘߦߊ߫ ߞߏߘߋߞߏߘߋ}} = ߛߊߞߍߟߌ߫ ߝߕߌߣߍ߲߫.",
        "history-fieldset-title": "ߣߐ߬ߡߊ߬ߛߊߦߌ߲ ߠߎ߬ ߛߍ߲ߛߍ߲߫",
+       "history-show-deleted": "ߟߢߊ߬ߟߌ ߖߏ߰ߛߌ߬ߣߍ߲ ߠߎ߬ ߘߐߙߐ߲߫",
        "histfirst": "ߞߘߐ߬ߡߊ߲ ߠߎ߬",
        "histlast": "ߞߎߘߊ ߟߎ߬",
        "historysize": "{{PLURAL:$1|ߝߙߐ߬ߢߐ|$1 ߝߙߐ߬ߢߐ ߟߎ߬}}",
        "rev-deleted-comment": "(ߟߊ߬ߘߛߏ߬ߟߌ ߛߋ߲߬ߓߐߣߍ߲ ߡߊߦߟߍ߬ߡߊ߲߫)",
        "rev-deleted-user": "(ߟߊ߬ߓߊ߰ߙߊ߬ߕߐ߮ ߓߘߊ߫ ߛߋ߲߬ߓߐ߫)",
        "rev-deleted-event": "(ߘߎ߲ߛߓߍ ߝߊߙߊ߲ߝߊ߯ߛߌ ߓߘߊ߫ ߛߋ߲߬ߓߐ߫)",
+       "rev-deleted-user-contribs": "[ߟߊ߬ߓߊ߰ߙߊ߬ ߕߐ߮ ߥߟߊ߫ IP ߛߊ߲߬ߓߊ߬ߕߐ߮ ߓߘߊ߫ ߛߋ߲߬ߓߐ߫ - ߡߊ߬ߦߟߍ߬ߡߊ߲߬ߠߌ߲ ߢߡߊߘߏ߲߰ߣߍ߲ ߓߟߏߓߌߟߊߢߐ߲߯ߞߊ߲ ߡߊ߬]",
+       "rev-deleted-text-permission": "ߞߐߜߍ ߣߌ߲߬ ߓߘߊ߫ ߓߊ߲߫ <strong>ߖߏ߰ߛߌ߬ ߟߊ߫</strong>. \nߝߊߙߊ߲ߝߊ߯ߛߌ ߘߌ߫ ߛߋ߫ ߛߐ߬ߘߐ߲߬ ߠߊ߫ ߦߊ߲߬  [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} deletion log].",
+       "rev-suppressed-text-permission": "ߞߐߜߍ ߣߌ߲߬ ߟߢߊ߬ߟߌ ߓߘߊ߫ ߓߊ߲߫ <strong>ߖߏ߰ߛߌ߬ ߟߊ߫</strong>. \nߝߊߙߊ߲ߝߊ߯ߛߌ ߘߌ߫ ߛߋ߫ ߛߐ߬ߘߐ߲߬ ߠߊ߫ ߦߊ߲߬ [{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGENAMEE}}}} ߘߎ߲ߛߓߍ ߖߏ߰ߛߌ߬ߟߌ]",
+       "rev-deleted-text-unhide": "ߞߐߜߍ ߣߌ߲߬ ߟߢߊ߬ߟߌ ߓߘߊ߫ ߓߊ߲߫ <strong>ߖߏ߰ߛߌ߬ ߟߊ߫</strong>. \nߝߊߙߊ߲ߝߊ߯ߛߌ ߘߌ߫ ߛߋ߫ ߛߐ߬ߘߐ߲߬ ߠߊ߫ ߦߊ߲߬ [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} ߖߏ߰ߛߌ߬ߟߌ]. \nߌ ߘߌ߫ ߛߋ߫ [$1 ߟߢߊ߬ߟߌ ߣߌ߲߬ ߦߋ߫ ߟߊ߫] ߣߴߌ ߦߴߊ߬ ߝߍ߬ ߞߵߊ߬ ߣߐ߬ߝߍ߬ߜߍ߲߫.",
+       "rev-suppressed-text-unhide": "ߞߐߜߍ ߣߌ߲߬ ߟߢߊ߬ߟߌ ߓߘߊ߫ ߓߊ߲߫ <strong>ߖߏ߰ߛߌ߬ ߟߊ߫</strong>. \nߝߊߙߊ߲ߝߊ߯ߛߌ ߘߌ߫ ߛߋ߫ ߛߐ߬ߘߐ߲߬ ߠߊ߫ ߦߊ߲߬ [{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGENAMEE}}}} ߖߏ߰ߛߌ߬ߟߌ]. \nߌ ߘߌ߫ ߛߋ߫ [$1 ߟߢߊ߬ߟߌ ߣߌ߲߬ ߦߋ߫ ߟߊ߫] ߣߴߌ ߦߴߊ߬ ߝߍ߬ ߞߵߊ߬ ߣߐ߬ߝߍ߬ߜߍ߲߫.",
+       "rev-deleted-text-view": "ߞߐߜߍ ߣߌ߲߬ ߟߢߊ߬ߟߌ ߓߘߊ߫ ߓߊ߲߫ <strong>ߖߏ߰ߛߌ߬ ߟߊ߫</strong>. \nߝߊߙߊ߲ߝߊ߯ߛߌ ߘߌ߫ ߛߋ߫ ߛߐ߬ߘߐ߲߬ ߠߊ߫ ߦߊ߲߬ [{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGENAMEE}}}}  ߖߏ߰ߛߌ߬ߟߌ]",
+       "rev-suppressed-text-view": "ߞߐߜߍ ߣߌ߲߬ ߟߢߊ߬ߟߌ ߓߘߊ߫ ߓߊ߲߫ <strong>ߖߏ߰ߛߌ߬ ߟߊ߫</strong>. \nߝߊߙߊ߲ߝߊ߯ߛߌ ߘߌ߫ ߛߋ߫ ߛߐ߬ߘߐ߲߬ ߠߊ߫ ߦߊ߲߬ [{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGENAMEE}}}} ߘߎ߲ߛߓߍ ߖߏ߰ߛߌ߬ߟߌ]",
        "rev-delundel": "ߊ߬ ߦߋߢߊ ߡߊߦߟߍ߬ߡߊ߲߫",
        "rev-showdeleted": "ߦߌ߬ߘߊ߬ߟߌ",
        "revisiondelete": "ߛߌ߰ߘߊ ߖߏ߬ߛߌ߬/ߖߏ߬ߛߌ߬ߣߍ߲ ߓߐ߫",
+       "revdelete-nooldid-title": "ߞߏ߲߭ ߟߢߊ߬ߟߌ ߓߍ߲߬ߓߊߟߌ",
        "revdelete-show-file-submit": "ߐ߲߬ߐ߲߬ߐ߲߫",
        "revdelete-legend": "ߦߋߟߌ ߟߊ߬ߘߐ߰ߦߊ߬ߟߌ ߟߊߘߏ߲߬",
        "revdelete-hide-text": "ߛߓߍߟߌ ߟߊߢߊ߬",
        "group-bot-member": "{{GENDER:$1|ߓߏߕ}}",
        "group-sysop-member": "{{GENDER:$1|ߟߊ߬ߓߊ߰ߙߊ߬ߟߊ}}",
        "group-bureaucrat-member": "{{GENDER:$1|ߛߓߍߘߟߊߡߐ߮}}",
+       "group-suppress-member": "{{GENDER:$1|ߖߏ߰ߛߟߌ߬ ߣߐ}}",
        "grouppage-user": "{{ns:project}}: ߟߊ߬ߓߊ߰ߙߊ߬ߟߊ",
+       "grouppage-autoconfirmed": "{{ns:project}}: ߟߊ߬ߓߊ߰ߙߊ߬ߟߊ߫ ߞߍߒߖߘߍߦߋ߫ ߟߊߛߙߋߦߊߣߍ߲",
        "grouppage-bot": "{{ns:project}}:ߓߏߕ",
        "grouppage-sysop": "{{ns:project}}:ߡߊ߬ߡߙߊ߬ߟߌ߬ߟߊ",
+       "grouppage-bureaucrat": "{{ns:project}}:ߛߓߍߘߟߊߡߐ߮ ߟߎ߬",
+       "grouppage-suppress": "{{ns:project}}:ߖߏ߰ߛߌ߬ߟߌ",
        "right-read": "ߞߐߜߍ ߘߐߞߊ߬ߙߊ߲߬",
        "right-edit": "ߞߐߜߍ ߡߊߦߟߍ߬ߡߊ߲߫",
        "right-createpage": "ߞߐߜߍ ߘߏ߫ ߛߌ߲ߘߌ߫ (ߡߍ߲ ߕߍ߫ ߓߊ߬ߘߏ߬ߓߊ߬ߘߌ߬ߦߊ߬ ߞߐߜߍ ߝߋ߲߫ ߘߌ߫)",
        "right-createtalk": "ߓߊ߬ߘߏ߬ߓߊ߬ߘߌ߬ߦߊ߬ ߞߐߜߍ ߛߌ߲ߘߌ߫",
        "right-createaccount": "ߖߊ߬ߕߋ߬ߘߊ߬ ߟߊߓߊ߯ߙߕߊ߫ ߞߎߘߊ߫ ߛߌ߲ߘߌ߫",
+       "right-autocreateaccount": "ߞߍߒߖߘߍߦߋ߫ ߜߊ߲ߞߎ߲ߠߌ߲ ߞߐߞߊ߲ߠߊ ߖߊ߬ߕߋ߬ߘߊ߬ ߟߊߓߊ߯ߙߕߊ ߟߊ߫",
        "right-minoredit": "ߡߊ߬ߦߟߍ߬ߡߊ߲߬ߠߌ߲ ߣߐ߬ߣߐ߬ ߡߌ߬ߛߍ߬ߡߊ߲ ߘߌ߫",
        "right-move": "ߞߐߜߍ ߟߎ߬ ߛߋ߲߬ߓߐ߫",
        "right-move-subpages": "ߞߐߜߍ ߛߋ߲߬ߓߐ߫ ߊ߬ߟߎ߬ ߟߊ߫ ߞߐߜߍߙߋ߲ ߠߎ߬ ߘߐ߫",
        "right-userrights-interwiki": "ߥߞߌ ߘߏ ߟߎ߬ ߟߊ߬ߓߊ߰ߙߊ߬ߟߊ ߟߎ߬ ߟߊ߬ߓߊ߰ߙߊ߬ߟߌ߬ ߤߊߞߍ ߡߊߦߟߍ߬ߡߊ߲߫",
        "right-siteadmin": "ߓߟߏߡߟߊ ߝߊ߲ ߣߍ߰ ߊ߬ ߣߌ߫ ߞߵߊ߬ ߟߊߞߊ߬",
        "right-sendemail": "ߢߎߡߍߙߋ߲ ߗߋ߫ ߟߊ߬ߓߊ߰ߙߊ߬ߟߊ ߘߏ ߟߎ߬ ߡߊ߬",
+       "grant-generic": "\"$1\" ߞߌߣߌ߲߫ ߝߍ߫ ߝߎߝߎ",
        "grant-group-email": "ߢߎߡߍߙߋ߲ ߗߋ߫",
        "grant-createaccount": "ߖߊ߬ߕߋ߬ߘߊ ߘߏ߫ ߛߌ߲ߘߌ߫",
        "grant-createeditmovepage": "ߞߐߜߍ ߛߌ߲ߘߌ߫߸ ߡߊߦߟߍ߬ߡߊ߲߫߸ ߊ߬ ߣߌ߫ ߞߵߊ߬ ߛߋ߲߬ߓߐ߫",
        "backend-fail-read": "ߞߐߕߐ߮ ߕߴߛߋ߫ ߘߐߞߊ߬ߙߊ߲߬ ߠߊ߫   \"$1\".",
        "backend-fail-create": "ߊ߬ ߕߍ߫ ߣߊ߬ ߛߐ߲߬ ߠߊ߫ ߞߐߕߐ߮  \"$1\" ߛߓߍ߫ ߟߊ߫.",
        "backend-fail-maxsize": "ߊ߫ ߕߍ߫ ߣߊ߬ ߞߐߕߐ߮  \"$1\" ߛߓߍ߫ ߟߊ߫߸ ߓߊߏ߬ ߊ߬ ߓߏ߲߬ߓߊ߫ ߞߊ߬ ߕߊ߬ߡߌ߲߬ {{PLURAL:$2|ߝߙߐ߬ߢߐ߬ ߞߋߟߋ߲߫|ߝߙߐ߬ߢߐ ߟߎ߬ $2}}.",
+       "uploadstash-errclear": "ߞߐߕߐ߯ ߗߌߙߏ߲ߣߍ߲ ߖߏ߰ߛߌ߬ߟߌ ߦߴߌ ߘߐ߫.",
+       "uploadstash-bad-path-unknown-type": "ߛߎ߯ߦߊ߫  \"$1\" ߡߊߟߐ߲ߓߊߟߌ",
+       "uploadstash-no-extension": "ߘߐ߬ߥߙߊ߬ߟߌ ߦߋ߫ ߝߏߦߊ߲ ߠߋ߬ ߘߌ߫.",
+       "uploadstash-zero-length": "ߞߐߕߐ߮ ߦߋ߫ ߥߊ߲߬ߥߊ߲߬ ߘߐߞߏߟߏ߲ ߠߋ߬ ߘߌ߫.",
        "img-auth-nofile": "ߞߐߕߐ߮  \"$1\" ߕߍ߫ ߦߋ߲߬.",
        "http-request-error": "HTTP ߡߊ߬ߢߌ߬ߣߌ߲߬ߠߌ߲ ߓߘߊ߫ ߗߌߙߏ߲߫ ߝߎ߬ߕߎ߲߬ߕߌ߬ ߡߊߟߐ߲ߓߊߟߌ ߘߏ߫ ߞߏߛߐ߲߬.",
        "http-read-error": "HTTP ߘߐ߬ߞߊ߬ߙߊ߲߬ߠߌ߲ ߝߎ߬ߕߎ߲߬ߕߌ.",
        "filepage-nofile": "ߕߐ߮ ߣߌ߲߬ ߞߐߕߐ߯ ߛߎ߯ ߕߍ߫ ߦߋ߲߬",
        "shared-repo-from": "ߞߊ߬ ߝߘߊ߫: $1",
        "upload-disallowed-here": "ߌ ߕߍߣߊ߬ ߞߐߜߍ ߣߌ߲߬ ߞߊ߲߬ߛߓߍ߫ ߟߊ߫.",
+       "filerevert-comment": "ߊ߬ ߛߊߓߎ:",
        "filedelete": "ߖߏ߰ߛߌ߬ߟߌ $1",
        "filedelete-legend": "ߞߐߕߐ߮ ߖߏ߰ߛߌ߬",
+       "filedelete-comment": "ߊ߬ ߛߊߓߎ:",
+       "filedelete-submit": "ߊ߬ ߖߏ߬ߛߌ߬",
+       "filedelete-success": "<strong>$1</strong> ߓߘߊ߫ ߓߊ߲߫ ߖߏ߰ߛߌ߬ ߟߊ߫.",
+       "filedelete-nofile": "<strong>$1</strong> ߕߴߦߋ߲߬ ߏ߬ ߞߐ߫.",
+       "filedelete-otherreason": "ߞߎ߲߬ ߡߊߞߊ߬ߝߏ߬ߕߊ߬/ߜߘߍ:",
+       "filedelete-reason-otherlist": "ߞߎ߲߬ ߜߘߍ ߟߎ߬",
+       "filedelete-reason-dropdown": "* ߖߏ߰ߛߌ߬ߟߌ ߟߎ߬ ߝߊ߲߬ߓߊ ߞߎ߲߭\n** ߓߊߦߟߍߡߊ߲ ߤߊߞߍ ߕߌߢߍߟߌ\n** ߞߐߕߐ߯ ߓߊߟߌߣߍ߲ ߠߎ߬",
+       "filedelete-edit-reasonlist": "ߖߏ߰ߛߌ߬ߟߌ ߞߎ߲߭ ߡߊߦߟߍ߬ߡߊ߲߫",
+       "filedelete-maintenance-title": "ߞߐߕߐ߮ ߕߍ߫ ߛߐ߲߬ ߖߏ߰ߛߌ߬ ߟߊ߫",
        "unusedtemplateswlh": "ߛߘߌ߬ߜߋ߲ ߜߘߍ ߟߎ߬",
        "randompage": "ߞߎ߲߬ߝߍ߬ ߞߐߜߍ",
        "randomincategory": "ߓߍ߲߬ߛߋ߲߬ߡߊ߬ ߞߐߜߍ ߦߌߟߡߊ ߘߐ߫",
        "statistics-pages": "ߞߐߜߍ ߟߎ߬",
        "statistics-pages-desc": "ߞߐߜߍ ߡߍ߲ ߓߍ߯ ߦߋ߫ ߥߞߌ ߞߊ߲߬߸ ߦߏ߫ ߞߎߡߊߢߐ߲߯ߦߊ߫ ߞߐߜߍ߸ ߟߊ߬ߞߎ߲߬ߛߌ߲߬ߠߌ߲߸ ߊ߬ ߣߌ߫.",
        "statistics-files": "ߞߐߕߐ߮ ߟߊߦߟߍ߬ߣߍ߲ ߠߎ߬",
+       "pageswithprop-submit": "ߕߊ߯",
        "double-redirect-fixer": "ߟߊ߬ߞߎ߲߬ߛߌ߲߬ߠߌ߲ ߘߐߓߍ߲߬ߟߊ߲",
+       "brokenredirects-edit": "ߊ߬ ߡߊߦߟߍ߬ߡߊ߲߬",
+       "brokenredirects-delete": "ߊ߬ ߖߏ߬ߛߌ߬",
+       "withoutinterwiki": "ߞߊ߲ ߛߘߌ߬ߜߋ߲ ߦߋ߫ ߞߐߜߍ ߡߍ߲ ߠߎ߬ ߟߊ߫",
+       "withoutinterwiki-submit": "ߊ߬ ߦߌ߬ߘߊ߬",
        "nbytes": "$1 {{PLURAL:$1|ߝߌ߬ߘߊ|ߝߌ߬ߘߊ߲ ߠߎ߬}}",
+       "ncategories": "$1 {{PLURAL:$1|ߦߌߟߡߊ|ߦߌߟߡߊ ߟߎ߬}}",
+       "ninterwikis": "$1 {{PLURAL:$1|ߥߞߌߕߍ|ߥߞߌߕߍ ߟߎ߬}}",
+       "nlinks": "$1 {{PLURAL:$1|ߛߘߌ߬ߜߋ߲|ߛߘߌ߬ߜߋ߲ ߠߎ߬}}",
        "nmembers": "$1 {{PLURAL:$1|ߛߌ߲߬ߝߏ߲ |ߛߌ߲߬ߝߏ߲ ߠߎ߬}}",
+       "nmemberschanged": "$1 → $2 {{PLURAL:$2|ߛߌ߲߬ߝߏ߲|ߛߌ߲߬ߝߏ߲ ߠߎ߬}}",
+       "nrevisions": "$1 {{PLURAL:$1|ߟߢߊ߬ߟߌ|ߟߢߊ߬ߟߌ ߟߎ߬}}",
+       "nimagelinks": "ߓߘߊ߫ ߟߊߓߊ߯ߙߊ߫ {{PLURAL:$1|ߞߐߜߍ|ߞߐߜߍ ߟߎ߬}} $1 ߘߐ߫",
+       "ntransclusions": "ߓߘߊ߫ ߟߊߓߊ߯ߙߊ߫ {{PLURAL:$1|ߞߐߜߍ|ߞߐߜߍ ߟߎ߬}} $1 ߘߐ߫",
+       "specialpage-empty": "ߞߐߝߟߌ߫ ߛߌ߫ ߕߍ߫ ߢߊߝߐߟߌ ߣߌ߲߬ ߞߊ߲߬.",
+       "lonelypages": "ߞߐߜߍ߫ ߝߊߙߌߕߊ ߟߎ߬",
+       "uncategorizedpages": "ߞߐߜߍ߫ ߦߌߟߡߊߦߊߓߊߟߌ ߟߎ߬",
+       "uncategorizedcategories": "ߦߌߟߡߊ߫ ߦߌߟߡߊߦߊߓߊߟߌ ߟߎ߬",
+       "uncategorizedimages": "ߞߐߕߐ߯ ߦߌߟߡߊߦߊߓߊߟߌ ߟߎ߬",
+       "uncategorizedtemplates": "ߞߙߊ߬ߞߏ߬ ߦߌߟߡߊߦߊߓߊߟߌ ߟߎ߬",
+       "uncategorized-categories-exceptionlist": " # Contains a list of categories, which shouldn't be mentioned on Special:UncategorizedCategories. One per line, starting with \"*\". Lines starting with another character (including whitespaces) are ignored. Use \"#\" for comments.",
+       "unusedcategories": "ߦߌߟߡߊ߫ ߟߊߓߊ߯ߙߊߓߊߟߌ ߟߎ߬",
+       "unusedimages": "ߞߐߕߐ߯ ߟߊߓߊ߯ߙߊߓߊߟߌ",
+       "wantedcategories": "ߦߌߟߡߊ߫ ߞߊ߬ߣߌ߲߬ߣߍ߲ ߠߎ߬",
+       "wantedpages": "ߞߐߜߍ߫ ߜߋ߬ߟߎ߲߬ߣߍ߲ ߠߎ߬",
+       "mostinterwikis": "ߞߐߜߍ ߡߍ߲ ߠߎ߬ ߦߋ߫ ߥߞߌ ߣߌ߫ ߢߐ߲ߕߍ ߝߊ߲߬ߓߊ ߘߐ߫",
        "prefixindex": "ߞߐߜߍ ߡߍ߲ ߠߎ߬ ߓߍ߯ ߟߊߝߟߐߣߍ߲߫",
+       "prefixindex-submit": "ߊ߬ ߦߌ߬ߘߊ߬",
+       "shortpages": "ߞߐߜߍ߫ ߛߎߘߎ߲ ߠߎ߬",
+       "longpages": "ߞߐߜߍ߫ ߖߊ߲ ߠߎ߬",
+       "deadendpagestext": "ߓߌ߬ߟߊ߬ߢߐ߲߰ߡߊ߬ ߕߍ߫ ߞߐߜߍ ߢߌ߲߬ ߠߎ߬ ߣߌ߫ ߞߐߜߍ ߕߐ߭ ߟߎ߬ ߕߍ߫ {{SITENAME}} ߘߐ߫.",
+       "protectedpages": "ߞߐߜߍ߫ ߟߊߞߊ߲ߘߊߣߍ߲ ߠߎ߬",
+       "protectedpages-filters": "ߛߍ߲ߛߍ߲ߟߊ߲ ߠߎ߬:",
+       "protectedpages-page": "ߞߐߜߍ",
+       "protectedpages-performer": "ߟߊ߬ߓߊ߰ߙߊ߬ߟߊ߫ ߟߊߞߊ߲ߘߊߣߍ߲",
+       "protectedpages-params": "ߟߊ߬ߓߍ߲߬ߢߐ߲߰ߡߊ ߟߊ߬ߞߊ߲߬ߘߊ߬ߟߌ",
+       "protectedpages-reason": "ߊ߬ ߛߊߓߎ",
+       "protectedpages-submit": "ߞߐߜߍ ߟߎ߫ ߦߌ߬ߘߊ߬ߟߌ",
+       "protectedpages-unknown-timestamp": "ߡߊߟߐ߲ߓߊߟߌ",
+       "protectedpages-unknown-performer": "ߟߊ߬ߓߊ߰ߙߊ߬ߟߊ߫ ߡߊߟߐ߲ߓߊߟߌ",
+       "protectedtitles": "ߞߎ߲߬ߕߐ߰ ߟߊߞߊ߲ߘߊߣߍ߲ ߠߎ߬",
+       "protectedtitles-submit": "ߞߎ߲߬ߕߐ߮ ߦߌ߬ߘߊ߬ߟߌ",
        "listusers": "ߟߊ߬ߓߊ߰ߙߊ߬ߟߊ ߛߙߍߘߍ",
+       "listusers-creationsort": "ߊ߬ ߦߋ߫ ߛߌ߲ߘߟߌ ߕߎ߬ߡߊ߬ߘߊ ߡߊ߬",
+       "usereditcount": "$1 {{PLURAL:$1|ߡߊ߬ߦߟߍ߬ߡߊ߲߬ߠߌ߲|ߡߊ߬ߦߟߍ߬ߡߊ߲߬ߠߌ߲ ߠߎ߬}}",
+       "usercreated": "{{GENDER:$3|ߛߌ߲ߘߟߌߣߐ ߟߋ߬}} $2 $1 ߡߊ߬",
        "newpages": "ߞߐߜߍ߫ ߞߎߘߊ ߟߎ߬",
+       "newpages-submit": "ߊ߬ ߦߌ߬ߘߊ߬",
+       "newpages-username": "ߟߊ߬ߓߊ߰ߙߊ߬ߟߊ ߕߐ߮:",
+       "ancientpages": "ߞߐߜߍ ߞߘߐ߬ߡߊ߲ ߠߎ߬",
        "move": "ߊ߬ ߛߋ߲߬ߓߐ߫",
+       "movethispage": "ߘߐߜߍ ߣߌ߲߬ ߛߋ߲߬ߓߐ߫",
+       "notargettitle": "ߞߏ߲߰ ߕߴߦߋ߲߬",
+       "nopagetitle": "ߞߏ߲߰ ߞߐߜߍ߫ ߛߎ߮ ߏ߬ ߕߴߦߋ߲߬",
+       "nopagetext": "ߌ ߣߊ߬ ߞߏ߲߰ ߞߐߜߍ ߡߍ߲ ߡߊߕߍ߰ ߟߊ߫ ߣߌ߲߬߸ ߊ߬ ߕߴߦߋ߲߬.",
        "pager-newer-n": "{{PLURAL:$1|ߞߎߘߡߊ1|ߞߎߘߡߊ$1}}",
        "pager-older-n": "{{PLURAL:$1|ߞߘߐ߬ߡߊ߲ ߁|ߞߘߐ߬ߡߊ߲ ߠߎ߬ $1}}",
+       "apisandbox-submit": "ߡߊ߬ߢߌ߬ߣߌ߲߬ߞߊ߬ߟߌ ߘߏ߫ ߞߍ߫",
+       "apisandbox-reset": "ߊ߬ ߖߏ߰ߛߌ߬",
+       "apisandbox-retry": "ߊ߬ ߡߊߝߍߣߍ߲߫ ߕߎ߲߯",
+       "apisandbox-helpurls": "ߘߍ߬ߡߍ߲߬ߠߌ߲ ߛߘߌ߬ߜߋ߲ ߠߎ߬",
+       "apisandbox-examples": "ߟߊߒߡߊ߫ ߘߐ߫",
+       "apisandbox-dynamic-parameters": "ߟߊ߬ߓߍ߲߬ߢߐ߲߰ߡߊ ߡߞߊ߬ߝߏ߬ߟߌ߬ ߜߘߍ߫",
+       "apisandbox-dynamic-parameters-add-label": "ߟߊ߬ߓߍ߲߬ߢߐ߲߰ߡߊ ߟߊߘߏ߲߬",
+       "apisandbox-dynamic-parameters-add-placeholder": "ߟߊ߬ߓߍ߲߬ߢߐ߲߰ߡߊ ߕߐ߮",
+       "apisandbox-dynamic-error-exists": "ߟߊ߬ߓߍ߲߬ߢߐ߲߰ߡߊ ߕߐ߮  \"$1\" ߦߋ߫ ߦߋ߲߬ ߞߘߐ߬ߡߊ߲߬.",
+       "apisandbox-add-multi": "ߟߊ߬ߘߏ߲߬ߠߌ߲",
+       "apisandbox-results": "ߞߐߖߋߓߌ ߟߎ߬",
+       "apisandbox-sending-request": "API ߡߊ߬ߢߌ߬ߣߌ߲߬ߞߊ߬ߟߌ ߗߋߟߌ ߦߴߌ ߘߐ߫...",
+       "apisandbox-loading-results": "API ߞߐߖߋߓߌ ߟߊߛߐ߬ߘߐ߲ ߦߵߌ ߘߐ߫...",
+       "apisandbox-results-error": "ߝߎ߬ߕߎ߲߬ߕߌ ߘߏ߫ ߓߘߊ߫ ߓߌ߬ߟߵߊ߬ ߘߐ߫ API ߡߊ߬ߢߌ߬ߣߌ߲߬ߞߊ߬ߟߌ ߞߐߖߋߓߌ ߟߊ߬ߢߎ߲߬ߠߌ߲ ߦߴߌ ߘߐ߫: $1",
+       "apisandbox-request-selectformat-label": "ߓߟߏߡߟߊ ߡߊ߬ߢߌ߬ߣߌ߲߬ߞߊ߬ߟߌ ߦߌ߬ߘߊ߬ ߦߏ߫:",
+       "apisandbox-request-url-label": "URL ߡߊ߬ߢߌ߬ߣߌ߲߬ߞߊ߬ߟߌ:",
+       "apisandbox-request-json-label": "JSON ߡߊ߬ߢߌ߬ߣߌ߲߬ߞߊ߬ߟߌ:",
+       "apisandbox-request-time": "ߡߊ߬ߢߌ߬ߣߌ߲߬ߞߊ߬ߟߌ ߕߎ߬ߡߊ: {{PLURAL:$1|$1 ms}}",
        "booksources": "ߞߊ߬ߝߊ ߛߎ߲",
        "booksources-search-legend": "ߞߊ߬ߝߊ ߛߎ߲ ߕߌߙߌ߲߫",
        "booksources-search": "ߢߌߣߌ߲ߠߌ߲",
        "all-logs-page": "ߝߘߏ߬ߓߊ߬ ߜߊ߲ߞߎ߲ߠߌ߲ ߠߎ߬ ߓߍ߯",
        "alllogstext": "ߓߟߏߞߘߐ߫ ߘߐߛߙߋ ߡߎ߰ߡߍ ߦߌ߬ߘߊ߬ߟߌ ߣߌ߲߬ ߞߣߐ߫ {{SITENAME}}.\nߌ ߘߌ߫ ߛߋ߫ ߛߙߍߘߍ ߘߊ߲߬ߠߊߕߍ߰ ߟߊ߫ ߓߘߍߞߍ߭ ߞߊ߬ ߢߊ߬߸ ߏ߬ ߛߋ߲߬ߝߍ߬ ߞߊ߬ ߘߐ߬ߛߙߋ ߛߎ߯ߦߊ ߡߊߡߌ߬ߘߊ߬߸ ߊ߬ ߣߌ߫ ߟߊߓߊ߯ߙߟߊ ߕߐ߮ (ߛߏ߬ߓߌ߬ߟߊ߲߬ߘߌ ߟߋ߬ ߛߓߍߘߋ߲ ߗߏ߯ߦߊ ߝߍ߬)߸ ߥߟߴߊ߬ ߥߟߏߣߍ߲߫ ߞߐߜߍ ߡߍ߲ ߞߊ߲߬ (ߛߏ߬ߓߌ߬ߟߊ߲߬ߘߌ ߟߋ߬ ߝߣߊ߫ ߛߓߍߘߋ߲ ߠߎ߬ ߗߏ߯ߦߊ ߝߍ߬).",
        "logempty": "ߞߍߞߏ ߛߌ߫ ߣߌ߫ ߘߐ߬ߛߙߋ ߡߊ ߓߍ߲߬ ߢߐ߲߮ ߡߊ߬.",
+       "checkbox-all": "ߊ߬ ߓߍ߯",
+       "checkbox-none": "ߝߏߦߌ߬",
        "allpages": "ߞߐߜߍ ߟߎ߬ ߓߍ߯",
+       "nextpage": "ߞߐߜߍ ߟߊ߬ߕߎ߲߰ߠߊ ($1)",
+       "prevpage": "ߞߐߜߍ ߟߊ߬ߕߎ߲߰ߠߊ ($1)",
        "allarticles": "ߞߐߜߍ ߟߎ߬ ߓߍ߯",
        "allpagessubmit": "ߥߊ߫",
        "allpages-hide-redirects": "ߟߊ߬ߞߎ߲߬ߛߌ߲߬ߠߌ߲ ߢߡߊߘߏ߲߰",
        "categories": "ߦߌߟߡߊ ߟߎ߬",
+       "linksearch": "ߞߐߞߊ߲ߠߊ ߛߘߌ߬ߜߋ߲ ߢߌߣߌ߲ߠߌ߲",
        "listgrouprights-members": "(ߛߌ߲߬ߝߏ߲ ߠߎ߫ ߛߙߍߘߍ)",
        "emailuser": "ߗߋߛߓߍ ߗߋ߫ ߣߌ߲߬ ߕߌ߭ ߡߊ߬",
        "usermessage-editor": "ߞߊ߲ߞߋ߫ ߗߋߛߓߍ ߡߊߦߟߍ߬ߡߊ߲߬ߓߊ߮",
index 8a3686a..0a12e70 100644 (file)
        "redirectedfrom": "(Érdirection édpis $1)",
        "redirectpagesub": "Pache érdérivée",
        "redirectto": "Ardiriger vers :",
-       "lastmodifiedat": "L'pache-lo ale o té modifiée l'fouos darin l' $1, à $2.",
+       "lastmodifiedat": "L'pache-lo al o tè modifiée l'fouos darin l' $1, à $2.",
        "viewcount": "L' page-lo ale o té vue {{PLURAL:$1|1 foués|$1 foués}}.",
        "protectedpage": "Pache défènnée",
        "jumpto": "Aler à:",
        "ns-specialprotected": "Ches paches éspéchiales, is n'peute poin éte éditées.",
        "virus-unknownscanner": "intivirus poin connu:",
        "yourname": "nom d'uzeu:",
+       "userlogin-yourname": "nom d'uzeu",
+       "userlogin-yourname-ph": "Intrez vote nom d’uzeu",
        "yourpassword": "Mot d'passe:",
+       "userlogin-yourpassword": "Mot d'passe:",
+       "userlogin-yourpassword-ph": "Intrez vote mot d' passe",
+       "createacct-yourpassword-ph": "Intrez un mot d' passe",
        "yourpasswordagain": "Intrer à nouvieu ch'mot d'passe:",
+       "createacct-yourpasswordagain": "Confirmez ch' mot d' passe",
+       "createacct-yourpasswordagain-ph": "Intrez à nouviau ch' mot d' passe",
+       "userlogin-remembermypassword": "Warder em session active",
        "yourdomainname": "Vote donmène:",
        "login": "Intrer",
        "nav-login-createaccount": "Intrer / créer vote conpte",
        "accountcreated": "Ch'conpte est créé",
        "accountcreatedtext": "Ech conpte d'uzeu pou $1 o té créé.",
        "loginlanguagelabel": "Langache: $1",
+       "pt-login": "Intrer",
+       "pt-login-button": "Intrer",
+       "pt-createaccount": "Créer un compte",
+       "pt-userlogout": "Sortir",
        "changepassword": "Canger ch'mot d'passe",
        "resetpass_header": "Canger ch'mot d'passe dech conpte",
        "oldpassword": "Anthiu mot d'passe:",
        "preview": "Prévir",
        "showpreview": "Fouaire vir l'prévue",
        "showdiff": "Montrer chés cangemints",
-       "anoneditwarning": "'''Wàrte ! :''' Vos n'ètes poin lodjé.\n\nVote adrèche IP, ale sro inrégistrée din l'historique éd chol pache.",
+       "anoneditwarning": "'''Wàrte ! :''' Vos n'ètes poin lodjé.\n\nVote adrèche IP, ale sro inrégistrée din l'historike éd chole pache. Si os <strong>[$1 vos connectez]</strong> o <strong>[$2 créez un compte]</strong>, vos modificacions s'ront attribuées à vote prope nom d’uzeu(utilisatrice) pi os érez d’eutes avantages.",
        "summary-preview": "Prévue dech résumè :",
+       "loginreqlink": "Intrer",
        "newarticle": "(nouvieu)",
        "newarticletext": "Os avez sui un loïen vers eune pache qui n’essiste poin coère ou qu' o té [{{fullurl:Special:Log|type=delete&page={{FULLPAGENAMEE}}}} défacée].\nPou créer chol pache, intrez vote teske din l'boéte édsou (vir [$1 l'pache d’aïude] ). <br />\nSi vos ètes ichi par bérlure, bukez su l'bouton '''értour''' du navigateu.",
        "noarticletext": "Achteure i n’y o nu teske su l'pache-lo.\nOs povez [[Special:Search/{{PAGENAME}}|foaire eune érchérche du tite del pache]] din chés eutes paches,\n<span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} érchércher din chés érliées opéracions]\nou [{{fullurl:{{FULLPAGENAME}}|action=edit}} créer chol pache]</span>.",
        "noarticletext-nopermission": "Achteure i n’y o autchun teske dseur l'pache-lo.\nOs povez [[Special:Search/{{PAGENAME}}|foaire eune érchérche du tite del pache]] din chés eutes paches,\no bin <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} érchércher din chés érliées gazètes]</span>\nmais vos n'avez poin l'droué d'créer chol pache.",
        "previewnote": "'''Afute! ch'teske-lo ch'est seulemint eune prévue.'''\n\nVos cangemints, is sont poin coèr inrégistrés!",
        "editing": "Éditer $1",
+       "creating": "Créachon éd $1",
        "editingsection": "$1 éditée (sekchon)",
        "yourtext": "Vote teske",
        "copyrightwarning": "Toutes chés contérbuchons su {{SITENAME}} ont érbéyées conme publiées dsou chés térmes del $2 (vir $1 pou pus d'détals). Si vos n'volez poin éq vos écrivures euchette canjés pi départis à volontè, mérci éd n'poin les soumétte ichi.<br />\nOs prométtez auchi éq vos avez écrit ch'teske vous-méme, ou éq vos l’avez ércopié d’eune source din ch'donmène public, ou d’eune libe érsource.<br /> '''N’IMPLOÉYEZ POIN D'TRAVAUX ÉDSOU DROÉ D’AUTEU SINS ACOR ÉSPRÉSSE !'''",
        "hiddencategories": "{{PLURAL:$1|Catégorie muchée|Catégories muchées}} pou chol pache:",
        "permissionserrorstext-withaction": "Vos n’avez poin l'pérmichon éd $2, pou {{PLURAL:$1|ch'motif suivant|chés motifs suivants}}:",
        "recreate-moveddeleted-warn": "'''Afute ! : Os ètes in route à ércréer eune pache qu'o té abolie édvant.'''\n\nControler qu'ch'est pértinint d' porsuire chés modificacions édseur chol pache. L'jornal des défacions pi des déplachemints l'est affiké chi-édsous :",
-       "moveddeleted-notice": "Chol pache ale o té abolie. L'jornal des défacions pi des déplachemints il est affiké chi-édsous pour référinche.",
+       "moveddeleted-notice": "Chol pache ale o té abolie. \nL'jornal des défacions, des appouès pi des déplachemints pour l'pache il est affiké chi-édsous pour référinche.",
        "post-expand-template-inclusion-warning": "Affute : Chèle pache ale a trop d’modèles. Des inclusions n'sront poin foaites.",
        "post-expand-template-inclusion-category": "Paches aveuc granmint d'modèles",
        "post-expand-template-argument-warning": "Afute : Chol pache ale o au moins un paramète d'modèle dont l'inclusion est rindue impossibe. Apré éstinsion, chti-chi il éroait produit un résultat trop long, i n'a donc poin té inclus.",
        "viewpagelogs": "Vir chés gasètes del pache-lo",
        "currentrev-asof": "Coursaule vérchon in date du $1",
        "revisionasof": "Ércordé conme $1",
-       "revision-info": "Version du $1 pèr $2",
+       "revision-info": "Version du $1 pèr {{GENDER:$6|$2}}$7",
        "previousrevision": "← érvue dvant",
        "nextrevision": "Cangemint pu nouvieu →",
        "currentrevisionlink": "Érvision éd qhére",
        "pagehist": "Histoère del pache",
        "revertmerge": "N'poin mélinger",
        "history-title": "Historike des canjemints éd \"$1\"",
+       "difference-title": "$1 : Différinche intre vérsions",
        "lineno": "Line $1:",
        "compareselectedversions": "Compérer chés couésies contérbuchons",
        "editundo": "n'poin foaire",
+       "diff-multi-sameuser": "({{PLURAL:$1|Eune révision intarmédiaire pèr ch' meume uzeu poin affichée|$1 révisions intarmédiaires pèr ch' meume uzeu poin affichées}})",
        "searchresults": "Tracher chés résultats",
        "searchresults-title": "Tracher chés résultats pou \"$1\"",
        "textmatches": "Teske del pache déniché",
        "shown-title": "Montrer $1 résultat{{PLURAL:$1||s}} pèr pache",
        "viewprevnext": "Vir ($1 {{int:pipe-separator}} $2) ($3)",
        "searchmenu-exists": "'''Il y o eune pache lonmée « [[:$1]] » édseur ch'wiki'''",
-       "searchmenu-new": "'''Créer l'pache « [[:$1|$1]] » édseur ech wiki !'''",
+       "searchmenu-new": "<strong>Créer l'pache « [[:$1|$1]] » édseur ech wiki !</strong>  {{PLURAL:$2|0=Voyez égalemint l' pache treuvèe aveuc vote archerche.|Voyez égalemint chés résultats éd vote archerche.}}",
        "searchprofile-articles": "Paches d'étnu",
        "searchprofile-images": "Multimédia",
        "searchprofile-everything": "Tout",
        "searchprofile-advanced-tooltip": "Couésir chés éspaches d'noms pour l'értrache",
        "search-result-size": "$1 ({{PLURAL:$2|1 mot|$2 mots}})",
        "search-result-category-size": "$1 mimbe{{PLURAL:$1||s}} ($2 édsous-catégorie{{PLURAL:$2||s}}, $3 fichié{{PLURAL:$3||s}})",
-       "search-redirect": "(érdirection $1)",
+       "search-redirect": "(érdirekcion édpis $1)",
        "search-section": "(sekchon $1)",
        "search-suggest": "Cha vo ti dire: $1",
        "search-interwiki-caption": "Proujé analocq",
        "search-interwiki-more": "(pus)",
        "searchrelated": "relaté",
        "searchall": "tout",
+       "search-showingresults": "{{PLURAL:$4|Résultat <strong>$1</strong> parmi <strong>$3</strong>|Résultats <strong>$1 à $2</strong> parmi <strong>$3</strong>}}",
        "search-nonefound": "Y a autchun résultat pour chol dmanne.",
        "powersearch-legend": "Érvue avanchée",
        "powersearch-ns": "Tracher din chés éspaches éd chés noms:",
        "group-sysop-member": "{{GENDER:$1|aménistrateu|aménistratriche}}",
        "group-bureaucrat-member": "{{GENDER:$1|buroécrate}}",
        "grouppage-sysop": "{{ns:project}}:Aménistrateus",
+       "right-writeapi": "Uzer l'API d' modificacion du wiki",
        "newuserlogpage": "Jornal éd chés créachons d'comptes d'uzeu",
        "rightslog": "Jornal d'chés droés dechl uzeu",
        "action-read": "Vir l'pache-lo",
        "action-import": "téléquértcher chol pache à partir d’un eute wiki",
        "action-importupload": "téléquértcher chol pache à partir d'un fichié",
        "nchanges": "$1 {{PLURAL:$1|cange|canges}}",
+       "enhancedrc-history": "Histoère",
        "recentchanges": "Darins canjemints",
        "recentchanges-legend": "Opchons éd chés nouvieus canjemints",
+       "recentchanges-summary": "Tracher chés pus darins cangemints du wiki dins chole pache.",
        "recentchanges-feed-description": "Tracher chés pus darins cangemints du wiki din chol alimintachon.",
        "recentchanges-label-newpage": "Chol modificacion al o créé eune nouvèle pache",
        "recentchanges-label-minor": "C'est un tiot canjemint",
        "recentchanges-label-bot": "Chol modificacion ale o té foaite pèr un robot.",
        "recentchanges-label-unpatrolled": "Chol modificacion ale n’o poin coèr té controlée.",
        "recentchanges-label-plusminus": "Él taille deul pache al o cangé éd chol nombe d’octets.",
+       "recentchanges-legend-heading": "<strong>Léginde :</strong>",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (vir étou èl [[Special:NewPages|lisse des nouvèles paches]]).",
        "rcfilters-legend-heading": "<strong>Lisse des abréviacions :</strong>",
        "rcnotefrom": "Vlo chés modificacions foaites édpuis l' '''$2''' (dousqu'à '''$1''' au plus).",
        "rclistfrom": "Montrer chés nouvieus cangemints d'puis $3 $2",
        "rcshowhideminor": "$1 tiotes éditions",
+       "rcshowhideminor-show": "Montrer",
+       "rcshowhideminor-hide": "Mucher",
        "rcshowhidebots": "$1 bots",
-       "rcshowhideliu": "$1 lodjés uzeus",
+       "rcshowhidebots-show": "Montrer",
+       "rcshowhidebots-hide": "Mucher",
+       "rcshowhideliu": "$1 uzeus inrégistreus",
+       "rcshowhideliu-hide": "Mucher",
        "rcshowhideanons": "$1 uzeus anonimes",
+       "rcshowhideanons-show": "Montrer",
+       "rcshowhideanons-hide": "Mucher",
        "rcshowhidepatr": "$1 chés modificacions wardées",
        "rcshowhidemine": "$1 ems éditions",
+       "rcshowhidemine-show": "Montrer",
+       "rcshowhidemine-hide": "Mucher",
        "rclinks": "Afiqher chés $1 darins canjemints din chés $2 darins jours",
        "diff": "dif",
        "hist": "hist",
        "minoreditletter": "m",
        "newpageletter": "N",
        "boteditletter": "b",
+       "rc-change-size-new": "$1 {{PLURAL:$1|octet|octets}} apré canjemint",
        "rc-enhanced-expand": "Montrer chés détals (i feut avoér JavaScript)",
        "rc-enhanced-hide": "Mucher chés détals",
        "recentchangeslinked": "Darins canjemints érliés",
        "recentchangeslinked-toolbox": "Suivi des paches loïées",
        "recentchangeslinked-title": "Cangemints à pérpos éd \"$1\"",
-       "recentchangeslinked-summary": "Ch'est eune lisse d'chés darins canjemints su chés paches qu'ont un loïen aveuc l'pache-lo. Chés paches din vote [[Special:Watchlist|''lisse à suire'']] il sont in '''cros'''.",
+       "recentchangeslinked-summary": "Intrer un nom d' pache pour vir chés modificacions foaites récemmint édseur des paches loyées vers o édpuis chole pache (pour vir chés mimbes d’unne catégorie, intrez {{ns:category}}:Nom d' catégorie). Chés modificacions des paches éd [[Special:Watchlist|vote lisse éd suivi]] sont <strong>in gras</strong>.",
        "recentchangeslinked-page": "Nom del pache:",
        "recentchangeslinked-to": "Vir putot chés canjemints d'chés paches aveuc un loïen su l'pache-lo",
        "upload": "Quértcher chés fichiés",
        "filedesc": "Résumè",
        "license": "Licince",
        "license-header": "Licince",
+       "imgfile": "Fichié",
        "listfiles": "Lisse des fichiés",
        "file-anchor-link": "Fichié",
        "filehist": "Histoère dech fichié",
        "filehist-dimensions": "Diminsions",
        "filehist-comment": "Fichié éd chés conmints",
        "imagelinks": "Usage dech fichié",
-       "linkstoimage": "{{PLURAL:$1|L'pache d'apreu est liée|Chés $1 paches d'apreu sont liées}} à ch'fichié-lo :",
+       "linkstoimage": "{{PLURAL:$1|L'pache d'apreu est loyée|Chés $1 paches d'apreu sont loyées}} à ch'fichié-lo :",
        "nolinkstoimage": "Autchune pache n'est loïée aveuc ch'fichié-lo",
        "sharedupload": "Ch'fichié i vient éd $1. I put ète imploïé par d'eutes proujés.",
        "sharedupload-desc-there": "Ch'fichié i vient éd $1. I put ète uzé pèr d’eutes prodjés. Vir l'pache [$2 édseur Commons].",
        "uploadnewversion-linktext": "Quértcher eune novèle vérchion del pache-lo",
        "shared-repo-from": "à : $1",
        "shared-repo": "un dépôt partagé",
+       "upload-disallowed-here": "Os n' povez poin rimplacer chole fichier.",
        "mimesearch": "Tracher pèr type éd contenu MIME",
        "unwatchedpages": "Paches poin suivies",
        "listredirects": "Lisse des érdiréccions",
        "pager-older-n": "{{PLURAL:$1|pus viu 1|pus vius $1}}",
        "booksources": "Sources dech live",
        "booksources-search-legend": "Tracher chés référinches d'chés lives",
+       "booksources-search": "Tracher",
        "log": "Gasètes",
        "allpages": "Tertous chés paches",
        "prevpage": "Pache édvant ($1)",
        "deleteotherreason": "Motif eute/suplémintère :",
        "deletereasonotherlist": "Eute motif",
        "rollbacklink": "èrtour",
+       "rollbacklinkcount": "révoquer $1 {{PLURAL:$1|modificacion|modificacions}}",
        "rollbackfailed": "Értour loupé",
        "cantrollback": "éj peus mie invérser l'édition;\nch'darin contérbucheu, ch'est ch'seu auteur del pache-lo.",
        "alreadyrolled": "éj pus mie invérser el darin édition éd [[:$1]] par [[User:$2|$2]] ([[User talk:$2|Talk]]{{int:pipe-separator}}[[Special:Contributions/$2|{{int:contribslink}}]]);\nqueuque-un il o édité ou invérsé l'pache déjo.\n\nL' passèie édition del pache étoait par  [[User:$3|$3]] ([[User talk:$3|Talk]]{{int:pipe-separator}}[[Special:Contributions/$3|{{int:contribslink}}]]).",
        "undeleteviewlink": "Vir",
        "namespace": "Éspace du nom:",
        "invert": "Invérser el sélékchon",
+       "tooltip-invert": "Cochez chole case pour mucher chés modificacions des pages dins l'éspache de noms sélekcionné (et pi l'éspache de noms achuchonné si coché)",
+       "namespace_association": "Éspache d' noms achuchonné",
+       "tooltip-namespace_association": "Cochez chole case pour inclure égalemint chl’éspache d' noms éd discussion o du sujet, achuchonné à chl’éspache de noms sélekcionné",
        "blanknamespace": "(Moaite)",
-       "contributions": "Contérbuchons dechl uzeu",
+       "contributions": "Contérbuchons éd l’{{GENDER:$1|utilisateu|utilisatriche}}",
        "contributions-title": "Contérbuchons dechl uzeu à pérpos éd $1",
        "mycontris": "Mes contérbuchons",
+       "anoncontribs": "Contérbuchons",
        "contribsub2": "Pou $1 ($2)",
        "uctop": "darin",
        "month": "Dpuis ch'moés (pi édvant)",
        "whatlinkshere-prev": "{{PLURAL:$1|édvant|édvants $1}}",
        "whatlinkshere-next": "{{PLURAL:$1|d'apreu|d'apreu $1}}",
        "whatlinkshere-links": "← loïens",
-       "whatlinkshere-hideredirs": "$1 érdireccions",
-       "whatlinkshere-hidetrans": "transclusions éd $1",
-       "whatlinkshere-hidelinks": "$1 loïens",
+       "whatlinkshere-hideredirs": "$1 chés érdireccions",
+       "whatlinkshere-hidetrans": "$1 chés transclusions",
+       "whatlinkshere-hidelinks": "$1 chés loïens",
        "whatlinkshere-hideimages": "$1 chés loïés fichiés",
        "whatlinkshere-filters": "Filtes",
        "block": "Blotcher l'uzeu",
        "allmessagesdefault": "Messache pèr défeut",
        "thumbnail-more": "Pu grand",
        "thumbnail_error": "Bérlurage tandir l'créachon éd la miniature : $1",
-       "tooltip-pt-userpage": "Vote pache éd uzeu",
+       "tooltip-pt-userpage": "Vote pache {{GENDER:|éd uzeu|d’ utilisatriche}}",
        "tooltip-pt-mytalk": "Vote pache d'pérlache",
        "tooltip-pt-preferences": "Vos préférinches",
        "tooltip-pt-watchlist": "El lisse d'chés paches éq vos suivez chés canjemints",
        "tooltip-pt-mycontris": "Lisse éd vos contérbuchons",
        "tooltip-pt-login": "vos ètes incoradjé éd vos lodjé; portanne ch'est mie oblidjé",
        "tooltip-pt-logout": "Sortir",
+       "tooltip-pt-createaccount": "Os vos incourageons à créer un compte d' uzeu et pi à vos connecter; mais cha n’est poin obligatoère",
        "tooltip-ca-talk": "Distchussion à pérpos del pache-lo",
-       "tooltip-ca-edit": "Os pouvez éditer l'pache-lo.\nMérci d'imploéyer ch'bouton \"vir\" édvant éd \"warder\"",
+       "tooltip-ca-edit": "Os povez éditer l'pache-lo.\nMérci d'imploéyer ch'bouton \"vir\" édvant éd \"warder\"",
        "tooltip-ca-addsection": "Débuter eune novèle sekchon",
        "tooltip-ca-viewsource": "Cht' pache-lo ale est garantie.\n\nOs pouvez vir l'source",
        "tooltip-ca-history": "Antieus canjemints éd chol pache-lo",
        "tooltip-t-recentchangeslinked": "Nouvieus cangemints din chés paches érliées aveuc l'pache-lo",
        "tooltip-feed-rss": "RSS pipe pou l'pache-lo",
        "tooltip-feed-atom": "Fil Atom pou chol pache",
-       "tooltip-t-contributions": "Vir l'lisse éd chés contérbuchons dech uzeu-lo",
+       "tooltip-t-contributions": "Vir l'lisse éd chés contérbuchons {{GENDER:$1|dech uzeu-lo|éd chole utilisatriche}}",
        "tooltip-t-emailuser": "Éspédier un imèle à cht'uzeu-lo",
        "tooltip-t-upload": "Quértcher chés fichiés",
        "tooltip-t-specialpages": "Lisse éd tous chés paches éspéchiales",
        "tooltip-undo": "« Undo » ( ''démangler'' ) értire ch'canjemint-lo pi ouvre l' fénéte d'édichon din ch'mode ''prévir''. <br /> In put mette un motif din ch'résumé.",
        "tooltip-preferences-save": "Warder chés préférinches.",
        "tooltip-summary": "Intrer un tiot résumè",
+       "simpleantispam-label": "Vérificacion anti-pourriel.\nN' <strong>rien</strong> inscrire ichi !",
        "pageinfo-toolboxlink": "Informacions édseur l'page",
        "previousdiff": "← Pu vieille édition",
        "nextdiff": "Nouvèle édichon →",
        "file-info-size": "$1 × $2 picséls, diminchon dech fichié: $3, MIME tipe: $4",
        "file-nohires": "Poin éd pu grande résoluchon possibe.",
        "svg-long-desc": "Fichié SVG, résoluchon éd $1 × $2 picsels, diminchon: $3",
-       "show-big-image": "Plinne résoluchon",
+       "show-big-image": "Fichier d’origine",
+       "show-big-image-preview": "Taille éd chl' apérchu : $1.",
+       "show-big-image-other": "{{PLURAL:$2|Eute résolucion|Eutes résolucions}} : $1.",
+       "show-big-image-size": "$1 × $2 pixels",
        "newimages": "Galerie d'chés nouvieus fichiés",
        "bad_image_list": "Ch'format ch'est:\n\nIn érbéye seulemint chés lisses éd limérachon (aveuc * al copéte). <br /> Ech preumié loïen d'eune line i doét éte échti d'eune méchante image. <br /> Chés eutes loïens su el méme line s'ront érbéyés conme des éssékcions, pèr eximpe des paches où l'image put aparoète.",
        "metadata": "Metadata",
        "watchlisttools-view": "Vir chés consécants cangemints",
        "watchlisttools-edit": "Vir pi éditer l'lisse à suire",
        "watchlisttools-raw": "Éditer eune brute lisse à suire",
+       "signature": "[[{{ns:user}}:$1|$2]] ([[{{ns:user_talk}}:$1|discussion]])",
        "duplicate-defaultsort": "Afute : él cleu d'tri pèr défeut « $2 » écrase l'précédinte « $1 ».",
        "version-specialpages": "Paches éspéchiales",
        "fileduplicatesearch": "Dénicher chés doublons",
        "external_image_whitelist": " #Laicher chol line egzactemint telle quelle.<pre>\n#Dire chés bérlukes d’éspressions rationnelles (juste l'partie désignée inte chés //) chi-édsous.\n#I correspondront aveuc chés URL des images éstérnes.\n#Chelles qui corresponde'te s’affikeront conme des images, sinon seul un loïen vers l’image i s'ra affiké.\n#Les lines conmençant par un # s'ront considérées conme des conmintaires.\n#Chol lisse n’est mie sensibe à la casse.\n\n#Mettez tous chés bérlukes d’éspressions rationnelles au-d'sus éd chol line. Laichez chol darin.ne line telle quelle.</pre>",
        "tags": "Balises des canjemints valides",
        "tag-filter": "Filtrer chés [[Special:Tags|balises]] :",
+       "tag-list-wrapper": "[[Special:Tags|{{PLURAL:$1|Balise|Balises}}]] : $2",
        "comparepages": "Compérer dés paches",
        "compare-page1": "Pache 1",
        "compare-page2": "Pache 2",
        "compare-rev1": "Canjemint 1",
        "compare-rev2": "Canjemint 2",
        "compare-submit": "Aconparer",
-       "htmlform-reset": "n'poin foaire chés canjemints"
+       "htmlform-reset": "n'poin foaire chés canjemints",
+       "logentry-delete-delete": "$1 a supprimé l' pache $3",
+       "logentry-move-move": "$1 a déplacé l' pache $3 vers $4",
+       "logentry-newusers-create": "Ch' compte éd l’utilisat{{GENDER:$4|eu|riche}} $1 il o tè créé",
+       "logentry-upload-upload": "$1 {{GENDER:$2|a téléversé}} $3",
+       "searchsuggest-search": "Tracher {{SITENAME}}"
 }
index 9c1de7e..cc77368 100644 (file)
        "ipbreason-dropdown": "*Najczęstsze przyczyny blokad\n** Ataki na innych użytkowników\n** Naruszenie praw autorskich\n** Niedozwolona nazwa użytkownika\n** Open proxy lub Tor\n** Spamowanie\n** Usuwanie treści stron\n** Wprowadzanie fałszywych informacji\n** Wulgaryzmy\n** Wypisywanie bzdur na stronach",
        "ipb-hardblock": "Zablokuj możliwość edytowania przez zalogowanych użytkowników z tego adresu IP.",
        "ipbcreateaccount": "Utworzenie konta",
-       "ipbemailban": "Wysyłanie e‐mailów",
+       "ipbemailban": "Wysyłanie e‐maili",
        "ipbenableautoblock": "Zablokuj ostatni adres IP tego użytkownika i automatycznie wszystkie kolejne, z których będzie próbował edytować",
        "ipbsubmit": "Zablokuj użytkownika",
        "ipbother": "Inny okres",
        "logentry-partialblock-block": "$1 {{GENDER:$2|wyłączył|wyłączyła}} {{GENDER:$4|$3}} z edytowania $7, czas blokady: $5 $6",
        "logentry-partialblock-reblock": "$1 {{GENDER:$2|zmienił|zmieniła}} ustawienia wyłączenia {{GENDER:$4|$3}} z edytowania $7, czas blokady: $5 $6",
        "logentry-non-editing-block-block": "$1 {{GENDER:$2|zablokował|zablokowała}} {{GENDER:$4|$3}} wykonywanie określonych operacji nieedycyjnych, czas blokady: $5 $6",
-       "logentry-non-editing-block-reblock": "$1 {{PLURAL:$2|zmienił|zmieniła}} ustawienia blokady wykonywania określonych operacji nieedycyjnych {{GENDER:$4|$3}}, czas blokady: $5 $6",
+       "logentry-non-editing-block-reblock": "$1 {{GENDER:$2|zmienił|zmieniła}} ustawienia blokady wykonywania określonych operacji nieedycyjnych {{GENDER:$4|użytkownikowi|użytkowniczce}} $3, czas blokady: $5 $6",
        "logentry-suppress-block": "$1 {{GENDER:$2|zablokował|zablokowała}} {{GENDER:$4|$3}}, czas blokady: $5 $6",
        "logentry-suppress-reblock": "$1 {{GENDER:$2|zmienił|zmieniła}} ustawienia blokady dla {{GENDER:$4|$3}}, czas blokady: $5 $6",
        "logentry-import-upload": "$1 {{GENDER:$2|zaimportował|zaimportowała}} $3 poprzez przesłanie pliku",
        "edit-error-short": "Błąd: $1",
        "edit-error-long": "Błędy:\n\n$1",
        "specialmute": "Ignoruj",
-       "specialmute-success": "Twoje preferencje ignorowania zostały pomyślnie zaktualizowane. Zobacz wszystkich ignorowanych użytkowników w [[Special:Preferences|preferencjach]].",
+       "specialmute-success": "Twoje preferencje ignorowania zostały zaktualizowane. Zobacz wszystkich ignorowanych użytkowników w [[Special:Preferences|swoich preferencjach]].",
        "specialmute-submit": "Potwierdź",
        "specialmute-label-mute-email": "Ignoruj e-maile od tego użytkownika",
        "specialmute-header": "Wybierz swoje preferencje ignorowania dla {{BIDI:[[User:$1]]}}.",
index e1635f4..9401e14 100644 (file)
        "edit-error-short": "Erro: $1",
        "edit-error-long": "Erros:\n$1",
        "specialmute": "Silenciar",
-       "specialmute-success": "Suas preferências de silêncio foram atualizadas com sucesso. Ver todos os usuários silenciados em [[Special:Preferences]].",
+       "specialmute-success": "Suas preferências de silêncio foram atualizadas com sucesso. Ver todos os usuários silenciados nas [[Special:Preferences|suas preferencias]].",
        "specialmute-submit": "Confirmar",
        "specialmute-label-mute-email": "Silenciar e-mails deste usuário",
        "specialmute-header": "Por favor, selecione suas preferências de mudo para {{BIDI:[[User:$1]]}}.",
index 0069197..7863e0c 100644 (file)
        "restrictionsfield-help": "Um endereço IP ou uma gama CIDR por linha. Para ativar todos,\nuse: <pre>0.0.0.0/0\n::/0</pre>",
        "edit-error-short": "Erro: $1",
        "edit-error-long": "Erros:\n\n$1",
+       "specialmute": "Silenciamento",
+       "specialmute-success": "As suas preferências de silenciamento foram atualizadas. Ver todos os utilizadores silenciados em [[Special:Preferences]].",
+       "specialmute-submit": "Confirmar",
+       "specialmute-label-mute-email": "Silenciar os correios eletrónicos deste utilizador",
+       "specialmute-header": "Selecione as suas preferências de silenciamento para {{BIDI:[[User:$1]]}}, por favor.",
+       "specialmute-error-invalid-user": "Não foi possível encontrar o nome de utilizador pedido.",
+       "specialmute-error-email-blacklist-disabled": "O silenciamento de utilizadores para impedi-los de enviar-lhe correio eletrónico não está ativado.",
+       "specialmute-error-email-preferences": "Tem de confirmar o seu endereço de correio eletrónico antes de poder silenciar um utilizador. Pode fazê-lo em [[Special:Preferences]].",
+       "specialmute-email-footer": "Para gerir as preferências de correio eletrónico de {{BIDI:$2}} visite <$1>, por favor.",
+       "specialmute-login-required": "Para alterar as suas preferências de silenciamento, inicie uma sessão, por favor.",
        "revid": "revisão $1",
        "pageid": "identificador de página $1",
        "interfaceadmin-info": "$1\n\nAs permissões de edição de ficheiros CSS/JS/JSON que afetam todo o ''site'' foram recentemente separadas do privilégio <code>editinterface</code>. Se não compreende porque está a receber este erro, consulte [[mw:MediaWiki_1.32/interface-admin]].",
index 2d22536..6ba308b 100644 (file)
        "editfont-monospace": "Option used in [[Special:Preferences]], tab Editing. {{Gender}}",
        "editfont-sansserif": "Option used in [[Special:Preferences]], tab Editing. {{Gender}}",
        "editfont-serif": "Option used in [[Special:Preferences]], tab Editing. {{Gender}}",
-       "sunday": "Name of the day of the week.\n{{Identical|Sunday}}",
-       "monday": "Name of the day of the week.\n{{Identical|Monday}}",
-       "tuesday": "Name of the day of the week.\n{{Identical|Tuesday}}",
-       "wednesday": "Name of the day of the week.\n{{Identical|Wednesday}}",
-       "thursday": "Name of the day of the week.\n{{Identical|Thursday}}",
-       "friday": "Name of the day of the week.\n{{Identical|Friday}}",
-       "saturday": "Name of the day of the week.\n{{Identical|Saturday}}",
-       "sun": "Abbreviation for Sunday, a day of the week.",
-       "mon": "Abbreviation for Monday, a day of the week.",
-       "tue": "Abbreviation for Tuesday, a day of the week.",
-       "wed": "Abbreviation for Wednesday, a day of the week.",
-       "thu": "Abbreviation for Thursday, a day of the week.",
-       "fri": "Abbreviation for Friday, a day of the week.",
-       "sat": "Abbreviation for Saturday, a day of the week.",
+       "sunday": "{{doc-weekdays}}\n{{Identical|Sunday}}",
+       "monday": "{{Doc-weekdays}}\nName of the day of the week.\n{{Identical|Monday}}",
+       "tuesday": "{{Doc-weekdays}}\nName of the day of the week.\n{{Identical|Tuesday}}",
+       "wednesday": "{{Doc-weekdays}}\nName of the day of the week.\n{{Identical|Wednesday}}",
+       "thursday": "{{doc-weekdays}}\n{{Identical|Thursday}}",
+       "friday": "{{doc-weekdays}}\n{{Identical|Friday}}",
+       "saturday": "{{doc-weekdays}}\n{{Identical|Saturday}}",
+       "sun": "{{doc-weekdays}}",
+       "mon": "{{doc-weekdays}}",
+       "tue": "{{doc-weekdays}}",
+       "wed": "{{doc-weekdays}}",
+       "thu": "{{doc-weekdays}}",
+       "fri": "{{doc-weekdays}}",
+       "sat": "{{doc-weekdays}}",
        "january": "{{doc-months|1}}\n{{Identical|January}}",
        "february": "{{doc-months|2}}\n{{Identical|February}}",
        "march": "{{doc-months|3}}\n{{Identical|March}}",
        "specialmute-error-invalid-user": "Error displayed when the username cannot be found.",
        "specialmute-error-email-blacklist-disabled": "Error displayed when email blacklist is not enabled.",
        "specialmute-error-email-preferences": "Error displayed when the user has not confirmed their email address.",
-       "specialmute-email-footer": "Email footer linking to [[Special:Mute]] preselecting the sender to manage muting options.\n* $1 - Url linking to [[Special:Mute]].\n* $2 - The user sending the email.",
+       "specialmute-email-footer": "Email footer in plain text linking to [[Special:Mute]] preselecting the sender to manage muting options.\n* $1 - Url linking to [[Special:Mute]].\n* $2 - The user sending the email.",
        "specialmute-login-required": "Error displayed when a user tries to access [[Special:Mute]] before logging in.",
        "revid": "Used to format a revision ID number in text. Parameters:\n* $1 - Revision ID number.\n{{Identical|Revision}}",
        "pageid": "Used to format a page ID number in text. Parameters:\n* $1 - Page ID number.",
index fc1efcf..b31ca37 100644 (file)
                        "1233qwer1234qwer4",
                        "Саша Волохов",
                        "Serhio Magpie",
-                       "ЛингвоЧел"
+                       "ЛингвоЧел",
+                       "OlegVeliky"
                ]
        },
        "tog-underline": "Подчёркивание ссылок:",
        "search-file-match": "(совпадает с содержимым файла)",
        "search-suggest": "Возможно, вы имели в виду «$1».",
        "search-rewritten": "Показаны результаты для $1. Искать вместо этого $2.",
-       "search-interwiki-caption": "Результаты братских проектов",
+       "search-interwiki-caption": "Результаты родственных проектов",
        "search-interwiki-default": "Результаты из $1:",
        "search-interwiki-more": "(ещё)",
        "search-interwiki-more-results": "ещё результаты",
index 9624db6..d657b61 100644 (file)
        "spam_reverting": "Turradda a l'ulthima versioni chena cullegamenti a $1",
        "spam_blanking": "Pàgina ibbiuddadda, tutti li ribisioni abìani cullegamenti a $1",
        "simpleantispam-label": "Cumprobu cuntraspam\nNo <strong>not</strong> ischribì nudda drentu!",
+       "pageinfo-header-basic": "Iffuimmaziòni basirari",
+       "pageinfo-header-edits": "Cronologia",
+       "pageinfo-robot-index": "Primmissu",
+       "pageinfo-firstuser": "Criadori di pàgini",
+       "pageinfo-firsttime": "Data di criazioni di la pàgina",
+       "pageinfo-edits": "Innùmaru totari di modìfichi",
        "pageinfo-toolboxlink": "Iffuimmaziòni pa la pàgina",
        "pageinfo-contentpage-yes": "Sì",
        "pageinfo-protect-cascading-yes": "Sì",
        "version": "Versioni",
        "version-other": "Althru",
        "version-software-version": "Versioni",
+       "redirect-submit": "Vai",
+       "redirect-revision": "Versioni di la pàgina",
        "fileduplicatesearch-filename": "Innòommu di lu file:",
        "fileduplicatesearch-submit": "Zercha",
        "specialpages": "Pagini ippiziari",
        "tag-list-wrapper": "[[Special:Tags|{{PLURAL:$1|Tag|Tags}}]]: $2",
        "tags-active-yes": "Sì",
        "tags-edit": "mudifigga",
+       "tags-hitcount": "$1 {{PLURAL:$1|mudìfigga|mudìfigghi}}",
        "htmlform-submit": "Invia",
        "htmlform-reset": "Annulla mudifigghi",
        "htmlform-selectorother-other": "Althru",
        "logentry-upload-upload": "$1 {{GENDER:$2|à carriggaddu}} $3",
        "rightsnone": "(nisciunu)",
        "searchsuggest-search": "Zercha di dentru a {{SITENAME}}",
+       "duration-days": "$1 {{PLURAL:$1|dì}}",
        "userlogout-continue": "Bói iscí?"
 }
index 58a0bbc..354bb70 100644 (file)
        "previewerrortext": "Dogodila se greška prilikom prikazivanja vaših izmjena.",
        "blockedtitle": "Korisnik je blokiran",
        "blocked-email-user": "<strong>Vašem korisničkom imenu je zabranjeno slanje e-poruka. Još uvijek možete da uređujete druge stranice na ovom wikiju.</strong> \nSve pojedinosti o zabrani naći ćete u [[Special:MyContributions|doprinosima naloga]].\n\nZabranu je dao/la $1.\n\nNaveden je sljedeći razlog: <em>$2</em>.\n\n* Početak zabrane: $8\n* Istek zabrane: $6\n* Namijenjena korisniku/ci ili IP adresi: $7\n* ID zabrane #$5",
-       "blockedtext-partial": "<strong>Vašem korisničkom imenu ili IP adresi je zabranjeno pravljenje izmjena na ovoj stranici. Još uvijek možete da uređujete druge stranice na ovom wikiju.</strong> Sve pojedinosti o zabrani naći ćete u [[Special:MyContributions|doprinosima naloga]].\n\nZabranu je dao/la $1.\n\nNaveden je sljedeći razlog: <em>$2</em>.\n\n* Početak zabrane: $8\n* Istek zabrane: $6\n* Namijenjena korisniku/ci ili IP adresi: $7\n* ID zabrane #$5",
+       "blockedtext-partial": "<strong>Vašem korisničkom imenu ili IP adresi je zabranjeno praviti izmjene na ovoj stranici. Još uvijek možete da uređujete druge stranice na ovom wikiju.</strong> Sve pojedinosti o zabrani naći ćete u [[Special:MyContributions|doprinosima naloga]].\n\nZabranu je dao/la $1.\n\nNaveden je sljedeći razlog: <em>$2</em>.\n\n* Početak zabrane: $8\n* Istek zabrane: $6\n* Predviđeni zabranjenik: $7\n* Naznaka zabrane #$5",
        "blockedtext": "<strong>Vaše korisničko ime ili IP adresa je blokirana.</strong>\n\nBlokada izvršena od strane $1.\nDati razlog je slijedeći: <em>$2</em>.\n\n* Početak blokade: $8\n* Kraj perioda blokade: $6\n* Ime blokiranog korisnika: $7\n\nMožete kontaktirati $1 ili nekog drugog [[{{MediaWiki:Grouppage-sysop}}|administratora]] da biste razgovarali o blokadi.\nMožete koristiti opciju \"{{int:emailuser}}\" ako je navedena valjana adresa e-pošte u [[Special:Preferences|Vašim postavkama]] i Vam nije zabranjeno je koristiti.\nVaša trenutna IP adresa je $3, a oznaka blokade je #$5.\nMolimo Vas da navedete gornje podatke u zahtjevu za deblokadu.",
        "autoblockedtext": "Vaša IP adresa je automatski blokirana jer je korištena od strane drugog korisnika, a blokirao ju je $1.\nNaveden je slijedeći razlog:\n\n:<em>$2</em>\n\n* Početak blokade: $8\n* Kraj blokade: $6\n* Blokirani korisnik: $7\n\nMožete kontaktirati $1 ili nekog drugog iz grupe [[{{MediaWiki:Grouppage-sysop}}|administratora]] i zahtijevati da Vas deblokira.\n\nZapamtite da ne možete koristiti opciju \"{{int:emailuser}}\" ukoliko nije unesena validna e-mail adresa u [[Special:Preferences|Vašim postavkama]] te Vas ne spriječava ga je koristite.\n\nVaša trenutna IP adresa je $3, a ID blokade je $5.\nMolimo da navedete sve gore navedene detalje u zahtjevu za deblokadu.",
        "systemblockedtext": "MediaWiki je automatski blokirao Vaše korisničko ime ili IP-adresu.\nDat je sljedeći razlog:\n\n:<em>$2</em>\n\n* Početak bloka: $8\n* Istek bloka: $6\n* Blok je namijenjen za: $7\n\nVaša trenutna IP-adresa je $3.\nPrepišite sve gorenavedene pojedinosti ukoliko želite da vlasti pitaju za blok.",
index 1606205..a330658 100644 (file)
        "title-invalid-too-long": "Požadovaný názov stránky je príliš dlhý. Nesmie byť dlhšií ako $1 {{PLURAL:$1|bajt|bajty|bajtov}} v kódovaní UTF-8.",
        "title-invalid-leading-colon": "Požadovaný názov stránky obsahuje na začiatku neplatnú dvojbodku.",
        "perfcached": "Nasledujúce údaje pochádzajú z vyrovnávacej pamäte a nemusia byť úplne aktuálne. Vo vyrovnávacej pamäti {{PLURAL:$1|je dostupný|sú dostupné|je dostupných}} najviac {{PLURAL:$1|jeden výsledok|$1 výsledky|$1 výsledkov}}.",
-       "perfcachedts": "Nasledujúce údaje pochádzajú z vyrovnávacej pamäte a naposledy boli aktualizované $1. Vo vyrovnávacej pamäti {{PLURAL:$4|je dostupný|sú dostupné|je dostupných}} najviac {{PLURAL:$4|jeden výsledok|$4 výsledky|$4 výsledkov}}.",
+       "perfcachedts": "Nasledujúce údaje pochádzajú z vyrovnávacej pamäte. Čas poslednej aktualizácie je $1. Vo vyrovnávacej pamäti {{PLURAL:$4|je dostupný|sú dostupné|je dostupných}} najviac {{PLURAL:$4|jeden výsledok|$4 výsledky|$4 výsledkov}}.",
        "querypage-no-updates": "Aktualizácie tejto stránky sú momentálne vypnuté. Tieto dáta sa v súčasnosti nebudú obnovovať.",
-       "viewsource": "Zobraziť zdroj",
+       "viewsource": "Zobraziť kód",
        "viewsource-title": "Zobrazenie zdroja stránky $1",
        "actionthrottled": "Činnosť bola spomalená",
        "actionthrottledtext": "Ako opatrenie proti spamu je počet vykonaní tejto činnosti za určitý čas obmedzený. Tento limit ste prekročili. Prosím, skúste to znova o niekoľko minút.",
index ae6455d..576512e 100644 (file)
        "edit-error-short": "Napaka: $1",
        "edit-error-long": "Napake:\n\n$1",
        "specialmute": "Utišaj",
-       "specialmute-success": "Vaše nastavitve utišanja smo uspešno posodobili. Oglejte si vse utišane uporabnike na strani [[Special:Preferences]].",
+       "specialmute-success": "Vaše nastavitve utišanja smo uspešno posodobili. Oglejte si vse utišane uporabnike v [[Special:Preferences|svojih nastavitvah]].",
        "specialmute-submit": "Potrdi",
        "specialmute-label-mute-email": "Utišaj e-pošto tega uporabnika",
        "specialmute-header": "Prosimo, izberite svoje nastavitve utišanja za uporabnika {{BIDI:[[User:$1]]}}.",
index 61b5c18..d28631e 100644 (file)
        "monthsall": "kabéh",
        "confirmemail": "Konfirmasi alamat surélék",
        "confirmemail_noemail": "Alamat surélék anu didaptarkeun dina [[Special:Preferences|préferénsi pamaké]] anjeun teu sah.",
-       "confirmemail_text": "{{SITENAME}} téh anjeun kudu ngonfirmasi alamat surélék sangkan bisa migunakeun fiturna.\nKlik tombol di handap pikeun ngirimkeun talatah nu eusina konfirmasieun kana alamat anjeun. Eusi talatahna ngandung tutumbu kodeu; muatkeun tumbuna kana panyungsi anjeun pikeun ngonfirmasi yén alamat surélék anjeun sah.",
+       "confirmemail_text": "{{SITENAME}} téh anjeun kudu ngonfirmasi alamat surélék sangkan bisa migunakeun fiturna.\nKlik tombol di handap pikeun ngirimkeun talatah nu eusina konfirmasieun kana alamat anjeun.\nEusi talatahna ngandung tutumbu kodeu;\nmuatkeun tumbuna kana panyungsi anjeun pikeun ngonfirmasi yén alamat surélék anjeun sah.",
        "confirmemail_pending": "Kecap sandi konfirmasi geus dikirimkeun ka alamat surélék anjeun; mun anyar nyieun akun, mangga antos sababaraha menit saméméh mundut kecap sandi anyar.",
        "confirmemail_send": "Kirimkeun surat konfirmasi sandi",
        "confirmemail_sent": "Surélék konfirmasi geus dikirim.",
index af4bd1e..5dd7c1b 100644 (file)
        "edit-error-short": "Fel: $1",
        "edit-error-long": "Fel:\n\n$1",
        "specialmute": "Tyst",
-       "specialmute-success": "Dina tystnadsinställningar har uppdateras. Se alla tystade användare i [[Special:Preferences|inställningarna]].",
+       "specialmute-success": "Dina tystnadsinställningar har uppdateras. Se alla tystade användare i [[Special:Preferences|dina inställningarna]].",
        "specialmute-submit": "Bekräfta",
        "specialmute-label-mute-email": "Tysta e-post från denna användare",
        "specialmute-header": "Välj dina tystnadsinställningar för {{BIDI:[[User:$1]]}}.",
        "specialmute-error-invalid-user": "Det begärda användarnamnet kunde inte hittas.",
        "specialmute-error-email-blacklist-disabled": "Att förhindra användare från att skicka e-post till dig har inte aktiverats.",
        "specialmute-error-email-preferences": "Du måste bekräfta din e-postadress innan du kan tysta en användare. Du kan göra det i [[Special:Preferences|inställningarna]].",
-       "specialmute-email-footer": "[$1 Hantera e-postinställningar för {{BIDI:$2}}.]",
+       "specialmute-email-footer": "För att hantera e-postinställningar för {{BIDI:$2}}, besök <$1>.",
        "specialmute-login-required": "Logga in för att ändra dina tystnadsinställningar.",
        "revid": "sidversion $1",
        "pageid": "sid-ID $1",
index b89b619..2eb7bdb 100644 (file)
                        "Hedda",
                        "Fitoschido",
                        "TmY e12",
-                       "Dual"
+                       "Dual",
+                       "ToprakM"
                ]
        },
        "tog-underline": "Bağlantıların altını çizme:",
index 635f99d..80a70bd 100644 (file)
        "gender-male": "Dekronoyo",
        "gender-female": "Neqıbṭonoyo",
        "email": "Email",
-       "prefs-help-email": "Latat majbur dkıṭwat uEmail-Adresayḍox, elo glozam inaqla ṫo³at uQliḍayḍox u hakka dlozam dmişadar lox Qliḍo ḥaṭo.",
+       "prefs-help-email": "Latat majbur dkıṭwat uEmail-Adresayḍox, elo glozam inaqla ṫo³at uQliḍayḍox u hakka dlozam dmişadar lox qliḍo ḥaṭo.",
        "prefs-help-email-others": "Kibux mijğolat 3am Hadome ğer biFaṭo duMamlo u luglozam dumat Işmux.",
        "prefs-signature": "Imḍa",
        "group-user": "Hadome",
index 66341a6..b3b48cc 100644 (file)
@@ -4,42 +4,58 @@
                        "Iyuqciyang"
                ]
        },
-       "sunday": "jiyax sngayan",
+       "sunday": "Jiyax sngayan",
        "monday": "Tg1 jiyax iyax sngayan",
        "tuesday": "Tg2 jiyax iyax sngayan",
        "wednesday": "Tg3 jiyax iyax sngayan",
        "thursday": "Tg4 jiyax iyax sngayan",
        "friday": "Tg5 jiyax iyax sngayan",
-       "saturday": "tg6 jiyax iyax sngayan",
-       "mon": "Tg1jiyax iyax sngayan",
-       "january": "tg1 idas",
-       "february": "tg2 idas",
+       "saturday": "Tg6 jiyax iyax sngayan",
+       "sun": "Js",
+       "mon": "J1",
+       "tue": "J2",
+       "wed": "J3",
+       "thu": "J4",
+       "fri": "J5",
+       "sat": "J6",
+       "january": "Tg1 idas",
+       "february": "Tg2 idas",
        "march": "Tg3 idas",
        "april": "Tg4 idas",
        "may_long": "Tg5 idas",
        "june": "Tg6 idas",
-       "july": "empitu idas",
+       "july": "Tg7 idas",
        "august": "Tg8 idas",
        "september": "Tg9 idas",
        "october": "Tg10 idas",
        "november": "Tg11 idas",
        "december": "Tg12 idas",
-       "january-gen": "tg1 idas",
-       "february-gen": "tg2 idas",
+       "january-gen": "Tg1 idas",
+       "february-gen": "Tg2 idas",
        "march-gen": "Tg3 idas",
        "april-gen": "Tg4 idas",
        "may-gen": "Tg5 idas",
        "june-gen": "Tg6 idas",
-       "july-gen": "empitu idas",
+       "july-gen": "Tg7 idas",
        "august-gen": "Tg8 idas",
        "september-gen": "Tg9 idas",
        "october-gen": "Tg10 idas",
        "november-gen": "Tg11 idas",
        "december-gen": "Tg12 idas",
-       "feb": "tg2 idas",
-       "may": "Tg5 idas",
+       "jan": "1id",
+       "feb": "2id",
+       "mar": "3id",
+       "apr": "4id",
+       "may": "5id",
+       "jun": "6id",
+       "jul": "7id",
+       "aug": "8id",
+       "sep": "9id",
+       "oct": "10id",
+       "nov": "11id",
+       "dec": "12id",
        "january-date": "tg1 idas $1",
-       "february-date": "tg2 idas $1",
+       "february-date": "Tg2 idas $1",
        "march-date": "Tg3 idas $1",
        "april-date": "Tg4 idas $1",
        "may-date": "Tg5 idas $1",
        "october-date": "Tg10 idas $1",
        "november-date": "Tg11 idas $1",
        "december-date": "Tg12 idas $1",
-       "pagecategories": "{{PLURAL:$1| keelgan |$1 sspug kingal keelgan }}",
-       "category_header": "keelgan \"$1\" kska ruwahan patas",
-       "subcategories": "spiq keelgan",
-       "category-media-header": "keelgan \"$1\" kaka psaput kari",
-       "category-empty": "<em>keelgan nii bitaq saying ini supu kana ruwahan patas aji uri o psaput kari.</em>",
-       "hidden-categories": "{{PLURAL:$1|keelgan lniing }}",
-       "category-subcat-count": "{PLURAL:$2| keelgan nii wana supu kana truma nii 1 kngkingal spiqkeelgan. | keelgan mseupu kana truma nii $1 keelgan kngkingal, mseupu $2 sspug kingal. }}. }}",
-       "category-article-count": "{PLURAL:$2| keelgan o supu kana truma ruwahan patas nii. | keelgan supu kana truma nii $1 kngkingal ruwahan patas, suupu $2 sspugkingal }}",
-       "category-file-count": "{{PLURAL:$2| keelgan nii wana supu kana truma kingal pusu patas. | keelgan supu kana truma patas nii, seupu $2 sspug kingal. }}",
+       "pagecategories": "{{PLURAL:$1|keelgan|$1 sspug kingal keelgan}}",
+       "category_header": "Keelgan \"$1\" kska ruwahan patas",
+       "subcategories": "Spiq keelgan",
+       "category-media-header": "Keelgan \"$1\" kaka psaput kari",
+       "category-empty": "<em>Keelgan nii bitaq saying ini supu kana ruwahan patas aji uri o psaput kari.</em>",
+       "hidden-categories": "{{PLURAL:$1|keelgan lniing}}",
+       "category-subcat-count": "{{PLURAL:$2|Keelgan nii wana supu kana truma nii 1 kngkingal spiqkeelgan.|Keelgan mseupu kana truma nii {{PLURAL:$1|$1}} keelgan kngkingal, mseupu $2 sspug kingal.}}",
+       "category-article-count": "{{PLURAL:$2|Keelgan o supu kana truma ruwahan patas nii.|Keelgan supu kana truma nii {{PLURAL:$1|$1}} kngkingal ruwahan patas, suupu $2 sspugkingal}}.",
+       "category-file-count": "{{PLURAL:$2|Keelgan nii wana supu kana truma kingal pusu patas.|Keelgan supu kana truma {{PLURAL:$1|$1 patas}} nii, seupu $2 sspug kingal.}}",
        "listingcontinuesabbrev": "lmutut",
        "noindex-category": "Ini bkgi patas pnslbu na ka ruwahan patas",
-       "broken-file-category": "pusu patas mggaluk  wada naqih ka ruwahan patas",
-       "newwindow": "(saw ruwahan bgurah lihaw qtaan )",
-       "cancel": "pkungat",
+       "broken-file-category": "Pusu patas mggaluk  wada naqih ka ruwahan patas",
+       "about": "Quri",
+       "article": "Kari ruwan ruwahan patas",
+       "newwindow": "(saw ruwahan bgurah lihaw qtaan)",
+       "cancel": "Pkungat",
        "moredotdotdot": "knlala...",
        "mypage": "ruwahan patas",
-       "mytalk": "empprngaw",
-       "anontalk": "empprngaw",
-       "navigation": "powda qmita",
-       "and": "&#32;ni &#32;",
-       "namespaces": "iyax ptngahan",
-       "variants": "kmpriyux hiyi",
-       "navigation-heading": "powda qmita patas gneegan",
-       "returnto": "embrinah miyah bitaq $1.",
-       "tagline": "pnyahan {{SITENAME}}",
-       "help": "pgkla",
+       "mytalk": "Empprngaw",
+       "anontalk": "Empprngaw",
+       "navigation": "Powda qmita",
+       "and": "&#32;ni",
+       "namespaces": "Iyax ptngahan",
+       "variants": "Kmpriyux hiyi",
+       "navigation-heading": "Powda qmita patas gneegan",
+       "returnto": "Embrinah miyah bitaq $1.",
+       "tagline": "Pnyahan {{SITENAME}}",
+       "help": "Pgkla",
+       "search": "Miying",
+       "searchbutton": "Miying",
        "go": "muda",
-       "searcharticle": "muda",
-       "history": "endaan ruwahan patas",
-       "printableversion": "mtduwa psreeru patas pusu",
-       "permalink": "mggaluk ini kglglug\n(mggaluk mgdhug,mggaluk ana bitaq knuwan)",
-       "view-foreign": "ga $1 qmita",
-       "edit": "smmalu patas",
-       "create": "phiyug",
+       "searcharticle": "Muda",
+       "history": "Endaan ruwahan patas",
+       "history_short": "Endaan",
+       "history_small": "endaan",
+       "printableversion": "Mtduwa psreeru patas pusu",
+       "permalink": "Mggaluk ini kglglug",
+       "view": "Qmita",
+       "view-foreign": "Ga $1 qmita",
+       "edit": "Smmalu patas",
+       "create": "Phiyug",
        "create-local": "Pgkla tnpusu mnrana",
-       "newpage": "bgurah ruwahan patas",
+       "newpage": "Bgurah ruwahan patas",
        "talkpagelinktext": "empprngaw",
-       "specialpage": "ruwahan patas knmalu",
-       "personaltools": "qnqaya taxa",
-       "talk": "empprngaw",
-       "views": "qmita",
-       "toolbox": "qngqaya",
-       "otherlanguages": "kari duma",
-       "redirectedfrom": "(wada brahan dmudul paah $1)",
-       "redirectpagesub": "psbgurah muda ruwahan patas",
-       "redirectto": "psbgurah muda quri bitaq:",
-       "lastmodifiedat": "ruwahan patas nii ka nhdaan smmalu patas o ga $1 $2.",
-       "jumpto": "pquri brah",
+       "specialpage": "Ruwahan patas knmalu",
+       "personaltools": "Qnqaya taxa",
+       "talk": "Empprngaw",
+       "views": "Qmita",
+       "toolbox": "Qngqaya",
+       "otherlanguages": "Kari duma",
+       "redirectedfrom": "(Wada brahan dmudul paah $1)",
+       "redirectpagesub": "Psbgurah muda ruwahan patas",
+       "redirectto": "Psbgurah muda quri bitaq:",
+       "lastmodifiedat": "Ruwahan patas nii ka nhdaan smmalu patas o ga $1, $2.",
+       "jumpto": "Pquri brah:",
        "jumptonavigation": "powda qmita",
-       "aboutsite": "quri  {{SITENAME}}",
-       "aboutpage": "quri",
-       "copyrightpage": "{{ns:project}}: biyax kklawa pnatas",
-       "currentevents": "mlglug ka psaput",
-       "currentevents-url": "Project: euda kari psaput",
-       "disclaimers": "pgkla pnspadaw",
-       "disclaimerpage": "Pnegkla ungat hmutan smriq",
-       "edithelp": "pgkla smmalu patas",
-       "mainpage": "ruwahan patas",
-       "mainpage-description": "ruwahan patas",
-       "portal": "tmayan qmpringan seejiq",
-       "portal-url": "tmayan qmpringan seejiq",
-       "privacy": "euda qmpah lniing",
-       "privacypage": "Euda qmpah lning",
+       "jumptosearch": "miying",
+       "aboutsite": "Quri {{SITENAME}}",
+       "aboutpage": "Project:Quri",
+       "copyrightpage": "{{ns:project}}: Biyax kklawa pnatas",
+       "currentevents": "Mlglug ka psaput",
+       "currentevents-url": "Project:Euda kari psaput",
+       "disclaimers": "Pgkla pnspadaw",
+       "disclaimerpage": "Project:Pnegkla ungat hmutan smriq",
+       "edithelp": "Pgkla smmalu patas",
+       "mainpage": "Ruwahan patas",
+       "mainpage-description": "Ruwahan patas",
+       "portal": "Tmayan qmpringan seejiq",
+       "portal-url": "Project:Tmayan qmpringan seejiq",
+       "privacy": "Euda qmpah lniing",
+       "privacypage": "Project:Euda qmpah lning",
        "retrievedfrom": "Nangal paah \"$1\"",
-       "youhavenewmessages": "Niqan nnisu$1 ($2).",
-       "youhavenewmessagesfromusers": "{{PLURAL:$4|su}}niqan pnaah {{PLURAL:$3|taxa duri empduuy\n|$3 hnigan empduuy }}ka $1 ($2).",
-       "newmessagesdifflinkplural": "{{PLURAL:$1| kmpriyux}} snii",
+       "youhavenewmessages": "{{PLURAL:$3|}}Niqan nnisu $1 ($2).",
+       "youhavenewmessagesfromusers": "{{PLURAL:$4|Su}} niqan pnaah {{PLURAL:$3|taxa duri empduuy|$3 hnigan empduuy}} ka $1 ($2).",
+       "newmessagesdifflinkplural": "{{PLURAL:$1|kmpriyux}} snii",
        "editsection": "smmalu patas",
        "editold": "smmalu patas",
        "viewsourceold": "ida nkiya patas sspgan ka qtai",
-       "editlink": "smmalu patas",
+       "editlink": "Smmalu patas",
        "viewsourcelink": "ida nkiya patas sspgan ka qtai",
-       "editsectionhint": "smmalu patas spgan",
-       "toc": "patas bngkgan",
+       "editsectionhint": "Smmalu patas spgan: $1",
+       "toc": "Patas bngkgan",
        "showtoc": "pqita",
        "hidetoc": "lmiying",
        "collapsible-expand": "muda",
        "site-atom-feed": "$1ka Atom pnyahan",
-       "red-link-title": "$1(ungat ruwahan patas)",
-       "nstab-main": "ruwahan patas",
-       "nstab-user": "empduuy ruwahan patas",
-       "nstab-special": "ruwahan patas knmalu",
-       "nstab-project": "pusu qpahun ruwahan patas",
-       "nstab-image": "pusu patas",
-       "nstab-template": "ptasan",
-       "nstab-category": "keelgan",
-       "mainpage-nstab": "ruwahan patas",
-       "nospecialpagetext": "<strong>brahaw misuu ruwahan patas knmalu ungat brihan. </strong> nasi mkmangal mangal brihan ka knmalu ruwahan patas leexan usa bitaq [[Special:SpecialPages|{{int:specialpages}}]].",
-       "badtitle": "ungat brih ka pusu kari",
-       "badtitletext": "tmiyu ka pusu kari ruwahan patas o ungat brih, kbrhuanl, aji uri o ini muda qmangaw kari aji uri o qmangaw Wiki ka pusu kari.\nkska pusu kari o yaa bi mseupu kana ungat klaan dmuuy mniq pusu kari ka cuyen.",
-       "viewsource": "ida nkiya patas sspgan ka qtai",
-       "viewsource-title": "pqita $1 ka ida nkiya sspgan patas",
-       "viewsourcetext": "Mtduwa su  pqita kiya o pnsreeru ruwahan patas nii ka sspgan patas",
+       "red-link-title": "$1 (ungat ruwahan patas)",
+       "nstab-main": "Ruwahan patas",
+       "nstab-user": "Empduuy ruwahan patas",
+       "nstab-special": "Ruwahan patas knmalu",
+       "nstab-project": "Pusu qpahun ruwahan patas",
+       "nstab-image": "Pusu patas",
+       "nstab-template": "Ptasan",
+       "nstab-category": "Keelgan",
+       "mainpage-nstab": "Ruwahan patas",
+       "nospecialpagetext": "<strong>Brahaw misuu ruwahan patas knmalu ungat brihan.</strong>\n\nNasi mkmangal mangal brihan ka knmalu ruwahan patas leexan usa bitaq [[Special:SpecialPages|{{int:specialpages}}]].",
+       "badtitle": "Ungat brih ka pusu kari",
+       "badtitletext": "Tmiyu ka pusu kari ruwahan patas o ungat brih, kbrhuanl, aji uri o ini muda qmangaw kari aji uri o qmangaw Wiki ka pusu kari.\nKska pusu kari o yaa bi mseupu kana ungat klaan dmuuy mniq pusu kari ka cuyen.",
+       "viewsource": "Ida nkiya patas sspgan ka qtai",
+       "viewsource-title": "Pqita $1 ka ida nkiya sspgan patas",
+       "viewsourcetext": "Mtduwa su  pqita kiya o pnsreeru ruwahan patas nii ka sspgan patas.",
        "yourname": "seejiq mduuy hangan:",
-       "userlogin-yourname-ph": "pstmay matas su mduuy hangan",
+       "userlogin-yourname-ph": "Pstmay matas su mduuy hangan",
        "yourpassword": "sspgan lniing:",
-       "userlogin-yourpassword": "sspgan lniing",
-       "userlogin-yourpassword-ph": "pstmay su sspgan lniing",
+       "userlogin-yourpassword": "Sspgan lniing",
+       "userlogin-yourpassword-ph": "Pstmay su sspgan lniing",
        "createacct-yourpassword-ph": "Pstymay matas sspgan lniing",
-       "createacct-yourpasswordagain": "pgkla sspgan lniing",
+       "createacct-yourpasswordagain": "Pgkla sspgan lniing",
        "createacct-yourpasswordagain-ph": "Pxal duri pstmay matas sspgan lniing",
-       "userlogin-remembermypassword": "\" iya shngii \" saw nii pstmay ku",
-       "login": "pstmay patas.",
+       "userlogin-remembermypassword": "\"Iya shngii\" saw nii pstmay ku",
+       "login": "Pstmay patas",
        "nav-login-createaccount": "pstmay patas. /phiyug patas sspgan",
-       "logout": "latat",
-       "userlogin-noaccount": "ungat patas sspgan hug?",
-       "userlogin-joinproject": "teumal {{SITENAME}}",
-       "createaccount": "phiyug patas sspgan",
-       "userlogin-resetpassword-link": "smhungi sspgan lniing?",
-       "userlogin-helplink2": "dmayaw pstmay",
-       "createacct-emailoptional": "nniqan guban patas samaw ( geegun )",
-       "createacct-email-ph": "pstmay su nniqan gluban patas samaw",
-       "createacct-submit": "phiyug su sspgan patas",
+       "logout": "Latat",
+       "userlogin-noaccount": "Ungat patas sspgan hug?",
+       "userlogin-joinproject": "Teumal {{SITENAME}}",
+       "createaccount": "Phiyug patas sspgan",
+       "userlogin-resetpassword-link": "Smhungi sspgan lniing?",
+       "userlogin-helplink2": "Dmayaw pstmay",
+       "createacct-emailoptional": "Nniqan guban patas samaw (geegun)",
+       "createacct-email-ph": "Pstmay su nniqan gluban patas samaw",
+       "createacct-submit": "Phiyug su sspgan patas",
        "createacct-another-submit": "phiyug patas sspgan",
        "createacct-benefit-heading": "{{SITENAME}} paah saw isumdka seejiq suyang qnpahan saw phiyug da.",
-       "createacct-benefit-body1": "{{PLURAL:$1|smsul smmalu patas }}",
-       "createacct-benefit-body2": "$1 ruwahan",
-       "createacct-benefit-body3": "Hnigan snii {{PLURAL:$1| seejiq suyang qnpahan }}",
+       "createacct-benefit-body1": "{{PLURAL:$1|smsul smmalu patas}}",
+       "createacct-benefit-body2": "{{PLURAL:$1|ruwahan}}",
+       "createacct-benefit-body3": "Hnigan snii {{PLURAL:$1|seejiq suyang qnpahan}}",
        "mailmypassword": "psbgurah powsa sspgan lniing",
-       "loginlanguagelabel": "kari:$1",
-       "pt-login": "pstmay patas.",
-       "pt-login-button": "pstmay patas.",
-       "pt-createaccount": "phiyug patas sspgan",
-       "pt-userlogout": "latat",
-       "botpasswords-label-cancel": "pkungat",
-       "resetpass-submit-cancel": "pkungat",
-       "passwordreset": "psbgurah powsa sspgan lniing",
+       "loginlanguagelabel": "Kari: $1",
+       "pt-login": "Pstmay patas",
+       "pt-login-button": "Pstmay patas",
+       "pt-createaccount": "Phiyug patas sspgan",
+       "pt-userlogout": "Latat",
+       "botpasswords-label-cancel": "Pkungat",
+       "resetpass-submit-cancel": "Pkungat",
+       "passwordreset": "Psbgurah powsa sspgan lniing",
        "passwordreset-username": "seejiq mduuy hangan:",
-       "bold_sample": "patas qthur",
-       "bold_tip": "patas qthur",
-       "italic_sample": "atas gmisil",
-       "italic_tip": "atas gmisil",
-       "link_sample": "mggaluk pusu kari",
-       "link_tip": "mggaluk ruwan",
-       "extlink_sample": "http://www.example.com mggaluk pusu kari",
-       "extlink_tip": "lipax mggaluk ( saw peeniq qsahur http:// pnrjingan)",
+       "bold_sample": "Patas qthur",
+       "bold_tip": "Patas qthur",
+       "italic_sample": "Atas gmisil",
+       "italic_tip": "Atas gmisil",
+       "link_sample": "Mggaluk pusu kari",
+       "link_tip": "Mggaluk ruwan",
+       "extlink_sample": "http://www.example.com/ mggaluk pusu kari",
+       "extlink_tip": "Lipax mggaluk (saw peeniq qsahur http:// pnrjingan)",
        "headline_sample": "Tg1 tntunan patas pusu kari",
        "headline_tip": "Tg2 tntunan patas pusu kari",
-       "nowiki_sample": "maat kska aji smmalu iyax ptasan patas",
-       "nowiki_tip": "brkagan Wiki smmalu iyax ptasan elug kari",
-       "image_tip": "numal pusu patas",
-       "media_tip": "mggaluk pusu patas",
-       "sig_tip": "patas hangan su ni jiyax",
-       "hr_tip": "qtaan ayus msbalay (bilaq bi dmuuy)",
-       "summary": "ramas kari:",
+       "nowiki_sample": "Maat kska aji smmalu iyax ptasan patas",
+       "nowiki_tip": "Brkagan Wiki smmalu iyax ptasan elug kari",
+       "image_tip": "Numal pusu patas",
+       "media_tip": "Mggaluk pusu patas",
+       "sig_tip": "Patas hangan su ni jiyax",
+       "hr_tip": "Qtaan ayus msbalay (bilaq bi dmuuy)",
+       "summary": "Ramas kari:",
        "minoredit": "Asaw nii snsul smmalu patas",
        "watchthis": "Gmraka qmita ruwahan patas nii",
-       "savearticle": "skuun ruwahan patas",
+       "savearticle": "Skuun ruwahan patas",
        "savearticle-start": "skuun ruwahan patas...",
-       "showpreview": "pqita daan qmita",
-       "showdiff": "kmpriyux pqita",
-       "anoneditwarning": "<strong> ptqlahang :</strong> Ini su pstmay matas na. nasi su muda ana manu smmalu patas su ga niqan IP mha wada traun. nasi su <strong>[$1 pstmay matas ]</strong> aji uri o <strong>[$2 phiyug patas sspgan </strong>, smmalu patas su o saw nnisu mha seejiq mduuy hangan pnskraya, niqan duma ka tgmalu.",
-       "blockedtext": "<strong> empduuy hangansu\n Aji uri o nniqan IP wada tna shmuk. </strong> wada su powda $1 hmuk, pusu asaw <em>$2</em>. * jiyax prajing hmuk:$8 * jiyaxqmhdu hmuk :$6 * quri hmuk seejiq:$7 mtduwa su mggaluk $1 aji uri o duma ka [[{{MediaWiki:Grouppage-sysop}}| seejiq kmlawa ]] pprngaw hmuk ka quri msriquu. Nasi tna su ga mniq [[Special:Preferences|smkuxul powsa ]] kska pha kingal brihan ka gluban patas samaw patas nniqan, aji o ini powda hmuk nabrihan bluban patas samaw, kiya do mtduwa su powda \" mggaluk samaw nii empduuy \" ka brihan nii mggaluk quri seejiq kmlawa. bitaq saying ka isu ga niqan IP o $3, saw nii hmuk ka ID asaw #$5. Eniq jiyax sslingan umal patas plxani bi pngkla kari.",
-       "loginreqlink": "pstmay patas.",
-       "newarticletext": "Nii su mggaluk bitaq kingal ruwahan patas aji mha ungat ruwahan patas.\nDai phiyug ruwahan patas nii,ga su mniq truma ka smmalu patas qpuruh mangal  kska kari ruwan ( leexan balay powda qtaan patas [$1 dmuuy pgkla ruwahan patas ]) .\nNasi su ini qlahang iyah hini ruwahan patas, powda gmaaw daan qmita ka <strong> embrinah miyah </strong> gluban.",
-       "anontalkpagetext": "---- <em> empprngaw ruwahan pusu nii ka ini bqani na phiyug sspgan patas pnskuan pila ka hangan lniing empduuy dmuuy </em> kiya do asi su ka dmuuy ga niqan IP miyah psenak hnigan, kiya kaq kiyta ni snruwayan ga niqan IPyaa bipaah lala bi ini pndkaempduuy saw pnspuan dmuuy. Nasi isu ka hangan lniing empduuy saw lnglungan suu rmngaw qntaan ka kari ruwan ungat pngluban, powda [[Special:CreateAccount| phiyug bgurah Sspgan patas ]]aji uri o[[Special:UserLogin|pstmay]] saw aji mha mdka duma mduuy hangan lniing mgamax.",
-       "noarticletext": "ruwahan patas nii bitaq sayang ungat kari ruwan, mtduwa su mniq kska duma ruwahan patas [[Special:Search/{{PAGENAME}}| miying pnskraya ruwahan patas nii ]]、<span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} miying quri jiyax rnisuh patas ]aji uri o [{{fullurl:{{FULLPAGENAME}}|action=edit}} phiyug ruwahan patas nii]</span>.",
-       "noarticletext-nopermission": "ruwahan patas nii bitaq sayang ungat kari ruwan,\nmtduwa su mniq kska duma ruwahan patas [[Special:Search/{{PAGENAME}}| miying pnskraya ruwahan patas nii ], aji uri o <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} miying quri saw jiyax rnisuh patas ]</span>, kiya ka kiya ni ungat su dduy biyax phiyug ruwahan patas nii.",
-       "userpage-userdoesnotexist-view": "seejiq mduuy patas sspgan \"$1\" ini ppatas na.",
-       "clearyourcache": "<strong> qlahang:</strong> ga mnmiq skuun su babaw na do asi su ka srsan daan qmita qngqaya rait bi mangal kika mtduwa qtaan kmpriyux. * <strong>Firefox / Safari:</strong>prci ni <em>Shift</em> 時 gmaaw <em> psbgurah smmalu </em>,aji uri o <em>Ctrl-F5</em> aji uri o <em>Ctrl-R</em> (Mac saw kiya do <em>⌘-R</em>) * <strong>Google Chrome:</strong>prci <em>Ctrl-Shift-R</em> (Mac saw kiya do <em>⌘-Shift-R</em>) * <strong>Internet Explorer:</strong>prci <em>Ctrl</em> 時 gmaaw <em> psbgurah smmalu </em>, aji uri o prci <em>Ctrl-F5</em> * <strong>Opera:</strong> pquri brah <em> gmaaw → pha </em> (mniq Mac asaw <em>Opera → smkuxul powsa </em>) babaw na duri o<em> lniing & aji hhuya → srsi qmita patas → wada rait mangal ka patas ni pusu patas </em>.",
-       "previewnote": "<strong>bitaq saying ni su qtaan, kmpriyux su ini skui na!</strong>",
-       "editing": "pida smmalu patas $1",
-       "creating": "nii muda phiyug $1",
-       "editingsection": "nii muda smmalu patas $1 ( spugan )",
-       "templatesused": "dmuuy ruwahan patas nii ka truma {{PLURAL:$1| qtaan }}:",
-       "templatesusedpreview": "plealay qmita nii o dmuuy truuma nii{{PLURAL:$1| qtaan pprgun }}:",
+       "showpreview": "Pqita daan qmita",
+       "showdiff": "Kmpriyux pqita",
+       "anoneditwarning": "<strong>Ptqlahang:</strong> Ini su pstmay matas na. Nasi su muda ana manu smmalu patas su ga niqan IP mha wada traun. Nasi su <strong>[$1 pstmay matas]</strong> aji uri o <strong>[$2 phiyug patas sspgan]</strong>, smmalu patas su o saw nnisu mha seejiq mduuy hangan pnskraya, niqan duma ka tgmalu.",
+       "blockedtext": "<strong>Empduuy hangansu aji uri o nniqan IP wada tna shmuk.</strong>\n\nWada su powda $1 hmuk.\nPusu asaw <em>$2</em>.\n\n* Jiyax prajing hmuk: 8\n* Jiyaxqmhdu hmuk: $6\n* Quri hmuk seejiq: $7\n\nMtduwa su mggaluk $1 aji uri o duma ka [[{{MediaWiki:Grouppage-sysop}}|seejiq kmlawa]] pprngaw hmuk ka quri msriquu.\nNasi tna su ga mniq [[Special:Preferences|smkuxul powsa]] kska pha kingal brihan ka gluban patas samaw patas nniqan, aji o ini powda hmuk nabrihan bluban patas samaw, kiya do mtduwa su powda \"{{int:emailuser}}\" ka brihan nii mggaluk quri seejiq kmlawa.\nBitaq saying ka isu ga niqan IP o $3, saw nii hmuk ka ID asaw #$5.\nEniq jiyax sslingan umal patas plxani bi pngkla kari.",
+       "loginreqlink": "pstmay patas",
+       "newarticletext": "Nii su mggaluk bitaq kingal ruwahan patas aji mha ungat ruwahan patas.\nDai phiyug ruwahan patas nii, ga su mniq truma ka smmalu patas qpuruh mangal  kska kari ruwan (leexan balay powda qtaan patas [$1 dmuuy pgkla ruwahan patas]).\nNasi su ini qlahang iyah hini ruwahan patas, powda gmaaw daan qmita ka <strong>embrinah miyah</strong> gluban.",
+       "anontalkpagetext": "----\n<em>Empprngaw ruwahan pusu nii ka ini bqani na phiyug sspgan patas pnskuan pila ka hangan lniing empduuy dmuuy.</em>\nKiya do asi su ka dmuuy ga niqan IP miyah psenak hnigan.\nKiya kaq kiyta ni snruwayan ga niqan IPyaa bipaah lala bi ini pndkaempduuy saw pnspuan dmuuy.\nNasi isu ka hangan lniing empduuy saw lnglungan suu rmngaw qntaan ka kari ruwan ungat pngluban, powda [[Special:CreateAccount|phiyug bgurah Sspgan patas]] aji uri o [[Special:UserLogin|pstmay]] saw aji mha mdka duma mduuy hangan lniing mgamax.",
+       "noarticletext": "Ruwahan patas nii bitaq sayang ungat kari ruwan.\nMtduwa su mniq kska duma ruwahan patas [[Special:Search/{{PAGENAME}}|miying pnskraya ruwahan patas nii]],\n<span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} miying quri jiyax rnisuh patas] aji uri\no [{{fullurl:{{FULLPAGENAME}}|action=edit}} phiyug ruwahan patas nii]</span>.",
+       "noarticletext-nopermission": "Ruwahan patas nii bitaq sayang ungat kari ruwan.\nMtduwa su mniq kska duma ruwahan patas [[Special:Search/{{PAGENAME}}|miying pnskraya ruwahan patas nii]], aji uri o <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} miying quri saw jiyax rnisuh patas]</span>, kiya ka kiya ni ungat su dduy biyax phiyug ruwahan patas nii.",
+       "userpage-userdoesnotexist-view": "Seejiq mduuy patas sspgan \"$1\" ini ppatas na.",
+       "clearyourcache": "<strong>Qlahang:</strong> Ga mnmiq skuun su babaw na do asi su ka srsan daan qmita qngqaya rait bi mangal kika mtduwa qtaan kmpriyux.\n* <strong>Firefox / Safari:</strong> Prci ni <em>Shift</em> 時 gmaaw <em> psbgurah smmalu </em>, aji uri o <em>Ctrl-F5</em> aji uri o <em>Ctrl-R</em> (Mac saw kiya do <em>⌘-R</em>).\n* <strong>Google Chrome:</strong> Prci <em>Ctrl-Shift-R</em> (Mac saw kiya do <em>⌘-Shift-R</em>).\n* <strong>Internet Explorer:</strong> Prci <em>Ctrl</em>, gmaaw <em>Psbgurah smmalu</em>, aji uri o prci <em>Ctrl-F5</em>.\n* <strong>Opera:</strong> Pquri brah <em>Gmaaw → Pha</em> (mniq Mac asaw <em>Opera → smkuxul powsa</em>) babaw na duri o <em>Lniing & aji hhuya → Srsi qmita patas → Wada rait mangal ka patas ni pusu patas</em>.",
+       "previewnote": "<strong>Bitaq saying ni su qtaan.</strong>\nKmpriyux su ini skui na!",
+       "editing": "Pida smmalu patas $1",
+       "creating": "Nii muda phiyug $1",
+       "editingsection": "Nii muda smmalu patas $1 (spugan)",
+       "templatesused": "Dmuuy ruwahan patas nii ka truma {{PLURAL:$1|qtaan}}:",
+       "templatesusedpreview": "Plealay qmita nii o dmuuy truuma nii {{PLURAL:$1|qtaan pprgun}}:",
        "template-protected": "(ga klwaun)",
-       "template-semiprotected": "(Smka bi knlwaan )",
-       "hiddencategories": "nruwahan patas nii {{PLURAL:$1|1 sspug kingal lmiing keelgan |$1 sspug kingal lmiing keelgan}} seejiq :",
-       "permissionserrorstext-withaction": "Saw nii truma {{PLURAL:$1| pusu }}, ungat biyax dduuy su muda $2 ka muda :",
-       "recreate-moveddeleted-warn": "<strong> ptqlahang :nii su psbgurah phiyug brah han o wada srsan ka ruwahan patas. </strong> naa su lmnglungyayaa aji mlutut smmalu patas ruwahan patas nii。 Ga hini mgay snrus ni hdlun jiyax rnisuh patas tai saw msleexan qtaan patas:",
-       "moveddeleted-notice": "ruwahan patas nii wada srsan.\ntruma mgay ruwahan patas nii ka wada srsan ni hdlun jiyax rnisuh patas tai saw qtaan patas.",
+       "template-semiprotected": "(smka bi knlwaan)",
+       "hiddencategories": "Nruwahan patas nii {{PLURAL:$1|$1 sspug kingal lmiing keelgan}} seejiq:",
+       "permissionserrorstext-withaction": "Saw nii truma {{PLURAL:$1|pusu}}, ungat biyax dduuy su muda $2 ka muda:",
+       "recreate-moveddeleted-warn": "<strong>Ptqlahang: Nii su psbgurah phiyug brah han o wada srsan ka ruwahan patas.</strong>\n\nNaa su lmnglungyayaa aji mlutut smmalu patas ruwahan patas nii.\nGa hini mgay snrus ni hdlun jiyax rnisuh patas tai saw msleexan qtaan patas:",
+       "moveddeleted-notice": "Ruwahan patas nii wada srsan.\nTruma mgay ruwahan patas nii ka wada srsan, ni hdlun jiyax rnisuh patas tai saw qtaan patas.",
        "undo-failure": "Paah nii smmalu patas ka muda smalu iyax o niqan mkeekan, smalu patas nii ini tduwa psnbrih.",
-       "viewpagelogs": "pqita ruwahan patas nii ka jiyax rnisuh patas",
+       "viewpagelogs": "Pqita ruwahan patas nii ka jiyax rnisuh patas",
        "currentrev": "Bgurah bi muda smalu",
-       "currentrev-asof": "mniq $1 ka Bgurah bi muda smmalu",
+       "currentrev-asof": "Mniq $1 ka Bgurah bi muda smmalu",
        "revisionasof": "nii $1 ka muda smalu",
-       "revision-info": "mniq $1 paah {{GENDER:$6|$2}} saw muda qmpah smalu $7",
-       "previousrevision": "←muda smmalu brah nii",
-       "nextrevision": "muda smmalu truma nii→",
+       "revision-info": "Mniq $1 paah {{GENDER:$6|$2}} saw muda qmpah smalu $7",
+       "previousrevision": "← Muda smmalu brah nii",
+       "nextrevision": "Muda smmalu truma nii →",
        "currentrevisionlink": "Bgurah bi muda smalu",
        "cur": "bitaq sayang",
        "last": "brah gntuan",
-       "histlegend": "pdkaun gmaaw ka ini pndka patas pusu : asi ka gmaaw pdkaun muda smmalu patas pusu gmaaw kinga qaya duri o gmaaw sulay gluban muda psdka. <br /> pgkla patas pnskraya :<strong>({{int:cur}})</strong> = ni bi pdkaun bgurah muda smmalu patas pusu, <strong>({{int:last}})</strong> = mseupu gntuan brah pdkaun muda smalu patas pusu, <strong>{{int:minoreditletter}}</strong> = smsul na muda smalu",
-       "history-feed-description": "patas Wiki powsa ruwahan patas nii ka endaan muda smmalu",
+       "histlegend": "Pdkaun gmaaw ka ini pndka patas pusu: Asi ka gmaaw pdkaun muda smmalu patas pusu gmaaw kinga qaya duri o gmaaw sulay gluban muda psdka.<br />\nPgkla patas pnskraya: <strong>({{int:cur}})</strong> = ni bi pdkaun bgurah muda smmalu patas pusu, <strong>({{int:last}})</strong> = mseupu gntuan brah pdkaun muda smalu patas pusu, <strong>{{int:minoreditletter}}</strong> = smsul na muda smalu.",
+       "history-feed-description": "Patas Wiki powsa ruwahan patas nii ka endaan muda smmalu",
        "history-feed-item-nocomment": "$1 ga $2",
        "rev-delundel": "kmpriyux mtduwa qtaan",
        "rev-showdeleted": "pqita",
        "pagehist": "endaan ruwahan patas",
        "history-title": "\"$1\" ka endaan muda smalu",
        "difference-title": "\"$1\" muda smmalu siida ka ini kndka",
-       "lineno": "qnay patas $1:",
-       "compareselectedversions": "psdka wada gmaaw ka muda smalu",
+       "lineno": "Qnay patas $1:",
+       "compareselectedversions": "Psdka wada gmaaw ka muda smalu",
        "editundo": "pkbrih",
-       "diff-multi-sameuser": "(ini pqita mdka kingak seejiq mduuy saw qnpahan kska na $1 smsul muda smalu )",
-       "diff-multi-otherusers": "(ini pqita ni paah $2 hnigan empduuy ka ruwam saw q11npahan $1 snsul muda smmalu )",
-       "searchresults-title": "$1 ka miying endaan qmpah",
-       "prevn": "Brah $1 gntuan",
-       "nextn": "Bukuy {{PLURAL:$1|$1}}gntuan",
-       "prevn-title": "brah $1 gntuan endaan qmpah",
-       "nextn-title": "babaw $1 gntuan endaan qmpah",
-       "shown-title": "qtaan kngkingal uwahan patas $1 gntuan endaan qmpah",
-       "viewprevnext": "pqita ($1 {{int:pipe-separator}} $2) ($3)",
-       "searchmenu-exists": "<strong>nii Wiki wada niqan hangan asaw bi \"[[:$1]]\" ka ruwahan patas. </strong> {{PLURAL:$2|0=|aji uri o powda qmita patas duma miying endaan qmpah.}}",
-       "searchmenu-new": "<strong>nii hini Wiki phiyug ruwahan patas \"[[:$1]]\"!</strong>{{PLURAL:$2|0=|powda qtaan patas su pstmay mataska pusu hlayan ka miying endaan qmpah. |aji uri o powda qtaan patas duma miying endaan qmpah. }}",
-       "searchprofile-articles": "kari ruwan ruwahan patas",
-       "searchprofile-images": "knlala samaw psaput",
-       "searchprofile-everything": "kana",
+       "diff-multi-sameuser": "(Ini pqita mdka kingak seejiq mduuy saw qnpahan kska na {{PLURAL:$1|$1}} smsul muda smalu)",
+       "diff-multi-otherusers": "(Ini pqita ni paah {{PLURAL:$2|}}$2 hnigan empduuy ka ruwam saw qnpahan {{PLURAL:$1|}}$1 snsul muda smmalu)",
+       "searchresults-title": "\"$1\" ka miying endaan qmpah",
+       "prevn": "brah {{PLURAL:$1|$1}} gntuan",
+       "nextn": "bukuy {{PLURAL:$1|$1}} gntuan",
+       "prevn-title": "Brah $1 {{PLURAL:$1|gntuan endaan qmpah}}",
+       "nextn-title": "Babaw $1 {{PLURAL:$1|gntuan endaan qmpah}}",
+       "shown-title": "Qtaan kngkingal uwahan patas {{PLURAL:$1|}}$1 gntuan endaan qmpah",
+       "viewprevnext": "Pqita ($1 {{int:pipe-separator}} $2) ($3)",
+       "searchmenu-exists": "<strong>Nii Wiki wada niqan hangan asaw bi \"[[:$1]]\" ka ruwahan patas.</strong> {{PLURAL:$2|0=|Aji uri o powda qmita patas duma miying endaan qmpah.}}",
+       "searchmenu-new": "<strong>Nii hini Wiki phiyug ruwahan patas \"[[:$1]]\"!</strong> {{PLURAL:$2|0=|Powda qtaan patas su pstmay mataska pusu hlayan ka miying endaan qmpah.|Aji uri o powda qtaan patas duma miying endaan qmpah.}}",
+       "searchprofile-articles": "Kari ruwan ruwahan patas",
+       "searchprofile-images": "Knlala samaw psaput",
+       "searchprofile-everything": "Kana",
        "searchprofile-advanced": "Mtmay quri brah",
-       "searchprofile-articles-tooltip": "ga $1 kska miying",
-       "searchprofile-images-tooltip": "miying pusu patas",
-       "searchprofile-everything-tooltip": "miying kana ruwan pntasan ( supu kana pprngagan ruwahan patas )",
-       "searchprofile-advanced-tooltip": "miying iyax ptngahan pnhiyug nanak",
-       "search-result-size": "$1 ({{PLURAL:$2|1 kingal patas |$2 kingal patas }})",
-       "search-result-category-size": "$1 hnigan hiyi ($2 kngkingal spiq keelgan, $3kngkingal pusu patas )",
+       "searchprofile-articles-tooltip": "Ga $1 kska miying",
+       "searchprofile-images-tooltip": "Miying pusu patas",
+       "searchprofile-everything-tooltip": "Miying kana ruwan pntasan (supu kana pprngagan ruwahan patas)",
+       "searchprofile-advanced-tooltip": "Miying iyax ptngahan pnhiyug nanak",
+       "search-result-size": "$1 ({{PLURAL:$2|1 kingal patas|$2 kingal patas}})",
+       "search-result-category-size": "{{PLURAL:$1|$1 hnigan hiyi}} ({{PLURAL:$2|$2 kngkingal spiq keelgan}}, {{PLURAL:$3|$3 kngkingal pusu patas}})",
        "search-redirect": "(brahan dmudul paah $1)",
        "search-section": "(spgan $1)",
        "search-category": "(keelgan $1)",
-       "search-file-match": "( mlngu kari ruwan pusu patas )",
-       "search-suggest": "aji isu ka tmniyu na :$1",
+       "search-file-match": "(mlngu kari ruwan pusu patas)",
+       "search-suggest": "Aji isu ka tmniyu na: $1",
        "search-interwiki-more": "(knlala)",
        "searchall": "kana",
-       "search-showingresults": "{{PLURAL:$4|tg <strong>$1</strong> gntuan endaan qmpah, seupu do <strong>$3</strong> gntuan|tg <strong>$1 - $2</strong> gntuan endaan qmpah, mseupu kana <strong>$3</strong> gntuan}}",
-       "search-nonefound": "ungat mlngu smiling pusu ka endaan qmpah.",
-       "powersearch-toggleall": "kana",
+       "search-showingresults": "{{PLURAL:$4|Tg <strong>$1</strong> gntuan endaan qmpah, seupu do <strong>$3</strong> gntuan|Tg <strong>$1 – $2</strong> gntuan endaan qmpah, mseupu kana <strong>$3</strong> gntuan}}",
+       "search-nonefound": "Ungat mlngu smiling pusu ka endaan qmpah.",
+       "powersearch-toggleall": "Kana",
        "preferences": "Smkuxul bi powsa",
        "mypreferences": "Smkuxul bi powsa",
        "prefs-user-pages": "empduuy ruwahan patas",
        "prefs-rc": "Kmpriyux snii",
        "prefs-watchlist": "Patas leexan gmraka",
        "prefs-editwatchlist-raw": "leexan patas gmraka ida nkiya smmalu patas",
+       "searchresultshead": "Miying",
+       "prefs-searchoptions": "Miying",
        "prefs-namespaces": "iyax ptngahan",
        "prefs-files": "pusu patas",
        "group-user": "Seejiq mduuy",
        "group-all": "(kana)",
        "right-upload": "wada pdsun brah pusu patas",
-       "right-writeapi": "ptasi dmuuy API",
+       "right-writeapi": "Ptasi dmuuy API",
        "grant-createaccount": "phiyug patas sspgan",
-       "newuserlogpage": "phiyug jiyax rnisuh patas seejiq mduuy",
-       "rightslog": "seejiq mduuy biyax kklawa jiyax rnisuh patas",
-       "action-edit": "smmalu patas ruwahan patas nii",
+       "newuserlogpage": "Phiyug jiyax rnisuh patas seejiq mduuy",
+       "rightslog": "Seejiq mduuy biyax kklawa jiyax rnisuh patas",
+       "action-edit": "Smmalu patas ruwahan patas nii",
        "action-createaccount": "phiyug seejiq mduuy patas sspgan nii",
        "action-move": "hdlun ruwahan patas nii",
+       "enhancedrc-history": "endaan",
        "recentchanges": "Kmpriyux snii",
-       "recentchanges-legend": "kmpriyux snii ka gneegan",
-       "recentchanges-summary": "murug Wiki nii kska ruwahan patas ka kmpriyux snii.",
-       "recentchanges-noresult": "mniq kiya kska jiyax ungat mlngu pusu ka kmpriyux",
-       "recentchanges-feed-description": "muurug kska Wiki nii ramas kari kmpriyux snii balay",
-       "recentchanges-label-newpage": "smmalu patas nii o phiyug bgurah ruwahan patas da",
+       "recentchanges-legend": "Kmpriyux snii ka gneegan",
+       "recentchanges-summary": "Murug Wiki nii kska ruwahan patas ka kmpriyux snii.",
+       "recentchanges-noresult": "Mniq kiya kska jiyax ungat mlngu pusu ka kmpriyux.",
+       "recentchanges-feed-description": "Muurug kska Wiki nii ramas kari kmpriyux snii balay.",
+       "recentchanges-label-newpage": "Smmalu patas nii o phiyug bgurah ruwahan patas da",
        "recentchanges-label-minor": "Asaw nii snsul smmalu patas",
-       "recentchanges-label-bot": "smmalu patas nii o  paah seejiq luqi samaw mowda",
-       "recentchanges-label-unpatrolled": "smmalu patas nii o ini dai qmita na",
-       "recentchanges-label-plusminus": "ruwahan patas kmpriyux nii ka prparu ni blbila ( pnspuan wiyiyeyn)",
-       "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (powda qita patas [[Special:NewPages| bgurah ruwahan patas ]])",
+       "recentchanges-label-bot": "Smmalu patas nii o  paah seejiq luqi samaw mowda",
+       "recentchanges-label-unpatrolled": "Smmalu patas nii o ini dai qmita na",
+       "recentchanges-label-plusminus": "Ruwahan patas kmpriyux nii ka prparu ni blbila (pnspuan wiyiyeyn)",
+       "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (powda qita patas [[Special:NewPages|bgurah ruwahan patas]])",
        "recentchanges-submit": "pqita",
-       "rcfilters-tag-remove": "hdlun pkungat '$1'",
+       "rcfilters-tag-remove": "Hdlun pkungat '$1'",
        "rcfilters-activefilters-hide": "lmiying",
        "rcfilters-activefilters-show": "pqita",
-       "rcfilters-days-show-days": "jiyax",
-       "rcfilters-savedqueries-cancel-label": "pkungat",
+       "rcfilters-days-show-days": "$1 {{PLURAL:$1|}}jiyax",
+       "rcfilters-savedqueries-cancel-label": "Pkungat",
        "rcfilters-filtergroup-lastrevision": "Bgurah bi muda smalu",
-       "rcnotefrom": "truma nii {{PLURAL:$5asaw }}hiya nanak <strong>$3 $4</strong> paah na niya kmpriyux (lala bi pqita <strong>$1</strong> gntuan).",
-       "rclistfrom": "pqita paah $3 $2 kmpriyux bgurah siida",
+       "rcnotefrom": "Truma nii {{PLURAL:$5|asaw}} hiya nanak <strong>$3, $4</strong> paah na niya kmpriyux (lala bi pqita <strong>$1</strong> gntuan).",
+       "rclistfrom": "Pqita paah $3, $2 kmpriyux bgurah siida",
        "rcshowhideminor": "$1 smsul smmalu patas",
-       "rcshowhideminor-show": "pqita",
-       "rcshowhideminor-hide": "lmiying",
+       "rcshowhideminor-show": "Pqita",
+       "rcshowhideminor-hide": "Lmiying",
        "rcshowhidebots": "$1 seejiq luqi samaw",
-       "rcshowhidebots-show": "pqita",
-       "rcshowhidebots-hide": "lmiying",
+       "rcshowhidebots-show": "Pqita",
+       "rcshowhidebots-hide": "Lmiying",
        "rcshowhideliu": "$1 wada matas patas ka seejiq mduuy",
-       "rcshowhideliu-show": "pqita",
-       "rcshowhideliu-hide": "lmiying",
+       "rcshowhideliu-show": "Pqita",
+       "rcshowhideliu-hide": "Lmiying",
        "rcshowhideanons": "$1 seejiq mduuy lniing hangan",
-       "rcshowhideanons-show": "pqita",
-       "rcshowhideanons-hide": "lmiying",
+       "rcshowhideanons-show": "Pqita",
+       "rcshowhideanons-hide": "Lmiying",
        "rcshowhidepatr": "$1 rmigaw qmita wada smmalu patas",
        "rcshowhidepatr-show": "pqita",
        "rcshowhidepatr-hide": "lmiying",
        "rcshowhidemine": "$1 smmalu patas nnaku",
-       "rcshowhidemine-show": "pqita",
-       "rcshowhidemine-hide": "lmiying",
+       "rcshowhidemine-show": "Pqita",
+       "rcshowhidemine-hide": "Lmiying",
        "rcshowhidecategorization-show": "pqita",
        "rcshowhidecategorization-hide": "lmiying",
-       "rclinks": "pqita snii $3 $2 snsul kmpriyux siida",
+       "rclinks": "Pqita snii $1, $2 snsul kmpriyux siida",
        "hist": "endaan",
-       "hide": "lmiying",
-       "show": "pqita",
-       "minoreditletter": "bilaq",
-       "newpageletter": "bgurah",
-       "boteditletter": "qaya",
-       "rc-change-size-new": "babaw kmpriyux $1 pnspuan wiyeyn",
-       "rc-old-title": "Plealay bi  phiyug ka hangan asaw bi \"$1\"",
-       "recentchangeslinked": "kmpriyux quri",
-       "recentchangeslinked-feed": "kmpriyux quri",
-       "recentchangeslinked-toolbox": "kmpriyux quri",
-       "recentchangeslinked-title": "mseupu \"$1\" quri ka kmpriyux",
-       "recentchangeslinked-page": "hangan ruwahan patas:",
-       "recentchangeslinked-to": "kmpriyux pqita mgaluk bitaq tniyu ruwahan patas ka kmpriyux",
-       "upload": "wada pdsun brah pusu patas",
-       "filedesc": "ramas kari",
+       "hide": "Lmiying",
+       "show": "Pqita",
+       "minoreditletter": "bi",
+       "newpageletter": "Bg",
+       "boteditletter": "qa",
+       "rc-change-size-new": "Babaw kmpriyux {{PLURAL:$1|}}$1 pnspuan wiyeyn",
+       "rc-old-title": "plealay bi  phiyug ka hangan asaw bi \"$1\"",
+       "recentchangeslinked": "Kmpriyux quri",
+       "recentchangeslinked-feed": "Kmpriyux quri",
+       "recentchangeslinked-toolbox": "Kmpriyux quri",
+       "recentchangeslinked-title": "Mseupu \"$1\" quri ka kmpriyux",
+       "recentchangeslinked-page": "Hangan ruwahan patas:",
+       "recentchangeslinked-to": "Kmpriyux pqita mgaluk bitaq tniyu ruwahan patas ka kmpriyux",
+       "upload": "Wada pdsun brah pusu patas",
+       "filedesc": "Ramas kari",
        "filesource": "pnyahan:",
        "upload-dialog-title": "wada pdsun brah pusu patas",
-       "upload-dialog-button-cancel": "pkungat",
+       "upload-dialog-button-cancel": "Pkungat",
        "upload-form-label-infoform-description": "Pgkla rmngaw",
        "upload-form-label-infoform-categories": "keelgan",
        "upload-form-label-infoform-date": "jiyax",
-       "license": "gaya mgay biyax kklawa:",
-       "license-header": "gaya mgay biyax kklawa",
+       "license": "Gaya mgay biyax kklawa:",
+       "license-header": "Gaya mgay biyax kklawa",
        "listfiles-userdoesnotexist": "seejiq mduuy patas sspgan \"$1\" ini ppatas na.",
        "imgfile": "pusu patas",
        "listfiles_thumb": "patas snblaqan",
        "listfiles_date": "jiyax",
        "listfiles_user": "Seejiq mduuy",
        "listfiles_description": "Pgkla rmngaw",
-       "file-anchor-link": "pusu patas",
-       "filehist": "endaan pusu patas",
-       "filehist-help": "gmaaw jiyax /saw jiyax pqita jiyax siida ka pusu patas.",
+       "file-anchor-link": "Pusu patas",
+       "filehist": "Endaan pusu patas",
+       "filehist-help": "Gmaaw jiyax/saw jiyax pqita jiyax siida ka pusu patas.",
        "filehist-current": "sayang",
-       "filehist-datetime": "jiyax / jiyax",
-       "filehist-thumb": "patas snblaqan",
-       "filehist-thumbtext": "nii $1 patas pusu ka patas snblaqan",
+       "filehist-datetime": "Jiyax/Jiyax",
+       "filehist-thumb": "Patas snblaqan",
+       "filehist-thumbtext": "Nii $1 patas pusu ka patas snblaqan",
        "filehist-user": "Seejiq mduuy",
-       "filehist-dimensions": "sspngan knbragan",
-       "filehist-comment": "patas numal pgkla",
-       "imagelinks": "djiyun pusu patas",
-       "linkstoimage-more": "mgkala $1 kngkingal{{PLURAL:$1| mggaluk ruwahan patas | mggaluk ruwahan patas }}bitaq hini pusu patas. leexan bi trumanii o wana pteeura brah {{PLURAL:$1|1 gntuan mggaluk |$1 gntuan mggaluk }}bitaq hin i pusu patas ka ruwahan patas ka pusu patas. mtduwa su uri pqita  [[Special:WhatLinksHere/$2| mttuku  leexan patas ]].",
-       "linkstoimage-redirect": "$1 (brahan muda pusu patas ) $2",
-       "sharedupload-desc-here": "pusu patas nii o pnaah $1 duri ni yaa bi wada jiyun duma saw pusu qpahun.\npnqita truma pusu patasnii ga [$2 pgkla pusu patas saw seerngaw ruwahan patas ] ka ruwan rnngaw kari",
-       "filepage-nofile": "ungat hangan nii ka pusu patas.",
-       "upload-disallowed-here": "ungat klaan su mubung pusu patas nii.",
-       "randompage": "ruwahan patas hmut dsdsun.",
+       "filehist-dimensions": "Sspngan knbragan",
+       "filehist-comment": "Patas numal pgkla",
+       "imagelinks": "Djiyun pusu patas",
+       "linkstoimage-more": "Mgkala $1 {{PLURAL:$1|kngkingal mggaluk ruwahan patas}} bitaq hini pusu patas.\nLeexan bi trumanii o wana pteeura brah $1 {{PLURAL:$1|gntuan mggaluk}} bitaq hin i pusu patas ka ruwahan patas ka pusu patas.\nMtduwa su uri pqita [[Special:WhatLinksHere/$2|mttuku leexan patas]].",
+       "linkstoimage-redirect": "$1 (brahan muda pusu patas) $2",
+       "sharedupload-desc-here": "Pusu patas nii o pnaah $1 duri ni yaa bi wada jiyun duma saw pusu qpahun.\nPnqita truma pusu patasnii ga [$2 pgkla pusu patas saw seerngaw ruwahan patas] ka ruwan rnngaw kari.",
+       "filepage-nofile": "Ungat hangan nii ka pusu patas.",
+       "upload-disallowed-here": "Ungat klaan su mubung pusu patas nii.",
+       "randompage": "Ruwahan patas hmut dsdsun.",
        "randomincategory": "ruwahan patas hmut dsdsun.",
        "randomincategory-submit": "muda",
-       "statistics-articles": "kari ruwan ruwahan patas",
+       "statistics-articles": "Kari ruwan ruwahan patas",
        "pageswithprop-submit": "muda",
        "double-redirect-fixer": "Psbgurah muda seejiq muda smalu",
        "brokenredirects-edit": "smmalu patas",
        "withoutinterwiki-submit": "pqita",
-       "nbytes": "$1 sspug kingal pnspuan wiyeyn",
+       "nbytes": "$1 {{PLURAL:$1|sspug kingal pnspuan wiyeyn}}",
        "ncategories": "$1 {{PLURAL:$1| keelgan |$1 sspug kingal keelgan }}",
-       "nmembers": "$1 seejiq sspug hiyi",
+       "nmembers": "$1 {{PLURAL:$1|seejiq sspug hiyi}}",
        "prefixindex": "Purug saw plealay kari smiling ruwahan patas",
        "prefixindex-submit": "pqita",
        "protectedpages-noredirect": "brahan muuda lniing ruwahan patas",
        "protectedpages-page": "ruwahan patas",
        "usereditcount": "$1 {{PLURAL:$1|smsul smmalu patas }}",
-       "newpages": "bgurah ruwahan patas",
+       "newpages": "Bgurah ruwahan patas",
        "newpages-submit": "pqita",
        "newpages-username": "seejiq mduuy hangan:",
-       "move": "hdlun",
+       "move": "Hdlun",
        "movethispage": "hdlun ruwahan patas nii",
-       "pager-newer-n": "{PLURAL:$1| bgurah hari $1 gntuan}}",
-       "pager-older-n": "smudal hari $1 gntuan",
+       "pager-newer-n": "{{PLURAL:$1|bgurah hari gntuan|bgurah hari $1 gntuan}}",
+       "pager-older-n": "{{PLURAL:$1|smudal hari gntuan|smudal hari $1 gntuan}}",
        "apisandbox-add-multi": "Mrana bgurah",
-       "booksources": "patas pnyahan",
-       "booksources-search-legend": "miying pnyahan patas",
-       "speciallogtitlelabel": "Saw dngusun( pusu kari aji uri o {{ns:user}}: seejiq mduuy pnqita seejiq mduuy):",
+       "booksources": "Patas pnyahan",
+       "booksources-search-legend": "Miying pnyahan patas",
+       "booksources-search": "Miying",
+       "speciallogtitlelabel": "Saw dngusun (pusu kari aji uri o {{ns:user}}: seejiq mduuy pnqita seejiq mduuy):",
        "log": "Jiyax rnisuh patas",
        "logeventslist-submit": "pqita",
-       "alllogstext": "pspuun pqita kana {{SITENAME}} kaka mdka hnigan kana ka jiyax rnisuh patas. mtduwa su gmaaw blbil quri truma patas gnaaw jiyax rnisuh patas ka mdka hnigan, kiya ka hangan mduuy (patas pnsnakan paru ni blbilq) aji uri o dmayak ruwahan patas (patas pnsnakan paru ni blbilq)",
-       "logempty": "ungat mlngu pusu ka jiyax rnisuh patas.",
-       "checkbox-all": "kana",
-       "allpages": "kana ruwahan patas",
-       "allarticles": "kana ruwahan patas",
-       "allpagessubmit": "muda",
-       "allpages-hide-redirects": "brahan muuda lniing ruwahan patas",
-       "categories": "keelgan",
+       "alllogstext": "Pspuun pqita kana {{SITENAME}} kaka mdka hnigan kana ka jiyax rnisuh patas.\nMtduwa su gmaaw blbil quri truma patas gnaaw jiyax rnisuh patas ka mdka hnigan, kiya ka hangan mduuy (patas pnsnakan paru ni blbilq) aji uri o dmayak ruwahan patas (patas pnsnakan paru ni blbilq).",
+       "logempty": "Ungat mlngu pusu ka jiyax rnisuh patas.",
+       "checkbox-all": "Kana",
+       "allpages": "Kana ruwahan patas",
+       "allarticles": "Kana ruwahan patas",
+       "allpagessubmit": "Muda",
+       "allpages-hide-redirects": "Brahan muuda lniing ruwahan patas",
+       "categories": "Keelgan",
        "categories-submit": "pqita",
        "sp-deletedcontributions-contribs": "suyang qnpahan",
        "linksearch-ns": "iyax ptngahan:",
+       "linksearch-ok": "Miying",
        "listusers-submit": "pqita",
        "emailuser": "Email mggaluk seejiq mduuy nii",
        "emailusername": "seejiq mduuy hangan:",
        "mywatchlist": "Patas leexan gmraka",
        "watchlistfor2": "$1 ka leexan patas gmraka $2",
        "watchthispage": "Gmraka qmita ruwahan patas nii",
-       "watchlist-details": "leexan patas gmraka su mseupu kana o niqan $1 kngkingal ruwahan patas(supu kana pprngaw ruwahan patas).",
-       "wlheader-showupdated": "Ga su mniq tnhici bi kingal babaw qmita wada kmpriyux smalu ruwahan patas mha saw muda <strong> patas qthur </strong> pqita.",
-       "wlnote": "Truma nii asaw paah $3 $4 brah na <strong>$2</strong> kska iyax tuki snluuan <strong>$1</strong> snsul kmpriyux.",
-       "wlshowlast": "pqita snii $1 iyax tuki $2 jiyax",
+       "watchlist-details": "Leexan patas gmraka su mseupu kana o niqan {{PLURAL:$1|$1 kngkingal ruwahan patas}} (supu kana pprngaw ruwahan patas).",
+       "wlheader-showupdated": "Ga su mniq tnhici bi kingal babaw qmita wada kmpriyux smalu ruwahan patas mha saw muda <strong>patas qthur</strong> pqita.",
+       "wlnote": "Truma nii asaw paah $3 $4 brah na {{PLURAL:$2|<strong>$2</strong> kska iyax}} tuki snluuan {{PLURAL:$1|<strong>$1</strong> snsul kmpriyux}}.",
+       "wlshowlast": "Pqita snii $1 {{PLURAL:$1|iyax}} tuki $2 {{PLURAL:$2|jiyax}}",
        "watchlist-hide": "lmiying",
        "watchlist-submit": "pqita",
-       "enotif_reset": "pnskraya kana ruwahan patas asaw wada pqita",
+       "enotif_reset": "Pnskraya kana ruwahan patas asaw wada pqita",
        "enotif_minoredit": "Asaw nii snsul smmalu patas",
-       "historyaction-submit": "pqita",
+       "historyaction-submit": "Pqita",
        "dellogpage": "Srsi jiyax rnisuh patas",
        "deletionlog": "Srsi jiyax rnisuh patas",
        "rollbacklink": "gbrih duri",
-       "rollbacklinkcount": "psnbrih $1 smsul smmalu patas",
-       "protectlogpage": "kmlawa jiyax rnisuh matas",
-       "protectedarticle": "kmlawa \"[[$1]]\"",
+       "rollbacklinkcount": "psnbrih $1 {{PLURAL:$1|smsul smmalu patas}}",
+       "protectlogpage": "Kmlawa jiyax rnisuh matas",
+       "protectedarticle": "Kmlawa \"[[$1]]\"",
        "modifiedarticleprotection": "Wada psbgurah smmalu \"[[$1]]\" ka kmlawa knparu hnigan",
-       "protect-default": "mtduwa kana ka nduuy",
+       "protect-default": "Mtduwa kana ka nduuy",
        "restriction-type": "mgay biyax kklawa snruwaan:",
-       "restriction-edit": "smmalu patas",
-       "restriction-move": "hdlun",
+       "restriction-edit": "Smmalu patas",
+       "restriction-move": "Hdlun",
+       "undeleteviewlink": "qmita",
        "undeleteinvert": "mspgriq embrinah gmaaw",
-       "namespace": "iyax ptngahan:",
-       "invert": "mspgriq embrinah gmaaw",
-       "tooltip-invert": "geegi gmaaw qpuruh nii, saw kska lmiing gmaaw iyax ptngahan ruwahan patas kmpriyux (nasi gneegan quri iyax ptngahan, aji saw kiya do jiyax siida lmiing quri iyax ptngahan )",
-       "namespace_association": "quri iyax ptngahan",
-       "tooltip-namespace_association": "geegi nii ka gmaaw saw patas 4 muhing supu kana ni gmaaw iyax ptngahan quri ka empprngaw aji uri o iyax ptngahan pusu kari",
-       "blanknamespace": "( pusu bi )",
-       "contributions": "{{GENDER:$1| empduuy }} suyang qnpahan",
+       "undelete-search-submit": "Miying",
+       "namespace": "Iyax ptngahan:",
+       "invert": "Mspgriq embrinah gmaaw",
+       "tooltip-invert": "Geegi gmaaw qpuruh nii, saw kska lmiing gmaaw iyax ptngahan ruwahan patas kmpriyux (nasi gneegan quri iyax ptngahan, aji saw kiya do jiyax siida lmiing quri iyax ptngahan)",
+       "namespace_association": "Quri iyax ptngahan",
+       "tooltip-namespace_association": "Geegi nii ka gmaaw saw patas 4 muhing supu kana ni gmaaw iyax ptngahan quri ka empprngaw aji uri o iyax ptngahan pusu kari",
+       "blanknamespace": "(pusu bi)",
+       "contributions": "{{GENDER:$1|Empduuy}} suyang qnpahan",
        "contributions-title": "$1 ka seejiq mduuy suyang qnpahan",
-       "mycontris": "suyang qnpahan",
-       "contribsub2": "{{GENDER:$3|$1}}ka suyang qnpahan ($2)",
+       "mycontris": "Suyang qnpahan",
+       "anoncontribs": "Suyang qnpahan",
+       "contribsub2": "{{GENDER:$3|$1}} ka suyang qnpahan ($2)",
        "contributions-userdoesnotexist": "seejiq mduuy patas sspgan \"$1\" ini ppatas na.",
-       "nocontribs": "ini hjiyal pusu mlngu kaq kmpriyux.",
+       "nocontribs": "Ini hjiyal pusu mlngu kaq kmpriyux.",
        "uctop": "sayang",
-       "month": "jiyax nhdaan kngkingal idas :",
-       "year": "jiyax bitaq hngkawas :",
+       "month": "Jiyax nhdaan kngkingal idas:",
+       "year": "Jiyax bitaq hngkawas:",
        "sp-contributions-newbies": "Wana pqita bgurah sspgan patas ka suyang qnpahan",
        "sp-contributions-blocklog": "hmuk jiyax rnisuh patas",
-       "sp-contributions-logs": "Jiyax rnisuh patas",
+       "sp-contributions-uploads": "",
+       "sp-contributions-logs": "jiyax rnisuh patas",
        "sp-contributions-talk": "empprngaw",
-       "sp-contributions-username": "nniqan IP aji uri o seejiq mduuy hangan :",
-       "sp-contributions-toponly": "wana pqita bgurah bi muda smalu ka smmalu patas",
-       "sp-contributions-newonly": "wana pqita phiyug ruwahan patas ka smmalu patas",
+       "sp-contributions-username": "Nniqan IP aji uri o seejiq mduuy hangan!",
+       "sp-contributions-toponly": "Wana pqita bgurah bi muda smalu ka smmalu patas",
+       "sp-contributions-newonly": "Wana pqita phiyug ruwahan patas ka smmalu patas",
+       "sp-contributions-submit": "Miying",
        "whatlinkshere": "Mggaluk bitaq ruwahan patas nii",
-       "whatlinkshere-title": "mgaluk bitaq \"$1\" ka ruwahan patas",
-       "whatlinkshere-page": "ruwahan patas:",
+       "whatlinkshere-title": "Mgaluk bitaq \"$1\" ka ruwahan patas",
+       "whatlinkshere-page": "Ruwahan patas:",
        "isredirect": "psbgurah muda ruwahan patas",
        "istemplate": "dmuuy",
        "isimage": "mggaluk pusu patas",
-       "whatlinkshere-prev": "brah $1gntuan",
+       "whatlinkshere-prev": "{{PLURAL:$1|brah gntuan|brah $1 gntuan}}",
        "whatlinkshere-next": "{{PLURAL:$1|truma gntuan|babaw na $1 gntuan}}",
-       "whatlinkshere-links": "←mggaluk",
+       "whatlinkshere-links": "← mggaluk",
        "whatlinkshere-hideredirs": "$1 psbgurah muda",
        "whatlinkshere-hidetrans": "$1 dmuuy",
        "whatlinkshere-hidelinks": "$1 mggaluk",
-       "whatlinkshere-hideimages": "$1 mggaluk pusu patas",
+       "whatlinkshere-hideimages": "$1 {{PLURAL:$1|mggaluk pusu patas}}",
        "whatlinkshere-submit": "muda",
        "ipaddressorusername": "nniqan IP aji uri o seejiq mduuy hangan :",
-       "ipboptions": "2:2 iyax tuki 2 hours,,1 jiyax:1 day,3 jiyax:3 days,1 iyax sngyan:1 week,2 iyax sngyan:2 weeks,1 idas:1 month,3 idas:3 months,6 idas:6 months,1 hngkawas:1 year, ungat nhdaan :infinite",
+       "ipboptions": "2 iyax tuki:2 hours,1 jiyax:1 day,3 jiyax:3 days,1 iyax sngyan:1 week,2 iyax sngyan:2 weeks,1 idas:1 month,3 idas:3 months,6 idas:6 months,1 hngkawas:1 year,ungat nhdaan:infinite",
        "ipb-pages-label": "ruwahan patas",
        "ipb-namespaces-label": "iyax ptngahan",
+       "autoblocklist-submit": "Miying",
+       "ipblocklist-submit": "Miying",
        "createaccountblock": "phiyug tndu dmuuy patas sspgan",
        "blocklist-editing-ns": "iyax ptngahan",
-       "blocklink": "hmuk",
-       "contribslink": "suyang qnpahan",
-       "blocklogpage": "hmuk jiyax rnisuh patas",
-       "blocklogentry": "wada shmuk [[$1]] ka",
+       "blocklink": "Hmuk",
+       "contribslink": "Suyang qnpahan",
+       "blocklogpage": "Hmuk jiyax rnisuh patas",
+       "blocklogentry": "Wada shmuk [[$1]] ka ''(with an expiration time of $2 $3)''",
        "reblock-logentry": "kmpriyux [[$1]] ka jiyax hmuk nhdaan jiyaxbitaq $2 $3",
        "block-log-flags-nocreate": "phiyug tndu dmuuy patas sspgan",
-       "proxyblocker": "pririh hmuk qaya suhuci",
+       "proxyblocker": "Pririh hmuk qaya suhuci",
        "move-page": "hdlun $1",
-       "movelogpage": "hdlun jiyax rnisuh patas",
-       "export": "wada paadas ruwahan patas",
-       "allmessages-filter-all": "kana",
-       "thumbnail-more": "pkparu",
-       "import-comment": "patas numal pgkla:",
+       "movelogpage": "Hdlun jiyax rnisuh patas",
+       "export": "Wada paadas ruwahan patas",
+       "allmessages-filter-all": "Kana",
+       "thumbnail-more": "Pkparu",
+       "import-comment": "Patas numal pgkla:",
        "tooltip-pt-userpage": "{{GENDER:| seejiq mduuy }} ruwahan patas su",
-       "tooltip-pt-mytalk": "{{GENDER:|su}} empprngaw ruwahan patas",
-       "tooltip-pt-preferences": "{{GENDER:|su}} smkuxul powsa",
-       "tooltip-pt-watchlist": "pida sugmraka kmpriyux ka ruwahan patas leexan patas\n( nasi niqan duma wada muda smnalu ruwahan patas (patas bnkgan), nii ruwahan patas mtduwa mniq mkug spgan brah wada miyah pqita.\npusu kari nii o:pida su pqita niqan wada psbgurah smmalu ruwahan patas ka mkug snpgan. )",
-       "tooltip-pt-mycontris": "{GENDER:|su}} suyang qnpahan leexan patas",
-       "tooltip-pt-login": "pstmay patas han msa dmdug rmngaw sunan , kiya ni aji ida saw kiya.",
-       "tooltip-pt-logout": "latat",
-       "tooltip-pt-createaccount": "Mha name dmudug sunan phiyug patas sspgan. Kiya o pstmay matas, ana yaa asi ka ka muda",
+       "tooltip-pt-mytalk": "{{GENDER:|Su}} empprngaw ruwahan patas",
+       "tooltip-pt-preferences": "{{GENDER:|Su}} smkuxul powsa",
+       "tooltip-pt-watchlist": "Pida sugmraka kmpriyux ka ruwahan patas leexan patas",
+       "tooltip-pt-mycontris": "{{GENDER:|Su}} suyang qnpahan leexan patas",
+       "tooltip-pt-login": "Pstmay patas han msa dmdug rmngaw sunan, kiya ni aji ida saw kiya",
+       "tooltip-pt-logout": "Latat",
+       "tooltip-pt-createaccount": "Mha name dmudug sunan phiyug patas sspgan; kiya o pstmay matas, ana yaa asi ka ka muda",
        "tooltip-ca-talk": "Empprngaw quri ruwan ruwahan patas",
-       "tooltip-ca-edit": "smmalu patas ruwahan patas nii",
-       "tooltip-ca-addsection": "prajing bgurah spugan",
-       "tooltip-ca-viewsource": "ruwahan patas nii wada kmlawa. sunan mtduwa qmita ruwahan patas sspgan nii",
-       "tooltip-ca-history": "ruwahan patas nii o wada psmuun smmalu da",
-       "tooltip-ca-move": "hdlun ruwahan patas nii",
-       "tooltip-ca-watch": "ngali ka ruwahan patas nii mali leexan patas gmraka su.",
-       "tooltip-ca-unwatch": "ruwahan patas nii paah leexan patas gmraka kska hdlun pkungat",
-       "tooltip-search": "miying {{SITENAME}}",
-       "tooltip-search-go": "Nasi niqan mndka hangan nii ka ruwahan patas o naa mquri ruwahan patas nii.",
-       "tooltip-search-fulltext": "miying dmuuy su patas nii ka ruwahan patas.",
-       "tooltip-p-logo": "pquri ruwahan patas pusu",
-       "tooltip-n-mainpage": "pquri ruwahan patas pusu",
-       "tooltip-n-mainpage-description": "pquri ruwahan patas pusu",
-       "tooltip-n-portal": "quri pusu qpahun, mtduwa su qmpah manu, inu ka mtduwa hlayan au smulu ka qaya nii",
-       "tooltip-n-currentevents": "ga kska pnsaput kari hlayan quri patas bukuy",
-       "tooltip-n-recentchanges": "kmpriyux patas leexamn snii ka Wiki nii o peiyah patas na.",
+       "tooltip-ca-edit": "Smmalu patas ruwahan patas nii",
+       "tooltip-ca-addsection": "Prajing bgurah spugan",
+       "tooltip-ca-viewsource": "Ruwahan patas nii wada kmlawa.\nSunan mtduwa qmita ruwahan patas sspgan nii.",
+       "tooltip-ca-history": "Ruwahan patas nii o wada psmuun smmalu da",
+       "tooltip-ca-move": "Hdlun ruwahan patas nii",
+       "tooltip-ca-watch": "Ngali ka ruwahan patas nii mali leexan patas gmraka su.",
+       "tooltip-ca-unwatch": "Ruwahan patas nii paah leexan patas gmraka kska hdlun pkungat",
+       "tooltip-search": "Miying {{SITENAME}}",
+       "tooltip-search-go": "Nasi niqan mndka hangan nii ka ruwahan patas o naa mquri ruwahan patas nii",
+       "tooltip-search-fulltext": "Miying dmuuy su patas nii ka ruwahan patas",
+       "tooltip-p-logo": "Pquri ruwahan patas pusu",
+       "tooltip-n-mainpage": "Pquri ruwahan patas pusu",
+       "tooltip-n-mainpage-description": "Pquri ruwahan patas pusu",
+       "tooltip-n-portal": "Quri pusu qpahun, mtduwa su qmpah manu, inu ka mtduwa hlayan au smulu ka qaya nii",
+       "tooltip-n-currentevents": "Ga kska pnsaput kari hlayan quri patas bukuy",
+       "tooltip-n-recentchanges": "Kmpriyux patas leexamn snii ka Wiki nii o peiyah patas na.",
        "tooltip-n-randompage": "Hmut ana knuwan mtmay kingal ruwahan patas",
        "tooltip-n-help": "Miying meysa ddjyagan",
-       "tooltip-t-whatlinkshere": "ngali patas kana ka mggaluk ruwahan patas nii ka ruwan patas.",
-       "tooltip-t-recentchangeslinked": "kmpriyux snii ka mggaluk ruwahan patas nii bitaq duma na ruwahan pataskpriyux snii",
+       "tooltip-t-whatlinkshere": "Ngali patas kana ka mggaluk ruwahan patas nii ka ruwan patas",
+       "tooltip-t-recentchangeslinked": "Kmpriyux snii ka mggaluk ruwahan patas nii bitaq duma na ruwahan pataskpriyux snii",
        "tooltip-feed-atom": "ruwahan patas nii ka Atom pnyahan",
-       "tooltip-t-contributions": "{{GENDER:$1| seejiq mduuy nii }}ka leexan patas suyang qnpahan",
-       "tooltip-t-emailuser": "peadas mggaluk {{ gluban patas samaw GENDER:$1| seejiq mduuy nii }}",
-       "tooltip-t-upload": "wada pdsun brah pusu patas",
-       "tooltip-t-specialpages": "patas kana leexan qmita ruwahan patas pnseanak",
-       "tooltip-t-print": "peiyah patas na ka ruwahan patas nii",
-       "tooltip-t-permalink": "ruwahan patas ka muda smmalu ini klglug mggaluk\n(mgdhug mggaluk /ana bitaq knuwan mggaluk )",
-       "tooltip-ca-nstab-main": "qmita ruwan ruwahan patas.",
-       "tooltip-ca-nstab-user": "pqita empduuy ruwahan patas",
-       "tooltip-ca-nstab-special": "ruwahan patas nii asaw knmalu ruwahan patas, ungat klaan smmalu patas",
-       "tooltip-ca-nstab-project": "pqita pusu qpahun ruwahan patas",
-       "tooltip-ca-nstab-image": "qmita pusu patas ruwahan patas",
-       "tooltip-ca-nstab-mediawiki": "pqita daan kari pngkla",
-       "tooltip-ca-nstab-template": "pqita qtaan",
+       "tooltip-t-contributions": "{{GENDER:$1|Seejiq mduuy nii}} ka leexan patas suyang qnpahan",
+       "tooltip-t-emailuser": "Peadas mggaluk gluban patas samaw {{GENDER:$1|seejiq mduuy nii}}",
+       "tooltip-t-upload": "Wada pdsun brah pusu patas",
+       "tooltip-t-specialpages": "Patas kana leexan qmita ruwahan patas pnseanak",
+       "tooltip-t-print": "Piyah patas na ka ruwahan patas nii",
+       "tooltip-t-permalink": "Ruwahan patas ka muda smmalu ini klglug mggaluk",
+       "tooltip-ca-nstab-main": "Qmita ruwan ruwahan patas.",
+       "tooltip-ca-nstab-user": "Pqita empduuy ruwahan patas",
+       "tooltip-ca-nstab-special": "Ruwahan patas nii asaw knmalu ruwahan patas, ungat klaan smmalu patas",
+       "tooltip-ca-nstab-project": "Pqita pusu qpahun ruwahan patas",
+       "tooltip-ca-nstab-image": "Qmita pusu patas ruwahan patas",
+       "tooltip-ca-nstab-mediawiki": "Pqita daan kari pngkla",
+       "tooltip-ca-nstab-template": "Pqita qtaan",
        "tooltip-ca-nstab-category": "Muda qmitaa keelgan ruwahan patas",
-       "tooltip-minoredit": "pnskraya muda saw nii jiyax  snsul smmalu patas",
-       "tooltip-save": "smku kmpriyux su",
-       "tooltip-preview": "Powda ga brah smku qmita sunan kmpriyux",
-       "tooltip-diff": "pqita su quri saw kmpriyux ruwan",
+       "tooltip-minoredit": "Pnskraya muda saw nii jiyax  snsul smmalu patas",
+       "tooltip-save": "Smku kmpriyux su",
+       "tooltip-preview": "Powda ga brah smku qmita sunan kmpriyux.",
+       "tooltip-diff": "Pqita su quri saw kmpriyux ruwan",
        "tooltip-compareselectedversions": "Qtai paah ruwahan patas nii, 2 ka wada gmaaw ka muda smmalu iyax ini kndka",
-       "tooltip-watch": "ngali ka ruwahan patas nii mali leexan patas gmraka su.",
-       "tooltip-rollback": "gmaaw \" psnbrih \" kiya o mggaluk mtduwa psnbrih bitaq kingal brah seejiq suyang qnpahan quri saw nii ruwahan patas ka smmalu patas",
-       "tooltip-undo": "\" psnbrih \" mtduwa psnbrih smmalu patas nii kiya o qtaan plealay ruwahan smmalu patas lblak patas, mtduwa powda sunan mniq ramas kari kska teumal pusu.",
+       "tooltip-watch": "Ngali ka ruwahan patas nii mali leexan patas gmraka su.",
+       "tooltip-rollback": "Gmaaw \"psnbrih\" kiya o mggaluk mtduwa psnbrih bitaq kingal brah seejiq suyang qnpahan quri saw nii ruwahan patas ka smmalu patas",
+       "tooltip-undo": "\"Psnbrih\" mtduwa psnbrih smmalu patas nii kiya o qtaan plealay ruwahan smmalu patas lblak patas. Mtduwa powda sunan mniq ramas kari kska teumal pusu.",
        "tooltip-summary": "Powda pstmay matas ramas kari",
-       "simpleantispam-label": "Qlhangi pnegkla enlaxan dmuuy pqita.\npowda <strong>aji</strong> ptasi iyax ptasan nii!",
-       "pageinfo-default-sort": "gnama psbkug euda:",
-       "pageinfo-length": "knbragan ruwahan patas ( pnspuan wiyeyn )",
-       "pageinfo-robot-policy": "paah seejiq luqi samaw phiyug patas pnslbu",
-       "pageinfo-few-watchers": "bilaq na $1 seejiq gmraka",
+       "simpleantispam-label": "Qlhangi pnegkla enlaxan dmuuy pqita.\nPowda <strong>aji</strong> ptasi iyax ptasan nii!",
+       "pageinfo-title": "Quri \"$1\"",
+       "pageinfo-default-sort": "Gnama psbkug euda",
+       "pageinfo-length": "Knbragan ruwahan patas (pnspuan wiyeyn)",
+       "pageinfo-robot-policy": "Paah seejiq luqi samaw phiyug patas pnslbu",
+       "pageinfo-few-watchers": "Bilaq na {{PLURAL:$1|$1 seejiq gmraka}}",
        "pageinfo-redirects-name": "Ciyu paah ruwahan patas hini ka psbgurah muda knlala ruwahan patas",
-       "pageinfo-subpages-name": "ruwahan patas nii ka sspug ruwahan patas",
-       "pageinfo-subpages-value": "1 ($2 kngkingal{{PLURAL:$2| brahan muda }}; $3 kngkingal{{PLURAL:$3|aji brahan mudal }})",
+       "pageinfo-subpages-name": "Ruwahan patas nii ka sspug ruwahan patas",
+       "pageinfo-subpages-value": "$1 ($2 kngkingal {{PLURAL:$2|brahan muda}}; $3 kngkingal {{PLURAL:$3|aji brahan mudal}})",
        "pageinfo-recent-edits": "s mnpiya ka smmalu patas snii bi (endaan $1 ruwan)",
-       "pageinfo-magic-words": "psteutux {{PLURAL:$1| patas  }} ($1)",
-       "pageinfo-hidden-categories": "Keelgan lmiing ($1)",
-       "pageinfo-templates": "dmuuy qaya qtaan ($1)",
+       "pageinfo-magic-words": "Psteutux {{PLURAL:$1|patas}} ($1)",
+       "pageinfo-hidden-categories": "{{PLURAL:$1|Keelgan lmiing}} ($1)",
+       "pageinfo-templates": "{{PLURAL:$1|Dmuuy qaya qtaan}} ($1)",
        "pageinfo-toolboxlink": "Kari patas ruwahan patas",
        "pageinfo-contentpage": "Saw endaan kari ruwan ppspug ruwahan patas",
-       "previousdiff": "←smudal hari smmalu patas",
-       "nextdiff": "smmalu patas snii→",
-       "widthheightpage": "$1 × $2, $3 ruwahan patas",
-       "file-info-size": "$1 × $2 patas hnigan, pusu patas prparu ni blbila :$3, MIME mdka hnigan :$4",
-       "file-info-size-pages": "$1 × $2 patas hnigan, pusu patas prparu ni blbila :$3, MIME keelgan hnigan :$4, $5 {{PLURAL:$5| ruwahan patas }}",
-       "file-nohires": "umtduwa mgay ngat mndka msleexan qtaan.",
-       "svg-long-desc": "SVG pusu patas, lipax prparu ni blbila:$1 × $2 patas hnigan, pusu patas prparu ni blbila:$3",
+       "pageinfo-contentpage-yes": "Kiya",
+       "previousdiff": "← Smudal hari smmalu patas",
+       "nextdiff": "Smmalu patas snii →",
+       "widthheightpage": "$1 × $2, $3 {{PLURAL:$3|ruwahan patas}}",
+       "file-info-size": "$1 × $2 patas hnigan, pusu patas prparu ni blbila: $3, MIME mdka hnigan: $4",
+       "file-info-size-pages": "$1 × $2 patas hnigan, pusu patas prparu ni blbila: $3, MIME keelgan hnigan: $4, $5 {{PLURAL:$5|ruwahan patas}}",
+       "file-nohires": "Umtduwa mgay ngat mndka msleexan qtaan.",
+       "svg-long-desc": "SVG pusu patas, lipax prparu ni blbila: $1 × $2 patas hnigan, pusu patas prparu ni blbila: $3",
        "show-big-image": "Ida nkiya pusu patas",
-       "show-big-image-preview": "Muda qmita prparu ni blbila :$1.",
-       "show-big-image-other": "duma {{PLURAL:$2||}} msleexan qtaan:$1",
-       "show-big-image-size": "$1 × $2 patas hnigan",
+       "show-big-image-preview": "Muda qmita prparu ni blbila$1.",
+       "show-big-image-other": "Duma {{PLURAL:$2|msleexan qtaan}}: $1.",
+       "show-big-image-size": "$1 × $2 patas hnigan",
        "newimages-newbies": "Wana pqita bgurah sspgan patas ka suyang qnpahan",
-       "metadata-help": "Kska pusu patas nii supu kana duma pniyahan kari, pniyahan kari nii o yaa bi paah suwi kikay mangal hnigan aji uri o kikay powda miing rnisuh patas ga phiyug aji uri o saw kska suwi endaan mrana da. nasi pusu patas paah balay bi npusu na o wada psbgrahan smmalu\n, duma leexan balay patas o yaa bi ungat klaan mttuku tkkla wada psbgrahan smmalu pusu patas.",
-       "metadata-fields": "Ga kska ka saw pngkla kari bngkgan ka EXIF patas pngkla ngali ka nniqan nii supu kana ka patas pqita ruwahan patas, pida patas pgkla ka smeeliq siida wana pqita truma nii pngkla .\nduma ka patas pngkla o gnama asaw lmiing\n* make\n* model\n* datetimeoriginal\n* exposuretime\n* fnumber\n* isospeedratings\n* focallength\n* artist\n* copyright\n* imagedescription\n* gpslatitude\n* gpslongitude\n* gpsaltitude",
+       "ilsubmit": "Miying",
+       "metadata-help": "Kska pusu patas nii supu kana duma pniyahan kari, pniyahan kari nii o yaa bi paah suwi kikay mangal hnigan aji uri o kikay powda miing rnisuh patas ga phiyug aji uri o saw kska suwi endaan mrana da.\nNasi pusu patas paah balay bi npusu na o wada psbgrahan smmalu, duma leexan balay patas o yaa bi ungat klaan mttuku tkkla wada psbgrahan smmalu pusu patas.",
+       "metadata-fields": "Ga kska ka saw pngkla kari bngkgan ka EXIF patas pngkla ngali ka nniqan nii supu kana ka patas pqita ruwahan patas, pida patas pgkla ka smeeliq siida wana pqita truma nii pngkla.\nDuma ka patas pngkla o gnama asaw lmiing.\n* make\n* model\n* datetimeoriginal\n* exposuretime\n* fnumber\n* isospeedratings\n* focallength\n* artist\n* copyright\n* imagedescription\n* gpslatitude\n* gpslongitude\n* gpsaltitude",
        "namespacesall": "kana",
        "monthsall": "kana",
        "confirm-watch-top": "ngali ka ruwahan patas nii mali leexan patas gmraka su?",
-       "confirm-unwatch-top": "ruwahan patas nii paah leexan patas gmraka kska hdlun pkungat?",
-       "imgmultigo": "muda!",
-       "imgmultigoto": "pquri brah tg $1 ruwahan",
+       "confirm-unwatch-top": "Ruwahan patas nii paah leexan patas gmraka kska hdlun pkungat?",
+       "imgmultigo": "Muda!",
+       "imgmultigoto": "Pquri brah tg $1 ruwahan",
        "img-lang-go": "muda",
        "table_pager_limit_submit": "muda",
        "watchlistedit-raw-title": "leexan patas gmraka ida nkiya smmalu patas",
-       "watchlisttools-view": "qmitaa quri kmpriyux",
-       "watchlisttools-edit": "pqita kiya do smmalu patas leexan patas gmraka",
-       "watchlisttools-raw": "leexan patas gmraka ida nkiya smmalu patas",
-       "signature": "[[{{ns:user}}:$1|$2]] ([[{{ns:user_talk}}:$1| empprngaw ]])",
-       "version-specialpages": "ruwahan patas kmalu",
+       "watchlisttools-view": "Qmitaa quri kmpriyux",
+       "watchlisttools-edit": "Vqita kiya do smmalu patas leexan patas gmraka",
+       "watchlisttools-raw": "Leexan patas gmraka ida nkiya smmalu patas",
+       "signature": "[[{{ns:user}}:$1|$2]] ([[{{ns:user_talk}}:$1|empprngaw]])",
+       "version-specialpages": "Ruwahan patas kmalu",
        "version-ext-colheader-description": "Pgkla rmngaw",
        "version-ext-colheader-credits": "seejiq pnatas",
        "version-libraries-description": "Pgkla rmngaw",
        "version-libraries-authors": "seejiq pnatas",
        "redirect": "Saw pusu patas, seejiq mduuy, ruwahan patas, muda smalu aji uri o jiyax rnisuh patas ID iyah psbgurah muda",
-       "redirect-summary": "ruwahan patas knmalu nii o mtduwa sduuy psbgurah muda bitaq pusu patas ( tmiyuu hangan pusu patas ), ruwahan patas ( tmiyu smalu ID aji uri ruwahan patas ID), seejiq mduuy ruwahan patas ( tmiyu seejiq mduuy ID), aji uri o seejiq keelgan jiyax rnisuh patas ( tmiyu jiyax rnisuh patas ID). dduy[[{{#Special:Redirect}}/file/Example.jpg]], [[{{#Special:Redirect}}/page/64308]], [[{{#Special:Redirect}}/revision/328429]],",
-       "redirect-submit": "muda",
-       "redirect-revision": "muda smalu ruwahan patas ID",
-       "specialpages": "ruwahan patas kmalu",
+       "redirect-summary": "Ruwahan patas knmalu nii o mtduwa sduuy psbgurah muda bitaq pusu patas (tmiyuu hangan pusu patas), ruwahan patas (tmiyu smalu ID aji uri ruwahan patas ID), seejiq mduuy ruwahan patas (tmiyu seejiq mduuy ID), aji uri o seejiq keelgan jiyax rnisuh patas (tmiyu jiyax rnisuh patas ID). Dduy [[{{#Special:Redirect}}/file/Example.jpg]], [[{{#Special:Redirect}}/page/64308]], [[{{#Special:Redirect}}/revision/328429]], [[{{#Special:Redirect}}/user/101]], o [[{{#Special:Redirect}}/logid/186]].",
+       "redirect-submit": "Muda",
+       "redirect-lookup": "Mying:",
+       "redirect-revision": "Muda smalu ruwahan patas ID",
+       "fileduplicatesearch-submit": "Miying",
+       "specialpages": "Ruwahan patas kmalu",
        "specialpages-group-login": "pstmay patas. /phiyug patas sspgan",
-       "tag-filter": "[[Special:Tags| rqci pnskraya ]] miying:",
-       "tag-list-wrapper": "([[Special:Tags|$1 kngkingal rqci pnskraya ]]:$2)",
+       "tag-filter": "[[Special:Tags|Rqci pnskraya]] miying:",
+       "tag-list-wrapper": "[[Special:Tags|{{PLURAL:$1|Kngkingal rqci pnskraya}}]]: $2",
        "tag-mw-rollback": "gbrih duri",
        "tag-mw-undo": "pkbrih",
        "tags-source-header": "pnyahan",
+       "tags-active-yes": "Kiya",
+       "tags-active-no": "Aji",
        "tags-edit": "smmalu patas",
-       "permanentlink": "mggaluk ini kglglug\n(mggaluk mgdhug,mggaluk ana bitaq knuwan)",
-       "htmlform-cloner-delete": "hdlun pkungat",
-       "logentry-delete-delete": "$1 pkungat ruwahan patas $3",
-       "logentry-delete-restore": "$1{{GENDER:$2| psnbrih }} ruwahan patas $3($4)",
-       "logentry-delete-revision": "$1 {{GENDER:$2| wada priyuxan}} ruwahan patas $3 kska {{PLURAL:$5|1 gntuan muda smmalu |$5 gntuan muda smmalu }}ka mtduwa qtaan:$4",
-       "logentry-move-move": "$1 {{GENDER:$2|wada hdlun }} ruwahan patas $3 bitaq $4",
-       "logentry-move-move-noredirect": "$1 {{GENDER:$2| wada hdlun }} ruwahan patas $3 bityaq $4,ini rangi brahan muda",
+       "permanentlink": "Mggaluk ini kglglug",
+       "htmlform-cloner-delete": "Hdlun pkungat",
+       "logentry-delete-delete": "$1 {{GENDER:$2|}}pkungat ruwahan patas $3",
+       "logentry-delete-restore": "$1 {{GENDER:$2|psnbrih}} ruwahan patas $3 ($4)",
+       "logentry-delete-revision": "$1 {{GENDER:$2|wada priyuxan}} ruwahan patas $3 kska {{PLURAL:|$5 gntuan muda smmalu}} ka mtduwa qtaan: $4",
+       "logentry-move-move": "$1 {{GENDER:$2|wada hdlun}} ruwahan patas $3 bitaq $4",
+       "logentry-move-move-noredirect": "$1 {{GENDER:$2|wada hdlun}} ruwahan patas $3 bityaq $4,ini rangi brahan muda",
        "logentry-move-move_redir": "$1 wada hdlun ruwahan patas $3 bitaq $4 kiya o mubung ida nniqan psbgurah muda",
-       "logentry-patrol-patrol-auto": "$1 wada hiya nanak mlglug{{GENDER:$2| pnskraya }} ruwahan patas $3 ka muda smmalu $4 asaw wada daan rmigaw qmita",
+       "logentry-patrol-patrol-auto": "$1 wada hiya nanak mlglug {{GENDER:$2|pnskraya}} ruwahan patas $3 ka muda smmalu $4 asaw wada daan rmigaw qmita",
        "logentry-newusers-newusers": "wada{{GENDER:$2| phiyug }} empduuy patas sspgan $1",
-       "logentry-newusers-create": "wada{{GENDER:$2| phiyug }} empduuy patas sspgan $1",
-       "logentry-newusers-autocreate": "Wada hiya nanak mlglug{{GENDER:$2| phiyug }} mduuy patas sspgan $1",
-       "logentry-upload-upload": "$1 {{GENDER:$2|wada wada pdsun brah }} $3",
-       "logentry-upload-overwrite": "$1 {{GENDER:$2| wada pdsun brah da}}bgurah patas da $3",
-       "logentry-upload-revert": "$1 {{GENDER:$2|wada wada pdsun brah }} $3",
-       "feedback-cancel": "pkungat",
-       "searchsuggest-search": "miying {{SITENAME}}",
-       "duration-days": "jiyax",
-       "log-action-filter-all": "kana",
+       "logentry-newusers-create": "Wada {{GENDER:$2|phiyug}} empduuy patas sspgan $1",
+       "logentry-newusers-autocreate": "Wada hiya nanak mlglug {{GENDER:$2|phiyug}} mduuy patas sspgan $1",
+       "logentry-upload-upload": "$1 {{GENDER:$2|wada wada pdsun brah}} $3",
+       "logentry-upload-overwrite": "$1 {{GENDER:$2|wada pdsun brah da}} bgurah patas da $3",
+       "logentry-upload-revert": "$1 {{GENDER:$2|wada wada pdsun brah}} $3",
+       "feedback-cancel": "Pkungat",
+       "searchsuggest-search": "Miying {{SITENAME}}",
+       "duration-days": "$1 {{PLURAL:$1|jiyax}}",
+       "log-action-filter-all": "Kana",
        "log-action-filter-block-block": "hmuk",
        "authmanager-userdoesnotexist": "seejiq mduuy patas sspgan \"$1\" ini ppatas na."
 }
index 4ea707f..be09343 100644 (file)
        "anontalkpagetext": "----\n<em>这是一个还未建立账户的匿名用户的讨论页, 因此我们只能用IP地址来与他们联络。</em>该IP地址可能由几名用户共享。如果您是一名匿名用户并认为此页上的评语与您无关,请[[Special:CreateAccount|创建新账户]]或[[Special:UserLogin|登录]]以避免在未来与其他匿名用户混淆。",
        "noarticletext": "本页面目前没有内容。您可以在其他页面中[[Special:Search/{{PAGENAME}}|搜索本页标题]]、<span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} 搜索相关日志]或[{{fullurl:{{FULLPAGENAME}}|action=edit}} 创建本页面]</span>。",
        "noarticletext-nopermission": "本页面目前没有内容。您可以在其他页面中[[Special:Search/{{PAGENAME}}|搜索本页标题]]或<span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} 搜索相关日志]</span>,但您没有权限创建本页面。",
-       "missing-revision": "“{{FULLPAGENAME}}”的版本#$1不存在。\n\n这通常是因为进入了一个已被删除的页面的历史链接。\n详细信息可以在[{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} 删除日志]中找到。",
+       "missing-revision": "“{{FULLPAGENAME}}”的版本#$1不存在。\n\n这通常是因为进入了一个已被删除的页面的历史链接。详细信息可以在[{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} 删除日志]中找到。",
        "userpage-userdoesnotexist": "用户账户“$1”没有注册。请在创建/编辑本页前检查。",
        "userpage-userdoesnotexist-view": "用户账户“$1”没有被注册。",
        "blocked-notice-logextract": "这位用户目前已被封禁。以下提供最近的封禁日志以供参考:",
        "passwordpolicies-policyflag-suggestchangeonlogin": "建议在登录时更改",
        "easydeflate-invaliddeflate": "提供的内容未被适当缩小",
        "unprotected-js": "基于安全原因,JavaScript不能在未保护页面中载入。请在“MediaWiki:”名字空间或者用户子页面中添加JavaScript。",
-       "userlogout-continue": "您确定要登出吗?"
+       "userlogout-continue": "您确定要退出登录吗?"
 }
index 966c9d3..1506e55 100644 (file)
        "anontalkpagetext": "----\n<em>此討論頁面是給尚未建立帳號的匿名使用者使用</em>\n因此我們必須使用 IP 位址來辨識對方,但相同的 IP 位址可能是由許多不同的使用者所共用。\n如果您是匿名使用者並且覺得評論的內容與您無關,請[[Special:CreateAccount|建立新帳號]]或[[Special:UserLogin|登入]]避免與其他匿名使用者混淆。",
        "noarticletext": "此頁面目前沒有內容,您可以在其它頁面中[[Special:Search/{{PAGENAME}}|搜尋此頁面標題]]、<span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} 搜尋相關日誌]或[{{fullurl:{{FULLPAGENAME}}|action=edit}} 建立此頁面]</span>。",
        "noarticletext-nopermission": "此頁面目前沒有內容,\n您可以在其它頁面中 [[Special:Search/{{PAGENAME}}|搜尋此頁面標題]],或 <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} 搜尋相關日誌]</span>,但您沒有權限建立此頁面。",
-       "missing-revision": "頁面名稱 \"{{FULLPAGENAME}}\" 的 #$1 修訂版本不存在。\n\n通常是因連結到過期的歷史頁面,該頁面已被刪除。\n詳情請參考 [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} 刪除日誌]。",
+       "missing-revision": "頁面名稱「{{FULLPAGENAME}}」的#$1修訂版本不存在。\n\n通常是因連結到過期的歷史頁面,該頁面已被刪除。詳情請參考[{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} 刪除日誌]。",
        "userpage-userdoesnotexist": "使用者帳號 \"$1\" 尚未註冊。\n若要建立或編輯此頁面,請先檢查清楚。",
        "userpage-userdoesnotexist-view": "使用者帳號 \"$1\" 尚未註冊。",
        "blocked-notice-logextract": "此使用者目前已被封鎖。\n以下為最近的封鎖紀錄以供參考:",
        "tags-deactivate-not-allowed": "無法停用標籤 \"$1\"。",
        "tags-deactivate-submit": "停用",
        "tags-apply-no-permission": "您沒有權限連同您的變更一起套用標籤。",
-       "tags-apply-blocked": "您無法在{{GENDER:$1|您}}被封鎖的情況下套用變更標籤為您的變更。",
+       "tags-apply-blocked": "{{GENDER:$1|您}}無法在被封鎖的情況下套用變更標籤到您的變更中。",
        "tags-apply-not-allowed-one": "不允許手動套用標籤 \"$1\"。",
        "tags-apply-not-allowed-multi": "不允許手動套用以下{{PLURAL:$2|標籤|標籤}}:$1",
        "tags-update-no-permission": "您沒有權限加入與移除任何於各別修訂與日誌項目的標籤",
index 6beda4e..0263425 100644 (file)
@@ -1737,7 +1737,7 @@ abstract class LoggedUpdateMaintenance extends Maintenance {
        protected function updateSkippedMessage() {
                $key = $this->getUpdateKey();
 
-               return "Update '{$key}' already logged as completed.";
+               return "Update '{$key}' already logged as completed. Use --force to run it again.";
        }
 
        /**
index 8e2acb2..30982e0 100644 (file)
@@ -17,7 +17,6 @@
  *
  * @file
  * @ingroup Benchmark
- * @author Timo Tijhof
  */
 
 require_once __DIR__ . '/Benchmarker.php';
index 3aa7af7..189da08 100644 (file)
@@ -17,7 +17,6 @@
  *
  * @file
  * @ingroup Benchmark
- * @author Timo Tijhof
  */
 
 require_once __DIR__ . '/Benchmarker.php';
index bb75660..d042fb7 100644 (file)
@@ -17,7 +17,6 @@
  *
  * @file
  * @ingroup Benchmark
- * @author Timo Tijhof
  */
 
 require_once __DIR__ . '/Benchmarker.php';
index 89fc44b..1da805e 100644 (file)
@@ -17,7 +17,6 @@
  *   symbols being documented but not declared or defined.
  *
  * Copyright (C) 2012 Tamas Imrei <tamas.imrei@gmail.com> https://virtualtee.blogspot.com/
- * Copyright (C) 2015 Timo Tijhof
  *
  * Permission is hereby granted, free of charge, to any person obtaining
  * a copy of this software and associated documentation files (the "Software"),
index f3e373a..c84f3de 100644 (file)
@@ -21,6 +21,7 @@
 
 use MediaWiki\MediaWikiServices;
 use MediaWiki\Revision\SlotRecord;
+use MediaWiki\Storage\BlobStore;
 use MediaWiki\Storage\NameTableStore;
 use MediaWiki\Storage\SqlBlobStore;
 use Wikimedia\Assert\Assert;
@@ -41,6 +42,9 @@ class PopulateContentTables extends Maintenance {
        /** @var NameTableStore */
        private $contentModelStore;
 
+       /** @var BlobStore */
+       private $blobStore;
+
        /** @var int */
        private $mainRoleId;
 
@@ -67,6 +71,7 @@ class PopulateContentTables extends Maintenance {
        private function initServices() {
                $this->dbw = $this->getDB( DB_MASTER );
                $this->contentModelStore = MediaWikiServices::getInstance()->getContentModelStore();
+               $this->blobStore = MediaWikiServices::getInstance()->getBlobStore();
                $this->mainRoleId = MediaWikiServices::getInstance()->getSlotRoleStore()
                        ->acquireId( SlotRecord::MAIN );
        }
@@ -262,13 +267,16 @@ class PopulateContentTables extends Maintenance {
 
                                Assert::invariant( $revisionId !== null, 'rev_id must not be null' );
 
-                               $modelId = $this->contentModelStore->acquireId( $this->getContentModel( $row ) );
+                               $model = $this->getContentModel( $row );
+                               $modelId = $this->contentModelStore->acquireId( $model );
                                $address = SqlBlobStore::makeAddressFromTextId( $row->text_id );
 
                                $key = "{$modelId}:{$address}";
                                $contentKeys[$revisionId] = $key;
 
                                if ( !isset( $map[$key] ) ) {
+                                       $this->fillMissingFields( $row, $model, $address );
+
                                        $map[$key] = false;
                                        $contentRows[] = [
                                                'content_size' => (int)$row->len,
@@ -345,6 +353,40 @@ class PopulateContentTables extends Maintenance {
        private function writeln( $msg ) {
                $this->output( "$msg\n" );
        }
+
+       /**
+        * Compute any missing fields in $row.
+        * The way the missing values are computed must correspond to the way this is done in SlotRecord.
+        *
+        * @param object $row to be modified
+        * @param string $model
+        * @param string $address
+        */
+       private function fillMissingFields( $row, $model, $address ) {
+               if ( !isset( $row->content_model ) ) {
+                       // just for completeness
+                       $row->content_model = $model;
+               }
+
+               if ( isset( $row->len ) && isset( $row->sha1 ) && $row->sha1 !== '' ) {
+                       // No need to load the content, quite now.
+                       return;
+               }
+
+               $blob = $this->blobStore->getBlob( $address );
+
+               if ( !isset( $row->len ) ) {
+                       // NOTE: The nominal size of the content may not be the length of the raw blob.
+                       $handler = ContentHandler::getForModelID( $model );
+                       $content = $handler->unserializeContent( $blob );
+
+                       $row->len = $content->getSize();
+               }
+
+               if ( !isset( $row->sha1 ) || $row->sha1 === '' ) {
+                       $row->sha1 = SlotRecord::base36Sha1( $blob );
+               }
+       }
 }
 
 $maintClass = 'PopulateContentTables';
index 9662044..f91a5b6 100644 (file)
@@ -24,6 +24,8 @@
 
 require_once __DIR__ . '/Maintenance.php';
 
+use MediaWiki\MediaWikiServices;
+
 /**
  * Maintenance script that fills the rev_sha1 and ar_sha1 columns of revision
  * and archive tables for revisions created before MW 1.19.
@@ -50,17 +52,22 @@ class PopulateRevisionSha1 extends LoggedUpdateMaintenance {
                        $this->fatalError( "archive table does not exist" );
                } elseif ( !$db->fieldExists( 'revision', 'rev_sha1', __METHOD__ ) ) {
                        $this->output( "rev_sha1 column does not exist\n\n", true );
-
                        return false;
                }
 
+               $revStore = MediaWikiServices::getInstance()->getRevisionStore();
+
                $this->output( "Populating rev_sha1 column\n" );
-               $rc = $this->doSha1Updates( 'revision', 'rev_id', Revision::getQueryInfo(), 'rev' );
+               $rc = $this->doSha1Updates( $revStore, 'revision', 'rev_id',
+                       $revStore->getQueryInfo(), 'rev'
+               );
 
                $this->output( "Populating ar_sha1 column\n" );
-               $ac = $this->doSha1Updates( 'archive', 'ar_rev_id', Revision::getArchiveQueryInfo(), 'ar' );
+               $ac = $this->doSha1Updates( $revStore, 'archive', 'ar_rev_id',
+                       $revStore->getArchiveQueryInfo(), 'ar'
+               );
                $this->output( "Populating ar_sha1 column legacy rows\n" );
-               $ac += $this->doSha1LegacyUpdates();
+               $ac += $this->doSha1LegacyUpdates( $revStore );
 
                $this->output( "rev_sha1 and ar_sha1 population complete "
                        . "[$rc revision rows, $ac archive rows].\n" );
@@ -69,13 +76,14 @@ class PopulateRevisionSha1 extends LoggedUpdateMaintenance {
        }
 
        /**
+        * @param MediaWiki\Revision\RevisionStore $revStore
         * @param string $table
         * @param string $idCol
         * @param array $queryInfo
         * @param string $prefix
         * @return int Rows changed
         */
-       protected function doSha1Updates( $table, $idCol, $queryInfo, $prefix ) {
+       protected function doSha1Updates( $revStore, $table, $idCol, $queryInfo, $prefix ) {
                $db = $this->getDB( DB_MASTER );
                $batchSize = $this->getBatchSize();
                $start = $db->selectField( $table, "MIN($idCol)", '', __METHOD__ );
@@ -93,6 +101,7 @@ class PopulateRevisionSha1 extends LoggedUpdateMaintenance {
                $blockEnd = $start + $batchSize - 1;
                while ( $blockEnd <= $end ) {
                        $this->output( "...doing $idCol from $blockStart to $blockEnd\n" );
+
                        $cond = "$idCol BETWEEN " . (int)$blockStart . " AND " . (int)$blockEnd .
                                " AND $idCol IS NOT NULL AND {$prefix}_sha1 = ''";
                        $res = $db->select(
@@ -101,7 +110,7 @@ class PopulateRevisionSha1 extends LoggedUpdateMaintenance {
 
                        $this->beginTransaction( $db, __METHOD__ );
                        foreach ( $res as $row ) {
-                               if ( $this->upgradeRow( $row, $table, $idCol, $prefix ) ) {
+                               if ( $this->upgradeRow( $revStore, $row, $table, $idCol, $prefix ) ) {
                                        $count++;
                                }
                        }
@@ -115,19 +124,21 @@ class PopulateRevisionSha1 extends LoggedUpdateMaintenance {
        }
 
        /**
+        * @param MediaWiki\Revision\RevisionStore $revStore
+        * @param string $emptySha1
         * @return int
         */
-       protected function doSha1LegacyUpdates() {
+       protected function doSha1LegacyUpdates( $revStore ) {
                $count = 0;
                $db = $this->getDB( DB_MASTER );
-               $arQuery = Revision::getArchiveQueryInfo();
+               $arQuery = $revStore->getArchiveQueryInfo();
                $res = $db->select( $arQuery['tables'], $arQuery['fields'],
                        [ 'ar_rev_id IS NULL', 'ar_sha1' => '' ], __METHOD__, [], $arQuery['joins'] );
 
                $updateSize = 0;
                $this->beginTransaction( $db, __METHOD__ );
                foreach ( $res as $row ) {
-                       if ( $this->upgradeLegacyArchiveRow( $row ) ) {
+                       if ( $this->upgradeLegacyArchiveRow( $revStore, $row ) ) {
                                ++$count;
                        }
                        if ( ++$updateSize >= 100 ) {
@@ -143,75 +154,67 @@ class PopulateRevisionSha1 extends LoggedUpdateMaintenance {
        }
 
        /**
+        * @param MediaWiki\Revision\RevisionStore $revStore
         * @param stdClass $row
         * @param string $table
         * @param string $idCol
         * @param string $prefix
         * @return bool
         */
-       protected function upgradeRow( $row, $table, $idCol, $prefix ) {
+       protected function upgradeRow( $revStore, $row, $table, $idCol, $prefix ) {
                $db = $this->getDB( DB_MASTER );
+
+               // Create a revision and use it to get the sha1 from the content table, if possible.
                try {
                        $rev = ( $table === 'archive' )
-                               ? Revision::newFromArchiveRow( $row )
-                               : new Revision( $row );
-                       $text = $rev->getSerializedData();
+                               ? $revStore->newRevisionFromArchiveRow( $row )
+                               : $revStore->newRevisionFromRow( $row );
+                       $sha1 = $rev->getSha1();
                } catch ( Exception $e ) {
                        $this->output( "Data of revision with {$idCol}={$row->$idCol} unavailable!\n" );
-
-                       return false; // T24624?
+                       return false; // T24624? T22757?
                }
-               if ( !is_string( $text ) ) {
-                       # This should not happen, but sometimes does (T22757)
-                       $this->output( "Data of revision with {$idCol}={$row->$idCol} unavailable!\n" );
 
-                       return false;
-               } else {
-                       $db->update( $table,
-                               [ "{$prefix}_sha1" => Revision::base36Sha1( $text ) ],
-                               [ $idCol => $row->$idCol ],
-                               __METHOD__
-                       );
+               $db->update( $table,
+                       [ "{$prefix}_sha1" => $sha1 ],
+                       [ $idCol => $row->$idCol ],
+                       __METHOD__
+               );
 
-                       return true;
-               }
+               return true;
        }
 
        /**
+        * @param MediaWiki\Revision\RevisionStore $revStore
         * @param stdClass $row
         * @return bool
         */
-       protected function upgradeLegacyArchiveRow( $row ) {
+       protected function upgradeLegacyArchiveRow( $revStore, $row ) {
                $db = $this->getDB( DB_MASTER );
+
+               // Create a revision and use it to get the sha1 from the content table, if possible.
                try {
-                       $rev = Revision::newFromArchiveRow( $row );
+                       $rev = $revStore->newRevisionFromArchiveRow( $row );
+                       $sha1 = $rev->getSha1();
                } catch ( Exception $e ) {
                        $this->output( "Text of revision with timestamp {$row->ar_timestamp} unavailable!\n" );
-
-                       return false; // T24624?
+                       return false; // T24624? T22757?
                }
-               $text = $rev->getSerializedData();
-               if ( !is_string( $text ) ) {
-                       # This should not happen, but sometimes does (T22757)
-                       $this->output( "Data of revision with timestamp {$row->ar_timestamp} unavailable!\n" );
 
-                       return false;
-               } else {
-                       # Archive table as no PK, but (NS,title,time) should be near unique.
-                       # Any duplicates on those should also have duplicated text anyway.
-                       $db->update( 'archive',
-                               [ 'ar_sha1' => Revision::base36Sha1( $text ) ],
-                               [
-                                       'ar_namespace' => $row->ar_namespace,
-                                       'ar_title' => $row->ar_title,
-                                       'ar_timestamp' => $row->ar_timestamp,
-                                       'ar_len' => $row->ar_len // extra sanity
-                               ],
-                               __METHOD__
-                       );
+               # Archive table has no PK, but (NS,title,time) should be near unique.
+               # Any duplicates on those should also have duplicated text anyway.
+               $db->update( 'archive',
+                       [ 'ar_sha1' => $sha1 ],
+                       [
+                               'ar_namespace' => $row->ar_namespace,
+                               'ar_title' => $row->ar_title,
+                               'ar_timestamp' => $row->ar_timestamp,
+                               'ar_len' => $row->ar_len // extra sanity
+                       ],
+                       __METHOD__
+               );
 
-                       return true;
-               }
+               return true;
        }
 }
 
index 3b25629..683c319 100644 (file)
@@ -1,7 +1,5 @@
 <?php
 /**
- * Remove all cache entries for ResourceLoader modules from the database.
- *
  * 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
@@ -19,7 +17,6 @@
  *
  * @file
  * @ingroup Maintenance
- * @author Timo Tijhof
  */
 
 use Wikimedia\Rdbms\IDatabase;
@@ -27,7 +24,7 @@ use Wikimedia\Rdbms\IDatabase;
 require_once __DIR__ . '/Maintenance.php';
 
 /**
- * Maintenance script to purge the module_deps database cache table.
+ * Maintenance script to purge the module_deps database cache table for ResourceLoader.
  *
  * @ingroup Maintenance
  */
index 235ff4a..6f899f8 100644 (file)
@@ -23,6 +23,7 @@
                $( '.dbRadio' ).on( 'click', function () {
                        var $checked = $( '.dbRadio:checked' ),
                                $wrapper = $( document.getElementById( $checked.attr( 'rel' ) ) );
+                       // eslint-disable-next-line no-jquery/no-sizzle
                        if ( $wrapper.is( ':hidden' ) ) {
                                // FIXME: Use CSS transition
                                // eslint-disable-next-line no-jquery/no-animate-toggle
index 15ec62d..b546cbf 100644 (file)
@@ -48,17 +48,16 @@ print Xml::openElement( 'OpenSearchDescription',
                'xmlns' => 'http://a9.com/-/spec/opensearch/1.1/',
                'xmlns:moz' => 'http://www.mozilla.org/2006/browser/search/' ] );
 
-/* The spec says the ShortName must be no longer than 16 characters,
- * but 16 is *realllly* short. In practice, browsers don't appear to care
- * when we give them a longer string, so we're no longer attempting to trim.
- *
- * Note: ShortName and the <link title=""> need to match; they are used as
- * a key for identifying if the search engine has been added already, *and*
- * as the display name presented to the end-user.
- *
- * Behavior seems about the same between Firefox and IE 7/8 here.
- * 'Description' doesn't appear to be used by either.
- */
+// The spec says the ShortName must be no longer than 16 characters,
+// but 16 is *realllly* short. In practice, browsers don't appear to care
+// when we give them a longer string, so we're no longer attempting to trim.
+//
+// Note: ShortName and the <link title=""> need to match; they are used as
+// a key for identifying if the search engine has been added already, *and*
+// as the display name presented to the end-user.
+//
+// Behavior seems about the same between Firefox and IE 7/8 here.
+// 'Description' doesn't appear to be used by either.
 $fullName = wfMessage( 'opensearch-desc' )->inContentLanguage()->text();
 print Xml::element( 'ShortName', null, $fullName );
 print Xml::element( 'Description', null, $fullName );
index bb52c61..044b9be 100644 (file)
       "dev": true
     },
     "agent-base": {
-      "version": "4.2.1",
-      "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.2.1.tgz",
-      "integrity": "sha512-JVwXMr9nHYTUXsBFKUqhJwvlcYU/blreOEUkhNR2eXZIvwd+c+o5V4MgDPKWnMS/56awN3TRzIP+KoPn+roQtg==",
+      "version": "4.3.0",
+      "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz",
+      "integrity": "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==",
       "dev": true,
       "requires": {
         "es6-promisify": "^5.0.0"
       "version": "1.0.10",
       "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
       "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
+      "dev": true,
       "requires": {
         "sprintf-js": "~1.0.2"
       }
       "dev": true
     },
     "babel-runtime": {
-      "version": "5.8.38",
-      "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-5.8.38.tgz",
-      "integrity": "sha1-HAsC62MxL18If/IEUIJ7QlydTBk=",
+      "version": "6.26.0",
+      "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz",
+      "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=",
       "dev": true,
       "requires": {
-        "core-js": "^1.0.0"
-      },
-      "dependencies": {
-        "core-js": {
-          "version": "1.2.7",
-          "resolved": "https://registry.npmjs.org/core-js/-/core-js-1.2.7.tgz",
-          "integrity": "sha1-ZSKUwUZR2yj6k70tX/KYOk8IxjY=",
-          "dev": true
-        }
+        "core-js": "^2.4.0",
+        "regenerator-runtime": "^0.11.0"
       }
     },
     "backo2": {
       "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=",
       "dev": true
     },
-    "boom": {
-      "version": "4.3.1",
-      "resolved": "https://registry.npmjs.org/boom/-/boom-4.3.1.tgz",
-      "integrity": "sha1-T4owBctKfjiJ90kDD9JbluAdLjE=",
-      "dev": true,
-      "requires": {
-        "hoek": "4.x.x"
-      }
-    },
     "brace-expansion": {
       "version": "1.1.11",
       "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
         "is-supported-regexp-flag": "^1.0.0"
       }
     },
-    "co": {
-      "version": "4.6.0",
-      "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz",
-      "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=",
-      "dev": true
-    },
     "coa": {
       "version": "2.0.2",
       "resolved": "https://registry.npmjs.org/coa/-/coa-2.0.2.tgz",
         "which": "^1.2.9"
       }
     },
-    "cryptiles": {
-      "version": "3.1.4",
-      "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-3.1.4.tgz",
-      "integrity": "sha512-8I1sgZHfVwcSOY6mSGpVU3lw/GSIZvusg8dD2+OGehCJpOhQRLNcH0qb9upQnOH4XhgxxFJSg6E2kx95deb1Tw==",
-      "dev": true,
-      "requires": {
-        "boom": "5.x.x"
-      },
-      "dependencies": {
-        "boom": {
-          "version": "5.2.0",
-          "resolved": "https://registry.npmjs.org/boom/-/boom-5.2.0.tgz",
-          "integrity": "sha512-Z5BTk6ZRe4tXXQlkqftmsAUANpXmuwlsF5Oov8ThoMbQRzdGTA1ngYRW160GexgOgjsFOKJz0LYhoNi+2AMBUw==",
-          "dev": true,
-          "requires": {
-            "hoek": "4.x.x"
-          }
-        }
-      }
-    },
     "css": {
       "version": "2.2.4",
       "resolved": "https://registry.npmjs.org/css/-/css-2.2.4.tgz",
       }
     },
     "es6-promise": {
-      "version": "4.2.6",
-      "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.6.tgz",
-      "integrity": "sha512-aRVgGdnmW2OiySVPUC9e6m+plolMAJKjZnQlCwNSuK5yQ0JN61DZSO1X1Ufd1foqWRAlig0rhduTCHe7sVtK5Q==",
+      "version": "4.2.8",
+      "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz",
+      "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==",
       "dev": true
     },
     "es6-promisify": {
       }
     },
     "eslint-config-wikimedia": {
-      "version": "0.12.0",
-      "resolved": "https://registry.npmjs.org/eslint-config-wikimedia/-/eslint-config-wikimedia-0.12.0.tgz",
-      "integrity": "sha512-ZkmGLvwmoEacj55t8Z6VH6wUu4/XTlgkSCerHkj+VU4tmyCD4mlzvTeSaPzOEDmZTVWUoiKnB6mvUx06l7uIbw==",
+      "version": "0.13.0",
+      "resolved": "https://registry.npmjs.org/eslint-config-wikimedia/-/eslint-config-wikimedia-0.13.0.tgz",
+      "integrity": "sha512-l64xMCgPE949H9rfhC0Ir+UaNAh685CE6xSnWkMU5yNryNTdL91lW8KcMFgMqmmH0Q+Jq+7DIdfGaVld6nQ80w==",
       "dev": true,
       "requires": {
         "eslint": "^5.16.0",
         "eslint-plugin-json": "^1.4.0",
-        "eslint-plugin-no-jquery": "^2.0.0",
+        "eslint-plugin-no-jquery": "^2.1.0",
         "eslint-plugin-qunit": "^4.0.0"
       },
       "dependencies": {
       }
     },
     "eslint-plugin-no-jquery": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/eslint-plugin-no-jquery/-/eslint-plugin-no-jquery-2.0.0.tgz",
-      "integrity": "sha512-aFy3fMBlc630/qeasjocb9uIqmwoyOmmTQiBaDs70Aryqi9uPH0EZLPtIOshDMcGeAkyyAkcc+WuIw6bRsoLuw==",
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/eslint-plugin-no-jquery/-/eslint-plugin-no-jquery-2.1.0.tgz",
+      "integrity": "sha512-5sr5tOJRfuRviyAvFTe/mr80TXWxTteD/JHRuJtDN8q/bxAh16eSKoKLAevLC7wZCRN2iwnEfhQPQV4rp/gYtg==",
       "dev": true
     },
     "eslint-plugin-qunit": {
     "esprima": {
       "version": "4.0.1",
       "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
-      "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A=="
+      "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
+      "dev": true
     },
     "esquery": {
       "version": "1.0.1",
           "version": "2.1.1",
           "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
           "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
-          "dev": true
+          "dev": true,
+          "optional": true
         },
         "aproba": {
           "version": "1.2.0",
           "version": "1.0.0",
           "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
           "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
-          "dev": true
+          "dev": true,
+          "optional": true
         },
         "brace-expansion": {
           "version": "1.1.11",
           "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
           "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
           "dev": true,
+          "optional": true,
           "requires": {
             "balanced-match": "^1.0.0",
             "concat-map": "0.0.1"
           "version": "1.1.0",
           "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz",
           "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=",
-          "dev": true
+          "dev": true,
+          "optional": true
         },
         "concat-map": {
           "version": "0.0.1",
           "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
           "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
-          "dev": true
+          "dev": true,
+          "optional": true
         },
         "console-control-strings": {
           "version": "1.1.0",
           "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz",
           "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=",
-          "dev": true
+          "dev": true,
+          "optional": true
         },
         "core-util-is": {
           "version": "1.0.2",
           "version": "2.0.3",
           "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
           "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=",
-          "dev": true
+          "dev": true,
+          "optional": true
         },
         "ini": {
           "version": "1.3.5",
           "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
           "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=",
           "dev": true,
+          "optional": true,
           "requires": {
             "number-is-nan": "^1.0.0"
           }
           "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
           "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
           "dev": true,
+          "optional": true,
           "requires": {
             "brace-expansion": "^1.1.7"
           }
           "version": "0.0.8",
           "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
           "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=",
-          "dev": true
+          "dev": true,
+          "optional": true
         },
         "minipass": {
           "version": "2.3.5",
           "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.3.5.tgz",
           "integrity": "sha512-Gi1W4k059gyRbyVUZQ4mEqLm0YIUiGYfvxhF6SIlk3ui1WVxMTGfGdQ2SInh3PDrRTVvPKgULkpJtT4RH10+VA==",
           "dev": true,
+          "optional": true,
           "requires": {
             "safe-buffer": "^5.1.2",
             "yallist": "^3.0.0"
           "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
           "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
           "dev": true,
+          "optional": true,
           "requires": {
             "minimist": "0.0.8"
           }
           "version": "1.0.1",
           "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz",
           "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=",
-          "dev": true
+          "dev": true,
+          "optional": true
         },
         "object-assign": {
           "version": "4.1.1",
           "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
           "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
           "dev": true,
+          "optional": true,
           "requires": {
             "wrappy": "1"
           }
           "version": "5.1.2",
           "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
           "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
-          "dev": true
+          "dev": true,
+          "optional": true
         },
         "safer-buffer": {
           "version": "2.1.2",
           "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
           "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
           "dev": true,
+          "optional": true,
           "requires": {
             "code-point-at": "^1.0.0",
             "is-fullwidth-code-point": "^1.0.0",
           "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
           "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
           "dev": true,
+          "optional": true,
           "requires": {
             "ansi-regex": "^2.0.0"
           }
           "version": "1.0.2",
           "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
           "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
-          "dev": true
+          "dev": true,
+          "optional": true
         },
         "yallist": {
           "version": "3.0.3",
           "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.3.tgz",
           "integrity": "sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A==",
-          "dev": true
+          "dev": true,
+          "optional": true
         }
       }
     },
       "integrity": "sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==",
       "dev": true
     },
+    "grapheme-splitter": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz",
+      "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==",
+      "dev": true
+    },
     "growl": {
       "version": "1.10.5",
       "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz",
         }
       }
     },
-    "hawk": {
-      "version": "6.0.2",
-      "resolved": "https://registry.npmjs.org/hawk/-/hawk-6.0.2.tgz",
-      "integrity": "sha512-miowhl2+U7Qle4vdLqDdPt9m09K6yZhkLDTWGoUiUzrQCn+mHHSmfJgAyGaLRZbPmTqfFFjRV1QWCW0VWUJBbQ==",
-      "dev": true,
-      "requires": {
-        "boom": "4.x.x",
-        "cryptiles": "3.x.x",
-        "hoek": "4.x.x",
-        "sntp": "2.x.x"
-      }
-    },
     "he": {
       "version": "1.1.1",
       "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz",
       "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=",
       "dev": true
     },
-    "hoek": {
-      "version": "4.2.1",
-      "resolved": "https://registry.npmjs.org/hoek/-/hoek-4.2.1.tgz",
-      "integrity": "sha512-QLg82fGkfnJ/4iy1xZ81/9SIJiq1NGFUMGs6ParyjBZr6jW2Ufj/snDqTHixNlHdPNwN2RLVD0Pi3igeK9+JfA==",
-      "dev": true
-    },
     "hooker": {
       "version": "0.2.3",
       "resolved": "https://registry.npmjs.org/hooker/-/hooker-0.2.3.tgz",
       }
     },
     "https-proxy-agent": {
-      "version": "2.2.1",
-      "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.1.tgz",
-      "integrity": "sha512-HPCTS1LW51bcyMYbxUIOO4HEOlQ1/1qRaFWcyxvwaqUS9TY88aoEuHUY33kuAh1YhVVaDQhLZsnPd+XNARWZlQ==",
+      "version": "2.2.2",
+      "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.2.tgz",
+      "integrity": "sha512-c8Ndjc9Bkpfx/vCJueCPy0jlP4ccCCSNDp8xwCZzPjKJUm+B+u9WX2x98Qx4n1PiMNTWo3D7KK5ifNV/yJyRzg==",
       "dev": true,
       "requires": {
-        "agent-base": "^4.1.0",
+        "agent-base": "^4.3.0",
         "debug": "^3.1.0"
       },
       "dependencies": {
       }
     },
     "humanize-duration": {
-      "version": "3.18.0",
-      "resolved": "https://registry.npmjs.org/humanize-duration/-/humanize-duration-3.18.0.tgz",
-      "integrity": "sha512-reYy4EJMqlhX13TDlgSqLYfVGKOoixoEzsSL6DBlp22dScWN8Q2eMgDF4L0q28mzbgO40rnBy3WyEUQEhfYALw==",
+      "version": "3.15.3",
+      "resolved": "https://registry.npmjs.org/humanize-duration/-/humanize-duration-3.15.3.tgz",
+      "integrity": "sha512-BMz6w8p3NVa6QP9wDtqUkXfwgBqDaZ5z/np0EYdoWrLqL849Onp6JWMXMhbHtuvO9jUThLN5H1ThRQ8dUWnYkA==",
       "dev": true
     },
     "iconv-lite": {
       "version": "3.13.1",
       "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz",
       "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==",
+      "dev": true,
       "requires": {
         "argparse": "^1.0.7",
         "esprima": "^4.0.0"
       "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==",
       "dev": true
     },
+    "lodash.get": {
+      "version": "4.4.2",
+      "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz",
+      "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=",
+      "dev": true
+    },
     "log-symbols": {
       "version": "2.2.0",
       "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz",
       "dev": true
     },
     "sauce-connect-launcher": {
-      "version": "1.2.6",
-      "resolved": "https://registry.npmjs.org/sauce-connect-launcher/-/sauce-connect-launcher-1.2.6.tgz",
-      "integrity": "sha512-yBTYfzI6AWRwoXJoIqmVgz+eCpWX6CsJ4Ap8fowjsGlN+27OKbnQxv6POd4Rzh57BH9WeA9K8orIzNxO8mMBQA==",
+      "version": "1.2.7",
+      "resolved": "https://registry.npmjs.org/sauce-connect-launcher/-/sauce-connect-launcher-1.2.7.tgz",
+      "integrity": "sha512-v07+QhFrxgz3seMFuRSonu3gW1s6DbcLQlFhjsRrmKUauzPbbudHdnn91WYgEwhoZVdPNzeZpAEJwcQyd9xnTA==",
       "dev": true,
       "requires": {
         "adm-zip": "~0.4.3",
         }
       }
     },
-    "sntp": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/sntp/-/sntp-2.1.0.tgz",
-      "integrity": "sha512-FL1b58BDrqS3A11lJ0zEdnJ3UOKqVxawAkF3k7F0CVN7VQ34aZrV+G8BZ1WC9ZL7NyrwsW0oviwsWDgRuVYtJg==",
-      "dev": true,
-      "requires": {
-        "hoek": "4.x.x"
-      }
-    },
     "socket.io": {
       "version": "2.1.1",
       "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-2.1.1.tgz",
     "sprintf-js": {
       "version": "1.0.3",
       "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
-      "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw="
+      "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=",
+      "dev": true
     },
     "sshpk": {
       "version": "1.16.1",
         "is-hexadecimal": "^1.0.0"
       }
     },
-    "stringstream": {
-      "version": "0.0.6",
-      "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.6.tgz",
-      "integrity": "sha512-87GEBAkegbBcweToUrdzf3eLhWNg06FJTebl4BVJz/JgWy8CvEr9dRtX5qWphiynMSQlxxi+QqN0z5T32SLlhA==",
-      "dev": true
-    },
     "strip-ansi": {
       "version": "4.0.0",
       "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
       "dev": true
     },
     "vscode-json-languageservice": {
-      "version": "3.2.1",
-      "resolved": "https://registry.npmjs.org/vscode-json-languageservice/-/vscode-json-languageservice-3.2.1.tgz",
-      "integrity": "sha512-ee9MJ70/xR55ywvm0bZsDLhA800HCRE27AYgMNTU14RSg20Y+ngHdQnUt6OmiTXrQDI/7sne6QUOtHIN0hPQYA==",
+      "version": "3.3.0",
+      "resolved": "https://registry.npmjs.org/vscode-json-languageservice/-/vscode-json-languageservice-3.3.0.tgz",
+      "integrity": "sha512-upq1PhwDItazdtRJ/R7uU0Fgrf9iaYa1xLK4WFLExR0DgbPojd0YgMpfyknVyXGlxsg3fJQ0H7J++QeByXHh9w==",
       "dev": true,
       "requires": {
-        "jsonc-parser": "^2.0.2",
-        "vscode-languageserver-types": "^3.13.0",
-        "vscode-nls": "^4.0.0",
-        "vscode-uri": "^1.0.6"
+        "jsonc-parser": "^2.1.0",
+        "vscode-languageserver-types": "^3.15.0-next.2",
+        "vscode-nls": "^4.1.1",
+        "vscode-uri": "^2.0.1"
       }
     },
     "vscode-languageserver-types": {
-      "version": "3.14.0",
-      "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.14.0.tgz",
-      "integrity": "sha512-lTmS6AlAlMHOvPQemVwo3CezxBp0sNB95KNPkqp3Nxd5VFEnuG1ByM0zlRWos0zjO3ZWtkvhal0COgiV1xIA4A==",
+      "version": "3.15.0-next.2",
+      "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.15.0-next.2.tgz",
+      "integrity": "sha512-2JkrMWWUi2rlVLSo9OFR2PIGUzdiowEM8NgNYiwLKnXTjpwpjjIrJbNNxDik7Rv4oo9KtikcFQZKXbrKilL/MQ==",
       "dev": true
     },
     "vscode-nls": {
-      "version": "4.1.0",
-      "resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-4.1.0.tgz",
-      "integrity": "sha512-zKsFWVzL1wlCezgaI3XiN42IT8DIPM1Qr+G+RBhiU3U0bJCdC8pPELakRCtuVT4wF3gBZjBrUDQ8mowL7hmgwA==",
+      "version": "4.1.1",
+      "resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-4.1.1.tgz",
+      "integrity": "sha512-4R+2UoUUU/LdnMnFjePxfLqNhBS8lrAFyX7pjb2ud/lqDkrUavFUTcG7wR0HBZFakae0Q6KLBFjMS6W93F403A==",
       "dev": true
     },
     "vscode-uri": {
-      "version": "1.0.6",
-      "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-1.0.6.tgz",
-      "integrity": "sha512-sLI2L0uGov3wKVb9EB+vIQBl9tVP90nqRvxSoJ35vI3NjxE8jfsE5DSOhWgSunHSZmKS4OCi2jrtfxK7uyp2ww==",
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-2.0.2.tgz",
+      "integrity": "sha512-VebpIxm9tG0fG2sBOhnsSPzDYuNUPP1UQW4K3mwthlca4e4f3d6HKq3HkITC2OPFomOaB7pHTSjcpdFWjfYTzg==",
       "dev": true
     },
     "wdio-dot-reporter": {
       "dev": true
     },
     "wdio-junit-reporter": {
-      "version": "0.2.0",
-      "resolved": "https://registry.npmjs.org/wdio-junit-reporter/-/wdio-junit-reporter-0.2.0.tgz",
-      "integrity": "sha1-88QXRHftcXN2k9wKFBU6wEhiG8g=",
+      "version": "0.4.4",
+      "resolved": "https://registry.npmjs.org/wdio-junit-reporter/-/wdio-junit-reporter-0.4.4.tgz",
+      "integrity": "sha512-EE5b7dnQ5yOCGVM48ItdJg9KJHpqCk8w0GL2rhwP+K9FPHhIokEAR0zZq5MqW8wRPR0ibWUmQKUN7D4ED85XLA==",
       "dev": true,
       "requires": {
-        "babel-runtime": "^5.8.25",
-        "junit-report-builder": "^1.1.1",
-        "mkdirp": "^0.5.1"
-      },
-      "dependencies": {
-        "babel-runtime": {
-          "version": "5.8.38",
-          "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-5.8.38.tgz",
-          "integrity": "sha1-HAsC62MxL18If/IEUIJ7QlydTBk=",
-          "dev": true,
-          "requires": {
-            "core-js": "^1.0.0"
-          }
-        },
-        "core-js": {
-          "version": "1.2.7",
-          "resolved": "https://registry.npmjs.org/core-js/-/core-js-1.2.7.tgz",
-          "integrity": "sha1-ZSKUwUZR2yj6k70tX/KYOk8IxjY=",
-          "dev": true
-        }
+        "junit-report-builder": "~1.3.0",
+        "lodash.get": "^4.4.2",
+        "mkdirp": "~0.5.1"
       }
     },
     "wdio-mediawiki": {
       }
     },
     "wdio-sauce-service": {
-      "version": "0.3.1",
-      "resolved": "https://registry.npmjs.org/wdio-sauce-service/-/wdio-sauce-service-0.3.1.tgz",
-      "integrity": "sha1-++wJG+UeaUgkGnsMdmAKfnguqM0=",
+      "version": "0.4.14",
+      "resolved": "https://registry.npmjs.org/wdio-sauce-service/-/wdio-sauce-service-0.4.14.tgz",
+      "integrity": "sha512-LlnMHVzbuaF69CzcqzJiMAkJbdOTlsX3vRqD4cf3eE3UTC6rdRN9DhFCFBeQq6KW1L2bE1LbegFteo0V4Nilkw==",
       "dev": true,
       "requires": {
-        "request": "^2.67.0",
-        "sauce-connect-launcher": "^1.1.1"
+        "request": "^2.88.0",
+        "sauce-connect-launcher": "~1.2.3"
       }
     },
     "wdio-spec-reporter": {
-      "version": "0.0.5",
-      "resolved": "https://registry.npmjs.org/wdio-spec-reporter/-/wdio-spec-reporter-0.0.5.tgz",
-      "integrity": "sha1-0PuP0UrxU/4BAFG7dAqjCrMQY/U=",
+      "version": "0.1.5",
+      "resolved": "https://registry.npmjs.org/wdio-spec-reporter/-/wdio-spec-reporter-0.1.5.tgz",
+      "integrity": "sha512-MqvgTow8hFwhFT47q67JwyJyeynKodGRQCxF7ijKPGfsaG1NLssbXYc0JhiL7SiAyxnQxII0UxzTCd3I6sEdkg==",
       "dev": true,
       "requires": {
-        "babel-runtime": "^5.8.25",
-        "humanize-duration": "^3.9.0"
+        "babel-runtime": "~6.26.0",
+        "chalk": "^2.3.0",
+        "humanize-duration": "~3.15.0"
       }
     },
     "wdio-sync": {
       }
     },
     "webdriverio": {
-      "version": "4.12.0",
-      "resolved": "https://registry.npmjs.org/webdriverio/-/webdriverio-4.12.0.tgz",
-      "integrity": "sha1-40De8nIYPIFopN0LOCMi+de+4Q0=",
+      "version": "4.14.4",
+      "resolved": "https://registry.npmjs.org/webdriverio/-/webdriverio-4.14.4.tgz",
+      "integrity": "sha512-Knp2vzuzP5c5ybgLu+zTwy/l1Gh0bRP4zAr8NWcrStbuomm9Krn9oRF0rZucT6AyORpXinETzmeowFwIoo7mNA==",
       "dev": true,
       "requires": {
         "archiver": "~2.1.0",
         "babel-runtime": "^6.26.0",
-        "css-parse": "~2.0.0",
+        "css-parse": "^2.0.0",
         "css-value": "~0.0.1",
         "deepmerge": "~2.0.1",
         "ejs": "~2.5.6",
         "gaze": "~1.1.2",
         "glob": "~7.1.1",
+        "grapheme-splitter": "^1.0.2",
         "inquirer": "~3.3.0",
         "json-stringify-safe": "~5.0.1",
         "mkdirp": "~0.5.1",
         "npm-install-package": "~2.1.0",
         "optimist": "~0.6.1",
         "q": "~1.5.0",
-        "request": "~2.83.0",
-        "rgb2hex": "~0.1.0",
+        "request": "^2.83.0",
+        "rgb2hex": "^0.1.9",
         "safe-buffer": "~5.1.1",
         "supports-color": "~5.0.0",
         "url": "~0.11.0",
         "wgxpath": "~1.0.0"
       },
       "dependencies": {
-        "ajv": {
-          "version": "5.5.2",
-          "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz",
-          "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=",
-          "dev": true,
-          "requires": {
-            "co": "^4.6.0",
-            "fast-deep-equal": "^1.0.0",
-            "fast-json-stable-stringify": "^2.0.0",
-            "json-schema-traverse": "^0.3.0"
-          }
-        },
-        "babel-runtime": {
-          "version": "6.26.0",
-          "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz",
-          "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=",
-          "dev": true,
-          "requires": {
-            "core-js": "^2.4.0",
-            "regenerator-runtime": "^0.11.0"
-          }
-        },
         "chardet": {
           "version": "0.4.2",
           "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.4.2.tgz",
             "tmp": "^0.0.33"
           }
         },
-        "fast-deep-equal": {
-          "version": "1.1.0",
-          "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz",
-          "integrity": "sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ=",
-          "dev": true
-        },
-        "har-validator": {
-          "version": "5.0.3",
-          "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.0.3.tgz",
-          "integrity": "sha1-ukAsJmGU8VlW7xXg/PJCmT9qff0=",
-          "dev": true,
-          "requires": {
-            "ajv": "^5.1.0",
-            "har-schema": "^2.0.0"
-          }
-        },
         "has-flag": {
           "version": "2.0.0",
           "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz",
             "through": "^2.3.6"
           }
         },
-        "json-schema-traverse": {
-          "version": "0.3.1",
-          "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz",
-          "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=",
-          "dev": true
-        },
-        "oauth-sign": {
-          "version": "0.8.2",
-          "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz",
-          "integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM=",
-          "dev": true
-        },
-        "punycode": {
-          "version": "1.4.1",
-          "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz",
-          "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=",
-          "dev": true
-        },
-        "qs": {
-          "version": "6.5.2",
-          "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz",
-          "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==",
-          "dev": true
-        },
-        "request": {
-          "version": "2.83.0",
-          "resolved": "https://registry.npmjs.org/request/-/request-2.83.0.tgz",
-          "integrity": "sha512-lR3gD69osqm6EYLk9wB/G1W/laGWjzH90t1vEa2xuxHD5KUrSzp9pUSfTm+YC5Nxt2T8nMPEvKlhbQayU7bgFw==",
-          "dev": true,
-          "requires": {
-            "aws-sign2": "~0.7.0",
-            "aws4": "^1.6.0",
-            "caseless": "~0.12.0",
-            "combined-stream": "~1.0.5",
-            "extend": "~3.0.1",
-            "forever-agent": "~0.6.1",
-            "form-data": "~2.3.1",
-            "har-validator": "~5.0.3",
-            "hawk": "~6.0.2",
-            "http-signature": "~1.2.0",
-            "is-typedarray": "~1.0.0",
-            "isstream": "~0.1.2",
-            "json-stringify-safe": "~5.0.1",
-            "mime-types": "~2.1.17",
-            "oauth-sign": "~0.8.2",
-            "performance-now": "^2.1.0",
-            "qs": "~6.5.1",
-            "safe-buffer": "^5.1.1",
-            "stringstream": "~0.0.5",
-            "tough-cookie": "~2.3.3",
-            "tunnel-agent": "^0.6.0",
-            "uuid": "^3.1.0"
-          }
-        },
         "supports-color": {
           "version": "5.0.1",
           "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.0.1.tgz",
           "requires": {
             "has-flag": "^2.0.0"
           }
-        },
-        "tough-cookie": {
-          "version": "2.3.4",
-          "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.4.tgz",
-          "integrity": "sha512-TZ6TTfI5NtZnuyy/Kecv+CnoROnyXn2DN97LontgQpCwsX2XyLYCC0ENhYkehSOwAp8rTQKc/NUIF7BkQ5rKLA==",
-          "dev": true,
-          "requires": {
-            "punycode": "^1.4.1"
-          }
         }
       }
     },
index 9f14c78..f16b605 100644 (file)
@@ -11,7 +11,7 @@
     "selenium-test": "wdio ./tests/selenium/wdio.conf.js"
   },
   "devDependencies": {
-    "eslint-config-wikimedia": "0.12.0",
+    "eslint-config-wikimedia": "0.13.0",
     "grunt": "1.0.4",
     "grunt-banana-checker": "0.7.0",
     "grunt-contrib-copy": "1.0.0",
     "postcss-less": "2.0.0",
     "qunit": "2.9.1",
     "stylelint-config-wikimedia": "0.6.0",
-    "wdio-junit-reporter": "0.2.0",
+    "wdio-junit-reporter": "0.4.4",
     "wdio-mediawiki": "file:tests/selenium/wdio-mediawiki",
     "wdio-mocha-framework": "0.6.4",
-    "wdio-sauce-service": "0.3.1",
-    "wdio-spec-reporter": "0.0.5",
-    "webdriverio": "4.12.0"
+    "wdio-sauce-service": "0.4.14",
+    "wdio-spec-reporter": "0.1.5",
+    "webdriverio": "4.14.4"
   }
 }
index 159adbc..2d182a6 100644 (file)
                <ini name="memory_limit" value="512M" />
        </php>
        <testsuites>
-               <testsuite name="unit">
+               <testsuite name="core:unit">
                        <directory>tests/phpunit/unit</directory>
-                       <directory>**/**/tests/phpunit/unit</directory>
                </testsuite>
-               <testsuite name="integration">
+               <testsuite name="extensions:unit">
+                       <directory>extensions/**/tests/phpunit/unit</directory>
+               </testsuite>
+               <testsuite name="skins:unit">
+                       <directory>skins/**/tests/phpunit/unit</directory>
+               </testsuite>
+               <testsuite name="core:integration">
                        <directory>tests/phpunit/integration</directory>
-                       <directory>**/**/tests/phpunit/integration</directory>
+               </testsuite>
+               <testsuite name="extensions:integration">
+                       <directory>extensions/**/tests/phpunit/integration</directory>
+               </testsuite>
+               <testsuite name="skins:integration">
+                       <directory>skins/**/tests/phpunit/integration</directory>
                </testsuite>
        </testsuites>
        <groups>
index 39eb0e8..6298086 100644 (file)
@@ -39,11 +39,6 @@ return [
                'class' => ResourceLoaderWikiModule::class,
                'styles' => [ 'MediaWiki:Filepage.css' ],
        ],
-       'user.groups' => [
-               // Merged into 'user' since MediaWiki 1.28 - kept for back-compat
-               'dependencies' => 'user',
-               'targets' => [ 'desktop', 'mobile' ],
-       ],
 
        // Scripts managed by the current user (stored in their user space)
        'user' => [ 'class' => ResourceLoaderUserModule::class ],
@@ -2820,14 +2815,7 @@ return [
                ],
        ],
 
-       /**
-        * html5shiv
-        *
-        * This library is intended to run on older browsers
-        * that MediaWiki no longer supports as Grade A, and
-        * is not loaded through the normal module loading
-        * system.
-        */
+       // @todo FIXME: Remove 7 days after Ib0020b6bd0156 is deployed to all wikis.
        'html5shiv' => [
                'scripts' => [
                        'resources/lib/html5shiv/html5shiv.js'
index d34b06c..7a131da 100644 (file)
@@ -83,6 +83,7 @@
                // eslint-disable-next-line no-jquery/no-map-util
                return $.map( node.childNodes, function ( elem ) {
                        if ( elem.nodeType === Node.ELEMENT_NODE ) {
+                               // eslint-disable-next-line no-jquery/no-class-state
                                if ( $( elem ).hasClass( 'reference' ) ) {
                                        return null;
                                }
 
                while ( i < l ) {
                        // if this is a child row, continue to the next row (as buildCache())
+                       // eslint-disable-next-line no-jquery/no-class-state
                        if ( rows[ rowIndex ] && !$( rows[ rowIndex ] ).hasClass( config.cssChildRow ) ) {
                                if ( rowIndex !== lastRowIndex ) {
                                        lastRowIndex = rowIndex;
 
                        // if this is a child row, add it to the last row's children and
                        // continue to the next row
+                       // eslint-disable-next-line no-jquery/no-class-state
                        if ( $row.hasClass( config.cssChildRow ) ) {
                                cache.row[ cache.row.length - 1 ] = cache.row[ cache.row.length - 1 ].add( $row );
                                // go to the next for loop
                        $cell = $( this );
                        columns = [];
 
+                       // eslint-disable-next-line no-jquery/no-class-state
                        if ( !$cell.hasClass( config.unsortableClass ) ) {
                                $cell
                                        .addClass( config.cssHeader )
 
                        $row = $rows.eq( i );
                        // if this is a child row, continue to the next row (as buildCache())
+                       // eslint-disable-next-line no-jquery/no-class-state
                        if ( $row.hasClass( config.cssChildRow ) ) {
                                // go to the next for loop
                                continue;
index 08bb601..70c32b9 100644 (file)
@@ -88,6 +88,7 @@
                        sideMargin = 'marginLeft';
                }
 
+               // eslint-disable-next-line no-jquery/no-class-state
                if ( $element.hasClass( 'jquery-confirmable-element' ) ) {
                        $wrapper = $element.closest( '.jquery-confirmable-wrapper' );
                        $interface = $wrapper.find( '.jquery-confirmable-interface' );
index b9c13f0..20bd405 100644 (file)
                if ( options.wasCollapsed !== undefined ) {
                        wasCollapsed = options.wasCollapsed;
                } else {
+                       // eslint-disable-next-line no-jquery/no-class-state
                        wasCollapsed = $collapsible.hasClass( 'mw-collapsed' );
                }
 
                        } );
 
                        // Initial state
+                       // eslint-disable-next-line no-jquery/no-class-state
                        if ( options.collapsed || $collapsible.hasClass( 'mw-collapsed' ) ) {
                                // One toggler can hook to multiple elements, and one element can have
                                // multiple togglers. This is the sanest way to handle that.
index 5111295..f4aea72 100644 (file)
                                context.data.prevText = '';
                        } else if (
                                val !== context.data.prevText ||
+                               // eslint-disable-next-line no-jquery/no-sizzle
                                !context.data.$container.is( ':visible' )
                        ) {
                                context.data.prevText = val;
         */
        function keypress( e, context, key ) {
                var selected,
+                       // eslint-disable-next-line no-jquery/no-sizzle
                        wasVisible = context.data.$container.is( ':visible' ),
                        preventDefault = false;
 
index e638108..5b43847 100644 (file)
@@ -80,15 +80,21 @@ $( function () {
                        $copyAction = $copyForm.find( '> [name="action"]' );
 
                        // Remove action=historysubmit and ids[..]=..
+                       // eslint-disable-next-line no-jquery/no-class-state
                        if ( $historySubmitter.hasClass( 'mw-history-compareselectedversions-button' ) ) {
                                $copyAction.remove();
                                $copyForm.find( 'input[name^="ids["]:checked' ).prop( 'checked', false );
 
                        // Remove diff=&oldid=, change action=historysubmit to revisiondelete, remove revisiondelete
-                       } else if ( $historySubmitter.hasClass( 'mw-history-revisiondelete-button' ) ||
-                                       $historySubmitter.hasClass( 'mw-history-editchangetags-button' ) ) {
+                       } else if (
+                               // eslint-disable-next-line no-jquery/no-class-state
+                               $historySubmitter.hasClass( 'mw-history-revisiondelete-button' ) ||
+                               // eslint-disable-next-line no-jquery/no-class-state
+                               $historySubmitter.hasClass( 'mw-history-editchangetags-button' )
+                       ) {
                                $copyRadios.remove();
                                $copyAction.val( $historySubmitter.attr( 'name' ) );
+                               // eslint-disable-next-line no-jquery/no-sizzle
                                $copyForm.find( ':submit' ).remove();
                        }
 
index 393846d..4db8445 100644 (file)
@@ -30,6 +30,7 @@
                                                e.type === 'click' ||
                                                e.type === 'keypress' && e.which === 13
                                        ) {
+                                               // eslint-disable-next-line no-jquery/no-class-state
                                                if ( $table.hasClass( 'collapsed' ) ) {
                                                        // From collapsed to expanded. Button will now collapse.
                                                        $( this ).text( collapseText );
@@ -37,6 +38,7 @@
                                                        // From expanded to collapsed. Button will now expand.
                                                        $( this ).text( expandText );
                                                }
+                                               // eslint-disable-next-line no-jquery/no-class-state
                                                $table.toggleClass( 'collapsed' );
                                        }
                                } );
index ecaddd8..674584b 100644 (file)
                        };
                        if (
                                $oldErrorBox !== $errorBox &&
+                               // eslint-disable-next-line no-jquery/no-class-state
                                ( $oldErrorBox.hasClass( 'error' ) || $oldErrorBox.hasClass( 'warning' ) )
                        ) {
                                // eslint-disable-next-line no-jquery/no-slide
index 8ead7a4..99eebae 100644 (file)
                        var $element = $( this ),
                                deleteButton;
 
+                       // eslint-disable-next-line no-jquery/no-class-state
                        if ( $element.hasClass( 'oo-ui-widget' ) ) {
                                deleteButton = OO.ui.infuse( $element );
                                deleteButton.on( 'click', function () {
                                        deleteButton.$element.closest( 'li.mw-htmlform-cloner-li' ).remove();
                                } );
                        } else {
+                               // eslint-disable-next-line no-jquery/no-sizzle
                                $element.filter( ':input' ).on( 'click', function ( e ) {
                                        e.preventDefault();
                                        $( this ).closest( 'li.mw-htmlform-cloner-li' ).remove();
                        }
                } );
 
+               // eslint-disable-next-line no-jquery/no-class-state
                if ( $createElement.hasClass( 'oo-ui-widget' ) ) {
                        createButton = OO.ui.infuse( $createElement );
                        createButton.on( 'click', function () {
                                appendToCloner( createButton.$element );
                        } );
                } else {
+                       // eslint-disable-next-line no-jquery/no-sizzle
                        $createElement.filter( ':input' ).on( 'click', function ( e ) {
                                e.preventDefault();
 
index c56aada..f550a91 100644 (file)
 
                        $link = $( this );
 
+                       // eslint-disable-next-line no-jquery/no-class-state
                        if ( $link.hasClass( 'loading' ) ) {
                                return;
                        }
index 78cd8f4..1a5ae6c 100644 (file)
@@ -262,6 +262,7 @@ ChangesListWrapperWidget.prototype.updateEnhancedParentHighlight = function () {
 
                // Collect the relevant classes from the first nested child
                firstChildClasses = activeHighlightClasses.filter( function ( className ) {
+                       // eslint-disable-next-line no-jquery/no-class-state
                        return $table.find( 'tr:nth-child(2)' ).hasClass( className );
                } );
                // Filter the non-head rows and see if they all have the same classes
@@ -271,6 +272,7 @@ ChangesListWrapperWidget.prototype.updateEnhancedParentHighlight = function () {
                                $this = $( this );
 
                        classesInThisRow = activeHighlightClasses.filter( function ( className ) {
+                               // eslint-disable-next-line no-jquery/no-class-state
                                return $this.hasClass( className );
                        } );
 
index ab75653..3429590 100644 (file)
@@ -711,6 +711,7 @@ FilterTagMultiselectWidget.prototype.createTagItemWidget = function ( data ) {
 
 FilterTagMultiselectWidget.prototype.emphasize = function () {
        if (
+               // eslint-disable-next-line no-jquery/no-class-state
                !this.$handle.hasClass( 'mw-rcfilters-ui-filterTagMultiselectWidget-animate' )
        ) {
                this.$handle
index df12b2e..ee70b71 100644 (file)
                                        .text( query );
                        }
 
+                       // eslint-disable-next-line no-jquery/no-class-state
                        if ( $el.parent().hasClass( 'mw-searchSuggest-link' ) ) {
                                $el.parent().attr( 'href', formData.baseHref + $.param( formData.linkParams ) + '&fulltext=1' );
                        } else {
index bc8ca37..6a1d66a 100644 (file)
@@ -6,6 +6,7 @@
        function updateImportSubprojectList() {
                var $projectField = $( '#mw-import-table-interwiki #interwiki' ),
                        $subprojectField = $projectField.parent().find( '#subproject' ),
+                       // eslint-disable-next-line no-jquery/no-sizzle
                        $selected = $projectField.find( ':selected' ),
                        oldValue = $subprojectField.val(),
                        option, options;
index 55d7ce9..1eeedfb 100644 (file)
@@ -10,6 +10,7 @@
                // (This function could be changed to infuse and check OOUI widgets, but that would only make it
                // slower and more complicated. It works fine to treat them as HTML elements.)
                function isPrefsChanged() {
+                       // eslint-disable-next-line no-jquery/no-sizzle
                        var inputs = $( '#mw-prefs-form :input[name]' ),
                                input, $input, inputType,
                                index, optIndex,
index 53617ca..abc8d7b 100644 (file)
@@ -17,6 +17,7 @@
                        mw.loader.load( 'mediawiki.notification' );
 
                        // Use the class to determine whether to watch or unwatch
+                       // eslint-disable-next-line no-jquery/no-class-state
                        if ( !$subjectLink.hasClass( 'mw-watched-item' ) ) {
                                $link.text( mw.msg( 'watching' ) );
                                promise = api.watch( title ).done( function () {
index 2d60b1d..e8373c3 100644 (file)
 
                                // Depending on whether we are watching or unwatching, for each entry of the page (and its associated page i.e. Talk),
                                // change the text, tooltip, and non-JS href of the (un)watch button, and update the styling of the watchlist entry.
+                               // eslint-disable-next-line no-jquery/no-class-state
                                if ( $unwatchLink.hasClass( 'mw-unwatch-link' ) ) {
                                        api.unwatch( pageTitle )
                                                .done( function () {
index c1066f2..8c69047 100644 (file)
@@ -13,6 +13,7 @@
 
                        // Hide/show the table of contents element
                        function toggleToc() {
+                               // eslint-disable-next-line no-jquery/no-class-state
                                if ( $this.hasClass( 'tochidden' ) ) {
                                        // FIXME: Use CSS transitions
                                        // eslint-disable-next-line no-jquery/no-slide
index 56bfc42..36a0195 100644 (file)
@@ -2,8 +2,7 @@
        'use strict';
 
        var util,
-               config = require( './config.json' ),
-               origConfig = config;
+               config = require( './config.json' );
 
        /**
         * Encode the string like PHP's rawurlencode
         */
        util = {
 
-               /* Main body */
-
-               setOptionsForTest: function ( opts ) {
-                       if ( !window.QUnit ) {
-                               throw new Error( 'Modifying options not allowed outside unit tests' );
-                       }
-                       config = $.extend( {}, config, opts );
-               },
-
-               resetOptionsForTest: function () {
-                       if ( !window.QUnit ) {
-                               throw new Error( 'Resetting options not allowed outside unit tests' );
-                       }
-                       config = origConfig;
-               },
-
                /**
                 * Encode the string like PHP's rawurlencode
                 *
                        $portlet.removeClass( 'emptyPortlet' );
 
                        // Setup the list item (and a span if $portlet is a Vector tab)
+                       // eslint-disable-next-line no-jquery/no-class-state
                        if ( $portlet.hasClass( 'vectorTabs' ) ) {
                                item = $( '<li>' ).append( $( '<span>' ).append( link )[ 0 ] )[ 0 ];
                        } else {
                }
        };
 
+       // Not allowed outside unit tests
+       if ( window.QUnit ) {
+               util.setOptionsForTest = function ( opts ) {
+                       var oldConfig = config;
+                       config = $.extend( {}, config, opts );
+                       return oldConfig;
+               };
+       }
+
        /**
         * Initialisation of mw.util.$content
         */
index 9fc7edb..2e78ba7 100644 (file)
        mw.widgets.MediaSearchWidget.prototype.runLayoutQueue = function () {
                var i, len;
 
+               // eslint-disable-next-line no-jquery/no-sizzle
                if ( this.$element.is( ':visible' ) ) {
                        for ( i = 0, len = this.layoutQueue.length; i < len; i++ ) {
                                this.layoutQueue.pop()();
index c25db2f..5ca39d5 100644 (file)
                if (
                        !this.isDisabled() &&
                        e.which === 1 &&
+                       // eslint-disable-next-line no-jquery/no-class-state
                        $( e.target ).hasClass( targetClass )
                ) {
                        this.deactivate( true );
index 5e9b6ab..0f044f8 100644 (file)
@@ -1,7 +1,6 @@
 /*!
  * Augment mw.loader to facilitate module-level profiling.
  *
- * @author Timo Tijhof
  * @since 1.32
  */
 /* global mw */
index 388b914..5d83b7e 100644 (file)
@@ -481,6 +481,26 @@ class HtmlTest extends MediaWikiTestCase {
                        ),
                        'Namespace selector namespace filtering.'
                );
+               $this->assertEquals(
+                       '<select id="namespace" name="namespace">' . "\n" .
+                               '<option value="" selected="">todos</option>' . "\n" .
+                               '<option value="2">User</option>' . "\n" .
+                               '<option value="4">MyWiki</option>' . "\n" .
+                               '<option value="5">MyWiki Talk</option>' . "\n" .
+                               '<option value="6">File</option>' . "\n" .
+                               '<option value="7">File talk</option>' . "\n" .
+                               '<option value="8">MediaWiki</option>' . "\n" .
+                               '<option value="9">MediaWiki talk</option>' . "\n" .
+                               '<option value="10">Template</option>' . "\n" .
+                               '<option value="11">Template talk</option>' . "\n" .
+                               '<option value="14">Category</option>' . "\n" .
+                               '<option value="15">Category talk</option>' . "\n" .
+                               '</select>',
+                       Html::namespaceSelector(
+                               [ 'exclude' => [ 0, 1, 3, 100, 101 ], 'all' => '' ]
+                       ),
+                       'Namespace selector namespace filtering with empty custom "all" option.'
+               );
        }
 
        /**
index 243a90d..448eec8 100644 (file)
@@ -2674,11 +2674,11 @@ class OutputPageTest extends MediaWikiTestCase {
                return [
                        'empty' => [
                                'exemptStyleModules' => [],
-                               '<meta name="ResourceLoaderDynamicStyles" content=""/>',
+                               '',
                        ],
                        'empty sets' => [
                                'exemptStyleModules' => [ 'site' => [], 'noscript' => [], 'private' => [], 'user' => [] ],
-                               '<meta name="ResourceLoaderDynamicStyles" content=""/>',
+                               '',
                        ],
                        'default logged-out' => [
                                'exemptStyleModules' => [ 'site' => [ 'site.styles' ] ],
index 88a3f43..3da73c1 100644 (file)
@@ -1105,8 +1105,8 @@ class PermissionManagerTest extends MediaWikiLangTestCase {
                ] );
                $this->user->mBlock->mTimestamp = 0;
                $this->assertEquals( [ [ 'autoblockedtext',
-                       '[[User:Useruser|Useruser]]', 'no reason given', '127.0.0.1',
-                       'Useruser', null, 'infinite', '127.0.8.1',
+                       "[[User:Useruser|\u{202A}Useruser\u{202C}]]", 'no reason given', '127.0.0.1',
+                       "\u{202A}Useruser\u{202C}", null, 'infinite', '127.0.8.1',
                        $wgLang->timeanddate( wfTimestamp( TS_MW, $prev ), true ) ] ],
                        MediaWikiServices::getInstance()->getPermissionManager()->getPermissionErrors(
                                'move-target', $this->user, $this->title ) );
@@ -1130,8 +1130,8 @@ class PermissionManagerTest extends MediaWikiLangTestCase {
                        'expiry' => 10,
                ] );
                $this->assertEquals( [ [ 'blockedtext',
-                       '[[User:Useruser|Useruser]]', 'no reason given', '127.0.0.1',
-                       'Useruser', null, '23:00, 31 December 1969', '127.0.8.1',
+                       "[[User:Useruser|\u{202A}Useruser\u{202C}]]", 'no reason given', '127.0.0.1',
+                       "\u{202A}Useruser\u{202C}", null, '23:00, 31 December 1969', '127.0.8.1',
                        $wgLang->timeanddate( wfTimestamp( TS_MW, $now ), true ) ] ],
                        MediaWikiServices::getInstance()->getPermissionManager()
                                ->getPermissionErrors( 'move-target', $this->user, $this->title ) );
@@ -1150,8 +1150,8 @@ class PermissionManagerTest extends MediaWikiLangTestCase {
                ] );
 
                $errors = [ [ 'systemblockedtext',
-                       '[[User:Useruser|Useruser]]', 'no reason given', '127.0.0.1',
-                       'Useruser', 'test', 'infinite', '127.0.8.1',
+                       "[[User:Useruser|\u{202A}Useruser\u{202C}]]", 'no reason given', '127.0.0.1',
+                       "\u{202A}Useruser\u{202C}", 'test', 'infinite', '127.0.8.1',
                        $wgLang->timeanddate( wfTimestamp( TS_MW, $now ), true ) ] ];
 
                $this->assertEquals( $errors,
@@ -1208,8 +1208,8 @@ class PermissionManagerTest extends MediaWikiLangTestCase {
                ] );
 
                $errors = [ [ 'blockedtext-partial',
-                       '[[User:Useruser|Useruser]]', 'no reason given', '127.0.0.1',
-                       'Useruser', null, '23:00, 31 December 1969', '127.0.8.1',
+                       "[[User:Useruser|\u{202A}Useruser\u{202C}]]", 'no reason given', '127.0.0.1',
+                       "\u{202A}Useruser\u{202C}", null, '23:00, 31 December 1969', '127.0.8.1',
                        $wgLang->timeanddate( wfTimestamp( TS_MW, $now ), true ) ] ];
 
                $this->assertEquals( $errors,
@@ -1282,8 +1282,8 @@ class PermissionManagerTest extends MediaWikiLangTestCase {
                ] );
 
                $errors = [ [ 'blockedtext',
-                       '[[User:Useruser|Useruser]]', 'no reason given', '127.0.0.1',
-                       'Useruser', null, 'infinite', '127.0.8.1',
+                       "[[User:Useruser|\u{202A}Useruser\u{202C}]]", 'no reason given', '127.0.0.1',
+                       "\u{202A}Useruser\u{202C}", null, 'infinite', '127.0.8.1',
                        $wgLang->timeanddate( wfTimestamp( TS_MW, $now ), true ) ] ];
 
                $this->assertEquals( $errors,
index 1b6ff2a..6495967 100644 (file)
@@ -77,7 +77,7 @@ class SlotRecordTest extends MediaWikiTestCase {
                $this->assertFalse( $record->isInherited() );
                $this->assertSame( 'A', $record->getContent()->getText() );
                $this->assertSame( 1, $record->getSize() );
-               $this->assertNotNull( $record->getSha1() );
+               $this->assertNotEmpty( $record->getSha1() );
                $this->assertSame( CONTENT_MODEL_WIKITEXT, $record->getModel() );
                $this->assertSame( 2, $record->getRevision() );
                $this->assertSame( 2, $record->getRevision() );
@@ -96,7 +96,7 @@ class SlotRecordTest extends MediaWikiTestCase {
                $this->assertFalse( $record->hasOrigin() );
                $this->assertSame( 'A', $record->getContent()->getText() );
                $this->assertSame( 1, $record->getSize() );
-               $this->assertNotNull( $record->getSha1() );
+               $this->assertNotEmpty( $record->getSha1() );
                $this->assertSame( CONTENT_MODEL_WIKITEXT, $record->getModel() );
                $this->assertSame( 'myRole', $record->getRole() );
        }
@@ -177,6 +177,14 @@ class SlotRecordTest extends MediaWikiTestCase {
                $this->assertSame( $hash, $record->getSha1() );
        }
 
+       public function testHashComputed() {
+               $row = $this->makeRow();
+               $row->content_sha1 = '';
+
+               $rec = new SlotRecord( $row, new WikitextContent( 'A' ) );
+               $this->assertNotEmpty( $rec->getSha1() );
+       }
+
        public function testNewWithSuppressedContent() {
                $input = new SlotRecord( $this->makeRow(), new WikitextContent( 'A' ) );
                $output = SlotRecord::newWithSuppressedContent( $input );
index 150e2ed..e6cf8c8 100644 (file)
@@ -948,8 +948,8 @@ class TitlePermissionTest extends MediaWikiLangTestCase {
                ] );
                $this->user->mBlock->setTimestamp( 0 );
                $this->assertEquals( [ [ 'autoblockedtext',
-                               '[[User:Useruser|Useruser]]', 'no reason given', '127.0.0.1',
-                               'Useruser', null, 'infinite', '127.0.8.1',
+                               "[[User:Useruser|\u{202A}Useruser\u{202C}]]", 'no reason given', '127.0.0.1',
+                               "\u{202A}Useruser\u{202C}", null, 'infinite', '127.0.8.1',
                                $wgLang->timeanddate( wfTimestamp( TS_MW, $prev ), true ) ] ],
                        $this->title->getUserPermissionsErrors( 'move-target',
                                $this->user ) );
@@ -970,8 +970,8 @@ class TitlePermissionTest extends MediaWikiLangTestCase {
                        'expiry' => 10,
                ] );
                $this->assertEquals( [ [ 'blockedtext',
-                               '[[User:Useruser|Useruser]]', 'no reason given', '127.0.0.1',
-                               'Useruser', null, '23:00, 31 December 1969', '127.0.8.1',
+                               "[[User:Useruser|\u{202A}Useruser\u{202C}]]", 'no reason given', '127.0.0.1',
+                               "\u{202A}Useruser\u{202C}", null, '23:00, 31 December 1969', '127.0.8.1',
                                $wgLang->timeanddate( wfTimestamp( TS_MW, $now ), true ) ] ],
                        $this->title->getUserPermissionsErrors( 'move-target', $this->user ) );
                # $action != 'read' && $action != 'createaccount' && $user->isBlockedFrom( $this )
@@ -988,8 +988,8 @@ class TitlePermissionTest extends MediaWikiLangTestCase {
                ] );
 
                $errors = [ [ 'systemblockedtext',
-                               '[[User:Useruser|Useruser]]', 'no reason given', '127.0.0.1',
-                               'Useruser', 'test', 'infinite', '127.0.8.1',
+                               "[[User:Useruser|\u{202A}Useruser\u{202C}]]", 'no reason given', '127.0.0.1',
+                               "\u{202A}Useruser\u{202C}", 'test', 'infinite', '127.0.8.1',
                                $wgLang->timeanddate( wfTimestamp( TS_MW, $now ), true ) ] ];
 
                $this->assertEquals( $errors,
@@ -1034,8 +1034,8 @@ class TitlePermissionTest extends MediaWikiLangTestCase {
                ] );
 
                $errors = [ [ 'blockedtext-partial',
-                               '[[User:Useruser|Useruser]]', 'no reason given', '127.0.0.1',
-                               'Useruser', null, '23:00, 31 December 1969', '127.0.8.1',
+                               "[[User:Useruser|\u{202A}Useruser\u{202C}]]", 'no reason given', '127.0.0.1',
+                               "\u{202A}Useruser\u{202C}", null, '23:00, 31 December 1969', '127.0.8.1',
                                $wgLang->timeanddate( wfTimestamp( TS_MW, $now ), true ) ] ];
 
                $this->assertEquals( $errors,
@@ -1102,8 +1102,8 @@ class TitlePermissionTest extends MediaWikiLangTestCase {
                ] );
 
                $errors = [ [ 'blockedtext',
-                               '[[User:Useruser|Useruser]]', 'no reason given', '127.0.0.1',
-                               'Useruser', null, 'infinite', '127.0.8.1',
+                               "[[User:Useruser|\u{202A}Useruser\u{202C}]]", 'no reason given', '127.0.0.1',
+                               "\u{202A}Useruser\u{202C}", null, 'infinite', '127.0.8.1',
                                $wgLang->timeanddate( wfTimestamp( TS_MW, $now ), true ) ] ];
 
                $this->assertEquals( $errors,
index 1645b85..defa0aa 100644 (file)
@@ -112,7 +112,7 @@ class LoadBalancerTest extends MediaWikiTestCase {
                global $wgDBserver;
 
                // Simulate web request with DBO_TRX
-               $lb = $this->newMultiServerLocalLoadBalancer( DBO_TRX );
+               $lb = $this->newMultiServerLocalLoadBalancer( [], [ 'flags' => DBO_TRX ] );
 
                $this->assertEquals( 8, $lb->getServerCount() );
                $this->assertTrue( $lb->hasReplicaServers() );
@@ -167,12 +167,12 @@ class LoadBalancerTest extends MediaWikiTestCase {
                ] );
        }
 
-       private function newMultiServerLocalLoadBalancer( $flags = DBO_DEFAULT ) {
+       private function newMultiServerLocalLoadBalancer( $lbExtra = [], $srvExtra = [] ) {
                global $wgDBserver, $wgDBname, $wgDBuser, $wgDBpassword, $wgDBtype, $wgSQLiteDataDir;
 
                $servers = [
                        // Master DB
-                       0 => [
+                       0 => $srvExtra + [
                                'host' => $wgDBserver,
                                'dbname' => $wgDBname,
                                'tablePrefix' => $this->dbPrefix(),
@@ -181,10 +181,9 @@ class LoadBalancerTest extends MediaWikiTestCase {
                                'type' => $wgDBtype,
                                'dbDirectory' => $wgSQLiteDataDir,
                                'load' => 0,
-                               'flags' => $flags
                        ],
                        // Main replica DBs
-                       1 => [
+                       1 => $srvExtra + [
                                'host' => $wgDBserver,
                                'dbname' => $wgDBname,
                                'tablePrefix' => $this->dbPrefix(),
@@ -193,9 +192,8 @@ class LoadBalancerTest extends MediaWikiTestCase {
                                'type' => $wgDBtype,
                                'dbDirectory' => $wgSQLiteDataDir,
                                'load' => 100,
-                               'flags' => $flags
                        ],
-                       2 => [
+                       2 => $srvExtra + [
                                'host' => $wgDBserver,
                                'dbname' => $wgDBname,
                                'tablePrefix' => $this->dbPrefix(),
@@ -204,10 +202,9 @@ class LoadBalancerTest extends MediaWikiTestCase {
                                'type' => $wgDBtype,
                                'dbDirectory' => $wgSQLiteDataDir,
                                'load' => 100,
-                               'flags' => $flags
                        ],
                        // RC replica DBs
-                       3 => [
+                       3 => $srvExtra + [
                                'host' => $wgDBserver,
                                'dbname' => $wgDBname,
                                'tablePrefix' => $this->dbPrefix(),
@@ -220,10 +217,9 @@ class LoadBalancerTest extends MediaWikiTestCase {
                                        'recentchanges' => 100,
                                        'watchlist' => 100
                                ],
-                               'flags' => $flags
                        ],
                        // Logging replica DBs
-                       4 => [
+                       4 => $srvExtra + [
                                'host' => $wgDBserver,
                                'dbname' => $wgDBname,
                                'tablePrefix' => $this->dbPrefix(),
@@ -235,9 +231,8 @@ class LoadBalancerTest extends MediaWikiTestCase {
                                'groupLoads' => [
                                        'logging' => 100
                                ],
-                               'flags' => $flags
                        ],
-                       5 => [
+                       5 => $srvExtra + [
                                'host' => $wgDBserver,
                                'dbname' => $wgDBname,
                                'tablePrefix' => $this->dbPrefix(),
@@ -249,10 +244,9 @@ class LoadBalancerTest extends MediaWikiTestCase {
                                'groupLoads' => [
                                        'logging' => 100
                                ],
-                               'flags' => $flags
                        ],
                        // Maintenance query replica DBs
-                       6 => [
+                       6 => $srvExtra + [
                                'host' => $wgDBserver,
                                'dbname' => $wgDBname,
                                'tablePrefix' => $this->dbPrefix(),
@@ -264,10 +258,9 @@ class LoadBalancerTest extends MediaWikiTestCase {
                                'groupLoads' => [
                                        'vslow' => 100
                                ],
-                               'flags' => $flags
                        ],
                        // Replica DB that only has a copy of some static tables
-                       7 => [
+                       7 => $srvExtra + [
                                'host' => $wgDBserver,
                                'dbname' => $wgDBname,
                                'tablePrefix' => $this->dbPrefix(),
@@ -279,12 +272,11 @@ class LoadBalancerTest extends MediaWikiTestCase {
                                'groupLoads' => [
                                        'archive' => 100
                                ],
-                               'flags' => $flags,
                                'is static' => true
                        ]
                ];
 
-               return new LoadBalancer( [
+               return new LoadBalancer( $lbExtra + [
                        'servers' => $servers,
                        'localDomain' => new DatabaseDomain( $wgDBname, null, $this->dbPrefix() ),
                        'queryLogger' => MediaWiki\Logger\LoggerFactory::getInstance( 'DBQuery' ),
@@ -585,7 +577,7 @@ class LoadBalancerTest extends MediaWikiTestCase {
        }
 
        public function testQueryGroupIndex() {
-               $lb = $this->newMultiServerLocalLoadBalancer();
+               $lb = $this->newMultiServerLocalLoadBalancer( [ 'defaultGroup' => false ] );
                /** @var LoadBalancer $lbWrapper */
                $lbWrapper = TestingAccessWrapper::newFromObject( $lb );
 
index a6adf34..1a99775 100644 (file)
@@ -5,179 +5,6 @@
  */
 class FormatJsonTest extends MediaWikiTestCase {
 
-       public static function provideEncoderPrettyPrinting() {
-               return [
-                       // Four spaces
-                       [ true, '    ' ],
-                       [ '    ', '    ' ],
-                       // Two spaces
-                       [ '  ', '  ' ],
-                       // One tab
-                       [ "\t", "\t" ],
-               ];
-       }
-
-       /**
-        * @dataProvider provideEncoderPrettyPrinting
-        */
-       public function testEncoderPrettyPrinting( $pretty, $expectedIndent ) {
-               $obj = [
-                       'emptyObject' => new stdClass,
-                       'emptyArray' => [],
-                       'string' => 'foobar\\',
-                       'filledArray' => [
-                               [
-                                       123,
-                                       456,
-                               ],
-                               // Nested json works without problems
-                               '"7":["8",{"9":"10"}]',
-                               // Whitespace clean up doesn't touch strings that look alike
-                               "{\n\t\"emptyObject\": {\n\t},\n\t\"emptyArray\": [ ]\n}",
-                       ],
-               ];
-
-               // No trailing whitespace, no trailing linefeed
-               $json = '{
-       "emptyObject": {},
-       "emptyArray": [],
-       "string": "foobar\\\\",
-       "filledArray": [
-               [
-                       123,
-                       456
-               ],
-               "\"7\":[\"8\",{\"9\":\"10\"}]",
-               "{\n\t\"emptyObject\": {\n\t},\n\t\"emptyArray\": [ ]\n}"
-       ]
-}';
-
-               $json = str_replace( "\r", '', $json ); // Windows compat
-               $json = str_replace( "\t", $expectedIndent, $json );
-               $this->assertSame( $json, FormatJson::encode( $obj, $pretty ) );
-       }
-
-       public static function provideEncodeDefault() {
-               return self::getEncodeTestCases( [] );
-       }
-
-       /**
-        * @dataProvider provideEncodeDefault
-        */
-       public function testEncodeDefault( $from, $to ) {
-               $this->assertSame( $to, FormatJson::encode( $from ) );
-       }
-
-       public static function provideEncodeUtf8() {
-               return self::getEncodeTestCases( [ 'unicode' ] );
-       }
-
-       /**
-        * @dataProvider provideEncodeUtf8
-        */
-       public function testEncodeUtf8( $from, $to ) {
-               $this->assertSame( $to, FormatJson::encode( $from, false, FormatJson::UTF8_OK ) );
-       }
-
-       public static function provideEncodeXmlMeta() {
-               return self::getEncodeTestCases( [ 'xmlmeta' ] );
-       }
-
-       /**
-        * @dataProvider provideEncodeXmlMeta
-        */
-       public function testEncodeXmlMeta( $from, $to ) {
-               $this->assertSame( $to, FormatJson::encode( $from, false, FormatJson::XMLMETA_OK ) );
-       }
-
-       public static function provideEncodeAllOk() {
-               return self::getEncodeTestCases( [ 'unicode', 'xmlmeta' ] );
-       }
-
-       /**
-        * @dataProvider provideEncodeAllOk
-        */
-       public function testEncodeAllOk( $from, $to ) {
-               $this->assertSame( $to, FormatJson::encode( $from, false, FormatJson::ALL_OK ) );
-       }
-
-       public function testEncodePhpBug46944() {
-               $this->assertNotEquals(
-                       '\ud840\udc00',
-                       strtolower( FormatJson::encode( "\xf0\xa0\x80\x80" ) ),
-                       'Test encoding an broken json_encode character (U+20000)'
-               );
-       }
-
-       public function testEncodeFail() {
-               // Set up a recursive object that can't be encoded.
-               $a = new stdClass;
-               $b = new stdClass;
-               $a->b = $b;
-               $b->a = $a;
-               $this->assertFalse( FormatJson::encode( $a ) );
-       }
-
-       public function testDecodeReturnType() {
-               $this->assertInternalType(
-                       'object',
-                       FormatJson::decode( '{"Name": "Cheeso", "Rank": 7}' ),
-                       'Default to object'
-               );
-
-               $this->assertInternalType(
-                       'array',
-                       FormatJson::decode( '{"Name": "Cheeso", "Rank": 7}', true ),
-                       'Optional array'
-               );
-       }
-
-       public static function provideParse() {
-               return [
-                       [ null ],
-                       [ true ],
-                       [ false ],
-                       [ 0 ],
-                       [ 1 ],
-                       [ 1.2 ],
-                       [ '' ],
-                       [ 'str' ],
-                       [ [ 0, 1, 2 ] ],
-                       [ [ 'a' => 'b' ] ],
-                       [ [ 'a' => 'b' ] ],
-                       [ [ 'a' => 'b', 'x' => [ 'c' => 'd' ] ] ],
-               ];
-       }
-
-       /**
-        * Recursively convert arrays into stdClass
-        * @param array|string|bool|int|float|null $value
-        * @return stdClass|string|bool|int|float|null
-        */
-       public static function toObject( $value ) {
-               return !is_array( $value ) ? $value : (object)array_map( __METHOD__, $value );
-       }
-
-       /**
-        * @dataProvider provideParse
-        * @param mixed $value
-        */
-       public function testParse( $value ) {
-               $expected = self::toObject( $value );
-               $json = FormatJson::encode( $expected, false, FormatJson::ALL_OK );
-               $this->assertJson( $json );
-
-               $st = FormatJson::parse( $json );
-               $this->assertInstanceOf( Status::class, $st );
-               $this->assertTrue( $st->isGood() );
-               $this->assertEquals( $expected, $st->getValue() );
-
-               $st = FormatJson::parse( $json, FormatJson::FORCE_ASSOC );
-               $this->assertInstanceOf( Status::class, $st );
-               $this->assertTrue( $st->isGood() );
-               $this->assertEquals( $value, $st->getValue() );
-       }
-
        /**
         * Test data for testParseTryFixing.
         *
@@ -252,185 +79,4 @@ class FormatJsonTest extends MediaWikiTestCase {
                }
        }
 
-       public static function provideParseErrors() {
-               return [
-                       [ 'aaa' ],
-                       [ '{"j": 1 ] }' ],
-               ];
-       }
-
-       /**
-        * @dataProvider provideParseErrors
-        * @param mixed $value
-        */
-       public function testParseErrors( $value ) {
-               $st = FormatJson::parse( $value );
-               $this->assertInstanceOf( Status::class, $st );
-               $this->assertFalse( $st->isOK() );
-       }
-
-       public function provideStripComments() {
-               return [
-                       [ '{"a":"b"}', '{"a":"b"}' ],
-                       [ "{\"a\":\"b\"}\n", "{\"a\":\"b\"}\n" ],
-                       [ '/*c*/{"c":"b"}', '{"c":"b"}' ],
-                       [ '{"a":"c"}/*c*/', '{"a":"c"}' ],
-                       [ '/*c//d*/{"c":"b"}', '{"c":"b"}' ],
-                       [ '{/*c*/"c":"b"}', '{"c":"b"}' ],
-                       [ "/*\nc\r\n*/{\"c\":\"b\"}", '{"c":"b"}' ],
-                       [ "//c\n{\"c\":\"b\"}", '{"c":"b"}' ],
-                       [ "//c\r\n{\"c\":\"b\"}", '{"c":"b"}' ],
-                       [ '{"a":"c"}//c', '{"a":"c"}' ],
-                       [ "{\"a-c\"://c\n\"b\"}", '{"a-c":"b"}' ],
-                       [ '{"/*a":"b"}', '{"/*a":"b"}' ],
-                       [ '{"a":"//b"}', '{"a":"//b"}' ],
-                       [ '{"a":"b/*c*/"}', '{"a":"b/*c*/"}' ],
-                       [ "{\"\\\"/*a\":\"b\"}", "{\"\\\"/*a\":\"b\"}" ],
-                       [ '', '' ],
-                       [ '/*c', '' ],
-                       [ '//c', '' ],
-                       [ '"http://example.com"', '"http://example.com"' ],
-                       [ "\0", "\0" ],
-                       [ '"Blåbærsyltetøy"', '"Blåbærsyltetøy"' ],
-               ];
-       }
-
-       /**
-        * @covers FormatJson::stripComments
-        * @dataProvider provideStripComments
-        * @param string $json
-        * @param string $expect
-        */
-       public function testStripComments( $json, $expect ) {
-               $this->assertSame( $expect, FormatJson::stripComments( $json ) );
-       }
-
-       public function provideParseStripComments() {
-               return [
-                       [ '/* blah */true', true ],
-                       [ "// blah \ntrue", true ],
-                       [ '[ "a" , /* blah */ "b" ]', [ 'a', 'b' ] ],
-               ];
-       }
-
-       /**
-        * @covers FormatJson::parse
-        * @covers FormatJson::stripComments
-        * @dataProvider provideParseStripComments
-        * @param string $json
-        * @param mixed $expect
-        */
-       public function testParseStripComments( $json, $expect ) {
-               $st = FormatJson::parse( $json, FormatJson::STRIP_COMMENTS );
-               $this->assertInstanceOf( Status::class, $st );
-               $this->assertTrue( $st->isGood() );
-               $this->assertEquals( $expect, $st->getValue() );
-       }
-
-       /**
-        * Generate a set of test cases for a particular combination of encoder options.
-        *
-        * @param array $unescapedGroups List of character groups to leave unescaped
-        * @return array Arrays of unencoded strings and corresponding encoded strings
-        */
-       private static function getEncodeTestCases( array $unescapedGroups ) {
-               $groups = [
-                       'always' => [
-                               // Forward slash (always unescaped)
-                               '/' => '/',
-
-                               // Control characters
-                               "\0" => '\u0000',
-                               "\x08" => '\b',
-                               "\t" => '\t',
-                               "\n" => '\n',
-                               "\r" => '\r',
-                               "\f" => '\f',
-                               "\x1f" => '\u001f', // representative example
-
-                               // Double quotes
-                               '"' => '\"',
-
-                               // Backslashes
-                               '\\' => '\\\\',
-                               '\\\\' => '\\\\\\\\',
-                               '\\u00e9' => '\\\u00e9', // security check for Unicode unescaping
-
-                               // Line terminators
-                               "\xe2\x80\xa8" => '\u2028',
-                               "\xe2\x80\xa9" => '\u2029',
-                       ],
-                       'unicode' => [
-                               "\xc3\xa9" => '\u00e9',
-                               "\xf0\x9d\x92\x9e" => '\ud835\udc9e', // U+1D49E, outside the BMP
-                       ],
-                       'xmlmeta' => [
-                               '<' => '\u003C', // JSON_HEX_TAG uses uppercase hex digits
-                               '>' => '\u003E',
-                               '&' => '\u0026',
-                       ],
-               ];
-
-               $cases = [];
-               foreach ( $groups as $name => $rules ) {
-                       $leaveUnescaped = in_array( $name, $unescapedGroups );
-                       foreach ( $rules as $from => $to ) {
-                               $cases[] = [ $from, '"' . ( $leaveUnescaped ? $from : $to ) . '"' ];
-                       }
-               }
-
-               return $cases;
-       }
-
-       public function provideEmptyJsonKeyStrings() {
-               return [
-                       [
-                               '{"":"foo"}',
-                               '{"":"foo"}',
-                               ''
-                       ],
-                       [
-                               '{"_empty_":"foo"}',
-                               '{"_empty_":"foo"}',
-                               '_empty_' ],
-                       [
-                               '{"\u005F\u0065\u006D\u0070\u0074\u0079\u005F":"foo"}',
-                               '{"_empty_":"foo"}',
-                               '_empty_'
-                       ],
-                       [
-                               '{"_empty_":"bar","":"foo"}',
-                               '{"_empty_":"bar","":"foo"}',
-                               ''
-                       ],
-                       [
-                               '{"":"bar","_empty_":"foo"}',
-                               '{"":"bar","_empty_":"foo"}',
-                               '_empty_'
-                       ]
-               ];
-       }
-
-       /**
-        * @covers FormatJson::encode
-        * @covers FormatJson::decode
-        * @dataProvider provideEmptyJsonKeyStrings
-        * @param string $json
-        *
-        * Decoding behavior with empty keys can be surprising.
-        * See https://phabricator.wikimedia.org/T206411
-        */
-       public function testEmptyJsonKeyArray( $json, $expect, $php71Name ) {
-               // Decoding to array is consistent across supported PHP versions
-               $this->assertSame( $expect, FormatJson::encode(
-                       FormatJson::decode( $json, true ) ) );
-
-               // Decoding to object differs between supported PHP versions
-               $obj = FormatJson::decode( $json );
-               if ( version_compare( PHP_VERSION, '7.1', '<' ) ) {
-                       $this->assertEquals( 'foo', $obj->_empty_ );
-               } else {
-                       $this->assertEquals( 'foo', $obj->{$php71Name} );
-               }
-       }
 }
diff --git a/tests/phpunit/includes/libs/mime/MSCompoundFileReaderTest.php b/tests/phpunit/includes/libs/mime/MSCompoundFileReaderTest.php
deleted file mode 100644 (file)
index 4509a61..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-<?php
-/*
- * Copyright 2019 Wikimedia Foundation
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed
- * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS
- * OF ANY KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations under the License.
- */
-
-/**
- * @group Media
- * @covers MSCompoundFileReader
- */
-class MSCompoundFileReaderTest extends PHPUnit\Framework\TestCase {
-       public static function provideValid() {
-               return [
-                       [ 'calc.xls', 'application/vnd.ms-excel' ],
-                       [ 'excel2016-compat97.xls', 'application/vnd.ms-excel' ],
-                       [ 'gnumeric.xls', 'application/vnd.ms-excel' ],
-                       [ 'impress.ppt', 'application/vnd.ms-powerpoint' ],
-                       [ 'powerpoint2016-compat97.ppt', 'application/vnd.ms-powerpoint' ],
-                       [ 'word2016-compat97.doc', 'application/msword' ],
-                       [ 'writer.doc', 'application/msword' ],
-               ];
-       }
-
-       /** @dataProvider provideValid */
-       public function testReadFile( $fileName, $expectedMime ) {
-               global $IP;
-
-               $info = MSCompoundFileReader::readFile( "$IP/tests/phpunit/data/MSCompoundFileReader/$fileName" );
-               $this->assertTrue( $info['valid'] );
-               $this->assertSame( $expectedMime, $info['mime'] );
-       }
-
-       public static function provideInvalid() {
-               return [
-                       [ 'dir-beyond-end.xls', 'ERROR_READ_PAST_END' ],
-                       [ 'fat-loop.xls', 'ERROR_INVALID_FORMAT' ],
-                       [ 'invalid-signature.xls', 'ERROR_INVALID_SIGNATURE' ],
-               ];
-       }
-
-       /** @dataProvider provideInvalid */
-       public function testReadFileInvalid( $fileName, $expectedError ) {
-               global $IP;
-
-               $info = MSCompoundFileReader::readFile( "$IP/tests/phpunit/data/MSCompoundFileReader/$fileName" );
-               $this->assertFalse( $info['valid'] );
-               $this->assertSame( constant( MSCompoundFileReader::class . '::' . $expectedError ),
-                       $info['errorCode'] );
-       }
-}
index e5ca3df..58f6c05 100644 (file)
@@ -1702,7 +1702,7 @@ class DatabaseSQLTest extends PHPUnit\Framework\TestCase {
                        $this->fail( 'Test exception not thrown' );
                } catch ( DBTransactionError $ex ) {
                        $this->assertSame(
-                               'Cannot execute query from ' . __METHOD__ . ' while transaction status is ERROR.',
+                               'Cannot execute query from ' . __METHOD__ . ' while transaction status is ERROR',
                                $ex->getMessage()
                        );
                }
@@ -1819,7 +1819,7 @@ class DatabaseSQLTest extends PHPUnit\Framework\TestCase {
                } catch ( DBUnexpectedError $e ) {
                        $m = __METHOD__;
                        $this->assertSame(
-                               "Invalid atomic section ended (got {$m}_X but expected {$m}).",
+                               "Invalid atomic section ended (got {$m}_X but expected {$m})",
                                $e->getMessage()
                        );
                }
@@ -1934,7 +1934,7 @@ class DatabaseSQLTest extends PHPUnit\Framework\TestCase {
                        $this->fail( 'Expected exception not thrown' );
                } catch ( DBUnexpectedError $ex ) {
                        $this->assertSame(
-                               'No atomic section is open (got ' . __METHOD__ . ').',
+                               'No atomic section is open (got ' . __METHOD__ . ')',
                                $ex->getMessage()
                        );
                }
@@ -1953,7 +1953,7 @@ class DatabaseSQLTest extends PHPUnit\Framework\TestCase {
                } catch ( DBUnexpectedError $ex ) {
                        $this->assertSame(
                                'Invalid atomic section ended (got ' . __METHOD__ . ' but expected ' .
-                                       __METHOD__ . 'X).',
+                                       __METHOD__ . 'X)',
                                $ex->getMessage()
                        );
                }
@@ -1970,7 +1970,7 @@ class DatabaseSQLTest extends PHPUnit\Framework\TestCase {
                        $this->fail( 'Expected exception not thrown' );
                } catch ( DBTransactionError $ex ) {
                        $this->assertSame(
-                               'Cannot execute query from ' . __METHOD__ . ' while transaction status is ERROR.',
+                               'Cannot execute query from ' . __METHOD__ . ' while transaction status is ERROR',
                                $ex->getMessage()
                        );
                }
@@ -1986,7 +1986,7 @@ class DatabaseSQLTest extends PHPUnit\Framework\TestCase {
                        $this->fail( 'Expected exception not thrown' );
                } catch ( DBUnexpectedError $ex ) {
                        $this->assertSame(
-                               'No atomic section is open (got ' . __METHOD__ . ').',
+                               'No atomic section is open (got ' . __METHOD__ . ')',
                                $ex->getMessage()
                        );
                }
@@ -2074,7 +2074,7 @@ class DatabaseSQLTest extends PHPUnit\Framework\TestCase {
                        $this->fail( 'Expected exception not thrown' );
                } catch ( DBTransactionError $e ) {
                        $this->assertEquals(
-                               'Cannot execute query from ' . __METHOD__ . ' while transaction status is ERROR.',
+                               'Cannot execute query from ' . __METHOD__ . ' while transaction status is ERROR',
                                $e->getMessage()
                        );
                }
@@ -2083,7 +2083,7 @@ class DatabaseSQLTest extends PHPUnit\Framework\TestCase {
                        $this->fail( 'Expected exception not thrown' );
                } catch ( DBTransactionError $e ) {
                        $this->assertEquals(
-                               'Cannot execute query from ' . __METHOD__ . ' while transaction status is ERROR.',
+                               'Cannot execute query from ' . __METHOD__ . ' while transaction status is ERROR',
                                $e->getMessage()
                        );
                }
@@ -2187,7 +2187,7 @@ class DatabaseSQLTest extends PHPUnit\Framework\TestCase {
                        $this->fail( 'Expected exception not thrown' );
                } catch ( DBUnexpectedError $ex ) {
                        $this->assertSame(
-                               "Wikimedia\Rdbms\Database::close: transaction is still open (from $fname).",
+                               "Wikimedia\Rdbms\Database::close: transaction is still open (from $fname)",
                                $ex->getMessage()
                        );
                }
@@ -2216,7 +2216,7 @@ class DatabaseSQLTest extends PHPUnit\Framework\TestCase {
                } catch ( DBUnexpectedError $ex ) {
                        $this->assertSame(
                                'Wikimedia\Rdbms\Database::close: atomic sections ' .
-                               'DatabaseSQLTest::testPrematureClose2 are still open.',
+                               'DatabaseSQLTest::testPrematureClose2 are still open',
                                $ex->getMessage()
                        );
                }
@@ -2239,7 +2239,7 @@ class DatabaseSQLTest extends PHPUnit\Framework\TestCase {
                } catch ( DBUnexpectedError $ex ) {
                        $this->assertSame(
                                'Wikimedia\Rdbms\Database::close: ' .
-                               'mass commit/rollback of peer transaction required (DBO_TRX set).',
+                               'mass commit/rollback of peer transaction required (DBO_TRX set)',
                                $ex->getMessage()
                        );
                }
index 8ddd798..e665d67 100644 (file)
@@ -3,9 +3,6 @@
 use Wikimedia\TestingAccessWrapper;
 
 /**
- * @todo Tests covering decodeCharReferences can be refactored into a single
- * method and dataprovider.
- *
  * @group Sanitizer
  */
 class SanitizerTest extends MediaWikiTestCase {
@@ -15,85 +12,6 @@ class SanitizerTest extends MediaWikiTestCase {
                parent::tearDown();
        }
 
-       /**
-        * @covers Sanitizer::decodeCharReferences
-        */
-       public function testDecodeNamedEntities() {
-               $this->assertEquals(
-                       "\xc3\xa9cole",
-                       Sanitizer::decodeCharReferences( '&eacute;cole' ),
-                       'decode named entities'
-               );
-       }
-
-       /**
-        * @covers Sanitizer::decodeCharReferences
-        */
-       public function testDecodeNumericEntities() {
-               $this->assertEquals(
-                       "\xc4\x88io bonas dans l'\xc3\xa9cole!",
-                       Sanitizer::decodeCharReferences( "&#x108;io bonas dans l'&#233;cole!" ),
-                       'decode numeric entities'
-               );
-       }
-
-       /**
-        * @covers Sanitizer::decodeCharReferences
-        */
-       public function testDecodeMixedEntities() {
-               $this->assertEquals(
-                       "\xc4\x88io bonas dans l'\xc3\xa9cole!",
-                       Sanitizer::decodeCharReferences( "&#x108;io bonas dans l'&eacute;cole!" ),
-                       'decode mixed numeric/named entities'
-               );
-       }
-
-       /**
-        * @covers Sanitizer::decodeCharReferences
-        */
-       public function testDecodeMixedComplexEntities() {
-               $this->assertEquals(
-                       "\xc4\x88io bonas dans l'\xc3\xa9cole! (mais pas &#x108;io dans l'&eacute;cole)",
-                       Sanitizer::decodeCharReferences(
-                               "&#x108;io bonas dans l'&eacute;cole! (mais pas &amp;#x108;io dans l'&#38;eacute;cole)"
-                       ),
-                       'decode mixed complex entities'
-               );
-       }
-
-       /**
-        * @covers Sanitizer::decodeCharReferences
-        */
-       public function testInvalidAmpersand() {
-               $this->assertEquals(
-                       'a & b',
-                       Sanitizer::decodeCharReferences( 'a & b' ),
-                       'Invalid ampersand'
-               );
-       }
-
-       /**
-        * @covers Sanitizer::decodeCharReferences
-        */
-       public function testInvalidEntities() {
-               $this->assertEquals(
-                       '&foo;',
-                       Sanitizer::decodeCharReferences( '&foo;' ),
-                       'Invalid named entity'
-               );
-       }
-
-       /**
-        * @covers Sanitizer::decodeCharReferences
-        */
-       public function testInvalidNumberedEntities() {
-               $this->assertEquals(
-                       UtfNormal\Constants::UTF8_REPLACEMENT,
-                       Sanitizer::decodeCharReferences( "&#88888888888888;" ),
-                       'Invalid numbered entity'
-               );
-       }
-
        /**
         * @covers Sanitizer::removeHTMLtags
         * @dataProvider provideHtml5Tags
@@ -172,82 +90,6 @@ class SanitizerTest extends MediaWikiTestCase {
                $this->assertEquals( $output, Sanitizer::removeHTMLtags( $input ), $msg );
        }
 
-       /**
-        * @dataProvider provideTagAttributesToDecode
-        * @covers Sanitizer::decodeTagAttributes
-        */
-       public function testDecodeTagAttributes( $expected, $attributes, $message = '' ) {
-               $this->assertEquals( $expected,
-                       Sanitizer::decodeTagAttributes( $attributes ),
-                       $message
-               );
-       }
-
-       public static function provideTagAttributesToDecode() {
-               return [
-                       [ [ 'foo' => 'bar' ], 'foo=bar', 'Unquoted attribute' ],
-                       [ [ 'עברית' => 'bar' ], 'עברית=bar', 'Non-Latin attribute' ],
-                       [ [ '६' => 'bar' ], '६=bar', 'Devanagari number' ],
-                       [ [ '搭𨋢' => 'bar' ], '搭𨋢=bar', 'Non-BMP character' ],
-                       [ [], 'ńgh=bar', 'Combining accent is not allowed' ],
-                       [ [ 'foo' => 'bar' ], '    foo   =   bar    ', 'Spaced attribute' ],
-                       [ [ 'foo' => 'bar' ], 'foo="bar"', 'Double-quoted attribute' ],
-                       [ [ 'foo' => 'bar' ], 'foo=\'bar\'', 'Single-quoted attribute' ],
-                       [
-                               [ 'foo' => 'bar', 'baz' => 'foo' ],
-                               'foo=\'bar\'   baz="foo"',
-                               'Several attributes'
-                       ],
-                       [
-                               [ 'foo' => 'bar', 'baz' => 'foo' ],
-                               'foo=\'bar\'   baz="foo"',
-                               'Several attributes'
-                       ],
-                       [
-                               [ 'foo' => 'bar', 'baz' => 'foo' ],
-                               'foo=\'bar\'   baz="foo"',
-                               'Several attributes'
-                       ],
-                       [ [ ':foo' => 'bar' ], ':foo=\'bar\'', 'Leading :' ],
-                       [ [ '_foo' => 'bar' ], '_foo=\'bar\'', 'Leading _' ],
-                       [ [ 'foo' => 'bar' ], 'Foo=\'bar\'', 'Leading capital' ],
-                       [ [ 'foo' => 'BAR' ], 'FOO=BAR', 'Attribute keys are normalized to lowercase' ],
-
-                       # Invalid beginning
-                       [ [], '-foo=bar', 'Leading - is forbidden' ],
-                       [ [], '.foo=bar', 'Leading . is forbidden' ],
-                       [ [ 'foo-bar' => 'bar' ], 'foo-bar=bar', 'A - is allowed inside the attribute' ],
-                       [ [ 'foo-' => 'bar' ], 'foo-=bar', 'A - is allowed inside the attribute' ],
-                       [ [ 'foo.bar' => 'baz' ], 'foo.bar=baz', 'A . is allowed inside the attribute' ],
-                       [ [ 'foo.' => 'baz' ], 'foo.=baz', 'A . is allowed as last character' ],
-                       [ [ 'foo6' => 'baz' ], 'foo6=baz', 'Numbers are allowed' ],
-
-                       # This bit is more relaxed than XML rules, but some extensions use
-                       # it, like ProofreadPage (see T29539)
-                       [ [ '1foo' => 'baz' ], '1foo=baz', 'Leading numbers are allowed' ],
-                       [ [], 'foo$=baz', 'Symbols are not allowed' ],
-                       [ [], 'foo@=baz', 'Symbols are not allowed' ],
-                       [ [], 'foo~=baz', 'Symbols are not allowed' ],
-                       [
-                               [ 'foo' => '1[#^`*%w/(' ],
-                               'foo=1[#^`*%w/(',
-                               'All kind of characters are allowed as values'
-                       ],
-                       [
-                               [ 'foo' => '1[#^`*%\'w/(' ],
-                               'foo="1[#^`*%\'w/("',
-                               'Double quotes are allowed if quoted by single quotes'
-                       ],
-                       [
-                               [ 'foo' => '1[#^`*%"w/(' ],
-                               'foo=\'1[#^`*%"w/(\'',
-                               'Single quotes are allowed if quoted by double quotes'
-                       ],
-                       [ [ 'foo' => '&"' ], 'foo=&amp;&quot;', 'Special chars can be provided as entities' ],
-                       [ [ 'foo' => '&foobar;' ], 'foo=&foobar;', 'Entity-like items are accepted' ],
-               ];
-       }
-
        /**
         * @dataProvider provideDeprecatedAttributes
         * @covers Sanitizer::fixTagAttributes
@@ -291,12 +133,12 @@ class SanitizerTest extends MediaWikiTestCase {
        public static function provideValidateTagAttributes() {
                return [
                        [ 'math',
-                         [ 'id' => 'foo bar', 'bogus' => 'stripped', 'data-foo' => 'bar' ],
-                         [ 'id' => 'foo_bar', 'data-foo' => 'bar' ],
+                               [ 'id' => 'foo bar', 'bogus' => 'stripped', 'data-foo' => 'bar' ],
+                               [ 'id' => 'foo_bar', 'data-foo' => 'bar' ],
                        ],
                        [ 'meta',
-                         [ 'id' => 'foo bar', 'itemprop' => 'foo', 'content' => 'bar' ],
-                         [ 'itemprop' => 'foo', 'content' => 'bar' ],
+                               [ 'id' => 'foo bar', 'itemprop' => 'foo', 'content' => 'bar' ],
+                               [ 'itemprop' => 'foo', 'content' => 'bar' ],
                        ],
                ];
        }
@@ -331,163 +173,6 @@ class SanitizerTest extends MediaWikiTestCase {
                ];
        }
 
-       /**
-        * @dataProvider provideCssCommentsFixtures
-        * @covers Sanitizer::checkCss
-        */
-       public function testCssCommentsChecking( $expected, $css, $message = '' ) {
-               $this->assertEquals( $expected,
-                       Sanitizer::checkCss( $css ),
-                       $message
-               );
-       }
-
-       public static function provideCssCommentsFixtures() {
-               /** [ <expected>, <css>, [message] ] */
-               return [
-                       // Valid comments spanning entire input
-                       [ '/**/', '/**/' ],
-                       [ '/* comment */', '/* comment */' ],
-                       // Weird stuff
-                       [ ' ', '/****/' ],
-                       [ ' ', '/* /* */' ],
-                       [ 'display: block;', "display:/* foo */block;" ],
-                       [ 'display: block;', "display:\\2f\\2a foo \\2a\\2f block;",
-                               'Backslash-escaped comments must be stripped (T30450)' ],
-                       [ '', '/* unfinished comment structure',
-                               'Remove anything after a comment-start token' ],
-                       [ '', "\\2f\\2a unifinished comment'",
-                               'Remove anything after a backslash-escaped comment-start token' ],
-                       [
-                               '/* insecure input */',
-                               'filter: progid:DXImageTransform.Microsoft.AlphaImageLoader'
-                                       . '(src=\'asdf.png\',sizingMethod=\'scale\');'
-                       ],
-                       [
-                               '/* insecure input */',
-                               '-ms-filter: "progid:DXImageTransform.Microsoft.AlphaImageLoader'
-                                       . '(src=\'asdf.png\',sizingMethod=\'scale\')";'
-                       ],
-                       [ '/* insecure input */', 'width: expression(1+1);' ],
-                       [ '/* insecure input */', 'background-image: image(asdf.png);' ],
-                       [ '/* insecure input */', 'background-image: -webkit-image(asdf.png);' ],
-                       [ '/* insecure input */', 'background-image: -moz-image(asdf.png);' ],
-                       [ '/* insecure input */', 'background-image: image-set("asdf.png" 1x, "asdf.png" 2x);' ],
-                       [
-                               '/* insecure input */',
-                               'background-image: -webkit-image-set("asdf.png" 1x, "asdf.png" 2x);'
-                       ],
-                       [
-                               '/* insecure input */',
-                               'background-image: -moz-image-set("asdf.png" 1x, "asdf.png" 2x);'
-                       ],
-                       [ '/* insecure input */', 'foo: attr( title, url );' ],
-                       [ '/* insecure input */', 'foo: attr( title url );' ],
-                       [ '/* insecure input */', 'foo: var(--evil-attribute)' ],
-               ];
-       }
-
-       /**
-        * @dataProvider provideEscapeHtmlAllowEntities
-        * @covers Sanitizer::escapeHtmlAllowEntities
-        */
-       public function testEscapeHtmlAllowEntities( $expected, $html ) {
-               $this->assertEquals(
-                       $expected,
-                       Sanitizer::escapeHtmlAllowEntities( $html )
-               );
-       }
-
-       public static function provideEscapeHtmlAllowEntities() {
-               return [
-                       [ 'foo', 'foo' ],
-                       [ 'a¡b', 'a&#161;b' ],
-                       [ 'foo&#039;bar', "foo'bar" ],
-                       [ '&lt;script&gt;foo&lt;/script&gt;', '<script>foo</script>' ],
-               ];
-       }
-
-       /**
-        * Test Sanitizer::escapeId
-        *
-        * @dataProvider provideEscapeId
-        * @covers Sanitizer::escapeId
-        */
-       public function testEscapeId( $input, $output ) {
-               $this->assertEquals(
-                       $output,
-                       Sanitizer::escapeId( $input, [ 'noninitial', 'legacy' ] )
-               );
-       }
-
-       public static function provideEscapeId() {
-               return [
-                       [ '+', '.2B' ],
-                       [ '&', '.26' ],
-                       [ '=', '.3D' ],
-                       [ ':', ':' ],
-                       [ ';', '.3B' ],
-                       [ '@', '.40' ],
-                       [ '$', '.24' ],
-                       [ '-_.', '-_.' ],
-                       [ '!', '.21' ],
-                       [ '*', '.2A' ],
-                       [ '/', '.2F' ],
-                       [ '[]', '.5B.5D' ],
-                       [ '<>', '.3C.3E' ],
-                       [ '\'', '.27' ],
-                       [ '§', '.C2.A7' ],
-                       [ 'Test:A & B/Here', 'Test:A_.26_B.2FHere' ],
-                       [ 'A&B&amp;C&amp;amp;D&amp;amp;amp;E', 'A.26B.26amp.3BC.26amp.3Bamp.3BD.26amp.3Bamp.3Bamp.3BE' ],
-               ];
-       }
-
-       /**
-        * Test escapeIdReferenceList for consistency with escapeIdForAttribute
-        *
-        * @dataProvider provideEscapeIdReferenceList
-        * @covers Sanitizer::escapeIdReferenceList
-        */
-       public function testEscapeIdReferenceList( $referenceList, $id1, $id2 ) {
-               $this->assertEquals(
-                       Sanitizer::escapeIdReferenceList( $referenceList ),
-                       Sanitizer::escapeIdForAttribute( $id1 )
-                               . ' '
-                               . Sanitizer::escapeIdForAttribute( $id2 )
-               );
-       }
-
-       public static function provideEscapeIdReferenceList() {
-               /** [ <reference list>, <individual id 1>, <individual id 2> ] */
-               return [
-                       [ 'foo bar', 'foo', 'bar' ],
-                       [ '#1 #2', '#1', '#2' ],
-                       [ '+1 +2', '+1', '+2' ],
-               ];
-       }
-
-       /**
-        * @dataProvider provideIsReservedDataAttribute
-        * @covers Sanitizer::isReservedDataAttribute
-        */
-       public function testIsReservedDataAttribute( $attr, $expected ) {
-               $this->assertSame( $expected, Sanitizer::isReservedDataAttribute( $attr ) );
-       }
-
-       public static function provideIsReservedDataAttribute() {
-               return [
-                       [ 'foo', false ],
-                       [ 'data', false ],
-                       [ 'data-foo', false ],
-                       [ 'data-mw', true ],
-                       [ 'data-ooui', true ],
-                       [ 'data-parsoid', true ],
-                       [ 'data-mw-foo', true ],
-                       [ 'data-ooui-foo', true ],
-                       [ 'data-mwfoo', true ], // could be false but this is how it's implemented currently
-               ];
-       }
-
        /**
         * @dataProvider provideEscapeIdForStuff
         *
@@ -560,35 +245,6 @@ class SanitizerTest extends MediaWikiTestCase {
                ];
        }
 
-       /**
-        * @dataProvider provideStripAllTags
-        *
-        * @covers Sanitizer::stripAllTags()
-        * @covers RemexStripTagHandler
-        *
-        * @param string $input
-        * @param string $expected
-        */
-       public function testStripAllTags( $input, $expected ) {
-               $this->assertEquals( $expected, Sanitizer::stripAllTags( $input ) );
-       }
-
-       public function provideStripAllTags() {
-               return [
-                       [ '<p>Foo</p>', 'Foo' ],
-                       [ '<p id="one">Foo</p><p id="two">Bar</p>', 'Foo Bar' ],
-                       [ "<p>Foo</p>\n<p>Bar</p>", 'Foo Bar' ],
-                       [ '<p>Hello &lt;strong&gt; wor&#x6c;&#100; caf&eacute;</p>', 'Hello <strong> world café' ],
-                       [
-                               '<p><small data-foo=\'bar"&lt;baz>quux\'><a href="./Foo">Bar</a></small> Whee!</p>',
-                               'Bar Whee!'
-                       ],
-                       [ '1<span class="<?php">2</span>3', '123' ],
-                       [ '1<span class="<?">2</span>3', '123' ],
-                       [ '<th>1</th><td>2</td>', '1 2' ],
-               ];
-       }
-
        /**
         * @expectedException InvalidArgumentException
         * @covers Sanitizer::escapeIdInternal()
index 88fc93b..37fa030 100644 (file)
@@ -167,7 +167,7 @@ class MediaWikiTestCaseTest extends MediaWikiTestCase {
 
                $lbFactory = MediaWikiServices::getInstance()->getDBLoadBalancerFactory();
                $lb = $lbFactory->newMainLB();
-               $db = $lb->getConnection( DB_REPLICA, DBO_TRX );
+               $db = $lb->getConnection( DB_REPLICA );
 
                // sanity
                $this->assertNotSame( $this->db, $db );
diff --git a/tests/phpunit/unit/includes/json/FormatJsonUnitTest.php b/tests/phpunit/unit/includes/json/FormatJsonUnitTest.php
new file mode 100644 (file)
index 0000000..58ad495
--- /dev/null
@@ -0,0 +1,362 @@
+<?php
+
+/**
+ * @covers FormatJson
+ */
+class FormatJsonUnitTest extends MediaWikiUnitTestCase {
+
+       public static function provideEncoderPrettyPrinting() {
+               return [
+                       // Four spaces
+                       [ true, '    ' ],
+                       [ '    ', '    ' ],
+                       // Two spaces
+                       [ '  ', '  ' ],
+                       // One tab
+                       [ "\t", "\t" ],
+               ];
+       }
+
+       /**
+        * @dataProvider provideEncoderPrettyPrinting
+        */
+       public function testEncoderPrettyPrinting( $pretty, $expectedIndent ) {
+               $obj = [
+                       'emptyObject' => new stdClass,
+                       'emptyArray' => [],
+                       'string' => 'foobar\\',
+                       'filledArray' => [
+                               [
+                                       123,
+                                       456,
+                               ],
+                               // Nested json works without problems
+                               '"7":["8",{"9":"10"}]',
+                               // Whitespace clean up doesn't touch strings that look alike
+                               "{\n\t\"emptyObject\": {\n\t},\n\t\"emptyArray\": [ ]\n}",
+                       ],
+               ];
+
+               // No trailing whitespace, no trailing linefeed
+               $json = '{
+       "emptyObject": {},
+       "emptyArray": [],
+       "string": "foobar\\\\",
+       "filledArray": [
+               [
+                       123,
+                       456
+               ],
+               "\"7\":[\"8\",{\"9\":\"10\"}]",
+               "{\n\t\"emptyObject\": {\n\t},\n\t\"emptyArray\": [ ]\n}"
+       ]
+}';
+
+               $json = str_replace( "\r", '', $json ); // Windows compat
+               $json = str_replace( "\t", $expectedIndent, $json );
+               $this->assertSame( $json, FormatJson::encode( $obj, $pretty ) );
+       }
+
+       public static function provideEncodeDefault() {
+               return self::getEncodeTestCases( [] );
+       }
+
+       /**
+        * @dataProvider provideEncodeDefault
+        */
+       public function testEncodeDefault( $from, $to ) {
+               $this->assertSame( $to, FormatJson::encode( $from ) );
+       }
+
+       public static function provideEncodeUtf8() {
+               return self::getEncodeTestCases( [ 'unicode' ] );
+       }
+
+       /**
+        * @dataProvider provideEncodeUtf8
+        */
+       public function testEncodeUtf8( $from, $to ) {
+               $this->assertSame( $to, FormatJson::encode( $from, false, FormatJson::UTF8_OK ) );
+       }
+
+       public static function provideEncodeXmlMeta() {
+               return self::getEncodeTestCases( [ 'xmlmeta' ] );
+       }
+
+       /**
+        * @dataProvider provideEncodeXmlMeta
+        */
+       public function testEncodeXmlMeta( $from, $to ) {
+               $this->assertSame( $to, FormatJson::encode( $from, false, FormatJson::XMLMETA_OK ) );
+       }
+
+       public static function provideEncodeAllOk() {
+               return self::getEncodeTestCases( [ 'unicode', 'xmlmeta' ] );
+       }
+
+       /**
+        * @dataProvider provideEncodeAllOk
+        */
+       public function testEncodeAllOk( $from, $to ) {
+               $this->assertSame( $to, FormatJson::encode( $from, false, FormatJson::ALL_OK ) );
+       }
+
+       public function testEncodePhpBug46944() {
+               $this->assertNotEquals(
+                       '\ud840\udc00',
+                       strtolower( FormatJson::encode( "\xf0\xa0\x80\x80" ) ),
+                       'Test encoding an broken json_encode character (U+20000)'
+               );
+       }
+
+       public function testEncodeFail() {
+               // Set up a recursive object that can't be encoded.
+               $a = new stdClass;
+               $b = new stdClass;
+               $a->b = $b;
+               $b->a = $a;
+               $this->assertFalse( FormatJson::encode( $a ) );
+       }
+
+       public function testDecodeReturnType() {
+               $this->assertInternalType(
+                       'object',
+                       FormatJson::decode( '{"Name": "Cheeso", "Rank": 7}' ),
+                       'Default to object'
+               );
+
+               $this->assertInternalType(
+                       'array',
+                       FormatJson::decode( '{"Name": "Cheeso", "Rank": 7}', true ),
+                       'Optional array'
+               );
+       }
+
+       public static function provideParse() {
+               return [
+                       [ null ],
+                       [ true ],
+                       [ false ],
+                       [ 0 ],
+                       [ 1 ],
+                       [ 1.2 ],
+                       [ '' ],
+                       [ 'str' ],
+                       [ [ 0, 1, 2 ] ],
+                       [ [ 'a' => 'b' ] ],
+                       [ [ 'a' => 'b' ] ],
+                       [ [ 'a' => 'b', 'x' => [ 'c' => 'd' ] ] ],
+               ];
+       }
+
+       /**
+        * Recursively convert arrays into stdClass
+        * @param array|string|bool|int|float|null $value
+        * @return stdClass|string|bool|int|float|null
+        */
+       public static function toObject( $value ) {
+               return !is_array( $value ) ? $value : (object)array_map( __METHOD__, $value );
+       }
+
+       /**
+        * @dataProvider provideParse
+        * @param mixed $value
+        */
+       public function testParse( $value ) {
+               $expected = self::toObject( $value );
+               $json = FormatJson::encode( $expected, false, FormatJson::ALL_OK );
+               $this->assertJson( $json );
+
+               $st = FormatJson::parse( $json );
+               $this->assertInstanceOf( Status::class, $st );
+               $this->assertTrue( $st->isGood() );
+               $this->assertEquals( $expected, $st->getValue() );
+
+               $st = FormatJson::parse( $json, FormatJson::FORCE_ASSOC );
+               $this->assertInstanceOf( Status::class, $st );
+               $this->assertTrue( $st->isGood() );
+               $this->assertEquals( $value, $st->getValue() );
+       }
+
+       public static function provideParseErrors() {
+               return [
+                       [ 'aaa' ],
+                       [ '{"j": 1 ] }' ],
+               ];
+       }
+
+       /**
+        * @dataProvider provideParseErrors
+        * @param mixed $value
+        */
+       public function testParseErrors( $value ) {
+               $st = FormatJson::parse( $value );
+               $this->assertInstanceOf( Status::class, $st );
+               $this->assertFalse( $st->isOK() );
+       }
+
+       public function provideStripComments() {
+               return [
+                       [ '{"a":"b"}', '{"a":"b"}' ],
+                       [ "{\"a\":\"b\"}\n", "{\"a\":\"b\"}\n" ],
+                       [ '/*c*/{"c":"b"}', '{"c":"b"}' ],
+                       [ '{"a":"c"}/*c*/', '{"a":"c"}' ],
+                       [ '/*c//d*/{"c":"b"}', '{"c":"b"}' ],
+                       [ '{/*c*/"c":"b"}', '{"c":"b"}' ],
+                       [ "/*\nc\r\n*/{\"c\":\"b\"}", '{"c":"b"}' ],
+                       [ "//c\n{\"c\":\"b\"}", '{"c":"b"}' ],
+                       [ "//c\r\n{\"c\":\"b\"}", '{"c":"b"}' ],
+                       [ '{"a":"c"}//c', '{"a":"c"}' ],
+                       [ "{\"a-c\"://c\n\"b\"}", '{"a-c":"b"}' ],
+                       [ '{"/*a":"b"}', '{"/*a":"b"}' ],
+                       [ '{"a":"//b"}', '{"a":"//b"}' ],
+                       [ '{"a":"b/*c*/"}', '{"a":"b/*c*/"}' ],
+                       [ "{\"\\\"/*a\":\"b\"}", "{\"\\\"/*a\":\"b\"}" ],
+                       [ '', '' ],
+                       [ '/*c', '' ],
+                       [ '//c', '' ],
+                       [ '"http://example.com"', '"http://example.com"' ],
+                       [ "\0", "\0" ],
+                       [ '"Blåbærsyltetøy"', '"Blåbærsyltetøy"' ],
+               ];
+       }
+
+       /**
+        * @covers FormatJson::stripComments
+        * @dataProvider provideStripComments
+        * @param string $json
+        * @param string $expect
+        */
+       public function testStripComments( $json, $expect ) {
+               $this->assertSame( $expect, FormatJson::stripComments( $json ) );
+       }
+
+       public function provideParseStripComments() {
+               return [
+                       [ '/* blah */true', true ],
+                       [ "// blah \ntrue", true ],
+                       [ '[ "a" , /* blah */ "b" ]', [ 'a', 'b' ] ],
+               ];
+       }
+
+       /**
+        * @covers FormatJson::parse
+        * @covers FormatJson::stripComments
+        * @dataProvider provideParseStripComments
+        * @param string $json
+        * @param mixed $expect
+        */
+       public function testParseStripComments( $json, $expect ) {
+               $st = FormatJson::parse( $json, FormatJson::STRIP_COMMENTS );
+               $this->assertInstanceOf( Status::class, $st );
+               $this->assertTrue( $st->isGood() );
+               $this->assertEquals( $expect, $st->getValue() );
+       }
+
+       /**
+        * Generate a set of test cases for a particular combination of encoder options.
+        *
+        * @param array $unescapedGroups List of character groups to leave unescaped
+        * @return array Arrays of unencoded strings and corresponding encoded strings
+        */
+       private static function getEncodeTestCases( array $unescapedGroups ) {
+               $groups = [
+                       'always' => [
+                               // Forward slash (always unescaped)
+                               '/' => '/',
+
+                               // Control characters
+                               "\0" => '\u0000',
+                               "\x08" => '\b',
+                               "\t" => '\t',
+                               "\n" => '\n',
+                               "\r" => '\r',
+                               "\f" => '\f',
+                               "\x1f" => '\u001f', // representative example
+
+                               // Double quotes
+                               '"' => '\"',
+
+                               // Backslashes
+                               '\\' => '\\\\',
+                               '\\\\' => '\\\\\\\\',
+                               '\\u00e9' => '\\\u00e9', // security check for Unicode unescaping
+
+                               // Line terminators
+                               "\xe2\x80\xa8" => '\u2028',
+                               "\xe2\x80\xa9" => '\u2029',
+                       ],
+                       'unicode' => [
+                               "\xc3\xa9" => '\u00e9',
+                               "\xf0\x9d\x92\x9e" => '\ud835\udc9e', // U+1D49E, outside the BMP
+                       ],
+                       'xmlmeta' => [
+                               '<' => '\u003C', // JSON_HEX_TAG uses uppercase hex digits
+                               '>' => '\u003E',
+                               '&' => '\u0026',
+                       ],
+               ];
+
+               $cases = [];
+               foreach ( $groups as $name => $rules ) {
+                       $leaveUnescaped = in_array( $name, $unescapedGroups );
+                       foreach ( $rules as $from => $to ) {
+                               $cases[] = [ $from, '"' . ( $leaveUnescaped ? $from : $to ) . '"' ];
+                       }
+               }
+
+               return $cases;
+       }
+
+       public function provideEmptyJsonKeyStrings() {
+               return [
+                       [
+                               '{"":"foo"}',
+                               '{"":"foo"}',
+                               ''
+                       ],
+                       [
+                               '{"_empty_":"foo"}',
+                               '{"_empty_":"foo"}',
+                               '_empty_' ],
+                       [
+                               '{"\u005F\u0065\u006D\u0070\u0074\u0079\u005F":"foo"}',
+                               '{"_empty_":"foo"}',
+                               '_empty_'
+                       ],
+                       [
+                               '{"_empty_":"bar","":"foo"}',
+                               '{"_empty_":"bar","":"foo"}',
+                               ''
+                       ],
+                       [
+                               '{"":"bar","_empty_":"foo"}',
+                               '{"":"bar","_empty_":"foo"}',
+                               '_empty_'
+                       ]
+               ];
+       }
+
+       /**
+        * @covers FormatJson::encode
+        * @covers FormatJson::decode
+        * @dataProvider provideEmptyJsonKeyStrings
+        * @param string $json
+        *
+        * Decoding behavior with empty keys can be surprising.
+        * See https://phabricator.wikimedia.org/T206411
+        */
+       public function testEmptyJsonKeyArray( $json, $expect, $php71Name ) {
+               // Decoding to array is consistent across supported PHP versions
+               $this->assertSame( $expect, FormatJson::encode(
+                       FormatJson::decode( $json, true ) ) );
+
+               // Decoding to object differs between supported PHP versions
+               $obj = FormatJson::decode( $json );
+               if ( version_compare( PHP_VERSION, '7.1', '<' ) ) {
+                       $this->assertEquals( 'foo', $obj->_empty_ );
+               } else {
+                       $this->assertEquals( 'foo', $obj->{$php71Name} );
+               }
+       }
+}
diff --git a/tests/phpunit/unit/includes/libs/mime/MSCompoundFileReaderTest.php b/tests/phpunit/unit/includes/libs/mime/MSCompoundFileReaderTest.php
new file mode 100644 (file)
index 0000000..4509a61
--- /dev/null
@@ -0,0 +1,60 @@
+<?php
+/*
+ * Copyright 2019 Wikimedia Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed
+ * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS
+ * OF ANY KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ */
+
+/**
+ * @group Media
+ * @covers MSCompoundFileReader
+ */
+class MSCompoundFileReaderTest extends PHPUnit\Framework\TestCase {
+       public static function provideValid() {
+               return [
+                       [ 'calc.xls', 'application/vnd.ms-excel' ],
+                       [ 'excel2016-compat97.xls', 'application/vnd.ms-excel' ],
+                       [ 'gnumeric.xls', 'application/vnd.ms-excel' ],
+                       [ 'impress.ppt', 'application/vnd.ms-powerpoint' ],
+                       [ 'powerpoint2016-compat97.ppt', 'application/vnd.ms-powerpoint' ],
+                       [ 'word2016-compat97.doc', 'application/msword' ],
+                       [ 'writer.doc', 'application/msword' ],
+               ];
+       }
+
+       /** @dataProvider provideValid */
+       public function testReadFile( $fileName, $expectedMime ) {
+               global $IP;
+
+               $info = MSCompoundFileReader::readFile( "$IP/tests/phpunit/data/MSCompoundFileReader/$fileName" );
+               $this->assertTrue( $info['valid'] );
+               $this->assertSame( $expectedMime, $info['mime'] );
+       }
+
+       public static function provideInvalid() {
+               return [
+                       [ 'dir-beyond-end.xls', 'ERROR_READ_PAST_END' ],
+                       [ 'fat-loop.xls', 'ERROR_INVALID_FORMAT' ],
+                       [ 'invalid-signature.xls', 'ERROR_INVALID_SIGNATURE' ],
+               ];
+       }
+
+       /** @dataProvider provideInvalid */
+       public function testReadFileInvalid( $fileName, $expectedError ) {
+               global $IP;
+
+               $info = MSCompoundFileReader::readFile( "$IP/tests/phpunit/data/MSCompoundFileReader/$fileName" );
+               $this->assertFalse( $info['valid'] );
+               $this->assertSame( constant( MSCompoundFileReader::class . '::' . $expectedError ),
+                       $info['errorCode'] );
+       }
+}
diff --git a/tests/phpunit/unit/includes/parser/SanitizerUnitTest.php b/tests/phpunit/unit/includes/parser/SanitizerUnitTest.php
new file mode 100644 (file)
index 0000000..71e4fff
--- /dev/null
@@ -0,0 +1,352 @@
+<?php
+
+/**
+ * @todo Tests covering decodeCharReferences can be refactored into a single
+ * method and dataprovider.
+ *
+ * @group Sanitizer
+ */
+class SanitizerUnitTest extends MediaWikiUnitTestCase {
+
+       /**
+        * @covers Sanitizer::decodeCharReferences
+        */
+       public function testDecodeNamedEntities() {
+               $this->assertEquals(
+                       "\xc3\xa9cole",
+                       Sanitizer::decodeCharReferences( '&eacute;cole' ),
+                       'decode named entities'
+               );
+       }
+
+       /**
+        * @covers Sanitizer::decodeCharReferences
+        */
+       public function testDecodeNumericEntities() {
+               $this->assertEquals(
+                       "\xc4\x88io bonas dans l'\xc3\xa9cole!",
+                       Sanitizer::decodeCharReferences( "&#x108;io bonas dans l'&#233;cole!" ),
+                       'decode numeric entities'
+               );
+       }
+
+       /**
+        * @covers Sanitizer::decodeCharReferences
+        */
+       public function testDecodeMixedEntities() {
+               $this->assertEquals(
+                       "\xc4\x88io bonas dans l'\xc3\xa9cole!",
+                       Sanitizer::decodeCharReferences( "&#x108;io bonas dans l'&eacute;cole!" ),
+                       'decode mixed numeric/named entities'
+               );
+       }
+
+       /**
+        * @covers Sanitizer::decodeCharReferences
+        */
+       public function testDecodeMixedComplexEntities() {
+               $this->assertEquals(
+                       "\xc4\x88io bonas dans l'\xc3\xa9cole! (mais pas &#x108;io dans l'&eacute;cole)",
+                       Sanitizer::decodeCharReferences(
+                               "&#x108;io bonas dans l'&eacute;cole! (mais pas &amp;#x108;io dans l'&#38;eacute;cole)"
+                       ),
+                       'decode mixed complex entities'
+               );
+       }
+
+       /**
+        * @covers Sanitizer::decodeCharReferences
+        */
+       public function testInvalidAmpersand() {
+               $this->assertEquals(
+                       'a & b',
+                       Sanitizer::decodeCharReferences( 'a & b' ),
+                       'Invalid ampersand'
+               );
+       }
+
+       /**
+        * @covers Sanitizer::decodeCharReferences
+        */
+       public function testInvalidEntities() {
+               $this->assertEquals(
+                       '&foo;',
+                       Sanitizer::decodeCharReferences( '&foo;' ),
+                       'Invalid named entity'
+               );
+       }
+
+       /**
+        * @covers Sanitizer::decodeCharReferences
+        */
+       public function testInvalidNumberedEntities() {
+               $this->assertEquals(
+                       UtfNormal\Constants::UTF8_REPLACEMENT,
+                       Sanitizer::decodeCharReferences( "&#88888888888888;" ),
+                       'Invalid numbered entity'
+               );
+       }
+
+       /**
+        * @dataProvider provideTagAttributesToDecode
+        * @covers Sanitizer::decodeTagAttributes
+        */
+       public function testDecodeTagAttributes( $expected, $attributes, $message = '' ) {
+               $this->assertEquals( $expected,
+                       Sanitizer::decodeTagAttributes( $attributes ),
+                       $message
+               );
+       }
+
+       public static function provideTagAttributesToDecode() {
+               return [
+                       [ [ 'foo' => 'bar' ], 'foo=bar', 'Unquoted attribute' ],
+                       [ [ 'עברית' => 'bar' ], 'עברית=bar', 'Non-Latin attribute' ],
+                       [ [ '६' => 'bar' ], '६=bar', 'Devanagari number' ],
+                       [ [ '搭𨋢' => 'bar' ], '搭𨋢=bar', 'Non-BMP character' ],
+                       [ [], 'ńgh=bar', 'Combining accent is not allowed' ],
+                       [ [ 'foo' => 'bar' ], '    foo   =   bar    ', 'Spaced attribute' ],
+                       [ [ 'foo' => 'bar' ], 'foo="bar"', 'Double-quoted attribute' ],
+                       [ [ 'foo' => 'bar' ], 'foo=\'bar\'', 'Single-quoted attribute' ],
+                       [
+                               [ 'foo' => 'bar', 'baz' => 'foo' ],
+                               'foo=\'bar\'   baz="foo"',
+                               'Several attributes'
+                       ],
+                       [
+                               [ 'foo' => 'bar', 'baz' => 'foo' ],
+                               'foo=\'bar\'   baz="foo"',
+                               'Several attributes'
+                       ],
+                       [
+                               [ 'foo' => 'bar', 'baz' => 'foo' ],
+                               'foo=\'bar\'   baz="foo"',
+                               'Several attributes'
+                       ],
+                       [ [ ':foo' => 'bar' ], ':foo=\'bar\'', 'Leading :' ],
+                       [ [ '_foo' => 'bar' ], '_foo=\'bar\'', 'Leading _' ],
+                       [ [ 'foo' => 'bar' ], 'Foo=\'bar\'', 'Leading capital' ],
+                       [ [ 'foo' => 'BAR' ], 'FOO=BAR', 'Attribute keys are normalized to lowercase' ],
+
+                       # Invalid beginning
+                       [ [], '-foo=bar', 'Leading - is forbidden' ],
+                       [ [], '.foo=bar', 'Leading . is forbidden' ],
+                       [ [ 'foo-bar' => 'bar' ], 'foo-bar=bar', 'A - is allowed inside the attribute' ],
+                       [ [ 'foo-' => 'bar' ], 'foo-=bar', 'A - is allowed inside the attribute' ],
+                       [ [ 'foo.bar' => 'baz' ], 'foo.bar=baz', 'A . is allowed inside the attribute' ],
+                       [ [ 'foo.' => 'baz' ], 'foo.=baz', 'A . is allowed as last character' ],
+                       [ [ 'foo6' => 'baz' ], 'foo6=baz', 'Numbers are allowed' ],
+
+                       # This bit is more relaxed than XML rules, but some extensions use
+                       # it, like ProofreadPage (see T29539)
+                       [ [ '1foo' => 'baz' ], '1foo=baz', 'Leading numbers are allowed' ],
+                       [ [], 'foo$=baz', 'Symbols are not allowed' ],
+                       [ [], 'foo@=baz', 'Symbols are not allowed' ],
+                       [ [], 'foo~=baz', 'Symbols are not allowed' ],
+                       [
+                               [ 'foo' => '1[#^`*%w/(' ],
+                               'foo=1[#^`*%w/(',
+                               'All kind of characters are allowed as values'
+                       ],
+                       [
+                               [ 'foo' => '1[#^`*%\'w/(' ],
+                               'foo="1[#^`*%\'w/("',
+                               'Double quotes are allowed if quoted by single quotes'
+                       ],
+                       [
+                               [ 'foo' => '1[#^`*%"w/(' ],
+                               'foo=\'1[#^`*%"w/(\'',
+                               'Single quotes are allowed if quoted by double quotes'
+                       ],
+                       [ [ 'foo' => '&"' ], 'foo=&amp;&quot;', 'Special chars can be provided as entities' ],
+                       [ [ 'foo' => '&foobar;' ], 'foo=&foobar;', 'Entity-like items are accepted' ],
+               ];
+       }
+
+       /**
+        * @dataProvider provideCssCommentsFixtures
+        * @covers Sanitizer::checkCss
+        */
+       public function testCssCommentsChecking( $expected, $css, $message = '' ) {
+               $this->assertEquals( $expected,
+                       Sanitizer::checkCss( $css ),
+                       $message
+               );
+       }
+
+       public static function provideCssCommentsFixtures() {
+               /** [ <expected>, <css>, [message] ] */
+               return [
+                       // Valid comments spanning entire input
+                       [ '/**/', '/**/' ],
+                       [ '/* comment */', '/* comment */' ],
+                       // Weird stuff
+                       [ ' ', '/****/' ],
+                       [ ' ', '/* /* */' ],
+                       [ 'display: block;', "display:/* foo */block;" ],
+                       [ 'display: block;', "display:\\2f\\2a foo \\2a\\2f block;",
+                               'Backslash-escaped comments must be stripped (T30450)' ],
+                       [ '', '/* unfinished comment structure',
+                               'Remove anything after a comment-start token' ],
+                       [ '', "\\2f\\2a unifinished comment'",
+                               'Remove anything after a backslash-escaped comment-start token' ],
+                       [
+                               '/* insecure input */',
+                               'filter: progid:DXImageTransform.Microsoft.AlphaImageLoader'
+                                       . '(src=\'asdf.png\',sizingMethod=\'scale\');'
+                       ],
+                       [
+                               '/* insecure input */',
+                               '-ms-filter: "progid:DXImageTransform.Microsoft.AlphaImageLoader'
+                                       . '(src=\'asdf.png\',sizingMethod=\'scale\')";'
+                       ],
+                       [ '/* insecure input */', 'width: expression(1+1);' ],
+                       [ '/* insecure input */', 'background-image: image(asdf.png);' ],
+                       [ '/* insecure input */', 'background-image: -webkit-image(asdf.png);' ],
+                       [ '/* insecure input */', 'background-image: -moz-image(asdf.png);' ],
+                       [ '/* insecure input */', 'background-image: image-set("asdf.png" 1x, "asdf.png" 2x);' ],
+                       [
+                               '/* insecure input */',
+                               'background-image: -webkit-image-set("asdf.png" 1x, "asdf.png" 2x);'
+                       ],
+                       [
+                               '/* insecure input */',
+                               'background-image: -moz-image-set("asdf.png" 1x, "asdf.png" 2x);'
+                       ],
+                       [ '/* insecure input */', 'foo: attr( title, url );' ],
+                       [ '/* insecure input */', 'foo: attr( title url );' ],
+                       [ '/* insecure input */', 'foo: var(--evil-attribute)' ],
+               ];
+       }
+
+       /**
+        * @dataProvider provideEscapeHtmlAllowEntities
+        * @covers Sanitizer::escapeHtmlAllowEntities
+        */
+       public function testEscapeHtmlAllowEntities( $expected, $html ) {
+               $this->assertEquals(
+                       $expected,
+                       Sanitizer::escapeHtmlAllowEntities( $html )
+               );
+       }
+
+       public static function provideEscapeHtmlAllowEntities() {
+               return [
+                       [ 'foo', 'foo' ],
+                       [ 'a¡b', 'a&#161;b' ],
+                       [ 'foo&#039;bar', "foo'bar" ],
+                       [ '&lt;script&gt;foo&lt;/script&gt;', '<script>foo</script>' ],
+               ];
+       }
+
+       /**
+        * Test Sanitizer::escapeId
+        *
+        * @dataProvider provideEscapeId
+        * @covers Sanitizer::escapeId
+        */
+       public function testEscapeId( $input, $output ) {
+               $this->assertEquals(
+                       $output,
+                       Sanitizer::escapeId( $input, [ 'noninitial', 'legacy' ] )
+               );
+       }
+
+       public static function provideEscapeId() {
+               return [
+                       [ '+', '.2B' ],
+                       [ '&', '.26' ],
+                       [ '=', '.3D' ],
+                       [ ':', ':' ],
+                       [ ';', '.3B' ],
+                       [ '@', '.40' ],
+                       [ '$', '.24' ],
+                       [ '-_.', '-_.' ],
+                       [ '!', '.21' ],
+                       [ '*', '.2A' ],
+                       [ '/', '.2F' ],
+                       [ '[]', '.5B.5D' ],
+                       [ '<>', '.3C.3E' ],
+                       [ '\'', '.27' ],
+                       [ '§', '.C2.A7' ],
+                       [ 'Test:A & B/Here', 'Test:A_.26_B.2FHere' ],
+                       [ 'A&B&amp;C&amp;amp;D&amp;amp;amp;E', 'A.26B.26amp.3BC.26amp.3Bamp.3BD.26amp.3Bamp.3Bamp.3BE' ],
+               ];
+       }
+
+       /**
+        * Test escapeIdReferenceList for consistency with escapeIdForAttribute
+        *
+        * @dataProvider provideEscapeIdReferenceList
+        * @covers Sanitizer::escapeIdReferenceList
+        */
+       public function testEscapeIdReferenceList( $referenceList, $id1, $id2 ) {
+               $this->assertEquals(
+                       Sanitizer::escapeIdReferenceList( $referenceList ),
+                       Sanitizer::escapeIdForAttribute( $id1 )
+                               . ' '
+                               . Sanitizer::escapeIdForAttribute( $id2 )
+               );
+       }
+
+       public static function provideEscapeIdReferenceList() {
+               /** [ <reference list>, <individual id 1>, <individual id 2> ] */
+               return [
+                       [ 'foo bar', 'foo', 'bar' ],
+                       [ '#1 #2', '#1', '#2' ],
+                       [ '+1 +2', '+1', '+2' ],
+               ];
+       }
+
+       /**
+        * @dataProvider provideIsReservedDataAttribute
+        * @covers Sanitizer::isReservedDataAttribute
+        */
+       public function testIsReservedDataAttribute( $attr, $expected ) {
+               $this->assertSame( $expected, Sanitizer::isReservedDataAttribute( $attr ) );
+       }
+
+       public static function provideIsReservedDataAttribute() {
+               return [
+                       [ 'foo', false ],
+                       [ 'data', false ],
+                       [ 'data-foo', false ],
+                       [ 'data-mw', true ],
+                       [ 'data-ooui', true ],
+                       [ 'data-parsoid', true ],
+                       [ 'data-mw-foo', true ],
+                       [ 'data-ooui-foo', true ],
+                       [ 'data-mwfoo', true ], // could be false but this is how it's implemented currently
+               ];
+       }
+
+       /**
+        * @dataProvider provideStripAllTags
+        *
+        * @covers Sanitizer::stripAllTags()
+        * @covers RemexStripTagHandler
+        *
+        * @param string $input
+        * @param string $expected
+        */
+       public function testStripAllTags( $input, $expected ) {
+               $this->assertEquals( $expected, Sanitizer::stripAllTags( $input ) );
+       }
+
+       public function provideStripAllTags() {
+               return [
+                       [ '<p>Foo</p>', 'Foo' ],
+                       [ '<p id="one">Foo</p><p id="two">Bar</p>', 'Foo Bar' ],
+                       [ "<p>Foo</p>\n<p>Bar</p>", 'Foo Bar' ],
+                       [ '<p>Hello &lt;strong&gt; wor&#x6c;&#100; caf&eacute;</p>', 'Hello <strong> world café' ],
+                       [
+                               '<p><small data-foo=\'bar"&lt;baz>quux\'><a href="./Foo">Bar</a></small> Whee!</p>',
+                               'Bar Whee!'
+                       ],
+                       [ '1<span class="<?php">2</span>3', '123' ],
+                       [ '1<span class="<?">2</span>3', '123' ],
+                       [ '<th>1</th><td>2</td>', '1 2' ],
+               ];
+       }
+
+}
index e67af10..54f6b4e 100644 (file)
                        '<div>' + loremIpsum + '</div>'
                );
 
+               // eslint-disable-next-line no-jquery/no-class-state
                assert.assertTrue( $collapsible.hasClass( 'mw-collapsible' ), 'mw-collapsible class present' );
        } );
 
                        { collapsed: true }
                );
 
+               // eslint-disable-next-line no-jquery/no-class-state
                assert.assertTrue( $collapsible.hasClass( 'mw-collapsed' ), 'mw-collapsed class present' );
        } );
 
                        .appendTo( '#qunit-fixture' ).makeCollapsible();
 
                $collapsible1.on( 'afterCollapse.mw-collapsible', function () {
+                       // eslint-disable-next-line no-jquery/no-class-state
                        assert.assertTrue( $collapsible1.hasClass( 'mw-collapsed' ), 'after collapsing: parent is collapsed' );
+                       // eslint-disable-next-line no-jquery/no-class-state
                        assert.assertFalse( $collapsible2.hasClass( 'mw-collapsed' ), 'after collapsing: child is not collapsed' );
+                       // eslint-disable-next-line no-jquery/no-class-state
                        assert.assertTrue( $collapsible1.find( '> .mw-collapsible-toggle' ).hasClass( 'mw-collapsible-toggle-collapsed' ) );
+                       // eslint-disable-next-line no-jquery/no-class-state
                        assert.assertFalse( $collapsible2.find( '> .mw-collapsible-toggle' ).hasClass( 'mw-collapsible-toggle-collapsed' ) );
                } ).find( '> .mw-collapsible-toggle a' ).trigger( 'click' );
        } );
index 2711ddf..476b505 100644 (file)
                $table.find( 'tr > th' ).eq( 1 ).trigger( 'click' );
 
                assert.strictEqual(
+                       // eslint-disable-next-line no-jquery/no-class-state
                        $cell.hasClass( 'headerSortUp' ) || $cell.hasClass( 'headerSortDown' ),
                        false,
                        'after sort: no class headerSortUp or headerSortDown'
                        mw.config.set( 'wgPageContentLanguage', 'sv' );
 
                        $table.tablesorter();
+                       // eslint-disable-next-line no-jquery/no-sizzle
                        $table.find( '.headerSort:eq(0)' ).trigger( 'click' );
                }
        );
index aafcd5b..738392a 100644 (file)
                // TODO abstract the double strictEquals
 
                // At first checkboxes are hidden
+               // eslint-disable-next-line no-jquery/no-class-state
                assert.strictEqual( $( '#nsinvert' ).closest( '.mw-input-with-label' ).hasClass( 'mw-input-hidden' ), true );
+               // eslint-disable-next-line no-jquery/no-class-state
                assert.strictEqual( $( '#nsassociated' ).closest( '.mw-input-with-label' ).hasClass( 'mw-input-hidden' ), true );
 
                // Initiate the recentchanges module
                rc.init();
 
                // By default
+               // eslint-disable-next-line no-jquery/no-class-state
                assert.strictEqual( $( '#nsinvert' ).closest( '.mw-input-with-label' ).hasClass( 'mw-input-hidden' ), true );
+               // eslint-disable-next-line no-jquery/no-class-state
                assert.strictEqual( $( '#nsassociated' ).closest( '.mw-input-with-label' ).hasClass( 'mw-input-hidden' ), true );
 
                // select second option...
@@ -50,7 +54,9 @@
                $( '#namespace' ).trigger( 'change' );
 
                // ... and checkboxes should be visible again
+               // eslint-disable-next-line no-jquery/no-class-state
                assert.strictEqual( $( '#nsinvert' ).closest( '.mw-input-with-label' ).hasClass( 'mw-input-hidden' ), false );
+               // eslint-disable-next-line no-jquery/no-class-state
                assert.strictEqual( $( '#nsassociated' ).closest( '.mw-input-with-label' ).hasClass( 'mw-input-hidden' ), false );
 
                // select first option ( 'all' namespace)...
@@ -59,7 +65,9 @@
                $( '#namespace' ).trigger( 'change' );
 
                // ... and checkboxes should now be hidden
+               // eslint-disable-next-line no-jquery/no-class-state
                assert.strictEqual( $( '#nsinvert' ).closest( '.mw-input-with-label' ).hasClass( 'mw-input-hidden' ), true );
+               // eslint-disable-next-line no-jquery/no-class-state
                assert.strictEqual( $( '#nsassociated' ).closest( '.mw-input-with-label' ).hasClass( 'mw-input-hidden' ), true );
 
                // DOM cleanup
index 6dcdb44..6dab026 100644 (file)
 
                assert.strictEqual( $toggleLink.length, 1, 'Toggle link is added to the table of contents' );
 
+               // eslint-disable-next-line no-jquery/no-class-state
                assert.strictEqual( $toc.hasClass( 'tochidden' ), false, 'The table of contents is now visible' );
 
                $toggleLink.trigger( 'click' );
                return $tocList.promise().then( function () {
+                       // eslint-disable-next-line no-jquery/no-class-state
                        assert.strictEqual( $toc.hasClass( 'tochidden' ), true, 'The table of contents is now hidden' );
                        $toggleLink.trigger( 'click' );
                        return $tocList.promise();
index 3679ed7..17672db 100644 (file)
        QUnit.module( 'mediawiki.util', QUnit.newMwEnvironment( {
                setup: function () {
                        $.fn.updateTooltipAccessKeys.setTestMode( true );
+                       this.origConfig = mw.util.setOptionsForTest( {
+                               FragmentMode: [ 'legacy', 'html5' ],
+                               LoadScript: '/w/load.php'
+                       } );
                },
                teardown: function () {
                        $.fn.updateTooltipAccessKeys.setTestMode( false );
-                       mw.util.resetOptionsForTest();
+                       mw.util.setOptionsForTest( this.origConfig );
                },
                messages: {
                        // Used by accessKeyLabel in test for addPortletLink
index dd766c8..21d230e 100644 (file)
@@ -11,6 +11,7 @@
                "mw": false
        },
        "rules": {
-               "no-console": 0
+               "no-console": "off",
+               "prefer-template": "off"
        }
 }
index 52d614f..730eff3 100644 (file)
@@ -29,7 +29,7 @@ class HistoryPage extends Page {
        }
 
        vandalizePage( name, content ) {
-               let vandalUsername = 'Evil_' + browser.options.username;
+               const vandalUsername = 'Evil_' + browser.options.username;
 
                browser.call( function () {
                        return Api.edit( name, content );
index 93e0b87..ab547e8 100644 (file)
@@ -1,5 +1,6 @@
 const assert = require( 'assert' ),
        Api = require( 'wdio-mediawiki/Api' ),
+       BlankPage = require( 'wdio-mediawiki/BlankPage' ),
        DeletePage = require( '../pageobjects/delete.page' ),
        RestorePage = require( '../pageobjects/restore.page' ),
        EditPage = require( '../pageobjects/edit.page' ),
@@ -14,7 +15,7 @@ describe( 'Page', function () {
 
        before( function () {
                // disable VisualEditor welcome dialog
-               UserLoginPage.open();
+               BlankPage.open();
                browser.localStorage( 'POST', { key: 've-beta-welcome-dialog', value: '1' } );
        } );
 
@@ -48,7 +49,7 @@ describe( 'Page', function () {
        } );
 
        it( 'should be re-creatable', function () {
-               let initialContent = Util.getTestString( 'initialContent-' );
+               const initialContent = Util.getTestString( 'initialContent-' );
 
                // create
                browser.call( function () {
@@ -75,7 +76,7 @@ describe( 'Page', function () {
                } );
 
                // edit
-               let editContent = Util.getTestString( 'editContent-' );
+               const editContent = Util.getTestString( 'editContent-' );
                EditPage.edit( name, editContent );
 
                // check
index d85b27b..daf7112 100644 (file)
@@ -1,4 +1,5 @@
 const assert = require( 'assert' ),
+       BlankPage = require( 'wdio-mediawiki/BlankPage' ),
        HistoryPage = require( '../pageobjects/history.page' ),
        UserLoginPage = require( 'wdio-mediawiki/LoginPage' ),
        Util = require( 'wdio-mediawiki/Util' );
@@ -10,7 +11,7 @@ describe( 'Rollback with confirmation', function () {
        before( function () {
                // disable VisualEditor welcome dialog
                browser.deleteCookie();
-               UserLoginPage.open();
+               BlankPage.open();
                browser.localStorage( 'POST', { key: 've-beta-welcome-dialog', value: '1' } );
 
                // Enable rollback confirmation for admin user
@@ -90,7 +91,7 @@ describe( 'Rollback without confirmation', function () {
        before( function () {
                // disable VisualEditor welcome dialog
                browser.deleteCookie();
-               UserLoginPage.open();
+               BlankPage.open();
                browser.localStorage( 'POST', { key: 've-beta-welcome-dialog', value: '1' } );
 
                // Disable rollback confirmation for admin user
index d55ff4c..1db49ae 100644 (file)
@@ -1,4 +1,5 @@
 const assert = require( 'assert' ),
+       BlankPage = require( 'wdio-mediawiki/BlankPage' ),
        CreateAccountPage = require( '../pageobjects/createaccount.page' ),
        PreferencesPage = require( '../pageobjects/preferences.page' ),
        UserLoginPage = require( 'wdio-mediawiki/LoginPage' ),
@@ -11,7 +12,7 @@ describe( 'User', function () {
 
        before( function () {
                // disable VisualEditor welcome dialog
-               UserLoginPage.open();
+               BlankPage.open();
                browser.localStorage( 'POST', { key: 've-beta-welcome-dialog', value: '1' } );
        } );
 
index 7947ff5..6b674b9 100644 (file)
@@ -22,7 +22,7 @@ module.exports = {
                password = browser.options.password,
                baseUrl = browser.options.baseUrl
        ) {
-               let bot = new MWBot();
+               const bot = new MWBot();
 
                return bot.loginGetEditToken( {
                        apiUrl: `${baseUrl}/api.php`,
@@ -43,7 +43,7 @@ module.exports = {
         * @return {Object} Promise for API action=delete response data.
         */
        delete( title, reason ) {
-               let bot = new MWBot();
+               const bot = new MWBot();
 
                return bot.loginGetEditToken( {
                        apiUrl: `${browser.options.baseUrl}/api.php`,
@@ -64,7 +64,7 @@ module.exports = {
         * @return {Object} Promise for API action=createaccount response data.
         */
        createAccount( username, password ) {
-               let bot = new MWBot();
+               const bot = new MWBot();
 
                // Log in as admin
                return bot.loginGetCreateaccountToken( {
@@ -94,7 +94,7 @@ module.exports = {
         * @return {Object} Promise for API action=block response data.
         */
        blockUser( username, expiry ) {
-               let bot = new MWBot();
+               const bot = new MWBot();
 
                // Log in as admin
                return bot.loginGetEditToken( {
@@ -122,7 +122,7 @@ module.exports = {
         * @return {Object} Promise for API action=unblock response data.
         */
        unblockUser( username ) {
-               let bot = new MWBot();
+               const bot = new MWBot();
 
                // Log in as admin
                return bot.loginGetEditToken( {
index 070ad56..2e675c0 100644 (file)
@@ -3,7 +3,7 @@ const MWBot = require( 'mwbot' ),
        MAINPAGE_REQUESTS_MAX_RUNS = 10; // (arbitrary) safe-guard against endless execution
 
 function getJobCount() {
-       let bot = new MWBot( {
+       const bot = new MWBot( {
                apiUrl: `${browser.options.baseUrl}/api.php`
        } );
        return bot.request( {
@@ -20,7 +20,7 @@ function log( message ) {
 }
 
 function runThroughMainPageRequests( runCount = 1 ) {
-       let page = new Page();
+       const page = new Page();
        log( `through requests to the main page (run ${runCount}).` );
 
        page.openTitle( '' );
index 56e4934..214c25a 100644 (file)
@@ -160,7 +160,7 @@ exports.config = {
        beforeTest: function ( test ) {
                if ( process.env.DISPLAY && process.env.DISPLAY.startsWith( ':' ) ) {
                        var logBuffer;
-                       let videoPath = filePath( test, logPath, 'mp4' );
+                       const videoPath = filePath( test, logPath, 'mp4' );
                        const { spawn } = require( 'child_process' );
                        ffmpeg = spawn( 'ffmpeg', [
                                '-f', 'x11grab', //  grab the X11 display
@@ -173,7 +173,7 @@ exports.config = {
                        ] );
 
                        logBuffer = function ( buffer, prefix ) {
-                               let lines = buffer.toString().trim().split( '\n' );
+                               const lines = buffer.toString().trim().split( '\n' );
                                lines.forEach( function ( line ) {
                                        console.log( prefix + line );
                                } );
@@ -215,7 +215,7 @@ exports.config = {
                        return;
                }
                // save screenshot
-               let screenshotfile = filePath( test, logPath, 'png' );
+               const screenshotfile = filePath( test, logPath, 'png' );
                browser.saveScreenshot( screenshotfile );
                console.log( '\n\tScreenshot location:', screenshotfile, '\n' );
        }