Merge "Use wikimedia/cldr-plural-rule-parser"
authorjenkins-bot <jenkins-bot@gerrit.wikimedia.org>
Thu, 24 Sep 2015 23:15:56 +0000 (23:15 +0000)
committerGerrit Code Review <gerrit@wikimedia.org>
Thu, 24 Sep 2015 23:15:56 +0000 (23:15 +0000)
143 files changed:
RELEASE-NOTES-1.26
UPGRADE
autoload.php
composer.json
includes/DefaultSettings.php
includes/GlobalFunctions.php
includes/HtmlFormatter.php
includes/Import.php
includes/User.php
includes/actions/RollbackAction.php
includes/api/ApiFormatPhp.php
includes/api/ApiQueryAllDeletedRevisions.php
includes/api/ApiQueryDeletedRevisions.php
includes/api/i18n/es.json
includes/api/i18n/it.json
includes/api/i18n/ko.json
includes/api/i18n/lt.json [new file with mode: 0644]
includes/api/i18n/pl.json
includes/api/i18n/ru.json
includes/changes/EnhancedChangesList.php
includes/db/DatabaseMysqlBase.php
includes/db/DatabaseSqlite.php
includes/db/LBFactory.php [deleted file]
includes/db/LBFactoryMulti.php [deleted file]
includes/db/LBFactorySingle.php [deleted file]
includes/db/LoadBalancer.php [deleted file]
includes/db/LoadMonitor.php [deleted file]
includes/db/LoadMonitorMySQL.php [deleted file]
includes/db/loadbalancer/LBFactory.php [new file with mode: 0644]
includes/db/loadbalancer/LBFactoryFake.php [new file with mode: 0644]
includes/db/loadbalancer/LBFactoryMulti.php [new file with mode: 0644]
includes/db/loadbalancer/LBFactorySimple.php [new file with mode: 0644]
includes/db/loadbalancer/LBFactorySingle.php [new file with mode: 0644]
includes/db/loadbalancer/LoadBalancer.php [new file with mode: 0644]
includes/db/loadbalancer/LoadMonitor.php [new file with mode: 0644]
includes/db/loadbalancer/LoadMonitorMySQL.php [new file with mode: 0644]
includes/filerepo/file/LocalFile.php
includes/gallery/TraditionalImageGallery.php
includes/installer/Installer.php
includes/installer/i18n/lt.json
includes/installer/i18n/ru.json
includes/parser/Parser.php
includes/resourceloader/ResourceLoaderFileModule.php
includes/resourceloader/ResourceLoaderModule.php
includes/site/MediaWikiSite.php
includes/specials/SpecialUserlogin.php
includes/utils/AvroValidator.php
languages/Language.php
languages/Names.php
languages/i18n/ady-cyrl.json
languages/i18n/af.json
languages/i18n/ar.json
languages/i18n/as.json
languages/i18n/ast.json
languages/i18n/be-tarask.json
languages/i18n/bho.json
languages/i18n/bn.json
languages/i18n/ca.json
languages/i18n/cs.json
languages/i18n/de.json
languages/i18n/dty.json
languages/i18n/el.json
languages/i18n/en.json
languages/i18n/es.json
languages/i18n/et.json
languages/i18n/eu.json
languages/i18n/fa.json
languages/i18n/fi.json
languages/i18n/fr.json
languages/i18n/frr.json
languages/i18n/gl.json
languages/i18n/gsw.json
languages/i18n/gu.json
languages/i18n/he.json
languages/i18n/ia.json
languages/i18n/ilo.json
languages/i18n/it.json
languages/i18n/ja.json
languages/i18n/jut.json
languages/i18n/ka.json
languages/i18n/kk-cyrl.json
languages/i18n/km.json
languages/i18n/ko.json
languages/i18n/ksh.json
languages/i18n/lb.json
languages/i18n/lt.json
languages/i18n/lv.json
languages/i18n/mg.json
languages/i18n/mk.json
languages/i18n/ml.json
languages/i18n/nah.json
languages/i18n/nap.json
languages/i18n/nl.json
languages/i18n/olo.json
languages/i18n/pa.json
languages/i18n/pl.json
languages/i18n/ps.json
languages/i18n/pt-br.json
languages/i18n/pt.json
languages/i18n/qqq.json
languages/i18n/ro.json
languages/i18n/roa-tara.json
languages/i18n/ru.json
languages/i18n/sah.json
languages/i18n/scn.json
languages/i18n/sl.json
languages/i18n/sr-ec.json
languages/i18n/sv.json
languages/i18n/th.json
languages/i18n/tr.json
languages/i18n/uk.json
languages/i18n/vec.json
languages/i18n/vi.json
languages/i18n/xmf.json
languages/i18n/yi.json
languages/i18n/yue.json
languages/i18n/zh-hans.json
languages/i18n/zh-hant.json
languages/messages/MessagesOlo.php [new file with mode: 0644]
maintenance/archives/patch-archive_ar_revid.sql
maintenance/archives/patch-backlinkindexes.sql
maintenance/archives/patch-categorylinksindex.sql
maintenance/cleanupPreferences.php
resources/Resources.php
resources/src/jquery/jquery.tablesorter.js
resources/src/mediawiki.special/mediawiki.special.upload.js
resources/src/mediawiki/mediawiki.Upload.BookletLayout.js
tests/parser/parserTests.txt
tests/phpunit/MediaWikiTestCase.php
tests/phpunit/includes/GlobalFunctions/GlobalTest.php
tests/phpunit/includes/HtmlFormatterTest.php
tests/phpunit/includes/ImportTest.php
tests/phpunit/includes/actions/ActionTest.php
tests/phpunit/includes/api/ApiBlockTest.php
tests/phpunit/includes/api/ApiUploadTest.php
tests/phpunit/includes/api/format/ApiFormatPhpTest.php
tests/phpunit/includes/parser/PreprocessorTest.php
tests/phpunit/includes/utils/AvroValidatorTest.php
tests/phpunit/suite.xml
tests/qunit/suites/resources/jquery/jquery.tablesorter.parsers.test.js
tests/qunit/suites/resources/jquery/jquery.tablesorter.test.js
tests/qunit/suites/resources/mediawiki/mediawiki.jqueryMsg.test.js
tests/qunit/suites/resources/mediawiki/mediawiki.test.js

index 1df0d03..a13fc2e 100644 (file)
@@ -153,6 +153,8 @@ changes to languages because of Phabricator reports.
 ** dty (डोटेली/Doteli), thanks to translators जनक राज भट्ट, बिप्लब आनन्द,
    मेश सिंह बोहरा, and राम प्रसाद जोशी
 ** luz (لئری دوٙمینی / Southern Luri)
+** olo (Livvinкarjala / Livvi-Karelian), thanks to translators Denö, Hiloin Natoi,
+   Ilja.mos, and Mashoi7
 
 === Other changes in 1.26 ===
 * ChangeTags::tagDescription() will return false if the interface message
diff --git a/UPGRADE b/UPGRADE
index 1ff98cd..088701a 100644 (file)
--- a/UPGRADE
+++ b/UPGRADE
@@ -5,7 +5,7 @@ specific problems, check
 * the documentation at https://www.mediawiki.org
 * the mediawiki-l mailing list archive at
   http://lists.wikimedia.org/pipermail/mediawiki-l/
-* the bug tracker at https://bugzilla.wikimedia.org
+* the bug tracker at https://phabricator.wikimedia.org
 
 for information and workarounds to common issues.
 
index 1c25a81..9cb5b43 100644 (file)
@@ -276,7 +276,7 @@ $wgAutoloadLocalClasses = array(
        'CsvStatsOutput' => __DIR__ . '/maintenance/language/StatOutputs.php',
        'CurlHttpRequest' => __DIR__ . '/includes/HttpFunctions.php',
        'DBAccessBase' => __DIR__ . '/includes/dao/DBAccessBase.php',
-       'DBAccessError' => __DIR__ . '/includes/db/LBFactory.php',
+       'DBAccessError' => __DIR__ . '/includes/db/loadbalancer/LBFactory.php',
        'DBAccessObjectUtils' => __DIR__ . '/includes/dao/DBAccessObjectUtils.php',
        'DBConnRef' => __DIR__ . '/includes/db/DBConnRef.php',
        'DBConnectionError' => __DIR__ . '/includes/db/DatabaseError.php',
@@ -604,11 +604,11 @@ $wgAutoloadLocalClasses = array(
        'JsonContentHandler' => __DIR__ . '/includes/content/JsonContentHandler.php',
        'KkConverter' => __DIR__ . '/languages/classes/LanguageKk.php',
        'KuConverter' => __DIR__ . '/languages/classes/LanguageKu.php',
-       'LBFactory' => __DIR__ . '/includes/db/LBFactory.php',
-       'LBFactoryFake' => __DIR__ . '/includes/db/LBFactory.php',
-       'LBFactoryMulti' => __DIR__ . '/includes/db/LBFactoryMulti.php',
-       'LBFactorySimple' => __DIR__ . '/includes/db/LBFactory.php',
-       'LBFactorySingle' => __DIR__ . '/includes/db/LBFactorySingle.php',
+       'LBFactory' => __DIR__ . '/includes/db/loadbalancer/LBFactory.php',
+       'LBFactoryFake' => __DIR__ . '/includes/db/loadbalancer/LBFactoryFake.php',
+       'LBFactoryMulti' => __DIR__ . '/includes/db/loadbalancer/LBFactoryMulti.php',
+       'LBFactorySimple' => __DIR__ . '/includes/db/loadbalancer/LBFactorySimple.php',
+       'LBFactorySingle' => __DIR__ . '/includes/db/loadbalancer/LBFactorySingle.php',
        'LCStore' => __DIR__ . '/includes/cache/LocalisationCache.php',
        'LCStoreCDB' => __DIR__ . '/includes/cache/LocalisationCache.php',
        'LCStoreDB' => __DIR__ . '/includes/cache/LocalisationCache.php',
@@ -679,11 +679,11 @@ $wgAutoloadLocalClasses = array(
        'ListDuplicatedFilesPage' => __DIR__ . '/includes/specials/SpecialListDuplicatedFiles.php',
        'ListVariants' => __DIR__ . '/maintenance/language/listVariants.php',
        'ListredirectsPage' => __DIR__ . '/includes/specials/SpecialListredirects.php',
-       'LoadBalancer' => __DIR__ . '/includes/db/LoadBalancer.php',
-       'LoadBalancerSingle' => __DIR__ . '/includes/db/LBFactorySingle.php',
-       'LoadMonitor' => __DIR__ . '/includes/db/LoadMonitor.php',
-       'LoadMonitorMySQL' => __DIR__ . '/includes/db/LoadMonitorMySQL.php',
-       'LoadMonitorNull' => __DIR__ . '/includes/db/LoadMonitor.php',
+       'LoadBalancer' => __DIR__ . '/includes/db/loadbalancer/LoadBalancer.php',
+       'LoadBalancerSingle' => __DIR__ . '/includes/db/loadbalancer/LBFactorySingle.php',
+       'LoadMonitor' => __DIR__ . '/includes/db/loadbalancer/LoadMonitor.php',
+       'LoadMonitorMySQL' => __DIR__ . '/includes/db/loadbalancer/LoadMonitorMySQL.php',
+       'LoadMonitorNull' => __DIR__ . '/includes/db/loadbalancer/LoadMonitor.php',
        'LocalFile' => __DIR__ . '/includes/filerepo/file/LocalFile.php',
        'LocalFileDeleteBatch' => __DIR__ . '/includes/filerepo/file/LocalFile.php',
        'LocalFileMoveBatch' => __DIR__ . '/includes/filerepo/file/LocalFile.php',
index ba9a892..6153045 100644 (file)
@@ -20,7 +20,7 @@
                "cssjanus/cssjanus": "1.1.1",
                "ext-iconv": "*",
                "liuggio/statsd-php-client": "1.0.16",
-               "oyejorge/less.php": "1.7.0.5",
+               "oyejorge/less.php": "1.7.0.8",
                "mediawiki/at-ease": "1.1.0",
                "oojs/oojs-ui": "0.12.9",
                "php": ">=5.3.3",
index 3895318..aa21c44 100644 (file)
@@ -7473,7 +7473,7 @@ $wgRunJobsAsync = true;
 /**
  * Number of rows to update per job
  */
-$wgUpdateRowsPerJob = 500;
+$wgUpdateRowsPerJob = 300;
 
 /**
  * Number of rows to update per query
index 486926f..404d2cf 100644 (file)
@@ -635,7 +635,7 @@ function wfExpandUrl( $url, $defaultProto = PROTO_CURRENT ) {
        $bits = wfParseUrl( $url );
 
        // ensure proper port for HTTPS arrives in URL
-       // https://bugzilla.wikimedia.org/show_bug.cgi?id=65184
+       // https://phabricator.wikimedia.org/T67184
        if ( $defaultProto === PROTO_HTTPS && $wgHttpsPort != 443 ) {
                $bits['port'] = $wgHttpsPort;
        }
index 221cefb..83db268 100644 (file)
@@ -75,7 +75,7 @@ class HtmlFormatter {
 
                        // Workaround for bug that caused spaces before references
                        // to disappear during processing:
-                       // https://bugzilla.wikimedia.org/show_bug.cgi?id=53086
+                       // https://phabricator.wikimedia.org/T55086
                        //
                        // Please replace with a better fix if one can be found.
                        $html = str_replace( ' <', '&#32;<', $html );
index 6a0bfd0..db4a6b2 100644 (file)
@@ -728,13 +728,14 @@ class WikiImporter {
                                        $title = $this->processTitle( $pageInfo['title'],
                                                isset( $pageInfo['ns'] ) ? $pageInfo['ns'] : null );
 
-                                       if ( !$title ) {
+                                       // $title is either an array of two titles or false.
+                                       if ( is_array( $title ) ) {
+                                               $this->pageCallback( $title );
+                                               list( $pageInfo['_title'], $foreignTitle ) = $title;
+                                       } else {
                                                $badTitle = true;
                                                $skip = true;
                                        }
-
-                                       $this->pageCallback( $title );
-                                       list( $pageInfo['_title'], $foreignTitle ) = $title;
                                }
 
                                if ( $title ) {
@@ -750,10 +751,17 @@ class WikiImporter {
                        }
                }
 
-               $this->pageOutCallback( $pageInfo['_title'], $foreignTitle,
+               // @note $pageInfo is only set if a valid $title is processed above with
+               //       no error. If we have a valid $title, then pageCallback is called
+               //       above, $pageInfo['title'] is set and we do pageOutCallback here.
+               //       If $pageInfo['_title'] is not set, then $foreignTitle is also not
+               //       set since they both come from $title above.
+               if ( array_key_exists( '_title', $pageInfo ) ) {
+                       $this->pageOutCallback( $pageInfo['_title'], $foreignTitle,
                                        $pageInfo['revisionCount'],
                                        $pageInfo['successfulRevisionCount'],
                                        $pageInfo );
+               }
        }
 
        /**
index 22c90cd..d57dfaa 100644 (file)
@@ -1694,6 +1694,7 @@ class User implements IDBAccessObject {
                        foreach ( (array)$bases as $base ) {
                                // Make hostname
                                // If we have an access key, use that too (ProjectHoneypot, etc.)
+                               $basename = $base;
                                if ( is_array( $base ) ) {
                                        if ( count( $base ) >= 2 ) {
                                                // Access key is 1, base URL is 0
@@ -1701,6 +1702,7 @@ class User implements IDBAccessObject {
                                        } else {
                                                $host = "$ipReversed.{$base[0]}";
                                        }
+                                       $basename = $base[0];
                                } else {
                                        $host = "$ipReversed.$base";
                                }
@@ -1709,11 +1711,11 @@ class User implements IDBAccessObject {
                                $ipList = gethostbynamel( $host );
 
                                if ( $ipList ) {
-                                       wfDebugLog( 'dnsblacklist', "Hostname $host is {$ipList[0]}, it's a proxy says $base!" );
+                                       wfDebugLog( 'dnsblacklist', "Hostname $host is {$ipList[0]}, it's a proxy says $basename!" );
                                        $found = true;
                                        break;
                                } else {
-                                       wfDebugLog( 'dnsblacklist', "Requested $host, not found in $base." );
+                                       wfDebugLog( 'dnsblacklist', "Requested $host, not found in $basename." );
                                }
                        }
                }
index 93669cf..70d7d16 100644 (file)
@@ -109,7 +109,7 @@ class RollbackAction extends FormlessAction {
                $this->getOutput()->returnToMain( false, $this->getTitle() );
 
                if ( !$request->getBool( 'hidediff', false ) &&
-                       !$this->getUser()->getBoolOption( 'norollbackdiff', false )
+                       !$this->getUser()->getBoolOption( 'norollbackdiff' )
                ) {
                        $contentHandler = $current->getContentHandler();
                        $de = $contentHandler->createDifferenceEngine(
index 6420a5b..df9d581 100644 (file)
@@ -69,7 +69,7 @@ class ApiFormatPhp extends ApiFormatBase {
                ) {
                        $this->dieUsage(
                                'This response cannot be represented using format=php. ' .
-                               'See https://bugzilla.wikimedia.org/show_bug.cgi?id=66776',
+                               'See https://phabricator.wikimedia.org/T68776',
                                'internalerror'
                        );
                }
index 172ee99..4f7984e 100644 (file)
@@ -54,7 +54,6 @@ class ApiQueryAllDeletedRevisions extends ApiQueryRevisionsBase {
                $params = $this->extractRequestParams( false );
 
                $result = $this->getResult();
-               $pageSet = $this->getPageSet();
 
                // This module operates in two modes:
                // 'user': List deleted revs by a certain user
index bf48b19..fa1dfc2 100644 (file)
@@ -46,7 +46,6 @@ class ApiQueryDeletedRevisions extends ApiQueryRevisionsBase {
                        );
                }
 
-               $result = $this->getResult();
                $pageSet = $this->getPageSet();
                $pageMap = $pageSet->getGoodAndMissingTitlesByNamespace();
                $pageCount = count( $pageSet->getGoodAndMissingTitles() );
index a9c04d0..1163680 100644 (file)
        "apihelp-stashedit-param-section": "Número de la sección. <kbd>0</kbd> para una sección superior, <kbd>new</kbd> para una sección nueva.",
        "apihelp-stashedit-param-sectiontitle": "El título de una sección nueva.",
        "apihelp-stashedit-param-text": "Contenido de la página.",
+       "apihelp-stashedit-param-contentmodel": "Modelo del contenido nuevo.",
        "apihelp-stashedit-param-contentformat": "Formato de serialización de contenido utilizado para el texto de entrada.",
        "apihelp-stashedit-param-baserevid": "Identificador de la revisión de base.",
        "apihelp-tag-param-logid": "Uno o más identificadores de entradas del registro a los que agregar o eliminar la etiqueta.",
index 90be9e2..f4c3c56 100644 (file)
        "api-help-parameters": "{{PLURAL:$1|Parametro|Parametri}}:",
        "api-help-param-deprecated": "Deprecato.",
        "api-help-param-required": "Questo parametro è obbligatorio.",
+       "api-help-param-list": "{{PLURAL:$1|1=Uno dei seguenti valori|2=Valori (separati da <kbd>{{!}}</kbd>)}}: $2",
        "api-help-param-multi-max": "Il numero massimo di valori è {{PLURAL:$1|$1}} ({{PLURAL:$2|$2}} per i bot).",
        "api-help-param-default": "Predefinito: $1",
        "api-help-param-default-empty": "Predefinito: <span class=\"apihelp-empty\">(vuoto)</span>",
index ab018c9..8750b8f 100644 (file)
@@ -75,6 +75,7 @@
        "apihelp-options-param-reset": "사이트 기본으로 설정 초기화",
        "apihelp-options-example-reset": "모든 설정 초기화",
        "apihelp-protect-example-protect": "문서 보호",
+       "apihelp-query+allmessages-example-ipb": "<kbd>ipb-</kbd>로 시작하는 메시지를 보입니다.",
        "apihelp-query+pageswithprop-param-limit": "나타낼 문서의 최대 수입니다.",
        "apihelp-query+pageswithprop-param-dir": "정렬 순서",
        "apihelp-query+prefixsearch-param-search": "문자열 검색",
diff --git a/includes/api/i18n/lt.json b/includes/api/i18n/lt.json
new file mode 100644 (file)
index 0000000..3b46841
--- /dev/null
@@ -0,0 +1,8 @@
+{
+       "@metadata": {
+               "authors": [
+                       "Zygimantus"
+               ]
+       },
+       "apihelp-stashedit-param-text": "Puslapio turinys."
+}
index a64e8e2..6d88ca5 100644 (file)
        "apihelp-query+alldeletedrevisions-param-user": "Pokazuj tylko zmiany dokonane przez tego użytkownika.",
        "apihelp-query+alldeletedrevisions-param-excludeuser": "Nie pokazuj zmian dokonanych przez tego użytkownika.",
        "apihelp-query+alldeletedrevisions-param-namespace": "Listuj tylko strony z tej przestrzeni nazw.",
-       "apihelp-query+allfileusages-param-limit": "Łączna ilość obiektów do zwrócenia.",
+       "apihelp-query+allfileusages-param-limit": "Łączna liczba obiektów do zwrócenia.",
        "apihelp-query+allfileusages-example-unique": "Lista unikatowych tytułów plików.",
        "apihelp-query+allimages-param-sort": "Sortowanie według właściwości.",
        "apihelp-query+allimages-example-recent": "Pokaż listę ostatnio przesłanych plików, podobnie do [[Special:NewFiles]].",
        "apihelp-query+allimages-example-mimetypes": "Pokaż listę plików z typem MIME <kbd>image/png</kbd> lub <kbd>image/gif</kbd>",
        "apihelp-query+alllinks-param-namespace": "Przestrzeń nazw do emulacji.",
-       "apihelp-query+alllinks-param-limit": "Łączna ilość obiektów do zwrócenia.",
+       "apihelp-query+alllinks-param-limit": "Łączna liczba obiektów do zwrócenia.",
        "apihelp-query+alllinks-example-unique": "Lista unikatowych tytułów plików.",
        "apihelp-query+allmessages-param-prop": "Właściwości do odczytu.",
        "apihelp-query+allmessages-param-prefix": "Zwróć wiadomości z tym prefixem.",
        "apihelp-query+allpages-param-prtype": "Ogranicz tylko do zabezpieczonych stron.",
-       "apihelp-query+allpages-param-limit": "Ilość stron do zwrócenia.",
+       "apihelp-query+allpages-param-limit": "Liczba stron do zwrócenia.",
        "apihelp-query+allpages-example-B": "Pokaż listę stron rozpoczynających się na literę <kbd>B</kbd>.",
        "apihelp-query+allredirects-description": "Lista wszystkich przekierowań do przestrzeni nazw.",
        "apihelp-query+allredirects-param-namespace": "Przestrzeń nazw do emulacji.",
-       "apihelp-query+allredirects-param-limit": "Łączna ilość obiektów do zwrócenia.",
+       "apihelp-query+allredirects-param-limit": "Łączna liczba obiektów do zwrócenia.",
        "apihelp-query+alltransclusions-param-namespace": "Przestrzeń nazw do emulacji.",
        "apihelp-query+allusers-param-witheditsonly": "Tylko użytkownicy, którzy edytowali.",
        "apihelp-query+backlinks-param-namespace": "Przestrzeń nazw do emulacji.",
        "apihelp-query+blocks-param-users": "Lista użytkowników do wyszukania (opcjonalne).",
        "apihelp-query+blocks-param-limit": "Maksymalna liczba blokad do wylistowania.",
        "apihelp-query+blocks-example-simple": "Listuj blokady.",
-       "apihelp-query+categories-param-limit": "Ilość kategorii do zwrócenia.",
+       "apihelp-query+categories-param-limit": "Liczba kategorii do zwrócenia.",
        "apihelp-query+categorymembers-description": "Wszystkie strony w danej kategorii.",
        "apihelp-query+categorymembers-param-limit": "Maksymalna liczba zwracanych wyników.",
        "apihelp-query+categorymembers-param-sort": "Sortowanie według właściwości.",
        "apihelp-query+deletedrevs-param-user": "Listuj tylko zmiany dokonane przez tego użytkownika.",
        "apihelp-query+deletedrevs-param-excludeuser": "Nie listuj zmian dokonanych przez tego użytkownika.",
        "apihelp-query+deletedrevs-param-namespace": "Listuj tylko strony z tej przestrzeni nazw.",
-       "apihelp-query+deletedrevs-param-limit": "Maksymalna ilość zmian do wylistowania.",
+       "apihelp-query+deletedrevs-param-limit": "Maksymalna liczba zmian do wylistowania.",
        "apihelp-query+duplicatefiles-example-generated": "Szukaj duplikatów wszystkich plików.",
        "apihelp-query+embeddedin-param-filterredir": "Jaki filtrować przekierowania.",
-       "apihelp-query+extlinks-param-limit": "Ilość linków do zwrócenia.",
-       "apihelp-query+exturlusage-param-limit": "Ilość stron do zwrócenia.",
+       "apihelp-query+extlinks-param-limit": "Liczba linków do zwrócenia.",
+       "apihelp-query+exturlusage-param-limit": "Liczba stron do zwrócenia.",
        "apihelp-query+filearchive-paramvalue-prop-dimensions": "Alias rozmiaru.",
        "apihelp-query+filearchive-example-simple": "Pokaż listę wszystkich usuniętych plików.",
        "apihelp-query+filerepoinfo-example-simple": "Uzyskaj informacje na temat repozytoriów plików.",
        "apihelp-query+imageinfo-paramvalue-prop-sha1": "Dodaj sumę kontrolną SHA-1 dla tego pliku.",
        "apihelp-query+imageinfo-paramvalue-prop-mime": "Dodaje typ MIME pliku.",
        "apihelp-query+imageinfo-param-urlheight": "Podobne do $1urlwidth.",
-       "apihelp-query+images-param-limit": "Ilość plików do zwrócenia.",
+       "apihelp-query+images-param-limit": "Liczba plików do zwrócenia.",
        "apihelp-query+info-description": "Pokaż podstawowe informacje o stronie.",
        "apihelp-query+info-paramvalue-prop-watchers": "Liczba obserwujących, jeśli jest to dozwolone.",
        "apihelp-query+info-paramvalue-prop-readable": "Czy użytkownik może przeczytać tę stronę.",
        "apihelp-query+iwbacklinks-param-prefix": "Prefix interwiki.",
-       "apihelp-query+iwbacklinks-param-limit": "Łączna ilość stron do zwrócenia.",
+       "apihelp-query+iwbacklinks-param-limit": "Łączna liczba stron do zwrócenia.",
        "apihelp-query+iwlinks-paramvalue-prop-url": "Dodaje pełny adres URL.",
-       "apihelp-query+links-param-limit": "Ilość linków do zwrócenia.",
+       "apihelp-query+links-param-limit": "Liczba linków do zwrócenia.",
        "apihelp-query+linkshere-paramvalue-prop-title": "Nazwa każdej strony.",
-       "apihelp-query+linkshere-param-limit": "Ilość do zwrócenia.",
+       "apihelp-query+linkshere-param-limit": "Liczba do zwrócenia.",
        "apihelp-query+logevents-description": "Pobierz eventy z logu.",
        "apihelp-query+logevents-example-simple": "Lista ostatnich zarejestrowanych zdarzeń.",
        "apihelp-query+pageswithprop-example-generator": "Pobierz dodatkowe informacje o pierwszych 10 stronach wykorzystując <code>_&#95;NOTOC_&#95;</code>.",
index 56b3f5b..3994cab 100644 (file)
@@ -9,7 +9,8 @@
                        "Дмитрий",
                        "WindEwriX",
                        "Ochilov",
-                       "Nzeemin"
+                       "Nzeemin",
+                       "INS Pirat"
                ]
        },
        "apihelp-main-description": "<div class=\"hlist plainlinks api-main-links\">\n* [[mw:API:Main_page|Документация]]\n* [[mw:API:FAQ|ЧаВО]]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api Почтовая рассылка]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api-announce Новости API]\n* [https://phabricator.wikimedia.org/maniphest/query/GebfyV4uCaLd/#R Ошибки и запросы]\n</div>\n<strong>Статус:</strong> Все отображаемые на этой странице функции должны работать, однако API находится в статусе активной разработки, и может измениться в любой момент. Подпишитесь на  [https://lists.wikimedia.org/pipermail/mediawiki-api-announce/ почтовую рассылку mediawiki-api-announce], чтобы быть в курсе обновлений.\n\n<strong>Ошибочные запросы:</strong> Если API получает запрос с ошибкой, вернётся заголовок HTTP с ключом \"MediaWiki-API-Error\", после чего значение заголовка и код ошибки будут отправлены обратно и установлены в то же значение. Более подробную информацию см. [[mw:API:Errors_and_warnings|API: Ошибки и предупреждения]].",
        "apihelp-query+transcludedin-param-limit": "Сколько возвращать",
        "apihelp-query+usercontribs-description": "Получить все правки пользователя",
        "apihelp-revisiondelete-description": "удалить и восстановить редакции",
+       "apihelp-stashedit-param-sectiontitle": "Заголовок нового раздела.",
        "apihelp-unblock-description": "Разблокировать пользователя.",
        "apihelp-unblock-param-reason": "Причина разблокировки",
        "apihelp-unblock-example-id": "Разблокировать блок с идентификатором #<kbd>105</kbd>.",
        "api-help-license-unknown": "Лицензия: <span class=\"apihelp-unknown\">unknown</span>",
        "api-help-parameters": "Параметр{{PLURAL:$1||ы}}:",
        "api-help-param-deprecated": "Устаревший.",
-       "api-help-param-required": "Этот параметр является обязательным.",
+       "api-help-param-required": "Это обязательный параметр.",
        "api-help-datatypes-header": "Типы данных",
        "api-help-param-type-limit": "Тип: целое число или <kbd>max</kbd>",
        "api-help-param-type-integer": "Тип: {{PLURAL:$1|1=integer|2=list of integers}}",
index d912e3a..1dcb7ae 100644 (file)
@@ -283,6 +283,10 @@ class EnhancedChangesList extends ChangesList {
                // Further down are some assumptions that $block is a 0-indexed array
                // with (count-1) as last key. Let's make sure it is.
                $block = array_values( $block );
+               if ( empty( $block ) ) {
+                       // if we can't show anything, don't display this block altogether
+                       return '';
+               }
 
                $r .= $this->getLogText( $block, $queryParams, $allLogs, $isnew, $namehidden );
 
@@ -453,6 +457,10 @@ class EnhancedChangesList extends ChangesList {
         * @return string
         */
        protected function getLogText( $block, $queryParams, $allLogs, $isnew, $namehidden ) {
+               if ( empty( $block ) ) {
+                       return '';
+               }
+
                # Changes message
                static $nchanges = array();
                static $sinceLastVisitMsg = array();
index be34242..160c354 100644 (file)
@@ -138,7 +138,7 @@ abstract class DatabaseMysqlBase extends DatabaseBase {
 
                if ( $set ) {
                        // Use doQuery() to avoid opening implicit transactions (DBO_TRX)
-                       $success = $this->doQuery( 'SET ' . implode( ', ', $set ), __METHOD__ );
+                       $success = $this->doQuery( 'SET ' . implode( ', ', $set ) );
                        if ( !$success ) {
                                wfLogDBError(
                                        'Error setting MySQL variables on server {db_server} (check $wgSQLMode)',
@@ -302,7 +302,7 @@ abstract class DatabaseMysqlBase extends DatabaseBase {
                // We are not checking for any errors here, since
                // these are no errors mysql_num_rows can cause.
                // See http://dev.mysql.com/doc/refman/5.0/en/mysql-fetch-row.html.
-               // See https://bugzilla.wikimedia.org/42430
+               // See https://phabricator.wikimedia.org/T44430
                return $n;
        }
 
index 656547b..7ece56d 100644 (file)
@@ -806,7 +806,7 @@ class DatabaseSqlite extends DatabaseBase {
                        // https://bugs.php.net/bug.php?id=62361
                        // There is an additional bug regarding sorting this data after insert
                        // on older versions of sqlite shipped with ubuntu 12.04
-                       // https://bugzilla.wikimedia.org/show_bug.cgi?id=72367
+                       // https://phabricator.wikimedia.org/T74367
                        wfDebugLog( __CLASS__, __FUNCTION__ . ': Quoting value containing null byte. For consistency all binary data should have been first processed with self::encodeBlob()' );
                        return "x'" . bin2hex( $s ) . "'";
                } else {
diff --git a/includes/db/LBFactory.php b/includes/db/LBFactory.php
deleted file mode 100644 (file)
index cf522b2..0000000
+++ /dev/null
@@ -1,387 +0,0 @@
-<?php
-/**
- * Generator of database load balancing objects.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- * http://www.gnu.org/copyleft/gpl.html
- *
- * @file
- * @ingroup Database
- */
-
-/**
- * An interface for generating database load balancers
- * @ingroup Database
- */
-abstract class LBFactory {
-       /** @var LBFactory */
-       private static $instance;
-
-       /**
-        * Disables all access to the load balancer, will cause all database access
-        * to throw a DBAccessError
-        */
-       public static function disableBackend() {
-               global $wgLBFactoryConf;
-               self::$instance = new LBFactoryFake( $wgLBFactoryConf );
-       }
-
-       /**
-        * Get an LBFactory instance
-        *
-        * @return LBFactory
-        */
-       public static function singleton() {
-               global $wgLBFactoryConf;
-
-               if ( is_null( self::$instance ) ) {
-                       $class = self::getLBFactoryClass( $wgLBFactoryConf );
-
-                       self::$instance = new $class( $wgLBFactoryConf );
-               }
-
-               return self::$instance;
-       }
-
-       /**
-        * Returns the LBFactory class to use and the load balancer configuration.
-        *
-        * @param array $config (e.g. $wgLBFactoryConf)
-        * @return string Class name
-        */
-       public static function getLBFactoryClass( array $config ) {
-               // For configuration backward compatibility after removing
-               // underscores from class names in MediaWiki 1.23.
-               $bcClasses = array(
-                       'LBFactory_Simple' => 'LBFactorySimple',
-                       'LBFactory_Single' => 'LBFactorySingle',
-                       'LBFactory_Multi' => 'LBFactoryMulti',
-                       'LBFactory_Fake' => 'LBFactoryFake',
-               );
-
-               $class = $config['class'];
-
-               if ( isset( $bcClasses[$class] ) ) {
-                       $class = $bcClasses[$class];
-                       wfDeprecated(
-                               '$wgLBFactoryConf must be updated. See RELEASE-NOTES for details',
-                               '1.23'
-                       );
-               }
-
-               return $class;
-       }
-
-       /**
-        * Shut down, close connections and destroy the cached instance.
-        */
-       public static function destroyInstance() {
-               if ( self::$instance ) {
-                       self::$instance->shutdown();
-                       self::$instance->forEachLBCallMethod( 'closeAll' );
-                       self::$instance = null;
-               }
-       }
-
-       /**
-        * Set the instance to be the given object
-        *
-        * @param LBFactory $instance
-        */
-       public static function setInstance( $instance ) {
-               self::destroyInstance();
-               self::$instance = $instance;
-       }
-
-       /**
-        * Construct a factory based on a configuration array (typically from $wgLBFactoryConf)
-        * @param array $conf
-        */
-       abstract public function __construct( array $conf );
-
-       /**
-        * Create a new load balancer object. The resulting object will be untracked,
-        * not chronology-protected, and the caller is responsible for cleaning it up.
-        *
-        * @param bool|string $wiki Wiki ID, or false for the current wiki
-        * @return LoadBalancer
-        */
-       abstract public function newMainLB( $wiki = false );
-
-       /**
-        * Get a cached (tracked) load balancer object.
-        *
-        * @param bool|string $wiki Wiki ID, or false for the current wiki
-        * @return LoadBalancer
-        */
-       abstract public function getMainLB( $wiki = false );
-
-       /**
-        * Create a new load balancer for external storage. The resulting object will be
-        * untracked, not chronology-protected, and the caller is responsible for
-        * cleaning it up.
-        *
-        * @param string $cluster External storage cluster, or false for core
-        * @param bool|string $wiki Wiki ID, or false for the current wiki
-        * @return LoadBalancer
-        */
-       abstract protected function newExternalLB( $cluster, $wiki = false );
-
-       /**
-        * Get a cached (tracked) load balancer for external storage
-        *
-        * @param string $cluster External storage cluster, or false for core
-        * @param bool|string $wiki Wiki ID, or false for the current wiki
-        * @return LoadBalancer
-        */
-       abstract public function &getExternalLB( $cluster, $wiki = false );
-
-       /**
-        * Execute a function for each tracked load balancer
-        * The callback is called with the load balancer as the first parameter,
-        * and $params passed as the subsequent parameters.
-        *
-        * @param callable $callback
-        * @param array $params
-        */
-       abstract public function forEachLB( $callback, array $params = array() );
-
-       /**
-        * Prepare all tracked load balancers for shutdown
-        * STUB
-        */
-       public function shutdown() {
-       }
-
-       /**
-        * Call a method of each tracked load balancer
-        *
-        * @param string $methodName
-        * @param array $args
-        */
-       private function forEachLBCallMethod( $methodName, array $args = array() ) {
-               $this->forEachLB( function ( LoadBalancer $loadBalancer, $methodName, array $args ) {
-                       call_user_func_array( array( $loadBalancer, $methodName ), $args );
-               }, array( $methodName, $args ) );
-       }
-
-       /**
-        * Commit on all connections. Done for two reasons:
-        * 1. To commit changes to the masters.
-        * 2. To release the snapshot on all connections, master and slave.
-        */
-       public function commitAll() {
-               $this->forEachLBCallMethod( 'commitAll' );
-       }
-
-       /**
-        * Commit changes on all master connections
-        */
-       public function commitMasterChanges() {
-               $this->forEachLBCallMethod( 'commitMasterChanges' );
-       }
-
-       /**
-        * Rollback changes on all master connections
-        * @since 1.23
-        */
-       public function rollbackMasterChanges() {
-               $this->forEachLBCallMethod( 'rollbackMasterChanges' );
-       }
-
-       /**
-        * Detemine if any master connection has pending changes.
-        * @since 1.23
-        * @return bool
-        */
-       public function hasMasterChanges() {
-               $ret = false;
-               $this->forEachLB( function ( LoadBalancer $lb ) use ( &$ret ) {
-                       $ret = $ret || $lb->hasMasterChanges();
-               } );
-               return $ret;
-       }
-}
-
-/**
- * A simple single-master LBFactory that gets its configuration from the b/c globals
- */
-class LBFactorySimple extends LBFactory {
-       /** @var LoadBalancer */
-       private $mainLB;
-
-       /** @var LoadBalancer[] */
-       private $extLBs = array();
-
-       /** @var ChronologyProtector */
-       private $chronProt;
-
-       public function __construct( array $conf ) {
-               $this->chronProt = new ChronologyProtector;
-       }
-
-       /**
-        * @param bool|string $wiki
-        * @return LoadBalancer
-        */
-       public function newMainLB( $wiki = false ) {
-               global $wgDBservers;
-               if ( $wgDBservers ) {
-                       $servers = $wgDBservers;
-               } else {
-                       global $wgDBserver, $wgDBuser, $wgDBpassword, $wgDBname, $wgDBtype, $wgDebugDumpSql;
-                       global $wgDBssl, $wgDBcompress;
-
-                       $flags = DBO_DEFAULT;
-                       if ( $wgDebugDumpSql ) {
-                               $flags |= DBO_DEBUG;
-                       }
-                       if ( $wgDBssl ) {
-                               $flags |= DBO_SSL;
-                       }
-                       if ( $wgDBcompress ) {
-                               $flags |= DBO_COMPRESS;
-                       }
-
-                       $servers = array( array(
-                               'host' => $wgDBserver,
-                               'user' => $wgDBuser,
-                               'password' => $wgDBpassword,
-                               'dbname' => $wgDBname,
-                               'type' => $wgDBtype,
-                               'load' => 1,
-                               'flags' => $flags
-                       ) );
-               }
-
-               return new LoadBalancer( array(
-                       'servers' => $servers,
-               ) );
-       }
-
-       /**
-        * @param bool|string $wiki
-        * @return LoadBalancer
-        */
-       public function getMainLB( $wiki = false ) {
-               if ( !isset( $this->mainLB ) ) {
-                       $this->mainLB = $this->newMainLB( $wiki );
-                       $this->mainLB->parentInfo( array( 'id' => 'main' ) );
-                       $this->chronProt->initLB( $this->mainLB );
-               }
-
-               return $this->mainLB;
-       }
-
-       /**
-        * @throws MWException
-        * @param string $cluster
-        * @param bool|string $wiki
-        * @return LoadBalancer
-        */
-       protected function newExternalLB( $cluster, $wiki = false ) {
-               global $wgExternalServers;
-               if ( !isset( $wgExternalServers[$cluster] ) ) {
-                       throw new MWException( __METHOD__ . ": Unknown cluster \"$cluster\"" );
-               }
-
-               return new LoadBalancer( array(
-                       'servers' => $wgExternalServers[$cluster]
-               ) );
-       }
-
-       /**
-        * @param string $cluster
-        * @param bool|string $wiki
-        * @return array
-        */
-       public function &getExternalLB( $cluster, $wiki = false ) {
-               if ( !isset( $this->extLBs[$cluster] ) ) {
-                       $this->extLBs[$cluster] = $this->newExternalLB( $cluster, $wiki );
-                       $this->extLBs[$cluster]->parentInfo( array( 'id' => "ext-$cluster" ) );
-                       $this->chronProt->initLB( $this->extLBs[$cluster] );
-               }
-
-               return $this->extLBs[$cluster];
-       }
-
-       /**
-        * Execute a function for each tracked load balancer
-        * The callback is called with the load balancer as the first parameter,
-        * and $params passed as the subsequent parameters.
-        *
-        * @param callable $callback
-        * @param array $params
-        */
-       public function forEachLB( $callback, array $params = array() ) {
-               if ( isset( $this->mainLB ) ) {
-                       call_user_func_array( $callback, array_merge( array( $this->mainLB ), $params ) );
-               }
-               foreach ( $this->extLBs as $lb ) {
-                       call_user_func_array( $callback, array_merge( array( $lb ), $params ) );
-               }
-       }
-
-       public function shutdown() {
-               if ( $this->mainLB ) {
-                       $this->chronProt->shutdownLB( $this->mainLB );
-               }
-               foreach ( $this->extLBs as $extLB ) {
-                       $this->chronProt->shutdownLB( $extLB );
-               }
-               $this->chronProt->shutdown();
-               $this->commitMasterChanges();
-       }
-}
-
-/**
- * LBFactory class that throws an error on any attempt to use it.
- * This will typically be done via wfGetDB().
- * Call LBFactory::disableBackend() to start using this, and
- * LBFactory::enableBackend() to return to normal behavior
- */
-class LBFactoryFake extends LBFactory {
-       public function __construct( array $conf ) {
-       }
-
-       public function newMainLB( $wiki = false ) {
-               throw new DBAccessError;
-       }
-
-       public function getMainLB( $wiki = false ) {
-               throw new DBAccessError;
-       }
-
-       protected function newExternalLB( $cluster, $wiki = false ) {
-               throw new DBAccessError;
-       }
-
-       public function &getExternalLB( $cluster, $wiki = false ) {
-               throw new DBAccessError;
-       }
-
-       public function forEachLB( $callback, array $params = array() ) {
-       }
-}
-
-/**
- * Exception class for attempted DB access
- */
-class DBAccessError extends MWException {
-       public function __construct() {
-               parent::__construct( "Mediawiki tried to access the database via wfGetDB(). " .
-                       "This is not allowed." );
-       }
-}
diff --git a/includes/db/LBFactoryMulti.php b/includes/db/LBFactoryMulti.php
deleted file mode 100644 (file)
index 92fbccd..0000000
+++ /dev/null
@@ -1,399 +0,0 @@
-<?php
-/**
- * Advanced generator of database load balancing objects for wiki farms.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- * http://www.gnu.org/copyleft/gpl.html
- *
- * @file
- * @ingroup Database
- */
-
-/**
- * A multi-wiki, multi-master factory for Wikimedia and similar installations.
- * Ignores the old configuration globals
- *
- * Configuration:
- *     sectionsByDB                A map of database names to section names.
- *
- *     sectionLoads                A 2-d map. For each section, gives a map of server names to
- *                                 load ratios. For example:
- *                                 array(
- *                                     'section1' => array(
- *                                         'db1' => 100,
- *                                         'db2' => 100
- *                                     )
- *                                 )
- *
- *     serverTemplate              A server info associative array as documented for $wgDBservers.
- *                                 The host, hostName and load entries will be overridden.
- *
- *     groupLoadsBySection         A 3-d map giving server load ratios for each section and group.
- *                                 For example:
- *                                 array(
- *                                     'section1' => array(
- *                                         'group1' => array(
- *                                             'db1' => 100,
- *                                             'db2' => 100
- *                                         )
- *                                     )
- *                                 )
- *
- *     groupLoadsByDB              A 3-d map giving server load ratios by DB name.
- *
- *     hostsByName                 A map of hostname to IP address.
- *
- *     externalLoads               A map of external storage cluster name to server load map.
- *
- *     externalTemplateOverrides   A set of server info keys overriding serverTemplate for external
- *                                 storage.
- *
- *     templateOverridesByServer   A 2-d map overriding serverTemplate and
- *                                 externalTemplateOverrides on a server-by-server basis. Applies
- *                                 to both core and external storage.
- *
- *     templateOverridesByCluster  A 2-d map overriding the server info by external storage cluster.
- *
- *     masterTemplateOverrides     An override array for all master servers.
- *
- *     readOnlyBySection           A map of section name to read-only message.
- *                                 Missing or false for read/write.
- *
- * @ingroup Database
- */
-class LBFactoryMulti extends LBFactory {
-       // Required settings
-
-       /** @var array A map of database names to section names */
-       private $sectionsByDB;
-
-       /**
-        * @var array A 2-d map. For each section, gives a map of server names to
-        * load ratios
-        */
-       private $sectionLoads;
-
-       /**
-        * @var array A server info associative array as documented for
-        * $wgDBservers. The host, hostName and load entries will be
-        * overridden
-        */
-       private $serverTemplate;
-
-       // Optional settings
-
-       /** @var array A 3-d map giving server load ratios for each section and group */
-       private $groupLoadsBySection = array();
-
-       /** @var array A 3-d map giving server load ratios by DB name */
-       private $groupLoadsByDB = array();
-
-       /** @var array A map of hostname to IP address */
-       private $hostsByName = array();
-
-       /** @var array A map of external storage cluster name to server load map */
-       private $externalLoads = array();
-
-       /**
-        * @var array A set of server info keys overriding serverTemplate for
-        * external storage
-        */
-       private $externalTemplateOverrides;
-
-       /**
-        * @var array A 2-d map overriding serverTemplate and
-        * externalTemplateOverrides on a server-by-server basis. Applies to both
-        * core and external storage
-        */
-       private $templateOverridesByServer;
-
-       /** @var array A 2-d map overriding the server info by external storage cluster */
-       private $templateOverridesByCluster;
-
-       /** @var array An override array for all master servers */
-       private $masterTemplateOverrides;
-
-       /**
-        * @var array|bool A map of section name to read-only message. Missing or
-        * false for read/write
-        */
-       private $readOnlyBySection = array();
-
-       // Other stuff
-
-       /** @var array Load balancer factory configuration */
-       private $conf;
-
-       /** @var LoadBalancer[] */
-       private $mainLBs = array();
-
-       /** @var LoadBalancer[] */
-       private $extLBs = array();
-
-       /** @var string */
-       private $lastWiki;
-
-       /** @var string */
-       private $lastSection;
-
-       /**
-        * @param array $conf
-        * @throws MWException
-        */
-       public function __construct( array $conf ) {
-               $this->chronProt = new ChronologyProtector;
-               $this->conf = $conf;
-               $required = array( 'sectionsByDB', 'sectionLoads', 'serverTemplate' );
-               $optional = array( 'groupLoadsBySection', 'groupLoadsByDB', 'hostsByName',
-                       'externalLoads', 'externalTemplateOverrides', 'templateOverridesByServer',
-                       'templateOverridesByCluster', 'masterTemplateOverrides',
-                       'readOnlyBySection' );
-
-               foreach ( $required as $key ) {
-                       if ( !isset( $conf[$key] ) ) {
-                               throw new MWException( __CLASS__ . ": $key is required in configuration" );
-                       }
-                       $this->$key = $conf[$key];
-               }
-
-               foreach ( $optional as $key ) {
-                       if ( isset( $conf[$key] ) ) {
-                               $this->$key = $conf[$key];
-                       }
-               }
-
-               // Check for read-only mode
-               $section = $this->getSectionForWiki();
-               if ( !empty( $this->readOnlyBySection[$section] ) ) {
-                       global $wgReadOnly;
-                       $wgReadOnly = $this->readOnlyBySection[$section];
-               }
-       }
-
-       /**
-        * @param bool|string $wiki
-        * @return string
-        */
-       private function getSectionForWiki( $wiki = false ) {
-               if ( $this->lastWiki === $wiki ) {
-                       return $this->lastSection;
-               }
-               list( $dbName, ) = $this->getDBNameAndPrefix( $wiki );
-               if ( isset( $this->sectionsByDB[$dbName] ) ) {
-                       $section = $this->sectionsByDB[$dbName];
-               } else {
-                       $section = 'DEFAULT';
-               }
-               $this->lastSection = $section;
-               $this->lastWiki = $wiki;
-
-               return $section;
-       }
-
-       /**
-        * @param bool|string $wiki
-        * @return LoadBalancer
-        */
-       public function newMainLB( $wiki = false ) {
-               list( $dbName, ) = $this->getDBNameAndPrefix( $wiki );
-               $section = $this->getSectionForWiki( $wiki );
-               $groupLoads = array();
-               if ( isset( $this->groupLoadsByDB[$dbName] ) ) {
-                       $groupLoads = $this->groupLoadsByDB[$dbName];
-               }
-
-               if ( isset( $this->groupLoadsBySection[$section] ) ) {
-                       $groupLoads = array_merge_recursive( $groupLoads, $this->groupLoadsBySection[$section] );
-               }
-
-               return $this->newLoadBalancer(
-                       $this->serverTemplate,
-                       $this->sectionLoads[$section],
-                       $groupLoads
-               );
-       }
-
-       /**
-        * @param bool|string $wiki
-        * @return LoadBalancer
-        */
-       public function getMainLB( $wiki = false ) {
-               $section = $this->getSectionForWiki( $wiki );
-               if ( !isset( $this->mainLBs[$section] ) ) {
-                       $lb = $this->newMainLB( $wiki );
-                       $lb->parentInfo( array( 'id' => "main-$section" ) );
-                       $this->chronProt->initLB( $lb );
-                       $this->mainLBs[$section] = $lb;
-               }
-
-               return $this->mainLBs[$section];
-       }
-
-       /**
-        * @param string $cluster
-        * @param bool|string $wiki
-        * @throws MWException
-        * @return LoadBalancer
-        */
-       protected function newExternalLB( $cluster, $wiki = false ) {
-               if ( !isset( $this->externalLoads[$cluster] ) ) {
-                       throw new MWException( __METHOD__ . ": Unknown cluster \"$cluster\"" );
-               }
-               $template = $this->serverTemplate;
-               if ( isset( $this->externalTemplateOverrides ) ) {
-                       $template = $this->externalTemplateOverrides + $template;
-               }
-               if ( isset( $this->templateOverridesByCluster[$cluster] ) ) {
-                       $template = $this->templateOverridesByCluster[$cluster] + $template;
-               }
-
-               return $this->newLoadBalancer( $template, $this->externalLoads[$cluster], array() );
-       }
-
-       /**
-        * @param string $cluster External storage cluster, or false for core
-        * @param bool|string $wiki Wiki ID, or false for the current wiki
-        * @return LoadBalancer
-        */
-       public function &getExternalLB( $cluster, $wiki = false ) {
-               if ( !isset( $this->extLBs[$cluster] ) ) {
-                       $this->extLBs[$cluster] = $this->newExternalLB( $cluster, $wiki );
-                       $this->extLBs[$cluster]->parentInfo( array( 'id' => "ext-$cluster" ) );
-                       $this->chronProt->initLB( $this->extLBs[$cluster] );
-               }
-
-               return $this->extLBs[$cluster];
-       }
-
-       /**
-        * Make a new load balancer object based on template and load array
-        *
-        * @param array $template
-        * @param array $loads
-        * @param array $groupLoads
-        * @return LoadBalancer
-        */
-       private function newLoadBalancer( $template, $loads, $groupLoads ) {
-               $servers = $this->makeServerArray( $template, $loads, $groupLoads );
-               $lb = new LoadBalancer( array(
-                       'servers' => $servers,
-               ) );
-
-               return $lb;
-       }
-
-       /**
-        * Make a server array as expected by LoadBalancer::__construct, using a template and load array
-        *
-        * @param array $template
-        * @param array $loads
-        * @param array $groupLoads
-        * @return array
-        */
-       private function makeServerArray( $template, $loads, $groupLoads ) {
-               $servers = array();
-               $master = true;
-               $groupLoadsByServer = $this->reindexGroupLoads( $groupLoads );
-               foreach ( $groupLoadsByServer as $server => $stuff ) {
-                       if ( !isset( $loads[$server] ) ) {
-                               $loads[$server] = 0;
-                       }
-               }
-               foreach ( $loads as $serverName => $load ) {
-                       $serverInfo = $template;
-                       if ( $master ) {
-                               $serverInfo['master'] = true;
-                               if ( isset( $this->masterTemplateOverrides ) ) {
-                                       $serverInfo = $this->masterTemplateOverrides + $serverInfo;
-                               }
-                               $master = false;
-                       }
-                       if ( isset( $this->templateOverridesByServer[$serverName] ) ) {
-                               $serverInfo = $this->templateOverridesByServer[$serverName] + $serverInfo;
-                       }
-                       if ( isset( $groupLoadsByServer[$serverName] ) ) {
-                               $serverInfo['groupLoads'] = $groupLoadsByServer[$serverName];
-                       }
-                       if ( isset( $this->hostsByName[$serverName] ) ) {
-                               $serverInfo['host'] = $this->hostsByName[$serverName];
-                       } else {
-                               $serverInfo['host'] = $serverName;
-                       }
-                       $serverInfo['hostName'] = $serverName;
-                       $serverInfo['load'] = $load;
-                       $servers[] = $serverInfo;
-               }
-
-               return $servers;
-       }
-
-       /**
-        * Take a group load array indexed by group then server, and reindex it by server then group
-        * @param array $groupLoads
-        * @return array
-        */
-       private function reindexGroupLoads( $groupLoads ) {
-               $reindexed = array();
-               foreach ( $groupLoads as $group => $loads ) {
-                       foreach ( $loads as $server => $load ) {
-                               $reindexed[$server][$group] = $load;
-                       }
-               }
-
-               return $reindexed;
-       }
-
-       /**
-        * Get the database name and prefix based on the wiki ID
-        * @param bool|string $wiki
-        * @return array
-        */
-       private function getDBNameAndPrefix( $wiki = false ) {
-               if ( $wiki === false ) {
-                       global $wgDBname, $wgDBprefix;
-
-                       return array( $wgDBname, $wgDBprefix );
-               } else {
-                       return wfSplitWikiID( $wiki );
-               }
-       }
-
-       /**
-        * Execute a function for each tracked load balancer
-        * The callback is called with the load balancer as the first parameter,
-        * and $params passed as the subsequent parameters.
-        * @param callable $callback
-        * @param array $params
-        */
-       public function forEachLB( $callback, array $params = array() ) {
-               foreach ( $this->mainLBs as $lb ) {
-                       call_user_func_array( $callback, array_merge( array( $lb ), $params ) );
-               }
-               foreach ( $this->extLBs as $lb ) {
-                       call_user_func_array( $callback, array_merge( array( $lb ), $params ) );
-               }
-       }
-
-       public function shutdown() {
-               foreach ( $this->mainLBs as $lb ) {
-                       $this->chronProt->shutdownLB( $lb );
-               }
-               foreach ( $this->extLBs as $extLB ) {
-                       $this->chronProt->shutdownLB( $extLB );
-               }
-               $this->chronProt->shutdown();
-               $this->commitMasterChanges();
-       }
-}
diff --git a/includes/db/LBFactorySingle.php b/includes/db/LBFactorySingle.php
deleted file mode 100644 (file)
index a41dadf..0000000
+++ /dev/null
@@ -1,112 +0,0 @@
-<?php
-/**
- * Simple generator of database connections that always returns the same object.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- * http://www.gnu.org/copyleft/gpl.html
- *
- * @file
- * @ingroup Database
- */
-
-/**
- * An LBFactory class that always returns a single database object.
- */
-class LBFactorySingle extends LBFactory {
-       /** @var LoadBalancerSingle */
-       private $lb;
-
-       /**
-        * @param array $conf An associative array with one member:
-        *  - connection: The DatabaseBase connection object
-        */
-       public function __construct( array $conf ) {
-               $this->lb = new LoadBalancerSingle( $conf );
-       }
-
-       /**
-        * @param bool|string $wiki
-        * @return LoadBalancerSingle
-        */
-       public function newMainLB( $wiki = false ) {
-               return $this->lb;
-       }
-
-       /**
-        * @param bool|string $wiki
-        * @return LoadBalancerSingle
-        */
-       public function getMainLB( $wiki = false ) {
-               return $this->lb;
-       }
-
-       /**
-        * @param string $cluster External storage cluster, or false for core
-        * @param bool|string $wiki Wiki ID, or false for the current wiki
-        * @return LoadBalancerSingle
-        */
-       protected function newExternalLB( $cluster, $wiki = false ) {
-               return $this->lb;
-       }
-
-       /**
-        * @param string $cluster External storage cluster, or false for core
-        * @param bool|string $wiki Wiki ID, or false for the current wiki
-        * @return LoadBalancerSingle
-        */
-       public function &getExternalLB( $cluster, $wiki = false ) {
-               return $this->lb;
-       }
-
-       /**
-        * @param string|callable $callback
-        * @param array $params
-        */
-       public function forEachLB( $callback, array $params = array() ) {
-               call_user_func_array( $callback, array_merge( array( $this->lb ), $params ) );
-       }
-}
-
-/**
- * Helper class for LBFactorySingle.
- */
-class LoadBalancerSingle extends LoadBalancer {
-       /** @var DatabaseBase */
-       private $db;
-
-       /**
-        * @param array $params
-        */
-       public function __construct( array $params ) {
-               $this->db = $params['connection'];
-               parent::__construct( array( 'servers' => array( array(
-                       'type' => $this->db->getType(),
-                       'host' => $this->db->getServer(),
-                       'dbname' => $this->db->getDBname(),
-                       'load' => 1,
-               ) ) ) );
-       }
-
-       /**
-        *
-        * @param string $server
-        * @param bool $dbNameOverride
-        *
-        * @return DatabaseBase
-        */
-       protected function reallyOpenConnection( $server, $dbNameOverride = false ) {
-               return $this->db;
-       }
-}
diff --git a/includes/db/LoadBalancer.php b/includes/db/LoadBalancer.php
deleted file mode 100644 (file)
index 52dca08..0000000
+++ /dev/null
@@ -1,1273 +0,0 @@
-<?php
-/**
- * Database load balancing.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- * http://www.gnu.org/copyleft/gpl.html
- *
- * @file
- * @ingroup Database
- */
-
-/**
- * Database load balancing object
- *
- * @todo document
- * @ingroup Database
- */
-class LoadBalancer {
-       /** @var array[] Map of (server index => server config array) */
-       private $mServers;
-       /** @var array[] Map of (local/foreignUsed/foreignFree => server index => DatabaseBase array) */
-       private $mConns;
-       /** @var array Map of (server index => weight) */
-       private $mLoads;
-       /** @var array[] Map of (group => server index => weight) */
-       private $mGroupLoads;
-       /** @var bool Whether to disregard slave lag as a factor in slave selection */
-       private $mAllowLagged;
-       /** @var integer Seconds to spend waiting on slave lag to resolve */
-       private $mWaitTimeout;
-
-       /** @var array LBFactory information */
-       private $mParentInfo;
-       /** @var string The LoadMonitor subclass name */
-       private $mLoadMonitorClass;
-       /** @var LoadMonitor */
-       private $mLoadMonitor;
-
-       /** @var bool|DatabaseBase Database connection that caused a problem */
-       private $mErrorConnection;
-       /** @var integer The generic (not query grouped) slave index (of $mServers) */
-       private $mReadIndex;
-       /** @var bool|DBMasterPos False if not set */
-       private $mWaitForPos;
-       /** @var bool Whether the generic reader fell back to a lagged slave */
-       private $mLaggedSlaveMode;
-       /** @var string The last DB selection or connection error */
-       private $mLastError = 'Unknown error';
-       /** @var integer Total connections opened */
-       private $connsOpened = 0;
-
-       /** @var integer Warn when this many connection are held */
-       const CONN_HELD_WARN_THRESHOLD = 10;
-
-       /**
-        * @param array $params Array with keys:
-        *   servers           Required. Array of server info structures.
-        *   loadMonitor       Name of a class used to fetch server lag and load.
-        * @throws MWException
-        */
-       public function __construct( array $params ) {
-               if ( !isset( $params['servers'] ) ) {
-                       throw new MWException( __CLASS__ . ': missing servers parameter' );
-               }
-               $this->mServers = $params['servers'];
-               $this->mWaitTimeout = 10;
-
-               $this->mReadIndex = -1;
-               $this->mWriteIndex = -1;
-               $this->mConns = array(
-                       'local' => array(),
-                       'foreignUsed' => array(),
-                       'foreignFree' => array() );
-               $this->mLoads = array();
-               $this->mWaitForPos = false;
-               $this->mLaggedSlaveMode = false;
-               $this->mErrorConnection = false;
-               $this->mAllowLagged = false;
-
-               if ( isset( $params['loadMonitor'] ) ) {
-                       $this->mLoadMonitorClass = $params['loadMonitor'];
-               } else {
-                       $master = reset( $params['servers'] );
-                       if ( isset( $master['type'] ) && $master['type'] === 'mysql' ) {
-                               $this->mLoadMonitorClass = 'LoadMonitorMySQL';
-                       } else {
-                               $this->mLoadMonitorClass = 'LoadMonitorNull';
-                       }
-               }
-
-               foreach ( $params['servers'] as $i => $server ) {
-                       $this->mLoads[$i] = $server['load'];
-                       if ( isset( $server['groupLoads'] ) ) {
-                               foreach ( $server['groupLoads'] as $group => $ratio ) {
-                                       if ( !isset( $this->mGroupLoads[$group] ) ) {
-                                               $this->mGroupLoads[$group] = array();
-                                       }
-                                       $this->mGroupLoads[$group][$i] = $ratio;
-                               }
-                       }
-               }
-       }
-
-       /**
-        * Get a LoadMonitor instance
-        *
-        * @return LoadMonitor
-        */
-       private function getLoadMonitor() {
-               if ( !isset( $this->mLoadMonitor ) ) {
-                       $class = $this->mLoadMonitorClass;
-                       $this->mLoadMonitor = new $class( $this );
-               }
-
-               return $this->mLoadMonitor;
-       }
-
-       /**
-        * Get or set arbitrary data used by the parent object, usually an LBFactory
-        * @param mixed $x
-        * @return mixed
-        */
-       public function parentInfo( $x = null ) {
-               return wfSetVar( $this->mParentInfo, $x );
-       }
-
-       /**
-        * Given an array of non-normalised probabilities, this function will select
-        * an element and return the appropriate key
-        *
-        * @deprecated since 1.21, use ArrayUtils::pickRandom()
-        *
-        * @param array $weights
-        * @return bool|int|string
-        */
-       public function pickRandom( array $weights ) {
-               return ArrayUtils::pickRandom( $weights );
-       }
-
-       /**
-        * @param array $loads
-        * @param bool|string $wiki Wiki to get non-lagged for
-        * @param float $maxLag Restrict the maximum allowed lag to this many seconds
-        * @return bool|int|string
-        */
-       private function getRandomNonLagged( array $loads, $wiki = false, $maxLag = INF ) {
-               $lags = $this->getLagTimes( $wiki );
-
-               # Unset excessively lagged servers
-               foreach ( $lags as $i => $lag ) {
-                       if ( $i != 0 ) {
-                               $maxServerLag = $maxLag;
-                               if ( isset( $this->mServers[$i]['max lag'] ) ) {
-                                       $maxServerLag = min( $maxServerLag, $this->mServers[$i]['max lag'] );
-                               }
-                               if ( $lag === false ) {
-                                       wfDebugLog( 'replication', "Server #$i is not replicating" );
-                                       unset( $loads[$i] );
-                               } elseif ( $lag > $maxServerLag ) {
-                                       wfDebugLog( 'replication', "Server #$i is excessively lagged ($lag seconds)" );
-                                       unset( $loads[$i] );
-                               }
-                       }
-               }
-
-               # Find out if all the slaves with non-zero load are lagged
-               $sum = 0;
-               foreach ( $loads as $load ) {
-                       $sum += $load;
-               }
-               if ( $sum == 0 ) {
-                       # No appropriate DB servers except maybe the master and some slaves with zero load
-                       # Do NOT use the master
-                       # Instead, this function will return false, triggering read-only mode,
-                       # and a lagged slave will be used instead.
-                       return false;
-               }
-
-               if ( count( $loads ) == 0 ) {
-                       return false;
-               }
-
-               #wfDebugLog( 'connect', var_export( $loads, true ) );
-
-               # Return a random representative of the remainder
-               return ArrayUtils::pickRandom( $loads );
-       }
-
-       /**
-        * Get the index of the reader connection, which may be a slave
-        * This takes into account load ratios and lag times. It should
-        * always return a consistent index during a given invocation
-        *
-        * Side effect: opens connections to databases
-        * @param string|bool $group Query group, or false for the generic reader
-        * @param string|bool $wiki Wiki ID, or false for the current wiki
-        * @throws MWException
-        * @return bool|int|string
-        */
-       public function getReaderIndex( $group = false, $wiki = false ) {
-               global $wgDBtype;
-
-               # @todo FIXME: For now, only go through all this for mysql databases
-               if ( $wgDBtype != 'mysql' ) {
-                       return $this->getWriterIndex();
-               }
-
-               if ( count( $this->mServers ) == 1 ) {
-                       # Skip the load balancing if there's only one server
-                       return 0;
-               } elseif ( $group === false && $this->mReadIndex >= 0 ) {
-                       # Shortcut if generic reader exists already
-                       return $this->mReadIndex;
-               }
-
-               # Find the relevant load array
-               if ( $group !== false ) {
-                       if ( isset( $this->mGroupLoads[$group] ) ) {
-                               $nonErrorLoads = $this->mGroupLoads[$group];
-                       } else {
-                               # No loads for this group, return false and the caller can use some other group
-                               wfDebug( __METHOD__ . ": no loads for group $group\n" );
-
-                               return false;
-                       }
-               } else {
-                       $nonErrorLoads = $this->mLoads;
-               }
-
-               if ( !count( $nonErrorLoads ) ) {
-                       throw new MWException( "Empty server array given to LoadBalancer" );
-               }
-
-               # Scale the configured load ratios according to the dynamic load (if the load monitor supports it)
-               $this->getLoadMonitor()->scaleLoads( $nonErrorLoads, $group, $wiki );
-
-               $laggedSlaveMode = false;
-
-               # No server found yet
-               $i = false;
-               # First try quickly looking through the available servers for a server that
-               # meets our criteria
-               $currentLoads = $nonErrorLoads;
-               while ( count( $currentLoads ) ) {
-                       if ( $this->mAllowLagged || $laggedSlaveMode ) {
-                               $i = ArrayUtils::pickRandom( $currentLoads );
-                       } else {
-                               $i = false;
-                               if ( $this->mWaitForPos && $this->mWaitForPos->asOfTime() ) {
-                                       # ChronologyProtecter causes mWaitForPos to be set via sessions.
-                                       # This triggers doWait() after connect, so it's especially good to
-                                       # avoid lagged servers so as to avoid just blocking in that method.
-                                       $ago = microtime( true ) - $this->mWaitForPos->asOfTime();
-                                       # Aim for <= 1 second of waiting (being too picky can backfire)
-                                       $i = $this->getRandomNonLagged( $currentLoads, $wiki, $ago + 1 );
-                               }
-                               if ( $i === false ) {
-                                       # Any server with less lag than it's 'max lag' param is preferable
-                                       $i = $this->getRandomNonLagged( $currentLoads, $wiki );
-                               }
-                               if ( $i === false && count( $currentLoads ) != 0 ) {
-                                       # All slaves lagged. Switch to read-only mode
-                                       wfDebugLog( 'replication', "All slaves lagged. Switch to read-only mode" );
-                                       $i = ArrayUtils::pickRandom( $currentLoads );
-                                       $laggedSlaveMode = true;
-                               }
-                       }
-
-                       if ( $i === false ) {
-                               # pickRandom() returned false
-                               # This is permanent and means the configuration or the load monitor
-                               # wants us to return false.
-                               wfDebugLog( 'connect', __METHOD__ . ": pickRandom() returned false" );
-
-                               return false;
-                       }
-
-                       $serverName = $this->getServerName( $i );
-                       wfDebugLog( 'connect', __METHOD__ . ": Using reader #$i: $serverName..." );
-
-                       $conn = $this->openConnection( $i, $wiki );
-                       if ( !$conn ) {
-                               wfDebugLog( 'connect', __METHOD__ . ": Failed connecting to $i/$wiki" );
-                               unset( $nonErrorLoads[$i] );
-                               unset( $currentLoads[$i] );
-                               $i = false;
-                               continue;
-                       }
-
-                       // Decrement reference counter, we are finished with this connection.
-                       // It will be incremented for the caller later.
-                       if ( $wiki !== false ) {
-                               $this->reuseConnection( $conn );
-                       }
-
-                       # Return this server
-                       break;
-               }
-
-               # If all servers were down, quit now
-               if ( !count( $nonErrorLoads ) ) {
-                       wfDebugLog( 'connect', "All servers down" );
-               }
-
-               if ( $i !== false ) {
-                       # Slave connection successful
-                       # Wait for the session master pos for a short time
-                       if ( $this->mWaitForPos && $i > 0 ) {
-                               if ( !$this->doWait( $i ) ) {
-                                       $this->mServers[$i]['slave pos'] = $conn->getSlavePos();
-                               }
-                       }
-                       if ( $this->mReadIndex <= 0 && $this->mLoads[$i] > 0 && $group === false ) {
-                               $this->mReadIndex = $i;
-                               # Record if the generic reader index is in "lagged slave" mode
-                               if ( $laggedSlaveMode ) {
-                                       $this->mLaggedSlaveMode = true;
-                               }
-                       }
-                       $serverName = $this->getServerName( $i );
-                       wfDebug( __METHOD__ . ": using server $serverName for group '$group'\n" );
-               }
-
-               return $i;
-       }
-
-       /**
-        * Set the master wait position
-        * If a DB_SLAVE connection has been opened already, waits
-        * Otherwise sets a variable telling it to wait if such a connection is opened
-        * @param DBMasterPos $pos
-        */
-       public function waitFor( $pos ) {
-               $this->mWaitForPos = $pos;
-               $i = $this->mReadIndex;
-
-               if ( $i > 0 ) {
-                       if ( !$this->doWait( $i ) ) {
-                               $this->mServers[$i]['slave pos'] = $this->getAnyOpenConnection( $i )->getSlavePos();
-                               $this->mLaggedSlaveMode = true;
-                       }
-               }
-       }
-
-       /**
-        * Set the master wait position and wait for a "generic" slave to catch up to it
-        *
-        * This can be used a faster proxy for waitForAll()
-        *
-        * @param DBMasterPos $pos
-        * @param int $timeout Max seconds to wait; default is mWaitTimeout
-        * @return bool Success (able to connect and no timeouts reached)
-        * @since 1.26
-        */
-       public function waitForOne( $pos, $timeout = null ) {
-               $this->mWaitForPos = $pos;
-
-               $i = $this->mReadIndex;
-               if ( $i <= 0 ) {
-                       // Pick a generic slave if there isn't one yet
-                       $readLoads = $this->mLoads;
-                       unset( $readLoads[$this->getWriterIndex()] ); // slaves only
-                       $readLoads = array_filter( $readLoads ); // with non-zero load
-                       $i = ArrayUtils::pickRandom( $readLoads );
-               }
-
-               if ( $i > 0 ) {
-                       $ok = $this->doWait( $i, true, $timeout );
-               } else {
-                       $ok = true; // no applicable loads
-               }
-
-               return $ok;
-       }
-
-       /**
-        * Set the master wait position and wait for ALL slaves to catch up to it
-        * @param DBMasterPos $pos
-        * @param int $timeout Max seconds to wait; default is mWaitTimeout
-        * @return bool Success (able to connect and no timeouts reached)
-        */
-       public function waitForAll( $pos, $timeout = null ) {
-               $this->mWaitForPos = $pos;
-               $serverCount = count( $this->mServers );
-
-               $ok = true;
-               for ( $i = 1; $i < $serverCount; $i++ ) {
-                       if ( $this->mLoads[$i] > 0 ) {
-                               $ok = $this->doWait( $i, true, $timeout ) && $ok;
-                       }
-               }
-
-               return $ok;
-       }
-
-       /**
-        * Get any open connection to a given server index, local or foreign
-        * Returns false if there is no connection open
-        *
-        * @param int $i
-        * @return DatabaseBase|bool False on failure
-        */
-       public function getAnyOpenConnection( $i ) {
-               foreach ( $this->mConns as $conns ) {
-                       if ( !empty( $conns[$i] ) ) {
-                               return reset( $conns[$i] );
-                       }
-               }
-
-               return false;
-       }
-
-       /**
-        * Wait for a given slave to catch up to the master pos stored in $this
-        * @param int $index Server index
-        * @param bool $open Check the server even if a new connection has to be made
-        * @param int $timeout Max seconds to wait; default is mWaitTimeout
-        * @return bool
-        */
-       protected function doWait( $index, $open = false, $timeout = null ) {
-               $close = false; // close the connection afterwards
-
-               # Find a connection to wait on, creating one if needed and allowed
-               $conn = $this->getAnyOpenConnection( $index );
-               if ( !$conn ) {
-                       if ( !$open ) {
-                               wfDebug( __METHOD__ . ": no connection open\n" );
-
-                               return false;
-                       } else {
-                               $conn = $this->openConnection( $index, '' );
-                               if ( !$conn ) {
-                                       wfDebug( __METHOD__ . ": failed to open connection\n" );
-
-                                       return false;
-                               }
-                               // Avoid connection spam in waitForAll() when connections
-                               // are made just for the sake of doing this lag check.
-                               $close = true;
-                       }
-               }
-
-               wfDebug( __METHOD__ . ": Waiting for slave #$index to catch up...\n" );
-               $timeout = $timeout ?: $this->mWaitTimeout;
-               $result = $conn->masterPosWait( $this->mWaitForPos, $timeout );
-
-               if ( $result == -1 || is_null( $result ) ) {
-                       # Timed out waiting for slave, use master instead
-                       $server = $server = $this->getServerName( $index );
-                       $msg = __METHOD__ . ": Timed out waiting on $server pos {$this->mWaitForPos}";
-                       wfDebug( "$msg\n" );
-                       wfDebugLog( 'DBPerformance', "$msg:\n" . wfBacktrace( true ) );
-                       $ok = false;
-               } else {
-                       wfDebug( __METHOD__ . ": Done\n" );
-                       $ok = true;
-               }
-
-               if ( $close ) {
-                       $this->closeConnection( $conn );
-               }
-
-               return $ok;
-       }
-
-       /**
-        * Get a connection by index
-        * This is the main entry point for this class.
-        *
-        * @param int $i Server index
-        * @param array|string|bool $groups Query group(s), or false for the generic reader
-        * @param string|bool $wiki Wiki ID, or false for the current wiki
-        *
-        * @throws MWException
-        * @return DatabaseBase
-        */
-       public function getConnection( $i, $groups = array(), $wiki = false ) {
-               if ( $i === null || $i === false ) {
-                       throw new MWException( 'Attempt to call ' . __METHOD__ .
-                               ' with invalid server index' );
-               }
-
-               if ( $wiki === wfWikiID() ) {
-                       $wiki = false;
-               }
-
-               $groups = ( $groups === false || $groups === array() )
-                       ? array( false ) // check one "group": the generic pool
-                       : (array)$groups;
-
-               $masterOnly = ( $i == DB_MASTER || $i == $this->getWriterIndex() );
-               $oldConnsOpened = $this->connsOpened; // connections open now
-
-               if ( $i == DB_MASTER ) {
-                       $i = $this->getWriterIndex();
-               } else {
-                       # Try to find an available server in any the query groups (in order)
-                       foreach ( $groups as $group ) {
-                               $groupIndex = $this->getReaderIndex( $group, $wiki );
-                               if ( $groupIndex !== false ) {
-                                       $i = $groupIndex;
-                                       break;
-                               }
-                       }
-               }
-
-               # Operation-based index
-               if ( $i == DB_SLAVE ) {
-                       $this->mLastError = 'Unknown error'; // reset error string
-                       # Try the general server pool if $groups are unavailable.
-                       $i = in_array( false, $groups, true )
-                               ? false // don't bother with this if that is what was tried above
-                               : $this->getReaderIndex( false, $wiki );
-                       # Couldn't find a working server in getReaderIndex()?
-                       if ( $i === false ) {
-                               $this->mLastError = 'No working slave server: ' . $this->mLastError;
-
-                               return $this->reportConnectionError();
-                       }
-               }
-
-               # Now we have an explicit index into the servers array
-               $conn = $this->openConnection( $i, $wiki );
-               if ( !$conn ) {
-                       return $this->reportConnectionError();
-               }
-
-               # Profile any new connections that happen
-               if ( $this->connsOpened > $oldConnsOpened ) {
-                       $host = $conn->getServer();
-                       $dbname = $conn->getDBname();
-                       $trxProf = Profiler::instance()->getTransactionProfiler();
-                       $trxProf->recordConnection( $host, $dbname, $masterOnly );
-               }
-
-               return $conn;
-       }
-
-       /**
-        * Mark a foreign connection as being available for reuse under a different
-        * DB name or prefix. This mechanism is reference-counted, and must be called
-        * the same number of times as getConnection() to work.
-        *
-        * @param DatabaseBase $conn
-        * @throws MWException
-        */
-       public function reuseConnection( $conn ) {
-               $serverIndex = $conn->getLBInfo( 'serverIndex' );
-               $refCount = $conn->getLBInfo( 'foreignPoolRefCount' );
-               if ( $serverIndex === null || $refCount === null ) {
-                       wfDebug( __METHOD__ . ": this connection was not opened as a foreign connection\n" );
-
-                       /**
-                        * This can happen in code like:
-                        *   foreach ( $dbs as $db ) {
-                        *     $conn = $lb->getConnection( DB_SLAVE, array(), $db );
-                        *     ...
-                        *     $lb->reuseConnection( $conn );
-                        *   }
-                        * When a connection to the local DB is opened in this way, reuseConnection()
-                        * should be ignored
-                        */
-
-                       return;
-               }
-
-               $dbName = $conn->getDBname();
-               $prefix = $conn->tablePrefix();
-               if ( strval( $prefix ) !== '' ) {
-                       $wiki = "$dbName-$prefix";
-               } else {
-                       $wiki = $dbName;
-               }
-               if ( $this->mConns['foreignUsed'][$serverIndex][$wiki] !== $conn ) {
-                       throw new MWException( __METHOD__ . ": connection not found, has " .
-                               "the connection been freed already?" );
-               }
-               $conn->setLBInfo( 'foreignPoolRefCount', --$refCount );
-               if ( $refCount <= 0 ) {
-                       $this->mConns['foreignFree'][$serverIndex][$wiki] = $conn;
-                       unset( $this->mConns['foreignUsed'][$serverIndex][$wiki] );
-                       wfDebug( __METHOD__ . ": freed connection $serverIndex/$wiki\n" );
-               } else {
-                       wfDebug( __METHOD__ . ": reference count for $serverIndex/$wiki reduced to $refCount\n" );
-               }
-       }
-
-       /**
-        * Get a database connection handle reference
-        *
-        * The handle's methods wrap simply wrap those of a DatabaseBase handle
-        *
-        * @see LoadBalancer::getConnection() for parameter information
-        *
-        * @param int $db
-        * @param array|string|bool $groups Query group(s), or false for the generic reader
-        * @param string|bool $wiki Wiki ID, or false for the current wiki
-        * @return DBConnRef
-        */
-       public function getConnectionRef( $db, $groups = array(), $wiki = false ) {
-               return new DBConnRef( $this, $this->getConnection( $db, $groups, $wiki ) );
-       }
-
-       /**
-        * Get a database connection handle reference without connecting yet
-        *
-        * The handle's methods wrap simply wrap those of a DatabaseBase handle
-        *
-        * @see LoadBalancer::getConnection() for parameter information
-        *
-        * @param int $db
-        * @param array|string|bool $groups Query group(s), or false for the generic reader
-        * @param string|bool $wiki Wiki ID, or false for the current wiki
-        * @return DBConnRef
-        */
-       public function getLazyConnectionRef( $db, $groups = array(), $wiki = false ) {
-               return new DBConnRef( $this, array( $db, $groups, $wiki ) );
-       }
-
-       /**
-        * Open a connection to the server given by the specified index
-        * Index must be an actual index into the array.
-        * If the server is already open, returns it.
-        *
-        * On error, returns false, and the connection which caused the
-        * error will be available via $this->mErrorConnection.
-        *
-        * @param int $i Server index
-        * @param string|bool $wiki Wiki ID, or false for the current wiki
-        * @return DatabaseBase
-        *
-        * @access private
-        */
-       public function openConnection( $i, $wiki = false ) {
-               if ( $wiki !== false ) {
-                       $conn = $this->openForeignConnection( $i, $wiki );
-               } elseif ( isset( $this->mConns['local'][$i][0] ) ) {
-                       $conn = $this->mConns['local'][$i][0];
-               } else {
-                       $server = $this->mServers[$i];
-                       $server['serverIndex'] = $i;
-                       $conn = $this->reallyOpenConnection( $server, false );
-                       $serverName = $this->getServerName( $i );
-                       if ( $conn->isOpen() ) {
-                               wfDebug( "Connected to database $i at $serverName\n" );
-                               $this->mConns['local'][$i][0] = $conn;
-                       } else {
-                               wfDebug( "Failed to connect to database $i at $serverName\n" );
-                               $this->mErrorConnection = $conn;
-                               $conn = false;
-                       }
-               }
-
-               if ( $conn && !$conn->isOpen() ) {
-                       // Connection was made but later unrecoverably lost for some reason.
-                       // Do not return a handle that will just throw exceptions on use,
-                       // but let the calling code (e.g. getReaderIndex) try another server.
-                       // See DatabaseMyslBase::ping() for how this can happen.
-                       $this->mErrorConnection = $conn;
-                       $conn = false;
-               }
-
-               return $conn;
-       }
-
-       /**
-        * Open a connection to a foreign DB, or return one if it is already open.
-        *
-        * Increments a reference count on the returned connection which locks the
-        * connection to the requested wiki. This reference count can be
-        * decremented by calling reuseConnection().
-        *
-        * If a connection is open to the appropriate server already, but with the wrong
-        * database, it will be switched to the right database and returned, as long as
-        * it has been freed first with reuseConnection().
-        *
-        * On error, returns false, and the connection which caused the
-        * error will be available via $this->mErrorConnection.
-        *
-        * @param int $i Server index
-        * @param string $wiki Wiki ID to open
-        * @return DatabaseBase
-        */
-       private function openForeignConnection( $i, $wiki ) {
-               list( $dbName, $prefix ) = wfSplitWikiID( $wiki );
-               if ( isset( $this->mConns['foreignUsed'][$i][$wiki] ) ) {
-                       // Reuse an already-used connection
-                       $conn = $this->mConns['foreignUsed'][$i][$wiki];
-                       wfDebug( __METHOD__ . ": reusing connection $i/$wiki\n" );
-               } elseif ( isset( $this->mConns['foreignFree'][$i][$wiki] ) ) {
-                       // Reuse a free connection for the same wiki
-                       $conn = $this->mConns['foreignFree'][$i][$wiki];
-                       unset( $this->mConns['foreignFree'][$i][$wiki] );
-                       $this->mConns['foreignUsed'][$i][$wiki] = $conn;
-                       wfDebug( __METHOD__ . ": reusing free connection $i/$wiki\n" );
-               } elseif ( !empty( $this->mConns['foreignFree'][$i] ) ) {
-                       // Reuse a connection from another wiki
-                       $conn = reset( $this->mConns['foreignFree'][$i] );
-                       $oldWiki = key( $this->mConns['foreignFree'][$i] );
-
-                       // The empty string as a DB name means "don't care".
-                       // DatabaseMysqlBase::open() already handle this on connection.
-                       if ( $dbName !== '' && !$conn->selectDB( $dbName ) ) {
-                               $this->mLastError = "Error selecting database $dbName on server " .
-                                       $conn->getServer() . " from client host " . wfHostname() . "\n";
-                               $this->mErrorConnection = $conn;
-                               $conn = false;
-                       } else {
-                               $conn->tablePrefix( $prefix );
-                               unset( $this->mConns['foreignFree'][$i][$oldWiki] );
-                               $this->mConns['foreignUsed'][$i][$wiki] = $conn;
-                               wfDebug( __METHOD__ . ": reusing free connection from $oldWiki for $wiki\n" );
-                       }
-               } else {
-                       // Open a new connection
-                       $server = $this->mServers[$i];
-                       $server['serverIndex'] = $i;
-                       $server['foreignPoolRefCount'] = 0;
-                       $server['foreign'] = true;
-                       $conn = $this->reallyOpenConnection( $server, $dbName );
-                       if ( !$conn->isOpen() ) {
-                               wfDebug( __METHOD__ . ": error opening connection for $i/$wiki\n" );
-                               $this->mErrorConnection = $conn;
-                               $conn = false;
-                       } else {
-                               $conn->tablePrefix( $prefix );
-                               $this->mConns['foreignUsed'][$i][$wiki] = $conn;
-                               wfDebug( __METHOD__ . ": opened new connection for $i/$wiki\n" );
-                       }
-               }
-
-               // Increment reference count
-               if ( $conn ) {
-                       $refCount = $conn->getLBInfo( 'foreignPoolRefCount' );
-                       $conn->setLBInfo( 'foreignPoolRefCount', $refCount + 1 );
-               }
-
-               return $conn;
-       }
-
-       /**
-        * Test if the specified index represents an open connection
-        *
-        * @param int $index Server index
-        * @access private
-        * @return bool
-        */
-       private function isOpen( $index ) {
-               if ( !is_integer( $index ) ) {
-                       return false;
-               }
-
-               return (bool)$this->getAnyOpenConnection( $index );
-       }
-
-       /**
-        * Really opens a connection. Uncached.
-        * Returns a Database object whether or not the connection was successful.
-        * @access private
-        *
-        * @param array $server
-        * @param bool $dbNameOverride
-        * @throws MWException
-        * @return DatabaseBase
-        */
-       protected function reallyOpenConnection( $server, $dbNameOverride = false ) {
-               if ( !is_array( $server ) ) {
-                       throw new MWException( 'You must update your load-balancing configuration. ' .
-                               'See DefaultSettings.php entry for $wgDBservers.' );
-               }
-
-               if ( $dbNameOverride !== false ) {
-                       $server['dbname'] = $dbNameOverride;
-               }
-
-               // Log when many connection are made on requests
-               if ( ++$this->connsOpened >= self::CONN_HELD_WARN_THRESHOLD ) {
-                       $masterAddr = $this->getServerName( 0 );
-                       wfDebugLog( 'DBPerformance', __METHOD__ . ": " .
-                               "{$this->connsOpened}+ connections made (master=$masterAddr)\n" .
-                               wfBacktrace( true ) );
-               }
-
-               # Create object
-               try {
-                       $db = DatabaseBase::factory( $server['type'], $server );
-               } catch ( DBConnectionError $e ) {
-                       // FIXME: This is probably the ugliest thing I have ever done to
-                       // PHP. I'm half-expecting it to segfault, just out of disgust. -- TS
-                       $db = $e->db;
-               }
-
-               $db->setLBInfo( $server );
-               if ( isset( $server['fakeSlaveLag'] ) ) {
-                       $db->setFakeSlaveLag( $server['fakeSlaveLag'] );
-               }
-               if ( isset( $server['fakeMaster'] ) ) {
-                       $db->setFakeMaster( true );
-               }
-
-               return $db;
-       }
-
-       /**
-        * @throws DBConnectionError
-        * @return bool
-        */
-       private function reportConnectionError() {
-               $conn = $this->mErrorConnection; // The connection which caused the error
-               $context = array(
-                       'method' => __METHOD__,
-                       'last_error' => $this->mLastError,
-               );
-
-               if ( !is_object( $conn ) ) {
-                       // No last connection, probably due to all servers being too busy
-                       wfLogDBError(
-                               "LB failure with no last connection. Connection error: {last_error}",
-                               $context
-                       );
-
-                       // If all servers were busy, mLastError will contain something sensible
-                       throw new DBConnectionError( null, $this->mLastError );
-               } else {
-                       $context['db_server'] = $conn->getProperty( 'mServer' );
-                       wfLogDBError(
-                               "Connection error: {last_error} ({db_server})",
-                               $context
-                       );
-                       $conn->reportConnectionError( "{$this->mLastError} ({$context['db_server']})" ); // throws DBConnectionError
-               }
-
-               return false; /* not reached */
-       }
-
-       /**
-        * @return int
-        * @since 1.26
-        */
-       public function getWriterIndex() {
-               return 0;
-       }
-
-       /**
-        * Returns true if the specified index is a valid server index
-        *
-        * @param string $i
-        * @return bool
-        */
-       public function haveIndex( $i ) {
-               return array_key_exists( $i, $this->mServers );
-       }
-
-       /**
-        * Returns true if the specified index is valid and has non-zero load
-        *
-        * @param string $i
-        * @return bool
-        */
-       public function isNonZeroLoad( $i ) {
-               return array_key_exists( $i, $this->mServers ) && $this->mLoads[$i] != 0;
-       }
-
-       /**
-        * Get the number of defined servers (not the number of open connections)
-        *
-        * @return int
-        */
-       public function getServerCount() {
-               return count( $this->mServers );
-       }
-
-       /**
-        * Get the host name or IP address of the server with the specified index
-        * Prefer a readable name if available.
-        * @param string $i
-        * @return string
-        */
-       public function getServerName( $i ) {
-               if ( isset( $this->mServers[$i]['hostName'] ) ) {
-                       $name = $this->mServers[$i]['hostName'];
-               } elseif ( isset( $this->mServers[$i]['host'] ) ) {
-                       $name = $this->mServers[$i]['host'];
-               } else {
-                       $name = '';
-               }
-
-               return ( $name != '' ) ? $name : 'localhost';
-       }
-
-       /**
-        * Return the server info structure for a given index, or false if the index is invalid.
-        * @param int $i
-        * @return array|bool
-        */
-       public function getServerInfo( $i ) {
-               if ( isset( $this->mServers[$i] ) ) {
-                       return $this->mServers[$i];
-               } else {
-                       return false;
-               }
-       }
-
-       /**
-        * Sets the server info structure for the given index. Entry at index $i
-        * is created if it doesn't exist
-        * @param int $i
-        * @param array $serverInfo
-        */
-       public function setServerInfo( $i, array $serverInfo ) {
-               $this->mServers[$i] = $serverInfo;
-       }
-
-       /**
-        * Get the current master position for chronology control purposes
-        * @return mixed
-        */
-       public function getMasterPos() {
-               # If this entire request was served from a slave without opening a connection to the
-               # master (however unlikely that may be), then we can fetch the position from the slave.
-               $masterConn = $this->getAnyOpenConnection( 0 );
-               if ( !$masterConn ) {
-                       $serverCount = count( $this->mServers );
-                       for ( $i = 1; $i < $serverCount; $i++ ) {
-                               $conn = $this->getAnyOpenConnection( $i );
-                               if ( $conn ) {
-                                       wfDebug( "Master pos fetched from slave\n" );
-
-                                       return $conn->getSlavePos();
-                               }
-                       }
-               } else {
-                       wfDebug( "Master pos fetched from master\n" );
-
-                       return $masterConn->getMasterPos();
-               }
-
-               return false;
-       }
-
-       /**
-        * Close all open connections
-        */
-       public function closeAll() {
-               foreach ( $this->mConns as $conns2 ) {
-                       foreach ( $conns2 as $conns3 ) {
-                               /** @var DatabaseBase $conn */
-                               foreach ( $conns3 as $conn ) {
-                                       $conn->close();
-                               }
-                       }
-               }
-               $this->mConns = array(
-                       'local' => array(),
-                       'foreignFree' => array(),
-                       'foreignUsed' => array(),
-               );
-               $this->connsOpened = 0;
-       }
-
-       /**
-        * Close a connection
-        * Using this function makes sure the LoadBalancer knows the connection is closed.
-        * If you use $conn->close() directly, the load balancer won't update its state.
-        * @param DatabaseBase $conn
-        */
-       public function closeConnection( $conn ) {
-               $done = false;
-               foreach ( $this->mConns as $i1 => $conns2 ) {
-                       foreach ( $conns2 as $i2 => $conns3 ) {
-                               foreach ( $conns3 as $i3 => $candidateConn ) {
-                                       if ( $conn === $candidateConn ) {
-                                               $conn->close();
-                                               unset( $this->mConns[$i1][$i2][$i3] );
-                                               --$this->connsOpened;
-                                               $done = true;
-                                               break;
-                                       }
-                               }
-                       }
-               }
-               if ( !$done ) {
-                       $conn->close();
-               }
-       }
-
-       /**
-        * Commit transactions on all open connections
-        */
-       public function commitAll() {
-               foreach ( $this->mConns as $conns2 ) {
-                       foreach ( $conns2 as $conns3 ) {
-                               /** @var DatabaseBase[] $conns3 */
-                               foreach ( $conns3 as $conn ) {
-                                       if ( $conn->trxLevel() ) {
-                                               $conn->commit( __METHOD__, 'flush' );
-                                       }
-                               }
-                       }
-               }
-       }
-
-       /**
-        *  Issue COMMIT only on master, only if queries were done on connection
-        */
-       public function commitMasterChanges() {
-               $masterIndex = $this->getWriterIndex();
-               foreach ( $this->mConns as $conns2 ) {
-                       if ( empty( $conns2[$masterIndex] ) ) {
-                               continue;
-                       }
-                       /** @var DatabaseBase $conn */
-                       foreach ( $conns2[$masterIndex] as $conn ) {
-                               if ( $conn->trxLevel() && $conn->writesOrCallbacksPending() ) {
-                                       $conn->commit( __METHOD__, 'flush' );
-                               }
-                       }
-               }
-       }
-
-       /**
-        * Issue ROLLBACK only on master, only if queries were done on connection
-        * @since 1.23
-        */
-       public function rollbackMasterChanges() {
-               $failedServers = array();
-
-               $masterIndex = $this->getWriterIndex();
-               foreach ( $this->mConns as $conns2 ) {
-                       if ( empty( $conns2[$masterIndex] ) ) {
-                               continue;
-                       }
-                       /** @var DatabaseBase $conn */
-                       foreach ( $conns2[$masterIndex] as $conn ) {
-                               if ( $conn->trxLevel() && $conn->writesOrCallbacksPending() ) {
-                                       try {
-                                               $conn->rollback( __METHOD__, 'flush' );
-                                       } catch ( DBError $e ) {
-                                               MWExceptionHandler::logException( $e );
-                                               $failedServers[] = $conn->getServer();
-                                       }
-                               }
-                       }
-               }
-
-               if ( $failedServers ) {
-                       throw new DBExpectedError( null, "Rollback failed on server(s) " .
-                               implode( ', ', array_unique( $failedServers ) ) );
-               }
-       }
-
-       /**
-        * @return bool Whether a master connection is already open
-        * @since 1.24
-        */
-       public function hasMasterConnection() {
-               return $this->isOpen( $this->getWriterIndex() );
-       }
-
-       /**
-        * Determine if there are pending changes in a transaction by this thread
-        * @since 1.23
-        * @return bool
-        */
-       public function hasMasterChanges() {
-               $masterIndex = $this->getWriterIndex();
-               foreach ( $this->mConns as $conns2 ) {
-                       if ( empty( $conns2[$masterIndex] ) ) {
-                               continue;
-                       }
-                       /** @var DatabaseBase $conn */
-                       foreach ( $conns2[$masterIndex] as $conn ) {
-                               if ( $conn->trxLevel() && $conn->writesOrCallbacksPending() ) {
-                                       return true;
-                               }
-                       }
-               }
-               return false;
-       }
-
-       /**
-        * Get the timestamp of the latest write query done by this thread
-        * @since 1.25
-        * @return float|bool UNIX timestamp or false
-        */
-       public function lastMasterChangeTimestamp() {
-               $lastTime = false;
-               $masterIndex = $this->getWriterIndex();
-               foreach ( $this->mConns as $conns2 ) {
-                       if ( empty( $conns2[$masterIndex] ) ) {
-                               continue;
-                       }
-                       /** @var DatabaseBase $conn */
-                       foreach ( $conns2[$masterIndex] as $conn ) {
-                               $lastTime = max( $lastTime, $conn->lastDoneWrites() );
-                       }
-               }
-               return $lastTime;
-       }
-
-       /**
-        * Check if this load balancer object had any recent or still
-        * pending writes issued against it by this PHP thread
-        *
-        * @param float $age How many seconds ago is "recent" [defaults to mWaitTimeout]
-        * @return bool
-        * @since 1.25
-        */
-       public function hasOrMadeRecentMasterChanges( $age = null ) {
-               $age = ( $age === null ) ? $this->mWaitTimeout : $age;
-
-               return ( $this->hasMasterChanges()
-                       || $this->lastMasterChangeTimestamp() > microtime( true ) - $age );
-       }
-
-       /**
-        * @param mixed $value
-        * @return mixed
-        */
-       public function waitTimeout( $value = null ) {
-               return wfSetVar( $this->mWaitTimeout, $value );
-       }
-
-       /**
-        * @return bool Whether the generic connection for reads is highly "lagged"
-        */
-       public function getLaggedSlaveMode() {
-               # Get a generic reader connection
-               $this->getConnection( DB_SLAVE );
-
-               return $this->mLaggedSlaveMode;
-       }
-
-       /**
-        * Disables/enables lag checks
-        * @param null|bool $mode
-        * @return bool
-        */
-       public function allowLagged( $mode = null ) {
-               if ( $mode === null ) {
-                       return $this->mAllowLagged;
-               }
-               $this->mAllowLagged = $mode;
-
-               return $this->mAllowLagged;
-       }
-
-       /**
-        * @return bool
-        */
-       public function pingAll() {
-               $success = true;
-               foreach ( $this->mConns as $conns2 ) {
-                       foreach ( $conns2 as $conns3 ) {
-                               /** @var DatabaseBase[] $conns3 */
-                               foreach ( $conns3 as $conn ) {
-                                       if ( !$conn->ping() ) {
-                                               $success = false;
-                                       }
-                               }
-                       }
-               }
-
-               return $success;
-       }
-
-       /**
-        * Call a function with each open connection object
-        * @param callable $callback
-        * @param array $params
-        */
-       public function forEachOpenConnection( $callback, array $params = array() ) {
-               foreach ( $this->mConns as $conns2 ) {
-                       foreach ( $conns2 as $conns3 ) {
-                               foreach ( $conns3 as $conn ) {
-                                       $mergedParams = array_merge( array( $conn ), $params );
-                                       call_user_func_array( $callback, $mergedParams );
-                               }
-                       }
-               }
-       }
-
-       /**
-        * Get the hostname and lag time of the most-lagged slave
-        *
-        * This is useful for maintenance scripts that need to throttle their updates.
-        * May attempt to open connections to slaves on the default DB. If there is
-        * no lag, the maximum lag will be reported as -1.
-        *
-        * @param bool|string $wiki Wiki ID, or false for the default database
-        * @return array ( host, max lag, index of max lagged host )
-        */
-       public function getMaxLag( $wiki = false ) {
-               $maxLag = -1;
-               $host = '';
-               $maxIndex = 0;
-
-               if ( $this->getServerCount() <= 1 ) {
-                       return array( $host, $maxLag, $maxIndex ); // no replication = no lag
-               }
-
-               $lagTimes = $this->getLagTimes( $wiki );
-               foreach ( $lagTimes as $i => $lag ) {
-                       if ( $lag > $maxLag ) {
-                               $maxLag = $lag;
-                               $host = $this->mServers[$i]['host'];
-                               $maxIndex = $i;
-                       }
-               }
-
-               return array( $host, $maxLag, $maxIndex );
-       }
-
-       /**
-        * Get lag time for each server
-        *
-        * Results are cached for a short time in memcached/process cache
-        *
-        * @param string|bool $wiki
-        * @return int[] Map of (server index => seconds)
-        */
-       public function getLagTimes( $wiki = false ) {
-               if ( $this->getServerCount() <= 1 ) {
-                       return array( 0 => 0 ); // no replication = no lag
-               }
-
-               # Send the request to the load monitor
-               return $this->getLoadMonitor()->getLagTimes( array_keys( $this->mServers ), $wiki );
-       }
-
-       /**
-        * Get the lag in seconds for a given connection, or zero if this load
-        * balancer does not have replication enabled.
-        *
-        * This should be used in preference to Database::getLag() in cases where
-        * replication may not be in use, since there is no way to determine if
-        * replication is in use at the connection level without running
-        * potentially restricted queries such as SHOW SLAVE STATUS. Using this
-        * function instead of Database::getLag() avoids a fatal error in this
-        * case on many installations.
-        *
-        * @param DatabaseBase $conn
-        * @return int
-        */
-       public function safeGetLag( $conn ) {
-               if ( $this->getServerCount() == 1 ) {
-                       return 0;
-               } else {
-                       return $conn->getLag();
-               }
-       }
-
-       /**
-        * Clear the cache for slag lag delay times
-        *
-        * This is only used for testing
-        */
-       public function clearLagTimeCache() {
-               $this->getLoadMonitor()->clearCaches();
-       }
-}
diff --git a/includes/db/LoadMonitor.php b/includes/db/LoadMonitor.php
deleted file mode 100644 (file)
index 4975ea1..0000000
+++ /dev/null
@@ -1,66 +0,0 @@
-<?php
-/**
- * Database load monitoring.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- * http://www.gnu.org/copyleft/gpl.html
- *
- * @file
- * @ingroup Database
- */
-
-/**
- * An interface for database load monitoring
- *
- * @ingroup Database
- */
-interface LoadMonitor {
-       /**
-        * Construct a new LoadMonitor with a given LoadBalancer parent
-        *
-        * @param LoadBalancer $parent
-        */
-       public function __construct( $parent );
-
-       /**
-        * Perform pre-connection load ratio adjustment.
-        * @param array $loads
-        * @param string|bool $group The selected query group. Default: false
-        * @param string|bool $wiki Default: false
-        */
-       public function scaleLoads( &$loads, $group = false, $wiki = false );
-
-       /**
-        * Return an estimate of replication lag for each server
-        *
-        * @param array $serverIndexes
-        * @param string $wiki
-        *
-        * @return array Map of (server index => seconds)
-        */
-       public function getLagTimes( $serverIndexes, $wiki );
-}
-
-class LoadMonitorNull implements LoadMonitor {
-       public function __construct( $parent ) {
-       }
-
-       public function scaleLoads( &$loads, $group = false, $wiki = false ) {
-       }
-
-       public function getLagTimes( $serverIndexes, $wiki ) {
-               return array_fill_keys( $serverIndexes, 0 );
-       }
-}
diff --git a/includes/db/LoadMonitorMySQL.php b/includes/db/LoadMonitorMySQL.php
deleted file mode 100644 (file)
index 3008419..0000000
+++ /dev/null
@@ -1,124 +0,0 @@
-<?php
-/**
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- * http://www.gnu.org/copyleft/gpl.html
- *
- * @file
- * @ingroup Database
- */
-
-/**
- * Basic MySQL load monitor with no external dependencies
- * Uses memcached to cache the replication lag for a short time
- *
- * @ingroup Database
- */
-class LoadMonitorMySQL implements LoadMonitor {
-       /** @var LoadBalancer */
-       public $parent;
-       /** @var BagOStuff */
-       protected $srvCache;
-       /** @var BagOStuff */
-       protected $mainCache;
-
-       public function __construct( $parent ) {
-               $this->parent = $parent;
-
-               $this->srvCache = ObjectCache::newAccelerator( 'hash' );
-               $this->mainCache = wfGetMainCache();
-       }
-
-       public function scaleLoads( &$loads, $group = false, $wiki = false ) {
-       }
-
-       public function getLagTimes( $serverIndexes, $wiki ) {
-               if ( count( $serverIndexes ) == 1 && reset( $serverIndexes ) == 0 ) {
-                       # Single server only, just return zero without caching
-                       return array( 0 => 0 );
-               }
-
-               $key = $this->getLagTimeCacheKey();
-               # Randomize TTLs to reduce stampedes (4.0 - 5.0 sec)
-               $ttl = mt_rand( 4e6, 5e6 ) / 1e6;
-               # Keep keys around longer as fallbacks
-               $staleTTL = 60;
-
-               # (a) Check the local APC cache
-               $value = $this->srvCache->get( $key );
-               if ( $value && $value['timestamp'] > ( microtime( true ) - $ttl ) ) {
-                       wfDebugLog( 'replication',  __FUNCTION__ . ": got lag times ($key) from local cache" );
-                       return $value['lagTimes']; // cache hit
-               }
-               $staleValue = $value ?: false;
-
-               # (b) Check the shared cache and backfill APC
-               $value = $this->mainCache->get( $key );
-               if ( $value && $value['timestamp'] > ( microtime( true ) - $ttl ) ) {
-                       $this->srvCache->set( $key, $value, $staleTTL );
-                       wfDebugLog( 'replication',  __FUNCTION__ . ": got lag times ($key) from main cache" );
-
-                       return $value['lagTimes']; // cache hit
-               }
-               $staleValue = $value ?: $staleValue;
-
-               # (c) Cache key missing or expired; regenerate and backfill
-               if ( $this->mainCache->lock( $key, 0, 10 ) ) {
-                       # Let this process alone update the cache value
-                       $cache = $this->mainCache;
-                       /** @noinspection PhpUnusedLocalVariableInspection */
-                       $unlocker = new ScopedCallback( function () use ( $cache, $key ) {
-                               $cache->unlock( $key );
-                       } );
-               } elseif ( $staleValue ) {
-                       # Could not acquire lock but an old cache exists, so use it
-                       return $staleValue['lagTimes'];
-               }
-
-               $lagTimes = array();
-               foreach ( $serverIndexes as $i ) {
-                       if ( $i == 0 ) { # Master
-                               $lagTimes[$i] = 0;
-                       } elseif ( false !== ( $conn = $this->parent->getAnyOpenConnection( $i ) ) ) {
-                               $lagTimes[$i] = $conn->getLag();
-                       } elseif ( false !== ( $conn = $this->parent->openConnection( $i, $wiki ) ) ) {
-                               $lagTimes[$i] = $conn->getLag();
-                               # Close the connection to avoid sleeper connections piling up.
-                               # Note that the caller will pick one of these DBs and reconnect,
-                               # which is slightly inefficient, but this only matters for the lag
-                               # time cache miss cache, which is far less common that cache hits.
-                               $this->parent->closeConnection( $conn );
-                       }
-               }
-
-               # Add a timestamp key so we know when it was cached
-               $value = array( 'lagTimes' => $lagTimes, 'timestamp' => microtime( true ) );
-               $this->mainCache->set( $key, $value, $staleTTL );
-               $this->srvCache->set( $key, $value, $staleTTL );
-               wfDebugLog( 'replication',  __FUNCTION__ . ": re-calculated lag times ($key)" );
-
-               return $value['lagTimes'];
-       }
-
-       public function clearCaches() {
-               $key = $this->getLagTimeCacheKey();
-               $this->srvCache->delete( $key );
-               $this->mainCache->delete( $key );
-       }
-
-       private function getLagTimeCacheKey() {
-               # Lag is per-server, not per-DB, so key on the master DB name
-               return wfGlobalCacheKey( 'lag-times', $this->parent->getServerName( 0 ) );
-       }
-}
diff --git a/includes/db/loadbalancer/LBFactory.php b/includes/db/loadbalancer/LBFactory.php
new file mode 100644 (file)
index 0000000..da0fe44
--- /dev/null
@@ -0,0 +1,226 @@
+<?php
+/**
+ * Generator of database load balancing objects.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ * @ingroup Database
+ */
+
+/**
+ * An interface for generating database load balancers
+ * @ingroup Database
+ */
+abstract class LBFactory {
+       /** @var LBFactory */
+       private static $instance;
+
+       /**
+        * Disables all access to the load balancer, will cause all database access
+        * to throw a DBAccessError
+        */
+       public static function disableBackend() {
+               global $wgLBFactoryConf;
+               self::$instance = new LBFactoryFake( $wgLBFactoryConf );
+       }
+
+       /**
+        * Get an LBFactory instance
+        *
+        * @return LBFactory
+        */
+       public static function singleton() {
+               global $wgLBFactoryConf;
+
+               if ( is_null( self::$instance ) ) {
+                       $class = self::getLBFactoryClass( $wgLBFactoryConf );
+
+                       self::$instance = new $class( $wgLBFactoryConf );
+               }
+
+               return self::$instance;
+       }
+
+       /**
+        * Returns the LBFactory class to use and the load balancer configuration.
+        *
+        * @param array $config (e.g. $wgLBFactoryConf)
+        * @return string Class name
+        */
+       public static function getLBFactoryClass( array $config ) {
+               // For configuration backward compatibility after removing
+               // underscores from class names in MediaWiki 1.23.
+               $bcClasses = array(
+                       'LBFactory_Simple' => 'LBFactorySimple',
+                       'LBFactory_Single' => 'LBFactorySingle',
+                       'LBFactory_Multi' => 'LBFactoryMulti',
+                       'LBFactory_Fake' => 'LBFactoryFake',
+               );
+
+               $class = $config['class'];
+
+               if ( isset( $bcClasses[$class] ) ) {
+                       $class = $bcClasses[$class];
+                       wfDeprecated(
+                               '$wgLBFactoryConf must be updated. See RELEASE-NOTES for details',
+                               '1.23'
+                       );
+               }
+
+               return $class;
+       }
+
+       /**
+        * Shut down, close connections and destroy the cached instance.
+        */
+       public static function destroyInstance() {
+               if ( self::$instance ) {
+                       self::$instance->shutdown();
+                       self::$instance->forEachLBCallMethod( 'closeAll' );
+                       self::$instance = null;
+               }
+       }
+
+       /**
+        * Set the instance to be the given object
+        *
+        * @param LBFactory $instance
+        */
+       public static function setInstance( $instance ) {
+               self::destroyInstance();
+               self::$instance = $instance;
+       }
+
+       /**
+        * Construct a factory based on a configuration array (typically from $wgLBFactoryConf)
+        * @param array $conf
+        */
+       abstract public function __construct( array $conf );
+
+       /**
+        * Create a new load balancer object. The resulting object will be untracked,
+        * not chronology-protected, and the caller is responsible for cleaning it up.
+        *
+        * @param bool|string $wiki Wiki ID, or false for the current wiki
+        * @return LoadBalancer
+        */
+       abstract public function newMainLB( $wiki = false );
+
+       /**
+        * Get a cached (tracked) load balancer object.
+        *
+        * @param bool|string $wiki Wiki ID, or false for the current wiki
+        * @return LoadBalancer
+        */
+       abstract public function getMainLB( $wiki = false );
+
+       /**
+        * Create a new load balancer for external storage. The resulting object will be
+        * untracked, not chronology-protected, and the caller is responsible for
+        * cleaning it up.
+        *
+        * @param string $cluster External storage cluster, or false for core
+        * @param bool|string $wiki Wiki ID, or false for the current wiki
+        * @return LoadBalancer
+        */
+       abstract protected function newExternalLB( $cluster, $wiki = false );
+
+       /**
+        * Get a cached (tracked) load balancer for external storage
+        *
+        * @param string $cluster External storage cluster, or false for core
+        * @param bool|string $wiki Wiki ID, or false for the current wiki
+        * @return LoadBalancer
+        */
+       abstract public function &getExternalLB( $cluster, $wiki = false );
+
+       /**
+        * Execute a function for each tracked load balancer
+        * The callback is called with the load balancer as the first parameter,
+        * and $params passed as the subsequent parameters.
+        *
+        * @param callable $callback
+        * @param array $params
+        */
+       abstract public function forEachLB( $callback, array $params = array() );
+
+       /**
+        * Prepare all tracked load balancers for shutdown
+        * STUB
+        */
+       public function shutdown() {
+       }
+
+       /**
+        * Call a method of each tracked load balancer
+        *
+        * @param string $methodName
+        * @param array $args
+        */
+       private function forEachLBCallMethod( $methodName, array $args = array() ) {
+               $this->forEachLB( function ( LoadBalancer $loadBalancer, $methodName, array $args ) {
+                       call_user_func_array( array( $loadBalancer, $methodName ), $args );
+               }, array( $methodName, $args ) );
+       }
+
+       /**
+        * Commit on all connections. Done for two reasons:
+        * 1. To commit changes to the masters.
+        * 2. To release the snapshot on all connections, master and slave.
+        */
+       public function commitAll() {
+               $this->forEachLBCallMethod( 'commitAll' );
+       }
+
+       /**
+        * Commit changes on all master connections
+        */
+       public function commitMasterChanges() {
+               $this->forEachLBCallMethod( 'commitMasterChanges' );
+       }
+
+       /**
+        * Rollback changes on all master connections
+        * @since 1.23
+        */
+       public function rollbackMasterChanges() {
+               $this->forEachLBCallMethod( 'rollbackMasterChanges' );
+       }
+
+       /**
+        * Detemine if any master connection has pending changes.
+        * @since 1.23
+        * @return bool
+        */
+       public function hasMasterChanges() {
+               $ret = false;
+               $this->forEachLB( function ( LoadBalancer $lb ) use ( &$ret ) {
+                       $ret = $ret || $lb->hasMasterChanges();
+               } );
+               return $ret;
+       }
+}
+
+/**
+ * Exception class for attempted DB access
+ */
+class DBAccessError extends MWException {
+       public function __construct() {
+               parent::__construct( "Mediawiki tried to access the database via wfGetDB(). " .
+                       "This is not allowed." );
+       }
+}
diff --git a/includes/db/loadbalancer/LBFactoryFake.php b/includes/db/loadbalancer/LBFactoryFake.php
new file mode 100644 (file)
index 0000000..d8becf5
--- /dev/null
@@ -0,0 +1,52 @@
+<?php
+/**
+ * Generator of database load balancing objects.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ * @ingroup Database
+ */
+
+/**
+ * LBFactory class that throws an error on any attempt to use it.
+ * This will typically be done via wfGetDB().
+ * Call LBFactory::disableBackend() to start using this, and
+ * LBFactory::enableBackend() to return to normal behavior
+ */
+class LBFactoryFake extends LBFactory {
+       public function __construct( array $conf ) {
+       }
+
+       public function newMainLB( $wiki = false ) {
+               throw new DBAccessError;
+       }
+
+       public function getMainLB( $wiki = false ) {
+               throw new DBAccessError;
+       }
+
+       protected function newExternalLB( $cluster, $wiki = false ) {
+               throw new DBAccessError;
+       }
+
+       public function &getExternalLB( $cluster, $wiki = false ) {
+               throw new DBAccessError;
+       }
+
+       public function forEachLB( $callback, array $params = array() ) {
+       }
+}
diff --git a/includes/db/loadbalancer/LBFactoryMulti.php b/includes/db/loadbalancer/LBFactoryMulti.php
new file mode 100644 (file)
index 0000000..92fbccd
--- /dev/null
@@ -0,0 +1,399 @@
+<?php
+/**
+ * Advanced generator of database load balancing objects for wiki farms.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ * @ingroup Database
+ */
+
+/**
+ * A multi-wiki, multi-master factory for Wikimedia and similar installations.
+ * Ignores the old configuration globals
+ *
+ * Configuration:
+ *     sectionsByDB                A map of database names to section names.
+ *
+ *     sectionLoads                A 2-d map. For each section, gives a map of server names to
+ *                                 load ratios. For example:
+ *                                 array(
+ *                                     'section1' => array(
+ *                                         'db1' => 100,
+ *                                         'db2' => 100
+ *                                     )
+ *                                 )
+ *
+ *     serverTemplate              A server info associative array as documented for $wgDBservers.
+ *                                 The host, hostName and load entries will be overridden.
+ *
+ *     groupLoadsBySection         A 3-d map giving server load ratios for each section and group.
+ *                                 For example:
+ *                                 array(
+ *                                     'section1' => array(
+ *                                         'group1' => array(
+ *                                             'db1' => 100,
+ *                                             'db2' => 100
+ *                                         )
+ *                                     )
+ *                                 )
+ *
+ *     groupLoadsByDB              A 3-d map giving server load ratios by DB name.
+ *
+ *     hostsByName                 A map of hostname to IP address.
+ *
+ *     externalLoads               A map of external storage cluster name to server load map.
+ *
+ *     externalTemplateOverrides   A set of server info keys overriding serverTemplate for external
+ *                                 storage.
+ *
+ *     templateOverridesByServer   A 2-d map overriding serverTemplate and
+ *                                 externalTemplateOverrides on a server-by-server basis. Applies
+ *                                 to both core and external storage.
+ *
+ *     templateOverridesByCluster  A 2-d map overriding the server info by external storage cluster.
+ *
+ *     masterTemplateOverrides     An override array for all master servers.
+ *
+ *     readOnlyBySection           A map of section name to read-only message.
+ *                                 Missing or false for read/write.
+ *
+ * @ingroup Database
+ */
+class LBFactoryMulti extends LBFactory {
+       // Required settings
+
+       /** @var array A map of database names to section names */
+       private $sectionsByDB;
+
+       /**
+        * @var array A 2-d map. For each section, gives a map of server names to
+        * load ratios
+        */
+       private $sectionLoads;
+
+       /**
+        * @var array A server info associative array as documented for
+        * $wgDBservers. The host, hostName and load entries will be
+        * overridden
+        */
+       private $serverTemplate;
+
+       // Optional settings
+
+       /** @var array A 3-d map giving server load ratios for each section and group */
+       private $groupLoadsBySection = array();
+
+       /** @var array A 3-d map giving server load ratios by DB name */
+       private $groupLoadsByDB = array();
+
+       /** @var array A map of hostname to IP address */
+       private $hostsByName = array();
+
+       /** @var array A map of external storage cluster name to server load map */
+       private $externalLoads = array();
+
+       /**
+        * @var array A set of server info keys overriding serverTemplate for
+        * external storage
+        */
+       private $externalTemplateOverrides;
+
+       /**
+        * @var array A 2-d map overriding serverTemplate and
+        * externalTemplateOverrides on a server-by-server basis. Applies to both
+        * core and external storage
+        */
+       private $templateOverridesByServer;
+
+       /** @var array A 2-d map overriding the server info by external storage cluster */
+       private $templateOverridesByCluster;
+
+       /** @var array An override array for all master servers */
+       private $masterTemplateOverrides;
+
+       /**
+        * @var array|bool A map of section name to read-only message. Missing or
+        * false for read/write
+        */
+       private $readOnlyBySection = array();
+
+       // Other stuff
+
+       /** @var array Load balancer factory configuration */
+       private $conf;
+
+       /** @var LoadBalancer[] */
+       private $mainLBs = array();
+
+       /** @var LoadBalancer[] */
+       private $extLBs = array();
+
+       /** @var string */
+       private $lastWiki;
+
+       /** @var string */
+       private $lastSection;
+
+       /**
+        * @param array $conf
+        * @throws MWException
+        */
+       public function __construct( array $conf ) {
+               $this->chronProt = new ChronologyProtector;
+               $this->conf = $conf;
+               $required = array( 'sectionsByDB', 'sectionLoads', 'serverTemplate' );
+               $optional = array( 'groupLoadsBySection', 'groupLoadsByDB', 'hostsByName',
+                       'externalLoads', 'externalTemplateOverrides', 'templateOverridesByServer',
+                       'templateOverridesByCluster', 'masterTemplateOverrides',
+                       'readOnlyBySection' );
+
+               foreach ( $required as $key ) {
+                       if ( !isset( $conf[$key] ) ) {
+                               throw new MWException( __CLASS__ . ": $key is required in configuration" );
+                       }
+                       $this->$key = $conf[$key];
+               }
+
+               foreach ( $optional as $key ) {
+                       if ( isset( $conf[$key] ) ) {
+                               $this->$key = $conf[$key];
+                       }
+               }
+
+               // Check for read-only mode
+               $section = $this->getSectionForWiki();
+               if ( !empty( $this->readOnlyBySection[$section] ) ) {
+                       global $wgReadOnly;
+                       $wgReadOnly = $this->readOnlyBySection[$section];
+               }
+       }
+
+       /**
+        * @param bool|string $wiki
+        * @return string
+        */
+       private function getSectionForWiki( $wiki = false ) {
+               if ( $this->lastWiki === $wiki ) {
+                       return $this->lastSection;
+               }
+               list( $dbName, ) = $this->getDBNameAndPrefix( $wiki );
+               if ( isset( $this->sectionsByDB[$dbName] ) ) {
+                       $section = $this->sectionsByDB[$dbName];
+               } else {
+                       $section = 'DEFAULT';
+               }
+               $this->lastSection = $section;
+               $this->lastWiki = $wiki;
+
+               return $section;
+       }
+
+       /**
+        * @param bool|string $wiki
+        * @return LoadBalancer
+        */
+       public function newMainLB( $wiki = false ) {
+               list( $dbName, ) = $this->getDBNameAndPrefix( $wiki );
+               $section = $this->getSectionForWiki( $wiki );
+               $groupLoads = array();
+               if ( isset( $this->groupLoadsByDB[$dbName] ) ) {
+                       $groupLoads = $this->groupLoadsByDB[$dbName];
+               }
+
+               if ( isset( $this->groupLoadsBySection[$section] ) ) {
+                       $groupLoads = array_merge_recursive( $groupLoads, $this->groupLoadsBySection[$section] );
+               }
+
+               return $this->newLoadBalancer(
+                       $this->serverTemplate,
+                       $this->sectionLoads[$section],
+                       $groupLoads
+               );
+       }
+
+       /**
+        * @param bool|string $wiki
+        * @return LoadBalancer
+        */
+       public function getMainLB( $wiki = false ) {
+               $section = $this->getSectionForWiki( $wiki );
+               if ( !isset( $this->mainLBs[$section] ) ) {
+                       $lb = $this->newMainLB( $wiki );
+                       $lb->parentInfo( array( 'id' => "main-$section" ) );
+                       $this->chronProt->initLB( $lb );
+                       $this->mainLBs[$section] = $lb;
+               }
+
+               return $this->mainLBs[$section];
+       }
+
+       /**
+        * @param string $cluster
+        * @param bool|string $wiki
+        * @throws MWException
+        * @return LoadBalancer
+        */
+       protected function newExternalLB( $cluster, $wiki = false ) {
+               if ( !isset( $this->externalLoads[$cluster] ) ) {
+                       throw new MWException( __METHOD__ . ": Unknown cluster \"$cluster\"" );
+               }
+               $template = $this->serverTemplate;
+               if ( isset( $this->externalTemplateOverrides ) ) {
+                       $template = $this->externalTemplateOverrides + $template;
+               }
+               if ( isset( $this->templateOverridesByCluster[$cluster] ) ) {
+                       $template = $this->templateOverridesByCluster[$cluster] + $template;
+               }
+
+               return $this->newLoadBalancer( $template, $this->externalLoads[$cluster], array() );
+       }
+
+       /**
+        * @param string $cluster External storage cluster, or false for core
+        * @param bool|string $wiki Wiki ID, or false for the current wiki
+        * @return LoadBalancer
+        */
+       public function &getExternalLB( $cluster, $wiki = false ) {
+               if ( !isset( $this->extLBs[$cluster] ) ) {
+                       $this->extLBs[$cluster] = $this->newExternalLB( $cluster, $wiki );
+                       $this->extLBs[$cluster]->parentInfo( array( 'id' => "ext-$cluster" ) );
+                       $this->chronProt->initLB( $this->extLBs[$cluster] );
+               }
+
+               return $this->extLBs[$cluster];
+       }
+
+       /**
+        * Make a new load balancer object based on template and load array
+        *
+        * @param array $template
+        * @param array $loads
+        * @param array $groupLoads
+        * @return LoadBalancer
+        */
+       private function newLoadBalancer( $template, $loads, $groupLoads ) {
+               $servers = $this->makeServerArray( $template, $loads, $groupLoads );
+               $lb = new LoadBalancer( array(
+                       'servers' => $servers,
+               ) );
+
+               return $lb;
+       }
+
+       /**
+        * Make a server array as expected by LoadBalancer::__construct, using a template and load array
+        *
+        * @param array $template
+        * @param array $loads
+        * @param array $groupLoads
+        * @return array
+        */
+       private function makeServerArray( $template, $loads, $groupLoads ) {
+               $servers = array();
+               $master = true;
+               $groupLoadsByServer = $this->reindexGroupLoads( $groupLoads );
+               foreach ( $groupLoadsByServer as $server => $stuff ) {
+                       if ( !isset( $loads[$server] ) ) {
+                               $loads[$server] = 0;
+                       }
+               }
+               foreach ( $loads as $serverName => $load ) {
+                       $serverInfo = $template;
+                       if ( $master ) {
+                               $serverInfo['master'] = true;
+                               if ( isset( $this->masterTemplateOverrides ) ) {
+                                       $serverInfo = $this->masterTemplateOverrides + $serverInfo;
+                               }
+                               $master = false;
+                       }
+                       if ( isset( $this->templateOverridesByServer[$serverName] ) ) {
+                               $serverInfo = $this->templateOverridesByServer[$serverName] + $serverInfo;
+                       }
+                       if ( isset( $groupLoadsByServer[$serverName] ) ) {
+                               $serverInfo['groupLoads'] = $groupLoadsByServer[$serverName];
+                       }
+                       if ( isset( $this->hostsByName[$serverName] ) ) {
+                               $serverInfo['host'] = $this->hostsByName[$serverName];
+                       } else {
+                               $serverInfo['host'] = $serverName;
+                       }
+                       $serverInfo['hostName'] = $serverName;
+                       $serverInfo['load'] = $load;
+                       $servers[] = $serverInfo;
+               }
+
+               return $servers;
+       }
+
+       /**
+        * Take a group load array indexed by group then server, and reindex it by server then group
+        * @param array $groupLoads
+        * @return array
+        */
+       private function reindexGroupLoads( $groupLoads ) {
+               $reindexed = array();
+               foreach ( $groupLoads as $group => $loads ) {
+                       foreach ( $loads as $server => $load ) {
+                               $reindexed[$server][$group] = $load;
+                       }
+               }
+
+               return $reindexed;
+       }
+
+       /**
+        * Get the database name and prefix based on the wiki ID
+        * @param bool|string $wiki
+        * @return array
+        */
+       private function getDBNameAndPrefix( $wiki = false ) {
+               if ( $wiki === false ) {
+                       global $wgDBname, $wgDBprefix;
+
+                       return array( $wgDBname, $wgDBprefix );
+               } else {
+                       return wfSplitWikiID( $wiki );
+               }
+       }
+
+       /**
+        * Execute a function for each tracked load balancer
+        * The callback is called with the load balancer as the first parameter,
+        * and $params passed as the subsequent parameters.
+        * @param callable $callback
+        * @param array $params
+        */
+       public function forEachLB( $callback, array $params = array() ) {
+               foreach ( $this->mainLBs as $lb ) {
+                       call_user_func_array( $callback, array_merge( array( $lb ), $params ) );
+               }
+               foreach ( $this->extLBs as $lb ) {
+                       call_user_func_array( $callback, array_merge( array( $lb ), $params ) );
+               }
+       }
+
+       public function shutdown() {
+               foreach ( $this->mainLBs as $lb ) {
+                       $this->chronProt->shutdownLB( $lb );
+               }
+               foreach ( $this->extLBs as $extLB ) {
+                       $this->chronProt->shutdownLB( $extLB );
+               }
+               $this->chronProt->shutdown();
+               $this->commitMasterChanges();
+       }
+}
diff --git a/includes/db/loadbalancer/LBFactorySimple.php b/includes/db/loadbalancer/LBFactorySimple.php
new file mode 100644 (file)
index 0000000..23cdbc6
--- /dev/null
@@ -0,0 +1,153 @@
+<?php
+/**
+ * Generator of database load balancing objects.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ * @ingroup Database
+ */
+
+/**
+ * A simple single-master LBFactory that gets its configuration from the b/c globals
+ */
+class LBFactorySimple extends LBFactory {
+       /** @var LoadBalancer */
+       private $mainLB;
+
+       /** @var LoadBalancer[] */
+       private $extLBs = array();
+
+       /** @var ChronologyProtector */
+       private $chronProt;
+
+       public function __construct( array $conf ) {
+               $this->chronProt = new ChronologyProtector;
+       }
+
+       /**
+        * @param bool|string $wiki
+        * @return LoadBalancer
+        */
+       public function newMainLB( $wiki = false ) {
+               global $wgDBservers;
+               if ( $wgDBservers ) {
+                       $servers = $wgDBservers;
+               } else {
+                       global $wgDBserver, $wgDBuser, $wgDBpassword, $wgDBname, $wgDBtype, $wgDebugDumpSql;
+                       global $wgDBssl, $wgDBcompress;
+
+                       $flags = DBO_DEFAULT;
+                       if ( $wgDebugDumpSql ) {
+                               $flags |= DBO_DEBUG;
+                       }
+                       if ( $wgDBssl ) {
+                               $flags |= DBO_SSL;
+                       }
+                       if ( $wgDBcompress ) {
+                               $flags |= DBO_COMPRESS;
+                       }
+
+                       $servers = array( array(
+                               'host' => $wgDBserver,
+                               'user' => $wgDBuser,
+                               'password' => $wgDBpassword,
+                               'dbname' => $wgDBname,
+                               'type' => $wgDBtype,
+                               'load' => 1,
+                               'flags' => $flags
+                       ) );
+               }
+
+               return new LoadBalancer( array(
+                       'servers' => $servers,
+               ) );
+       }
+
+       /**
+        * @param bool|string $wiki
+        * @return LoadBalancer
+        */
+       public function getMainLB( $wiki = false ) {
+               if ( !isset( $this->mainLB ) ) {
+                       $this->mainLB = $this->newMainLB( $wiki );
+                       $this->mainLB->parentInfo( array( 'id' => 'main' ) );
+                       $this->chronProt->initLB( $this->mainLB );
+               }
+
+               return $this->mainLB;
+       }
+
+       /**
+        * @throws MWException
+        * @param string $cluster
+        * @param bool|string $wiki
+        * @return LoadBalancer
+        */
+       protected function newExternalLB( $cluster, $wiki = false ) {
+               global $wgExternalServers;
+               if ( !isset( $wgExternalServers[$cluster] ) ) {
+                       throw new MWException( __METHOD__ . ": Unknown cluster \"$cluster\"" );
+               }
+
+               return new LoadBalancer( array(
+                       'servers' => $wgExternalServers[$cluster]
+               ) );
+       }
+
+       /**
+        * @param string $cluster
+        * @param bool|string $wiki
+        * @return array
+        */
+       public function &getExternalLB( $cluster, $wiki = false ) {
+               if ( !isset( $this->extLBs[$cluster] ) ) {
+                       $this->extLBs[$cluster] = $this->newExternalLB( $cluster, $wiki );
+                       $this->extLBs[$cluster]->parentInfo( array( 'id' => "ext-$cluster" ) );
+                       $this->chronProt->initLB( $this->extLBs[$cluster] );
+               }
+
+               return $this->extLBs[$cluster];
+       }
+
+       /**
+        * Execute a function for each tracked load balancer
+        * The callback is called with the load balancer as the first parameter,
+        * and $params passed as the subsequent parameters.
+        *
+        * @param callable $callback
+        * @param array $params
+        */
+       public function forEachLB( $callback, array $params = array() ) {
+               if ( isset( $this->mainLB ) ) {
+                       call_user_func_array( $callback, array_merge( array( $this->mainLB ), $params ) );
+               }
+               foreach ( $this->extLBs as $lb ) {
+                       call_user_func_array( $callback, array_merge( array( $lb ), $params ) );
+               }
+       }
+
+       public function shutdown() {
+               if ( $this->mainLB ) {
+                       $this->chronProt->shutdownLB( $this->mainLB );
+               }
+               foreach ( $this->extLBs as $extLB ) {
+                       $this->chronProt->shutdownLB( $extLB );
+               }
+               $this->chronProt->shutdown();
+               $this->commitMasterChanges();
+       }
+}
diff --git a/includes/db/loadbalancer/LBFactorySingle.php b/includes/db/loadbalancer/LBFactorySingle.php
new file mode 100644 (file)
index 0000000..a41dadf
--- /dev/null
@@ -0,0 +1,112 @@
+<?php
+/**
+ * Simple generator of database connections that always returns the same object.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ * @ingroup Database
+ */
+
+/**
+ * An LBFactory class that always returns a single database object.
+ */
+class LBFactorySingle extends LBFactory {
+       /** @var LoadBalancerSingle */
+       private $lb;
+
+       /**
+        * @param array $conf An associative array with one member:
+        *  - connection: The DatabaseBase connection object
+        */
+       public function __construct( array $conf ) {
+               $this->lb = new LoadBalancerSingle( $conf );
+       }
+
+       /**
+        * @param bool|string $wiki
+        * @return LoadBalancerSingle
+        */
+       public function newMainLB( $wiki = false ) {
+               return $this->lb;
+       }
+
+       /**
+        * @param bool|string $wiki
+        * @return LoadBalancerSingle
+        */
+       public function getMainLB( $wiki = false ) {
+               return $this->lb;
+       }
+
+       /**
+        * @param string $cluster External storage cluster, or false for core
+        * @param bool|string $wiki Wiki ID, or false for the current wiki
+        * @return LoadBalancerSingle
+        */
+       protected function newExternalLB( $cluster, $wiki = false ) {
+               return $this->lb;
+       }
+
+       /**
+        * @param string $cluster External storage cluster, or false for core
+        * @param bool|string $wiki Wiki ID, or false for the current wiki
+        * @return LoadBalancerSingle
+        */
+       public function &getExternalLB( $cluster, $wiki = false ) {
+               return $this->lb;
+       }
+
+       /**
+        * @param string|callable $callback
+        * @param array $params
+        */
+       public function forEachLB( $callback, array $params = array() ) {
+               call_user_func_array( $callback, array_merge( array( $this->lb ), $params ) );
+       }
+}
+
+/**
+ * Helper class for LBFactorySingle.
+ */
+class LoadBalancerSingle extends LoadBalancer {
+       /** @var DatabaseBase */
+       private $db;
+
+       /**
+        * @param array $params
+        */
+       public function __construct( array $params ) {
+               $this->db = $params['connection'];
+               parent::__construct( array( 'servers' => array( array(
+                       'type' => $this->db->getType(),
+                       'host' => $this->db->getServer(),
+                       'dbname' => $this->db->getDBname(),
+                       'load' => 1,
+               ) ) ) );
+       }
+
+       /**
+        *
+        * @param string $server
+        * @param bool $dbNameOverride
+        *
+        * @return DatabaseBase
+        */
+       protected function reallyOpenConnection( $server, $dbNameOverride = false ) {
+               return $this->db;
+       }
+}
diff --git a/includes/db/loadbalancer/LoadBalancer.php b/includes/db/loadbalancer/LoadBalancer.php
new file mode 100644 (file)
index 0000000..52dca08
--- /dev/null
@@ -0,0 +1,1273 @@
+<?php
+/**
+ * Database load balancing.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ * @ingroup Database
+ */
+
+/**
+ * Database load balancing object
+ *
+ * @todo document
+ * @ingroup Database
+ */
+class LoadBalancer {
+       /** @var array[] Map of (server index => server config array) */
+       private $mServers;
+       /** @var array[] Map of (local/foreignUsed/foreignFree => server index => DatabaseBase array) */
+       private $mConns;
+       /** @var array Map of (server index => weight) */
+       private $mLoads;
+       /** @var array[] Map of (group => server index => weight) */
+       private $mGroupLoads;
+       /** @var bool Whether to disregard slave lag as a factor in slave selection */
+       private $mAllowLagged;
+       /** @var integer Seconds to spend waiting on slave lag to resolve */
+       private $mWaitTimeout;
+
+       /** @var array LBFactory information */
+       private $mParentInfo;
+       /** @var string The LoadMonitor subclass name */
+       private $mLoadMonitorClass;
+       /** @var LoadMonitor */
+       private $mLoadMonitor;
+
+       /** @var bool|DatabaseBase Database connection that caused a problem */
+       private $mErrorConnection;
+       /** @var integer The generic (not query grouped) slave index (of $mServers) */
+       private $mReadIndex;
+       /** @var bool|DBMasterPos False if not set */
+       private $mWaitForPos;
+       /** @var bool Whether the generic reader fell back to a lagged slave */
+       private $mLaggedSlaveMode;
+       /** @var string The last DB selection or connection error */
+       private $mLastError = 'Unknown error';
+       /** @var integer Total connections opened */
+       private $connsOpened = 0;
+
+       /** @var integer Warn when this many connection are held */
+       const CONN_HELD_WARN_THRESHOLD = 10;
+
+       /**
+        * @param array $params Array with keys:
+        *   servers           Required. Array of server info structures.
+        *   loadMonitor       Name of a class used to fetch server lag and load.
+        * @throws MWException
+        */
+       public function __construct( array $params ) {
+               if ( !isset( $params['servers'] ) ) {
+                       throw new MWException( __CLASS__ . ': missing servers parameter' );
+               }
+               $this->mServers = $params['servers'];
+               $this->mWaitTimeout = 10;
+
+               $this->mReadIndex = -1;
+               $this->mWriteIndex = -1;
+               $this->mConns = array(
+                       'local' => array(),
+                       'foreignUsed' => array(),
+                       'foreignFree' => array() );
+               $this->mLoads = array();
+               $this->mWaitForPos = false;
+               $this->mLaggedSlaveMode = false;
+               $this->mErrorConnection = false;
+               $this->mAllowLagged = false;
+
+               if ( isset( $params['loadMonitor'] ) ) {
+                       $this->mLoadMonitorClass = $params['loadMonitor'];
+               } else {
+                       $master = reset( $params['servers'] );
+                       if ( isset( $master['type'] ) && $master['type'] === 'mysql' ) {
+                               $this->mLoadMonitorClass = 'LoadMonitorMySQL';
+                       } else {
+                               $this->mLoadMonitorClass = 'LoadMonitorNull';
+                       }
+               }
+
+               foreach ( $params['servers'] as $i => $server ) {
+                       $this->mLoads[$i] = $server['load'];
+                       if ( isset( $server['groupLoads'] ) ) {
+                               foreach ( $server['groupLoads'] as $group => $ratio ) {
+                                       if ( !isset( $this->mGroupLoads[$group] ) ) {
+                                               $this->mGroupLoads[$group] = array();
+                                       }
+                                       $this->mGroupLoads[$group][$i] = $ratio;
+                               }
+                       }
+               }
+       }
+
+       /**
+        * Get a LoadMonitor instance
+        *
+        * @return LoadMonitor
+        */
+       private function getLoadMonitor() {
+               if ( !isset( $this->mLoadMonitor ) ) {
+                       $class = $this->mLoadMonitorClass;
+                       $this->mLoadMonitor = new $class( $this );
+               }
+
+               return $this->mLoadMonitor;
+       }
+
+       /**
+        * Get or set arbitrary data used by the parent object, usually an LBFactory
+        * @param mixed $x
+        * @return mixed
+        */
+       public function parentInfo( $x = null ) {
+               return wfSetVar( $this->mParentInfo, $x );
+       }
+
+       /**
+        * Given an array of non-normalised probabilities, this function will select
+        * an element and return the appropriate key
+        *
+        * @deprecated since 1.21, use ArrayUtils::pickRandom()
+        *
+        * @param array $weights
+        * @return bool|int|string
+        */
+       public function pickRandom( array $weights ) {
+               return ArrayUtils::pickRandom( $weights );
+       }
+
+       /**
+        * @param array $loads
+        * @param bool|string $wiki Wiki to get non-lagged for
+        * @param float $maxLag Restrict the maximum allowed lag to this many seconds
+        * @return bool|int|string
+        */
+       private function getRandomNonLagged( array $loads, $wiki = false, $maxLag = INF ) {
+               $lags = $this->getLagTimes( $wiki );
+
+               # Unset excessively lagged servers
+               foreach ( $lags as $i => $lag ) {
+                       if ( $i != 0 ) {
+                               $maxServerLag = $maxLag;
+                               if ( isset( $this->mServers[$i]['max lag'] ) ) {
+                                       $maxServerLag = min( $maxServerLag, $this->mServers[$i]['max lag'] );
+                               }
+                               if ( $lag === false ) {
+                                       wfDebugLog( 'replication', "Server #$i is not replicating" );
+                                       unset( $loads[$i] );
+                               } elseif ( $lag > $maxServerLag ) {
+                                       wfDebugLog( 'replication', "Server #$i is excessively lagged ($lag seconds)" );
+                                       unset( $loads[$i] );
+                               }
+                       }
+               }
+
+               # Find out if all the slaves with non-zero load are lagged
+               $sum = 0;
+               foreach ( $loads as $load ) {
+                       $sum += $load;
+               }
+               if ( $sum == 0 ) {
+                       # No appropriate DB servers except maybe the master and some slaves with zero load
+                       # Do NOT use the master
+                       # Instead, this function will return false, triggering read-only mode,
+                       # and a lagged slave will be used instead.
+                       return false;
+               }
+
+               if ( count( $loads ) == 0 ) {
+                       return false;
+               }
+
+               #wfDebugLog( 'connect', var_export( $loads, true ) );
+
+               # Return a random representative of the remainder
+               return ArrayUtils::pickRandom( $loads );
+       }
+
+       /**
+        * Get the index of the reader connection, which may be a slave
+        * This takes into account load ratios and lag times. It should
+        * always return a consistent index during a given invocation
+        *
+        * Side effect: opens connections to databases
+        * @param string|bool $group Query group, or false for the generic reader
+        * @param string|bool $wiki Wiki ID, or false for the current wiki
+        * @throws MWException
+        * @return bool|int|string
+        */
+       public function getReaderIndex( $group = false, $wiki = false ) {
+               global $wgDBtype;
+
+               # @todo FIXME: For now, only go through all this for mysql databases
+               if ( $wgDBtype != 'mysql' ) {
+                       return $this->getWriterIndex();
+               }
+
+               if ( count( $this->mServers ) == 1 ) {
+                       # Skip the load balancing if there's only one server
+                       return 0;
+               } elseif ( $group === false && $this->mReadIndex >= 0 ) {
+                       # Shortcut if generic reader exists already
+                       return $this->mReadIndex;
+               }
+
+               # Find the relevant load array
+               if ( $group !== false ) {
+                       if ( isset( $this->mGroupLoads[$group] ) ) {
+                               $nonErrorLoads = $this->mGroupLoads[$group];
+                       } else {
+                               # No loads for this group, return false and the caller can use some other group
+                               wfDebug( __METHOD__ . ": no loads for group $group\n" );
+
+                               return false;
+                       }
+               } else {
+                       $nonErrorLoads = $this->mLoads;
+               }
+
+               if ( !count( $nonErrorLoads ) ) {
+                       throw new MWException( "Empty server array given to LoadBalancer" );
+               }
+
+               # Scale the configured load ratios according to the dynamic load (if the load monitor supports it)
+               $this->getLoadMonitor()->scaleLoads( $nonErrorLoads, $group, $wiki );
+
+               $laggedSlaveMode = false;
+
+               # No server found yet
+               $i = false;
+               # First try quickly looking through the available servers for a server that
+               # meets our criteria
+               $currentLoads = $nonErrorLoads;
+               while ( count( $currentLoads ) ) {
+                       if ( $this->mAllowLagged || $laggedSlaveMode ) {
+                               $i = ArrayUtils::pickRandom( $currentLoads );
+                       } else {
+                               $i = false;
+                               if ( $this->mWaitForPos && $this->mWaitForPos->asOfTime() ) {
+                                       # ChronologyProtecter causes mWaitForPos to be set via sessions.
+                                       # This triggers doWait() after connect, so it's especially good to
+                                       # avoid lagged servers so as to avoid just blocking in that method.
+                                       $ago = microtime( true ) - $this->mWaitForPos->asOfTime();
+                                       # Aim for <= 1 second of waiting (being too picky can backfire)
+                                       $i = $this->getRandomNonLagged( $currentLoads, $wiki, $ago + 1 );
+                               }
+                               if ( $i === false ) {
+                                       # Any server with less lag than it's 'max lag' param is preferable
+                                       $i = $this->getRandomNonLagged( $currentLoads, $wiki );
+                               }
+                               if ( $i === false && count( $currentLoads ) != 0 ) {
+                                       # All slaves lagged. Switch to read-only mode
+                                       wfDebugLog( 'replication', "All slaves lagged. Switch to read-only mode" );
+                                       $i = ArrayUtils::pickRandom( $currentLoads );
+                                       $laggedSlaveMode = true;
+                               }
+                       }
+
+                       if ( $i === false ) {
+                               # pickRandom() returned false
+                               # This is permanent and means the configuration or the load monitor
+                               # wants us to return false.
+                               wfDebugLog( 'connect', __METHOD__ . ": pickRandom() returned false" );
+
+                               return false;
+                       }
+
+                       $serverName = $this->getServerName( $i );
+                       wfDebugLog( 'connect', __METHOD__ . ": Using reader #$i: $serverName..." );
+
+                       $conn = $this->openConnection( $i, $wiki );
+                       if ( !$conn ) {
+                               wfDebugLog( 'connect', __METHOD__ . ": Failed connecting to $i/$wiki" );
+                               unset( $nonErrorLoads[$i] );
+                               unset( $currentLoads[$i] );
+                               $i = false;
+                               continue;
+                       }
+
+                       // Decrement reference counter, we are finished with this connection.
+                       // It will be incremented for the caller later.
+                       if ( $wiki !== false ) {
+                               $this->reuseConnection( $conn );
+                       }
+
+                       # Return this server
+                       break;
+               }
+
+               # If all servers were down, quit now
+               if ( !count( $nonErrorLoads ) ) {
+                       wfDebugLog( 'connect', "All servers down" );
+               }
+
+               if ( $i !== false ) {
+                       # Slave connection successful
+                       # Wait for the session master pos for a short time
+                       if ( $this->mWaitForPos && $i > 0 ) {
+                               if ( !$this->doWait( $i ) ) {
+                                       $this->mServers[$i]['slave pos'] = $conn->getSlavePos();
+                               }
+                       }
+                       if ( $this->mReadIndex <= 0 && $this->mLoads[$i] > 0 && $group === false ) {
+                               $this->mReadIndex = $i;
+                               # Record if the generic reader index is in "lagged slave" mode
+                               if ( $laggedSlaveMode ) {
+                                       $this->mLaggedSlaveMode = true;
+                               }
+                       }
+                       $serverName = $this->getServerName( $i );
+                       wfDebug( __METHOD__ . ": using server $serverName for group '$group'\n" );
+               }
+
+               return $i;
+       }
+
+       /**
+        * Set the master wait position
+        * If a DB_SLAVE connection has been opened already, waits
+        * Otherwise sets a variable telling it to wait if such a connection is opened
+        * @param DBMasterPos $pos
+        */
+       public function waitFor( $pos ) {
+               $this->mWaitForPos = $pos;
+               $i = $this->mReadIndex;
+
+               if ( $i > 0 ) {
+                       if ( !$this->doWait( $i ) ) {
+                               $this->mServers[$i]['slave pos'] = $this->getAnyOpenConnection( $i )->getSlavePos();
+                               $this->mLaggedSlaveMode = true;
+                       }
+               }
+       }
+
+       /**
+        * Set the master wait position and wait for a "generic" slave to catch up to it
+        *
+        * This can be used a faster proxy for waitForAll()
+        *
+        * @param DBMasterPos $pos
+        * @param int $timeout Max seconds to wait; default is mWaitTimeout
+        * @return bool Success (able to connect and no timeouts reached)
+        * @since 1.26
+        */
+       public function waitForOne( $pos, $timeout = null ) {
+               $this->mWaitForPos = $pos;
+
+               $i = $this->mReadIndex;
+               if ( $i <= 0 ) {
+                       // Pick a generic slave if there isn't one yet
+                       $readLoads = $this->mLoads;
+                       unset( $readLoads[$this->getWriterIndex()] ); // slaves only
+                       $readLoads = array_filter( $readLoads ); // with non-zero load
+                       $i = ArrayUtils::pickRandom( $readLoads );
+               }
+
+               if ( $i > 0 ) {
+                       $ok = $this->doWait( $i, true, $timeout );
+               } else {
+                       $ok = true; // no applicable loads
+               }
+
+               return $ok;
+       }
+
+       /**
+        * Set the master wait position and wait for ALL slaves to catch up to it
+        * @param DBMasterPos $pos
+        * @param int $timeout Max seconds to wait; default is mWaitTimeout
+        * @return bool Success (able to connect and no timeouts reached)
+        */
+       public function waitForAll( $pos, $timeout = null ) {
+               $this->mWaitForPos = $pos;
+               $serverCount = count( $this->mServers );
+
+               $ok = true;
+               for ( $i = 1; $i < $serverCount; $i++ ) {
+                       if ( $this->mLoads[$i] > 0 ) {
+                               $ok = $this->doWait( $i, true, $timeout ) && $ok;
+                       }
+               }
+
+               return $ok;
+       }
+
+       /**
+        * Get any open connection to a given server index, local or foreign
+        * Returns false if there is no connection open
+        *
+        * @param int $i
+        * @return DatabaseBase|bool False on failure
+        */
+       public function getAnyOpenConnection( $i ) {
+               foreach ( $this->mConns as $conns ) {
+                       if ( !empty( $conns[$i] ) ) {
+                               return reset( $conns[$i] );
+                       }
+               }
+
+               return false;
+       }
+
+       /**
+        * Wait for a given slave to catch up to the master pos stored in $this
+        * @param int $index Server index
+        * @param bool $open Check the server even if a new connection has to be made
+        * @param int $timeout Max seconds to wait; default is mWaitTimeout
+        * @return bool
+        */
+       protected function doWait( $index, $open = false, $timeout = null ) {
+               $close = false; // close the connection afterwards
+
+               # Find a connection to wait on, creating one if needed and allowed
+               $conn = $this->getAnyOpenConnection( $index );
+               if ( !$conn ) {
+                       if ( !$open ) {
+                               wfDebug( __METHOD__ . ": no connection open\n" );
+
+                               return false;
+                       } else {
+                               $conn = $this->openConnection( $index, '' );
+                               if ( !$conn ) {
+                                       wfDebug( __METHOD__ . ": failed to open connection\n" );
+
+                                       return false;
+                               }
+                               // Avoid connection spam in waitForAll() when connections
+                               // are made just for the sake of doing this lag check.
+                               $close = true;
+                       }
+               }
+
+               wfDebug( __METHOD__ . ": Waiting for slave #$index to catch up...\n" );
+               $timeout = $timeout ?: $this->mWaitTimeout;
+               $result = $conn->masterPosWait( $this->mWaitForPos, $timeout );
+
+               if ( $result == -1 || is_null( $result ) ) {
+                       # Timed out waiting for slave, use master instead
+                       $server = $server = $this->getServerName( $index );
+                       $msg = __METHOD__ . ": Timed out waiting on $server pos {$this->mWaitForPos}";
+                       wfDebug( "$msg\n" );
+                       wfDebugLog( 'DBPerformance', "$msg:\n" . wfBacktrace( true ) );
+                       $ok = false;
+               } else {
+                       wfDebug( __METHOD__ . ": Done\n" );
+                       $ok = true;
+               }
+
+               if ( $close ) {
+                       $this->closeConnection( $conn );
+               }
+
+               return $ok;
+       }
+
+       /**
+        * Get a connection by index
+        * This is the main entry point for this class.
+        *
+        * @param int $i Server index
+        * @param array|string|bool $groups Query group(s), or false for the generic reader
+        * @param string|bool $wiki Wiki ID, or false for the current wiki
+        *
+        * @throws MWException
+        * @return DatabaseBase
+        */
+       public function getConnection( $i, $groups = array(), $wiki = false ) {
+               if ( $i === null || $i === false ) {
+                       throw new MWException( 'Attempt to call ' . __METHOD__ .
+                               ' with invalid server index' );
+               }
+
+               if ( $wiki === wfWikiID() ) {
+                       $wiki = false;
+               }
+
+               $groups = ( $groups === false || $groups === array() )
+                       ? array( false ) // check one "group": the generic pool
+                       : (array)$groups;
+
+               $masterOnly = ( $i == DB_MASTER || $i == $this->getWriterIndex() );
+               $oldConnsOpened = $this->connsOpened; // connections open now
+
+               if ( $i == DB_MASTER ) {
+                       $i = $this->getWriterIndex();
+               } else {
+                       # Try to find an available server in any the query groups (in order)
+                       foreach ( $groups as $group ) {
+                               $groupIndex = $this->getReaderIndex( $group, $wiki );
+                               if ( $groupIndex !== false ) {
+                                       $i = $groupIndex;
+                                       break;
+                               }
+                       }
+               }
+
+               # Operation-based index
+               if ( $i == DB_SLAVE ) {
+                       $this->mLastError = 'Unknown error'; // reset error string
+                       # Try the general server pool if $groups are unavailable.
+                       $i = in_array( false, $groups, true )
+                               ? false // don't bother with this if that is what was tried above
+                               : $this->getReaderIndex( false, $wiki );
+                       # Couldn't find a working server in getReaderIndex()?
+                       if ( $i === false ) {
+                               $this->mLastError = 'No working slave server: ' . $this->mLastError;
+
+                               return $this->reportConnectionError();
+                       }
+               }
+
+               # Now we have an explicit index into the servers array
+               $conn = $this->openConnection( $i, $wiki );
+               if ( !$conn ) {
+                       return $this->reportConnectionError();
+               }
+
+               # Profile any new connections that happen
+               if ( $this->connsOpened > $oldConnsOpened ) {
+                       $host = $conn->getServer();
+                       $dbname = $conn->getDBname();
+                       $trxProf = Profiler::instance()->getTransactionProfiler();
+                       $trxProf->recordConnection( $host, $dbname, $masterOnly );
+               }
+
+               return $conn;
+       }
+
+       /**
+        * Mark a foreign connection as being available for reuse under a different
+        * DB name or prefix. This mechanism is reference-counted, and must be called
+        * the same number of times as getConnection() to work.
+        *
+        * @param DatabaseBase $conn
+        * @throws MWException
+        */
+       public function reuseConnection( $conn ) {
+               $serverIndex = $conn->getLBInfo( 'serverIndex' );
+               $refCount = $conn->getLBInfo( 'foreignPoolRefCount' );
+               if ( $serverIndex === null || $refCount === null ) {
+                       wfDebug( __METHOD__ . ": this connection was not opened as a foreign connection\n" );
+
+                       /**
+                        * This can happen in code like:
+                        *   foreach ( $dbs as $db ) {
+                        *     $conn = $lb->getConnection( DB_SLAVE, array(), $db );
+                        *     ...
+                        *     $lb->reuseConnection( $conn );
+                        *   }
+                        * When a connection to the local DB is opened in this way, reuseConnection()
+                        * should be ignored
+                        */
+
+                       return;
+               }
+
+               $dbName = $conn->getDBname();
+               $prefix = $conn->tablePrefix();
+               if ( strval( $prefix ) !== '' ) {
+                       $wiki = "$dbName-$prefix";
+               } else {
+                       $wiki = $dbName;
+               }
+               if ( $this->mConns['foreignUsed'][$serverIndex][$wiki] !== $conn ) {
+                       throw new MWException( __METHOD__ . ": connection not found, has " .
+                               "the connection been freed already?" );
+               }
+               $conn->setLBInfo( 'foreignPoolRefCount', --$refCount );
+               if ( $refCount <= 0 ) {
+                       $this->mConns['foreignFree'][$serverIndex][$wiki] = $conn;
+                       unset( $this->mConns['foreignUsed'][$serverIndex][$wiki] );
+                       wfDebug( __METHOD__ . ": freed connection $serverIndex/$wiki\n" );
+               } else {
+                       wfDebug( __METHOD__ . ": reference count for $serverIndex/$wiki reduced to $refCount\n" );
+               }
+       }
+
+       /**
+        * Get a database connection handle reference
+        *
+        * The handle's methods wrap simply wrap those of a DatabaseBase handle
+        *
+        * @see LoadBalancer::getConnection() for parameter information
+        *
+        * @param int $db
+        * @param array|string|bool $groups Query group(s), or false for the generic reader
+        * @param string|bool $wiki Wiki ID, or false for the current wiki
+        * @return DBConnRef
+        */
+       public function getConnectionRef( $db, $groups = array(), $wiki = false ) {
+               return new DBConnRef( $this, $this->getConnection( $db, $groups, $wiki ) );
+       }
+
+       /**
+        * Get a database connection handle reference without connecting yet
+        *
+        * The handle's methods wrap simply wrap those of a DatabaseBase handle
+        *
+        * @see LoadBalancer::getConnection() for parameter information
+        *
+        * @param int $db
+        * @param array|string|bool $groups Query group(s), or false for the generic reader
+        * @param string|bool $wiki Wiki ID, or false for the current wiki
+        * @return DBConnRef
+        */
+       public function getLazyConnectionRef( $db, $groups = array(), $wiki = false ) {
+               return new DBConnRef( $this, array( $db, $groups, $wiki ) );
+       }
+
+       /**
+        * Open a connection to the server given by the specified index
+        * Index must be an actual index into the array.
+        * If the server is already open, returns it.
+        *
+        * On error, returns false, and the connection which caused the
+        * error will be available via $this->mErrorConnection.
+        *
+        * @param int $i Server index
+        * @param string|bool $wiki Wiki ID, or false for the current wiki
+        * @return DatabaseBase
+        *
+        * @access private
+        */
+       public function openConnection( $i, $wiki = false ) {
+               if ( $wiki !== false ) {
+                       $conn = $this->openForeignConnection( $i, $wiki );
+               } elseif ( isset( $this->mConns['local'][$i][0] ) ) {
+                       $conn = $this->mConns['local'][$i][0];
+               } else {
+                       $server = $this->mServers[$i];
+                       $server['serverIndex'] = $i;
+                       $conn = $this->reallyOpenConnection( $server, false );
+                       $serverName = $this->getServerName( $i );
+                       if ( $conn->isOpen() ) {
+                               wfDebug( "Connected to database $i at $serverName\n" );
+                               $this->mConns['local'][$i][0] = $conn;
+                       } else {
+                               wfDebug( "Failed to connect to database $i at $serverName\n" );
+                               $this->mErrorConnection = $conn;
+                               $conn = false;
+                       }
+               }
+
+               if ( $conn && !$conn->isOpen() ) {
+                       // Connection was made but later unrecoverably lost for some reason.
+                       // Do not return a handle that will just throw exceptions on use,
+                       // but let the calling code (e.g. getReaderIndex) try another server.
+                       // See DatabaseMyslBase::ping() for how this can happen.
+                       $this->mErrorConnection = $conn;
+                       $conn = false;
+               }
+
+               return $conn;
+       }
+
+       /**
+        * Open a connection to a foreign DB, or return one if it is already open.
+        *
+        * Increments a reference count on the returned connection which locks the
+        * connection to the requested wiki. This reference count can be
+        * decremented by calling reuseConnection().
+        *
+        * If a connection is open to the appropriate server already, but with the wrong
+        * database, it will be switched to the right database and returned, as long as
+        * it has been freed first with reuseConnection().
+        *
+        * On error, returns false, and the connection which caused the
+        * error will be available via $this->mErrorConnection.
+        *
+        * @param int $i Server index
+        * @param string $wiki Wiki ID to open
+        * @return DatabaseBase
+        */
+       private function openForeignConnection( $i, $wiki ) {
+               list( $dbName, $prefix ) = wfSplitWikiID( $wiki );
+               if ( isset( $this->mConns['foreignUsed'][$i][$wiki] ) ) {
+                       // Reuse an already-used connection
+                       $conn = $this->mConns['foreignUsed'][$i][$wiki];
+                       wfDebug( __METHOD__ . ": reusing connection $i/$wiki\n" );
+               } elseif ( isset( $this->mConns['foreignFree'][$i][$wiki] ) ) {
+                       // Reuse a free connection for the same wiki
+                       $conn = $this->mConns['foreignFree'][$i][$wiki];
+                       unset( $this->mConns['foreignFree'][$i][$wiki] );
+                       $this->mConns['foreignUsed'][$i][$wiki] = $conn;
+                       wfDebug( __METHOD__ . ": reusing free connection $i/$wiki\n" );
+               } elseif ( !empty( $this->mConns['foreignFree'][$i] ) ) {
+                       // Reuse a connection from another wiki
+                       $conn = reset( $this->mConns['foreignFree'][$i] );
+                       $oldWiki = key( $this->mConns['foreignFree'][$i] );
+
+                       // The empty string as a DB name means "don't care".
+                       // DatabaseMysqlBase::open() already handle this on connection.
+                       if ( $dbName !== '' && !$conn->selectDB( $dbName ) ) {
+                               $this->mLastError = "Error selecting database $dbName on server " .
+                                       $conn->getServer() . " from client host " . wfHostname() . "\n";
+                               $this->mErrorConnection = $conn;
+                               $conn = false;
+                       } else {
+                               $conn->tablePrefix( $prefix );
+                               unset( $this->mConns['foreignFree'][$i][$oldWiki] );
+                               $this->mConns['foreignUsed'][$i][$wiki] = $conn;
+                               wfDebug( __METHOD__ . ": reusing free connection from $oldWiki for $wiki\n" );
+                       }
+               } else {
+                       // Open a new connection
+                       $server = $this->mServers[$i];
+                       $server['serverIndex'] = $i;
+                       $server['foreignPoolRefCount'] = 0;
+                       $server['foreign'] = true;
+                       $conn = $this->reallyOpenConnection( $server, $dbName );
+                       if ( !$conn->isOpen() ) {
+                               wfDebug( __METHOD__ . ": error opening connection for $i/$wiki\n" );
+                               $this->mErrorConnection = $conn;
+                               $conn = false;
+                       } else {
+                               $conn->tablePrefix( $prefix );
+                               $this->mConns['foreignUsed'][$i][$wiki] = $conn;
+                               wfDebug( __METHOD__ . ": opened new connection for $i/$wiki\n" );
+                       }
+               }
+
+               // Increment reference count
+               if ( $conn ) {
+                       $refCount = $conn->getLBInfo( 'foreignPoolRefCount' );
+                       $conn->setLBInfo( 'foreignPoolRefCount', $refCount + 1 );
+               }
+
+               return $conn;
+       }
+
+       /**
+        * Test if the specified index represents an open connection
+        *
+        * @param int $index Server index
+        * @access private
+        * @return bool
+        */
+       private function isOpen( $index ) {
+               if ( !is_integer( $index ) ) {
+                       return false;
+               }
+
+               return (bool)$this->getAnyOpenConnection( $index );
+       }
+
+       /**
+        * Really opens a connection. Uncached.
+        * Returns a Database object whether or not the connection was successful.
+        * @access private
+        *
+        * @param array $server
+        * @param bool $dbNameOverride
+        * @throws MWException
+        * @return DatabaseBase
+        */
+       protected function reallyOpenConnection( $server, $dbNameOverride = false ) {
+               if ( !is_array( $server ) ) {
+                       throw new MWException( 'You must update your load-balancing configuration. ' .
+                               'See DefaultSettings.php entry for $wgDBservers.' );
+               }
+
+               if ( $dbNameOverride !== false ) {
+                       $server['dbname'] = $dbNameOverride;
+               }
+
+               // Log when many connection are made on requests
+               if ( ++$this->connsOpened >= self::CONN_HELD_WARN_THRESHOLD ) {
+                       $masterAddr = $this->getServerName( 0 );
+                       wfDebugLog( 'DBPerformance', __METHOD__ . ": " .
+                               "{$this->connsOpened}+ connections made (master=$masterAddr)\n" .
+                               wfBacktrace( true ) );
+               }
+
+               # Create object
+               try {
+                       $db = DatabaseBase::factory( $server['type'], $server );
+               } catch ( DBConnectionError $e ) {
+                       // FIXME: This is probably the ugliest thing I have ever done to
+                       // PHP. I'm half-expecting it to segfault, just out of disgust. -- TS
+                       $db = $e->db;
+               }
+
+               $db->setLBInfo( $server );
+               if ( isset( $server['fakeSlaveLag'] ) ) {
+                       $db->setFakeSlaveLag( $server['fakeSlaveLag'] );
+               }
+               if ( isset( $server['fakeMaster'] ) ) {
+                       $db->setFakeMaster( true );
+               }
+
+               return $db;
+       }
+
+       /**
+        * @throws DBConnectionError
+        * @return bool
+        */
+       private function reportConnectionError() {
+               $conn = $this->mErrorConnection; // The connection which caused the error
+               $context = array(
+                       'method' => __METHOD__,
+                       'last_error' => $this->mLastError,
+               );
+
+               if ( !is_object( $conn ) ) {
+                       // No last connection, probably due to all servers being too busy
+                       wfLogDBError(
+                               "LB failure with no last connection. Connection error: {last_error}",
+                               $context
+                       );
+
+                       // If all servers were busy, mLastError will contain something sensible
+                       throw new DBConnectionError( null, $this->mLastError );
+               } else {
+                       $context['db_server'] = $conn->getProperty( 'mServer' );
+                       wfLogDBError(
+                               "Connection error: {last_error} ({db_server})",
+                               $context
+                       );
+                       $conn->reportConnectionError( "{$this->mLastError} ({$context['db_server']})" ); // throws DBConnectionError
+               }
+
+               return false; /* not reached */
+       }
+
+       /**
+        * @return int
+        * @since 1.26
+        */
+       public function getWriterIndex() {
+               return 0;
+       }
+
+       /**
+        * Returns true if the specified index is a valid server index
+        *
+        * @param string $i
+        * @return bool
+        */
+       public function haveIndex( $i ) {
+               return array_key_exists( $i, $this->mServers );
+       }
+
+       /**
+        * Returns true if the specified index is valid and has non-zero load
+        *
+        * @param string $i
+        * @return bool
+        */
+       public function isNonZeroLoad( $i ) {
+               return array_key_exists( $i, $this->mServers ) && $this->mLoads[$i] != 0;
+       }
+
+       /**
+        * Get the number of defined servers (not the number of open connections)
+        *
+        * @return int
+        */
+       public function getServerCount() {
+               return count( $this->mServers );
+       }
+
+       /**
+        * Get the host name or IP address of the server with the specified index
+        * Prefer a readable name if available.
+        * @param string $i
+        * @return string
+        */
+       public function getServerName( $i ) {
+               if ( isset( $this->mServers[$i]['hostName'] ) ) {
+                       $name = $this->mServers[$i]['hostName'];
+               } elseif ( isset( $this->mServers[$i]['host'] ) ) {
+                       $name = $this->mServers[$i]['host'];
+               } else {
+                       $name = '';
+               }
+
+               return ( $name != '' ) ? $name : 'localhost';
+       }
+
+       /**
+        * Return the server info structure for a given index, or false if the index is invalid.
+        * @param int $i
+        * @return array|bool
+        */
+       public function getServerInfo( $i ) {
+               if ( isset( $this->mServers[$i] ) ) {
+                       return $this->mServers[$i];
+               } else {
+                       return false;
+               }
+       }
+
+       /**
+        * Sets the server info structure for the given index. Entry at index $i
+        * is created if it doesn't exist
+        * @param int $i
+        * @param array $serverInfo
+        */
+       public function setServerInfo( $i, array $serverInfo ) {
+               $this->mServers[$i] = $serverInfo;
+       }
+
+       /**
+        * Get the current master position for chronology control purposes
+        * @return mixed
+        */
+       public function getMasterPos() {
+               # If this entire request was served from a slave without opening a connection to the
+               # master (however unlikely that may be), then we can fetch the position from the slave.
+               $masterConn = $this->getAnyOpenConnection( 0 );
+               if ( !$masterConn ) {
+                       $serverCount = count( $this->mServers );
+                       for ( $i = 1; $i < $serverCount; $i++ ) {
+                               $conn = $this->getAnyOpenConnection( $i );
+                               if ( $conn ) {
+                                       wfDebug( "Master pos fetched from slave\n" );
+
+                                       return $conn->getSlavePos();
+                               }
+                       }
+               } else {
+                       wfDebug( "Master pos fetched from master\n" );
+
+                       return $masterConn->getMasterPos();
+               }
+
+               return false;
+       }
+
+       /**
+        * Close all open connections
+        */
+       public function closeAll() {
+               foreach ( $this->mConns as $conns2 ) {
+                       foreach ( $conns2 as $conns3 ) {
+                               /** @var DatabaseBase $conn */
+                               foreach ( $conns3 as $conn ) {
+                                       $conn->close();
+                               }
+                       }
+               }
+               $this->mConns = array(
+                       'local' => array(),
+                       'foreignFree' => array(),
+                       'foreignUsed' => array(),
+               );
+               $this->connsOpened = 0;
+       }
+
+       /**
+        * Close a connection
+        * Using this function makes sure the LoadBalancer knows the connection is closed.
+        * If you use $conn->close() directly, the load balancer won't update its state.
+        * @param DatabaseBase $conn
+        */
+       public function closeConnection( $conn ) {
+               $done = false;
+               foreach ( $this->mConns as $i1 => $conns2 ) {
+                       foreach ( $conns2 as $i2 => $conns3 ) {
+                               foreach ( $conns3 as $i3 => $candidateConn ) {
+                                       if ( $conn === $candidateConn ) {
+                                               $conn->close();
+                                               unset( $this->mConns[$i1][$i2][$i3] );
+                                               --$this->connsOpened;
+                                               $done = true;
+                                               break;
+                                       }
+                               }
+                       }
+               }
+               if ( !$done ) {
+                       $conn->close();
+               }
+       }
+
+       /**
+        * Commit transactions on all open connections
+        */
+       public function commitAll() {
+               foreach ( $this->mConns as $conns2 ) {
+                       foreach ( $conns2 as $conns3 ) {
+                               /** @var DatabaseBase[] $conns3 */
+                               foreach ( $conns3 as $conn ) {
+                                       if ( $conn->trxLevel() ) {
+                                               $conn->commit( __METHOD__, 'flush' );
+                                       }
+                               }
+                       }
+               }
+       }
+
+       /**
+        *  Issue COMMIT only on master, only if queries were done on connection
+        */
+       public function commitMasterChanges() {
+               $masterIndex = $this->getWriterIndex();
+               foreach ( $this->mConns as $conns2 ) {
+                       if ( empty( $conns2[$masterIndex] ) ) {
+                               continue;
+                       }
+                       /** @var DatabaseBase $conn */
+                       foreach ( $conns2[$masterIndex] as $conn ) {
+                               if ( $conn->trxLevel() && $conn->writesOrCallbacksPending() ) {
+                                       $conn->commit( __METHOD__, 'flush' );
+                               }
+                       }
+               }
+       }
+
+       /**
+        * Issue ROLLBACK only on master, only if queries were done on connection
+        * @since 1.23
+        */
+       public function rollbackMasterChanges() {
+               $failedServers = array();
+
+               $masterIndex = $this->getWriterIndex();
+               foreach ( $this->mConns as $conns2 ) {
+                       if ( empty( $conns2[$masterIndex] ) ) {
+                               continue;
+                       }
+                       /** @var DatabaseBase $conn */
+                       foreach ( $conns2[$masterIndex] as $conn ) {
+                               if ( $conn->trxLevel() && $conn->writesOrCallbacksPending() ) {
+                                       try {
+                                               $conn->rollback( __METHOD__, 'flush' );
+                                       } catch ( DBError $e ) {
+                                               MWExceptionHandler::logException( $e );
+                                               $failedServers[] = $conn->getServer();
+                                       }
+                               }
+                       }
+               }
+
+               if ( $failedServers ) {
+                       throw new DBExpectedError( null, "Rollback failed on server(s) " .
+                               implode( ', ', array_unique( $failedServers ) ) );
+               }
+       }
+
+       /**
+        * @return bool Whether a master connection is already open
+        * @since 1.24
+        */
+       public function hasMasterConnection() {
+               return $this->isOpen( $this->getWriterIndex() );
+       }
+
+       /**
+        * Determine if there are pending changes in a transaction by this thread
+        * @since 1.23
+        * @return bool
+        */
+       public function hasMasterChanges() {
+               $masterIndex = $this->getWriterIndex();
+               foreach ( $this->mConns as $conns2 ) {
+                       if ( empty( $conns2[$masterIndex] ) ) {
+                               continue;
+                       }
+                       /** @var DatabaseBase $conn */
+                       foreach ( $conns2[$masterIndex] as $conn ) {
+                               if ( $conn->trxLevel() && $conn->writesOrCallbacksPending() ) {
+                                       return true;
+                               }
+                       }
+               }
+               return false;
+       }
+
+       /**
+        * Get the timestamp of the latest write query done by this thread
+        * @since 1.25
+        * @return float|bool UNIX timestamp or false
+        */
+       public function lastMasterChangeTimestamp() {
+               $lastTime = false;
+               $masterIndex = $this->getWriterIndex();
+               foreach ( $this->mConns as $conns2 ) {
+                       if ( empty( $conns2[$masterIndex] ) ) {
+                               continue;
+                       }
+                       /** @var DatabaseBase $conn */
+                       foreach ( $conns2[$masterIndex] as $conn ) {
+                               $lastTime = max( $lastTime, $conn->lastDoneWrites() );
+                       }
+               }
+               return $lastTime;
+       }
+
+       /**
+        * Check if this load balancer object had any recent or still
+        * pending writes issued against it by this PHP thread
+        *
+        * @param float $age How many seconds ago is "recent" [defaults to mWaitTimeout]
+        * @return bool
+        * @since 1.25
+        */
+       public function hasOrMadeRecentMasterChanges( $age = null ) {
+               $age = ( $age === null ) ? $this->mWaitTimeout : $age;
+
+               return ( $this->hasMasterChanges()
+                       || $this->lastMasterChangeTimestamp() > microtime( true ) - $age );
+       }
+
+       /**
+        * @param mixed $value
+        * @return mixed
+        */
+       public function waitTimeout( $value = null ) {
+               return wfSetVar( $this->mWaitTimeout, $value );
+       }
+
+       /**
+        * @return bool Whether the generic connection for reads is highly "lagged"
+        */
+       public function getLaggedSlaveMode() {
+               # Get a generic reader connection
+               $this->getConnection( DB_SLAVE );
+
+               return $this->mLaggedSlaveMode;
+       }
+
+       /**
+        * Disables/enables lag checks
+        * @param null|bool $mode
+        * @return bool
+        */
+       public function allowLagged( $mode = null ) {
+               if ( $mode === null ) {
+                       return $this->mAllowLagged;
+               }
+               $this->mAllowLagged = $mode;
+
+               return $this->mAllowLagged;
+       }
+
+       /**
+        * @return bool
+        */
+       public function pingAll() {
+               $success = true;
+               foreach ( $this->mConns as $conns2 ) {
+                       foreach ( $conns2 as $conns3 ) {
+                               /** @var DatabaseBase[] $conns3 */
+                               foreach ( $conns3 as $conn ) {
+                                       if ( !$conn->ping() ) {
+                                               $success = false;
+                                       }
+                               }
+                       }
+               }
+
+               return $success;
+       }
+
+       /**
+        * Call a function with each open connection object
+        * @param callable $callback
+        * @param array $params
+        */
+       public function forEachOpenConnection( $callback, array $params = array() ) {
+               foreach ( $this->mConns as $conns2 ) {
+                       foreach ( $conns2 as $conns3 ) {
+                               foreach ( $conns3 as $conn ) {
+                                       $mergedParams = array_merge( array( $conn ), $params );
+                                       call_user_func_array( $callback, $mergedParams );
+                               }
+                       }
+               }
+       }
+
+       /**
+        * Get the hostname and lag time of the most-lagged slave
+        *
+        * This is useful for maintenance scripts that need to throttle their updates.
+        * May attempt to open connections to slaves on the default DB. If there is
+        * no lag, the maximum lag will be reported as -1.
+        *
+        * @param bool|string $wiki Wiki ID, or false for the default database
+        * @return array ( host, max lag, index of max lagged host )
+        */
+       public function getMaxLag( $wiki = false ) {
+               $maxLag = -1;
+               $host = '';
+               $maxIndex = 0;
+
+               if ( $this->getServerCount() <= 1 ) {
+                       return array( $host, $maxLag, $maxIndex ); // no replication = no lag
+               }
+
+               $lagTimes = $this->getLagTimes( $wiki );
+               foreach ( $lagTimes as $i => $lag ) {
+                       if ( $lag > $maxLag ) {
+                               $maxLag = $lag;
+                               $host = $this->mServers[$i]['host'];
+                               $maxIndex = $i;
+                       }
+               }
+
+               return array( $host, $maxLag, $maxIndex );
+       }
+
+       /**
+        * Get lag time for each server
+        *
+        * Results are cached for a short time in memcached/process cache
+        *
+        * @param string|bool $wiki
+        * @return int[] Map of (server index => seconds)
+        */
+       public function getLagTimes( $wiki = false ) {
+               if ( $this->getServerCount() <= 1 ) {
+                       return array( 0 => 0 ); // no replication = no lag
+               }
+
+               # Send the request to the load monitor
+               return $this->getLoadMonitor()->getLagTimes( array_keys( $this->mServers ), $wiki );
+       }
+
+       /**
+        * Get the lag in seconds for a given connection, or zero if this load
+        * balancer does not have replication enabled.
+        *
+        * This should be used in preference to Database::getLag() in cases where
+        * replication may not be in use, since there is no way to determine if
+        * replication is in use at the connection level without running
+        * potentially restricted queries such as SHOW SLAVE STATUS. Using this
+        * function instead of Database::getLag() avoids a fatal error in this
+        * case on many installations.
+        *
+        * @param DatabaseBase $conn
+        * @return int
+        */
+       public function safeGetLag( $conn ) {
+               if ( $this->getServerCount() == 1 ) {
+                       return 0;
+               } else {
+                       return $conn->getLag();
+               }
+       }
+
+       /**
+        * Clear the cache for slag lag delay times
+        *
+        * This is only used for testing
+        */
+       public function clearLagTimeCache() {
+               $this->getLoadMonitor()->clearCaches();
+       }
+}
diff --git a/includes/db/loadbalancer/LoadMonitor.php b/includes/db/loadbalancer/LoadMonitor.php
new file mode 100644 (file)
index 0000000..4975ea1
--- /dev/null
@@ -0,0 +1,66 @@
+<?php
+/**
+ * Database load monitoring.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ * @ingroup Database
+ */
+
+/**
+ * An interface for database load monitoring
+ *
+ * @ingroup Database
+ */
+interface LoadMonitor {
+       /**
+        * Construct a new LoadMonitor with a given LoadBalancer parent
+        *
+        * @param LoadBalancer $parent
+        */
+       public function __construct( $parent );
+
+       /**
+        * Perform pre-connection load ratio adjustment.
+        * @param array $loads
+        * @param string|bool $group The selected query group. Default: false
+        * @param string|bool $wiki Default: false
+        */
+       public function scaleLoads( &$loads, $group = false, $wiki = false );
+
+       /**
+        * Return an estimate of replication lag for each server
+        *
+        * @param array $serverIndexes
+        * @param string $wiki
+        *
+        * @return array Map of (server index => seconds)
+        */
+       public function getLagTimes( $serverIndexes, $wiki );
+}
+
+class LoadMonitorNull implements LoadMonitor {
+       public function __construct( $parent ) {
+       }
+
+       public function scaleLoads( &$loads, $group = false, $wiki = false ) {
+       }
+
+       public function getLagTimes( $serverIndexes, $wiki ) {
+               return array_fill_keys( $serverIndexes, 0 );
+       }
+}
diff --git a/includes/db/loadbalancer/LoadMonitorMySQL.php b/includes/db/loadbalancer/LoadMonitorMySQL.php
new file mode 100644 (file)
index 0000000..3008419
--- /dev/null
@@ -0,0 +1,124 @@
+<?php
+/**
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ * @ingroup Database
+ */
+
+/**
+ * Basic MySQL load monitor with no external dependencies
+ * Uses memcached to cache the replication lag for a short time
+ *
+ * @ingroup Database
+ */
+class LoadMonitorMySQL implements LoadMonitor {
+       /** @var LoadBalancer */
+       public $parent;
+       /** @var BagOStuff */
+       protected $srvCache;
+       /** @var BagOStuff */
+       protected $mainCache;
+
+       public function __construct( $parent ) {
+               $this->parent = $parent;
+
+               $this->srvCache = ObjectCache::newAccelerator( 'hash' );
+               $this->mainCache = wfGetMainCache();
+       }
+
+       public function scaleLoads( &$loads, $group = false, $wiki = false ) {
+       }
+
+       public function getLagTimes( $serverIndexes, $wiki ) {
+               if ( count( $serverIndexes ) == 1 && reset( $serverIndexes ) == 0 ) {
+                       # Single server only, just return zero without caching
+                       return array( 0 => 0 );
+               }
+
+               $key = $this->getLagTimeCacheKey();
+               # Randomize TTLs to reduce stampedes (4.0 - 5.0 sec)
+               $ttl = mt_rand( 4e6, 5e6 ) / 1e6;
+               # Keep keys around longer as fallbacks
+               $staleTTL = 60;
+
+               # (a) Check the local APC cache
+               $value = $this->srvCache->get( $key );
+               if ( $value && $value['timestamp'] > ( microtime( true ) - $ttl ) ) {
+                       wfDebugLog( 'replication',  __FUNCTION__ . ": got lag times ($key) from local cache" );
+                       return $value['lagTimes']; // cache hit
+               }
+               $staleValue = $value ?: false;
+
+               # (b) Check the shared cache and backfill APC
+               $value = $this->mainCache->get( $key );
+               if ( $value && $value['timestamp'] > ( microtime( true ) - $ttl ) ) {
+                       $this->srvCache->set( $key, $value, $staleTTL );
+                       wfDebugLog( 'replication',  __FUNCTION__ . ": got lag times ($key) from main cache" );
+
+                       return $value['lagTimes']; // cache hit
+               }
+               $staleValue = $value ?: $staleValue;
+
+               # (c) Cache key missing or expired; regenerate and backfill
+               if ( $this->mainCache->lock( $key, 0, 10 ) ) {
+                       # Let this process alone update the cache value
+                       $cache = $this->mainCache;
+                       /** @noinspection PhpUnusedLocalVariableInspection */
+                       $unlocker = new ScopedCallback( function () use ( $cache, $key ) {
+                               $cache->unlock( $key );
+                       } );
+               } elseif ( $staleValue ) {
+                       # Could not acquire lock but an old cache exists, so use it
+                       return $staleValue['lagTimes'];
+               }
+
+               $lagTimes = array();
+               foreach ( $serverIndexes as $i ) {
+                       if ( $i == 0 ) { # Master
+                               $lagTimes[$i] = 0;
+                       } elseif ( false !== ( $conn = $this->parent->getAnyOpenConnection( $i ) ) ) {
+                               $lagTimes[$i] = $conn->getLag();
+                       } elseif ( false !== ( $conn = $this->parent->openConnection( $i, $wiki ) ) ) {
+                               $lagTimes[$i] = $conn->getLag();
+                               # Close the connection to avoid sleeper connections piling up.
+                               # Note that the caller will pick one of these DBs and reconnect,
+                               # which is slightly inefficient, but this only matters for the lag
+                               # time cache miss cache, which is far less common that cache hits.
+                               $this->parent->closeConnection( $conn );
+                       }
+               }
+
+               # Add a timestamp key so we know when it was cached
+               $value = array( 'lagTimes' => $lagTimes, 'timestamp' => microtime( true ) );
+               $this->mainCache->set( $key, $value, $staleTTL );
+               $this->srvCache->set( $key, $value, $staleTTL );
+               wfDebugLog( 'replication',  __FUNCTION__ . ": re-calculated lag times ($key)" );
+
+               return $value['lagTimes'];
+       }
+
+       public function clearCaches() {
+               $key = $this->getLagTimeCacheKey();
+               $this->srvCache->delete( $key );
+               $this->mainCache->delete( $key );
+       }
+
+       private function getLagTimeCacheKey() {
+               # Lag is per-server, not per-DB, so key on the master DB name
+               return wfGlobalCacheKey( 'lag-times', $this->parent->getServerName( 0 ) );
+       }
+}
index d2c37e6..4c9c2aa 100644 (file)
@@ -456,7 +456,7 @@ class LocalFile extends File {
        }
 
        /**
-        * @param array $row Row
+        * @param array|object $row
         * @param string $prefix
         * @throws MWException
         * @return array
index 0df6f84..0934f6a 100644 (file)
@@ -46,6 +46,7 @@ class TraditionalImageGallery extends ImageGalleryBase {
                        array( 'class' => 'gallery mw-gallery-' . $this->mMode ), $this->mAttribs );
 
                $modules = $this->getModules();
+               $modules[] = 'mediawiki.page.gallery.styles';
 
                if ( $this->mParser ) {
                        $this->mParser->getOutput()->addModules( $modules );
index 662469b..72e11db 100644 (file)
@@ -534,7 +534,7 @@ abstract class Installer {
                // then some poorly-formed extensions try to call their own classes
                // after immediately registering them. We really need to get extension
                // registration out of the global scope and into a real format.
-               // @see https://bugzilla.wikimedia.org/67440
+               // @see https://phabricator.wikimedia.org/T69440
                global $wgAutoloadClasses;
                $wgAutoloadClasses = array();
 
@@ -1477,7 +1477,7 @@ abstract class Installer {
                 * want here is $wgHooks['LoadExtensionSchemaUpdates']. This won't work
                 * if the extension has hidden hook registration in $wgExtensionFunctions,
                 * but we're not opening that can of worms
-                * @see https://bugzilla.wikimedia.org/show_bug.cgi?id=26857
+                * @see https://phabricator.wikimedia.org/T28857
                 */
                global $wgAutoloadClasses;
                $wgAutoloadClasses = array();
index f7e4e67..078ff72 100644 (file)
@@ -2,14 +2,15 @@
        "@metadata": {
                "authors": [
                        "Eitvys200",
-                       "Mantak111"
+                       "Mantak111",
+                       "Zygimantus"
                ]
        },
        "config-desc": "MediaWiki diegimas",
        "config-title": "MediaWiki $1 diegimas",
        "config-information": "Informacija",
        "config-localsettings-key": "Naujinimo raktas:",
-       "config-localsettings-badkey": "Raktą, kurį pateikėte yra neteisingas.",
+       "config-localsettings-badkey": "Raktas, kurį pateikėte, yra neteisingas.",
        "config-your-language": "Jūsų kalba:",
        "config-wiki-language": "Viki kalba:",
        "config-back": "← Atgal",
        "config-page-install": "Įdiegti",
        "config-page-complete": "Baigta!",
        "config-page-restart": "Iš naujo paleiskite diegimą",
-       "config-page-readme": "Perskaityk manę",
+       "config-page-readme": "Skaityti daugiau",
        "config-page-copying": "Kopijuojama",
        "config-page-upgradedoc": "Atnaujinama",
-       "config-page-existingwiki": "Esamas wiki",
+       "config-page-existingwiki": "Esamas viki",
        "config-restart": "Taip, paleiskite jį iš naujo",
        "config-env-php": "PHP $1 yra įdiegtas.",
-       "config-env-php-toolow": "PHP $1 įdiegta.\nTačiau, MediaWiki reikia PHP $2 ar naujesnės.",
        "config-db-type": "Duomenų bazės tipas:",
        "config-db-host": "Duomenų bazės serveris:",
        "config-db-name": "Duomenų bazės pavadinimas:",
        "config-mssql-windowsauth": "Windows autentifikavimas",
        "config-site-name": "Viki pavadinimas:",
        "config-site-name-blank": "Įveskite svetainės pavadinimą.",
-       "config-project-namespace": "Projekto pavadinimas:",
+       "config-project-namespace": "Projekto vardų sritis:",
        "config-ns-generic": "Projektas",
        "config-ns-site-name": "Toks pat kaip viki pavadinimas: $1",
-       "config-ns-other-default": "ManoWiki",
+       "config-ns-other-default": "ManoViki",
        "config-admin-box": "Administratoriaus paskyra",
-       "config-admin-name": "Jūsų vardas:",
+       "config-admin-name": "Jūsų naudotojo vardas:",
        "config-admin-password": "Slaptažodis:",
        "config-admin-password-confirm": "Slaptažodis dar kartą:",
        "config-admin-name-blank": "Įveskite administratoriaus vartotojo vardą.",
@@ -67,9 +67,9 @@
        "config-optional-continue": "Paklausti daugiau klausimų.",
        "config-optional-skip": "Man jau nuobodu, tiesiog įdiekite viki.",
        "config-profile": "Vartotojo teisių paskyra:",
-       "config-profile-wiki": "Tradicinė viki",
+       "config-profile-wiki": "Atidaryti viki",
        "config-profile-private": "Privati viki",
-       "config-license-pd": "Viešas Domenas",
+       "config-license-pd": "Viešas domenas",
        "config-email-settings": "El. pašto nustatymai",
        "config-upload-enable": "Įgalinti failų įkėlimus",
        "config-logo": "Logotipo URL:",
@@ -81,7 +81,7 @@
        "config-install-tables": "Kuriamos lentelės",
        "config-install-stats": "Inicijuojamos statistikos",
        "config-install-keys": "Generuojami slapti raktai",
-       "config-install-done": "'''Sveikiname!'''\nJūs sėkmingai įdiegėte MediaWiki.\n\nĮdiegimo programa sukūrė <code>LocalSettings.php</code> failą.\nJame yra visos jūsų konfigūracijos.\n\nJums reikės atsisiųsti ir įdėti jį į savo wiki įdiegimo bazę (pačiame kataloge, kaip index.php). Atsisiuntimas turėtų prasidėti automatiškai.\n\nJei atsisiuntimas nebuvo pasiūlytas, arba jį atšaukėte, galite iš naujo atsisiųsti paspaudę žemiau esančią nuorodą:\n\n$3\n\n'''Pastaba:''' Jei jūs to nepadarysite dabar, tada šis sukurtas konfigūracijos failas nebus galimas vėliau, jei išeisite iš įdiegimo be atsisiuntimo.\n\nKai baigsite, jūs galėsite '''[$2 įeiti į savo wiki]'''.",
+       "config-install-done": "'''Sveikiname!'''\nJūs sėkmingai įdiegėte MediaWiki.\n\nĮdiegimo programa sukūrė <code>LocalSettings.php</code> failą.\nJame yra visos jūsų konfigūracijos.\n\nJums reikės atsisiųsti ir įdėti jį į savo wiki įdiegimo bazę (pačiame kataloge, kaip index.php). Atsisiuntimas turėtų prasidėti automatiškai.\n\nJei atsisiuntimas nebuvo pasiūlytas, arba jį atšaukėte, galite iš naujo atsisiųsti paspaudę žemiau esančią nuorodą:\n\n$3\n\n'''Pastaba:''' Jei jūs to nepadarysite dabar, tada šis sukurtas konfigūracijos failas nebus galimas vėliau, jei išeisite iš įdiegimo be atsisiuntimo.\n\nKai baigsite, jūs galėsite '''[$2 įeiti į savo viki]'''.",
        "config-download-localsettings": "Atsisiųsti <code>LocalSettings.php</code>",
        "config-help": "pagalba",
        "mainpagetext": "'''MediaWiki sėkmingai įdiegta.'''",
index dfe4376..c4ccec6 100644 (file)
@@ -58,7 +58,7 @@
        "config-help-restart": "Вы хотите удалить все сохранённые данные, которые вы ввели, и запустить процесс установки заново?",
        "config-restart": "Да, начать заново",
        "config-welcome": "=== Проверка окружения ===\nБудут проведены базовые проверки с целью определить, подходит ли данная система для установки MediaWiki.\nНе забудьте включить эту информацию, если вам потребуется помощь для завершения установки.",
-       "config-copyright": "=== Авторские права и условия ===\n\n$1\n\nMediaWiki является свободным программным обеспечением, которое вы можете распространять и/или изменять в соответствии с условиями лицензии GNU General Public License, опубликованной фондом свободного программного обеспечения; второй версии, либо любой более поздней версии.\n\nMediaWiki распространяется в надежде, что она будет полезной, но '''без каких-либо гарантий''', даже без подразумеваемых гарантий '''коммерческой ценности''' или '''пригодности для определённой цели'''. См. лицензию GNU General Public License для более подробной информации.\n\nВы должны были получить <doclink href=Copying>копию GNU General Public License</doclink> вместе с этой программой, если нет, то напишите Free Software Foundation, Inc., по адресу: 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA или [http://www.gnu.org/licenses/old-licenses/gpl-2.0.html прочтите её онлайн].",
+       "config-copyright": "=== Авторские права и условия ===\n\n$1\n\nMediaWiki — свободное программное обеспечение, которое вы можете распространять и/или изменять в соответствии с условиями лицензии GNU General Public License, опубликованной фондом свободного программного обеспечения; второй версии, либо любой более поздней версии.\n\nMediaWiki распространяется в надежде, что она будет полезной, но <strong>без каких-либо гарантий</strong>, даже без подразумеваемых гарантий <strong>коммерческой ценности</strong> или <strong>пригодности для определённой цели</strong>. См. лицензию GNU General Public License для более подробной информации.\n\nВы должны были получить <doclink href=Copying>копию GNU General Public License</doclink> вместе с этой программой, если нет, то напишите Free Software Foundation, Inc., по адресу: 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA или [http://www.gnu.org/copyleft/gpl.html прочтите её онлайн].",
        "config-sidebar": "* [//www.mediawiki.org Сайт MediaWiki]\n* [//www.mediawiki.org/wiki/Special:MyLanguage/Help:Contents/ru Справка для пользователей]\n* [//www.mediawiki.org/wiki/Special:MyLanguage/Manual:Contents/ru Справка для администраторов]\n* [//www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ/ru FAQ]\n----\n* <doclink href=Readme>Readme-файл</doclink>\n* <doclink href=ReleaseNotes>Информация о выпуске</doclink>\n* <doclink href=Copying>Лицензия</doclink>\n* <doclink href=UpgradeDoc>Обновление</doclink>",
        "config-env-good": "Проверка внешней среды была успешно проведена.\nВы можете установить MediaWiki.",
        "config-env-bad": "Была проведена проверка внешней среды.\nВы не можете установить MediaWiki.",
index 12bb175..3e5e8a1 100644 (file)
@@ -5318,7 +5318,6 @@ class Parser {
                $ig->setParser( $this );
                $ig->setHideBadImages();
                $ig->setAttributes( Sanitizer::validateTagAttributes( $params, 'table' ) );
-               $this->getOutput()->addModuleStyles( 'mediawiki.page.gallery.styles' );
 
                if ( isset( $params['showfilename'] ) ) {
                        $ig->setShowFilename( true );
index 51118b1..ca10ab7 100644 (file)
@@ -417,21 +417,8 @@ class ResourceLoaderFileModule extends ResourceLoaderModule {
                );
                // Collect referenced files
                $this->localFileRefs = array_unique( $this->localFileRefs );
-               // If the list has been modified since last time we cached it, update the cache
-               try {
-                       if ( $this->localFileRefs !== $this->getFileDependencies( $context->getSkin() ) ) {
-                               $dbw = wfGetDB( DB_MASTER );
-                               $dbw->replace( 'module_deps',
-                                       array( array( 'md_module', 'md_skin' ) ), array(
-                                               'md_module' => $this->getName(),
-                                               'md_skin' => $context->getSkin(),
-                                               'md_deps' => FormatJson::encode( $this->localFileRefs ),
-                                       )
-                               );
-                       }
-               } catch ( Exception $e ) {
-                       wfDebugLog( 'resourceloader', __METHOD__ . ": failed to update DB: $e" );
-               }
+               $this->saveFileDependencies( $context->getSkin(), $this->localFileRefs );
+
                return $styles;
        }
 
index 376b62c..80c8220 100644 (file)
@@ -374,12 +374,13 @@ abstract class ResourceLoaderModule {
 
        /**
         * Get the files this module depends on indirectly for a given skin.
-        * Currently these are only image files referenced by the module's CSS.
+        *
+        * These are only image files referenced by the module's stylesheet.
         *
         * @param string $skin Skin name
         * @return array List of files
         */
-       public function getFileDependencies( $skin ) {
+       protected function getFileDependencies( $skin ) {
                // Try in-object cache first
                if ( isset( $this->fileDeps[$skin] ) ) {
                        return $this->fileDeps[$skin];
@@ -405,8 +406,11 @@ abstract class ResourceLoaderModule {
        }
 
        /**
-        * Set preloaded file dependency information. Used so we can load this
-        * information for all modules at once.
+        * Set in-object cache for file dependencies.
+        *
+        * This is used to retrieve data in batches. See ResourceLoader::preloadModuleInfo().
+        * To save the data, use saveFileDependencies().
+        *
         * @param string $skin Skin name
         * @param array $deps Array of file names
         */
@@ -414,6 +418,31 @@ abstract class ResourceLoaderModule {
                $this->fileDeps[$skin] = $deps;
        }
 
+       /**
+        * Set the files this module depends on indirectly for a given skin.
+        *
+        * @since 1.26
+        * @param string $skin Skin name
+        * @param array $localFileRefs List of files
+        */
+       protected function saveFileDependencies( $skin, $localFileRefs ) {
+               try {
+                       // If the list has been modified since last time we cached it, update the cache
+                       if ( $localFileRefs !== $this->getFileDependencies( $skin ) ) {
+                               $dbw = wfGetDB( DB_MASTER );
+                               $dbw->replace( 'module_deps',
+                                       array( array( 'md_module', 'md_skin' ) ), array(
+                                               'md_module' => $this->getName(),
+                                               'md_skin' => $skin,
+                                               'md_deps' => FormatJson::encode( $localFileRefs ),
+                                       )
+                               );
+                       }
+               } catch ( Exception $e ) {
+                       wfDebugLog( 'resourceloader', __METHOD__ . ": failed to update DB: $e" );
+               }
+       }
+
        /**
         * Get the last modification timestamp of the messages in this module for a given language.
         * @param string $lang Language code
@@ -445,8 +474,10 @@ abstract class ResourceLoaderModule {
        }
 
        /**
-        * Set a preloaded message blob last modification timestamp. Used so we
-        * can load this information for all modules at once.
+        * Set in-object cache for message blob time.
+        *
+        * This is used to retrieve data in batches. See ResourceLoader::preloadModuleInfo().
+        *
         * @param string $lang Language code
         * @param int $mtime UNIX timestamp
         */
index 95631f8..029919c 100644 (file)
@@ -113,9 +113,9 @@ class MediaWikiSite extends Site {
                        return $t->getPrefixedText();
                } else {
 
-                       // Make sure the string is normalized into NFC (due to the bug 40017)
+                       // Make sure the string is normalized into NFC (due to T42017)
                        // but do nothing to the whitespaces, that should work appropriately.
-                       // @see https://bugzilla.wikimedia.org/show_bug.cgi?id=40017
+                       // @see https://phabricator.wikimedia.org/T42017
                        $pageName = UtfNormal\Validator::cleanUp( $pageName );
 
                        // Build the args for the specific call
index 21f1194..ee78a61 100644 (file)
@@ -1380,7 +1380,7 @@ class LoginForm extends SpecialPage {
 
                if ( $this->mType == 'signup' ) {
                        // XXX hack pending RL or JS parse() support for complex content messages
-                       // https://bugzilla.wikimedia.org/show_bug.cgi?id=25349
+                       // https://phabricator.wikimedia.org/T27349
                        $out->addJsConfigVars( 'wgCreateacctImgcaptchaHelp',
                                $this->msg( 'createacct-imgcaptcha-help' )->parse() );
 
index 4f8e0b1..89341ea 100644 (file)
@@ -93,22 +93,19 @@ class AvroValidator {
                        }
                        $errors = array();
                        foreach ($datum as $d) {
-                               $result = $this->validate( $schema->items(), $d );
+                               $result = self::getErrors( $schema->items(), $d );
                                if ( $result ) {
                                        $errors[] = $result;
                                }
                        }
-                       if ( $errors ) {
-                               return $errors;
-                       }
-                       return array();
+                       return $errors;
                case AvroSchema::MAP_SCHEMA:
                        if (!is_array($datum)) {
                                return self::wrongType( 'array', $datum );
                        }
                        $errors = array();
                        foreach ($datum as $k => $v) {
-                       if ( !is_string($k) ) {
+                               if ( !is_string($k) ) {
                                        $errors[] = self::wrongType( 'string key', $k );
                                }
                                $result = self::getErrors( $schema->values(), $v );
index e6baac0..be97d83 100644 (file)
@@ -2680,7 +2680,7 @@ class Language {
                # Even with //IGNORE iconv can whine about illegal characters in
                # *input* string. We just ignore those too.
                # REF: http://bugs.php.net/bug.php?id=37166
-               # REF: https://bugzilla.wikimedia.org/show_bug.cgi?id=16885
+               # REF: https://phabricator.wikimedia.org/T18885
                MediaWiki\suppressWarnings();
                $text = iconv( $in, $out . '//IGNORE', $string );
                MediaWiki\restoreWarnings();
index a81f17f..5a14003 100644 (file)
        'nv' => 'Diné bizaad', # Navajo
        'ny' => 'Chi-Chewa',    # Chichewa
        'oc' => 'occitan',              # Occitan
+       'olo' => 'Livvinкarjala',              # Livvi-Karelian
        'om' => 'Oromoo',               # Oromo
        'or' => 'ଓଡ଼ିଆ',              # Oriya
        'os' => 'Ирон', # Ossetic, bug 29091
index 2b6bd58..a2c308d 100644 (file)
        "nstab-template": "Шапхъэ",
        "nstab-help": "IэпыIэгъу нэкIубгъу",
        "nstab-category": "Категорие",
+       "mainpage-nstab": "НэкӀубгъо шъхьаӀ",
        "nosuchaction": "Ащ фэдэ шIагъэ щыIэп",
        "nosuchspecialpage": "Афэдэ специал нэкIубгъо щыIэп",
        "error": "Къончагъэ",
        "cannotdelete-title": "НэкIубгъоу \"$1\" тегъэкIыгъэн лъэкIырэп",
        "badtitle": "ЦӀэ дэгъуэп",
        "badtitletext": "УзкIэупчIэрэ нэкIубгъом ыцIэр къуанчэ, е нэкIы, е бзэзэпыщэ е интервики гъэнэфагъэп.\nМыхъущт символ агъэфедагъэнкIи мэхъу.",
+       "title-invalid-characters": "УзыкIэупчIэрэ нэкIубгъуацIэм символ фыкъуагъэ хэт: \"$1\".",
        "viewsource": "Еплъ лъапсэм",
        "viewsource-title": "Еплъ лъапсэм $1 пае",
        "protectedpagetext": "ЕIэзэнхэм ыкIи нэмыкI шIэнмэ яягъэ къэмыкIынэу мы нэкIубгъор ухъумагъэу щыт.",
        "noname": "НэбгырацIэ тэрэз итхагъэп.",
        "loginsuccesstitle": "ШIоу ухэхьагъ",
        "nouserspecified": "НэбгырацIэр птхын фае.",
+       "login-userblocked": "Мы нэбгырэр блокыгъэ. Системэм хэхьашъущтэп.",
        "wrongpassword": "ШъэфгущыIэр тэрэзэп.\nДжыри зэ еплъ.",
        "wrongpasswordempty": "ШъэфгущыIэр нэкIы.\nДжыри зэ еплъ.",
        "passwordtooshort": "ШъэфгущыIэр мыхъуми {{PLURAL:$1|1 символ |символ $1}} хъун фае.",
        "passwordreset-emailsent": "ШъэфгущыIэм и зэтедзым пае емэйл агъэхьыгъ.",
        "passwordreset-emailsent-capture": "ШъэфгущыIэм изэтедз фэгъэхьыгъэ емэйлыр гъахьыгъэ, ычIэгъкIэ ар олъэгъу.",
        "changeemail": "Зэблэхъу емэйл адресыр",
+       "changeemail-no-info": "Мы нэкIубгъом занкIэу укIонэу уфаемэ, системэм ухэхьэгъэн фае.",
        "changeemail-oldemail": "Джырэ емэйл адрес:",
        "changeemail-newemail": "Емэйл адресыкIэр:",
        "changeemail-none": "(зи)",
        "upload-misc-error": "ЗэхэмышIыкIыгъэ илъхьан фыкъуагъэ",
        "upload-http-error": "HTTP фыкъуагъэ горэ хъугъэ: $1",
        "upload-dialog-title": "Файлыр илъхь",
-       "upload-dialog-error": "Фыкъуагъэ горэ хъугъэ",
        "upload-dialog-button-cancel": "Ыуж икӀ",
        "upload-dialog-button-done": "ЗэшIуэкIыгъэ",
        "upload-dialog-button-save": "Итх",
        "upload-dialog-button-upload": "Илъхь",
-       "upload-dialog-label-select-file": "Къыхэх файл",
-       "upload-dialog-label-infoform-title": "Къэбар",
-       "upload-dialog-label-infoform-name": "ЦIэ",
-       "upload-dialog-label-infoform-description": "АгурыбгъэIон",
-       "upload-dialog-label-usage-title": "Гъэфедэныгъэ",
-       "upload-dialog-label-usage-filename": "ФайлыцIэ",
+       "upload-process-error": "Фыкъуагъэ горэ хъугъэ",
+       "upload-form-label-select-file": "Къыхэх файл",
+       "upload-form-label-infoform-title": "Къэбар",
+       "upload-form-label-infoform-name": "ЦIэ",
+       "upload-form-label-infoform-description": "АгурыбгъэIон",
+       "upload-form-label-usage-title": "Гъэфедэныгъэ",
+       "upload-form-label-usage-filename": "ФайлыцIэ",
        "backend-fail-notexists": "Файлэу $1 щыIэп.",
        "backend-fail-delete": "Файлэу \"$1\" тегъэкIын лъэкIырэп.",
        "backend-fail-read": "Файлэу \"$1\" еплъын лъэкIырэп.",
index f2ee892..8835795 100644 (file)
        "upload-http-error": "'n HTTP-fout het voorgekom: $1",
        "upload-copy-upload-invalid-domain": "Gekopieerde oplaaie word nie vanuit die domein toegelaat nie.",
        "upload-dialog-title": "Laai lêer op",
-       "upload-dialog-error": "'n Fout het voorgekom",
-       "upload-dialog-warning": "'n Waarskuwing is uitgereik",
        "upload-dialog-button-cancel": "Kanselleer",
        "upload-dialog-button-done": "Gedoen",
        "upload-dialog-button-save": "Stoor",
        "upload-dialog-button-upload": "Oplaai",
-       "upload-dialog-label-select-file": "Kies lêer",
-       "upload-dialog-label-infoform-title": "Details",
-       "upload-dialog-label-infoform-name": "Naam",
-       "upload-dialog-label-infoform-description": "Beskrywing",
-       "upload-dialog-label-usage-title": "Gebruik",
-       "upload-dialog-label-usage-filename": "Lêernaam",
+       "upload-process-error": "'n Fout het voorgekom",
+       "upload-process-warning": "'n Waarskuwing is uitgereik",
+       "upload-form-label-select-file": "Kies lêer",
+       "upload-form-label-infoform-title": "Details",
+       "upload-form-label-infoform-name": "Naam",
+       "upload-form-label-infoform-description": "Beskrywing",
+       "upload-form-label-usage-title": "Gebruik",
+       "upload-form-label-usage-filename": "Lêernaam",
        "backend-fail-stream": "Kon nie die lêer $1 uitstroom nie.",
        "backend-fail-backup": "Kon nie 'n rugsteunkopie van die lêer $1 maak nie.",
        "backend-fail-notexists": "Die lêer $1 bestaan nie.",
index 11bf0a2..ba6e341 100644 (file)
        "upload-http-error": "صودف خطأ HTTP: $1",
        "upload-copy-upload-invalid-domain": "رفع النسخ غير متاح من هذا الموقع",
        "upload-dialog-title": "رفع الملف",
-       "upload-dialog-error": "حدث خطأ",
-       "upload-dialog-warning": "حدث تنبيه",
        "upload-dialog-button-cancel": "إلغاء",
        "upload-dialog-button-done": "تم",
        "upload-dialog-button-save": "احفظ",
        "upload-dialog-button-upload": "رفع",
-       "upload-dialog-label-select-file": "اختر ملفا",
-       "upload-dialog-label-infoform-title": "التفاصيل",
-       "upload-dialog-label-infoform-name": "الاسم",
-       "upload-dialog-label-infoform-description": "الوصف",
-       "upload-dialog-label-usage-title": "الاستخدام",
-       "upload-dialog-label-usage-filename": "اسم الملف",
+       "upload-process-error": "حدث خطأ",
+       "upload-process-warning": "حدث تنبيه",
+       "upload-form-label-select-file": "اختر ملفا",
+       "upload-form-label-infoform-title": "التفاصيل",
+       "upload-form-label-infoform-name": "الاسم",
+       "upload-form-label-infoform-description": "الوصف",
+       "upload-form-label-usage-title": "الاستخدام",
+       "upload-form-label-usage-filename": "اسم الملف",
        "backend-fail-stream": "لا يمكن عرض الملف $1.",
        "backend-fail-backup": "لا يمكن صنع نسخة أحتياطية للملف $1.",
        "backend-fail-notexists": "الملف $1 غير موجود.",
index e183181..d55e744 100644 (file)
        "upload-http-error": "এটা HTTP ত্ৰুটিয়ে দেখা দিছে: $1",
        "upload-copy-upload-invalid-domain": "এই ডমেইনত কপী আপল'ড নাপাব।",
        "upload-dialog-title": "ফাইল আপল’ড কৰক",
-       "upload-dialog-error": "এটা ত্ৰুটি পোৱা গৈছে",
-       "upload-dialog-warning": "এটা সতৰ্কবাণী পোৱা গৈছে",
        "upload-dialog-button-cancel": "বাতিল কৰক",
        "upload-dialog-button-done": "কৰা হ’ল",
        "upload-dialog-button-save": "সাঁচি থওক",
        "upload-dialog-button-upload": "আপল'ড",
-       "upload-dialog-label-select-file": "ফাইল নিৰ্বাচন কৰক",
-       "upload-dialog-label-infoform-title": "বিস্তাৰিত",
-       "upload-dialog-label-infoform-name": "নাম",
-       "upload-dialog-label-infoform-description": "বিৱৰণ",
-       "upload-dialog-label-usage-title": "ব্যৱহাৰ",
-       "upload-dialog-label-usage-filename": "ফাইলৰ নাম",
+       "upload-process-error": "এটা ত্ৰুটি পোৱা গৈছে",
+       "upload-process-warning": "এটা সতৰ্কবাণী পোৱা গৈছে",
+       "upload-form-label-select-file": "ফাইল নিৰ্বাচন কৰক",
+       "upload-form-label-infoform-title": "বিস্তাৰিত",
+       "upload-form-label-infoform-name": "নাম",
+       "upload-form-label-infoform-description": "বিৱৰণ",
+       "upload-form-label-usage-title": "ব্যৱহাৰ",
+       "upload-form-label-usage-filename": "ফাইলৰ নাম",
        "backend-fail-stream": "$1 ফাইলটো ষ্ট্ৰীম কৰিব পৰা নগ'ল।",
        "backend-fail-backup": "$1 ফাইলটো বেকআপ্‌ কৰিব পৰা নগ'ল।",
        "backend-fail-notexists": "$1 ফাইলটোৰ কোনো অস্তিত্ব নাই।",
index 76940e6..4e6f970 100644 (file)
        "upload-http-error": "Hebo un error HTTP: $1",
        "upload-copy-upload-invalid-domain": "La xubida de copies nun ta disponible dende esti dominiu.",
        "upload-dialog-title": "Xubir ficheru",
-       "upload-dialog-error": "Hebo un error",
-       "upload-dialog-warning": "Hebo un avisu",
        "upload-dialog-button-cancel": "Encaboxar",
        "upload-dialog-button-done": "Fecho",
        "upload-dialog-button-save": "Guardar",
        "upload-dialog-button-upload": "Xubir",
-       "upload-dialog-label-select-file": "Seleiciona un ficheru",
-       "upload-dialog-label-infoform-title": "Detalles",
-       "upload-dialog-label-infoform-name": "Nome",
-       "upload-dialog-label-infoform-description": "Descripción",
-       "upload-dialog-label-usage-title": "Usu",
-       "upload-dialog-label-usage-filename": "Nome del ficheru",
+       "upload-process-error": "Hebo un error",
+       "upload-process-warning": "Hebo un avisu",
+       "upload-form-label-select-file": "Seleiciona un ficheru",
+       "upload-form-label-infoform-title": "Detalles",
+       "upload-form-label-infoform-name": "Nome",
+       "upload-form-label-infoform-description": "Descripción",
+       "upload-form-label-usage-title": "Usu",
+       "upload-form-label-usage-filename": "Nome del ficheru",
        "backend-fail-stream": "Nun se pudo tresmitir el ficheru $1.",
        "backend-fail-backup": "Nun se pudo facer copia de seguridá del ficheru $1.",
        "backend-fail-notexists": "El ficheru $1 nun esiste.",
index 9155990..6c6176d 100644 (file)
        "upload-http-error": "Узьнікла памылка HTTP: $1",
        "upload-copy-upload-invalid-domain": "Капіяваньне загрузак не дазволенае ў гэтым дамэне.",
        "upload-dialog-title": "Загрузка файла",
-       "upload-dialog-error": "Адбылася памылка",
-       "upload-dialog-warning": "Зьявілася папярэджаньне",
        "upload-dialog-button-cancel": "Адмяніць",
        "upload-dialog-button-done": "Зроблена",
        "upload-dialog-button-save": "Захаваць",
        "upload-dialog-button-upload": "Загрузіць",
-       "upload-dialog-label-select-file": "Абраць файл",
-       "upload-dialog-label-infoform-title": "Падрабязнасьці",
-       "upload-dialog-label-infoform-name": "Назва",
-       "upload-dialog-label-infoform-description": "Апісаньне",
-       "upload-dialog-label-usage-title": "Выкарыстаньне",
-       "upload-dialog-label-usage-filename": "Назва файлу",
+       "upload-process-error": "Адбылася памылка",
+       "upload-process-warning": "Зьявілася папярэджаньне",
+       "upload-form-label-select-file": "Абраць файл",
+       "upload-form-label-infoform-title": "Падрабязнасьці",
+       "upload-form-label-infoform-name": "Назва",
+       "upload-form-label-infoform-description": "Апісаньне",
+       "upload-form-label-usage-title": "Выкарыстаньне",
+       "upload-form-label-usage-filename": "Назва файлу",
        "backend-fail-stream": "Немагчыма накіраваць файл $1.",
        "backend-fail-backup": "Немагчыма зрабіць рэзэрвовую копію файла $1.",
        "backend-fail-notexists": "Файл $1 не існуе.",
        "filerevert-legend": "Вярнуць папярэднюю вэрсію файла",
        "filerevert-intro": "Вы вяртаеце '''[[Media:$1|$1]]''' да [вэрсіі $4 ад $3, $2].",
        "filerevert-comment": "Прычына:",
-       "filerevert-defaultcomment": "Вернутая вэрсія ад $2, $1",
+       "filerevert-defaultcomment": "Вернутая вэрсія ад $2 $1 ($3)",
        "filerevert-submit": "Вярнуць",
        "filerevert-success": "'''[[Media:$1|$1]]''' быў вернуты да [вэрсіі $4 ад $3, $2].",
        "filerevert-badversion": "Не існуе папярэдняй лякальнай вэрсіі гэтага файла з пазначанай датай.",
index 9467810..92a1404 100644 (file)
        "upload-file-error": "इंटरनल खराबी",
        "upload-misc-error": "नामालूम अपलोड खराबी",
        "upload-dialog-title": "फाइल अपलोड",
-       "upload-dialog-error": "कौनो खराबी आ गइल",
-       "upload-dialog-warning": "कौनो चेतावनी बा",
        "upload-dialog-button-cancel": "कैंसिल",
        "upload-dialog-button-done": "पूरा भइल",
        "upload-dialog-button-save": "सहेजीं",
        "upload-dialog-button-upload": "अपलोड",
-       "upload-dialog-label-select-file": "फाइल चुनीं",
-       "upload-dialog-label-infoform-title": "डिटेल जानकारी",
-       "upload-dialog-label-infoform-name": "नाँव",
-       "upload-dialog-label-infoform-description": "विवरण",
-       "upload-dialog-label-usage-title": "इस्तेमाल",
-       "upload-dialog-label-usage-filename": "फाइल नाँव",
+       "upload-process-error": "कौनो खराबी आ गइल",
+       "upload-process-warning": "कौनो चेतावनी बा",
+       "upload-form-label-select-file": "फाइल चुनीं",
+       "upload-form-label-infoform-title": "डिटेल जानकारी",
+       "upload-form-label-infoform-name": "नाँव",
+       "upload-form-label-infoform-description": "विवरण",
+       "upload-form-label-usage-title": "इस्तेमाल",
+       "upload-form-label-usage-filename": "फाइल नाँव",
        "backend-fail-stream": "फाइल \"$1\" स्ट्रीम ना हो पावल।",
        "backend-fail-backup": "फाइल \"$1\" के बैकअप ना हो पावल।",
        "backend-fail-notexists": "फाइल $1 मौजूद नइखे।",
index c88085a..48e7351 100644 (file)
        "upload-http-error": "একটি এইচটিটিপি ত্রুটি দেখা দিয়েছে: $1",
        "upload-copy-upload-invalid-domain": "এই ডোমেইন থেকে আপলোড সম্ভব নয়।",
        "upload-dialog-title": "ফাইল আপলোড করুন",
-       "upload-dialog-error": "একটি ত্রুটি দেখা দিয়েছে",
-       "upload-dialog-warning": "একটি সতর্কবার্তা দেখা দিয়েছে",
        "upload-dialog-button-cancel": "বাতিল",
        "upload-dialog-button-done": "সম্পন্ন",
        "upload-dialog-button-save": "সংরক্ষণ",
        "upload-dialog-button-upload": "আপলোড",
-       "upload-dialog-label-select-file": "ফাইল নির্বাচন করুন",
-       "upload-dialog-label-infoform-title": "বিস্তারিত",
-       "upload-dialog-label-infoform-name": "নাম",
-       "upload-dialog-label-infoform-description": "বিবরণ",
-       "upload-dialog-label-usage-title": "ব্যবহার",
-       "upload-dialog-label-usage-filename": "ফাইলের নাম",
+       "upload-process-error": "একটি ত্রুটি দেখা দিয়েছে",
+       "upload-process-warning": "একটি সতর্কবার্তা দেখা দিয়েছে",
+       "upload-form-label-select-file": "ফাইল নির্বাচন করুন",
+       "upload-form-label-infoform-title": "বিস্তারিত",
+       "upload-form-label-infoform-name": "নাম",
+       "upload-form-label-infoform-description": "বিবরণ",
+       "upload-form-label-usage-title": "ব্যবহার",
+       "upload-form-label-usage-filename": "ফাইলের নাম",
        "backend-fail-stream": "\"$1\" ফাইলের স্ট্রিম দেখানো যাচ্ছে না।",
        "backend-fail-backup": "\"$1\" ফাইলের ব্যাকআপ তৈরী সম্ভব নয়।",
        "backend-fail-notexists": "\"$1\" নামের কোনো ফাইল নেই।",
index ac591c9..5007e73 100644 (file)
        "upload-http-error": "Ha ocorregut un error HTTP: $1",
        "upload-copy-upload-invalid-domain": "Les càrregues de còpia no són disponibles des d'aquest domini.",
        "upload-dialog-title": "Carrega un fitxer",
-       "upload-dialog-error": "S’ha produït un error",
-       "upload-dialog-warning": "S'ha produït un avís",
        "upload-dialog-button-cancel": "Cancel·la",
        "upload-dialog-button-done": "Fet",
        "upload-dialog-button-save": "Desa",
        "upload-dialog-button-upload": "Carrega",
-       "upload-dialog-label-select-file": "Seleccioneu fitxer",
-       "upload-dialog-label-infoform-title": "Detalls",
-       "upload-dialog-label-infoform-name": "Nom",
-       "upload-dialog-label-infoform-description": "Descripció",
-       "upload-dialog-label-usage-title": "Ús",
-       "upload-dialog-label-usage-filename": "Nom del fitxer",
+       "upload-process-error": "S’ha produït un error",
+       "upload-process-warning": "S'ha produït un avís",
+       "upload-form-label-select-file": "Seleccioneu fitxer",
+       "upload-form-label-infoform-title": "Detalls",
+       "upload-form-label-infoform-name": "Nom",
+       "upload-form-label-infoform-description": "Descripció",
+       "upload-form-label-usage-title": "Ús",
+       "upload-form-label-usage-filename": "Nom del fitxer",
        "backend-fail-stream": "No s'ha pogut transmetre el fitxer $1.",
        "backend-fail-backup": "No s'ha pogut fer una còpia de seguretat del fitxer $1.",
        "backend-fail-notexists": "El fitxer $1 no existeix.",
index f2de5d0..795fd4a 100644 (file)
        "createacct-captcha": "Bezpečnostní kontrola",
        "createacct-imgcaptcha-ph": "Opište výše zobrazený text",
        "createacct-submit": "Vytvořit účet",
-       "createacct-another-submit": "Vytvořit jiný účet",
+       "createacct-another-submit": "Vytvořit účet",
        "createacct-benefit-heading": "{{grammar:4sg|{{SITENAME}}}} tvoří lidé jako vy.",
        "createacct-benefit-body1": "{{PLURAL:$1|editace|editace|editací}}",
        "createacct-benefit-body2": "{{PLURAL:$1|stránka|stránky|stránek}}",
        "permissionserrorstext-withaction": "Z {{PLURAL:$1|následujícího důvodu|následujících důvodů}} nemáte oprávnění $2:",
        "recreate-moveddeleted-warn": "'''Upozornění: Pokoušíte se znovuzaložit stránku, která byla v minulosti smazána.'''\n\nZvažte, zda je vhodné v editaci této stránky pokračovat.\nNíže vidíte soupis přesunů a smazání této stránky:",
        "moveddeleted-notice": "Tato stránka byla smazána.\nPodrobnosti si můžete prohlédnout v níže zobrazeném seznamu provedených přesunů a smazání této stránky.",
+       "moveddeleted-notice-recent": "Omlouváme se, ale tato stránka byla nedávno (v posledních 24 hodinách) smazána. Pro úplnost je níže zobrazen soupis přesunů a smazání této stránky.",
        "log-fulllog": "Zobrazit všechny záznamy",
        "edit-hook-aborted": "Editace byla bez bližšího vysvětlení zrušena přípojným bodem.",
        "edit-gone-missing": "Stránku se nepodařilo aktualizovat.\nZřejmě byla smazána.",
        "group-bot": "Boti",
        "group-sysop": "Správci",
        "group-bureaucrat": "Byrokraté",
-       "group-suppress": "Dohlížitelé",
+       "group-suppress": "Utajovatelé",
        "group-all": "(všichni)",
        "group-user-member": "{{GENDER:$1|uživatel|uživatelka|uživatel}}",
        "group-autoconfirmed-member": "automaticky {{GENDER:$1|schválený uživatel|schválená uživatelka|schválený uživatel}}",
        "group-bot-member": "{{GENDER:$1|bot|botka|bot}}",
        "group-sysop-member": "{{GENDER:$1|správce|správkyně|správce}}",
        "group-bureaucrat-member": "{{GENDER:$1|byrokrat|byrokratka|byrokrat}}",
-       "group-suppress-member": "{{GENDER:$1|dohlížitel|dohlížitelka|dohlížitel}}",
+       "group-suppress-member": "{{GENDER:$1|utajovatel|utajovatelka|utajovatel}}",
        "grouppage-user": "{{ns:project}}:Uživatelé",
        "grouppage-autoconfirmed": "{{ns:project}}:Automaticky schválení uživatelé",
        "grouppage-bot": "{{ns:project}}:Boti",
        "grouppage-sysop": "{{ns:project}}:Správci",
        "grouppage-bureaucrat": "{{ns:project}}:Byrokraté",
-       "grouppage-suppress": "{{ns:project}}:Dohlížitelé",
+       "grouppage-suppress": "{{ns:project}}:Utajovatelé",
        "right-read": "Čtení stránek",
        "right-edit": "Editace stránek",
        "right-createpage": "Zakládání stránek (které nejsou diskusní)",
        "upload-http-error": "Došlo k chybě HTTP: $1",
        "upload-copy-upload-invalid-domain": "Načítání kopírováním není dostupné z této domény.",
        "upload-dialog-title": "Načtení souboru",
-       "upload-dialog-error": "Došlo k chybě",
-       "upload-dialog-warning": "Objevilo se upozornění",
        "upload-dialog-button-cancel": "Storno",
        "upload-dialog-button-done": "Hotovo",
        "upload-dialog-button-save": "Uložit",
        "upload-dialog-button-upload": "Načíst",
-       "upload-dialog-label-select-file": "Výběr souboru",
-       "upload-dialog-label-infoform-title": "Podrobnosti",
-       "upload-dialog-label-infoform-name": "Název",
-       "upload-dialog-label-infoform-description": "Popis",
-       "upload-dialog-label-usage-title": "Použití",
-       "upload-dialog-label-usage-filename": "Jméno souboru",
+       "upload-process-error": "Došlo k chybě",
+       "upload-process-warning": "Objevilo se upozornění",
+       "upload-form-label-select-file": "Výběr souboru",
+       "upload-form-label-infoform-title": "Podrobnosti",
+       "upload-form-label-infoform-name": "Název",
+       "upload-form-label-infoform-description": "Popis",
+       "upload-form-label-usage-title": "Použití",
+       "upload-form-label-usage-filename": "Jméno souboru",
        "backend-fail-stream": "Soubor $1 nelze streamovat.",
        "backend-fail-backup": "Soubor $1 nelze zazálohovat.",
        "backend-fail-notexists": "Soubor $1 neexistuje.",
        "filerevert-legend": "Vrátit zpět soubor",
        "filerevert-intro": "Vracíte zpět '''[[Media:$1|$1]]''' na [$4 verzi z $3 $2].",
        "filerevert-comment": "Důvod:",
-       "filerevert-defaultcomment": "Navrácena verze nahraná v $2 dne $1.",
+       "filerevert-defaultcomment": "Návrat na verzi z $2, $1 ($3)",
        "filerevert-submit": "Vrátit zpět",
        "filerevert-success": "Soubor '''[[Media:$1|$1]]''' byl vrácen zpět na [$4 verzi z $3 $2].",
        "filerevert-badversion": "Není dostupná předchozí verze tohoto souboru s odpovídající časovou značkou.",
        "nopagetext": "Cílová stránka, kterou jste specifikovali, neexistuje.",
        "pager-newer-n": "{{PLURAL:$1|1 novější|$1 novější|$1 novějších}}",
        "pager-older-n": "{{PLURAL:$1|1 starší|$1 starší|$1 starších}}",
-       "suppress": "Dozor",
+       "suppress": "Utajit",
        "querypage-disabled": "Tato speciální stránka je z výkonnostních důvodů vypnuta.",
        "apihelp": "Nápověda k API",
        "apihelp-no-such-module": "Modul „$1“ nebyl nalezen.",
index 89fe6cd..f0bf64e 100644 (file)
        "group-bot": "Bots",
        "group-sysop": "Administratoren",
        "group-bureaucrat": "Bürokraten",
-       "group-suppress": "Oversighter",
+       "group-suppress": "Unterdrücker",
        "group-all": "(alle)",
        "group-user-member": "{{GENDER:$1|Benutzer|Benutzerin}}",
        "group-autoconfirmed-member": "{{GENDER:$1|Automatisch bestätigter Benutzer|Automatisch bestätigte Benutzerin}}",
        "group-bot-member": "Bot",
        "group-sysop-member": "{{GENDER:$1|Administrator|Administratorin}}",
        "group-bureaucrat-member": "{{GENDER:$1|Bürokrat|Bürokratin}}",
-       "group-suppress-member": "{{GENDER:$1|Oversighter|Oversighterin}}",
+       "group-suppress-member": "{{GENDER:$1|Unterdrücker|Unterdrückerin}}",
        "grouppage-user": "{{ns:project}}:Benutzer",
        "grouppage-autoconfirmed": "{{ns:project}}:Automatisch bestätigte Benutzer",
        "grouppage-bot": "{{ns:project}}:Bots",
        "grouppage-sysop": "{{ns:project}}:Administratoren",
        "grouppage-bureaucrat": "{{ns:project}}:Bürokraten",
-       "grouppage-suppress": "{{ns:project}}:Oversighter",
+       "grouppage-suppress": "{{ns:project}}:Unterdrücker",
        "right-read": "Seiten lesen",
        "right-edit": "Seiten bearbeiten",
        "right-createpage": "Seiten erstellen (die keine Diskussionsseiten sind)",
        "upload-http-error": "Ein HTTP-Fehler ist aufgetreten: $1",
        "upload-copy-upload-invalid-domain": "Als Kopie hochladbare Dateien sind über diese Domain nicht verfügbar.",
        "upload-dialog-title": "Datei hochladen",
-       "upload-dialog-error": "Es ist ein Fehler aufgetreten",
-       "upload-dialog-warning": "Es ist eine Warnung aufgetreten",
        "upload-dialog-button-cancel": "Abbrechen",
        "upload-dialog-button-done": "Schließen",
        "upload-dialog-button-save": "Speichern",
        "upload-dialog-button-upload": "Hochladen",
-       "upload-dialog-label-select-file": "Datei auswählen",
-       "upload-dialog-label-infoform-title": "Einzelheiten",
-       "upload-dialog-label-infoform-name": "Name",
-       "upload-dialog-label-infoform-description": "Beschreibung",
-       "upload-dialog-label-usage-title": "Verwendung",
-       "upload-dialog-label-usage-filename": "Dateiname",
+       "upload-process-error": "Es ist ein Fehler aufgetreten",
+       "upload-process-warning": "Es ist eine Warnung aufgetreten",
+       "upload-form-label-select-file": "Datei auswählen",
+       "upload-form-label-infoform-title": "Einzelheiten",
+       "upload-form-label-infoform-name": "Name",
+       "upload-form-label-infoform-description": "Beschreibung",
+       "upload-form-label-usage-title": "Verwendung",
+       "upload-form-label-usage-filename": "Dateiname",
        "backend-fail-stream": "Die Datei $1 konnte nicht übertragen werden.",
        "backend-fail-backup": "Die Datei $1 konnte nicht gesichert werden.",
        "backend-fail-notexists": "Die Datei $1 ist nicht vorhanden.",
        "filerevert-legend": "Datei zurücksetzen",
        "filerevert-intro": "Du setzt die Datei '''[[Media:$1|$1]]''' auf die [$4 Version vom $2, $3 Uhr] zurück.",
        "filerevert-comment": "Grund:",
-       "filerevert-defaultcomment": "Zurückgesetzt auf die Version vom $1, $2 Uhr",
+       "filerevert-defaultcomment": "Zurückgesetzt auf die Version vom $1, $2 Uhr ($3)",
        "filerevert-submit": "Zurücksetzen",
        "filerevert-success": "'''[[Media:$1|$1]]''' wurde auf die [$4 Version vom $2, $3 Uhr] zurückgesetzt.",
        "filerevert-badversion": "Es gibt keine Version der Datei zu dem angegebenen Zeitpunkt.",
        "nopagetext": "Die angegebene Seite ist nicht vorhanden.",
        "pager-newer-n": "{{PLURAL:$1|nächster|nächste $1}}",
        "pager-older-n": "{{PLURAL:$1|vorheriger|vorherige $1}}",
-       "suppress": "Oversight",
+       "suppress": "Unterdrücken",
        "querypage-disabled": "Diese Spezialseite wurde aus Gründen der Leistungserhaltung deaktiviert.",
        "apihelp": "API-Hilfe",
        "apihelp-no-such-module": "Modul „$1“ nicht gefunden.",
        "emailccsubject": "Kopie deiner Nachricht an $1: $2",
        "emailsent": "E-Mail verschickt",
        "emailsenttext": "Deine E-Mail wurde verschickt.",
-       "emailuserfooter": "Diese E-Mail wurde von „$1“ an „$2“ durch die Funktion „{{int:emailuser}}“ bei {{SITENAME}} gesendet.",
+       "emailuserfooter": "Diese E-Mail wurde von „$1“ an „{{GENDER:$2|$2}}“ durch die Funktion „{{int:emailuser}}“ bei {{SITENAME}} {{GENDER:$1|gesendet}}.",
        "usermessage-summary": "Systemnachricht gespeichert.",
        "usermessage-editor": "System-Messenger",
        "usermessage-template": "MediaWiki:Benutzernachricht",
index 76c1aad..88a6a34 100644 (file)
        "fileexists": "यै नामको फाइल पैल्ली नैं छ, यदि तम परिवर्तन गद्या कुरडीमू सुनिश्चित छैनौ भण्या कृपया <strong>[[:$1]]</strong> जाँच गर।\n[[$1|thumb]]",
        "filewasdeleted": "यै नामको एक फाइल पहिली पनि अपलोड गरिबर पछि हटाई सकियाको छ।\nपुनः अपलोड गद्दु पूर्व तम $1 लाई निक्करी जाँच गर ।",
        "upload-dialog-title": "चित्र अपलोड गर",
-       "upload-dialog-error": "गल्ती भयो",
-       "upload-dialog-warning": "सूचना हुनु",
        "upload-dialog-button-cancel": "रद्द",
        "upload-dialog-button-done": "सकियो",
        "upload-dialog-button-save": "सङ्ग्रह गद्या",
        "upload-dialog-button-upload": "अपलोड",
-       "upload-dialog-label-select-file": "फाइल छान",
-       "upload-dialog-label-infoform-title": "विवरण",
-       "upload-dialog-label-infoform-name": "नाऊ",
-       "upload-dialog-label-infoform-description": "बेलिविस्तार",
-       "upload-dialog-label-usage-title": "रिती",
-       "upload-dialog-label-usage-filename": "फाइल नाउ",
+       "upload-process-error": "गल्ती भयो",
+       "upload-process-warning": "सूचना हुनु",
+       "upload-form-label-select-file": "फाइल छान",
+       "upload-form-label-infoform-title": "विवरण",
+       "upload-form-label-infoform-name": "नाऊ",
+       "upload-form-label-infoform-description": "बेलिविस्तार",
+       "upload-form-label-usage-title": "रिती",
+       "upload-form-label-usage-filename": "फाइल नाउ",
        "uploadstash-nofiles": "तमरा कोइ पनि स्टाश गर्याका फाइलहरू नाइथिन् ।",
        "uploadstash-badtoken": "त्यो कार्य असफलभयो , सायद तमरो सम्पादन अधिकार समाप्त भयो । पुन: प्रयास गर ।",
        "uploadstash-refresh": "फाइलहरूको सूची ताजा गर्न्या",
index 9620918..829e363 100644 (file)
        "upload-http-error": "Εμφανίστηκε κάποιο σφάλμα HTTP: $1",
        "upload-copy-upload-invalid-domain": "Δεν υπάρχουν διαθέσιμα ανεβάσματα αντιγράφων από αυτό τον τομέα.",
        "upload-dialog-title": "Ανέβασμα αρχείου",
-       "upload-dialog-error": "Ένα σφάλμα συνέβη",
-       "upload-dialog-warning": "Προέκυψε μία προειδοποίηση",
        "upload-dialog-button-cancel": "Ακύρωση",
        "upload-dialog-button-done": "Ολοκληρώθηκε",
        "upload-dialog-button-save": "Αποθήκευση",
        "upload-dialog-button-upload": "Ανέβασμα",
-       "upload-dialog-label-select-file": "Επιλογή αρχείου",
-       "upload-dialog-label-infoform-title": "Λεπτομέρειες",
-       "upload-dialog-label-infoform-name": "Όνομα",
-       "upload-dialog-label-infoform-description": "Περιγραφή",
-       "upload-dialog-label-usage-title": "Χρήση",
-       "upload-dialog-label-usage-filename": "Όνομα αρχείου",
+       "upload-process-error": "Ένα σφάλμα συνέβη",
+       "upload-process-warning": "Προέκυψε μία προειδοποίηση",
+       "upload-form-label-select-file": "Επιλογή αρχείου",
+       "upload-form-label-infoform-title": "Λεπτομέρειες",
+       "upload-form-label-infoform-name": "Όνομα",
+       "upload-form-label-infoform-description": "Περιγραφή",
+       "upload-form-label-usage-title": "Χρήση",
+       "upload-form-label-usage-filename": "Όνομα αρχείου",
        "backend-fail-stream": "Αδύνατη η μετάδοση του αρχείου $1.",
        "backend-fail-backup": "Αδύνατη η δημιουργία αντίγραφου ασφαλείας του αρχείου $1.",
        "backend-fail-notexists": "Το αρχείο $1 δεν υπάρχει.",
index a33517c..3fc297c 100644 (file)
        "upload-http-error": "An HTTP error occurred: $1",
        "upload-copy-upload-invalid-domain": "Copy uploads are not available from this domain.",
        "upload-dialog-title": "Upload file",
-       "upload-dialog-error": "An error occurred",
-       "upload-dialog-warning": "A warning occurred",
        "upload-dialog-button-cancel": "Cancel",
        "upload-dialog-button-done": "Done",
        "upload-dialog-button-save": "Save",
        "upload-dialog-button-upload": "Upload",
-       "upload-dialog-label-select-file": "Select file",
-       "upload-dialog-label-infoform-title": "Details",
-       "upload-dialog-label-infoform-name": "Name",
-       "upload-dialog-label-infoform-description": "Description",
-       "upload-dialog-label-usage-title": "Usage",
-       "upload-dialog-label-usage-filename": "File name",
+       "upload-process-error": "An error occurred",
+       "upload-process-warning": "A warning occurred",
+       "upload-form-label-select-file": "Select file",
+       "upload-form-label-infoform-title": "Details",
+       "upload-form-label-infoform-name": "Name",
+       "upload-form-label-infoform-description": "Description",
+       "upload-form-label-usage-title": "Usage",
+       "upload-form-label-usage-filename": "File name",
        "backend-fail-stream": "Could not stream file \"$1\".",
        "backend-fail-backup": "Could not backup file \"$1\".",
        "backend-fail-notexists": "The file $1 does not exist.",
        "emailccsubject": "Copy of your message to $1: $2",
        "emailsent": "Email sent",
        "emailsenttext": "Your email message has been sent.",
-       "emailuserfooter": "This email was sent by $1 to $2 by the \"{{int:emailuser}}\" function at {{SITENAME}}.",
+       "emailuserfooter": "This email was {{GENDER:$1|sent}} by $1 to {{GENDER:$2|$2}} by the \"{{int:emailuser}}\" function at {{SITENAME}}.",
        "usermessage-summary": "Leaving system message.",
        "usermessage-editor": "System messenger",
        "usermessage-template": "MediaWiki:UserMessage",
index 2dd6ab0..bd7c068 100644 (file)
        "upload-http-error": "Ha ocurrido un error HTTP: $1",
        "upload-copy-upload-invalid-domain": "No se pueden realizar subidas remotas desde este dominio.",
        "upload-dialog-title": "Subir archivo",
-       "upload-dialog-error": "Ha ocurrido un error",
-       "upload-dialog-warning": "Ha ocurrido una advertencia",
        "upload-dialog-button-cancel": "Cancelar",
        "upload-dialog-button-done": "Hecho",
        "upload-dialog-button-save": "Guardar",
        "upload-dialog-button-upload": "Subir",
-       "upload-dialog-label-select-file": "Seleccionar archivo",
-       "upload-dialog-label-infoform-title": "Detalles",
-       "upload-dialog-label-infoform-name": "Nombre",
-       "upload-dialog-label-infoform-description": "Descripción",
-       "upload-dialog-label-usage-title": "Uso",
-       "upload-dialog-label-usage-filename": "Nombre del archivo",
+       "upload-process-error": "Ha ocurrido un error",
+       "upload-process-warning": "Ha ocurrido una advertencia",
+       "upload-form-label-select-file": "Seleccionar archivo",
+       "upload-form-label-infoform-title": "Detalles",
+       "upload-form-label-infoform-name": "Nombre",
+       "upload-form-label-infoform-description": "Descripción",
+       "upload-form-label-usage-title": "Uso",
+       "upload-form-label-usage-filename": "Nombre del archivo",
        "backend-fail-stream": "No se pudo transmitir el archivo «$1».",
        "backend-fail-backup": "No se pudo hacer copia de seguridad del archivo «$1».",
        "backend-fail-notexists": "El archivo  $1  no existe.",
index 65dd24f..6dcb457 100644 (file)
        "upload-http-error": "HTTP-viga: $1",
        "upload-copy-upload-invalid-domain": "Sellest domeenist pole kopeerimise teel üleslaadimine võimalik.",
        "upload-dialog-title": "Faili üleslaadimine",
-       "upload-dialog-error": "Esines tõrge",
-       "upload-dialog-warning": "Esines hoiatus",
        "upload-dialog-button-cancel": "Loobu",
        "upload-dialog-button-done": "Valmis",
        "upload-dialog-button-save": "Salvesta",
        "upload-dialog-button-upload": "Laadi üles",
-       "upload-dialog-label-select-file": "Vali fail",
-       "upload-dialog-label-infoform-title": "Üksikasjad",
-       "upload-dialog-label-infoform-name": "Pealkiri",
-       "upload-dialog-label-infoform-description": "Kirjeldus",
-       "upload-dialog-label-usage-title": "Kasutus",
-       "upload-dialog-label-usage-filename": "Failinimi",
+       "upload-process-error": "Esines tõrge",
+       "upload-process-warning": "Esines hoiatus",
+       "upload-form-label-select-file": "Vali fail",
+       "upload-form-label-infoform-title": "Üksikasjad",
+       "upload-form-label-infoform-name": "Pealkiri",
+       "upload-form-label-infoform-description": "Kirjeldus",
+       "upload-form-label-usage-title": "Kasutus",
+       "upload-form-label-usage-filename": "Failinimi",
        "backend-fail-stream": "Faili $1 ei saanud edastada.",
        "backend-fail-backup": "Faili $1 ei saanud varundada.",
        "backend-fail-notexists": "Faili $1 pole olemas.",
index 79fbcbe..9caf091 100644 (file)
        "nstab-help": "Laguntza orrialdea",
        "nstab-category": "Kategoria",
        "mainpage-nstab": "Azala",
-       "nosuchaction": "Ekintza hori ez da existitizen",
+       "nosuchaction": "Ekintza hori ez da existitzen",
        "nosuchactiontext": "URL bidez zehaztutako ekintza okerra da.\nURLa gaizki idatzi duzu, edo hautsitako lotura jarraitu duzu.\nHonek akatsa indikatzen du {{SITENAME}}-(e)n.",
-       "nosuchspecialpage": "Ez da aparteko orrialde hori existitzen",
+       "nosuchspecialpage": "Orri berezi hori ez existitzen",
        "nospecialpagetext": "<strong>Orri berezi baliogabe bat eskatu duzu.</strong>\n\nBada orri berezien zerrenda bat, [[Special:SpecialPages|{{int:specialpages}}]] orrian.",
        "error": "Errorea",
        "databaseerror": "Datu-base errorea",
        "rev-deleted-text-permission": "Orrialdearen berrikuspen hau '''ezabatua''' izan da.\nXehetasunak [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} ezabaketa erregistroan] ikus daitezke.",
        "rev-deleted-text-unhide": "Orriaren bertsio hau '''ezabatu''' da.\nXehetasunak ikusgai daude [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} ezabatze erregistroan].\nAdministratzailea zarenez, oraindik [$1 bertsio hau ikus dezakezu], nahi izanez gero.",
        "rev-suppressed-text-unhide": "Orriaren bertsio hau '''ezeztatu''' da.\nXehetasunak ikusgai daude [{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGENAMEE}}}} ezeztatze erregistroan].\nAdministratzailea zarenez, oraindik [$1 bertsio hau ikus dezakezu], nahi izanez gero.",
-       "rev-deleted-text-view": "Orrialdearen berrikuspen hau '''ezabatua''' izan da.\nZuk ikusteko aukera daukazu; xehetasunak [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} ezabaketa erregistroan] ikus ditzakezu.",
+       "rev-deleted-text-view": "Orriaren berrikuspen hau '''ezabatua''' izan da.\nZuk ikusteko aukera daukazu; xehetasunak [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} ezabaketa erregistroan] ikus ditzakezu.",
        "rev-suppressed-text-view": "Berrikuspen hau '''ezabatua''' izan da.\nAdministratzaile bezala ikus dezakezu; xehetasun gehiagorako [{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGENAMEE}}}} ezabapen erregistrora joan].",
        "rev-deleted-no-diff": "Ezin duzu ezberdintasun hau ikusi, berrikuspenetako bat '''ezabatua''' izan delako.\nXehetasunak [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} ezabaketa erregistroan] aurki ditzakezu.",
        "rev-suppressed-no-diff": "Ezin duzu ezberdintasunik ikusi berrikuspenen bat '''ezabatua''' izan delako.",
        "upload-http-error": "HTTP errorea gertatu da: $1",
        "upload-copy-upload-invalid-domain": "Domeinu honetan ezin dira igoerak kopiatu.",
        "upload-dialog-title": "Igo fitxategia",
-       "upload-dialog-error": "Errore bat gertatu da",
        "upload-dialog-button-cancel": "Utzi",
        "upload-dialog-button-done": "Egina",
        "upload-dialog-button-save": "Gorde",
        "upload-dialog-button-upload": "Igo",
-       "upload-dialog-label-select-file": "Fitxategia Aukeratu",
-       "upload-dialog-label-infoform-title": "Xehetasunak",
-       "upload-dialog-label-infoform-name": "Izena",
-       "upload-dialog-label-infoform-description": "Deskribapena",
-       "upload-dialog-label-usage-title": "Erabilera",
-       "upload-dialog-label-usage-filename": "Fitxategiaren izena",
+       "upload-process-error": "Errore bat gertatu da",
+       "upload-form-label-select-file": "Fitxategia Aukeratu",
+       "upload-form-label-infoform-title": "Xehetasunak",
+       "upload-form-label-infoform-name": "Izena",
+       "upload-form-label-infoform-description": "Deskribapena",
+       "upload-form-label-usage-title": "Erabilera",
+       "upload-form-label-usage-filename": "Fitxategiaren izena",
        "backend-fail-stream": "Ezin izan da \"$1\" fitxategiaren stream egin.",
        "backend-fail-backup": "Ezin izan da \"$1\" fitxategiaren backup egin.",
        "backend-fail-notexists": "$1 fitxategia ez da existitzen.",
        "undeletedrevisions-files": "{{PLURAL:$1|berrikuspen|berrikuspen}} eta {{PLURAL:$2|fitxategi|fitxategi}} leheneratu dira",
        "undeletedfiles": "{{PLURAL:$1|fitxategi|fitxategi}} leheneratu dira",
        "cannotundelete": "Ezabatutako birgaitzean akatsa: $1",
-       "undeletedpage": "'''$1 leheneratu egin da'''\n\n[[Special:Log/delete|Ezabaketa erregistrora]] jo azken ezabaketa eta leheneraketak ikusteko.",
-       "undelete-header": "Berriki ezabatutako orrialdeak ikusteko [[Special:Log/delete|ezabaketa erregistrora]] jo.",
+       "undeletedpage": "'''«$1» leheneratu da'''\n\nAzken ezabatze eta leheneratzeak ikusteko, jo ezazu [[Special:Log/delete|ezabaketa erregistrora]].",
+       "undelete-header": "Berriki ezabatutako orriak ikusteko, jo ezazu [[Special:Log/delete|ezabaketa erregistrora]].",
        "undelete-search-title": "Ezabatutako orrialdeak bilatu",
        "undelete-search-box": "Ezabatutako orrialdeak bilatu",
        "undelete-search-prefix": "Honela hasten diren orrialdeak erakutsi:",
        "tooltip-ca-nstab-main": "Eduki orrialdea ikusi",
        "tooltip-ca-nstab-user": "Lankide orrialdea ikusi",
        "tooltip-ca-nstab-media": "Media orrialdea ikusi",
-       "tooltip-ca-nstab-special": "Hau aparteko orrialde bat da, ezin duzu orrialdea aldatu.",
+       "tooltip-ca-nstab-special": "Hau orri berezi bat da, ezin duzu orria aldatu.",
        "tooltip-ca-nstab-project": "Proiektuaren orrialdea ikusi",
        "tooltip-ca-nstab-image": "Irudiaren orrialdea ikusi",
        "tooltip-ca-nstab-mediawiki": "Sistemaren mezua ikusi",
        "compare-rev2": "2. berrikuspena",
        "compare-submit": "Alderatu",
        "compare-invalid-title": "Zehaztutako izenburua ez dago zuzen.",
-       "compare-title-not-exists": "Zehazturiko izenburua ez da existitzen.",
+       "compare-title-not-exists": "Adierazi duzun izenburua ez da existitzen.",
        "compare-revision-not-exists": "Zehazturiko berrikuspena ez da existitzen.",
        "dberr-problems": "Barkatu! Webgune honek zailtasun teknikoak jasaten ari da.",
        "dberr-again": "Saiatu pare bat minutu itxaroten edo kargatu ezazu orrialdea berriro.",
index e94a443..a163ddb 100644 (file)
        "upload-http-error": "یک خطای اچ‌تی‌تی‌پی رخ داد: $1",
        "upload-copy-upload-invalid-domain": "بارگذاری کپی پرونده‌ها از این دامنه امکان‌پذیر نیست.",
        "upload-dialog-title": "بارگذاری پرونده",
-       "upload-dialog-error": "يک خطا اتفاق افتاد",
-       "upload-dialog-warning": "یک هشدار رخ‌داد",
        "upload-dialog-button-cancel": "لغو",
        "upload-dialog-button-done": "انجام شد",
        "upload-dialog-button-save": "ذخیره",
        "upload-dialog-button-upload": "بارگذاری",
-       "upload-dialog-label-select-file": "یک فایل انتخاب کنید",
-       "upload-dialog-label-infoform-title": "جزئیات",
-       "upload-dialog-label-infoform-name": "نام",
-       "upload-dialog-label-infoform-description": "توضیحات",
-       "upload-dialog-label-usage-title": "کاربرد",
-       "upload-dialog-label-usage-filename": "نام پرونده",
+       "upload-process-error": "يک خطا اتفاق افتاد",
+       "upload-process-warning": "یک هشدار رخ‌داد",
+       "upload-form-label-select-file": "یک فایل انتخاب کنید",
+       "upload-form-label-infoform-title": "جزئیات",
+       "upload-form-label-infoform-name": "نام",
+       "upload-form-label-infoform-description": "توضیحات",
+       "upload-form-label-usage-title": "کاربرد",
+       "upload-form-label-usage-filename": "نام پرونده",
        "backend-fail-stream": "نمی‌توان پروندهٔ $1 را ارسال کرد.",
        "backend-fail-backup": "نمی‌توان نسخهٔ پشتیبان برای پروندهٔ $1 ایجاد کرد.",
        "backend-fail-notexists": "پروندهٔ $1 وجود ندارد.",
index 3966983..f242172 100644 (file)
        "nstab-template": "Malline",
        "nstab-help": "Ohjesivu",
        "nstab-category": "Luokka",
+       "mainpage-nstab": "Etusivu",
        "nosuchaction": "Toimintoa ei ole olemassa",
        "nosuchactiontext": "URL:ssä määritelty toiminto ei ole kelvollinen.\nOlet saattanut kirjoittaa URL:in väärin tai olet seurannut virheellistä linkkiä.\nKyseessä voi myös mahdollisesti olla virhe sivuston {{SITENAME}} käyttämässä ohjelmistossa.",
        "nosuchspecialpage": "Kyseistä toimintosivua ei ole",
        "changeemail-password": "{{SITENAME}}-salasanasi:",
        "changeemail-submit": "Muuta sähköpostiosoite",
        "changeemail-throttled": "Olet tehnyt liian monta kirjautumisyritystä.\nOdota $1 ennen kuin yrität uudelleen.",
+       "changeemail-nochange": "Anna joku toinen sähköpostiosoite.",
        "resettokens": "Uudista avaimet",
        "resettokens-text": "Tällä sivulla voit uudistaa avaimesi (''eng.'' reset tokens), jotka mahdollistavat pääsyn käyttäjätunnukseesi liittyviin tiettyihin yksityisiin tietoihin.\n\nSinun pitäisi tehdä tämä, jos olet vahingossa jakanut avaimet jonkun kanssa tai jos käyttäjätunnuksesi on vaarannettu.",
        "resettokens-no-tokens": "Avaimia ei ole uudistettavaksi.",
        "permissionserrorstext-withaction": "Sinulla ei ole oikeutta {{lcfirst:$2}} {{PLURAL:$1|seuraavasta syystä|seuraavista syistä}}:",
        "recreate-moveddeleted-warn": "'''Varoitus: Olet luomassa sellaista sivua, joka on aikaisemmin poistettu.'''\n\nHarkitse, kannattaako tätä sivua luoda uudelleen. \nAlla on tämän sivun poisto- ja siirtohistoria:",
        "moveddeleted-notice": "Tämä sivu on poistettu. Alla on tämän sivun poisto- ja siirtohistoria.",
+       "moveddeleted-notice-recent": "Valitettavasti tämä sivu on poistettu aivan äskettäin (viimeisen 24 tunnin aikana).\nAlla näkyy sivun poisto- ja siirtolokin tietoja.",
        "log-fulllog": "Näytä loki kokonaan",
        "edit-hook-aborted": "Laajennuskoodi esti muokkauksen antamatta syytä.",
        "edit-gone-missing": "Sivun päivitys ei onnistunut.\nSe on ilmeisesti poistettu.",
        "upload-http-error": "HTTP-virhe: $1",
        "upload-copy-upload-invalid-domain": "Tiedostojen tallentamista tästä verkko-osoitteesta ei ole sallittu.",
        "upload-dialog-title": "Tiedoston tallennus",
-       "upload-dialog-error": "Tapahtui virhe",
-       "upload-dialog-warning": "Sisältää varoituksen",
        "upload-dialog-button-cancel": "Peru",
        "upload-dialog-button-done": "Valmis",
        "upload-dialog-button-save": "Tallenna",
        "upload-dialog-button-upload": "Tallenna",
-       "upload-dialog-label-select-file": "Valitse tiedosto",
-       "upload-dialog-label-infoform-title": "Yksityiskohdat",
-       "upload-dialog-label-infoform-name": "Nimi",
-       "upload-dialog-label-infoform-description": "Kuvaus",
-       "upload-dialog-label-usage-title": "Käyttö",
-       "upload-dialog-label-usage-filename": "Tiedostonimi",
+       "upload-process-error": "Tapahtui virhe",
+       "upload-process-warning": "Sisältää varoituksen",
+       "upload-form-label-select-file": "Valitse tiedosto",
+       "upload-form-label-infoform-title": "Yksityiskohdat",
+       "upload-form-label-infoform-name": "Nimi",
+       "upload-form-label-infoform-description": "Kuvaus",
+       "upload-form-label-usage-title": "Käyttö",
+       "upload-form-label-usage-filename": "Tiedostonimi",
        "backend-fail-stream": "Tiedoston $1 virtauttaminen epäonnistui.",
        "backend-fail-backup": "Tiedostoa $1 ei voitu varmuuskopioida.",
        "backend-fail-notexists": "Tiedostoa $1 ei ole olemassa.",
        "filerevert-legend": "Tiedoston palautus",
        "filerevert-intro": "Olet palauttamassa takaisin tiedostoa '''[[Media:$1|$1]]''' [$4 versioon, joka luotiin $2 kello $3].",
        "filerevert-comment": "Syy:",
-       "filerevert-defaultcomment": "Palautettiin takaisin versioon, joka luotiin $1 kello $2 (UTC)",
+       "filerevert-defaultcomment": "Palautettiin takaisin versioon, joka tehtiin $1 kello $2 ($3)",
        "filerevert-submit": "Suorita palauttaminen",
        "filerevert-success": "'''[[Media:$1|$1]]''' on palautettu takaisin [$4 versioon, joka luotiin $2 kello $3].",
        "filerevert-badversion": "Tiedostosta ei ole luotu versiota kyseisellä ajan hetkellä.",
        "api-error-badaccess-groups": "Sinulla ei ole oikeutta tallentaa tiedostoja tähän wikiin.",
        "api-error-badtoken": "Sisäinen virhe: virheellinen tarkistussumma.",
        "api-error-copyuploaddisabled": "Tallentaminen URL-osoitteesta ei ole käytössä.",
-       "api-error-duplicate": "Samansisältöisiä tiedostoja löytyi {{PLURAL:$1|[$2 yksi kappale]|[$2 useampia kappaleita]}}.",
+       "api-error-duplicate": "Samansisältöisiä tiedostoja löytyi {{PLURAL:$1|[yksi kappale]|[useampia kappaleita]}}.",
        "api-error-duplicate-archive": "Sivustolla oli aiemmin {{PLURAL:$1|toinen samansisältöinen tiedosto|toisia samansisältöisiä tiedostoja}}, mutta {{PLURAL:$1|se|ne}} poistettiin.",
        "api-error-empty-file": "Määrittämäsi tiedosto on tyhjä.",
        "api-error-emptypage": "Ei ole sallittua luoda uutta, tyhjää sivua.",
index 7eb3b97..0f9d7cb 100644 (file)
        "group-bot": "Robots",
        "group-sysop": "Administrateurs",
        "group-bureaucrat": "Bureaucrates",
-       "group-suppress": "Superviseurs",
+       "group-suppress": "Limitateurs",
        "group-all": "(tous)",
        "group-user-member": "{{GENDER:$1|utilisateur|utilisatrice}}",
        "group-autoconfirmed-member": "{{GENDER:$1|utilisateur enregistré|utilisatrice enregistrée}}",
        "group-bot-member": "{{GENDER:$1|robot}}",
        "group-sysop-member": "{{GENDER:$1|administrateur|administratrice}}",
        "group-bureaucrat-member": "{{GENDER:$1|bureaucrate}}",
-       "group-suppress-member": "{{GENDER:$1|superviseur|superviseuse}}",
+       "group-suppress-member": "{{GENDER:$1|limitateur|limitatrice}}",
        "grouppage-user": "{{ns:project}}:Utilisateurs",
        "grouppage-autoconfirmed": "{{ns:project}}:Utilisateurs enregistrés",
        "grouppage-bot": "{{ns:project}}:Robots",
        "grouppage-sysop": "{{ns:project}}:Administrateurs",
        "grouppage-bureaucrat": "{{ns:project}}:Bureaucrates",
-       "grouppage-suppress": "{{ns:project}}:Superviseurs",
+       "grouppage-suppress": "{{ns:project}}:Suppress",
        "right-read": "Lire les pages",
        "right-edit": "Modifier les pages",
        "right-createpage": "Créer des pages (qui ne sont pas des pages de discussion)",
        "upload-http-error": "Une erreur HTTP est survenue : $1",
        "upload-copy-upload-invalid-domain": "La copie des téléversements n’est pas disponible depuis ce domaine.",
        "upload-dialog-title": "Téléverser un fichier",
-       "upload-dialog-error": "Une erreur est survenue",
-       "upload-dialog-warning": "Un avertissement s’est produit",
        "upload-dialog-button-cancel": "Annuler",
        "upload-dialog-button-done": "Fait",
        "upload-dialog-button-save": "Enregistrer",
        "upload-dialog-button-upload": "Téléverser",
-       "upload-dialog-label-select-file": "Sélectionner un fichier",
-       "upload-dialog-label-infoform-title": "Détails",
-       "upload-dialog-label-infoform-name": "Nom",
-       "upload-dialog-label-infoform-description": "Description",
-       "upload-dialog-label-usage-title": "Utilisation",
-       "upload-dialog-label-usage-filename": "Nom du fichier",
+       "upload-process-error": "Une erreur est survenue",
+       "upload-process-warning": "Un avertissement s’est produit",
+       "upload-form-label-select-file": "Sélectionner un fichier",
+       "upload-form-label-infoform-title": "Détails",
+       "upload-form-label-infoform-name": "Nom",
+       "upload-form-label-infoform-description": "Description",
+       "upload-form-label-usage-title": "Utilisation",
+       "upload-form-label-usage-filename": "Nom du fichier",
        "backend-fail-stream": "Impossible de lire le fichier $1.",
        "backend-fail-backup": "Impossible de sauvegarder le fichier $1.",
        "backend-fail-notexists": "Le fichier $1 n’existe pas.",
        "filerevert-legend": "Rétablir le fichier",
        "filerevert-intro": "Vous êtes sur le point de rétablir le fichier '''[[Media:$1|$1]]''' à la [$4 version du $2 à $3].",
        "filerevert-comment": "Motif :",
-       "filerevert-defaultcomment": "Version du $1 à $2 rétablie",
+       "filerevert-defaultcomment": "Retour sur la version du $2, $1 ($3)",
        "filerevert-submit": "Rétablir",
        "filerevert-success": "'''[[Media:$1|$1]]''' a été rétabli à [$4 la version du $2 à $3].",
        "filerevert-badversion": "Il n'y a pas localement de version antérieure du fichier qui porte la date indiquée.",
        "nopagetext": "La page cible que vous avez indiquée n'existe pas.",
        "pager-newer-n": "{{PLURAL:$1|plus récente|$1 plus récentes}}",
        "pager-older-n": "{{PLURAL:$1|plus ancienne|$1 plus anciennes}}",
-       "suppress": "Superviser",
+       "suppress": "Supprimer",
        "querypage-disabled": "Cette page spéciale est désactivée pour des raisons de performances.",
        "apihelp": "Aide de l’API",
        "apihelp-no-such-module": "Le module « $1 » est introuvable.",
index 5b6b18c..4d693bf 100644 (file)
        "upload-http-error": "Diar as en HTTP-feeler mä: $1",
        "upload-copy-upload-invalid-domain": "Kopiin faan datein kön faan detdiar domeen ei huuchschüürd wurd.",
        "upload-dialog-title": "Datei huuchschüür",
-       "upload-dialog-error": "Diar as wat skiaf gingen",
-       "upload-dialog-warning": "Diar as en wäärnang kimen",
        "upload-dialog-button-cancel": "Ufbreeg",
        "upload-dialog-button-done": "Klaar",
        "upload-dialog-button-save": "Seekre",
        "upload-dialog-button-upload": "Huuchschüür",
-       "upload-dialog-label-select-file": "Datei ütjschük",
-       "upload-dialog-label-infoform-title": "Enkelthaiden",
-       "upload-dialog-label-infoform-name": "Nööm",
-       "upload-dialog-label-infoform-description": "Beskriiwang",
-       "upload-dialog-label-usage-title": "Brük",
-       "upload-dialog-label-usage-filename": "Dateinööm",
+       "upload-process-error": "Diar as wat skiaf gingen",
+       "upload-process-warning": "Diar as en wäärnang kimen",
+       "upload-form-label-select-file": "Datei ütjschük",
+       "upload-form-label-infoform-title": "Enkelthaiden",
+       "upload-form-label-infoform-name": "Nööm",
+       "upload-form-label-infoform-description": "Beskriiwang",
+       "upload-form-label-usage-title": "Brük",
+       "upload-form-label-usage-filename": "Dateinööm",
        "backend-fail-stream": "Det datei $1 küd ei auerdraanj wurd.",
        "backend-fail-backup": "Det datei $1 küd ei seekert wurd.",
        "backend-fail-notexists": "Det datei $1 jaft at ei.",
index bb52e39..18d854f 100644 (file)
        "upload-http-error": "Produciuse un erro HTTP: $1",
        "upload-copy-upload-invalid-domain": "A copia de cargas non está dispoñible neste dominio.",
        "upload-dialog-title": "Subir un ficheiro",
-       "upload-dialog-error": "Houbo un erro",
-       "upload-dialog-warning": "Produciuse unha advertencia",
        "upload-dialog-button-cancel": "Cancelar",
        "upload-dialog-button-done": "Feito",
        "upload-dialog-button-save": "Gardar",
        "upload-dialog-button-upload": "Subir",
-       "upload-dialog-label-select-file": "Seleccionar un ficheiro",
-       "upload-dialog-label-infoform-title": "Detalles",
-       "upload-dialog-label-infoform-name": "Nome",
-       "upload-dialog-label-infoform-description": "Descrición",
-       "upload-dialog-label-usage-title": "Uso",
-       "upload-dialog-label-usage-filename": "Nome do ficheiro",
+       "upload-process-error": "Houbo un erro",
+       "upload-process-warning": "Produciuse unha advertencia",
+       "upload-form-label-select-file": "Seleccionar un ficheiro",
+       "upload-form-label-infoform-title": "Detalles",
+       "upload-form-label-infoform-name": "Nome",
+       "upload-form-label-infoform-description": "Descrición",
+       "upload-form-label-usage-title": "Uso",
+       "upload-form-label-usage-filename": "Nome do ficheiro",
        "backend-fail-stream": "Non se puido transmitir o ficheiro \"$1\".",
        "backend-fail-backup": "Non se puido facer unha copia de seguridade do ficheiro \"$1\".",
        "backend-fail-notexists": "O ficheiro \"$1\" non existe.",
index f0a9a4e..f1eea2e 100644 (file)
        "upload-http-error": "E HTTP-Fähler isch ufträtte: $1",
        "upload-copy-upload-invalid-domain": "As Kopi uffeladbari Dateie sin iber die Domain nit verfiegbar.",
        "upload-dialog-title": "Datei ufelade",
-       "upload-dialog-error": "Es het e Fähler ’gä",
-       "upload-dialog-warning": "Es het e Warnig ’gä",
        "upload-dialog-button-cancel": "Abbräche",
        "upload-dialog-button-done": "Fertig",
        "upload-dialog-button-save": "Spychere",
        "upload-dialog-button-upload": "Ufelade",
-       "upload-dialog-label-select-file": "Datei ussueche",
-       "upload-dialog-label-infoform-title": "Details",
-       "upload-dialog-label-infoform-name": "Name",
-       "upload-dialog-label-infoform-description": "Beschrybig",
-       "upload-dialog-label-usage-title": "Verwändig",
-       "upload-dialog-label-usage-filename": "Dateiname",
+       "upload-process-error": "Es het e Fähler ’gä",
+       "upload-process-warning": "Es het e Warnig ’gä",
+       "upload-form-label-select-file": "Datei ussueche",
+       "upload-form-label-infoform-title": "Details",
+       "upload-form-label-infoform-name": "Name",
+       "upload-form-label-infoform-description": "Beschrybig",
+       "upload-form-label-usage-title": "Verwändig",
+       "upload-form-label-usage-filename": "Dateiname",
        "backend-fail-stream": "D Datei $1 het nit chenne ibertrait wäre.",
        "backend-fail-backup": "D Datei $1 het nit chenne gsicheret wäre.",
        "backend-fail-notexists": "D Datei $1 git s nit.",
index d476e5a..0bd1984 100644 (file)
        "upload-dialog-button-done": "સંપન્ન",
        "upload-dialog-button-save": "સાચવો",
        "upload-dialog-button-upload": "ચઢાવો",
-       "upload-dialog-label-select-file": "ફાઈલ પસંદ કરો",
-       "upload-dialog-label-infoform-title": "વિગતો",
-       "upload-dialog-label-infoform-name": "નામ",
-       "upload-dialog-label-infoform-description": "વર્ણન",
-       "upload-dialog-label-usage-title": "વપરાશ",
-       "upload-dialog-label-usage-filename": "ફાઈલનું નામ",
+       "upload-form-label-select-file": "ફાઈલ પસંદ કરો",
+       "upload-form-label-infoform-title": "વિગતો",
+       "upload-form-label-infoform-name": "નામ",
+       "upload-form-label-infoform-description": "વર્ણન",
+       "upload-form-label-usage-title": "વપરાશ",
+       "upload-form-label-usage-filename": "ફાઈલનું નામ",
        "backend-fail-stream": "ફાઈલ $1 ને લાવી ન શકાઈ.",
        "backend-fail-backup": "ફાઈલ $1 ની પ્રત ન સાચવી શકાઈ.",
        "backend-fail-notexists": "ફાઈલ $1 ઉપલબ્ધ નથી.",
index 3a38c7a..5d8586e 100644 (file)
        "upload-http-error": "התרחשה שגיאת HTTP‏: $1",
        "upload-copy-upload-invalid-domain": "העלאת קבצים משרת זה אינה אפשרית.",
        "upload-dialog-title": "העלאת קובץ",
-       "upload-dialog-error": "אירעה שגיאה",
-       "upload-dialog-warning": "אירעה אזהרה",
        "upload-dialog-button-cancel": "ביטול",
        "upload-dialog-button-done": "בוצע",
        "upload-dialog-button-save": "שמירה",
        "upload-dialog-button-upload": "העלאה",
-       "upload-dialog-label-select-file": "בחירת קובץ",
-       "upload-dialog-label-infoform-title": "פרטים",
-       "upload-dialog-label-infoform-name": "שם",
-       "upload-dialog-label-infoform-description": "תיאור",
-       "upload-dialog-label-usage-title": "שימושים",
-       "upload-dialog-label-usage-filename": "שם הקובץ",
+       "upload-process-error": "אירעה שגיאה",
+       "upload-process-warning": "אירעה אזהרה",
+       "upload-form-label-select-file": "בחירת קובץ",
+       "upload-form-label-infoform-title": "פרטים",
+       "upload-form-label-infoform-name": "שם",
+       "upload-form-label-infoform-description": "תיאור",
+       "upload-form-label-usage-title": "שימושים",
+       "upload-form-label-usage-filename": "שם הקובץ",
        "backend-fail-stream": "לא הייתה אפשרות להזרים את הקובץ \"$1\".",
        "backend-fail-backup": "לא הייתה אפשרות לגבות את הקובץ \"$1\".",
        "backend-fail-notexists": "הקובץ \"$1\" אינו קיים.",
        "filerevert-legend": "שחזור קובץ",
        "filerevert-intro": "אתם עומדים לשחזר את הקובץ '''[[Media:$1|$1]]''' ל[$4 גרסה מ־$3, $2].",
        "filerevert-comment": "סיבה:",
-       "filerevert-defaultcomment": "שוחזר לגרסה מ־$2, $1",
+       "filerevert-defaultcomment": "שוחזר לגרסה מ־$2, $1 ($3)",
        "filerevert-submit": "שחזור",
        "filerevert-success": "<strong>[[Media:$1|$1]]</strong> שוחזר ל[$4 גרסה מ־$3, $2].",
        "filerevert-badversion": "אין גרסה מקומית קודמת של הקובץ שהועלתה בתאריך המבוקש.",
index de0be0e..30f7181 100644 (file)
        "upload-http-error": "Un error HTTP occurreva: $1",
        "upload-copy-upload-invalid-domain": "Le incargamento de copias non es disponibile ab iste dominio.",
        "upload-dialog-title": "Incargar file",
-       "upload-dialog-error": "Un error ha occurrite",
-       "upload-dialog-warning": "Un advertimento se ha producite",
        "upload-dialog-button-cancel": "Cancellar",
        "upload-dialog-button-done": "Facite",
        "upload-dialog-button-save": "Salveguardar",
        "upload-dialog-button-upload": "Incargar",
-       "upload-dialog-label-select-file": "Seliger file",
-       "upload-dialog-label-infoform-title": "Detalios",
-       "upload-dialog-label-infoform-name": "Nomine",
-       "upload-dialog-label-infoform-description": "Description",
-       "upload-dialog-label-usage-title": "Uso",
-       "upload-dialog-label-usage-filename": "Nomine del file",
+       "upload-process-error": "Un error ha occurrite",
+       "upload-process-warning": "Un advertimento se ha producite",
+       "upload-form-label-select-file": "Seliger file",
+       "upload-form-label-infoform-title": "Detalios",
+       "upload-form-label-infoform-name": "Nomine",
+       "upload-form-label-infoform-description": "Description",
+       "upload-form-label-usage-title": "Uso",
+       "upload-form-label-usage-filename": "Nomine del file",
        "backend-fail-stream": "Non poteva transmitter le file $1.",
        "backend-fail-backup": "Non poteva facer un copia de reserva del file $1.",
        "backend-fail-notexists": "Le file $1 non existe.",
index a633533..49da7a9 100644 (file)
        "nstab-template": "Plantilia",
        "nstab-help": "Panid ti tulong",
        "nstab-category": "Kategoria",
+       "mainpage-nstab": "Umuna a Panid",
        "nosuchaction": "Awan ti kasta nga aramid",
        "nosuchactiontext": "Ti aramid a nainaganan babaen ti URL ket imbalido.\nMabalin a madi ti naimakiniliam nga URL, wenno sinurotmo ti saan a nasayaat a silpo.\nMabalinmo pay nga ibaga ti parikut ti sopwer nga us-usaren babaen ti {{SITENAME}}.",
        "nosuchspecialpage": "Awan ti kasta nga espesial a panid",
        "createacct-captcha": "Panagpatalged ti seguridad",
        "createacct-imgcaptcha-ph": "Ikabil ti teksto a makitam dita ngato",
        "createacct-submit": "Partuatem ti pakabilangam",
-       "createacct-another-submit": "Agpartuat iti sabali a pakabilangan",
+       "createacct-another-submit": "Agpartuat iti pakabilangan",
        "createacct-benefit-heading": "Ti {{SITENAME}} ket inar-aramid babaen ti tattao a kasla kenka.",
        "createacct-benefit-body1": "{{PLURAL:$1|nga inurnos|nga inur-urnos}}",
        "createacct-benefit-body2": "{{PLURAL:$1|a panid|a pampanid}}",
        "changeemail-password": "Ti bukodmo a kontrasenias ti {{SITENAME}}:",
        "changeemail-submit": "Sukatan ti esurat",
        "changeemail-throttled": "Adu unay ti panagpadasmo a sumrek.\nPangngaasi nga aguray ti $1 sakbay a padasen manen.",
+       "changeemail-nochange": "Pangngaasi nga agikabil iti sabali a baro nga adres ti esurat.",
        "resettokens": "Isaad manen dagiti tandaan",
        "resettokens-text": "Mabalinmo nga isaad manen dagiti tandaan a mangpalubos ti panagserrek ti naisangayan a pribado datos a mainaig ti pakabilangam ditoy.\n\nAramidem daytoy no aksidente nga inbingaymo dagitoy iti sabali wenno ti pakabilangam ket nakomprimiso.",
        "resettokens-no-tokens": "Awan dagiti maisaad manen a tandaan.",
        "group-bot": "Dagiti bot",
        "group-sysop": "Dagiti administrador",
        "group-bureaucrat": "Dagiti burokrata",
-       "group-suppress": "Pakapansin",
+       "group-suppress": "Dagiti agilaplapped",
        "group-all": "(amin)",
        "group-user-member": "{{GENDER:$1|agar-aramat}}",
        "group-autoconfirmed-member": "{{GENDER:$1|automatiko a napasingkedan nga agar-aramat}}",
        "group-bot-member": "{{GENDER:$1|bot}}",
        "group-sysop-member": "{{GENDER:$1|administrador}}",
        "group-bureaucrat-member": "{{GENDER:$1|burokrata}}",
-       "group-suppress-member": "{{GENDER:$1|pagpansin}}",
+       "group-suppress-member": "{{GENDER:$1|agilaplapped}}",
        "grouppage-user": "{{ns:project}}:Dagiti agar-aramat",
        "grouppage-autoconfirmed": "{{ns:project}}:Dagiti automatiko a napasingkedan nga agar-aramat",
        "grouppage-bot": "{{ns:project}}:Dagiti bot",
        "grouppage-sysop": "{{ns:project}}:Dagiti administrador",
        "grouppage-bureaucrat": "{{ns:project}}:Dagiti burokrata",
-       "grouppage-suppress": "{{ns:project}}:Pagpansin",
+       "grouppage-suppress": "{{ns:project}}:Ilapped",
        "right-read": "Basaen dagiti panid",
        "right-edit": "Agurnos kadagiti panid",
        "right-createpage": "Agpartuat kadagiti panid (saan a pagtutungtongan a pampanid)",
        "upload-http-error": "Adda napasamak a biddut ti HTTP: $1",
        "upload-copy-upload-invalid-domain": "Dagiti kopia a panagikarga ket saan a magun-od manipud iti daytoy a dominio.",
        "upload-dialog-title": "Agikarga iti papeles",
-       "upload-dialog-error": "Adda napasamak a biddut",
-       "upload-dialog-warning": "Adda napasamak a ballaag",
        "upload-dialog-button-cancel": "Ukasen",
        "upload-dialog-button-done": "Nalpasen",
        "upload-dialog-button-save": "Idulin",
        "upload-dialog-button-upload": "Agikarga",
-       "upload-dialog-label-select-file": "Pilien ti papeles",
-       "upload-dialog-label-infoform-title": "Dagiti salaysay",
-       "upload-dialog-label-infoform-name": "Nagan",
-       "upload-dialog-label-infoform-description": "Deskripsion",
-       "upload-dialog-label-usage-title": "Panagusar",
-       "upload-dialog-label-usage-filename": "Nagan ti papeles",
+       "upload-process-error": "Adda napasamak a biddut",
+       "upload-process-warning": "Adda napasamak a ballaag",
+       "upload-form-label-select-file": "Pilien ti papeles",
+       "upload-form-label-infoform-title": "Dagiti salaysay",
+       "upload-form-label-infoform-name": "Nagan",
+       "upload-form-label-infoform-description": "Deskripsion",
+       "upload-form-label-usage-title": "Panagusar",
+       "upload-form-label-usage-filename": "Nagan ti papeles",
        "backend-fail-stream": "Saan a maipan ti papeles $1.",
        "backend-fail-backup": "Saan a makaidulin ti kapada ti papeles ti $1.",
        "backend-fail-notexists": "Awan ti papeles ti $1.",
        "filerevert-legend": "Isubli ti papeles",
        "filerevert-intro": "Mangrugrugika nga agipasubli ti papeles ti <strong>[[Media:$1|$1]]</strong> iti [$4 bersion manipud idi $3, $2].",
        "filerevert-comment": "Rason:",
-       "filerevert-defaultcomment": "Naisubli iti bersion manipud idi $2, $1",
+       "filerevert-defaultcomment": "Naisubli iti bersion manipud idi $2, $1 ($3)",
        "filerevert-submit": "Isubli",
        "filerevert-success": "Ti <strong>[[Media:$1|$1]]</strong> ket naipasubli iti [$4 bersion manipud idi $3, $2].",
        "filerevert-badversion": "Awan ti dati a lokal a bersion iti daytoy a papeles a naited ti dayta nga oras ken petsa.",
        "nopagetext": "Awan ti puntaan a panid a nainaganam.",
        "pager-newer-n": "{{PLURAL:$1|nabarbaro a 1|nabarbaro a $1}}",
        "pager-older-n": "{{PLURAL:$1|nadadaan a 1|nadadaan a $1}}",
-       "suppress": "Pakapansin",
+       "suppress": "Ilapped",
        "querypage-disabled": "Daytoy nga espesial a panid ket nabaldado gapu kadagiti rason ti kasayaat ti panagpataray.",
        "apihelp": "Tulong ti API",
        "apihelp-no-such-module": "Saan a nabirukan ti modulo ti \"$1\".",
        "emailccsubject": "Kopia ti mensahem kenni $1: $2",
        "emailsent": "Naipatuloden ti esurat",
        "emailsenttext": "Naipatuloden ti esurat a mensahem.",
-       "emailuserfooter": "Daytoy nga esurat ket impatulod babaen ni $1 kenni $2 iti \"{{int:emailuser}}\" nga annong iti {{SITENAME}}",
+       "emailuserfooter": "Daytoy nga esurat ket {{GENDER:$1|impatulod}} babaen ni $1 kenni {{GENDER:$2|$2}} babaen ti \"{{int:emailuser}}\" nga annong iti {{SITENAME}}",
        "usermessage-summary": "Pumanpanaw iti mesahe ti sistema.",
        "usermessage-editor": "Mensahero ti sistema",
        "watchlist": "Bambantayan",
index 27bd8af..be41378 100644 (file)
        "createacct-captcha": "Controllo di sicurezza",
        "createacct-imgcaptcha-ph": "Inserisci il testo che vedi sopra",
        "createacct-submit": "Crea la tua utenza",
-       "createacct-another-submit": "Crea un'altra utenza",
+       "createacct-another-submit": "Crea utenza",
        "createacct-benefit-heading": "{{SITENAME}} cresce grazie a persone come te.",
        "createacct-benefit-body1": "{{PLURAL:$1|modifica|modifiche}}",
        "createacct-benefit-body2": "{{PLURAL:$1|pagina|pagine}}",
        "group-bot": "Bot",
        "group-sysop": "Amministratori",
        "group-bureaucrat": "Burocrati",
-       "group-suppress": "Oversight",
+       "group-suppress": "Soppressori",
        "group-all": "(tutti)",
        "group-user-member": "{{GENDER:$1|utente}}",
        "group-autoconfirmed-member": "{{GENDER:$1|utente autoconvalidato|utente autoconvalidata|utente autoconvalidato/a}}",
        "group-bot-member": "{{GENDER:$1|bot}}",
        "group-sysop-member": "{{GENDER:$1|amministratore|amministratrice|amministratore/trice}}",
        "group-bureaucrat-member": "{{GENDER:$1|burocrate}}",
-       "group-suppress-member": "{{GENDER:$1|oversight}}",
+       "group-suppress-member": "{{GENDER:$1|soppressore|sopprimitrice}}",
        "grouppage-user": "{{ns:project}}:Utenti",
        "grouppage-autoconfirmed": "{{ns:project}}:Utenti autoconvalidati",
        "grouppage-bot": "{{ns:project}}:Bot",
        "grouppage-sysop": "{{ns:project}}:Amministratori",
        "grouppage-bureaucrat": "{{ns:project}}:Burocrati",
-       "grouppage-suppress": "{{ns:project}}:Oversight",
+       "grouppage-suppress": "{{ns:project}}:Soppressori",
        "right-read": "Legge pagine",
        "right-edit": "Modifica pagine",
        "right-createpage": "Crea pagine (escluse le pagine di discussione)",
        "upload-http-error": "Si è verificato un errore HTTP: $1",
        "upload-copy-upload-invalid-domain": "Non è consentito il caricamento di copie da questo dominio.",
        "upload-dialog-title": "Carica file",
-       "upload-dialog-error": "Si è verificato un errore",
-       "upload-dialog-warning": "Si è verificato un avviso",
        "upload-dialog-button-cancel": "Annulla",
        "upload-dialog-button-done": "Fatto",
        "upload-dialog-button-save": "Salva",
        "upload-dialog-button-upload": "Carica",
-       "upload-dialog-label-select-file": "Seleziona file",
-       "upload-dialog-label-infoform-title": "Dettagli",
-       "upload-dialog-label-infoform-name": "Nome",
-       "upload-dialog-label-infoform-description": "Descrizione",
-       "upload-dialog-label-usage-title": "Utilizzo",
-       "upload-dialog-label-usage-filename": "Nome del file",
+       "upload-process-error": "Si è verificato un errore",
+       "upload-process-warning": "Si è verificato un avviso",
+       "upload-form-label-select-file": "Seleziona file",
+       "upload-form-label-infoform-title": "Dettagli",
+       "upload-form-label-infoform-name": "Nome",
+       "upload-form-label-infoform-description": "Descrizione",
+       "upload-form-label-usage-title": "Utilizzo",
+       "upload-form-label-usage-filename": "Nome del file",
        "backend-fail-stream": "Impossibile trasmettere il file $1.",
        "backend-fail-backup": "Impossibile eseguire il backup del file $1 .",
        "backend-fail-notexists": "Il file $1 non esiste.",
        "filerevert-legend": "Ripristina file",
        "filerevert-intro": "Si sta per ripristinare il file '''[[Media:$1|$1]]''' alla [$4 versione del $2, $3].",
        "filerevert-comment": "Motivo:",
-       "filerevert-defaultcomment": "Ripristinata la versione del $2, $1",
+       "filerevert-defaultcomment": "Ripristinata la versione del $2, $1 ($3)",
        "filerevert-submit": "Ripristina",
        "filerevert-success": "'''Il file [[Media:$1|$1]]''' è stato ripristinato alla [$4 versione del $2, $3].",
        "filerevert-badversion": "Non esistono versioni locali precedenti del file con il timestamp richiesto.",
        "nopagetext": "La pagina richiesta non esiste.",
        "pager-newer-n": "{{PLURAL:$1|1 più recente|$1 più recenti}}",
        "pager-older-n": "{{PLURAL:$1|1 meno recente|$1 meno recenti}}",
-       "suppress": "Oversight",
+       "suppress": "Sopprimi",
        "querypage-disabled": "Questa pagina speciale è disattivata per motivi di prestazioni.",
        "apihelp": "Aiuto API",
        "apihelp-no-such-module": "Modulo \"$1\" non trovato.",
        "emailccsubject": "Copia del messaggio inviato a $1: $2",
        "emailsent": "Messaggio inviato",
        "emailsenttext": "Il messaggio e-mail è stato inviato.",
-       "emailuserfooter": "Questa email è stata inviata da $1 a $2 attraverso la funzione \"{{int:emailuser}}\" su {{SITENAME}}.",
+       "emailuserfooter": "Questa email è stata {{GENDER:$1|inviata}} da $1 a {{GENDER:$2|$2}} attraverso la funzione \"{{int:emailuser}}\" su {{SITENAME}}.",
        "usermessage-summary": "Messaggio di sistema",
        "usermessage-editor": "Messaggero di sistema",
        "usermessage-template": "MediaWiki:MessaggioUtente",
        "api-error-badaccess-groups": "Non sei autorizzato a caricare documenti su questa wiki.",
        "api-error-badtoken": "Errore interno: token errato.",
        "api-error-copyuploaddisabled": "Il caricamento tramite URL è disabilitato su questo server.",
-       "api-error-duplicate": "Sul sito {{PLURAL:$1|c'è già [$2 un altro documento]|ci sono già [$2 altri documenti]}} con lo stesso contenuto.",
+       "api-error-duplicate": "Sul sito {{PLURAL:$1|c'è già un altro documento|ci sono già altri documenti}} con lo stesso contenuto.",
        "api-error-duplicate-archive": "{{PLURAL:$1|C'era un altro file|C'erano altri file}} già nel sito con lo stesso contenuto, ma {{PLURAL:$1|è stato cancellato|sono stati cancellati}}.",
        "api-error-empty-file": "Il file selezionato era vuoto.",
        "api-error-emptypage": "La creazione di nuove pagine vuote non è consentita.",
index ead03df..0004996 100644 (file)
        "createacct-captcha": "自動作成防止チェック",
        "createacct-imgcaptcha-ph": "上に表示されている文字列を入力",
        "createacct-submit": "アカウントを作成",
-       "createacct-another-submit": "アカウントを作成",
+       "createacct-another-submit": "アカウントを作成",
        "createacct-benefit-heading": "{{SITENAME}}は、あなたのような人々が創っています。",
        "createacct-benefit-body1": "{{PLURAL:$1|編集}}",
        "createacct-benefit-body2": "{{PLURAL:$1|ページ}}",
        "upload-http-error": "HTTP エラー発生: $1",
        "upload-copy-upload-invalid-domain": "このドメインからのアップロードは許可されていません。",
        "upload-dialog-title": "ファイルをアップロード",
-       "upload-dialog-error": "エラーが発生しました",
-       "upload-dialog-warning": "警告",
        "upload-dialog-button-cancel": "中止",
        "upload-dialog-button-done": "完了",
        "upload-dialog-button-save": "保存",
        "upload-dialog-button-upload": "アップロード",
-       "upload-dialog-label-select-file": "ファイル選択",
-       "upload-dialog-label-infoform-title": "詳細",
-       "upload-dialog-label-infoform-name": "名前",
-       "upload-dialog-label-infoform-description": "説明",
-       "upload-dialog-label-usage-title": "使用法",
-       "upload-dialog-label-usage-filename": "ファイル名",
+       "upload-process-error": "エラーが発生しました",
+       "upload-process-warning": "警告",
+       "upload-form-label-select-file": "ファイル選択",
+       "upload-form-label-infoform-title": "詳細",
+       "upload-form-label-infoform-name": "名前",
+       "upload-form-label-infoform-description": "説明",
+       "upload-form-label-usage-title": "使用法",
+       "upload-form-label-usage-filename": "ファイル名",
        "backend-fail-stream": "ファイル $1 をストリームできませんでした。",
        "backend-fail-backup": "ファイル $1 をバックアップできませんでした。",
        "backend-fail-notexists": "ファイル $1 は存在しません。",
        "filerevert-legend": "ファイルを差し戻す",
        "filerevert-intro": "ファイル<strong>[[Media:$1|$1]]</strong>を[$4 $2$3版]に差し戻そうとしています。",
        "filerevert-comment": "理由:",
-       "filerevert-defaultcomment": "$1$2の版へ差し戻し",
+       "filerevert-defaultcomment": "$1$2の版へ差し戻し ($3)",
        "filerevert-submit": "差し戻す",
        "filerevert-success": "<strong>[[Media:$1|$1]]</strong>は[$4 $2$3の版]に差し戻されました。",
        "filerevert-badversion": "このファイルに指定された時刻印を持つ過去の版はありません。",
index 575e43f..2fe06b6 100644 (file)
        "jumpto": "Skift te:",
        "jumptonavigation": "navigasjon",
        "jumptosearch": "Syegneng",
+       "view-pool-error": "Beklawe, men serveren ä i yeblikk öwebelasten. \nFor mång bruga forsyege å sietj siden.\nWentj e yeblikk, för du forsyege å besyeg siden idjen.\n\n$1",
+       "generic-pool-error": "Beklawe, men serveren ä i yeblikk öwebelasten.\nFor mång bruga forsyeg å sietj siden.\nWentj e yeblikk för du forsyege å besyeg siden idjen.",
+       "pool-timeout": "Timeout mens man wentje på låsnengen",
+       "pool-queuefull": "Pool-køen ä full",
+       "pool-errorunknown": "Utjentj fejl",
+       "pool-servererror": "Pool-counterservicen ä ett te rådihed ($1).",
+       "poolcounter-usage-error": "Brugsfejl: $1",
        "aboutsite": "Om {{SITENAME}}",
        "aboutpage": "Project:Om",
        "copyright": "Inholje ä utdjøwen unje $1 mämenna ånj ä åndjøwen.",
        "ok": "OK",
        "retrievedfrom": "Hentjen fra \"$1\"",
        "youhavenewmessages": "{{PLURAL:$3|Du hår}} $1 ($2).",
+       "youhavenewmessagesfromusers": "{{PLURAL:$4|Du hår}} $1 fra {{PLURAL:$3|i ånj bruge| $3 bruga}} ($2).",
+       "youhavenewmessagesmanyusers": "Du hår $1 fra mång bruga ($2).",
+       "newmessageslinkplural": "{{PLURAL:$1|e ny besked|999=nyj beskede}}",
+       "newmessagesdifflinkplural": "siensti {{PLURAL:$1|øndreng|999=øndrenge}}",
        "youhavenewmessagesmulti": "Du hår nyj beskede på $1",
        "editsection": "redigiir",
        "editold": "redigiir",
        "page-rss-feed": "\"$1\" RSS-feed",
        "page-atom-feed": "\"$1\" Atom-feed",
        "red-link-title": "$1 (siden ä ett skrøwen ennu)",
+       "sort-descending": "Sortiir fallenje",
+       "sort-ascending": "Sortiir stigenje",
        "nstab-main": "Siid",
        "nstab-user": "Brugesiid",
        "nstab-media": "Mediesiid",
        "nstab-category": "Kategori",
        "mainpage-nstab": "Forsiid",
        "nosuchaction": "Funksjonen finjs ett",
-       "nosuchactiontext": "Funksje ångævet i'n URL ken ekke genkendes åf æ MediaWiki-softwær",
+       "nosuchactiontext": "Hånjlengen som ä åndjøwen i URL'i ä udjylji.\nDu kan ha skrøwen URL'i forkiertj, elle fuljtj en ukorrekt henwisneng.\nDä kan åsså skyljs en fejl i programmet som brugs å {{SITENAME}}.",
        "nosuchspecialpage": "En sån specialsiid finjs ett",
-       "nospecialpagetext": "Du harst bedt en sonstside'm, der ekke ken genkendes åf æ MediaWiki-softwær.",
+       "nospecialpagetext": "<strong>Du hår bien om en specialsiid, som ett kan djenkentjs å MediaWiki-softwari.</strong>\n\nEn list öwe djylji specialside finjs på [[Special:SpecialPages|{{int:specialpages}}]].",
        "error": "Fejl",
        "databaseerror": "Databasefejl",
+       "databaseerror-text": "Där opstue fejl i en forspöyrgsel te databasi.\nDetj kan indikiir en fejl i softwari.",
+       "databaseerror-textcl": "Där opstue fejl i en forspöyrgsel te databasi.",
        "databaseerror-query": "Forspöyrgsel: $1",
        "databaseerror-function": "Funksjon: $1",
        "databaseerror-error": "Fejl: $1",
        "pt-createaccount": "Oprett konto",
        "pt-userlogout": "Logg å",
        "retypenew": "Djentast ny adgångskode",
+       "resetpass-submit-cancel": "Åbryd",
        "passwordreset": "Nullstell adgångskode",
        "bold_sample": "Fied tekst",
        "bold_tip": "Fied tekst",
        "editing": "Redigiire $1",
        "creating": "Oprette $1",
        "editingsection": "Redigiire $1 (åsnit)",
+       "editingcomment": "Redigiire $1 (ny åsnit)",
+       "editconflict": "Redigiirengskonflikt: $1",
        "copyrightwarning": "Bemærk wenlist å åll bidraw te {{SITENAME}} ä å betrakt som utdjøwen unje $2 (se $1 for detalje).\nHwes du ett onske å din tekst skal utsätts for nådesløs redigiirenge å å den kan blyw kopiiirtj ette forgodtbefinjenje, så skal du ett placiir den her.<br />\nDu låwe os åsså, å du siel hår forfatten teksten elle hår kopiiirtj den fra en public domain-tjelj elle en tilswarenje fri tjelj.\n'''Lägg åller material her som ä beskøttetj å anjas ophawsrett uen dæes tillædels!'''",
        "templatesused": "{{PLURAL:$1|Skabelon|Skabelone}} som ä brugtj på siden:",
        "templatesusedpreview": "Følgende skablåner bruges åf denne ertikelførhåndsvesnenge:",
        "histfirst": "älsti",
        "histlast": "nysti",
        "historysize": "({{PLURAL:$1|1 byte|$1 bytes}})",
+       "history-feed-title": "Versjonshistori",
        "history-feed-item-nocomment": "$1 mä $2",
        "rev-delundel": "ønda sijtbarhed",
        "history-title": "$1: Versjonshistorik",
        "search-redirect": "(omdirigiireng $1)",
        "search-section": "(åsnit $1)",
        "search-suggest": "Mientje du: $1",
+       "search-interwiki-caption": "Systeprojekte",
+       "search-interwiki-default": "Resultate fra $1:",
+       "search-interwiki-more": "(mier)",
+       "search-relatedarticle": "Relatiirtj",
+       "searchrelated": "relatiirtj",
        "searchall": "åll",
        "search-showingresults": "{{PLURAL:$4|Resultat <strong>$1</strong> å <strong>$3</strong>|Resultat <strong>$1 - $2</strong> å <strong>$3</strong>}}",
        "search-nonefound": "Syegnengen djij ien resultate.",
        "mypreferences": "Instellenge",
        "prefs-skin": "Utsienje",
        "skin-preview": "Forhånjswisneng",
+       "prefs-misc": "Forskelli",
+       "prefs-resetpass": "Skift adgångskode",
+       "prefs-changeemail": "Ønda e-mailadress",
+       "prefs-setemail": "Åndjie en e-mailadress",
+       "prefs-email": "Instellenge for e-mail",
        "prefs-rendering": "Utsienje",
+       "saveprefs": "Djiem instellenge",
+       "restoreprefs": "Djensätt åll standardinstellenge (i åll seksjone)",
+       "prefs-editing": "Redigiireng",
+       "rows": "Räkke:",
+       "columns": "Kolonne:",
+       "searchresultshead": "Syegresultate",
+       "stub-threshold": "Græns for stumplinkformatiireng ($1):",
+       "stub-threshold-sample-link": "eksempel",
+       "stub-threshold-disabled": "Deaktiviirtj",
+       "recentchangesdays": "Åntal daw som skal wises i siensti øndrenge:",
+       "recentchangesdays-max": "Maksimal $1 {{PLURAL:$1|daw}}",
+       "recentchangescount": "Åntal redigiirenge som skal wises som standard:",
+       "prefs-help-recentchangescount": "Dä djälje for siensti øndrenge, historike å logge.",
+       "prefs-help-watchlist-token2": "Detj ä hemmeli lygli te webfeed å din öwewågnengslist.\nHwes anjer tjenne den, will man wær istånj te å läs din öwewågnengslist, så diel den ett.\n[[Special:ResetTokens|Klikk her hwes du hår brug å nullstell den]].",
+       "savedprefs": "Din instellenge ä bløwen djiemen.",
+       "timezonelegend": "Tidszone:",
+       "localtime": "Lokaltiid:",
+       "timezoneuseserverdefault": "Brug wikiis standardinstelleng ($1)",
+       "timezoneuseoffset": "Ånj (åndjie forskell)",
+       "servertime": "Serveris tiid:",
+       "guesstimezone": "Hentj tidszone fra browseri",
+       "timezoneregion-africa": "Afrika",
+       "timezoneregion-america": "Amerika",
+       "timezoneregion-antarctica": "Antarktis",
+       "timezoneregion-arctic": "Arktis",
+       "timezoneregion-asia": "Asien",
+       "timezoneregion-atlantic": "Atlantjerhawe",
+       "timezoneregion-australia": "Australien",
+       "timezoneregion-europe": "Europa",
+       "timezoneregion-indian": "Indisk Ocean",
+       "timezoneregion-pacific": "Stillhawe",
+       "allowemail": "Tillæd e-mail fra anjer bruga",
+       "prefs-searchoptions": "Syeg",
+       "prefs-namespaces": "Naunrum",
+       "default": "standard",
+       "prefs-files": "File",
+       "prefs-custom-css": "Personli CSS",
+       "prefs-custom-js": "Personli JavaScript",
+       "prefs-common-css-js": "Fælls CSS/JS for åll utsienje:",
+       "prefs-reset-intro": "Du kan brug siden te å tebagstell åll din instellenge te standardinstellenger.\nDä kan ett djendjörs.",
+       "prefs-emailconfirm-label": "Bekräftels å e-mail:",
        "youremail": "E-mail:",
+       "username": "{{GENDER:$1|Brugenaun}}:",
+       "prefs-memberingroups": "{{GENDER:$2|Mälemm}} å {{PLURAL:$1|gruppen|grupper}}:",
+       "prefs-registration": "Registriirengstidspuntj:",
        "yourrealname": "Det rijti naun:",
+       "yourlanguage": "Spraw:",
+       "yourvariant": "Sprawvariantj for inholj:",
+       "prefs-help-variant": "Sprawvaruabtheb elle rettskriiwneng, som du forträkke, å denn wikis inholjsside wises i.",
+       "yournick": "Ny signatur:",
+       "prefs-help-signature": "Kommentare på diskusjonsside bör signiirs mä \"<nowiki>~~~~</nowiki>\" som will blyw konvertiirtj te din signatur å e tidsstempel.",
+       "badsig": "Syntaksi i signaturen ä udjylji; kontrolliir wenlist den brugtje HTML.",
+       "badsiglength": "Din signatur ä for lång. Den ma hyest inholj $1 {{PLURAL:$1|tejn}}.",
+       "yourgender": "Hwant forträkke du å blyw beskriiwen?",
        "prefs-help-realname": "Åndjiels å rijti naun ä walgfritj.\nHwes du wælge å oplys det naun, wil dä blyw brugtj te å tilskriiw dej det arbejt.",
+       "prefs-editor": "Redigiirengsprogramme",
+       "prefs-preview": "Forhånjswisneng",
+       "prefs-advancedrc": "Avanciirtje instellinge",
+       "prefs-advancedrendering": "Avanciirtje instellinge",
+       "prefs-advancedsearchoptions": "Avanciirtje instellinge",
+       "prefs-advancedwatchlist": "Avanciirtje instellinge",
+       "prefs-displayrc": "Instellenge for wisneng",
+       "prefs-displaywatchlist": "Wisnengsmulihede",
+       "prefs-tokenwatchlist": "Märk",
+       "prefs-diffs": "Forskell",
        "grouppage-sysop": "{{ns:project}}:Administrore",
        "right-writeapi": "Brug redigiirengsdieli å API",
        "newuserlogpage": "Brugeoprettelslogg",
        "randompage": "Tefælji siid",
        "randomredirect": "Tefælji henwisnenge",
        "statistics": "Statistik",
+       "pageswithprop": "Side mä e side-ejnskåp",
+       "pageswithprop-legend": "Side mä e side-ejnskåp",
        "doubleredirects": "Doppelt omdirigiirenge",
        "brokenredirects": "Defekt omdirigiirenge",
        "withoutinterwiki": "Side uen henwisnenge te anjer spraw",
        "unusedimages": "Ubrugtje file",
        "wantedcategories": "Onske kategorie",
        "wantedpages": "Onske side",
-       "mostlinked": "Side mä fliest henwisnenge",
+       "wantedfiles": "Onske file",
+       "wantedtemplates": "Onske skabelone",
+       "mostlinked": "Side mä di fliesti henwisnenge",
        "mostlinkedcategories": "Miest-brugtje kategorie",
        "mostlinkedtemplates": "Miest-brugtje side",
        "mostcategories": "Side mä di fliesti kategorie",
        "mostimages": "Miest-brugtje file",
+       "mostinterwikis": "Side mä di fliesti interwikilinks",
        "mostrevisions": "Side mä di fliesti versjone",
        "prefixindex": "Åll side som bedjynne mä",
        "shortpages": "Kort side",
        "longpages": "Lång side",
        "deadendpages": "Blinjenjside",
        "protectedpages": "Skriiwbeskøttetj side",
+       "protectedtitles": "Beskøttetj sidenaun",
        "listusers": "Brugelist",
        "newpages": "Nysti side",
        "ancientpages": "Älsti side",
        "linksearch-text": "Wildcards som \"*.wikipedia.org\" kan benøtts.\nDär skal som minimum åndjies e topnivå-domæn som f. eks. \"*.org\".<br />\n{{PLURAL:$2|Unjestötten protokol|Unjestötten protokolle}}: $1 (bruge automatisk http:// hwes där ett ä åndjøwen no protokol).",
        "linksearch-line": "$2 linke te $1",
        "linksearch-error": "Wildcards ma kons benøtts i starti å hostnaune.",
+       "trackingcategories": "Spørengskategorie",
        "emailuser": "E-mail te bruge",
        "watchlist": "Öwewågnengslist",
        "mywatchlist": "Öwewågnengslist",
        "signature": "[[{{ns:user}}:$1|$2]] ([[{{ns:user_talk}}:$1|diskusjon]])",
        "version": "Informasjon om MediaWiki",
        "specialpages": "Specialside",
+       "specialpages-group-maintenance": "Weliholjelsside",
+       "specialpages-group-pages": "Sideliste",
        "tag-filter": "[[Special:Tags|Tag]]filtjer:",
        "tag-list-wrapper": "([[Special:Tags|{{PLURAL:$1|Tag|Tags}}]]: $2)",
        "logentry-delete-delete": "$1 {{GENDER:$2|slettetj}} siden $3",
index 61a3382..55ff98f 100644 (file)
@@ -23,7 +23,8 @@
                        "გიორგიმელა",
                        "아라",
                        "Macofe",
-                       "SHOTHA"
+                       "SHOTHA",
+                       "Gi777ga"
                ]
        },
        "tog-underline": "ბმულების ხაზგასმა:",
        "nstab-template": "თარგი",
        "nstab-help": "დახმარება",
        "nstab-category": "კატეგორია",
+       "mainpage-nstab": "მთავარი გვერდი",
        "nosuchaction": "მოქმედება არ არსებობს",
        "nosuchactiontext": "URL-ის მიერ მითითებული მოქმედება მცდარია.\nშესაძლოა შეცდომით აკრიფეთ URL, ან არასწორ ბმულზე გადახვედით.\nაგრეთვე შესაძლოა, {{SITENAME}}-ს მიერ გამოყენებულ პროგრამულ უზრუნველყოფაში იყოს შეცდომა.",
        "nosuchspecialpage": "სპეციალური გვერდი არ არსებობს",
        "actionthrottled": "სიჩქარის შეზღუდვა.",
        "actionthrottledtext": "სპამთან ბრძოლასთან დაკავშირებით აკრძალულია შემდეგი მონაცემების მრავალჯერ გამეორება. გთხოვთ გაიმეოროთ იგი მოგვიანებით.",
        "protectedpagetext": "ეს გვერდი დაბლოკილია რედაქტირებისათვის ან სხვა მოქმედებისათვის.",
-       "viewsourcetext": "თქვენ შეგიძლიათ ნახოთ ამ გვერდის საწყისი ფაილი და მისი ასლი შექმნათ:",
-       "viewyourtext": "თქვენ შეგიძლიათ იხილოთ და დააკოპიროთ  '''თქვენი რედაქტირებების''' საწყისი ტექსტი ამ გვერდზე:",
+       "viewsourcetext": "თქვენ შეგიძლიათ ნახოთ ამ გვერდის საწყისი ფაილი და მისი ასლი შექმნათ.",
+       "viewyourtext": "თქვენ შეგიძლიათ იხილოთ და დააკოპიროთ  <strong>თქვენი რედაქტირებების</strong> საწყისი ტექსტი ამ გვერდზე:",
        "protectedinterface": "ეს გვერდი წარმოადგენს ტექსტურ ინტერფეისს პროგრამული უზრუნველყოფისათვის და დაცულია ვანდალიზმის აღკვეთის მიზნით.",
        "editinginterface": "'''ყურადღება:''' თქვენ არედაქტირებთ გვერდს, რომელიც პროგრამის ინტერფეისის ტექსტს შეიცავს. \nამ გვერდზე განხორციელებული რედაქტირება გამოიწვევს ამ ვიკის სხვა მომხმარებელთა სამუშაო ინტერფეისის შეცვლასაც. \nიმისათვის, რომ დაამატოთ ან შეცვალოთ თარგმანები ყველა ვიკიში, გთხოვთ, გამოიყენოთ მედიავიკის ლოკალიზაციის პროექტი [//translatewiki.net/ translatewiki.net].",
        "translateinterface": "თარგმანების ყველა ვიკიში დასამატებლად ან შესაცვლელად, გთხოვთ გამოიყენოთ მედიავიკებისლოკალიზაციის პროექტი [//translatewiki.net/ translatewiki.net].",
        "changeemail-password": "თქვენი პაროლი პროექტში {{SITENAME}}:",
        "changeemail-submit": "ელ-ფოსტის შეცვლა",
        "changeemail-throttled": "თქვენ უკვე ძალიან ბევრჯერ სცადეთ შესვლა.\nგთხოვთ, მოიცადოთ $1, სანამ კიდევ სცდიდეთ.",
+       "changeemail-nochange": "გთხოვთ, შეიყვანოთ ახალი, განსხვავებული ელექტრონული მისამართი.",
        "resettokens": "ტოკენების ჩამოყრა",
        "resettokens-text": "თქვენ შეგიძლიათ ჩამოყაროთ ტოკენები, რომლებიც შესაძლებლობას იძლევიან შესვლას განსაზღვრულ პირად მონაცემებში, დაკავშირებულს თქვენ ანგარიშთან აქ. \n\nთქვენ ეს აუცილებლად უნდა გააკეთოთ, თუ თქვენ ის შემთხვევით გააცანით სხვას ან თუკი თქვენი ანგარიში იქნა გატეხილი.",
        "resettokens-no-tokens": "არ არის ტოკენები ჩამოსაყრელად",
        "yourdiff": "განსხვავებები",
        "copyrightwarning": "ყურადღება მიაქციეთ: ნებისმიერი წვლილი გვერდზე {{SITENAME}} $2 ლიცენზიას ექვემდებარება (იხ. $1 დეტალებისთვის). თუ არ გსურთ თქვენი ნამუშევარი თავისუფლად გავრცელდეს და მისი დაუნდობელი რედაქტირება მოხდეს, მაშინ ნუ შეიყვანთ მას აქ.<br />\nთქვენ ასევე პირობას დებთ, რომ ეს თქვენი დაწერილია, ან გადმოღებულია საზოგადოებრივი დომენიდან, ან მსგავსი თავისუფალი წყაროდან.\n'''ნუ შემოიტანთ საავტორო უფლებებით დაცულ ნაშრომს ავტორის თანხმობის გარეშე!'''",
        "copyrightwarning2": "*გაითვალისწინეთ, რომ ნებისმიერი წვლილი {{SITENAME}}-ში შეიძლება ჩასწორდეს, შეიცვალოს ან წაიშალოს სხვა რედაქტორების მიერ.\n*თუ არ გსურთ, რომ თქვენი ნამუშევარი შეუზღუდავად იქნეს რედაქტირებული, მას აქ ნუ განათავსებთ.<br />\n*თქვენ აგრეთვე პირობას დებთ, რომ თქვენს მიერ განთავსებული ტექსტი თქვენი დაწერილია, ან გადმოწერილია საზოგადოებრივი დომენიდან ან მსგავსი თავისუფალი წყაროდან. (იხ. $1 დეტალებისთვის).\n*'''ნუ შემოიტანთ საავტორო უფლებებით დაცულ ნაშრომს ავტორის ნებართვის გარეშე!'''",
+       "editpage-cannot-use-custom-model": "ამ გვერდის მასალის მოდელი არ შეიძლება, რომ შეიცვალოს.",
        "longpageerror": "'''შეცდომა: თქვენს მიერ აკრეფილი ტექსტის ზომა {{PLURAL:$1|$1 კილობაიტია}}, რაც აღემატება, დადგენილ {{PLURAL:$2|$2 კილობაიტიან}} ზღვარს. გვერდის შენახვა შეუძლებელია.'''",
        "readonlywarning": "'''გაფრთხილება: მონაცემთა ბაზა დახურულია პერიოდული შემოწმებისთვის, შესაბამისად თქვენ ვერ შეძლებთ რედაქტირებას ამ მომენტში.'''\nსასურველია ტექსტის ასლი შეინახოთ ტექსტურ რედაქტორში და მოგვიანებით შემოიტანოთ.\n\nმონაცემთა ბაზის დამბლოკველმა ადმინისტრატორმა შემდეგი კომენტარი დატოვა: $1",
        "protectedpagewarning": "'''ყურადღება:  ეს გვერდი დაბლოკილია და მისი რედაქტირება შეუძლიათ მხოლოდ მომხმარებლებს ადმინისტრატორის უფლებებით'''\nიხილეთ დაცვის ჟურნალის ჩანაწერი",
index 5d881be..a595f86 100644 (file)
        "upload-http-error": "HTTP қатесі кездесті: $1",
        "upload-copy-upload-invalid-domain": "Бұл домейннен еселеп жүктеу қолжетімді емес.",
        "upload-dialog-title": "Файл жүктеу",
-       "upload-dialog-error": "Белгісіз қате кездесті",
-       "upload-dialog-warning": "Ескерту кездесті",
        "upload-dialog-button-cancel": "Қажет емес",
        "upload-dialog-button-done": "Бітті",
        "upload-dialog-button-save": "Сақтау",
        "upload-dialog-button-upload": "Жүктеу",
-       "upload-dialog-label-select-file": "Файлды таңдау",
-       "upload-dialog-label-infoform-title": "Егжей-тегжейі",
-       "upload-dialog-label-infoform-name": "Атауы",
-       "upload-dialog-label-infoform-description": "Сипаттамасы",
-       "upload-dialog-label-usage-title": "Қолданылуы",
-       "upload-dialog-label-usage-filename": "Файл атауы",
+       "upload-process-error": "Белгісіз қате кездесті",
+       "upload-process-warning": "Ескерту кездесті",
+       "upload-form-label-select-file": "Файлды таңдау",
+       "upload-form-label-infoform-title": "Егжей-тегжейі",
+       "upload-form-label-infoform-name": "Атауы",
+       "upload-form-label-infoform-description": "Сипаттамасы",
+       "upload-form-label-usage-title": "Қолданылуы",
+       "upload-form-label-usage-filename": "Файл атауы",
        "backend-fail-stream": "«$1» файлы ақпады.",
        "backend-fail-backup": "«$1» файлының сақтық есесі жасалмады.",
        "backend-fail-notexists": "$1 файлы бар емес.",
index 0cc83c4..c703b25 100644 (file)
        "upload-too-many-redirects": "URLនេះមានតំណភ្ជាប់បញ្ជូនបន្តច្រើនពេកហើយ",
        "upload-http-error": "មានកំហុសHTTPមួយបានកើតឡើង៖ $1",
        "upload-dialog-title": "ផ្ទុកឯកសារឡើង",
-       "upload-dialog-error": "មានបញ្ហាកើតឡើង",
-       "upload-dialog-warning": "មានការព្រមាន",
        "upload-dialog-button-cancel": "បោះបង់",
        "upload-dialog-button-done": "រួចរាល់",
        "upload-dialog-button-save": "រក្សាទុក",
        "upload-dialog-button-upload": "ផ្ទុកឡើង",
-       "upload-dialog-label-select-file": "ជ្រើសរើសឯកសារ",
-       "upload-dialog-label-infoform-title": "ព័ត៌មាន​លំអិត",
-       "upload-dialog-label-infoform-name": "ឈ្មោះ​",
-       "upload-dialog-label-infoform-description": "ការ​ពិពណ៌នា",
-       "upload-dialog-label-usage-title": "បម្រើបម្រាស់",
-       "upload-dialog-label-usage-filename": "ឈ្មោះឯកសារ",
+       "upload-process-error": "មានបញ្ហាកើតឡើង",
+       "upload-process-warning": "មានការព្រមាន",
+       "upload-form-label-select-file": "ជ្រើសរើសឯកសារ",
+       "upload-form-label-infoform-title": "ព័ត៌មាន​លំអិត",
+       "upload-form-label-infoform-name": "ឈ្មោះ​",
+       "upload-form-label-infoform-description": "ការ​ពិពណ៌នា",
+       "upload-form-label-usage-title": "បម្រើបម្រាស់",
+       "upload-form-label-usage-filename": "ឈ្មោះឯកសារ",
        "backend-fail-notexists": "គ្មានឯកសារ \"$1\" ទេ។",
        "backend-fail-notsame": "ឯកសារដែលមិនដូចគ្នាបេះបិទមួយមានរួចហើយនៅ \"$1\"។",
        "backend-fail-delete": "មិនអាចលុបឯកសារ \"$1\" បានទេ។",
index b45065c..da37a07 100644 (file)
        "nstab-template": "틀",
        "nstab-help": "도움말",
        "nstab-category": "분류",
+       "mainpage-nstab": "대문",
        "nosuchaction": "이러한 명령이 없습니다",
        "nosuchactiontext": "URL에 지정한 명령이 올바르지 않습니다.\nURL을 잘못 입력했거나, 올바르지 않은 링크를 따라갔을 수 있습니다.\n{{SITENAME}}에 사용하는 소프트웨어의 버그가 있을 수 있습니다.",
        "nosuchspecialpage": "해당하는 특수 문서가 없습니다.",
        "createacct-captcha": "보안 검사",
        "createacct-imgcaptcha-ph": "위에 보이는 텍스트를 입력하세요",
        "createacct-submit": "계정 만들기",
-       "createacct-another-submit": "다른 계정 만들기",
+       "createacct-another-submit": "계정 만들기",
        "createacct-benefit-heading": "{{SITENAME}} 프로젝트는 여러분과 같은 사람들이 만듭니다.",
        "createacct-benefit-body1": "{{PLURAL:$1|편집}}",
        "createacct-benefit-body2": "{{PLURAL:$1|문서}}",
        "changeemail-password": "{{SITENAME}} 비밀번호:",
        "changeemail-submit": "이메일 주소 바꾸기",
        "changeemail-throttled": "로그인에 연속으로 너무 많이 실패하였습니다.\n$1 기다렸다가 다시 시도하세요.",
+       "changeemail-nochange": "다른 이메일 주소를 입력해 주세요.",
        "resettokens": "토큰 재설정",
        "resettokens-text": "여기에 당신의 계정과 관련된 특정 개인 데이터에 접근을 허용하는 토큰을 재설정합니다.\n\n토큰이 다른 사람에게 알려졌거나 계정이 침해되었을 때는 재설정해야 합니다.",
        "resettokens-no-tokens": "재설정할 토큰이 없습니다.",
        "rows": "줄 수:",
        "columns": "열 수:",
        "searchresultshead": "검색",
-       "stub-threshold": "링크를 <a href=\"#\" class=\"stub\">토막글</a> 형식으로 보여줄 문서 크기 (바이트 수):",
+       "stub-threshold": "링크를 토막글 형식으로 보여줄 문서 크기 ($1):",
+       "stub-threshold-sample-link": "샘플",
        "stub-threshold-disabled": "비활성화됨",
        "recentchangesdays": "최근 바뀜에 보여줄 날짜 수:",
        "recentchangesdays-max": "최대 $1{{PLURAL:$1|일}}",
        "upload-http-error": "HTTP 오류 발생: $1",
        "upload-copy-upload-invalid-domain": "이 도메인에 속하지 않는 웹사이트의 파일을 올릴 수 없습니다.",
        "upload-dialog-title": "파일 올리기",
-       "upload-dialog-error": "오류가 발생했습니다",
-       "upload-dialog-warning": "경고가 일어났습니다",
        "upload-dialog-button-cancel": "취소",
        "upload-dialog-button-done": "완료",
        "upload-dialog-button-save": "저장",
        "upload-dialog-button-upload": "올리기",
-       "upload-dialog-label-select-file": "파일을 선택해주세요.",
-       "upload-dialog-label-infoform-title": "자세한 사항",
-       "upload-dialog-label-infoform-name": "이름",
-       "upload-dialog-label-infoform-description": "설명",
-       "upload-dialog-label-usage-title": "사용",
-       "upload-dialog-label-usage-filename": "파일 이름",
+       "upload-process-error": "오류가 발생했습니다",
+       "upload-process-warning": "경고가 일어났습니다",
+       "upload-form-label-select-file": "파일을 선택해주세요.",
+       "upload-form-label-infoform-title": "자세한 사항",
+       "upload-form-label-infoform-name": "이름",
+       "upload-form-label-infoform-description": "설명",
+       "upload-form-label-usage-title": "사용",
+       "upload-form-label-usage-filename": "파일 이름",
        "backend-fail-stream": "\"$1\" 파일을 스트림할 수 없습니다.",
        "backend-fail-backup": "\"$1\" 파일을 백업할 수 없습니다.",
        "backend-fail-notexists": "$1 파일이 존재하지 않습니다.",
        "filerevert-legend": "파일 되돌리기",
        "filerevert-intro": "'''[[Media:$1|$1]]''' 파일을 [$4 $2 $3 버전]으로 되돌립니다.",
        "filerevert-comment": "이유:",
-       "filerevert-defaultcomment": "$1 $2 판으로 되돌림",
+       "filerevert-defaultcomment": "$1 $2 ($3) 판으로 되돌림",
        "filerevert-submit": "되돌리기",
        "filerevert-success": "'''[[Media:$1|$1]]''' 파일을 [$4 $2 $3 버전]으로 되돌렸습니다.",
        "filerevert-badversion": "입력된 시간 기록을 가진 파일의 로컬 버전이 없습니다.",
        "booksources-text": "아래의 목록은 새 책이나 중고 책을 판매하는 바깥 사이트로, 원하는 책의 정보를 얻을 수 있습니다.",
        "booksources-invalid-isbn": "입력한 ISBN이 올바르지 않은 것으로 보입니다. 원본과 대조해 문제가 있는지 확인해보세요.",
        "specialloguserlabel": "작업 수행자:",
-       "speciallogtitlelabel": "대상 (제목 또는 사용자):",
+       "speciallogtitlelabel": "대상 (제목 또는 {{ns:user}}:사용자_이름 으로사용자):",
        "log": "기록 목록",
        "all-logs-page": "모든 공개 기록",
        "alllogstext": "{{SITENAME}}에서의 기록이 모두 나와 있습니다.\n기록 종류, 사용자 이름, 문서 이름을 선택해서 볼 수 있습니다. (대소문자를 구별합니다.)",
        "api-error-badaccess-groups": "이 위키에 파일을 올릴 권한이 없습니다.",
        "api-error-badtoken": "내부 오류: 토큰이 잘못되었습니다.",
        "api-error-copyuploaddisabled": "이 서버에서 URL을 통해 파일 올리기가 비활성화되어 있습니다.",
-       "api-error-duplicate": "이 위키에 내용이 똑같은 {{PLURAL:$1|[$2 다른 파일]}}이 있습니다.",
+       "api-error-duplicate": "이 위키에 내용이 똑같은 {{PLURAL:$1|다른 파일}}이 있습니다.",
        "api-error-duplicate-archive": "같은 내용을 담고 있던 {{PLURAL:$1|다른 파일}}이 있었지만 이 {{PLURAL:$1|파일}}은 삭제되었습니다.",
        "api-error-empty-file": "올리려는 파일이 비어 있습니다.",
        "api-error-emptypage": "새 문서로 빈 문서를 만들 수 없습니다.",
index 8269b09..140d80a 100644 (file)
        "upload-http-error": "Ene <i lang=\"en\">HTTP</i>-Fäähler es opjetrodde: $1",
        "upload-copy-upload-invalid-domain": "Fun dä Domain künne mer nix noh heh huh laade. Di es nit zohjelohße.",
        "upload-dialog-title": "Dateij huhlahde",
-       "upload-dialog-error": "Ene Fähler es opjetrodde",
-       "upload-dialog-warning": "En Warnong wood ußjejovve.",
        "upload-dialog-button-cancel": "Ophühre!",
        "upload-dialog-button-done": "Jedonn",
        "upload-dialog-button-save": "Faßhalde",
        "upload-dialog-button-upload": "Lohß Jonn!",
-       "upload-dialog-label-select-file": "De ußjesöhk Dattei",
-       "upload-dialog-label-infoform-title": "Eijnzelheijte",
-       "upload-dialog-label-infoform-name": "Nahme",
-       "upload-dialog-label-infoform-description": "Äkliehrong",
-       "upload-dialog-label-usage-title": "Der Jebruch",
-       "upload-dialog-label-usage-filename": "Dä Dattei iehre Nahme",
+       "upload-process-error": "Ene Fähler es opjetrodde",
+       "upload-process-warning": "En Warnong wood ußjejovve.",
+       "upload-form-label-select-file": "De ußjesöhk Dattei",
+       "upload-form-label-infoform-title": "Eijnzelheijte",
+       "upload-form-label-infoform-name": "Nahme",
+       "upload-form-label-infoform-description": "Äkliehrong",
+       "upload-form-label-usage-title": "Der Jebruch",
+       "upload-form-label-usage-filename": "Dä Dattei iehre Nahme",
        "backend-fail-stream": "Mer kunnte di Dattei $1 nit övverdraare.",
        "backend-fail-backup": "Mer kunnte kein Sescherongskopih vun dä Dattei $1 maache.",
        "backend-fail-notexists": "En Dattei $1 jidd et nit.",
        "version-entrypoints": "<i lang=\"en\" xml:lang=\"en\">URL</i>s för enzeschteije",
        "version-entrypoints-header-entrypoint": "Enschteesch",
        "version-entrypoints-header-url": "<i lang=\"en\">URL</i>",
-       "version-entrypoints-articlepath": "[https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:$wgArticlePath Der Pad noh de Atikele]",
+       "version-entrypoints-articlepath": "[https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:$wgArticlePath Der Pahd noh de Atikele]",
        "version-entrypoints-scriptpath": "[https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:$wgScriptPath Der Pahd noh de Skrepte]",
        "version-libraries": "Enschtallehrte Projrammsammlonge",
        "version-libraries-library": "Projrammsammlong",
index b1a78f5..4cfa465 100644 (file)
        "upload-http-error": "Et ass en HTTP-Feeler geschitt: $1",
        "upload-copy-upload-invalid-domain": "Vun dësem Domain ass d'Eropluede vu Kopien net méiglech.",
        "upload-dialog-title": "Fichier eroplueden",
-       "upload-dialog-error": "Et ass e Feeler geschitt",
-       "upload-dialog-warning": "Eng Warnung gouf ausgeschwat",
        "upload-dialog-button-cancel": "Ofbriechen",
        "upload-dialog-button-done": "Fäerdeg",
        "upload-dialog-button-save": "Späicheren",
        "upload-dialog-button-upload": "Eroplueden",
-       "upload-dialog-label-select-file": "Fichier eraussichen",
-       "upload-dialog-label-infoform-title": "Detailer",
-       "upload-dialog-label-infoform-name": "Numm",
-       "upload-dialog-label-infoform-description": "Beschreiwung",
-       "upload-dialog-label-usage-title": "Benotzung",
-       "upload-dialog-label-usage-filename": "Numm vum Fichier",
+       "upload-process-error": "Et ass e Feeler geschitt",
+       "upload-process-warning": "Eng Warnung gouf ausgeschwat",
+       "upload-form-label-select-file": "Fichier eraussichen",
+       "upload-form-label-infoform-title": "Detailer",
+       "upload-form-label-infoform-name": "Numm",
+       "upload-form-label-infoform-description": "Beschreiwung",
+       "upload-form-label-usage-title": "Benotzung",
+       "upload-form-label-usage-filename": "Numm vum Fichier",
        "backend-fail-stream": "De Fichier $1 konnt net iwwerdroe ginn.",
        "backend-fail-backup": "De Fichier $1 konnt net geséchert ginn.",
        "backend-fail-notexists": "De Fichier $1 gëtt et net.",
index 29dad5a..b3f22db 100644 (file)
                        "Aswanas",
                        "Pofka",
                        "Albertas",
-                       "Macofe"
+                       "Macofe",
+                       "Zygimantus"
                ]
        },
-       "tog-underline": "Pabraukti nuorodas:",
+       "tog-underline": "Nuorodos pabraukimas:",
        "tog-hideminor": "Slėpti smulkius pakeitimus naujausių keitimų sąraše",
        "tog-hidepatrolled": "Slėpti patikrintus keitimus paskutinių keitimų sąraše",
        "tog-newpageshidepatrolled": "Slėpti patikrintus puslapius iš naujausių straipsnių sąrašo",
        "sat": "Šeš",
        "january": "sausio",
        "february": "vasario",
-       "march": "Kovo",
+       "march": "kovo",
        "april": "balandžio",
        "may_long": "gegužės",
        "june": "birželio",
        "july": "liepos",
        "august": "rugpjūčio",
-       "september": "Rugsėjo",
+       "september": "rugsėjo",
        "october": "spalio",
        "november": "lapkričio",
        "december": "gruodžio",
        "cancel": "Atšaukti",
        "moredotdotdot": "Daugiau...",
        "morenotlisted": "Šis sąrašas nėra išsamus.",
-       "mypage": "Naudotojo puslapis",
-       "mytalk": "Mano aptarimas",
+       "mypage": "Puslapis",
+       "mytalk": "Aptarimas",
        "anontalk": "Šio IP aptarimas",
        "navigation": "Naršymas",
        "and": "&#32;ir",
        "create-this-page": "Sukurti šį puslapį",
        "delete": "Trinti",
        "deletethispage": "Ištrinti šį puslapį",
-       "undeletethispage": "Attrinti šį puslapį",
+       "undeletethispage": "Atkurti šį puslapį",
        "undelete_short": "Atkurti $1 {{PLURAL:$1:redagavimą|redagavimus|redagavimų}}",
        "viewdeleted_short": "Peržiūrėti $1 {{PLURAL:$1|ištrintą keitimą|ištrintus keitimus|ištrintų keitimų}}",
        "protect": "Užrakinti",
        "pool-servererror": "Saugyklos skaitiklio paslauga negalima ($1).",
        "poolcounter-usage-error": "Naudojimo klaida: $1",
        "aboutsite": "Apie {{SITENAME}}",
-       "aboutpage": "Project:About",
+       "aboutpage": "Project:Apie",
        "copyright": "Turinys pateikiamas pagal  $1  jei nenurodyta kitaip.",
        "copyrightpage": "{{ns:project}}:Autorinės teisės",
        "currentevents": "Naujienos",
        "databaseerror": "Duomenų bazės klaida",
        "databaseerror-text": "Įvyko duomenų bazės klaida.\nTai gali rodyti programinės įrangos sutrikimą.",
        "databaseerror-textcl": "Įvyko duomenų bazės klaida.",
-       "databaseerror-query": "Užklausa:$1",
+       "databaseerror-query": "Užklausa: $1",
        "databaseerror-function": "Paskirtis: $1",
        "databaseerror-error": "Klaida: $1",
        "laggedslavemode": "Dėmesio: Puslapyje gali nesimatyti naujausių pakeitimų.",
        "permissionserrorstext-withaction": "Jūs neturite leidimo $2 dėl {{PLURAL:$1|šios priežasties|šių priežasčių}}:",
        "recreate-moveddeleted-warn": "'''Dėmesio: Jūs atkuriate puslapį, kuris anksčiau buvo ištrintas.'''\n\nTurėtumėte nuspręsti, ar reikėtų toliau redaguoti šį puslapį.\nJūsų patogumui čia pateikiamas šio puslapio šalinimų ir perkėlimų sąrašas:",
        "moveddeleted-notice": "Šis puslapis buvo ištrintas.\nŽemiau pateikiamas puslapio šalinimų ir pervadinimų sąrašas.",
+       "moveddeleted-notice-recent": "Atsiprašome, šis puslapis pastaruoju metu buvo ištrintas (per pastarąsias 24 valandas). Puslapio ištrynimo ir perkėlimo istorija yra pateikiama žemiau kaip nuoroda.",
        "log-fulllog": "Rodyti visą istoriją",
        "edit-hook-aborted": "Keitimas nutrauktas užlūžimo.\nTam nėra paaiškinimo.",
        "edit-gone-missing": "Negalima atnaujinti puslapio.\nGreičiausiai jis yra ištrintas.",
        "upload-http-error": "Įvyko HTTP klaida: $1",
        "upload-copy-upload-invalid-domain": "Pakrovimų kopijos yra neleidžiamos iš šio domeno.",
        "upload-dialog-title": "Įkelti failą",
-       "upload-dialog-error": "Įvyko klaida",
-       "upload-dialog-warning": "Įvyko įspėjimas",
        "upload-dialog-button-cancel": "Atšaukti",
        "upload-dialog-button-done": "Atlikta",
        "upload-dialog-button-save": "Išsaugoti",
        "upload-dialog-button-upload": "Įkelti",
-       "upload-dialog-label-select-file": "Pasirinkti failą",
-       "upload-dialog-label-infoform-title": "Detalės",
-       "upload-dialog-label-infoform-name": "Pavadinimas",
-       "upload-dialog-label-infoform-description": "Aprašymas",
-       "upload-dialog-label-usage-title": "Naudojimas",
-       "upload-dialog-label-usage-filename": "Failo pavadinimas",
+       "upload-process-error": "Įvyko klaida",
+       "upload-process-warning": "Įvyko įspėjimas",
+       "upload-form-label-select-file": "Pasirinkti failą",
+       "upload-form-label-infoform-title": "Detalės",
+       "upload-form-label-infoform-name": "Pavadinimas",
+       "upload-form-label-infoform-description": "Aprašymas",
+       "upload-form-label-usage-title": "Naudojimas",
+       "upload-form-label-usage-filename": "Failo pavadinimas",
        "backend-fail-stream": "Negali būti apdorotas failas $1.",
        "backend-fail-backup": "Negali būti išsaugotas failas $1.",
        "backend-fail-notexists": "Failas $1 neegzistuoja.",
index 1d8f185..fbe61bb 100644 (file)
        "upload-dialog-button-done": "Gatavs",
        "upload-dialog-button-save": "Saglabāt",
        "upload-dialog-button-upload": "Augšupielādēt",
-       "upload-dialog-label-select-file": "Izvēlieties file",
-       "upload-dialog-label-infoform-title": "Papildinformācija",
-       "upload-dialog-label-infoform-description": "Apraksts",
-       "upload-dialog-label-usage-title": "Pielietojums",
-       "upload-dialog-label-usage-filename": "Faila nosaukums",
+       "upload-form-label-select-file": "Izvēlieties file",
+       "upload-form-label-infoform-title": "Papildinformācija",
+       "upload-form-label-infoform-description": "Apraksts",
+       "upload-form-label-usage-title": "Pielietojums",
+       "upload-form-label-usage-filename": "Faila nosaukums",
        "backend-fail-stream": "Nevar straumēt failu $1.",
        "backend-fail-backup": "Nevar dublēt failu $1.",
        "backend-fail-notexists": "Fails $1 nepastāv.",
index f427852..6487b45 100644 (file)
        "upload-http-error": "Nisy tsy fetezana HTTP nitranga : $1",
        "upload-copy-upload-invalid-domain": "Tsy misy eto amin'ity dômenina ity ny tahaky ny upload.",
        "upload-dialog-title": "Hanafatra rakitra",
-       "upload-dialog-error": "Nisy hadisoana nitranga",
-       "upload-dialog-warning": "Nisy fampitandremana nitranga",
        "upload-dialog-button-cancel": "Aoka",
        "upload-dialog-button-done": "Vita",
        "upload-dialog-button-save": "Tehirizina",
        "upload-dialog-button-upload": "Mampiditra",
-       "upload-dialog-label-select-file": "Hifidy rakitra",
-       "upload-dialog-label-infoform-title": "Antsipirihany",
-       "upload-dialog-label-infoform-name": "Anarana",
-       "upload-dialog-label-infoform-description": "Famisavisana",
-       "upload-dialog-label-usage-title": "Fampiasana",
-       "upload-dialog-label-usage-filename": "Anaran-drakitra",
+       "upload-process-error": "Nisy hadisoana nitranga",
+       "upload-process-warning": "Nisy fampitandremana nitranga",
+       "upload-form-label-select-file": "Hifidy rakitra",
+       "upload-form-label-infoform-title": "Antsipirihany",
+       "upload-form-label-infoform-name": "Anarana",
+       "upload-form-label-infoform-description": "Famisavisana",
+       "upload-form-label-usage-title": "Fampiasana",
+       "upload-form-label-usage-filename": "Anaran-drakitra",
        "backend-fail-stream": "Tsy afaka mamaky ilay rakitra $1.",
        "backend-fail-backup": "Tsy afaka mitahiry ilay rakitra $1.",
        "backend-fail-notexists": "Tsy misy ilay rakitra $1.",
index a7628ba..a339220 100644 (file)
        "upload-http-error": "Се појави грешка во HTTP: $1.",
        "upload-copy-upload-invalid-domain": "Примероци од подигањата не се достапни на овој домен.",
        "upload-dialog-title": "Подигни податотека",
-       "upload-dialog-error": "Се појави грешка",
-       "upload-dialog-warning": "Се јави предупредување",
        "upload-dialog-button-cancel": "Откажи",
        "upload-dialog-button-done": "Готово",
        "upload-dialog-button-save": "Зачувај",
        "upload-dialog-button-upload": "Подигни",
-       "upload-dialog-label-select-file": "Одберете податотека",
-       "upload-dialog-label-infoform-title": "Подробно",
-       "upload-dialog-label-infoform-name": "Назив",
-       "upload-dialog-label-infoform-description": "Опис",
-       "upload-dialog-label-usage-title": "Употреба",
-       "upload-dialog-label-usage-filename": "Назив на податотеката",
+       "upload-process-error": "Се појави грешка",
+       "upload-process-warning": "Се јави предупредување",
+       "upload-form-label-select-file": "Одберете податотека",
+       "upload-form-label-infoform-title": "Подробно",
+       "upload-form-label-infoform-name": "Назив",
+       "upload-form-label-infoform-description": "Опис",
+       "upload-form-label-usage-title": "Употреба",
+       "upload-form-label-usage-filename": "Назив на податотеката",
        "backend-fail-stream": "Не можев да ја емитувам податотеката $1.",
        "backend-fail-backup": "Не можев да направам резерва на податотеката $1.",
        "backend-fail-notexists": "Податотеката $1 не постои.",
index 791ce8b..1787ec7 100644 (file)
        "upload-http-error": "ഒരു എച്ച്.റ്റി.റ്റി.പി. പിഴവു സംഭവിച്ചിരിക്കുന്നു: $1",
        "upload-copy-upload-invalid-domain": "ഈ ഡൊമൈനിൽ നിന്നും പകർത്തി അപ്‌ലോഡ് ചെയ്യൽ ലഭ്യമല്ല.",
        "upload-dialog-title": "പ്രമാണം അപ്‌ലോഡ് ചെയ്യുക",
-       "upload-dialog-error": "ഒരു പിഴവുണ്ടായി",
-       "upload-dialog-warning": "ഒരു മുന്നറിയിപ്പുണ്ടായി",
        "upload-dialog-button-cancel": "റദ്ദാക്കുക",
        "upload-dialog-button-done": "ചെയ്തു കഴിഞ്ഞു",
        "upload-dialog-button-save": "സേവ് ചെയ്യുക",
        "upload-dialog-button-upload": "അപ്‌‌ലോഡ്",
-       "upload-dialog-label-select-file": "പ്രമാണം തിരഞ്ഞെടുക്കുക",
-       "upload-dialog-label-infoform-title": "വിശദാംശങ്ങൾ",
-       "upload-dialog-label-infoform-name": "പേര്‌",
-       "upload-dialog-label-infoform-description": "വിവരണം",
-       "upload-dialog-label-usage-title": "ഉപയോഗം",
-       "upload-dialog-label-usage-filename": "പ്രമാണത്തിന്റെ പേര്",
+       "upload-process-error": "ഒരു പിഴവുണ്ടായി",
+       "upload-process-warning": "ഒരു മുന്നറിയിപ്പുണ്ടായി",
+       "upload-form-label-select-file": "പ്രമാണം തിരഞ്ഞെടുക്കുക",
+       "upload-form-label-infoform-title": "വിശദാംശങ്ങൾ",
+       "upload-form-label-infoform-name": "പേര്‌",
+       "upload-form-label-infoform-description": "വിവരണം",
+       "upload-form-label-usage-title": "ഉപയോഗം",
+       "upload-form-label-usage-filename": "പ്രമാണത്തിന്റെ പേര്",
        "backend-fail-stream": "$1 എന്ന പ്രമാണം സ്ട്രീം ചെയ്യാൻ കഴിഞ്ഞില്ല.",
        "backend-fail-backup": "$1 എന്ന പ്രമാണത്തിന്റെ ബാക്ക്അപ് എടുക്കാൻ കഴിഞ്ഞില്ല.",
        "backend-fail-notexists": "$1 എന്ന പ്രമാണം നിലവിലില്ല.",
index df571ba..0047452 100644 (file)
        "destfilename": "Tōcāhuīc:",
        "watchthisupload": "Tictlachiyāz inīn zāzanilli",
        "upload-success-subj": "Cualli quetzaliztli",
-       "upload-dialog-label-infoform-name": "Tōcāitl",
-       "upload-dialog-label-usage-filename": "Ihcuilōlli ītōcā",
+       "upload-form-label-infoform-name": "Tōcāitl",
+       "upload-form-label-usage-filename": "Ihcuilōlli ītōcā",
        "upload_source_file": " (cē tlahcuilōlli mochīuhpōhualhuazco)",
        "listfiles_search_for": "Tlatēmōz mēdiatl tōcācopa:",
        "imgfile": "īxiptli",
index 213135f..de16baa 100644 (file)
        "createacct-captcha": "Cuntrollo 'e sicurezza",
        "createacct-imgcaptcha-ph": "Scrivite 'o testo ca vedite ncoppa",
        "createacct-submit": "Cria 'a toja utenza",
-       "createacct-another-submit": "Cria n'atu cunto",
+       "createacct-another-submit": "Cria nu cunto",
        "createacct-benefit-heading": "{{SITENAME}} è fatta 'e perzone comme te.",
        "createacct-benefit-body1": "{{PLURAL:$1|càgnamiento|càgnamiente}}",
        "createacct-benefit-body2": "{{PLURAL:$1|paggena|paggene}}",
        "group-bot": "Bot",
        "group-sysop": "Ammenistrature",
        "group-bureaucrat": "Burocrate",
-       "group-suppress": "Oversight",
+       "group-suppress": "Soppressure",
        "group-all": "(tutte)",
        "group-user-member": "{{GENDER:$1|utente}}",
        "group-autoconfirmed-member": "{{GENDER:$1|utente autocunfermato|utente autocunfermata|utente autocunfermato/a}}",
        "group-bot-member": "{{GENDER:$1|bot}}",
        "group-sysop-member": "{{GENDER:$1|ammenistratore|ammenistratrice|ammenistratore/trice}}",
        "group-bureaucrat-member": "{{GENDER:$1|burocrate}}",
-       "group-suppress-member": "{{GENDER:$1|oversight}}",
+       "group-suppress-member": "{{GENDER:$1|suppressure|supprimitrice}}",
        "grouppage-user": "{{ns:project}}:Utente",
        "grouppage-autoconfirmed": "{{ns:project}}:Utente autocunfermate",
        "grouppage-bot": "{{ns:project}}:Bot",
        "grouppage-sysop": "{{ns:project}}:Ammenistrature",
        "grouppage-bureaucrat": "{{ns:project}}:Burocrate",
-       "grouppage-suppress": "{{ns:project}}:Oversight",
+       "grouppage-suppress": "{{ns:project}}:Suppressure",
        "right-read": "Liegge paggene",
        "right-edit": "Cagna paggene",
        "right-createpage": "Crìa paggene (ca nun songo paggene 'e chiacchiera)",
        "upload-http-error": "N'errore HTTP è succiesso: $1",
        "upload-copy-upload-invalid-domain": "Nun è permessa 'a carreca 'e copie 'a chistu dumminio.",
        "upload-dialog-title": "Carreca file",
-       "upload-dialog-error": "N'errore cumparette",
-       "upload-dialog-warning": "N'avviso cumparette",
        "upload-dialog-button-cancel": "Canciella",
        "upload-dialog-button-done": "Fatto",
        "upload-dialog-button-save": "Sarva",
        "upload-dialog-button-upload": "Carreca",
-       "upload-dialog-label-select-file": "Sceglie file",
-       "upload-dialog-label-infoform-title": "Dettaglie",
-       "upload-dialog-label-infoform-name": "Nomme",
-       "upload-dialog-label-infoform-description": "Descrizzione",
-       "upload-dialog-label-usage-title": "Aúso",
-       "upload-dialog-label-usage-filename": "Nomme d' 'o file",
+       "upload-process-error": "N'errore cumparette",
+       "upload-process-warning": "N'avviso cumparette",
+       "upload-form-label-select-file": "Sceglie file",
+       "upload-form-label-infoform-title": "Dettaglie",
+       "upload-form-label-infoform-name": "Nomme",
+       "upload-form-label-infoform-description": "Descrizzione",
+       "upload-form-label-usage-title": "Aúso",
+       "upload-form-label-usage-filename": "Nomme d' 'o file",
        "backend-fail-stream": "Nun se può mannà 'o file \"$1\".",
        "backend-fail-backup": "Nun se può ffà 'o backup d' 'o file \"$1\".",
        "backend-fail-notexists": "'O file $1 nun esiste.",
        "filerevert-legend": "Arrepiglia 'o file",
        "filerevert-intro": "State arrepiglianno 'o file '''[[Media:$1|$1]]''' int' 'a [$4 verzione d' 'o $3, $2].",
        "filerevert-comment": "Mutive:",
-       "filerevert-defaultcomment": "Arripigliata 'a verzione d' 'o $2, $1",
+       "filerevert-defaultcomment": "Turnata 'a verzione comm' 'o $2, $1 ($3)",
        "filerevert-submit": "Arrepiglia",
        "filerevert-success": "'''[[Media:$1|$1]]''' è stat'arripigliato â verziona [$4 d' 'e $3 d' 'o $2].",
        "filerevert-badversion": "Nun ce sta na virziona lucale 'e stu file cu l'orario addimannato.",
        "nopagetext": "'A paggena 'e destinazione c'avite specificato nun esiste.",
        "pager-newer-n": "{{PLURAL:$1|1 cchiù nova|$1 cchiù nnove}}",
        "pager-older-n": "{{PLURAL:$1|1 cchiù viecchio|$1 cchiù viecchie}}",
-       "suppress": "Supervisione",
+       "suppress": "Supprime",
        "querypage-disabled": "Sta paggena speciale è stutata pe' mutive 'e prestaziune.",
        "apihelp": "Ajuto cu l'API",
        "apihelp-no-such-module": "'O modulo \"$1\" nun se trova.",
        "emailccsubject": "Copia d' 'a mmasciata tua 'a $1: $2",
        "emailsent": "Mmasciata e-mail mannata",
        "emailsenttext": "'A mmasciata d' 'a toja s'è mannata.",
-       "emailuserfooter": "Chista mmasciata e-mail è stata mannata 'a $1 a $2 p' 'a funziona \"{{int:emailuser}}\" 'e {{SITENAME}}.",
+       "emailuserfooter": "Chista mmasciata e-mail è stata {{GENDER:$1|mannata}} 'a $1 a {{GENDER:$2|$2}} p' 'a funziona \"{{int:emailuser}}\" 'e {{SITENAME}}.",
        "usermessage-summary": "Lassanno na mmasciata 'e sistema.",
        "usermessage-editor": "Mmasciatore d' 'o sistema",
        "watchlist": "Paggene cuntrullate",
index 6e3d661..77f6b64 100644 (file)
        "nstab-template": "Sjabloon",
        "nstab-help": "Hulppagina",
        "nstab-category": "Categorie",
+       "mainpage-nstab": "Hoofdpagina",
        "nosuchaction": "Opgegeven handeling bestaat niet",
        "nosuchactiontext": "De opdracht in de URL is ongeldig.\nMogelijk heeft u een typefout gemaakt in de URL of een onjuiste koppeling gevolgd.\nHet kan ook wijzen op een fout in de software van {{SITENAME}}.",
        "nosuchspecialpage": "Deze speciale pagina bestaat niet",
        "upload-http-error": "Er is een HTTP-fout opgetreden: $1",
        "upload-copy-upload-invalid-domain": "Uploaden per kopie is niet beschikbaar vanuit dit domein.",
        "upload-dialog-title": "Bestand uploaden",
-       "upload-dialog-error": "Er is een fout opgetreden",
-       "upload-dialog-warning": "Een waarschuwing is opgetreden",
        "upload-dialog-button-cancel": "Annuleren",
        "upload-dialog-button-done": "Afgerond",
        "upload-dialog-button-save": "Opslaan",
        "upload-dialog-button-upload": "Upload",
-       "upload-dialog-label-select-file": "Selecteer bestand",
-       "upload-dialog-label-infoform-title": "Details",
-       "upload-dialog-label-infoform-name": "Naam",
-       "upload-dialog-label-infoform-description": "Beschrijving",
-       "upload-dialog-label-usage-title": "Gebruik",
-       "upload-dialog-label-usage-filename": "Bestandsnaam",
+       "upload-process-error": "Er is een fout opgetreden",
+       "upload-process-warning": "Een waarschuwing is opgetreden",
+       "upload-form-label-select-file": "Selecteer bestand",
+       "upload-form-label-infoform-title": "Details",
+       "upload-form-label-infoform-name": "Naam",
+       "upload-form-label-infoform-description": "Beschrijving",
+       "upload-form-label-usage-title": "Gebruik",
+       "upload-form-label-usage-filename": "Bestandsnaam",
        "backend-fail-stream": "Het was niet mogelijk het bestand \"$1\" te streamen.",
        "backend-fail-backup": "Het was niet mogelijk een reservekopie van het bestand $1 te maken.",
        "backend-fail-notexists": "Het bestand $1 bestaat niet.",
index f593f3c..e411a97 100644 (file)
@@ -27,7 +27,7 @@
        "tog-norollbackdiff": "Älä ozuta eroloi, konzu olet ottanuh järilleh aijemban versien järilleh tuondu -toimindol",
        "underline-always": "Ainos",
        "underline-never": "Nikonzu",
-       "editfont-style": "Edituičendualovehen kirjainstiilu:",
+       "editfont-style": "Edituičendualovehen kirjainstiil'u:",
        "editfont-sansserif": "Sans-serif -fontu",
        "editfont-serif": "Serif-fontu",
        "sunday": "Pyhäpäivy",
        "listingcontinuesabbrev": "(jatko)",
        "index-category": "Indeksiruitut sivut",
        "noindex-category": "Indeksiruičemattomat sivut",
-       "broken-file-category": "Sivut, kudamil on ruadamattomii failulinkilöi",
+       "broken-file-category": "Sivut, kudamil on avuamattomii failulinkilöi",
        "about": "Tieduo sovellukses",
        "article": "Yhtevyssivu",
        "newwindow": "(avata uvves ikkunas)",
        "morenotlisted": "Tämä listu ei ole valmis.",
        "mypage": "Sivu",
        "mytalk": "Pagin",
-       "anontalk": "Paginsivutälle IP-adressile",
+       "anontalk": "Paginsivu tälle IP-adressile",
        "navigation": "Navigatsii",
        "and": "&#32;da",
        "qbfind": "Eči",
        "redirectedfrom": "(siirretty $1:späi)",
        "redirectpagesub": "uvvellehohjavussivu",
        "redirectto": "Uvvellehohjuau sivuh:",
-       "lastmodifiedat": "Tädä sivuu on muutettu jälgimäizen kerran $1, $2 aigah.",
+       "lastmodifiedat": "Tädä sivuu on muutettu jälgimäzen kerran $1, $2 aigah.",
        "protectedpage": "Suojattu sivu",
        "jumpto": "Siirry",
        "jumptonavigation": "navigatsii",
        "internalerror": "Syväindölline haireh",
        "internalerror_info": "Syväindölline haireh: $1",
        "filecopyerror": "Failua \"$1\" ei voitu kopiruija failakse \"$2\".",
-       "filerenameerror": "Ei voi uvvellehnimittoä \"$1\"-failua nimele \"$2\".",
+       "filerenameerror": "Ei voi uvvellehnimittiä \"$1\"-failua nimele \"$2\".",
        "filedeleteerror": "Failua \"$1\" ei voitu ottua iäre.",
        "directorycreateerror": "Ei voi luadie al'bomua \"$1\".",
        "directoryreadonlyerror": "Al'bom $1 on kirjutussuojattu.",
        "password-name-match": "Peittosana pidäy olla eri migu käyttäinimi.",
        "password-login-forbidden": "Tämän käyttäinimen da peittosanan käyttö on estetty.",
        "mailmypassword": "Azeta peittosana uvvelleh",
-       "passwordremindertitle": "Uusi väliaigaine peittosana {{SITENAME}}-sivuh niškoi",
-       "passwordremindertext": "Kentah IP-adressispäi $1 kyzyi työndämäh uuttu peittosanua saitale {{SITENAME}} ($4). Väliaigaine peittosana käyttäjäle $2 on nygöi $3. Kirjuttai da vaihta peittosana. Väliaigaine peittosana vahnenou {{PLURAL:$5|yhten päivän|$5 päivän}} jälles.\n\nOllou kentah toine työndänyh tämän pakičuksen, libo ku ollet mustanuh sinun peittosanan da et tahto vaihtua sidä, voit jättiä tämän viestin huomivottah dajatkua vahnan peittosanan käyttyö.",
+       "passwordremindertitle": "Uuzi väliaigaine peittosana {{SITENAME}}-sivuh niškoi",
+       "passwordremindertext": "Kentah IP-adressispäi $1 kyzyi työndämäh uuttu peittosanua saitale {{SITENAME}} ($4). Väliaigaine peittosana käyttäjäle $2 on nygöi $3. Kirjuttai da vaihta peittosana. Väliaigaine peittosana vahnenou {{PLURAL:$5|yhten päivän|$5 päivän}} jälles.\n\nOllou kentah toine työndänyh tämän pakičuksen, libo ku ollet mustanuh sinun peittosanan da et tahto vaihtua sidä, voit jättiä tämän viestin huomivottah da jatkua vahnan peittosanan käyttyö.",
        "mailerror": "Haireh työndäjes sähköpoštua: $1",
        "accountcreated": "Tili luajittu",
        "loginlanguagelabel": "Kieli: $1",
        "changeemail-none": "(niyhty)",
        "changeemail-password": "Sinun {{SITENAME}}-peittosana:",
        "changeemail-submit": "Vaihta sähköpoštu",
-       "changeemail-throttled": "Olet oppinuh kirjuttuakseh liijan moni kerdua. Ole hyvä, vuota $1 enne ku opit uvvelleh.",
+       "changeemail-throttled": "Olet oppinuh kirjuttuakseh liijan moni kerdua. Ole hyvä, vuota $1 enne ku opit uvvessah.",
        "resettokens-tokens": "Avaimet:",
        "bold_sample": "Lihavoitu tekstu",
        "bold_tip": "Lihavoitu tekstu",
        "watchthis": "Tarkaile tädä sivuu",
        "savearticle": "Tallenda sivu",
        "preview": "Ezikačo",
-       "showpreview": "Ezikaččo",
+       "showpreview": "Ezikačo",
        "showdiff": "Luajitut korjavukset",
        "anoneditwarning": "<strong>Varaitus:</strong> Et ole kirjutannuhes. Luadinet muutoksii syväindölöih, sinun Ip-adressu tulou nägövih kaikile. Ku <strong>[$1 kirjutannuttos]</strong> libo <strong>[$2 registriiruičettos]</strong>, sinun syväindömuutokset nävytäh sinun käyttäinimel, toizien eduloin ližäkse.",
        "blockedtitle": "Käyttäi on estetty",
        "filename-tooshort": "Failunimi on liijan lyhyt.",
        "watchthisupload": "Valvo tädä failua",
        "upload-dialog-button-save": "Tallenda",
-       "upload-dialog-label-infoform-title": "Tiijot",
-       "upload-dialog-label-infoform-name": "Nimi",
-       "upload-dialog-label-infoform-description": "Kuvavus",
-       "upload-dialog-label-usage-title": "Käyttö",
-       "upload-dialog-label-usage-filename": "Failunimi",
+       "upload-form-label-infoform-title": "Tiijot",
+       "upload-form-label-infoform-name": "Nimi",
+       "upload-form-label-infoform-description": "Kuvavus",
+       "upload-form-label-usage-title": "Käyttö",
+       "upload-form-label-usage-filename": "Failunimi",
        "license-header": "Licenzii",
        "imgfile": "tiijosto",
        "listfiles_name": "Nimi",
index 9a2588d..788451c 100644 (file)
@@ -38,6 +38,7 @@
        "tog-watchdefault": "ਮੇਰੇ ਵੱਲੋਂ ਸੋਧੇ ਗਏ ਸਫ਼ੇ ਅਤੇ ਫ਼ਾਈਲਾਂ ਮੇਰੀ ਨਿਗਰਾਨੀ-ਲਿਸਟ ਵਿੱਚ ਪਾਓ",
        "tog-watchmoves": "ਮੇਰੇ ਵੱਲੋਂ ਬਦਲੇ ਸਿਰਲੇਖਾਂ ਵਾਲ਼ੇ ਸਫ਼ੇ ਅਤੇ ਫ਼ਾਈਲਾਂ ਮੇਰੀ ਨਿਗਰਾਨੀ-ਲਿਸਟ ਵਿੱਚ ਪਾਓ",
        "tog-watchdeletion": "ਮੇਰੇ ਵਲੋਂ ਮਿਟਾਏ ਗਏ ਸਫ਼ੇ ਅਤੇ ਫ਼ਾਈਲਾਂ ਮੇਰੀ ਨਿਗਰਾਨੀ-ਲਿਸਟ ਵਿੱਚ ਪਾਓ",
+       "tog-watchrollback": "ਮੇਰੇ ਦੁਆਰਾ ਮੋੜੇ ਗਏ ਸਫ਼ਿਅਾਂ ਨੂੰ ਮੇਰੀ ਧਿਆਨਸੂਚੀ ਵਿੱਚ ਸ਼ਾਮਿਲ ਕਰੋ",
        "tog-minordefault": "ਸਾਰੀਆਂ ਸੋਧਾਂ ’ਤੇ ਮੂਲ ਰੂਪ ਵਿਚ ਛੋਟੇ ਹੋਣ ਦਾ ਨਿਸ਼ਾਨ ਲਾਓ",
        "tog-previewontop": "ਸੋਧ ਬਕਸੇ ਤੋਂ ਪਹਿਲਾਂ ਝਲਕ ਵਖਾਓ",
        "tog-previewonfirst": "ਪਹਿਲੀ ਸੋਧ ਉੱਤੇ ਝਲਕ ਵਖਾਓ",
@@ -48,7 +49,7 @@
        "tog-shownumberswatching": "ਨਜ਼ਰ ਰੱਖ ਰਹੇ ਵਰਤੋਂਕਾਰਾਂ ਦੀ ਗਿਣਤੀ ਵਖਾਓ",
        "tog-oldsig": "ਮੌਜੂਦਾ ਦਸਤਖ਼ਤ:",
        "tog-fancysig": "ਦਸਤਖ਼ਤ ਨੂੰ ਬਤੌਰ ਵਿਕੀਲਿਖਤ ਮੰਨੋ (ਬਿਨਾਂ ਆਟੋਮੈਟਿਕ ਲਿੰਕ)",
-       "tog-uselivepreview": "ਸਿੱਧà©\80 à¨\9dਲà¨\95 à¨µà¨°à¨¤à©\8b (ਤà¨\9cਰਬà©\87-à¨\85ਧà©\80ਨ)",
+       "tog-uselivepreview": "ਮà©\8cà¨\9cà©\82ਦਾ à¨\9dਲà¨\95 à¨µà¨°à¨¤à©\8b",
        "tog-forceeditsummary": "ਜਦੋਂ ਮੈਂ ਖ਼ਾਲੀ ਸੋਧ ਸਾਰ ਦੇਵਾਂ ਤਾਂ ਮੈਨੂੰ ਆਗਾਹ ਕਰੋ",
        "tog-watchlisthideown": "ਨਿਗਰਾਨੀ-ਲਿਸਟ ਵਿੱਚੋਂ ਮੇਰੀਆਂ ਸੋਧਾਂ ਲੁਕਾਓ",
        "tog-watchlisthidebots": "ਨਿਗਰਾਨੀ-ਲਿਸਟ ਵਿੱਚੋਂ ਬੋਟਾਂ ਦੀਆਂ ਸੋਧਾਂ ਲੁਕਾਓ",
        "jumptonavigation": "ਨੇਵੀਗੇਸ਼ਨ",
        "jumptosearch": "ਖੋਜ",
        "view-pool-error": "ਅਫ਼ਸੋਸ, ਸਰਵਰ ਇਸ ਵੇਲੇ ਓਵਰਲੋਡ ਹੈ।\nਬਹੁਤ ਸਾਰੇ ਮੈਂਬਰ ਇਸ ਸਫ਼ੇ ਨੂੰ ਵੇਖਣ ਦੀ ਕੋਸ਼ਿਸ਼ ਕਰ ਰਹੇ ਹਨ।\nਫੇਰ ਕੋਸ਼ਿਸ਼ ਕਰਨ ਤੋਂ ਪਹਿਲਾਂ ਥੋੜੀ ਉਡੀਕ ਕਰੋ ਜੀ।\n$1",
+       "generic-pool-error": "ਮੁਆਫ਼ ਕਰੋ, ਇਸ ਵੇਲੇ ਸਰਵਰ ਕੰਮ ਨਹੀਂ ਕਰ ਰਹੇ।\nਇਸ ਚੀਜ਼ ਨੂੰ ਇਸ ਵੇਲੇ ਬਹੁਤ ਜ਼ਿਆਦਾ ਵਰਤੋਂਕਾਰ ਵੇਖਣ ਦੀ ਕੋਸ਼ਿਸ਼ ਕਰ ਰਹੇ ਹਨ।\nਇਸ ਚੀਜ਼ ਨੂੰ ਦੁਆਰਾ ਦੇਖਣ ਦੀ ਕੋਸ਼ਿਸ਼ ਕਰਨ ਤੋਂ ਪਹਿਲਾਂ ਥੋੜ੍ਹੀ ਦੇਰ ਇੰਤਜ਼ਾਰ ਕਰੋ।",
        "pool-timeout": "ਲਾਕ ਲਈ ਉਡੀਕ ਦਾ ਵਕਤ ਖ਼ਤਮ ਹੋ ਗਿਆ ਹੈ",
        "pool-queuefull": "ਪੂਲ ਕਤਾਰ ਭਰੀ ਹੋਈ ਹੈ",
        "pool-errorunknown": "ਅਣਜਾਣ ਗਲਤੀ",
        "nstab-template": "ਫਰਮਾ",
        "nstab-help": "ਮਦਦ ਸਫ਼ਾ",
        "nstab-category": "ਸ਼੍ਰੇਣੀ",
+       "mainpage-nstab": "ਮੁੱਖ ਸਫ਼ਾ",
        "nosuchaction": "ਅਜਿਹੀ ਕੋਈ ਕਾਰਵਾਈ ਨਹੀਂ ਹੈ",
        "nosuchactiontext": "URL ਦੁਆਰਾ ਦੱਸਿਆ ਕੰਮ ਗ਼ਲਤ ਹੈ।\nਸ਼ਾਇਦ ਤੁਸੀਂ URL ਸਹੀ ਨਹੀਂ ਲਿਖਿਆ ਜਾਂ ਕਿਸੇ ਗ਼ਲਤ ਲਿੰਕ ਤੇ ਆਏ ਹੋ।\nਇਹ ਵੀ ਹੋ ਸਕਦਾ ਹੈ ਕਿ ਇਹ {{SITENAME}} ਦੁਆਰੇ ਵਰਤੇ ਜਾਂਦੇ ਸਾਫ਼ਟਵੇਅਰ ਵਿਚਲੀ ਗ਼ਲਤੀ ਵੱਲ ਇਸ਼ਾਰਾ ਹੋਵੇ।",
        "nosuchspecialpage": "ਅਜਿਹਾ ਕੋਈ ਖ਼ਾਸ ਸਫ਼ਾ ਨਹੀਂ ਹੈ",
        "filerenameerror": "ਫ਼ਾਈਲ ''$1'' ਦਾ ਨਾਂ ''$2'' ਨਹੀਂ ਸਾ ਸਕਿਆ।",
        "filedeleteerror": "''$1'' ਫ਼ਾਈਲ ਹਟਾਈ ਨਹੀਂ ਜਾ ਸਕੀ।",
        "directorycreateerror": "ਡਾਇਰੈਕਟਰੀ ''$1'' ਬਣਾਈ ਨਹੀਂ ਜਾ ਸਕੀ।",
+       "directoryreadonlyerror": "\"$1\" ਨਾਮਾਵਲੀ ਸਿਰਫ਼ ਪੜ੍ਹਣਯੋਗ ਹੈ।",
+       "directorynotreadableerror": "\"$1\" ਨਾਮਾਵਲੀ ਪੜ੍ਹਣਯੋਗ ਨਹੀਂ ਹੈ।",
        "filenotfound": "ਫ਼ਾਈਲ ''$1'' ਲੱਭੀ ਨਹੀਂ ਜਾ ਸਕੀ।",
        "unexpected": "ਅਣਉਮੀਦਿਆ ਮੁੱਲ: \"$1\"=\"$2\"।",
        "formerror": "ਗ਼ਲਤੀ: ਫ਼ਾਰਮ ਪੇਸ਼ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਿਆ",
        "changeemail-password": "ਤੁਹਾਡਾ {{SITENAME}} ਪਾਸਵਰਡ:",
        "changeemail-submit": "ਈ-ਮੇਲ ਬਦਲੋ",
        "changeemail-throttled": "ਤੁਸੀਂ ਦਾਖ਼ਲ ਹੋਣ ਦੀਆਂ ਬਹੁਤ ਸਾਰੀਆਂ ਕੋਸ਼ਿਸ਼ਾਂ ਕੀਤੀਆਂ ਹਨ।\nਮੁੜ ਕੋਸ਼ਿਸ਼ ਕਰਨ ਤੋਂ ਪਹਿਲਾਂ $1 ਉਡੀਕ ਕਰੋ ਜੀ।",
+       "changeemail-nochange": "ਕਿਰਪਾ ਕਰਕੇ ਕੋਈ ਵੱਖਰਾ ਈਮੇਲ ਪਤਾ ਭਰੋ।",
        "resettokens": "ਟੋਕਨ ਮੁੜ-ਸੈੱਟ ਕਰੋ",
        "resettokens-text": "ਤੁਸੀਂ ਆਪਣੀਆਂ ਨਿਸ਼ਾਨੀਆਂ, ਜੋ ਤੁਹਾਡੇ ਖਾਤੇ ਨਾਲ਼ ਜੁੜੇ ਖ਼ਾਸ ਨਿੱਜੀ ਅੰਕੜਿਆਂ ਤੱਕ ਪੁੱਜਣ ਵਾਸਤੇ ਇਜਾਜ਼ਤ ਦਿੰਦੀਆਂ ਹਨ, ਨੂੰ ਇੱਥੇ ਮੁੜ-ਬਣਾ ਸਕਦੇ ਹੋ।\n\nਤੁਹਾਨੂੰ ਇਹ ਤਾਂ ਕਰਨਾ ਚਾਹੀਦਾ ਹੈ ਜੇਕਰ ਤੁਸੀਂ ਇਹਨਾਂ ਨੂੰ ਰੱਬ-ਸਬੱਬੀ ਕਿਸੇ ਨਾਲ਼ ਸਾਂਝਾ ਕਰ ਦਿੱਤਾ ਜਾਂ ਤੁਹਾਡਾ ਖਾਤਾ ਖ਼ਤਰੇ ਵਿੱਚ ਆ ਗਿਆ ਹੈ।",
        "resettokens-no-tokens": "ਨਵੀਆਂ ਬਣਾਉਣ ਵਾਸਤੇ ਕੋਈ ਨਿਸ਼ਾਨੀਆਂ ਨਹੀਂ ਹਨ।",
        "content-model-text": "ਆਮ ਲਿਖਤ",
        "content-model-javascript": "ਜਾਵਾਸਕਰਿਪਟ",
        "content-model-css": "ਸੀਐਸਐਸ",
+       "content-json-empty-object": "ਖਾਲੀ ਚੀਜ਼",
+       "content-json-empty-array": "ਖਾਲੀ ਤਰਤੀਬ",
        "post-expand-template-inclusion-warning": "'''ਖ਼ਬਰਦਾਰ:''' ਫਰਮੇ ਦਾ ਅਕਾਰ ਬਹੁਤ ਵੱਡਾ ਹੈ। ਕੁਝ ਫਰਮੇ ਸ਼ਾਮਲ ਨਹੀਂ ਹੋਣਗੇ।",
        "post-expand-template-inclusion-category": "ਉਹ ਸਫ਼ੇ ਜਿੱਥੇ ਫਰਮੇ ਸ਼ਾਮਲ ਕਰਨ ਦਾ ਅਕਾਰ ਹੱਦੋਂ ਵੱਧ ਗਿਆ ਹੈ",
        "post-expand-template-argument-warning": "'''ਚੇਤਾਵਨੀ:'''\nਇਸ ਪੰਨੇ ਤੇ ਘੱਟੋ ਘੱਟ ਇੱਕ ਐਸੀ ਸਾਂਚਾ ਬਹਿਸ ਹੈ ਜਿਸ ਦਾ ਅਕਾਰ ਬਹੁਤ ਵੱਡਾ ਹੈ। ਅਜਿਹੀਆਂ ਬਹਿਸਾਂ ਨੂੰ ਛੱਡ ਦਿੱਤਾ ਗਿਆ ਹੈ।",
        "parser-template-loop-warning": "ਫਰਮੇ ਦਾ ਲੂਪ ਲੱਭਿਆ: [[$1]]",
        "undo-success": "ਇਹ ਸੋਧ ਨਕਾਰੀ ਜਾ ਸਕਦੀ ਹੈ।\nਮਿਹਰਬਾਨੀ ਕਰਕੇ ਇਹ ਤਸਦੀਕ ਕਰਨ ਲਈ ਹੇਠਲੀ ਤੁਲਨਾ ਜਾਂਚੋ ਕਿ ਇਹ ਓਹੀ ਹੈ ਜੋ ਤੁਸੀਂ ਕਰਨਾ ਚਾਹੁੰਦੇ ਹੋ ਅਤੇ ਫਿਰ ਸੋਧ ਨਕਾਰਨ ਲਈ ਤਬਦੀਲੀਆਂ ਸਾਂਭ ਦਿਓ।",
        "undo-norev": "ਸੋਧ ਨਕਾਰੀ ਨਹੀਂ ਜਾ ਸਕਦੀ ਕਿਉਂਕਿ ਇਹ ਮੌਜੂਦ ਨਹੀਂ ਜਾਂ ਮਿਟਾ ਦਿੱਤੀ ਗਈ ਹੈ।",
+       "undo-nochange": "ਲਗਦਾ ਹੈ ਕਿ ਿਹ ਸੋਧ ਪਹਿਲਾਂ ਹੀ ਮੋੜ ਦਿੱਤੀ ਗਈ ਹੈ।",
        "undo-summary": "[[Special:Contributions/$2|$2]] ([[User talk:$2|ਗੱਲ-ਬਾਤ]]) ਦੀ ਸੋਧ $1 ਨਕਾਰੀ",
        "undo-summary-username-hidden": "ਗੁਪਤ ਵਰਤੋਂਕਾਰ ਵੱਲੋਂ ਕੀਤੀ $1 ਸੋਧ ਰੱਦ ਕਰੋ",
        "cantcreateaccounttitle": "ਖਾਤਾ ਬਣਾਇਆ ਨਹੀਂ ਜਾ ਸਕਦਾ",
        "rows": "ਕਤਾਰਾਂ:",
        "columns": "ਕਾਲਮ:",
        "searchresultshead": "ਖੋਜ",
+       "stub-threshold-sample-link": "ਨਮੂਨਾ",
        "stub-threshold-disabled": "ਬੰਦ ਹੈ",
        "recentchangesdays": "ਤਾਜ਼ਾ ਤਬਦੀਲੀਆਂ ਵਿਚ ਵਿਖਾਉਣ ਲਈ ਦਿਨ:",
        "recentchangesdays-max": "ਵੱਧ ਤੋਂ ਵੱਧ $1 {{PLURAL:$1|ਦਿਨ|ਦਿਨ}}",
        "right-editmyuserjs": "ਆਪਣੀਆਂ ਵਰਤੋਂਕਾਰ ਜਾਵਾਸਕਰਿਪਟ ਫ਼ਾਈਲਾਂ ਸੋਧੋ",
        "right-viewmywatchlist": "ਆਪਣੀ ਨਿਗਰਾਨੀ-ਲਿਸਟ ਵੇਖੋ",
        "right-editmywatchlist": "ਆਪਣੀ ਨਿਗਰਾਨੀ-ਲਿਸਟ ਸੋਧੋ। ਧਿਆਨ ਦਿਓ ਕਿ ਕੁਝ ਸਫ਼ੇ ਇਸ ਹੱਕ ਤੋਂ ਬਿਨਾਂ ਵੀ ਜੁੜਨਗੇ।",
+       "right-viewmyprivateinfo": "ਆਪਣਾ ਨਿੱਜੀ ਡਾਟਾ ਵੇਖੋ (ਉਦਾਹਰਨ ਵਜੋਂ ਈਮੇਲ ਪਤਾ, ਅਸਲੀ ਨਾਂ)",
+       "right-editmyprivateinfo": "ਆਪਣਾ ਨਿੱਜੀ ਡਾਟਾ ਸੋਧੋ (ਉਦਾਹਰਨ ਵਜੋਂ ਈਮੇਲ ਪਤਾ, ਅਸਲੀ ਨਾਂ)",
        "right-editmyoptions": "ਆਪਣੀਆਂ ਤਰਜੀਹਾਂ ਸੋਧੋ",
+       "right-import": "ਹੋਰ ਵਿਕੀਅਾਂ ਤੋਂ ਸਫ਼ੇ ਦਰਾਮਦ ਕਰੋ",
+       "right-importupload": "ਕਿਸੇ ਫ਼ਾਈਲ ਅਪਲੋਡ ਤੋਂ ਸਫ਼ੇ ਦਰਾਮਦ ਕਰੋ",
        "right-unwatchedpages": "ਨਜ਼ਰ ਨਾ ਰੱਖੇ ਜਾ ਰਹੇ ਸਫ਼ਿਆਂ ਦੀ ਲਿਸਟ ਵੇਖਣੀ",
        "right-mergehistory": "ਸਫ਼ਿਆਂ ਦੇ ਅਤੀਤਾਂ ਨੂੰ ਰਲ਼ਾਉਣਾ",
        "right-userrights": "ਸਾਰੇ ਵਰਤੋਂਕਾਰਾਂ ਦੇ ਹੱਕ ਬਦਲਣੇ",
        "action-viewmywatchlist": "ਆਪਣੀ ਨਿਗਰਾਨੀ-ਲਿਸਟ ਵੇਖੋ",
        "action-viewmyprivateinfo": "ਆਪਣੀ ਨਿੱਜੀ ਜਾਣਕਾਰੀ ਵੇਖੋ",
        "action-editmyprivateinfo": "ਆਪਣੀ ਨਿੱਜੀ ਜਾਣਕਾਰੀ ਸੋਧੋ",
+       "action-editcontentmodel": "ਕਿਸੇ ਸਫ਼ੇ ਦਾ ਸਮੱਗਰੀ ਮਾਡਲ ਸੋਧੋ",
        "nchanges": "$1 {{PLURAL:$1|ਤਬਦੀਲੀ|ਤਬਦੀਲੀਆਂ}}",
        "enhancedrc-since-last-visit": "$1 {{PLURAL:$1|ਆਖ਼ਰੀ ਫੇਰੀ ਤੋਂ ਲੈ ਕੇ}}",
        "enhancedrc-history": "ਅਤੀਤ",
        "newpageletter": "ਨ",
        "boteditletter": "ਬੋਟ",
        "number_of_watching_users_pageview": "[$1 ਵੇਖ ਰਹੇ ਹਨ {{PLURAL:$1|ਯੂਜ਼ਰ}}]",
-       "rc_categories_any": "ਕੋਈ ਵੀ",
+       "rc_categories_any": "à¨\9aà©\81ਣà©\87 à¨¹à©\8bà¨\87à¨\85ਾà¨\82 à¨µà¨¿à©±à¨\9aà©\8bà¨\82 à¨\95à©\8bà¨\88 à¨µà©\80",
        "rc-change-size-new": "$1 {{PLURAL:$|ਬਾਈਟ|ਬਾਈਟਾਂ}} ਤਬਦੀਲੀ ਤੋਂ ਬਾਅਦ",
        "newsectionsummary": "/* $1 */ ਨਵਾਂ ਭਾਗ",
        "rc-enhanced-expand": "ਵੇਰਵੇ ਵੇਖਾਓ",
        "tmp-create-error": "ਆਰਜ਼ੀ ਫ਼ਾਈਲ ਬਣਾਈ ਨਾ ਜਾ ਸਕੀ।",
        "tmp-write-error": "ਆਰਜ਼ੀ ਫ਼ਾਈਲ ਲਿਖਣ ਲਈ ਗ਼ਲਤੀ ਆਈ।",
        "large-file": "ਫ਼ਾਈਲਾਂ $1 ਤੋਂ ਵੱਡੀਆਂ ਨਾ ਹੋਣ ਦੀ ਸਲਾਹ ਦਿੱਤੀ ਜਾਂਦੀ ਹੈ;\nਇਹ ਫ਼ਾਈਲ $2 ਦੀ ਹੈ।",
+       "largefileserver": "ਇਹ ਫ਼ਾਈਲ ਸਰਵਰ ਦੇ ਮੁਤਾਬਕ ਵੱਡੀ ਹੈ।",
        "windows-nonascii-filename": "ਵਿਕੀ ਖ਼ਾਸ ਚਿੰਨ੍ਹਾਂ ਵਾਲੇ ਫ਼ਾਈਲ ਨਾਮਾਂ ਨੂੰ ਇਜਾਜ਼ਤ ਨਹੀਂ ਦਿੰਦਾ।",
-       "fileexists": "à¨\87ਹ à¨«à¨¼à¨¾à¨\88ਲ à¨¨à¨¾à¨\82 à¨ªà¨¹à¨¿à¨²à¨¾à¨\82 à¨¹à©\80 à¨®à©\8cà¨\9cà©\82ਦ à¨¹à©\88। à¨\9cà©\87 à¨¤à©\81ਸà©\80à¨\82 à¨\87ਹਨà©\82à©° à¨¬à¨¦à¨²à¨£ à¨¬à¨¾à¨°à©\87 à¨¦à©\8dਰਿà©\9c à¨¨à¨¹à©\80à¨\82 à¨¹à©\8b à¨¤à¨¾à¨\82  <strong>[[:$1]]</strong> à¨µà©\87à¨\96à©\8b à¨\9cà©\80। [[$1|thumb]]",
+       "fileexists": "à¨\87ਸ à¨¨à¨¾à¨\82 à¨¦à©\80 à¨«à¨¼à¨¾à¨\88ਲ à¨ªà¨¹à¨¿à¨²à¨¾à¨\82 à¨¹à©\80 à¨®à©\8cà¨\9cà©\82ਦ à¨¹à©\88। à¨\9cà©\87 {{GENDER:|ਤà©\81ਸà©\80à¨\82}} à¨\87ਸ à¨¨à©\82à©° à¨¬à¨¦à¨²à¨£ à¨¬à¨¾à¨°à©\87 à¨¦à©\8dਰਿà©\9c à¨¨à¨¹à©\80à¨\82 à¨¹à©\8b à¨¤à¨¾à¨\82  <strong>[[:$1]]</strong> à¨µà©\87à¨\96à©\8b à¨\9cà©\80।\n [[$1|thumb]]",
        "fileexists-extension": "ਇਸ ਨਾਂ ਨਾਲ਼ ਰਲਦੀ ਫ਼ਾਈਲ ਮੌਜੂਦ ਹੈ: [[$2|thumb]]\n* ਅੱਪਲੋਡ ਕੀਤੀ ਜਾਂਦੀ ਫ਼ਾਈਲ ਦਾ ਨਾਂ: <strong>[[:$1]]</strong>\n* ਮੌਜੂਦ ਫ਼ਾਈਲ ਦਾ ਨਾਂ: <strong>[[:$2]]</strong>\nਕੋਈ ਵੱਖਰਾ ਨਾਂ ਚੁਣੋ ਜੀ।",
        "file-exists-duplicate": "ਇਹ ਫ਼ਾਈਲ {{PLURAL:$1|ਇਸ ਫ਼ਾਈਲ|ਇਹਨਾਂ ਫ਼ਾਈਲਾਂ}} ਦੀ ਨਕਲ ਹੈ:",
        "uploadwarning": "ਅੱਪਲੋਡ ਚਿਤਾਵਨੀ",
index 0257dbf..9977080 100644 (file)
        "createacct-captcha": "Kontrola bezpieczeństwa",
        "createacct-imgcaptcha-ph": "Wpisz tekst widoczny powyżej",
        "createacct-submit": "Utwórz konto",
-       "createacct-another-submit": "Utwórz kolejne konto",
+       "createacct-another-submit": "Utwórz konto",
        "createacct-benefit-heading": "{{grammar:B.lp|{{SITENAME}}}} tworzą ludzie tacy jak Ty.",
        "createacct-benefit-body1": "{{PLURAL:$1|edycja|edycje|edycji}}",
        "createacct-benefit-body2": "{{PLURAL:$1|strona|strony|stron}}",
        "upload-http-error": "Wystąpił błąd protokołu HTTP – $1",
        "upload-copy-upload-invalid-domain": "Przesyłanie kopii z tej domeny nie jest dostępne.",
        "upload-dialog-title": "Prześlij plik",
-       "upload-dialog-error": "Wystąpił błąd",
-       "upload-dialog-warning": "Pojawiło się ostrzeżenie",
        "upload-dialog-button-cancel": "Anuluj",
        "upload-dialog-button-done": "Gotowe",
        "upload-dialog-button-save": "Zapisz",
        "upload-dialog-button-upload": "Prześlij",
-       "upload-dialog-label-select-file": "Wybierz plik",
-       "upload-dialog-label-infoform-title": "Szczegóły",
-       "upload-dialog-label-infoform-name": "Nazwa",
-       "upload-dialog-label-infoform-description": "Opis",
-       "upload-dialog-label-usage-title": "Korzystanie",
-       "upload-dialog-label-usage-filename": "Nazwa pliku",
+       "upload-process-error": "Wystąpił błąd",
+       "upload-process-warning": "Pojawiło się ostrzeżenie",
+       "upload-form-label-select-file": "Wybierz plik",
+       "upload-form-label-infoform-title": "Szczegóły",
+       "upload-form-label-infoform-name": "Nazwa",
+       "upload-form-label-infoform-description": "Opis",
+       "upload-form-label-usage-title": "Korzystanie",
+       "upload-form-label-usage-filename": "Nazwa pliku",
        "backend-fail-stream": "Nie można odczytać pliku $1.",
        "backend-fail-backup": "Nie można utworzyć kopii zapasowej pliku  $1 .",
        "backend-fail-notexists": "Plik  $1  nie istnieje.",
        "filerevert-legend": "Przywracanie poprzedniej wersji pliku",
        "filerevert-intro": "Zamierzasz przywrócić '''[[Media:$1|$1]]''' do [$4 wersji z $3, $2].",
        "filerevert-comment": "Powód:",
-       "filerevert-defaultcomment": "Przywrócono wersję z $2, $1",
+       "filerevert-defaultcomment": "Przywrócono wersję z $1, $2 ($3)",
        "filerevert-submit": "Przywróć",
        "filerevert-success": "Plik '''[[Media:$1|$1]]''' został cofnięty do [$4 wersji z $3, $2].",
        "filerevert-badversion": "Brak poprzedniej lokalnej wersji tego pliku z podaną datą.",
index 6383cfd..c6dced9 100644 (file)
        "nstab-template": "کينډۍ",
        "nstab-help": "لارښود مخ",
        "nstab-category": "وېشنيزه",
+       "mainpage-nstab": "لومړی مخ",
        "nosuchaction": "هېڅ داسې کومه کړنه نشته",
        "nosuchactiontext": "کومه کړنه چې د URL لخوا ځانگړې شوې سمه نه ده.\nکېدای شي چې URL مو سم نه وي ټايپ کړی، او يا مو يوه ناسمه تړنه څارلې وي.\nدا د دې هم ښکارندويي کوي چې کېدای شي چې د {{SITENAME}} لخوا کارېدونکې ساوترې کې يوه تېروتنه وي.",
        "nosuchspecialpage": "داسې هېڅ کوم ځانگړی مخ نشته",
        "badtitletext": "ستاسې د غوښتل شوي مخ سرليک سم نه وو، يا مو د سرليک ځای تش وو او يا هم د ژبو خپلمنځي تړنې څخه يا د ويکي گانو خپلمنځي سرليکونو څخه يو ناسم توری مو پکې کارولی وي.\nکېدای شي چې ستاسې په ورکړ شوي سرليک کې يو يا څو داسې توري وي چې د سرليک په توگه بايد و نه کارېږي.",
        "title-invalid-interwiki": "په سرليک کې يوه ويکي خپلمنځي تړنه ده",
        "perfcached": "لاندينی اومتوک په حافظه کې ساتل شوی او کېدای شي اوسمهاله شوی نه وي.  اکثر بريد له مخې {{PLURAL:$1|يوه پايله|$1 پايلې}} په حافظه کې شته.",
+       "perfcachedts": "لاندې راغلی اومتوک په حافظه کې ساتل شوی او وروستی ځل په $1 هم مهاله شوی. په ساتلې حافظې کې ډېر تر ډېره {{PLURAL:$4|يوه پايله ده|$4 پايلې دي}}.",
        "querypage-no-updates": "د دې مخ اوسمهالېدنې ناچارن شوي.\nپه ښکاره توگه د دې ځای اومتوک به نه وي تازه شوي.",
        "viewsource": "سرچينه کتل",
        "viewsource-title": "د $1 سرچينه کتل",
        "yourpassword": "پټنوم:",
        "userlogin-yourpassword": "پټنوم",
        "userlogin-yourpassword-ph": "پټنوم مو وليکۍ",
-       "createacct-yourpassword-ph": "پټنوم مو وټاپۍ",
+       "createacct-yourpassword-ph": "پټنوم مو وټاپئ",
        "yourpasswordagain": "پټنوم بيا وليکه",
        "createacct-yourpasswordagain": "پټنوم مو تاييد کړۍ",
-       "createacct-yourpasswordagain-ph": "پټنوم مو بيا وټاپۍ",
+       "createacct-yourpasswordagain-ph": "پټنوم مو بيا وټاپئ",
        "remembermypassword": "زما پټنوم په دې کمپيوټر (تر $1 {{PLURAL:$1|ورځې|ورځو}}) په ياد وساته!",
        "userlogin-remembermypassword": "غونډال کې مې ننوتلی وساته",
        "userlogin-signwithsecure": "خوندي اړيکتيا کارول",
        "userlogin-createanother": "بل گڼون جوړول",
        "createacct-emailrequired": "برېښليک پته",
        "createacct-emailoptional": "برېښليک پته (اختياري)",
-       "createacct-email-ph": "برېښليک پته مو وټاپۍ",
+       "createacct-email-ph": "برېښليک پته مو وټاپئ",
        "createacct-another-email-ph": "برېښليک پته مو ورکړۍ",
        "createaccountmail": "يو لنډمهاله ناټاکلی پټنوم کارول او ځانگړې شوې برېښليک پتې ته ورلېږل",
        "createacct-realname": "آر نوم (اختياري)",
        "createacct-reason": "سبب",
        "createacct-reason-ph": "ولې تاسې بل گڼون جوړول غوااړۍ",
        "createacct-captcha": "امنيتي تدبير",
-       "createacct-imgcaptcha-ph": "پورته تاسې ته ښکاره شوی متن وټاپۍ",
+       "createacct-imgcaptcha-ph": "پورته ښکاره شوی متن دلته وټاپئ",
        "createacct-submit": "گڼون مو جوړ کړئ",
        "createacct-another-submit": "بل گڼون جوړول",
        "createacct-benefit-heading": "{{SITENAME}} ستاسې په شان خلکو لخوا جوړ شوی.",
        "prefs-namespaces": "نوم-تشيالونه",
        "default": "تلواليز",
        "prefs-files": "دوتنې",
-       "prefs-custom-css": "ځاني CSS",
+       "prefs-custom-css": "دوديزه سي اس اس",
        "prefs-custom-js": "ځاني جاواسکرېپټ",
        "prefs-common-css-js": "د ټولو پوښونو لپاره د CSS/جاواسکرېپټ دوتنه:",
        "prefs-emailconfirm-label": "د برېښليک باورتيا:",
        "prefs-registration": "د نومليکنې وخت:",
        "yourrealname": "اصلي نوم:",
        "yourlanguage": "ژبه:",
+       "yourvariant": "د ژبگړدود مېنځپانگه:",
        "yournick": "نوی لاسليک:",
        "badsiglength": "ستاسو لاسليک ډېر اوږد دی.\nبايد چې لاسليک مو له $1 {{PLURAL:$1|توري|تورو}} نه لږ وي.",
        "yourgender": "څنگه غواړۍ ځان څرگند کړۍ؟",
        "gender-unknown": "ناڅرگنده",
        "gender-male": "نارينه",
        "gender-female": "ښځينه",
+       "prefs-help-gender": "دا غوره توب اختياري دی.\nساوتری د خپلو ارزښتونو په کارولو سره تاسې ته مخاطب کېږي او د کره جنسيت او کره گرامري صيغې له مخې ستاسې يادونه کوي.\nدا مالومات به په عامه توگه ښکاري.",
        "email": "برېښليک",
        "prefs-help-realname": "آر نوم ورکول ستاسې د خوښې کار دی.\nکه تاسې خپل آر نوم ورکړۍ، نو ستاسې ټولې کړنې به ستاسې په نوم اړوندې شي.",
        "prefs-help-email": "د برېښليک ورکړه ستاسې په خوښه ده، خو په ورکړې سره به يې د يوه نوي پټنوم د لېږلو چار آسانه کړي هغه هم کله چې تاسې نه خپل پټنوم هېر شوی وي.",
        "boteditletter": "ر",
        "number_of_watching_users_pageview": "[$1  {{PLURAL:$1|کتونکی کارن|کتونکي کارنان}}]",
        "rc_categories": "د وېشنيزو بريدونه (په \"|\" بېلول)",
-       "rc_categories_any": "هر يو",
+       "rc_categories_any": "Ù\84Ù\87 Ù¼Ø§Ú©Ù\84 Ø´Ù\88Ù\8aÙ\88 Ù\87ر Ù\8aÙ\88",
        "rc-change-size-new": "$1 {{PLURAL:$1|بايټ|بايټونه}} د بدلون وروسته",
        "newsectionsummary": "/* $1 */ نوې برخه",
        "rc-enhanced-expand": "تفصيل ښکاره کول",
        "upload-misc-error": "د پورته کېدنې نامالومه تېروتنه",
        "upload-http-error": "د HTTP يوه ستونزه رامېنځ ته شوې: $1",
        "upload-dialog-title": "دوتنه پورته کول",
-       "upload-dialog-error": "يوه ستونزه پېښه شوې",
-       "upload-dialog-warning": "يوه گواښنه رامېنځ ته شوه",
        "upload-dialog-button-cancel": "ناگارل",
        "upload-dialog-button-done": "ترسره شو",
        "upload-dialog-button-save": "خوندي کول",
        "upload-dialog-button-upload": "پورته کول",
-       "upload-dialog-label-select-file": "دوتنه ټاکل",
-       "upload-dialog-label-infoform-title": "ځانگړنې",
-       "upload-dialog-label-infoform-name": "نوم",
-       "upload-dialog-label-infoform-description": "څرگندونه",
-       "upload-dialog-label-usage-title": "کارېدنې",
-       "upload-dialog-label-usage-filename": "د دوتنې نوم",
+       "upload-process-error": "يوه ستونزه پېښه شوې",
+       "upload-process-warning": "يوه گواښنه رامېنځ ته شوه",
+       "upload-form-label-select-file": "دوتنه ټاکل",
+       "upload-form-label-infoform-title": "ځانگړنې",
+       "upload-form-label-infoform-name": "نوم",
+       "upload-form-label-infoform-description": "څرگندونه",
+       "upload-form-label-usage-title": "کارېدنې",
+       "upload-form-label-usage-filename": "د دوتنې نوم",
        "backend-fail-notexists": "د $1 په نوم دوتنه نشته.",
        "backend-fail-delete": "د \"$1\" دوتنه ړنګه نه شوه.",
        "backend-fail-alreadyexists": "د $1 دوتنه له پخوا نه شته.",
        "pageswithprop-submit": "ورځه",
        "doubleredirects": "دوه ځلي ورگرځېدنې",
        "brokenredirects": "ماتې ورگرځېدنې",
+       "brokenredirectstext": "لاندينۍ مخ گرځونې ناموجوده مخونو سره تړنې لري:",
        "brokenredirects-edit": "سمول",
        "brokenredirects-delete": "ړنگول",
        "withoutinterwiki": "د ژبې د تړنو بې برخې مخونه",
        "nmembers": "$1 {{PLURAL:$1|غړی|غړي}}",
        "nmemberschanged": "$1 → $2 {{PLURAL:$2|غړی|غړي}}",
        "nrevisions": "$1 {{PLURAL:$1|بڼه|بڼې}}",
-       "nimagelinks": "په $1 {{PLURAL:$1|کارېدلی مخ|کارېدلي مخونه}}",
+       "nimagelinks": "په $1 {{PLURAL:$1|مخ|مخونو}} کارېدلی",
        "ntransclusions": "په $1 {{PLURAL:$1|مخ|مخونو}} کارېدلی",
        "specialpage-empty": "د دې راپور لپاره کومې پايلې نشته.",
        "lonelypages": "يتيم مخونه",
        "editcomment": "د سمون لنډيز دا و: \"''$1''\".",
        "changecontentmodel-title-label": "مخ سرليک",
        "changecontentmodel-reason-label": "سبب:",
+       "logentry-contentmodel-change-revertlink": "په څټ گرځول",
+       "logentry-contentmodel-change-revert": "په څټ گرځول",
        "protectlogpage": "د ژغورنې يادښت",
        "protectlogtext": "دلته لاندې د ژغورل شويو مخونو د بدلونونو لړليک راغلی.\nد دم گړۍ فعالو مخ ژغورنو لړليک لپاره د [[Special:ProtectedPages|ژغورل شويو مخونو لړليک]] وگورئ.",
        "protectedarticle": "\"[[$1]]\" وژغورل شو",
        "sp-contributions-search": "د ونډو پلټنه",
        "sp-contributions-username": "IP پته يا کارن-نوم:",
        "sp-contributions-toponly": "يوازې هغه سمونونه چې تر ټولو تازه بڼې لري ښکاره کول",
+       "sp-contributions-newonly": "يوازې د مخ جوړېدنې سمونونه ښکاره کول",
        "sp-contributions-submit": "پلټل",
        "whatlinkshere": "د دې مخ تړنې",
        "whatlinkshere-title": "هغه مخونه چې د \"$1\" سره تړنې لري",
        "ipb_already_blocked": "پر \"$1\" د پخوا نه بنديز دی",
        "ipb-needreblock": "پر $1 د پخوا نه بنديز لگېدلی.\nآيا تاسې د امستنو بدلول غواړۍ؟",
        "ipb-otherblocks-header": "{{PLURAL:$1|بل بنديز|نور بنديزونه}}",
+       "ip_range_invalid": "ناسم آی پي بريد.",
        "lockdb": "توکبنسټ تړل",
        "unlockdb": "توکبنسټ پرانيستل",
        "lockconfirm": "هو، زه د توکبنسټ تړل غواړم.",
        "exif-unknowndate": "ناڅرگنده نېټه",
        "exif-orientation-1": "نورمال",
        "exif-componentsconfiguration-0": "نشته دی",
+       "exif-exposureprogram-1": "لاسي",
        "exif-exposureprogram-2": "نورماله پروګرام",
        "exif-subjectdistance-value": "$1 متره",
        "exif-meteringmode-0": "ناجوت",
index 457e955..0de51d7 100644 (file)
        "upload-dialog-button-done": "Feito",
        "upload-dialog-button-save": "Salvar",
        "upload-dialog-button-upload": "Enviar",
-       "upload-dialog-label-select-file": "Selecionar arquivo",
-       "upload-dialog-label-infoform-title": "Detalhes",
-       "upload-dialog-label-infoform-name": "Nome",
-       "upload-dialog-label-infoform-description": "Descrição",
-       "upload-dialog-label-usage-title": "Uso",
-       "upload-dialog-label-usage-filename": "Nome do arquivo",
+       "upload-form-label-select-file": "Selecionar arquivo",
+       "upload-form-label-infoform-title": "Detalhes",
+       "upload-form-label-infoform-name": "Nome",
+       "upload-form-label-infoform-description": "Descrição",
+       "upload-form-label-usage-title": "Uso",
+       "upload-form-label-usage-filename": "Nome do arquivo",
        "backend-fail-stream": "Não foi possível transmitir o arquivo  $1.",
        "backend-fail-backup": "Não foi possível fazer backup do arquivo  $1 .",
        "backend-fail-notexists": "O arquivo $1 não existe.",
index 5c340e0..b431452 100644 (file)
        "upload-http-error": "Ocorreu um erro HTTP: $1",
        "upload-copy-upload-invalid-domain": "Não é possível realizar carregamentos remotos neste domínio.",
        "upload-dialog-title": "Carregar ficheiro",
-       "upload-dialog-error": "Ocorreu um erro",
-       "upload-dialog-warning": "Ocorreu um aviso",
        "upload-dialog-button-cancel": "Cancelar",
        "upload-dialog-button-done": "Feito",
        "upload-dialog-button-save": "Gravar",
        "upload-dialog-button-upload": "Carregar",
-       "upload-dialog-label-select-file": "Selecionar ficheiro",
-       "upload-dialog-label-infoform-title": "Detalhes",
-       "upload-dialog-label-infoform-name": "Nome",
-       "upload-dialog-label-infoform-description": "Descrição",
-       "upload-dialog-label-usage-title": "Uso",
-       "upload-dialog-label-usage-filename": "Nome do ficheiro",
+       "upload-process-error": "Ocorreu um erro",
+       "upload-process-warning": "Ocorreu um aviso",
+       "upload-form-label-select-file": "Selecionar ficheiro",
+       "upload-form-label-infoform-title": "Detalhes",
+       "upload-form-label-infoform-name": "Nome",
+       "upload-form-label-infoform-description": "Descrição",
+       "upload-form-label-usage-title": "Uso",
+       "upload-form-label-usage-filename": "Nome do ficheiro",
        "backend-fail-stream": "Não foi possível transmitir o ficheiro \"$1\".",
        "backend-fail-backup": "Não foi possível fazer cópia de segurança do ficheiro \"$1\".",
        "backend-fail-notexists": "O ficheiro $1 não existe.",
index 4474ec4..79d8a69 100644 (file)
        "upload-http-error": "Parameters:\n* $1 - error message",
        "upload-copy-upload-invalid-domain": "Error message shown if a user is trying to upload (i.e. copy) a file from a website that is not in $wgCopyUploadsDomains (if set).\n\nSee also:\n* {{msg-mw|http-invalid-url}}\n* {{msg-mw|tmp-create-error}}\n* {{msg-mw|tmp-write-error}}",
        "upload-dialog-title": "Title of the upload dialog box\n{{Identical|Upload file}}",
-       "upload-dialog-error": "Error message from upload",
-       "upload-dialog-warning": "Warning message from upload",
        "upload-dialog-button-cancel": "Button to cancel the dialog\n{{Identical|Cancel}}",
        "upload-dialog-button-done": "Button to close the dialog once upload is complete\n{{Identical|Done}}",
        "upload-dialog-button-save": "Button to save the file\n{{Identical|Save}}",
        "upload-dialog-button-upload": "Button to initiate upload\n{{Identical|Upload}}",
-       "upload-dialog-label-select-file": "Label for the select file widget\n{{Identical|Select file}}",
-       "upload-dialog-label-infoform-title": "Title for the information form\n{{Identical|Detail}}",
-       "upload-dialog-label-infoform-name": "Label for the file name input\n{{Identical|Name}}",
-       "upload-dialog-label-infoform-description": "Label for the file description input\n{{Identical|Description}}",
-       "upload-dialog-label-usage-title": "Title for the insert form showing how to use the uploaded item.\n{{Identical|Usage}}",
-       "upload-dialog-label-usage-filename": "Label for the file name input\n{{Identical|Filename}}",
+       "upload-process-error": "Error message from upload",
+       "upload-process-warning": "Warning message from upload",
+       "upload-form-label-select-file": "Label for the select file widget\n{{Identical|Select file}}",
+       "upload-form-label-infoform-title": "Title for the information form\n{{Identical|Detail}}",
+       "upload-form-label-infoform-name": "Label for the file name input\n{{Identical|Name}}",
+       "upload-form-label-infoform-description": "Label for the file description input\n{{Identical|Description}}",
+       "upload-form-label-usage-title": "Title for the insert form showing how to use the uploaded item.\n{{Identical|Usage}}",
+       "upload-form-label-usage-filename": "Label for the file name input\n{{Identical|Filename}}",
        "backend-fail-stream": "Parameters:\n* $1 - a filename",
        "backend-fail-backup": "Parameters:\n* $1 - a filename",
        "backend-fail-notexists": "Parameters:\n* $1 - a filename",
index 284ebe0..49f7b55 100644 (file)
        "upload-http-error": "A avut loc o eroare HTTP: $1",
        "upload-copy-upload-invalid-domain": "Încărcarea copiilor nu este disponibilă pentru acest domeniu.",
        "upload-dialog-title": "Încărcare fișier",
-       "upload-dialog-error": "A apărut o eroare",
-       "upload-dialog-warning": "A apărut o atenționare",
        "upload-dialog-button-cancel": "Revocare",
        "upload-dialog-button-done": "Realizat",
        "upload-dialog-button-save": "Salvare",
        "upload-dialog-button-upload": "Încarcă",
-       "upload-dialog-label-select-file": "Selectează fișier",
-       "upload-dialog-label-infoform-title": "Detalii",
-       "upload-dialog-label-infoform-name": "Nume",
-       "upload-dialog-label-infoform-description": "Descriere",
-       "upload-dialog-label-usage-title": "Utilizare",
-       "upload-dialog-label-usage-filename": "Numele fișierului",
+       "upload-process-error": "A apărut o eroare",
+       "upload-process-warning": "A apărut o atenționare",
+       "upload-form-label-select-file": "Selectează fișier",
+       "upload-form-label-infoform-title": "Detalii",
+       "upload-form-label-infoform-name": "Nume",
+       "upload-form-label-infoform-description": "Descriere",
+       "upload-form-label-usage-title": "Utilizare",
+       "upload-form-label-usage-filename": "Numele fișierului",
        "backend-fail-stream": "Imposibil de citit fișierul $1.",
        "backend-fail-backup": "Imposibil de efectuat o copie de rezervă a fișierului $1.",
        "backend-fail-notexists": "Fișierul $1 nu există.",
index ad04743..21e37ba 100644 (file)
        "upload-http-error": "S'a verificate 'n'errore HTTP: $1",
        "upload-copy-upload-invalid-domain": "'A copie de le carecaminde non g'è disponibbile da stu dominie.",
        "upload-dialog-title": "Careche 'u file",
-       "upload-dialog-error": "Ave assute 'n'errore",
-       "upload-dialog-warning": "Ha assute 'n'avvise",
        "upload-dialog-button-cancel": "Annulle",
        "upload-dialog-button-done": "Fatte",
        "upload-dialog-button-save": "Reggìstre",
        "upload-dialog-button-upload": "Careche",
-       "upload-dialog-label-select-file": "Scacchie 'u file",
-       "upload-dialog-label-infoform-title": "Dettaglie",
-       "upload-dialog-label-infoform-name": "Nome",
-       "upload-dialog-label-infoform-description": "Descrizione",
-       "upload-dialog-label-usage-title": "Ause",
-       "upload-dialog-label-usage-filename": "Nome d'u file",
+       "upload-process-error": "Ave assute 'n'errore",
+       "upload-process-warning": "Ha assute 'n'avvise",
+       "upload-form-label-select-file": "Scacchie 'u file",
+       "upload-form-label-infoform-title": "Dettaglie",
+       "upload-form-label-infoform-name": "Nome",
+       "upload-form-label-infoform-description": "Descrizione",
+       "upload-form-label-usage-title": "Ause",
+       "upload-form-label-usage-filename": "Nome d'u file",
        "backend-fail-stream": "Non ge pozze trasmettere 'u file $1.",
        "backend-fail-backup": "Non ge pozze cupià 'u file $1.",
        "backend-fail-notexists": "'U file $1 non g'esiste.",
index 97a111a..bd49b6f 100644 (file)
@@ -83,7 +83,8 @@
                        "Marina Melik-Adamyan",
                        "Normalex",
                        "WindEwriX",
-                       "Nzeemin"
+                       "Nzeemin",
+                       "INS Pirat"
                ]
        },
        "tog-underline": "Подчёркивание ссылок:",
        "no-null-revision": "Не удалось создать новую нулевую правку для страницы «$1»",
        "badtitle": "Недопустимое название",
        "badtitletext": "Запрашиваемое название страницы неправильно, пусто, либо неверно указано межъязыковое или интервики название. Возможно, в названии используются недопустимые символы.",
-       "title-invalid-empty": " Ð\97аголовок Ð·Ð°Ð¿Ñ\80оÑ\88енной Ñ\81Ñ\82Ñ\80аниÑ\86Ñ\8b Ð¿Ñ\83Ñ\81Ñ\82 Ð¸Ð»Ð¸ Ñ\8fвлÑ\8fеÑ\82Ñ\81Ñ\8f Ð½Ð°Ð·Ð²Ð°Ð½Ð¸ÐµÐ¼ Ð¿Ñ\80оÑ\81Ñ\82Ñ\80анÑ\81Ñ\82ва Ð¸Ð¼Ðµн.",
+       "title-invalid-empty": " Ð\97аголовок Ð·Ð°Ð¿Ñ\80оÑ\88енной Ñ\81Ñ\82Ñ\80аниÑ\86Ñ\8b Ð¿Ñ\83Ñ\81Ñ\82 Ð¸Ð»Ð¸ Ñ\81одеÑ\80жиÑ\82 Ñ\82олÑ\8cко Ð½Ð°Ð·Ð²Ð°Ð½Ð¸Ðµ Ð¿Ñ\80оÑ\81Ñ\82Ñ\80анÑ\81Ñ\82ва Ð¸Ð¼Ñ\91н.",
        "title-invalid-utf8": "Запрашиваемое название страницы содержит некорректную последовательность символов UTF-8.",
        "title-invalid-interwiki": "Запрашиваемое название страницы содержит интервики-ссылку, которая не может быть использована в названиях.",
        "title-invalid-talk-namespace": "Запрашиваемое название страницы ссылается на страницу обсуждения, которая не может существовать.",
        "file-thumbnail-no": "Название файла начинается с <strong>$1</strong>.\nВероятно, это уменьшенная копия изображения ''(миниатюра)''.\nЕсли у вас есть данное изображение в полном размере, пожалуйста, загрузите его или измените имя файла.",
        "fileexists-forbidden": "Файл с этим именем уже существует и не может быть перезаписан.\nЕсли всё равно хотите загрузить данный файл, пожалуйста, вернитесь назад и загрузите его под другим именем. [[File:$1|thumb|center|$1]]",
        "fileexists-shared-forbidden": "Файл с этим именем уже существует в общем хранилище файлов.\nЕсли вы всё-таки хотите загрузить этот файл, пожалуйста, вернитесь назад и измените имя файла. [[File:$1|thumb|center|$1]]",
-       "file-exists-duplicate": "Этот файл является дубликатом {{PLURAL:$1|1=следующего файла|следующих файлов}}:",
+       "file-exists-duplicate": "Этот файл — дубликат {{PLURAL:$1|1=следующего файла|следующих файлов}}:",
        "file-deleted-duplicate": "Подобный файл ([[:$1]]) уже удалялся. Пожалуйста, ознакомьтесь с историей удаления файла, прежде чем загружать его снова.",
        "file-deleted-duplicate-notitle": "Файл, идентичный этому файлу, был ранее удалён, а имя файла было запрещено.\nВам следует попросить кого-нибудь с правами просмотра данных по запрещённым файлам, чтобы он проанализировал ситуацию перед тем, как загружать файл снова.",
        "uploadwarning": "Предупреждение",
        "upload-options": "Параметры загрузки",
        "watchthisupload": "Следить за этим файлом",
        "filewasdeleted": "Файл с таким именем уже существовал ранее, но был удалён. Пожалуйста, проверьте $1 перед повторной загрузкой.",
-       "filename-bad-prefix": "Имя загружаемого файла начинается с «'''$1'''» и, вероятно, является одним из шаблонных имён, которые цифровые фотокамеры дают снимкам. Пожалуйста, выберите имя, лучше описывающее содержание файла.",
+       "filename-bad-prefix": "Имя загружаемого файла начинается с «<strong>$1</strong>» и, вероятно, представляет собой одно из шаблонных имён, генерируемых цифровыми фотокамерами. Пожалуйста, выберите имя, лучше описывающее содержание файла.",
        "filename-prefix-blacklist": " #<!-- оставьте эту строчку как есть --> <pre>\n# Синтаксис следующий:\n#   * Всё, что начинается с символа «#», считается комментарием (до конца строки)\n#   * Каждая непустая строка — префикс стандартного названия файла, которое обычно даёт цифровая камера\nCIMG # Casio\nDSC_ # Nikon\nDSCF # Fuji\nDSCN # Nikon\nDUW # некоторые мобильные телефоны\nIMG # общее\nJD # Jenoptik\nMGP # Pentax\nPICT # различные\n #</pre> <!-- оставьте эту строчку как есть -->",
        "upload-success-subj": "Загрузка успешно завершена",
        "upload-success-msg": "Ваша загрузка [$2] прошла успешно. Вы можете посмотреть результат здесь: [[:{{ns:file}}:$1]]",
        "upload-http-error": "Произошла ошибка HTTP: $1",
        "upload-copy-upload-invalid-domain": "Копирование загрузок не доступно в этом домене.",
        "upload-dialog-title": "Загрузить файл",
-       "upload-dialog-error": "Произошла ошибка",
-       "upload-dialog-warning": "Появилось предупреждение",
        "upload-dialog-button-cancel": "Отменить",
        "upload-dialog-button-done": "Готово",
        "upload-dialog-button-save": "Сохранить",
        "upload-dialog-button-upload": "Загрузить",
-       "upload-dialog-label-select-file": "Выбрать файл",
-       "upload-dialog-label-infoform-title": "Подробности",
-       "upload-dialog-label-infoform-name": "Имя",
-       "upload-dialog-label-infoform-description": "Описание",
-       "upload-dialog-label-usage-title": "Использование",
-       "upload-dialog-label-usage-filename": "Имя файла",
+       "upload-process-error": "Произошла ошибка",
+       "upload-process-warning": "Появилось предупреждение",
+       "upload-form-label-select-file": "Выбрать файл",
+       "upload-form-label-infoform-title": "Подробности",
+       "upload-form-label-infoform-name": "Имя",
+       "upload-form-label-infoform-description": "Описание",
+       "upload-form-label-usage-title": "Использование",
+       "upload-form-label-usage-filename": "Имя файла",
        "backend-fail-stream": "Не удалось транслировать файл $1.",
        "backend-fail-backup": "Невозможно сделать резервную копию файла $1.",
        "backend-fail-notexists": "Файл $1 не существует.",
        "img-auth-nofile": "Файл «$1» не существует.",
        "img-auth-isdir": "Вы пытаетесь получить доступ к каталогу «$1».\nРазрешён только доступ к файлам.",
        "img-auth-streaming": "Потоковая передача «$1».",
-       "img-auth-public": "Назначением img_auth.php является вывод файлов из закрытой вики.\nЭта вики настроена как общедоступная.\nДля оптимизации безопасности img_auth.php отключена.",
+       "img-auth-public": "Назначение img_auth.php — вывод файлов из закрытой вики.\nЭта вики настроена как общедоступная.\nДля оптимизации безопасности img_auth.php отключена.",
        "img-auth-noread": "Участник не имеет доступа на чтение «$1».",
        "http-invalid-url": "Ошибочный URL: $1",
        "http-invalid-scheme": "Не поддерживаются адреса со схемой «$1»",
        "version-poweredby-others": "другие",
        "version-poweredby-translators": "переводчики translatewiki.net",
        "version-credits-summary": "Хотим поблагодарить следующих участников за их вклад в развитие [[Special:Version|MediaWiki]].",
-       "version-license-info": "MediaWiki является свободным программным обеспечением, которое вы можете распространять и/или изменять в соответствии с условиями лицензии GNU General Public License, опубликованной фондом свободного программного обеспечения; второй версии, либо любой более поздней версии.\n\nMediaWiki распространяется в надежде, что она будет полезной, но БЕЗ КАКИХ-ЛИБО ГАРАНТИЙ, даже без подразумеваемых гарантий КОММЕРЧЕСКОЙ ЦЕННОСТИ или ПРИГОДНОСТИ ДЛЯ ОПРЕДЕЛЕННОЙ ЦЕЛИ. См. лицензию GNU General Public License для более подробной информации.\n\nВы должны были получить [{{SERVER}}{{SCRIPTPATH}}/COPYING копию GNU General Public License] вместе с этой программой, если нет, то напишите Free Software Foundation, Inc., по адресу: 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA или [//www.gnu.org/licenses/old-licenses/gpl-2.0.html прочтите её онлайн].",
+       "version-license-info": "MediaWiki — свободное программное обеспечение, которое вы можете распространять и/или изменять в соответствии с условиями лицензии GNU General Public License, опубликованной фондом свободного программного обеспечения; второй версии, либо любой более поздней версии.\n\nMediaWiki распространяется в надежде, что она будет полезной, но БЕЗ КАКИХ-ЛИБО ГАРАНТИЙ, даже без подразумеваемых гарантий КОММЕРЧЕСКОЙ ЦЕННОСТИ или ПРИГОДНОСТИ ДЛЯ ОПРЕДЕЛЕННОЙ ЦЕЛИ. См. лицензию GNU General Public License для более подробной информации.\n\nВы должны были получить [{{SERVER}}{{SCRIPTPATH}}/COPYING копию GNU General Public License] вместе с этой программой, если нет, то напишите Free Software Foundation, Inc., по адресу: 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA или [//www.gnu.org/licenses/old-licenses/gpl-2.0.html прочтите её онлайн].",
        "version-software": "Установленное программное обеспечение",
        "version-software-product": "Продукт",
        "version-software-version": "Версия",
        "api-error-badaccess-groups": "Вам не разрешено загружать файлы в эту вики.",
        "api-error-badtoken": "Внутренняя ошибка:  некорректный токен.",
        "api-error-copyuploaddisabled": "Загрузка по URL-адресу отключена на этом сервере.",
-       "api-error-duplicate": "Уже {{PLURAL:$1|1=существует [$2 другой файл]|существуют [$2 другие файлы]}} с таким же содержимым",
+       "api-error-duplicate": "Уже {{PLURAL:$1|существует другой файл|существуют другие файлы}} с таким же содержимым.",
        "api-error-duplicate-archive": "Раньше на сайте {{PLURAL:$1|1=уже был файл|были файлы}} с точно таким же содержанием, но {{PLURAL:$1|1=он был удалён|они были удалены}}.",
        "api-error-empty-file": "Отправленный вами файл пуст.",
        "api-error-emptypage": "Не допускается создание новых пустых страниц.",
index 3fc1ed3..3e0c9f0 100644 (file)
        "upload-dialog-button-done": "Оҥоһулунна",
        "upload-dialog-button-save": "Бигэргэт",
        "upload-dialog-button-upload": "Киллэрии",
-       "upload-dialog-label-select-file": "Билэни тал",
-       "upload-dialog-label-infoform-title": "Сиһилии",
-       "upload-dialog-label-infoform-name": "Аата",
-       "upload-dialog-label-infoform-description": "Быһаарыыта",
-       "upload-dialog-label-usage-title": "Туһаныы",
-       "upload-dialog-label-usage-filename": "Билэ аата",
+       "upload-process-error": "Алҕас таҕыста",
+       "upload-process-warning": "Сэрэтии үөскээтэ",
+       "upload-form-label-select-file": "Билэни тал",
+       "upload-form-label-infoform-title": "Сиһилии",
+       "upload-form-label-infoform-name": "Аата",
+       "upload-form-label-infoform-description": "Быһаарыыта",
+       "upload-form-label-usage-title": "Туһаныы",
+       "upload-form-label-usage-filename": "Билэ аата",
        "backend-fail-stream": "$1 билэни ыытар табыллыбата.",
        "backend-fail-backup": "Бу билэ $1 резервнэй куопуйатын оҥорор табыллыбата.",
        "backend-fail-notexists": "Маннык $1 билэ суох эбит.",
        "booksources-text": "Манна кинигэ туһунан атын саайтарга ыйынньыктар хомулуннулар, онно баҕар эбии информация көстүөҕэ.",
        "booksources-invalid-isbn": "ISBN, арааһа, сыыһалаах. Нүөмэр көһөрөргө алҕас тахсыбатаҕын хат көр эрэ.",
        "specialloguserlabel": "Толорооччу:",
-       "speciallogtitlelabel": "Сорук (тиэкис эбэтэр киһи аата)",
+       "speciallogtitlelabel": "Сыал (тиэкис эбэтэр {{ns:user}}:кыттааччы аата):",
        "log": "Сурунааллар",
        "all-logs-page": "Көстөр сурунааллар барыта",
        "alllogstext": "{{SITENAME}} сурунаалларын уопсай испииһэгэ.\nСурунаал көрүҥүнэн, кыттааччы аатынан (улахан-кыра буукубата учуоттанар) эбэтэр сирэй аатынан (эмиэ улахана-кырата учуоттанар) наардыаххытын сөп.",
index 01b8a38..5013665 100644 (file)
        "versionrequiredtext": "P'usari sta pàggina ci voli la virsioni $1 dû software MediaWiki. Talìa [[Special:Version|sta pàggina]]",
        "ok": "Va bonu",
        "retrievedfrom": "Estrattu di \"$1\"",
-       "youhavenewmessages": "Arricivisti $1 ($2).",
-       "youhavenewmessagesfromusers": "Arricivisti $1 di {{PLURAL:$3|n'àutru utenti|$3 utenti}} ($2).",
+       "youhavenewmessages": "{{PLURAL:$3|Arricivisti}} $1 ($2).",
+       "youhavenewmessagesfromusers": "{{PLURAL:$4|Arricivisti}} $1 di {{PLURAL:$3|n'àutru utenti|$3 utenti}} ($2).",
        "youhavenewmessagesmanyusers": "Arricivisti $1 di tanti utenti ($2).",
        "newmessageslinkplural": "{{PLURAL:$1|nu missaggiu novu|999=missaggi novi}}",
        "newmessagesdifflinkplural": "{{PLURAL:$1|ùrtimu canciamentu|999=ùrtimi canciamenti}}",
        "createacct-captcha": "Cuntrollu di sicurizza",
        "createacct-imgcaptcha-ph": "Nzirìsci lu testu ca vidi ccassupra",
        "createacct-submit": "Crea lu tò cuntu",
-       "createacct-another-submit": "Crea n'àutru cuntu",
+       "createacct-another-submit": "Crìa un cuntu",
        "createacct-benefit-heading": "{{SITENAME}} è fatta di pirsuni comu a tìa.",
        "createacct-benefit-body1": "{{PLURAL:$1|cuntribbutu|cuntribbuti}}",
        "createacct-benefit-body2": "{{PLURAL:$1|pàggina|pàggini}}",
        "changeemail-password": "La tò password di {{SITENAME}}:",
        "changeemail-submit": "Cancia nnirizzu",
        "changeemail-throttled": "Facisti troppi tintativi di trasuta.\nPi favuri aspetta $1 prima di pruvari n'àutra vota.",
+       "changeemail-nochange": "Pi’ favuri metti nu nnirizzu di posta elittrònica diffirenti di chiddu ca già cc’è.",
        "resettokens": "Azziramentu dî token",
        "resettokens-text": "Ccà poi azzirari li ''token'' chi dùnanu accessu a certi dati risirvati assuciati ô tò cuntu.\n\nSta cosa s'avissi a fari si pi sbagghiu li facisti sapiri a quarchidunu o si lu tò cuntu fu cumprumisu.",
        "resettokens-no-tokens": "Nun ci sunnu token d'azzirari.",
        "permissionserrorstext-withaction": "Nun hai lu pirmissu di $2, pi {{PLURAL:$1|stu mutivu|sti mutivi}}:",
        "recreate-moveddeleted-warn": "'''Accura: stai pi criari na pàggina chi fu cancillata 'n passatu.'''\n\nAccuràtivi ch'è uppurtunu cuntinuari a canciari sta pàggina.\nL'alencu dî cancillazzioni e spustamenti rilativi veni ripurtatu ccà pi cummudità:",
        "moveddeleted-notice": "Sta pàggina fu scancillata. La lista di li scancillazzioni e spustamenti veni ammustrata di sècutu pi nfurmazzioni.",
+       "moveddeleted-notice-recent": "Nni dispiaci, ma sta pàggina ricintimenti fu scancillata (nta l’ùrtimi 24 uri).\nComu rifirimentu, ccassutta cci sunnu li riggistra dî scancillazzioni e dî spustamenti rilativi a’ sta pàggina.",
        "log-fulllog": "Talìa lu riggistru cumpletu",
        "edit-hook-aborted": "Canciamentu annullatu di n'hook.\nNun desi nudda spigazzioni.",
        "edit-gone-missing": "Nun si pò aggiurnari la pàggina.\nPari ca fu cancillata.",
        "mergehistory-empty": "Nudda virsioni di jùnciri.",
        "mergehistory-success": "$3 {{PLURAL:$3|virsioni di [[:$1]] fu junciuta|$3 virsioni di [[:$1]] foru junciuti}} â crunuluggìa di [[:$2]].",
        "mergehistory-fail": "Nun fu pussìbbili jùnciri li crunuluggìi, pi favuri cuntrolla n'àutra vota li paràmitri chi spicìficanu li pàggini e li dati.",
-       "mergehistory-fail-toobig": "Nun fu pussìbbili jùnciri li crunuluggìi pirchì s'avìssiru a spustari cchiossai virsioni dû lìmiti chi è $1.",
+       "mergehistory-fail-toobig": "Nun fu pussìbbili jùnciri li crunuluggìi pirchì s'avìssiru a spustari cchiossai virsioni dû lìmiti chi è {{PLURAL:$1|$1}}.",
        "mergehistory-no-source": "La pàggina d'orìggini $1 nun esisti.",
        "mergehistory-no-destination": "La pàggina di distinazzioni $1 nun esisti.",
        "mergehistory-invalid-source": "La pàggina d'orìggini havi a aviri nu tìtulu vàlidu.",
        "yournick": "Firma nova:",
        "prefs-help-signature": "Li cummenti ntê pàggini di discussioni s'avìssiru a firmari cu \"<nowiki>~~~~</nowiki>\", ca veni cunvirtutu ntâ tò firma cu appressu la data.",
        "badsig": "Firma grezza nun vàlida.\nCuntrolla l'etichetti HTML.",
-       "badsiglength": "La tò firma è troppu longa.\nNun havi a èssiri cchiù longa di $1 {{PLURAL:$1|caràttiri|caràttiri}}.",
+       "badsiglength": "La tò firma è troppu longa.\nNun havi a èssiri cchiù longa di $1 {{PLURAL:$1|caràttiri}}.",
        "yourgender": "Comu prifirisci èssiri discrivutu?",
        "gender-unknown": "Quannu t'ammintua, si pò, lu prugramma adòpira lu gèniri grammaticali nèutru",
        "gender-male": "È riggistratu supra {{SITENAME}}",
        "upload-http-error": "Ammattìu n'erruri HTTP: $1",
        "upload-copy-upload-invalid-domain": "Lu carricamentu di copî nun è cunzintutu di stu duminiu.",
        "upload-dialog-title": "Carricamentu dûn file",
-       "upload-dialog-error": "Ammattìu n'erruri",
-       "upload-dialog-warning": "Ammattìu n'avvisu",
        "upload-dialog-button-cancel": "Annulla",
        "upload-dialog-button-done": "Finutu",
        "upload-dialog-button-save": "Sarva",
        "upload-dialog-button-upload": "Càrrica",
-       "upload-dialog-label-select-file": "Scegghi lu file",
-       "upload-dialog-label-infoform-title": "Dittagghî",
-       "upload-dialog-label-infoform-name": "Nomu",
-       "upload-dialog-label-infoform-description": "Discrizzioni",
-       "upload-dialog-label-usage-title": "Usu",
-       "upload-dialog-label-usage-filename": "Nomu dû file",
+       "upload-process-error": "Ammattìu n'erruri",
+       "upload-process-warning": "Ammattìu n'avvisu",
+       "upload-form-label-select-file": "Scegghi lu file",
+       "upload-form-label-infoform-title": "Dittagghî",
+       "upload-form-label-infoform-name": "Nomu",
+       "upload-form-label-infoform-description": "Discrizzioni",
+       "upload-form-label-usage-title": "Usu",
+       "upload-form-label-usage-filename": "Nomu dû file",
        "backend-fail-stream": "Nun fu pussìbbili trasmèttiri lu file \"$1\".",
        "backend-fail-backup": "Nun fu pussìbbili fari na copia di riserva dû file \"$1\".",
        "backend-fail-notexists": "Lu file $1 nun esisti.",
        "filerevert-legend": "Riprìstina file",
        "filerevert-intro": "Stai pi ripristinari lu file '''[[Media:$1|$1]]''' â [virsioni $4 dô $2, $3].",
        "filerevert-comment": "Mutivu:",
-       "filerevert-defaultcomment": "Ripristinata la virsioni dô $1, $2",
+       "filerevert-defaultcomment": "Ripristinata la virsioni dô $1, $2 ($3)",
        "filerevert-submit": "Riprìstina",
        "filerevert-success": "'''Lu file [[Media:$1|$1]]''' hà statu ripristinatu â [$4 virsioni dô $2, $3].",
        "filerevert-badversion": "Nun esistanu virsiona locali pricidenti dô file cû timestamp richiestu.",
        "suppress": "Supravisuri",
        "querypage-disabled": "Sta pàggina spiciali fu disattivata pi mutivi di pristazzioni.",
        "apihelp": "Guida a l'API",
-       "apihelp-no-such-module": "Mòdulu \"$\" nun attruvatu.",
+       "apihelp-no-such-module": "Mòdulu «$1» nun attruvatu.",
        "booksources": "Fonti libbrarî",
        "booksources-search-legend": "Arricerca di fonti libbrarî",
        "booksources-isbn": "Còdici ISBN:",
        "listusers-blocked": "(bluccatu)",
        "activeusers": "Lista di l'utenti attivi",
        "activeusers-intro": "Chista è na lista di l'utenti chi fìciru na quarchi attività {{PLURAL:$1|nta l'ùrtimu jornu|nta l'ùrtimi $1 jorna}}.",
-       "activeusers-count": "$1 {{PLURAL:$1|azzioni|azzioni}} nta {{PLURAL:$3|l'ùrtimu jornu|l'ùrtimi $3 jorna}}",
+       "activeusers-count": "$1 {{PLURAL:$1|azzioni}} nta {{PLURAL:$3|l'ùrtimu jornu|l'ùrtimi $3 jorna}}",
        "activeusers-from": "Ammustra l'utenti a pàrtiri di:",
        "activeusers-hidebots": "Ammuccia li bot",
        "activeusers-hidesysops": "Ammuccia l'amministratura",
        "emailccsubject": "Copia dû missaggiu ca mannasti a $1: $2",
        "emailsent": "Missaggiu di posta elittrònica mannatu",
        "emailsenttext": "Lu tò missaggiu di posta elittrònica fu mannatu.",
-       "emailuserfooter": "Stu missaggiu fu mannatu di $1 a $2 pi menzu dâ funzioni \"{{int:emailuser}}\" supra a {{SITENAME}}.",
+       "emailuserfooter": "Stu missaggiu fu mannatu di {{GENDER:$1|$1}} a {{GENDER:$2|$2}} pi menzu dâ funzioni «{{int:emailuser}}» supra a {{SITENAME}}.",
        "usermessage-summary": "Lassatu nu missaggiu di sistema.",
        "usermessage-editor": "Missaggeri di sistema",
        "watchlist": "Lista taliata",
        "exbeforeblank": "lu cuntinutu prima dû svacantamentu era: \"$1\"",
        "delete-confirm": "Cancella \"$1\"",
        "delete-legend": "Cancella",
-       "historywarning": "<strong>Accura:</strong> La pàggina ca stai pi cancillari havi na crunuluggìa cu $1 virsioni:",
+       "historywarning": "<strong>Accura:</strong> La pàggina ca stai pi cancillari havi na crunuluggìa cu $1 {{PLURAL:$1|virsioni}}:",
        "confirmdeletetext": "Stai cancillannu na pàggina cu tutta la sò crunuluggìa.\nPi favuri, cunferma ca ntenni fari sta cosa, ca capisti li cunziguenzi, e chi lu fai secunnu [[{{MediaWiki:Policy-url}}|li lìnii guida]].",
        "actioncomplete": "Azzioni cumpritata",
        "actionfailed": "Azioni fallita",
        "deletereasonotherlist": "Àutru mutivu",
        "deletereason-dropdown": "* Mutivi cchiù cumuni pâ cancillazzioni\n** Spam\n** Vannalismu\n** Viulazzioni di lu drittu d'auturi\n** Dumanna di l'auturi\n** Rimannu scassatu",
        "delete-edit-reasonlist": "Cancia li mutivi dâ cancillazzioni",
-       "delete-toobig": "Sta pàggina havi na crunuluggìa dî canciamenti assai longa, cchiossai di $1 {{PLURAL:$1|virsioni|virsioni}}).\nLa cancillazzioni dî pàggini comu a chista è risirvata, pi scanzari la pussibbilitati di pruvucari senza vulìrilu prubblemi a {{SITENAME}}.",
-       "delete-warning-toobig": "Sta pàggina havi na crunuluggìa dî canciamenti assai longa, cchiossai di $1 {{PLURAL:$1|virsioni|virsioni}}).\nLa sò cancillazzioni pò disturbari lu funziunamentu di  {{SITENAME}}; prucedi cu cautela.",
+       "delete-toobig": "Sta pàggina havi na crunuluggìa dî canciamenti assai longa, cchiossai di $1 {{PLURAL:$1|virsioni}}.\nLa cancillazzioni dî pàggini comu a chista è risirvata, pi scanzari la pussibbilitati di pruvucari senza vulìrilu prubblemi a {{SITENAME}}.",
+       "delete-warning-toobig": "Sta pàggina havi na crunuluggìa dî canciamenti assai longa, cchiossai di $1 {{PLURAL:$1|virsioni}}.\nLa sò cancillazzioni pò disturbari lu funziunamentu di  {{SITENAME}}; prucedi cu cautela.",
        "deleteprotected": "Nun poi cancillari sta pàggina pirchì fu prutiggiuta.",
        "deleting-backlinks-warning": "'''Accura:''' [[Special:WhatLinksHere/{{FULLPAGENAME}}|Àutri pàggini]] sunnu culligati o nclùdinu la pàggina chi stai cancillannu.",
        "rollback": "Annullamentu di canciamenti",
        "api-error-badaccess-groups": "Nun hai lu pirmissu di carricari file nta sta wiki.",
        "api-error-badtoken": "Erruri nternu: Token sbagghiatu",
        "api-error-copyuploaddisabled": "Lu carricamentu a pàrtiri d'URL è disattivatu nta stu server.",
-       "api-error-duplicate": "Già {{PLURAL:$1|c'è [$2 n'àutru file]|ci sunnu [$2 àutri file]}} supra ô situ chi {{PLURAL:$1|havi|hannu}} lu stissu cuntinutu.",
+       "api-error-duplicate": "Già {{PLURAL:$1|c'è n'àutru file]|ci sunnu àutri file]}} supra ô situ chi {{PLURAL:$1|havi|hannu}} lu stissu cuntinutu.",
        "api-error-duplicate-archive": "{{PLURAL:$1|C'era n'àutru file|C'èranu àutri file}} supra ô situ c'{{PLURAL:$1|avìa|avìanu}} lu stissu cuntinutu, ma {{PLURAL:$1|fu cancillatu|foru cancillati}}.",
        "api-error-empty-file": "Lu file chi mannasti era vacanti.",
        "api-error-emptypage": "Criari pàggini novi e vacanti nun è cunzintutu.",
index be35f72..d165d07 100644 (file)
        "upload-http-error": "Prišlo je do napake HTTP: $1",
        "upload-copy-upload-invalid-domain": "Nalaganje kopij s te domene ni možno.",
        "upload-dialog-title": "Naloži datoteko",
-       "upload-dialog-error": "Prišlo je do napake",
-       "upload-dialog-warning": "Pojavilo se je opozorilo",
        "upload-dialog-button-cancel": "Prekliči",
        "upload-dialog-button-done": "Končano",
        "upload-dialog-button-save": "Shrani",
        "upload-dialog-button-upload": "Naloži",
-       "upload-dialog-label-select-file": "Izberi datoteko",
-       "upload-dialog-label-infoform-title": "Podrobnosti",
-       "upload-dialog-label-infoform-name": "Ime",
-       "upload-dialog-label-infoform-description": "Opis",
-       "upload-dialog-label-usage-title": "Uporaba",
-       "upload-dialog-label-usage-filename": "Ime datoteke",
+       "upload-process-error": "Prišlo je do napake",
+       "upload-process-warning": "Pojavilo se je opozorilo",
+       "upload-form-label-select-file": "Izberi datoteko",
+       "upload-form-label-infoform-title": "Podrobnosti",
+       "upload-form-label-infoform-name": "Ime",
+       "upload-form-label-infoform-description": "Opis",
+       "upload-form-label-usage-title": "Uporaba",
+       "upload-form-label-usage-filename": "Ime datoteke",
        "backend-fail-stream": "Ne morem pretakati datoteke $1.",
        "backend-fail-backup": "Ne morem varnostno kopirati datoteke $1.",
        "backend-fail-notexists": "Datoteka $1 ne obstaja.",
index 9f9ebe9..f814d2a 100644 (file)
        "upload-dialog-button-done": "Готово",
        "upload-dialog-button-save": "Сачувај",
        "upload-dialog-button-upload": "Пошаљи",
-       "upload-dialog-label-select-file": "Изабери датотеку",
-       "upload-dialog-label-infoform-title": "Детаљи",
-       "upload-dialog-label-infoform-name": "Назив",
-       "upload-dialog-label-infoform-description": "Опис",
-       "upload-dialog-label-usage-filename": "Назив датотеке",
+       "upload-form-label-select-file": "Изабери датотеку",
+       "upload-form-label-infoform-title": "Детаљи",
+       "upload-form-label-infoform-name": "Назив",
+       "upload-form-label-infoform-description": "Опис",
+       "upload-form-label-usage-filename": "Назив датотеке",
        "backend-fail-stream": "Не могу да емитујем датотеку $1.",
        "backend-fail-backup": "Не могу да направим резерву датотеке $1.",
        "backend-fail-notexists": "Датотека $1 не постоји.",
index a045c12..8ae161a 100644 (file)
        "nstab-template": "Mall",
        "nstab-help": "Hjälpsida",
        "nstab-category": "Kategori",
+       "mainpage-nstab": "Huvudsida",
        "nosuchaction": "Funktionen finns inte",
        "nosuchactiontext": "Den handling som specificerats av webbadressen är ogiltig.\nDu kan ha stavat webbadressen fel, eller följt en felaktig länk.\nDet kan även bero på en bugg i mjukvaran som används på {{SITENAME}}.",
        "nosuchspecialpage": "Någon sådan specialsida finns inte",
        "createacct-captcha": "Säkerhetskontroll",
        "createacct-imgcaptcha-ph": "Fyll i texten du ser ovan",
        "createacct-submit": "Skapa ditt konto",
-       "createacct-another-submit": "Skapa ett till konto",
+       "createacct-another-submit": "Skapa konto",
        "createacct-benefit-heading": "{{SITENAME}} är skapad av människor som dig.",
        "createacct-benefit-body1": "{{PLURAL:$1|redigering|redigeringar}}",
        "createacct-benefit-body2": "{{PLURAL:$1|sida|sidor}}",
        "permissionserrorstext-withaction": "Du har inte behörighet att $2, av följande {{PLURAL:$1|anledning|anledningar}}:",
        "recreate-moveddeleted-warn": "'''Varning: Du återskapar en sida som tidigare raderats.'''\n\nDu bör överväga om det är lämpligt att fortsätta redigera den här sidan.\nRaderings- och sidflyttningsloggen för den här sidan visas här som hjälp:",
        "moveddeleted-notice": "Den här sidan har raderats.\nRaderings- och sidflyttningsloggen för sidan visas nedan som referens.",
+       "moveddeleted-notice-recent": "Tyvärr, denna sida raderades nyligen (inom de senaste 24 timmarna).\nLoggen för radering och flyttning av sidan visas nedan som referens.",
        "log-fulllog": "Visa fullständig logg",
        "edit-hook-aborted": "Redigering avbruten av hook.\nDen gav ingen förklaring.",
        "edit-gone-missing": "Kunde inte uppdatera sidan.\nDet verkar som att den har raderats.",
        "upload-http-error": "Ett HTTP-fel uppstod: $1",
        "upload-copy-upload-invalid-domain": "Uppladdning av kopior är inte tillgängligt från denna domän.",
        "upload-dialog-title": "Ladda upp fil",
-       "upload-dialog-error": "Ett fel uppstod",
-       "upload-dialog-warning": "En varning uppstod",
        "upload-dialog-button-cancel": "Avbryt",
        "upload-dialog-button-done": "Klar",
        "upload-dialog-button-save": "Spara",
        "upload-dialog-button-upload": "Ladda upp",
-       "upload-dialog-label-select-file": "Välj fil",
-       "upload-dialog-label-infoform-title": "Detaljer",
-       "upload-dialog-label-infoform-name": "Namn",
-       "upload-dialog-label-infoform-description": "Beskrivning",
-       "upload-dialog-label-usage-title": "Användning",
-       "upload-dialog-label-usage-filename": "Filnamn",
+       "upload-process-error": "Ett fel uppstod",
+       "upload-process-warning": "En varning uppstod",
+       "upload-form-label-select-file": "Välj fil",
+       "upload-form-label-infoform-title": "Detaljer",
+       "upload-form-label-infoform-name": "Namn",
+       "upload-form-label-infoform-description": "Beskrivning",
+       "upload-form-label-usage-title": "Användning",
+       "upload-form-label-usage-filename": "Filnamn",
        "backend-fail-stream": "Kunde inte strömma filen $1.",
        "backend-fail-backup": "Kunde inte säkerhetskopiera filen ''$1''.",
        "backend-fail-notexists": "Filen $1 finns inte.",
        "filerevert-legend": "Återställ fil",
        "filerevert-intro": "Du återställer '''[[Media:$1|$1]]''' till [$4 versionen från $2 kl. $3].",
        "filerevert-comment": "Anledning:",
-       "filerevert-defaultcomment": "Återställer till versionen från $1 kl. $2.",
+       "filerevert-defaultcomment": "Återställer till versionen från $1 kl. $2 ($3)",
        "filerevert-submit": "Återställ",
        "filerevert-success": "'''[[Media:$1|$1]]''' har återställts till [$4 versionen från $2 kl. $3].",
        "filerevert-badversion": "Det finns ingen tidigare version av filen från den angivna tidpunkten.",
        "emailccsubject": "Kopia av ditt meddelande till $1: $2",
        "emailsent": "E-post har nu skickats",
        "emailsenttext": "Ditt e-postmeddelande har skickats",
-       "emailuserfooter": "Detta e-postmeddelande skickades av $1 till $2 med funktionen \"{{int:emailuser}}\" på {{SITENAME}}.",
+       "emailuserfooter": "Detta e-postmeddelande {{GENDER:$1|skickades}} av $1 till {{GENDER:$2|$2}} med funktionen \"{{int:emailuser}}\" på {{SITENAME}}.",
        "usermessage-summary": "Lämnar systemmeddelande.",
        "usermessage-editor": "Systemmeddelare",
        "watchlist": "Bevakningslista",
        "api-error-badaccess-groups": "Du får inte ladda upp filer till denna wiki.",
        "api-error-badtoken": "Internt fel: felaktig nyckel.",
        "api-error-copyuploaddisabled": "Uppladdning via URL är inaktiverad på den här servern.",
-       "api-error-duplicate": "Det finns redan {{PLURAL:$1|[$2 en annan fil]|[$2 andra filer]}} på webbplatsen med samma innehåll.",
+       "api-error-duplicate": "Det finns redan {{PLURAL:$1|en annan fil|andra filer}} på webbplatsen med samma innehåll.",
        "api-error-duplicate-archive": "Det fanns redan {{PLURAL:$1|en annan fil|några andra filer}} på webbplatsen med samma innehåll, men {{PLURAL:$1|den har|de har}} raderats.",
        "api-error-empty-file": "Filen du skickade var tom.",
        "api-error-emptypage": "Det är inte tillåtet att skapa nya, tomma sidor.",
index b0ce154..e29f413 100644 (file)
        "upload-http-error": "เกิดข้อผิดพลาดเอชทีทีพี: $1",
        "upload-copy-upload-invalid-domain": "ไม่สามารถคัดลอกการอัปโหลดจากโดเมนนี้",
        "upload-dialog-title": "อัปโหลดไฟล์",
-       "upload-dialog-error": "เกิดข้อผิดพลาด",
-       "upload-dialog-warning": "เกิดคำเตือน",
        "upload-dialog-button-cancel": "ยกเลิก",
        "upload-dialog-button-done": "เสร็จสิ้น",
        "upload-dialog-button-save": "บันทึก",
        "upload-dialog-button-upload": "อัปโหลด",
-       "upload-dialog-label-select-file": "เลือกไฟล์",
-       "upload-dialog-label-infoform-title": "รายละเอียด",
-       "upload-dialog-label-infoform-name": "ชื่อ",
-       "upload-dialog-label-infoform-description": "คำอธิบาย",
-       "upload-dialog-label-usage-title": "การใช้",
-       "upload-dialog-label-usage-filename": "ชื่อไฟล์",
+       "upload-process-error": "เกิดข้อผิดพลาด",
+       "upload-process-warning": "เกิดคำเตือน",
+       "upload-form-label-select-file": "เลือกไฟล์",
+       "upload-form-label-infoform-title": "รายละเอียด",
+       "upload-form-label-infoform-name": "ชื่อ",
+       "upload-form-label-infoform-description": "คำอธิบาย",
+       "upload-form-label-usage-title": "การใช้",
+       "upload-form-label-usage-filename": "ชื่อไฟล์",
        "backend-fail-backup": "ไม่สามารถสำรองไฟล์ \"$1\"",
        "backend-fail-notexists": "ไม่มีไฟล์ $1",
        "backend-fail-delete": "ไม่สามารถลบไฟล์ \"$1\"",
index a92a1b0..24b7adc 100644 (file)
        "upload-dialog-button-cancel": "İptal",
        "upload-dialog-button-save": "Kaydet",
        "upload-dialog-button-upload": "Yükle",
-       "upload-dialog-label-select-file": "Dosya seç",
-       "upload-dialog-label-infoform-title": "Ayrıntılar",
-       "upload-dialog-label-infoform-name": "Ad",
-       "upload-dialog-label-infoform-description": "Açıklama",
-       "upload-dialog-label-usage-title": "Kullanımı",
-       "upload-dialog-label-usage-filename": "Dosya adı",
+       "upload-form-label-select-file": "Dosya seç",
+       "upload-form-label-infoform-title": "Ayrıntılar",
+       "upload-form-label-infoform-name": "Ad",
+       "upload-form-label-infoform-description": "Açıklama",
+       "upload-form-label-usage-title": "Kullanımı",
+       "upload-form-label-usage-filename": "Dosya adı",
        "backend-fail-stream": "$1 dosyası okunamadı.",
        "backend-fail-backup": "\"$1\" dosyası yedeklenemedi.",
        "backend-fail-notexists": "$1 dosyası mevcut değil.",
index c2b7e8b..d0985a5 100644 (file)
        "upload-http-error": "Відбулася помилка HTTP: $1",
        "upload-copy-upload-invalid-domain": "З цього домену завантаження неможливе.",
        "upload-dialog-title": "Завантажити файл",
-       "upload-dialog-error": "Сталася помилка",
-       "upload-dialog-warning": "З'явилось попередження",
        "upload-dialog-button-cancel": "Скасувати",
        "upload-dialog-button-done": "Готово",
        "upload-dialog-button-save": "Зберегти",
        "upload-dialog-button-upload": "Завантажити",
-       "upload-dialog-label-select-file": "Обрати файл",
-       "upload-dialog-label-infoform-title": "Деталі",
-       "upload-dialog-label-infoform-name": "Назва",
-       "upload-dialog-label-infoform-description": "Опис",
-       "upload-dialog-label-usage-title": "Використання",
-       "upload-dialog-label-usage-filename": "Назва файлу",
+       "upload-process-error": "Сталася помилка",
+       "upload-process-warning": "З'явилось попередження",
+       "upload-form-label-select-file": "Обрати файл",
+       "upload-form-label-infoform-title": "Деталі",
+       "upload-form-label-infoform-name": "Назва",
+       "upload-form-label-infoform-description": "Опис",
+       "upload-form-label-usage-title": "Використання",
+       "upload-form-label-usage-filename": "Назва файлу",
        "backend-fail-stream": "Не вдалося транслювати файл $1.",
        "backend-fail-backup": "Не вдалося створити резервну копію файлу $1.",
        "backend-fail-notexists": "Файл $1 не існує.",
index 32c714a..07e4bb4 100644 (file)
        "upload-dialog-button-done": "Fato",
        "upload-dialog-button-save": "Salva",
        "upload-dialog-button-upload": "Carga",
-       "upload-dialog-label-select-file": "Siegli el file",
-       "upload-dialog-label-infoform-name": "Nome",
-       "upload-dialog-label-infoform-description": "Descrision",
-       "upload-dialog-label-usage-title": "Uso",
-       "upload-dialog-label-usage-filename": "Nome del file",
+       "upload-form-label-select-file": "Siegli el file",
+       "upload-form-label-infoform-name": "Nome",
+       "upload-form-label-infoform-description": "Descrision",
+       "upload-form-label-usage-title": "Uso",
+       "upload-form-label-usage-filename": "Nome del file",
        "backend-fail-stream": "Inposibiłe traxmetare el file $1.",
        "backend-fail-backup": "Inposibiłe fare el backup del file $1.",
        "backend-fail-notexists": "El file $1 no existe.",
index 6fff828..9dc8fbc 100644 (file)
        "upload-http-error": "Xảy ra lỗi HTTP: $1",
        "upload-copy-upload-invalid-domain": "Không có sẵn các bản sao tải lên tại tên miền này.",
        "upload-dialog-title": "Tải tập tin lên",
-       "upload-dialog-error": "Đã xuất hiện lỗi",
-       "upload-dialog-warning": "Đã xuất hiện cảnh báo",
        "upload-dialog-button-cancel": "Hủy bỏ",
        "upload-dialog-button-done": "Xong",
        "upload-dialog-button-save": "Lưu",
        "upload-dialog-button-upload": "Tải lên",
-       "upload-dialog-label-select-file": "Chọn tập tin",
-       "upload-dialog-label-infoform-title": "Chi tiết",
-       "upload-dialog-label-infoform-name": "Tên",
-       "upload-dialog-label-infoform-description": "Miêu tả",
-       "upload-dialog-label-usage-title": "Sử dụng",
-       "upload-dialog-label-usage-filename": "Tên tập tin",
+       "upload-process-error": "Đã xuất hiện lỗi",
+       "upload-process-warning": "Đã xuất hiện cảnh báo",
+       "upload-form-label-select-file": "Chọn tập tin",
+       "upload-form-label-infoform-title": "Chi tiết",
+       "upload-form-label-infoform-name": "Tên",
+       "upload-form-label-infoform-description": "Miêu tả",
+       "upload-form-label-usage-title": "Sử dụng",
+       "upload-form-label-usage-filename": "Tên tập tin",
        "backend-fail-stream": "Không thể gửi luồng tập tin $1.",
        "backend-fail-backup": "Không thể sao lưu tập tin $1.",
        "backend-fail-notexists": "Tập tin $1 không tồn tại.",
index 0a79897..af06d31 100644 (file)
        "upload-http-error": "მოხდა HTTP შეცდომა: $1",
        "upload-copy-upload-invalid-domain": "ამ დომენში ატვირთვების კოპირება არ არის ხელმისაწვდომი.",
        "upload-dialog-title": "გეხარგე ფაილეფი",
-       "upload-dialog-error": "ჩილათაქ მოხვადჷ",
        "upload-dialog-button-cancel": "გოუქვაფა",
        "upload-dialog-button-done": "ღოლამირჷ რე",
        "upload-dialog-button-save": "ჩუალა",
        "upload-dialog-button-upload": "ეხარგუა",
-       "upload-dialog-label-select-file": "გეგშაგორით ფაილი",
-       "upload-dialog-label-infoform-title": "დეტალეფი",
-       "upload-dialog-label-infoform-name": "ჯოხო",
-       "upload-dialog-label-infoform-description": "ეჭარუა",
-       "upload-dialog-label-usage-title": "გიმორინაფა",
-       "upload-dialog-label-usage-filename": "ფაილიშ ჯოხო",
+       "upload-process-error": "ჩილათაქ მოხვადჷ",
+       "upload-form-label-select-file": "გეგშაგორით ფაილი",
+       "upload-form-label-infoform-title": "დეტალეფი",
+       "upload-form-label-infoform-name": "ჯოხო",
+       "upload-form-label-infoform-description": "ეჭარუა",
+       "upload-form-label-usage-title": "გიმორინაფა",
+       "upload-form-label-usage-filename": "ფაილიშ ჯოხო",
        "backend-fail-stream": "ფაილი $1 ტრანსლირება ვერ მოხერხდა.",
        "backend-fail-backup": "ფაილი $1 სარეზერვო ასლის გაკეთება ვერ მოხერხდა.",
        "backend-fail-notexists": "ფაილი $1 არ არსებობს.",
index 064e619..dafae55 100644 (file)
        "upload-http-error": "א HTTP גרײַז האט פאַסירט: $1",
        "upload-copy-upload-invalid-domain": "ארויפלאדן טעקעס פון דעם דאמיין נישט מעגלעך.",
        "upload-dialog-title": "אַרױפֿלאָדן טעקע",
-       "upload-dialog-error": "א גרײַז האט פאסירט",
-       "upload-dialog-warning": "א ווארענונג האט פאסירט",
        "upload-dialog-button-cancel": "אַנולירן",
        "upload-dialog-button-done": "ערליידיקט",
        "upload-dialog-button-save": "אויפֿהיטן",
        "upload-dialog-button-upload": "אַרויפֿלאָדן",
-       "upload-dialog-label-select-file": "קלויבן טעקע",
-       "upload-dialog-label-infoform-title": "פרטים",
-       "upload-dialog-label-infoform-name": "נאָמען",
-       "upload-dialog-label-infoform-description": "באַשרײבונג",
-       "upload-dialog-label-usage-title": "באניץ",
-       "upload-dialog-label-usage-filename": "טעקע נאמען",
+       "upload-process-error": "א גרײַז האט פאסירט",
+       "upload-process-warning": "א ווארענונג האט פאסירט",
+       "upload-form-label-select-file": "קלויבן טעקע",
+       "upload-form-label-infoform-title": "פרטים",
+       "upload-form-label-infoform-name": "נאָמען",
+       "upload-form-label-infoform-description": "באַשרײבונג",
+       "upload-form-label-usage-title": "באניץ",
+       "upload-form-label-usage-filename": "טעקע נאמען",
        "backend-fail-stream": "קען נישט מאכן שטראמען טעקע $1.",
        "backend-fail-notexists": "נישט פֿאראן די טעקע $1.",
        "backend-fail-notsame": "א נישט־אידענטישע טעקע עקזיסטירט שוין ביי \"$1\".",
index d5dc7ad..c87d14c 100644 (file)
        "upload-http-error": "一個HTTP錯誤發生咗: $1",
        "upload-copy-upload-invalid-domain": "從嗰個域名度冇複製上傳功能",
        "upload-dialog-title": "上載檔案",
-       "upload-dialog-error": "出錯",
-       "upload-dialog-warning": "警告",
        "upload-dialog-button-cancel": "取消",
        "upload-dialog-button-done": "搞掂",
        "upload-dialog-button-save": "儲存",
        "upload-dialog-button-upload": "上載",
-       "upload-dialog-label-select-file": "揀檔案",
-       "upload-dialog-label-infoform-title": "細節",
-       "upload-dialog-label-infoform-name": "名",
-       "upload-dialog-label-infoform-description": "描述",
-       "upload-dialog-label-usage-title": "用法",
-       "upload-dialog-label-usage-filename": "文件名",
+       "upload-process-error": "出錯",
+       "upload-process-warning": "警告",
+       "upload-form-label-select-file": "揀檔案",
+       "upload-form-label-infoform-title": "細節",
+       "upload-form-label-infoform-name": "名",
+       "upload-form-label-infoform-description": "描述",
+       "upload-form-label-usage-title": "用法",
+       "upload-form-label-usage-filename": "文件名",
        "backend-fail-stream": "傳送唔到檔案「$1」。",
        "backend-fail-backup": "檔案 \"$1\" 唔備份得。",
        "backend-fail-notexists": "檔案$1唔存在。",
index 1113d86..ece1aed 100644 (file)
        "group-bot": "机器人",
        "group-sysop": "管理员",
        "group-bureaucrat": "行政员",
-       "group-suppress": "ç\9b\91ç\9d£å\91\98",
+       "group-suppress": "ç¦\81æ­¢æ\89§è¡\8cè\80\85",
        "group-all": "(所有)",
        "group-user-member": "{{GENDER:$1|用户}}",
        "group-autoconfirmed-member": "自动确认用户",
        "group-bot-member": "机器人",
        "group-sysop-member": "{{GENDER:$1|管理员}}",
        "group-bureaucrat-member": "行政员",
-       "group-suppress-member": "{{GENDER:$1|ç\9b\91ç\9d£å\91\98}}",
+       "group-suppress-member": "{{GENDER:$1|ç¦\81æ­¢æ\89§è¡\8cè\80\85}}",
        "grouppage-user": "{{ns:project}}:用户",
        "grouppage-autoconfirmed": "{{ns:project}}:自动确认用户",
        "grouppage-bot": "{{ns:project}}:机器人",
        "grouppage-sysop": "{{ns:project}}:管理员",
        "grouppage-bureaucrat": "{{ns:project}}:行政员",
-       "grouppage-suppress": "{{ns:project}}:ç\9b\91ç\9d£",
+       "grouppage-suppress": "{{ns:project}}:ç¦\81æ­¢",
        "right-read": "阅读页面",
        "right-edit": "编辑页面",
        "right-createpage": "创建非讨论页面",
        "upload-http-error": "发生HTTP错误:$1",
        "upload-copy-upload-invalid-domain": "不能从该域名上载文件副本。",
        "upload-dialog-title": "上传文件",
-       "upload-dialog-error": "发生错误",
-       "upload-dialog-warning": "发生一条警告",
        "upload-dialog-button-cancel": "取消",
        "upload-dialog-button-done": "完成",
        "upload-dialog-button-save": "保存",
        "upload-dialog-button-upload": "上传",
-       "upload-dialog-label-select-file": "选择文件",
-       "upload-dialog-label-infoform-title": "详细信息",
-       "upload-dialog-label-infoform-name": "名称",
-       "upload-dialog-label-infoform-description": "说明",
-       "upload-dialog-label-usage-title": "用法",
-       "upload-dialog-label-usage-filename": "文件名",
+       "upload-process-error": "发生错误",
+       "upload-process-warning": "发生一条警告",
+       "upload-form-label-select-file": "选择文件",
+       "upload-form-label-infoform-title": "详细信息",
+       "upload-form-label-infoform-name": "名称",
+       "upload-form-label-infoform-description": "说明",
+       "upload-form-label-usage-title": "用法",
+       "upload-form-label-usage-filename": "文件名",
        "backend-fail-stream": "无法流传送文件$1。",
        "backend-fail-backup": "无法备份文件$1。",
        "backend-fail-notexists": "条目$1不存在。",
        "filerevert-legend": "恢复文件",
        "filerevert-intro": "你将要恢复文件'''[[Media:$1|$1]]'''至[$4 $2 $3的版本]。",
        "filerevert-comment": "原因:",
-       "filerevert-defaultcomment": "恢复至$1 $2的版本",
+       "filerevert-defaultcomment": "回退至$1 $2($3)的版本",
        "filerevert-submit": "恢复",
        "filerevert-success": "<strong>[[Media:$1|$1]]</strong>已经恢复至[$4 $2 $3的版本]。",
        "filerevert-badversion": "文件并无所请求时间戳下的早期本地版本。",
        "nopagetext": "您所指定的目标页面并不存在。",
        "pager-newer-n": "前$1个",
        "pager-older-n": "后$1个",
-       "suppress": "ç\9b\91ç\9d£",
+       "suppress": "ç¦\81æ­¢",
        "querypage-disabled": "本特殊页面因性能问题而停用。",
        "apihelp": "API 帮助",
        "apihelp-no-such-module": "找不到模块“$1”。",
index f2ef8fd..d09f04b 100644 (file)
        "upload-http-error": "發生 HTTP 錯誤:$1",
        "upload-copy-upload-invalid-domain": "此網域不允許複製上傳的檔案。",
        "upload-dialog-title": "上傳檔案",
-       "upload-dialog-error": "發生錯誤",
-       "upload-dialog-warning": "發生警告",
        "upload-dialog-button-cancel": "取消",
        "upload-dialog-button-done": "完成",
        "upload-dialog-button-save": "儲存",
        "upload-dialog-button-upload": "上傳",
-       "upload-dialog-label-select-file": "選擇檔案",
-       "upload-dialog-label-infoform-title": "詳細資訊",
-       "upload-dialog-label-infoform-name": "名稱",
-       "upload-dialog-label-infoform-description": "描述",
-       "upload-dialog-label-usage-title": "用法",
-       "upload-dialog-label-usage-filename": "檔案名稱",
+       "upload-process-error": "發生錯誤",
+       "upload-process-warning": "發生警告",
+       "upload-form-label-select-file": "選擇檔案",
+       "upload-form-label-infoform-title": "詳細資訊",
+       "upload-form-label-infoform-name": "名稱",
+       "upload-form-label-infoform-description": "描述",
+       "upload-form-label-usage-title": "用法",
+       "upload-form-label-usage-filename": "檔案名稱",
        "backend-fail-stream": "無法傳輸檔案 \"$1\"。",
        "backend-fail-backup": "無法備份檔案 \"$1\"。",
        "backend-fail-notexists": "檔案 $1 不存在。",
diff --git a/languages/messages/MessagesOlo.php b/languages/messages/MessagesOlo.php
new file mode 100644 (file)
index 0000000..ba3d364
--- /dev/null
@@ -0,0 +1,14 @@
+<?php
+/** Livvi-Karelian (Livvinкarjala)
+ *
+ * To improve a translation please visit https://translatewiki.net
+ *
+ * @ingroup Language
+ * @file
+ *
+ */
+
+$fallback = 'ru';
+
+$linkTrail = '/^([a-zčČšŠžŽäÄöÖ]+)(.*)$/sDu';
+
index 3b3fdee..f3b9c3c 100644 (file)
@@ -1,3 +1,3 @@
 -- Hopefully temporary index.
--- For https://bugzilla.wikimedia.org/show_bug.cgi?id=21279
+-- For https://phabricator.wikimedia.org/T23279
 CREATE INDEX /*i*/ar_revid ON /*$wgDBprefix*/archive ( ar_rev_id );
\ No newline at end of file
index 22cc587..9a991b8 100644 (file)
@@ -1,7 +1,7 @@
 --
 -- patch-backlinkindexes.sql
 --
--- Per bug 6440 / http://bugzilla.wikimedia.org/show_bug.cgi?id=6440
+-- Per task T8440 / https://phabricator.wikimedia.org/T8440
 --
 -- Improve performance of the "what links here"-type queries
 --
index 24ad84f..e2b2c3a 100644 (file)
@@ -1,7 +1,7 @@
 --
 -- patch-categorylinksindex.sql
 --
--- Per bug 10280 / http://bugzilla.wikimedia.org/show_bug.cgi?id=10280
+-- Per task T12280 / https://phabricator.wikimedia.org/T12280
 --
 -- Improve enum continuation performance of the what pages belong to a category query
 --
index 06ae17f..4e19b79 100644 (file)
@@ -19,7 +19,7 @@
  *
  * @file
  * @author TyA <tya.wiki@gmail.com>
- * @see [[bugzilla:30976]]
+ * @see https://phabricator.wikimedia.org/T32976
  * @ingroup Maintenance
  */
 
index fc0bed1..b35ebad 100644 (file)
@@ -1174,14 +1174,14 @@ return array(
                        'mediawiki.Upload',
                ),
                'messages' => array(
-                       'upload-dialog-error',
-                       'upload-dialog-warning',
-                       'upload-dialog-label-select-file',
-                       'upload-dialog-label-infoform-title',
-                       'upload-dialog-label-infoform-name',
-                       'upload-dialog-label-infoform-description',
-                       'upload-dialog-label-usage-title',
-                       'upload-dialog-label-usage-filename',
+                       'upload-process-error',
+                       'upload-process-warning',
+                       'upload-form-label-select-file',
+                       'upload-form-label-infoform-title',
+                       'upload-form-label-infoform-name',
+                       'upload-form-label-infoform-description',
+                       'upload-form-label-usage-title',
+                       'upload-form-label-usage-filename',
                ),
        ),
        'mediawiki.toc' => array(
index eaa138b..f6857e8 100644 (file)
                                new RegExp( /(https?|ftp|file):\/\// )
                        ],
                        isoDate: [
-                               new RegExp( /^\d{4}[\/\-]\d{1,2}[\/\-]\d{1,2}$/ )
+                               new RegExp( /^([-+]?\d{1,4})-([01]\d)-([0-3]\d)([T\s]((([01]\d|2[0-3])(:?[0-5]\d)?|24:?00)?(:?([0-5]\d))?([.,]\d+)?)([zZ]|([\+-])([01]\d|2[0-3]):?([0-5]\d)?)?)?/ ),
+                               new RegExp( /^([-+]?\d{1,4})-([01]\d)-([0-3]\d)/ )
                        ],
                        usLongDate: [
                                new RegExp( /^[A-Za-z]{3,10}\.? [0-9]{1,2}, ([0-9]{4}|'?[0-9]{2}) (([0-2]?[0-9]:[0-5][0-9])|([0-1]?[0-9]:[0-5][0-9]\s(AM|PM)))$/ )
                        return ts.rgx.isoDate[ 0 ].test( s );
                },
                format: function ( s ) {
-                       return $.tablesorter.formatFloat( ( s !== '' ) ? new Date( s.replace(
-                       new RegExp( /-/g ), '/' ) ).getTime() : '0' );
+                       var isodate,
+                               matches;
+                       if ( !Date.prototype.toISOString ) {
+                               // Old browsers don't understand iso, Fallback to US date parsing and ignore the time part.
+                               matches = $.trim( s ).match( ts.rgx.isoDate[ 1 ] );
+                               if ( matches ) {
+                                       isodate = new Date( matches[ 2 ]  + '/' + matches[ 3 ] + '/' + matches[ 1 ] );
+                               } else {
+                                       return $.tablesorter.formatFloat( 0 );
+                               }
+                       } else {
+                               isodate = new Date( $.trim( s ) );
+                       }
+                       return $.tablesorter.formatFloat( ( isodate !== undefined ) ? isodate.getTime() : 0 );
                },
                type: 'numeric'
        } );
index 677d26d..c6ae5ac 100644 (file)
                 *
                 * TODO: Is there a way we can ask the browser what's supported in `<img>`s?
                 *
-                * TODO: Put SVG back after working around Firefox 7 bug <https://bugzilla.wikimedia.org/show_bug.cgi?id=31643>
+                * TODO: Put SVG back after working around Firefox 7 bug <https://phabricator.wikimedia.org/T33643>
                 *
                 * @param {File} file
                 * @return {boolean}
index 0f85154..cb532c3 100644 (file)
                this.uploadPromise.always( function () {
 
                        if ( layout.upload.getState() === mw.Upload.State.ERROR ) {
-                               deferred.reject( new OO.ui.Error( mw.msg( 'upload-dialog-error' )  ) );
+                               deferred.reject( new OO.ui.Error( mw.msg( 'upload-process-error' )  ) );
                                return false;
                        }
 
                        if ( layout.upload.getState() === mw.Upload.State.WARNING ) {
-                               deferred.reject( new OO.ui.Error( mw.msg( 'upload-dialog-error' )  ) );
+                               deferred.reject( new OO.ui.Error( mw.msg( 'upload-process-error' )  ) );
                                return false;
                        }
 
                                var name;
 
                                if ( layout.upload.getState() === mw.Upload.State.ERROR ) {
-                                       deferred.reject( new OO.ui.Error( mw.msg( 'upload-dialog-error' ) ) );
+                                       deferred.reject( new OO.ui.Error( mw.msg( 'upload-process-error' ) ) );
                                        return false;
                                }
 
                                if ( layout.upload.getState() === mw.Upload.State.WARNING ) {
-                                       deferred.reject( new OO.ui.Error( mw.msg( 'upload-dialog-warning' ) ) );
+                                       deferred.reject( new OO.ui.Error( mw.msg( 'upload-process-warning' ) ) );
                                        return false;
                                }
 
                var fieldset;
 
                this.selectFileWidget = new OO.ui.SelectFileWidget();
-               fieldset = new OO.ui.FieldsetLayout( { label: mw.msg( 'upload-dialog-label-select-file' ) } );
+               fieldset = new OO.ui.FieldsetLayout( { label: mw.msg( 'upload-form-label-select-file' ) } );
                fieldset.addItems( [ this.selectFileWidget ] );
                this.uploadForm = new OO.ui.FormLayout( { items: [ fieldset ] } );
 
                } );
 
                fieldset = new OO.ui.FieldsetLayout( {
-                       label: mw.msg( 'upload-dialog-label-infoform-title' )
+                       label: mw.msg( 'upload-form-label-infoform-title' )
                } );
                fieldset.addItems( [
                        new OO.ui.FieldLayout( this.filenameWidget, {
-                               label: mw.msg( 'upload-dialog-label-infoform-name' ),
+                               label: mw.msg( 'upload-form-label-infoform-name' ),
                                align: 'top'
                        } ),
                        new OO.ui.FieldLayout( this.descriptionWidget, {
-                               label: mw.msg( 'upload-dialog-label-infoform-description' ),
+                               label: mw.msg( 'upload-form-label-infoform-description' ),
                                align: 'top'
                        } )
                ] );
 
                this.filenameUsageWidget = new OO.ui.TextInputWidget();
                fieldset = new OO.ui.FieldsetLayout( {
-                       label: mw.msg( 'upload-dialog-label-usage-title' )
+                       label: mw.msg( 'upload-form-label-usage-title' )
                } );
                fieldset.addItems( [
                        new OO.ui.FieldLayout( this.filenameUsageWidget, {
-                               label: mw.msg( 'upload-dialog-label-usage-filename' ),
+                               label: mw.msg( 'upload-form-label-usage-filename' ),
                                align: 'top'
                        } )
                ] );
index 4c6c9a5..7719a28 100644 (file)
@@ -10354,12 +10354,52 @@ BUG 553: link with two variables in a piped link
 {|
 |[[{{{1}}}|{{{2}}}]]
 |}
-!! html
+!! html/php
 <table>
 <tr>
 <td>[[{{{1}}}|{{{2}}}]]
 </td></tr></table>
 
+!! html/parsoid
+<table>
+<tbody><tr><td>[[<span about="#mwt5" typeof="mw:Param" data-parsoid='{"src":"{{{1}}}"}'>{{{1}}}</span>|<span about="#mwt2" typeof="mw:Param" data-parsoid='{"src":"{{{2}}}"}'>{{{2}}}</span>]]</td></tr>
+!! end
+
+# See: T2553
+!! test
+Abort table cell attribute parsing on wikilink
+!! wikitext
+{|
+| testing [[one|two]] | three || four
+| testing one two | three || four
+|}
+!! html/php
+<table>
+<tr>
+<td> testing <a href="/index.php?title=One&amp;action=edit&amp;redlink=1" class="new" title="One (page does not exist)">two</a> | three </td>
+<td> four
+</td>
+<td> three </td>
+<td> four
+</td></tr></table>
+
+!! html/parsoid
+<table>
+<tbody><tr data-parsoid='{"autoInsertedEnd":true,"autoInsertedStart":true}'><td data-parsoid='{"autoInsertedEnd":true}'> testing <a rel="mw:WikiLink" href="./One" title="One" data-parsoid='{"stx":"piped","a":{"href":"./One"},"sa":{"href":"one"}}'>two</a> | three </td><td data-parsoid='{"stx_v":"row","autoInsertedEnd":true}'> four</td>
+<td data-parsoid='{"a":{"testing":null,"one":null,"two":null},"sa":{"testing":"","one":"","two":""},"autoInsertedEnd":true}'> three </td><td data-parsoid='{"stx_v":"row","autoInsertedEnd":true}'> four</td></tr>
+</tbody></table>
+!! end
+
+!! test
+Don't abort table cell attribute parsing if wikilink is found in template arg
+!! wikitext
+{|
+| Test {{#tag:ref|One two "[[three]]" four}}
+|}
+!! html/parsoid
+<table>
+<tbody><tr><td> Test <ref about="#mwt1" typeof="mw:Transclusion" data-parsoid='{"pi":[[{"k":"1","spc":["","","",""]}]]}' data-mw='{"parts":[{"template":{"target":{"wt":"#tag:ref","function":"#tag"},"params":{"1":{"wt":"One two \"[[three]]\" four"}},"i":0}}]}'>One two "<a rel="mw:WikiLink" href="./Three" title="Three">three</a>" four</ref></td></tr>
+</tbody></table>
 !! end
 
 !! test
@@ -11819,6 +11859,17 @@ Templates: Ugly templates: 6. Template encapsulation test: Cyclical nesting of t
 </table></td></tr></tbody></table>
 !! end
 
+!! test
+Templates: Parameters substituted at the top-level
+!! wikitext
+{{{foo|''who'' {{echo|me}}? '''never!'''}}}
+!! html/php
+<p><i>who</i> me? <b>never!</b>
+</p>
+!! html/parsoid
+<p about="#mwt2" typeof="mw:Param" data-parsoid="{&quot;src&quot;:&quot;{{{foo|''who'' {{echo|me}}? '''never!'''}}}&quot;}"><i>who</i> me? <b>never!</b></p>
+!! end
+
 !!test
 Parser Functions: 1. Simple example
 !! wikitext
@@ -17974,11 +18025,15 @@ Special:Search page linking.
 {{!}} is a magic word
 !! wikitext
 {{!}} is a magic word there and {{!}} is still a magic word here
+| is not a magic word here but {{!}} is still a magic word here
 !! html/php
 <p>| is a magic word there and | is still a magic word here
+| is not a magic word here but | is still a magic word here
 </p>
 !! html/parsoid
-<p><span about="#mwt1" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"!","href":"./Template:!"},"params":{},"i":0}}]}' data-parsoid='{"pi":[[]]}'>|</span> is a magic word there and <span about="#mwt2" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"!","href":"./Template:!"},"params":{},"i":0}}]}' data-parsoid='{"pi":[[]]}'>|</span> is still a magic word here</p>
+<p><span about="#mwt1" typeof="mw:Transclusion" data-parsoid='{"pi":[[]]}' data-mw='{"parts":[{"template":{"target":{"wt":"!","href":"./Template:!"},"params":{},"i":0}}]}'>|</span> is a magic word there and <span about="#mwt2" typeof="mw:Transclusion" data-parsoid='{"pi":[[]]}' data-mw='{"parts":[{"template":{"target":{"wt":"!","href":"./Template:!"},"params":{},"i":0}}]}'>|</span> is still a magic word here
+| is not a magic word here but <span about="#mwt3" typeof="mw:Transclusion" data-parsoid='{"pi":[[]]}' data-mw='{"parts":[{"template":{"target":{"wt":"!","href":"./Template:!"},"params":{},"i":0}}]}'>|</span> is still a magic word here</p>
+
 !! end
 
 !! test
@@ -23745,11 +23800,15 @@ RT-ed inter-element separators should be valid separators
 {|
 |- [[foo]]
 |}
-!! html
+!! html/php
 <table>
 
 </table>
 
+!! html/parsoid
+<table>
+<tbody><tr data-parsoid='{"startTagSrc":"|-","a":{"[[foo]]":null},"sa":{"[[foo]]":""},"autoInsertedEnd":true}'></tr>
+</tbody></table>
 !!end
 
 # Parsoid-only since PHP parser relies on Tidy for correct output
@@ -26060,6 +26119,37 @@ parsoid={
 </table>
 !! end
 
+## T111151 Remove font elements without attributes
+!! test
+5a. font tags without attributes should be dropped in scrubWikitext mode
+!! options
+parsoid={
+  "modes": ["html2wt"],
+  "scrubWikitext": true
+}
+!! html
+<font>foo</font>
+<font><font>bar</font></font>
+<font class="x">boo</font>
+!! wikitext
+foo
+bar
+<font class="x">boo</font>
+!! end
+
+!! test
+5b. font tags should not be dropped without scrubWikitext being enabled
+!! options
+parsoid={
+  "modes": ["html2wt"],
+  "scrubWikitext": false
+}
+!! html
+<font>foo</font>
+!! wikitext
+<font>foo</font>
+!! end
+
 !! test
 Escape nowiki DOM elements
 !! options
index 7dc7027..ec95665 100644 (file)
@@ -1151,7 +1151,7 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase {
 
        /**
         * Note: we are overriding this method to remove the deprecated error
-        * @see https://bugzilla.wikimedia.org/show_bug.cgi?id=69505
+        * @see https://phabricator.wikimedia.org/T71505
         * @see https://github.com/sebastianbergmann/phpunit/issues/1292
         * @deprecated
         *
index e89e36f..69dcd4c 100644 (file)
@@ -551,10 +551,10 @@ class GlobalTest extends MediaWikiTestCase {
 
        public static function provideMakeUrlIndexes() {
                return array(
+                       // Testcase for T30627
                        array(
-                               // just a regular :)
-                               'https://bugzilla.wikimedia.org/show_bug.cgi?id=28627',
-                               array( 'https://org.wikimedia.bugzilla./show_bug.cgi?id=28627' )
+                               'https://example.org/test.cgi?id=12345',
+                               array( 'https://org.example./test.cgi?id=12345' )
                        ),
                        array(
                                // mailtos are handled special
@@ -563,7 +563,7 @@ class GlobalTest extends MediaWikiTestCase {
                                array( 'mailto:org.wikimedia@wiki.' )
                        ),
 
-                       // file URL cases per bug 28627...
+                       // file URL cases per T30627...
                        array(
                                // three slashes: local filesystem path Unix-style
                                'file:///whatever/you/like.txt',
@@ -587,12 +587,12 @@ class GlobalTest extends MediaWikiTestCase {
                        // Those will survive the algorithm but with results that
                        // are less consistent.
 
-                       // protocol-relative URL cases per bug 29854...
+                       // protocol-relative URL cases per T31854...
                        array(
-                               '//bugzilla.wikimedia.org/show_bug.cgi?id=28627',
+                               '//example.org/test.cgi?id=12345',
                                array(
-                                       'http://org.wikimedia.bugzilla./show_bug.cgi?id=28627',
-                                       'https://org.wikimedia.bugzilla./show_bug.cgi?id=28627'
+                                       'http://org.example./test.cgi?id=12345',
+                                       'https://org.example./test.cgi?id=12345'
                                )
                        ),
                );
index 1c3e853..df54914 100644 (file)
@@ -114,7 +114,7 @@ class HtmlFormatterTest extends MediaWikiTestCase {
                                array(),
                                $removeTags, // Have some rules to trigger a DOM parse
                        ),
-                       // https://bugzilla.wikimedia.org/show_bug.cgi?id=53086
+                       // https://phabricator.wikimedia.org/T55086
                        array(
                                'Foo<sup id="cite_ref-1" class="reference"><a href="#cite_note-1">[1]</a></sup>'
                                        . ' <a href="/wiki/Bar" title="Bar" class="mw-redirect">Bar</a>',
index ea753e8..7ef44e7 100644 (file)
@@ -10,6 +10,9 @@
 class ImportTest extends MediaWikiLangTestCase {
 
        private function getInputStreamSource( $xml ) {
+               if ( ini_get( 'allow_url_fopen' ) != 1 ) {
+                       $this->markTestSkipped( 'bug 73283: this test needs allow_url_fopen to be enabled' );
+               }
                $file = 'data:application/xml,' . $xml;
                $status = ImportStreamSource::newFromFile( $file );
                if ( !$status->isGood() ) {
index 3babb97..63e0c8e 100644 (file)
@@ -92,7 +92,7 @@ class ActionTest extends MediaWikiTestCase {
        }
 
        public function testGetActionName_editredlinkWorkaround() {
-               // See https://bugzilla.wikimedia.org/show_bug.cgi?id=20966
+               // See https://phabricator.wikimedia.org/T22966
                $context = $this->getContext( 'editredlink' );
                $actionName = Action::getActionName( $context );
 
@@ -100,7 +100,7 @@ class ActionTest extends MediaWikiTestCase {
        }
 
        public function testGetActionName_historysubmitWorkaround() {
-               // See https://bugzilla.wikimedia.org/show_bug.cgi?id=20966
+               // See https://phabricator.wikimedia.org/T22966
                $context = $this->getContext( 'historysubmit' );
                $actionName = Action::getActionName( $context );
 
@@ -108,7 +108,7 @@ class ActionTest extends MediaWikiTestCase {
        }
 
        public function testGetActionName_revisiondeleteWorkaround() {
-               // See https://bugzilla.wikimedia.org/show_bug.cgi?id=20966
+               // See https://phabricator.wikimedia.org/T22966
                $context = $this->getContext( 'historysubmit' );
                $context->getRequest()->setVal( 'revisiondelete', true );
                $actionName = Action::getActionName( $context );
index 575efd6..e0488b7 100644 (file)
@@ -30,11 +30,11 @@ class ApiBlockTest extends ApiTestCase {
 
        /**
         * This test has probably always been broken and use an invalid token
-        * Bug tracking brokenness is https://bugzilla.wikimedia.org/35646
+        * Bug tracking brokenness is https://phabricator.wikimedia.org/T37646
         *
         * Root cause is https://gerrit.wikimedia.org/r/3434
         * Which made the Block/Unblock API to actually verify the token
-        * previously always considered valid (bug 34212).
+        * previously always considered valid (T36212).
         */
        public function testMakeNormalBlock() {
                $tokens = $this->getTokens();
index c852d72..40de254 100644 (file)
@@ -11,7 +11,7 @@
  * @todo Port the other Upload tests, and other API tests to this framework
  *
  * @todo Broken test, reports false errors from time to time.
- * See https://bugzilla.wikimedia.org/26169
+ * See https://phabricator.wikimedia.org/T28169
  *
  * @todo This is pretty sucky... needs to be prettified.
  *
index 0cb44e9..09c7c0c 100644 (file)
@@ -134,7 +134,7 @@ class ApiFormatPhpTest extends ApiFormatTestBase {
                } catch ( UsageException $ex ) {
                        ob_end_clean();
                        $this->assertSame(
-                               'This response cannot be represented using format=php. See https://bugzilla.wikimedia.org/show_bug.cgi?id=66776',
+                               'This response cannot be represented using format=php. See https://phabricator.wikimedia.org/T68776',
                                $ex->getMessage(),
                                'Expected exception'
                        );
index 345fd0a..1ebba1a 100644 (file)
@@ -193,7 +193,7 @@ class PreprocessorTest extends MediaWikiTestCase {
        }
 
        /**
-        * Tests from Bug 28642 · https://bugzilla.wikimedia.org/28642
+        * Tests from T30642 · https://phabricator.wikimedia.org/T30642
         */
        public static function provideHeadings() {
                // @codingStandardsIgnoreStart Ignore Generic.Files.LineLength.TooLong
index 52c242c..d63af9a 100644 (file)
@@ -19,6 +19,10 @@ class AvroValidatorTest extends PHPUnit_Framework_TestCase {
 
        public function getErrorsProvider() {
                $stringSchema = AvroSchema::parse( json_encode( array( 'type' => 'string' ) ) );
+               $stringArraySchema = AvroSchema::parse( json_encode( array(
+                       'type' => 'array',
+                       'items' => 'string',
+               ) ) );
                $recordSchema = AvroSchema::parse( json_encode( array(
                        'type' => 'record',
                        'name' => 'ut',
@@ -80,6 +84,18 @@ class AvroValidatorTest extends PHPUnit_Framework_TestCase {
                                        )
                                ) )
                        ),
+                       array(
+                               'Empty array is accepted',
+                               $stringArraySchema, array(), array()
+                       ),
+                       array(
+                               'correct array element accepted',
+                               $stringArraySchema, array( 'fizzbuzz' ), array()
+                       ),
+                       array(
+                               'incorrect array element rejected',
+                               $stringArraySchema, array( '12', 34 ), array( 'Expected string, but recieved integer' )
+                       ),
                );
        }
 
index 1acbc24..d93dafb 100644 (file)
@@ -26,6 +26,8 @@ phpunit.php enables colors for other OSs at runtime
                </testsuite>
                <testsuite name="skins">
                        <directory>skins</directory>
+                       <directory>structure</directory>
+                       <file>suites/LessTestSuite.php</file>
                </testsuite>
                <!-- As there is a class Maintenance, we cannot use the
                     name "maintenance" directly -->
index 032551d..1726a48 100644 (file)
@@ -5,7 +5,7 @@
         */
 
        var text, ipv4,
-               simpleMDYDatesInMDY, simpleMDYDatesInDMY, oldMDYDates, complexMDYDates, clobberedDates, MYDates, YDates,
+               simpleMDYDatesInMDY, simpleMDYDatesInDMY, oldMDYDates, complexMDYDates, clobberedDates, MYDates, YDates, ISODates,
                currencyData, transformedCurrencyData;
 
        QUnit.module( 'jquery.tablesorter.parsers', QUnit.newMwEnvironment( {
        ];
        parserTest( 'Y Dates', 'date', YDates );
 
+       ISODates = [
+               [ '2000',               false, 946684800000, 'Plain 4-digit year' ],
+               [ '2000-01',            false, 946684800000, 'Year with month' ],
+               [ '2000-01-01', true, 946684800000, 'Year with month and day' ],
+               [ '2000-13-01', true, 0, 'Non existant month' ],
+               [ '2000-01-32', true, 0, 'Non existant day' ],
+               [ '2000-01-01T12:30:30',                true, 946729830000, 'Date with a time' ],
+               [ '2000-01-01T12:30:30Z',       true, 946729830000, 'Date with a UTC+0 time' ],
+               [ '2000-01-01T24:30:30Z',       true, 0, 'Date with invalid hours' ],
+               [ '2000-01-01T12:60:30Z',       true, 0, 'Date with invalid minutes' ],
+               [ '2000-01-01T12:30:61Z',       true, 0, 'Date with invalid amount of seconds' ],
+               [ '2000-01-01T23:59:59Z',       true, 946771199000, 'Edges of time' ],
+               [ '2000-01-01T12:30:30.111Z',   true, 946729830111, 'Date with milliseconds' ],
+               [ '2000-01-01T12:30:30.11111Z', true, 946729830111, 'Date with too high precision' ],
+               [ '2000-01-01T12:30:30,111Z',   true, 0, 'Date with milliseconds and , separator' ],
+               [ '2000-01-01T12:30:30+01:00',  true, 946726230000, 'Date time in UTC+1' ],
+               [ '2000-01-01T12:30:30+01:30',  true, 946724430000, 'Date time in UTC+1:30' ],
+               [ '2000-01-01T12:30:30-01:00',  true, 946733430000, 'Date time in UTC-1' ],
+               [ '2000-01-01T12:30:30-01:30',  true, 946735230000, 'Date time in UTC-1:30' ],
+               [ '2000-01-01T12:30:30.111+01:00', true, 946726230111, 'Date time and milliseconds in UTC+1 ' ]
+               /* Disable testcases, because behavior is browser dependant */
+               /*
+               [ '2000-11-31', true, 0, '31 days in 30 day month' ],
+               [ '50-01-01',   false, -60589296000000, 'Year with just two digits' ],
+               [ '-1000-01-01',        true, -93724128000000, 'Year BC' ],
+               [ '+1000-01-01',        true, -30610224000000, 'Date with +sign' ],
+               [ '2000-01-01 12:30:30Z',       true, 0, 'Date and time with no T marker' ],
+               [ '2000-01-01T12:30:60Z',       true, 946729860000, 'Date with leap second' ],
+               [ '2000-01-01T12:30:30-24:00',  true, 946816230000, 'Date time in UTC-24' ],
+               [ '2000-01-01T12:30:30+24:00',  true, 946643430000, 'Date time in UTC+24' ],
+               [ '2000-01-01T12:30:30+0100',   true, 946726230000, 'Time without separator in timezone offset' ]
+               */
+       ];
+       parserTest( 'ISO Dates', 'isoDate', ISODates );
+
        currencyData = [
                [ '1.02 $',     true, 1.02, '' ],
                [ '$ 3.00',     true, 3, '' ],
index d4d0ce1..8026cc3 100644 (file)
                        [ 'January 01 2010' ],
                        [ 'January 16 2010' ],
                        [ 'February 05 2010' ]
+               ],
+               isoDateSorting = [
+                       [ '2010-02-01' ],
+                       [ '2009-12-25T12:30:45.001Z' ],
+                       [ '2010-01-31' ],
+                       [ '2009' ],
+                       [ '2009-12-25T12:30:45' ],
+                       [ '2009-12-25T12:30:45.111' ],
+                       [ '2009-12-25T12:30:45+01:00' ]
+               ],
+               isoDateSortingSorted = [
+                       [ '2009' ],
+                       [ '2009-12-25T12:30:45' ],
+                       [ '2009-12-25T12:30:45+01:00' ],
+                       [ '2009-12-25T12:30:45.001Z' ],
+                       [ '2009-12-25T12:30:45.111' ],
+                       [ '2010-01-31' ],
+                       [ '2010-02-01' ]
                ];
 
        QUnit.module( 'jquery.tablesorter', QUnit.newMwEnvironment( {
                }
        );
 
+       tableTest(
+               'ISO date sorting',
+               [ 'isoDate' ],
+               isoDateSorting,
+               isoDateSortingSorted,
+               function ( $table ) {
+                       mw.config.set( 'wgDefaultDateFormat', 'dmy' );
+
+                       $table.tablesorter();
+                       $table.find( '.headerSort:eq(0)' ).click();
+               }
+       );
+
        QUnit.test( 'Sorting images using alt text', 1, function ( assert ) {
                var $table = $(
                        '<table class="sortable">' +
index e7f4517..161b8e1 100644 (file)
@@ -41,7 +41,7 @@
                        'gender-msg-currentuser': '{{GENDER:|blue|pink|green}}',
 
                        'plural-msg': 'Found $1 {{PLURAL:$1|item|items}}',
-                       // See https://bugzilla.wikimedia.org/69993
+                       // See https://phabricator.wikimedia.org/T71993
                        'plural-msg-explicit-forms-nested': 'Found {{PLURAL:$1|$1 results|0=no results in {{SITENAME}}|1=$1 result}}',
                        // Assume the grammar form grammar_case_foo is not valid in any language
                        'grammar-msg': 'Przeszukaj {{GRAMMAR:grammar_case_foo|{{SITENAME}}}}',
index 111d85b..cec0552 100644 (file)
 
                hello = mw.message( 'hello' );
 
-               // https://bugzilla.wikimedia.org/show_bug.cgi?id=44459
+               // https://phabricator.wikimedia.org/T46459
                assert.equal( hello.format, 'text', 'Message property "format" defaults to "text"' );
 
                assert.strictEqual( hello.map, mw.messages, 'Message property "map" defaults to the global instance in mw.messages' );