Merge "resourceloader: Increase minification cache version"
authorjenkins-bot <jenkins-bot@gerrit.wikimedia.org>
Fri, 17 Aug 2018 19:26:42 +0000 (19:26 +0000)
committerGerrit Code Review <gerrit@wikimedia.org>
Fri, 17 Aug 2018 19:26:42 +0000 (19:26 +0000)
64 files changed:
.eslintrc.json
RELEASE-NOTES-1.32
autoload.php
includes/GlobalFunctions.php
includes/MediaWikiServices.php
includes/Message.php
includes/ServiceWiring.php
includes/Setup.php
includes/api/i18n/ko.json
includes/api/i18n/pt.json
includes/api/i18n/zh-hant.json
includes/libs/rdbms/loadbalancer/LoadBalancer.php
includes/pager/RangeChronologicalPager.php
includes/resourceloader/ResourceLoaderJqueryMsgModule.php
includes/specialpage/SpecialPageFactory.php
includes/specialpage/SpecialPageFactory_deprecated.php [new file with mode: 0644]
includes/specials/SpecialLog.php
languages/Language.php
languages/classes/LanguageAr.php
languages/classes/LanguageMl.php
languages/i18n/ast.json
languages/i18n/ce.json
languages/i18n/de.json
languages/i18n/el.json
languages/i18n/ia.json
languages/i18n/ja.json
languages/i18n/mnw.json
languages/i18n/nb.json
languages/i18n/pl.json
languages/i18n/pt.json
languages/i18n/sco.json
languages/i18n/sr-ec.json
languages/i18n/te.json
languages/i18n/tt-cyrl.json
maintenance/benchmarks/Benchmarker.php
resources/Resources.php
resources/src/jquery/jquery.lengthLimit.js
resources/src/jquery/jquery.suggestions.js
resources/src/mediawiki.ForeignStructuredUpload.BookletLayout/BookletLayout.js
resources/src/mediawiki.ForeignStructuredUpload.BookletLayout/BookletLayout.less [deleted file]
resources/src/mediawiki.confirmCloseWindow.js
resources/src/mediawiki.htmlform/autocomplete.js
resources/src/mediawiki.inspect.js
resources/src/mediawiki.jqueryMsg/mediawiki.jqueryMsg.js
resources/src/mediawiki.legacy/protect.js
resources/src/mediawiki.searchSuggest/searchSuggest.js
resources/src/mediawiki.special.apisandbox/apisandbox.js
resources/src/mediawiki.userSuggest.js
resources/src/mediawiki.widgets.datetime/DateTimeFormatter.js
resources/src/mediawiki.widgets.datetime/DiscordianDateTimeFormatter.js
resources/src/mediawiki.widgets.datetime/ProlepticGregorianDateTimeFormatter.js
resources/src/mediawiki.widgets/mw.widgets.NamespaceInputWidget.js
resources/src/mediawiki.widgets/mw.widgets.TitleWidget.js
tests/phpunit/MediaWikiTestCase.php
tests/phpunit/includes/HtmlTest.php
tests/phpunit/includes/PrefixSearchTest.php
tests/phpunit/includes/search/SearchEnginePrefixTest.php
tests/phpunit/includes/specialpage/SpecialPageFactoryTest.php
tests/phpunit/languages/classes/LanguageArTest.php
tests/phpunit/languages/classes/LanguageMlTest.php
tests/phpunit/structure/SpecialPageFatalTest.php
tests/phpunit/suite.xml
tests/qunit/suites/resources/mediawiki/mediawiki.jqueryMsg.test.js
tests/qunit/suites/resources/mediawiki/mediawiki.user.test.js

index 844895d..da5d409 100644 (file)
                "OO": false
        },
        "rules": {
+               "no-restricted-properties": [
+                       2,
+                       {
+                               "object": "$",
+                               "property": "map",
+                               "message": "Please use Array.prototype.map instead"
+                       },
+                       {
+                               "object": "$",
+                               "property": "isArray",
+                               "message": "Please use Array.isArray instead"
+                       },
+                       {
+                               "object": "$",
+                               "property": "isFunction",
+                               "message": "Please use typeof (e.g. typeof e === 'function') instead"
+                       },
+                       {
+                               "object": "$",
+                               "property": "grep",
+                               "message": "Please use Array.prototype.filter instead"
+                       },
+                       {
+                               "object": "$",
+                               "property": "trim",
+                               "message": "Please use String.prototype.trim instead"
+                       }
+               ],
                "dot-notation": 0,
                "max-len": 0
        }
index 0ed2631..8305d71 100644 (file)
@@ -249,6 +249,8 @@ because of Phabricator reports.
   resetServiceForTesting( 'MagicWordFactory' ) on a MediaWikiServices.
 * mw.util.init() has been removed. This function is not needed anymore and was
   a no-op function since 1.30.
+* SpecialPageFactory::resetList() is a no-op.  Call overrideMwServices()
+  instead.
 
 === Deprecations in 1.32 ===
 * Use of a StartProfiler.php file is deprecated in favour of placing
@@ -348,6 +350,15 @@ because of Phabricator reports.
   methods instead.
 * PasswordFactory::init is deprecated. To get a password factory with the
   standard configuration, use MediaWikiServices::getPasswordFactory.
+* $wgContLang is deprecated, use MediaWikiServices::getContentLanguage()
+  instead.
+* $wgParser is deprecated, use MediaWikiServices::getParser() instead.
+* wfGetMainCache() is deprecated, use ObjectCache::getLocalClusterInstance()
+  instead.
+* wfGetCache() is deprecated, use ObjectCache::getInstance() instead.
+* All SpecialPageFactory static methods are deprecated. Instead, call the
+  methods on a SpecialPageFactory instance, which may be obtained from
+  MediaWikiServices.
 
 === Other changes in 1.32 ===
 * (T198811) The following tables have had their UNIQUE indexes turned into
index 1c1eeef..999d82d 100644 (file)
@@ -930,6 +930,7 @@ $wgAutoloadLocalClasses = [
        'MediaWiki\\Search\\ParserOutputSearchDataExtractor' => __DIR__ . '/includes/search/ParserOutputSearchDataExtractor.php',
        'MediaWiki\\ShellDisabledError' => __DIR__ . '/includes/exception/ShellDisabledError.php',
        'MediaWiki\\Site\\MediaWikiPageNameNormalizer' => __DIR__ . '/includes/site/MediaWikiPageNameNormalizer.php',
+       'MediaWiki\\Special\\SpecialPageFactory' => __DIR__ . '/includes/specialpage/SpecialPageFactory.php',
        'MediaWiki\\User\\UserIdentity' => __DIR__ . '/includes/user/UserIdentity.php',
        'MediaWiki\\User\\UserIdentityValue' => __DIR__ . '/includes/user/UserIdentityValue.php',
        'MediaWiki\\Widget\\ComplexNamespaceInputWidget' => __DIR__ . '/includes/widget/ComplexNamespaceInputWidget.php',
@@ -1392,7 +1393,7 @@ $wgAutoloadLocalClasses = [
        'SpecialPage' => __DIR__ . '/includes/specialpage/SpecialPage.php',
        'SpecialPageAction' => __DIR__ . '/includes/actions/SpecialPageAction.php',
        'SpecialPageData' => __DIR__ . '/includes/specials/SpecialPageData.php',
-       'SpecialPageFactory' => __DIR__ . '/includes/specialpage/SpecialPageFactory.php',
+       'SpecialPageFactory' => __DIR__ . '/includes/specialpage/SpecialPageFactory_deprecated.php',
        'SpecialPageLanguage' => __DIR__ . '/includes/specials/SpecialPageLanguage.php',
        'SpecialPagesWithProp' => __DIR__ . '/includes/specials/SpecialPagesWithProp.php',
        'SpecialPasswordPolicies' => __DIR__ . '/includes/specials/SpecialPasswordPolicies.php',
index 567db85..d24b74d 100644 (file)
@@ -3119,6 +3119,7 @@ function wfBCP47( $code ) {
 /**
  * Get a specific cache object.
  *
+ * @deprecated since 1.32, use ObjectCache::getInstance() instead
  * @param int|string $cacheType A CACHE_* constants, or other key in $wgObjectCaches
  * @return BagOStuff
  */
@@ -3129,11 +3130,11 @@ function wfGetCache( $cacheType ) {
 /**
  * Get the main cache object
  *
+ * @deprecated since 1.32, use ObjectCache::getLocalClusterInstance() instead
  * @return BagOStuff
  */
 function wfGetMainCache() {
-       global $wgMainCacheType;
-       return ObjectCache::getInstance( $wgMainCacheType );
+       return ObjectCache::getLocalClusterInstance();
 }
 
 /**
index 326c12c..f9d9aab 100644 (file)
@@ -15,6 +15,7 @@ use IBufferingStatsdDataFactory;
 use MediaWiki\Http\HttpRequestFactory;
 use MediaWiki\Preferences\PreferencesFactory;
 use MediaWiki\Shell\CommandFactory;
+use MediaWiki\Special\SpecialPageFactory;
 use MediaWiki\Storage\BlobStore;
 use MediaWiki\Storage\BlobStoreFactory;
 use MediaWiki\Storage\NameTableStore;
@@ -828,6 +829,14 @@ class MediaWikiServices extends ServiceContainer {
                return $this->getService( 'SlotRoleStore' );
        }
 
+       /**
+        * @since 1.32
+        * @return SpecialPageFactory
+        */
+       public function getSpecialPageFactory() : SpecialPageFactory {
+               return $this->getService( 'SpecialPageFactory' );
+       }
+
        /**
         * @since 1.27
         * @return IBufferingStatsdDataFactory
index e2fe254..3bd7755 100644 (file)
@@ -473,13 +473,13 @@ class Message implements MessageSpecifier, Serializable {
                global $wgForceUIMsgAsContentMsg;
 
                $contLang = MediaWikiServices::getInstance()->getContentLanguage();
+               $lang = $this->getLanguage();
                $title = $this->key;
                if (
-                       !$this->language->equals( $contLang )
+                       !$lang->equals( $contLang )
                        && in_array( $this->key, (array)$wgForceUIMsgAsContentMsg )
                ) {
-                       $code = $this->language->getCode();
-                       $title .= '/' . $code;
+                       $title .= '/' . $lang->getCode();
                }
 
                return Title::makeTitle(
index 344c31d..e710575 100644 (file)
@@ -48,6 +48,7 @@ use MediaWiki\MediaWikiServices;
 use MediaWiki\Preferences\PreferencesFactory;
 use MediaWiki\Preferences\DefaultPreferencesFactory;
 use MediaWiki\Shell\CommandFactory;
+use MediaWiki\Special\SpecialPageFactory;
 use MediaWiki\Storage\BlobStore;
 use MediaWiki\Storage\BlobStoreFactory;
 use MediaWiki\Storage\NameTableStore;
@@ -545,6 +546,13 @@ return [
                );
        },
 
+       'SpecialPageFactory' => function ( MediaWikiServices $services ) : SpecialPageFactory {
+               return new SpecialPageFactory(
+                       $services->getMainConfig(),
+                       $services->getContentLanguage()
+               );
+       },
+
        'StatsdDataFactory' => function ( MediaWikiServices $services ) : IBufferingStatsdDataFactory {
                return new BufferingStatsdDataFactory(
                        rtrim( $services->getMainConfig()->get( 'StatsdMetricPrefix' ), '.' )
index 9923ae2..c015eac 100644 (file)
@@ -774,7 +774,7 @@ if ( $wgCommandLineMode ) {
        wfDebug( $debug );
 }
 
-$wgMemc = wfGetMainCache();
+$wgMemc = ObjectCache::getLocalClusterInstance();
 $messageMemc = wfGetMessageCacheStorage();
 
 wfDebugLog( 'caches',
@@ -898,6 +898,7 @@ $wgOut = RequestContext::getMain()->getOutput(); // BackCompat
 
 /**
  * @var Parser $wgParser
+ * @deprecated since 1.32, use MediaWikiServices::getParser() instead
  */
 $wgParser = new StubObject( 'wgParser', function () {
        return MediaWikiServices::getInstance()->getParser();
index 084dfac..e37bbbc 100644 (file)
        "apierror-readonly": "위키는 현재 읽기 전용 모드입니다.",
        "apierror-revisions-badid": "<var>$1</var> 변수에 대한 판을 발견하지 못했습니다.",
        "apierror-revwrongpage": "r$1은(는) $2의 판이 아닙니다.",
+       "apierror-siteinfo-includealldenied": "<var>$wgShowHostnames</var>가 참이 아닐 경우 모든 서버의 정보를 볼 수 없습니다.",
        "apierror-specialpage-cantexecute": "특수 문서의 결과를 볼 권한이 없습니다.",
        "apierror-stashwrongowner": "잘못된 소유자: $1",
        "apierror-systemblocked": "당신은 미디어위키에 의해서 자동으로 차단되었습니다.",
index aa040e3..0733a2a 100644 (file)
        "apihelp-query+search-paramvalue-prop-sectionsnippet": "Adiciona um fragmento de código com o título da secção correspondente, após análise sintática.",
        "apihelp-query+search-paramvalue-prop-sectiontitle": "Adiciona o título da secção correspondente.",
        "apihelp-query+search-paramvalue-prop-categorysnippet": "Adiciona um fragmento de código com a categoria correspondente, após análise sintática.",
-       "apihelp-query+search-paramvalue-prop-isfilematch": "Adiciona um valor booleano que indica se a pesquisa encontrou correspondência no conteúdo de ficheiros.",
+       "apihelp-query+search-paramvalue-prop-isfilematch": "Adiciona um valor booliano que indica se a pesquisa encontrou correspondência no conteúdo de ficheiros.",
        "apihelp-query+search-paramvalue-prop-extensiondata": "Acrescenta dados adicionais gerados por extensões.",
        "apihelp-query+search-paramvalue-prop-score": "Ignorado.",
        "apihelp-query+search-paramvalue-prop-hasrelated": "Ignorado.",
        "apihelp-json-param-callback": "Se especificado, envolve o resultado de saída na forma de uma chamada para uma função. Por segurança, todos os dados específicos do utilizador estarão restringidos.",
        "apihelp-json-param-utf8": "Se especificado, codifica a maioria dos caracteres não ASCII (mas não todos) em UTF-8, em vez de substitui-los por sequências de escape hexadecimais. É o comportamento padrão quando <var>formatversion</var> não tem o valor <kbd>1</kbd>.",
        "apihelp-json-param-ascii": "Se especificado, codifica todos caracteres não ASCII usando sequências de escape hexadecimais. É o comportamento padrão quando <var>formatversion</var> tem o valor <kbd>1</kbd>.",
-       "apihelp-json-param-formatversion": "Formatação do resultado de saída:\n;1:Formato compatível com versões anteriores (booleanos ao estilo XML, <samp>*</samp> chaves para nodos de conteúdo, etc.).\n;2:Formato moderno experimental. As especificações podem mudar!\n;latest:Usar o formato mais recente (atualmente <kbd>2</kbd>), mas pode ser alterado sem aviso prévio.",
+       "apihelp-json-param-formatversion": "Formatação do resultado de saída:\n;1:Formato compatível com versões anteriores (boolianos ao estilo XML, <samp>*</samp> chaves para nodos de conteúdo, etc.).\n;2:Formato moderno experimental. As especificações podem mudar!\n;latest:Usar o formato mais recente (atualmente <kbd>2</kbd>), mas pode ser alterado sem aviso prévio.",
        "apihelp-jsonfm-summary": "Produzir os dados de saída em formato JSON (realce sintático em HTML).",
        "apihelp-none-summary": "Não produzir nada.",
        "apihelp-php-summary": "Produzir os dados de saída em formato PHP seriado.",
-       "apihelp-php-param-formatversion": "Formatação do resultado de saída:\n;1:Formato compatível com versões anteriores (booleanos ao estilo XML, <samp>*</samp> chaves para nodos de conteúdo, etc.).\n;2:Formato moderno experimental. As especificações podem mudar!\n;latest:Usar o formato mais recente (atualmente <kbd>2</kbd>), mas pode ser alterado sem aviso prévio.",
+       "apihelp-php-param-formatversion": "Formatação do resultado de saída:\n;1:Formato compatível com versões anteriores (boolianos ao estilo XML, <samp>*</samp> chaves para nodos de conteúdo, etc.).\n;2:Formato moderno experimental. As especificações podem mudar!\n;latest:Usar o formato mais recente (atualmente <kbd>2</kbd>), mas pode ser alterado sem aviso prévio.",
        "apihelp-phpfm-summary": "Produzir os dados de saída em formato PHP seriado (realce sintático em HTML).",
        "apihelp-rawfm-summary": "Produzir os dados de saída, incluindo elementos para despiste de erros, em formato JSON (realce sintático em HTML).",
        "apihelp-xml-summary": "Produzir os dados de saída em formato XML.",
        "api-help-param-templated-var-first": "<var>&#x7B;$1&#x7D;</var> no nome do parâmetro deve ser substituído com os valores de <var>$2</var>",
        "api-help-param-templated-var": "<var>&#x7B;$1&#x7D;</var> com valores de <var>$2</var>",
        "api-help-datatypes-header": "Tipo de dados",
-       "api-help-datatypes": "O formato de entrada para o MediaWiki deve ser UTF-8, normalizado de acordo com a norma NFC. O MediaWiki pode converter outros tipos de entrada, mas esta conversão pode originar a falha de algumas operações (tais como as [[Special:ApiHelp/edit|edições]] com verificações MD5).\n\nAlguns tipos de parâmetros nos pedidos à API necessitam de mais explicações:\n;boolean\n:Os parâmetros booleanos funcionam como as caixas de seleção HTML: se o parâmetro for especificado, independentemente do seu valor, é considerado verdadeiro. Para um valor falso, omitir o parâmetro completo.\n;timestamp\n:As datas e horas podem ser especificadas em vários formatos. É recomendado o formato ISO 8601. Todas as horas estão em UTC, qualquer inclusão do fuso horário é ignorada.\n:* Data e hora ISO 8601, <kbd><var>2001</var>-<var>01</var>-<var>15</var>T<var>14</var>:<var>56</var>:<var>00</var>Z</kbd> (pontuação e <kbd>Z</kbd> são opcionais)\n:* Data e hora ISO 8601 com segundos fracionários (estes são ignorados), <kbd><var>2001</var>-<var>01</var>-<var>15</var>T<var>14</var>:<var>56</var>:<var>00</var>.<var>00001</var>Z</kbd> (traços, dois pontos e <kbd>Z</kbd> são opcionais)\n:* Formato do MediaWiki, <kbd><var>2001</var><var>01</var><var>15</var><var>14</var><var>56</var><var>00</var></kbd>\n:* Formato numérico genérico, <kbd><var>2001</var>-<var>01</var>-<var>15</var> <var>14</var>:<var>56</var>:<var>00</var></kbd> (fuso horário opcional <kbd>GMT</kbd>, <kbd>+<var>##</var></kbd>, ou <kbd>-<var>##</var></kbd> são ignorados)\n:* Formato EXIF, <kbd><var>2001</var>:<var>01</var>:<var>15</var> <var>14</var>:<var>56</var>:<var>00</var></kbd>\n:*Formato RFC 2822 (o fuso horário pode ser omitido), <kbd><var>Mon</var>, <var>15</var> <var>Jan</var> <var>2001</var> <var>14</var>:<var>56</var>:<var>00</var></kbd>\n:* Formato RFC 850 (o fuso horário pode ser omitido), <kbd><var>Monday</var>, <var>15</var>-<var>Jan</var>-<var>2001</var> <var>14</var>:<var>56</var>:<var>00</var></kbd>\n:* Formato C ctime, <kbd><var>Mon</var> <var>Jan</var> <var>15</var> <var>14</var>:<var>56</var>:<var>00</var> <var>2001</var></kbd>\n:* Segundos desde 1970-01-01T00:00:00Z como um inteiro de 1 a 13 algarismos (excluindo <kbd>0</kbd>)\n:* O texto <kbd>now</kbd>\n;separador alternativo de valores múltiplos\n:Os parâmetros que aceitam vários valores são normalmente fornecidos com os valores separados por uma barra vertical (''pipe''), por exemplo <kbd>parâmetro=valor1|valor2</kbd> ou <kbd>parâmetro=valor1%7Cvalor2</kbd>. Se um valor contém a barra vertical, use como separador o U+001F (Separador de Unidades) ''e'' prefixe o valor com U+001F, isto é, <kbd>parâmetro=%1Fvalor1%1Fvalor2</kbd>.",
+       "api-help-datatypes": "O formato de entrada para o MediaWiki deve ser UTF-8, normalizado de acordo com a norma NFC. O MediaWiki pode converter outros tipos de entrada, mas esta conversão pode originar a falha de algumas operações (tais como as [[Special:ApiHelp/edit|edições]] com verificações MD5).\n\nAlguns tipos de parâmetros nos pedidos à API necessitam de mais explicações:\n;boolean\n:Os parâmetros boolianos funcionam como as caixas de seleção HTML: se o parâmetro for especificado, independentemente do seu valor, é considerado verdadeiro. Para um valor falso, omitir o parâmetro completo.\n;timestamp\n:As datas e horas podem ser especificadas em vários formatos. É recomendado o formato ISO 8601. Todas as horas estão em UTC, qualquer inclusão do fuso horário é ignorada.\n:* Data e hora ISO 8601, <kbd><var>2001</var>-<var>01</var>-<var>15</var>T<var>14</var>:<var>56</var>:<var>00</var>Z</kbd> (pontuação e <kbd>Z</kbd> são opcionais)\n:* Data e hora ISO 8601 com segundos fracionários (estes são ignorados), <kbd><var>2001</var>-<var>01</var>-<var>15</var>T<var>14</var>:<var>56</var>:<var>00</var>.<var>00001</var>Z</kbd> (traços, dois pontos e <kbd>Z</kbd> são opcionais)\n:* Formato do MediaWiki, <kbd><var>2001</var><var>01</var><var>15</var><var>14</var><var>56</var><var>00</var></kbd>\n:* Formato numérico genérico, <kbd><var>2001</var>-<var>01</var>-<var>15</var> <var>14</var>:<var>56</var>:<var>00</var></kbd> (fuso horário opcional <kbd>GMT</kbd>, <kbd>+<var>##</var></kbd>, ou <kbd>-<var>##</var></kbd> são ignorados)\n:* Formato EXIF, <kbd><var>2001</var>:<var>01</var>:<var>15</var> <var>14</var>:<var>56</var>:<var>00</var></kbd>\n:*Formato RFC 2822 (o fuso horário pode ser omitido), <kbd><var>Mon</var>, <var>15</var> <var>Jan</var> <var>2001</var> <var>14</var>:<var>56</var>:<var>00</var></kbd>\n:* Formato RFC 850 (o fuso horário pode ser omitido), <kbd><var>Monday</var>, <var>15</var>-<var>Jan</var>-<var>2001</var> <var>14</var>:<var>56</var>:<var>00</var></kbd>\n:* Formato C ctime, <kbd><var>Mon</var> <var>Jan</var> <var>15</var> <var>14</var>:<var>56</var>:<var>00</var> <var>2001</var></kbd>\n:* Segundos desde 1970-01-01T00:00:00Z como um inteiro de 1 a 13 algarismos (excluindo <kbd>0</kbd>)\n:* O texto <kbd>now</kbd>\n;separador alternativo de valores múltiplos\n:Os parâmetros que aceitam vários valores são normalmente fornecidos com os valores separados por uma barra vertical (''pipe''), por exemplo <kbd>parâmetro=valor1|valor2</kbd> ou <kbd>parâmetro=valor1%7Cvalor2</kbd>. Se um valor contém a barra vertical, use como separador o U+001F (Separador de Unidades) ''e'' prefixe o valor com U+001F, isto é, <kbd>parâmetro=%1Fvalor1%1Fvalor2</kbd>.",
        "api-help-templatedparams-header": "Parâmetros modelados",
        "api-help-templatedparams": "Os parâmetros modelados usam-se nos casos em que um módulo da API necessita de um valor para cada valor de um outro parâmetro. Por exemplo, se existisse um módulo da API para encomendar fruta, poderia ter um parâmetro <var>frutas</var> para especificar as frutas que estão a ser encomendadas e um parâmetro modelado <var>quantidade-de-{fruta}</var> para especificar quanto de cada fruta. Um cliente da API que pretenda 1 maçã, 5 bananas e 20 morangos pode então fazer um pedido como <kbd>frutas=maçãs|bananas|morangos&quantidade-de-maçãs=1&quantidade-de-bananas=5&quantidade-de-morangos=20</kbd>.",
        "api-help-param-type-limit": "Tipo: inteiro ou <kbd>max</kbd>",
        "api-help-param-type-integer": "Tipo: {{PLURAL:$1|1=inteiro|2=lista de números inteiros}}",
-       "api-help-param-type-boolean": "Tipo: booleano ([[Special:ApiHelp/main#main/datatypes|detalhes]])",
+       "api-help-param-type-boolean": "Tipo: booliano ([[Special:ApiHelp/main#main/datatypes|detalhes]])",
        "api-help-param-type-timestamp": "Tipo: {{PLURAL:$1|1=data e hora|2=lista de datas e horas}} ([[Special:ApiHelp/main#main/datatypes|formatos permitidos]])",
        "api-help-param-type-user": "Tipo: {{PLURAL:$1|1=nome de utilizador|2=lista de nomes de utilizadores}}",
        "api-help-param-list": "{{PLURAL:$1|1=Um dos seguintes valores|2=Valores (separados com <kbd>{{!}}</kbd> ou [[Special:ApiHelp/main#main/datatypes|alternativas]])}}: $2",
index efabab7..98ecec6 100644 (file)
        "apihelp-query+allrevisions-param-user": "此列出由該使用者作出的修訂。",
        "apihelp-query+allrevisions-param-excludeuser": "不要列出由該使用者作出的修訂。",
        "apihelp-query+allrevisions-param-namespace": "僅列出此命名空間的頁面。",
+       "apihelp-query+mystashedfiles-param-prop": "要索取的檔案屬性。",
+       "apihelp-query+mystashedfiles-paramvalue-prop-size": "索取檔案大小與圖片尺寸。",
+       "apihelp-query+mystashedfiles-paramvalue-prop-type": "索取檔案的 MIME 類型以及媒體類型。",
        "apihelp-query+mystashedfiles-param-limit": "要取得的檔案數量。",
        "apihelp-query+alltransclusions-param-limit": "要回傳的項目總數。",
+       "apihelp-query+alltransclusions-param-dir": "列出時所採用的方向。",
        "apihelp-query+allusers-param-from": "起始列舉的使用者名稱。",
        "apihelp-query+allusers-param-dir": "排序的方向。",
        "apihelp-query+allusers-example-Y": "列出以<kbd>Y</kbd>開頭的使用者。",
        "apihelp-query+authmanagerinfo-summary": "取得目前身分核對狀態的資訊。",
        "apihelp-query+backlinks-param-namespace": "要列舉的命名空間。",
+       "apihelp-query+backlinks-param-dir": "列出時所採用的方向。",
+       "apihelp-query+blocks-summary": "列出所有被封鎖使用者與 IP 位址。",
        "apihelp-query+blocks-param-start": "起始列舉的時間戳記。",
+       "apihelp-query+blocks-param-end": "終止列舉的時間戳記。",
        "apihelp-query+blocks-param-prop": "要取得的屬性。",
+       "apihelp-query+blocks-paramvalue-prop-id": "添加封鎖 ID。",
+       "apihelp-query+blocks-paramvalue-prop-user": "添加已封鎖使用者的使用者名稱。",
+       "apihelp-query+blocks-paramvalue-prop-userid": "添加已封鎖使用者的使用者 ID。",
+       "apihelp-query+blocks-paramvalue-prop-by": "添加進行封鎖中的使用者之使用者名稱。",
+       "apihelp-query+blocks-paramvalue-prop-byid": "添加進行封鎖中的使用者之使用者 ID。",
        "apihelp-query+categories-param-limit": "要回傳的分類數量。",
        "apihelp-query+categoryinfo-summary": "回傳有關指定分類的資訊。",
        "apihelp-query+categorymembers-summary": "在指定的分類中列出所有頁面。",
+       "apihelp-query+categorymembers-paramvalue-prop-ids": "添加頁面 ID。",
        "apihelp-query+categorymembers-param-limit": "回傳的頁面數量上限。",
        "apihelp-query+categorymembers-param-startsortkey": "請改用 $1starthexsortkey。",
        "apihelp-query+categorymembers-param-endsortkey": "請改用 $1endhexsortkey。",
        "apihelp-query+exturlusage-param-limit": "要回傳的頁面數量。",
        "apihelp-query+filearchive-param-limit": "要回傳的圖片總數。",
        "apihelp-query+filearchive-param-dir": "列出時所採用的方向。",
+       "apihelp-query+filearchive-param-sha1": "圖片的 SHA1 雜湊值。覆蓋 $1sha1base36。",
        "apihelp-query+filearchive-param-prop": "要取得的圖片資訊:",
        "apihelp-query+filearchive-paramvalue-prop-sha1": "替圖片添加 SHA-1 雜湊值。",
        "apihelp-query+filearchive-paramvalue-prop-mime": "添加圖片的 MIME。",
-       "apihelp-query+filearchive-paramvalue-prop-mediatype": "æ·»å\8a å\9c\96ç\89\87ç\9a\84å¤\9aåª\92é«\94é¡\9eå\9e\8bã\80\82",
+       "apihelp-query+filearchive-paramvalue-prop-mediatype": "添加圖片的媒體類型。",
        "apihelp-query+fileusage-param-prop": "要取得的屬性。",
+       "apihelp-query+fileusage-paramvalue-prop-pageid": "各頁面的頁面 ID。",
+       "apihelp-query+fileusage-paramvalue-prop-title": "各頁面的標題。",
+       "apihelp-query+fileusage-paramvalue-prop-redirect": "若頁面為重新導向,則做出標記。",
+       "apihelp-query+fileusage-param-namespace": "僅包含這些命名空間的頁面。",
        "apihelp-query+fileusage-param-limit": "要回傳的數量。",
        "apihelp-query+imageinfo-summary": "回傳檔案資訊與上傳日誌。",
+       "apihelp-query+imageinfo-param-prop": "要取得的檔案資訊:",
+       "apihelp-query+imageinfo-paramvalue-prop-sha1": "替檔案添加 SHA-1 雜湊值。",
+       "apihelp-query+imageinfo-paramvalue-prop-mime": "替檔案添加 MIME 類型。",
+       "apihelp-query+imageinfo-paramvalue-prop-mediatype": "添加檔案的媒體類型。",
        "apihelp-query+imageinfo-param-limit": "每個檔案要回傳的檔案修訂數量。",
        "apihelp-query+images-summary": "回傳指定頁面中包含的所有檔案。",
        "apihelp-query+images-param-limit": "要回傳的檔案數量。",
+       "apihelp-query+images-param-dir": "列出時所採用的方向。",
+       "apihelp-query+images-example-simple": "取得使用在 [[Main Page]] 的檔案清單。",
+       "apihelp-query+imageusage-param-namespace": "要列舉的命名空間。",
+       "apihelp-query+imageusage-param-dir": "列出時所採用的方向。",
        "apihelp-query+info-summary": "取得基本頁面訊息。",
+       "apihelp-query+info-param-prop": "要取得的額外屬性:",
        "apihelp-query+iwbacklinks-param-prop": "要取得的屬性。",
        "apihelp-query+iwlinks-summary": "回傳指定頁面的所有 interwiki 連結。",
        "apihelp-query+iwlinks-paramvalue-prop-url": "添加完整的 URL。",
index 5e08094..fbc3be9 100644 (file)
@@ -1928,14 +1928,14 @@ class LoadBalancer implements ILoadBalancer {
                                "Foreign domain connections are still in use ($domains)." );
                }
 
-               $oldDomain = $this->localDomain->getId();
                $this->setLocalDomain( new DatabaseDomain(
                        $this->localDomain->getDatabase(),
                        $this->localDomain->getSchema(),
                        $prefix
                ) );
 
-               $this->forEachOpenConnection( function ( IDatabase $db ) use ( $prefix, $oldDomain ) {
+               // Update the prefix for all local connections...
+               $this->forEachOpenConnection( function ( IDatabase $db ) use ( $prefix ) {
                        if ( !$db->getLBInfo( 'foreign' ) ) {
                                $db->tablePrefix( $prefix );
                        }
index d3cb566..bf36983 100644 (file)
@@ -45,14 +45,12 @@ abstract class RangeChronologicalPager extends ReverseChronologicalPager {
                try {
                        if ( $startStamp !== '' ) {
                                $startTimestamp = MWTimestamp::getInstance( $startStamp );
-                               $startTimestamp->setTimezone( $this->getConfig()->get( 'Localtimezone' ) );
                                $startOffset = $this->mDb->timestamp( $startTimestamp->getTimestamp() );
                                $this->rangeConds[] = $this->mIndexField . '>=' . $this->mDb->addQuotes( $startOffset );
                        }
 
                        if ( $endStamp !== '' ) {
                                $endTimestamp = MWTimestamp::getInstance( $endStamp );
-                               $endTimestamp->setTimezone( $this->getConfig()->get( 'Localtimezone' ) );
                                $endOffset = $this->mDb->timestamp( $endTimestamp->getTimestamp() );
                                $this->rangeConds[] = $this->mIndexField . '<=' . $this->mDb->addQuotes( $endOffset );
 
index bef34f9..8f4aa3b 100644 (file)
@@ -33,8 +33,7 @@ class ResourceLoaderJqueryMsgModule extends ResourceLoaderFileModule {
                $fileScript = parent::getScript( $context );
 
                $tagData = Sanitizer::getRecognizedTagData();
-               $parserDefaults = [];
-               $parserDefaults['allowedHtmlElements'] = array_merge(
+               $allowedHtmlElements = array_merge(
                        array_keys( $tagData['htmlpairs'] ),
                        array_diff(
                                array_keys( $tagData['htmlsingle'] ),
@@ -42,26 +41,24 @@ class ResourceLoaderJqueryMsgModule extends ResourceLoaderFileModule {
                        )
                );
 
-               $mainDataScript = Xml::encodeJsCall( 'mw.jqueryMsg.setParserDefaults', [ $parserDefaults ] );
-
-               // Associative array mapping magic words (e.g. SITENAME)
-               // to their values.
                $magicWords = [
                        'SITENAME' => $this->getConfig()->get( 'Sitename' ),
                ];
-
                Hooks::run( 'ResourceLoaderJqueryMsgModuleMagicWords', [ $context, &$magicWords ] );
 
-               $magicWordExtendData = [
+               $parserDefaults = [
+                       'allowedHtmlElements' => $allowedHtmlElements,
                        'magic' => $magicWords,
                ];
 
-               $magicWordDataScript = Xml::encodeJsCall( 'mw.jqueryMsg.setParserDefaults', [
-                       $magicWordExtendData,
-                       /* deep= */ true
+               $setDataScript = Xml::encodeJsCall( 'mw.jqueryMsg.setParserDefaults', [
+                       $parserDefaults,
+                       // Pass deep=true because mediawiki.jqueryMsg.js contains
+                       // page-specific magic words that must not be overwritten.
+                       true,
                ] );
 
-               return $fileScript . $mainDataScript . $magicWordDataScript;
+               return $fileScript . $setDataScript;
        }
 
        /**
index 9645811..c6ffbe4 100644 (file)
  * @ingroup SpecialPage
  * @defgroup SpecialPage SpecialPage
  */
+
+namespace MediaWiki\Special;
+
+use Config;
+use Hooks;
+use IContextSource;
+use Language;
 use MediaWiki\Linker\LinkRenderer;
-use MediaWiki\MediaWikiServices;
+use Profiler;
+use RequestContext;
+use SpecialPage;
+use Title;
+use User;
 use Wikimedia\ObjectFactory;
 
 /**
@@ -43,165 +54,180 @@ use Wikimedia\ObjectFactory;
  * SpecialPageFactory::$list. To remove a core static special page at runtime, use
  * a SpecialPage_initList hook.
  *
+ * @note There are two classes called SpecialPageFactory.  You should use this first one, in
+ * namespace MediaWiki\Special, which is a service.  \SpecialPageFactory is a deprecated collection
+ * of static methods that forwards to the global service.
+ *
  * @ingroup SpecialPage
  * @since 1.17
  */
 class SpecialPageFactory {
        /**
         * List of special page names to the subclass of SpecialPage which handles them.
+        * @todo Make this a const when we drop HHVM support (T192166).  It can still be private in PHP
+        * 7.1.
         */
        private static $coreList = [
                // Maintenance Reports
-               'BrokenRedirects' => BrokenRedirectsPage::class,
-               'Deadendpages' => DeadendPagesPage::class,
-               'DoubleRedirects' => DoubleRedirectsPage::class,
-               'Longpages' => LongPagesPage::class,
-               'Ancientpages' => AncientPagesPage::class,
-               'Lonelypages' => LonelyPagesPage::class,
-               'Fewestrevisions' => FewestrevisionsPage::class,
-               'Withoutinterwiki' => WithoutInterwikiPage::class,
-               'Protectedpages' => SpecialProtectedpages::class,
-               'Protectedtitles' => SpecialProtectedtitles::class,
-               'Shortpages' => ShortPagesPage::class,
-               'Uncategorizedcategories' => UncategorizedCategoriesPage::class,
-               'Uncategorizedimages' => UncategorizedImagesPage::class,
-               'Uncategorizedpages' => UncategorizedPagesPage::class,
-               'Uncategorizedtemplates' => UncategorizedTemplatesPage::class,
-               'Unusedcategories' => UnusedCategoriesPage::class,
-               'Unusedimages' => UnusedimagesPage::class,
-               'Unusedtemplates' => UnusedtemplatesPage::class,
-               'Unwatchedpages' => UnwatchedpagesPage::class,
-               'Wantedcategories' => WantedCategoriesPage::class,
-               'Wantedfiles' => WantedFilesPage::class,
-               'Wantedpages' => WantedPagesPage::class,
-               'Wantedtemplates' => WantedTemplatesPage::class,
+               'BrokenRedirects' => \BrokenRedirectsPage::class,
+               'Deadendpages' => \DeadendPagesPage::class,
+               'DoubleRedirects' => \DoubleRedirectsPage::class,
+               'Longpages' => \LongPagesPage::class,
+               'Ancientpages' => \AncientPagesPage::class,
+               'Lonelypages' => \LonelyPagesPage::class,
+               'Fewestrevisions' => \FewestrevisionsPage::class,
+               'Withoutinterwiki' => \WithoutInterwikiPage::class,
+               'Protectedpages' => \SpecialProtectedpages::class,
+               'Protectedtitles' => \SpecialProtectedtitles::class,
+               'Shortpages' => \ShortPagesPage::class,
+               'Uncategorizedcategories' => \UncategorizedCategoriesPage::class,
+               'Uncategorizedimages' => \UncategorizedImagesPage::class,
+               'Uncategorizedpages' => \UncategorizedPagesPage::class,
+               'Uncategorizedtemplates' => \UncategorizedTemplatesPage::class,
+               'Unusedcategories' => \UnusedCategoriesPage::class,
+               'Unusedimages' => \UnusedimagesPage::class,
+               'Unusedtemplates' => \UnusedtemplatesPage::class,
+               'Unwatchedpages' => \UnwatchedpagesPage::class,
+               'Wantedcategories' => \WantedCategoriesPage::class,
+               'Wantedfiles' => \WantedFilesPage::class,
+               'Wantedpages' => \WantedPagesPage::class,
+               'Wantedtemplates' => \WantedTemplatesPage::class,
 
                // List of pages
-               'Allpages' => SpecialAllPages::class,
-               'Prefixindex' => SpecialPrefixindex::class,
-               'Categories' => SpecialCategories::class,
-               'Listredirects' => ListredirectsPage::class,
-               'PagesWithProp' => SpecialPagesWithProp::class,
-               'TrackingCategories' => SpecialTrackingCategories::class,
+               'Allpages' => \SpecialAllPages::class,
+               'Prefixindex' => \SpecialPrefixindex::class,
+               'Categories' => \SpecialCategories::class,
+               'Listredirects' => \ListredirectsPage::class,
+               'PagesWithProp' => \SpecialPagesWithProp::class,
+               'TrackingCategories' => \SpecialTrackingCategories::class,
 
                // Authentication
-               'Userlogin' => SpecialUserLogin::class,
-               'Userlogout' => SpecialUserLogout::class,
-               'CreateAccount' => SpecialCreateAccount::class,
-               'LinkAccounts' => SpecialLinkAccounts::class,
-               'UnlinkAccounts' => SpecialUnlinkAccounts::class,
-               'ChangeCredentials' => SpecialChangeCredentials::class,
-               'RemoveCredentials' => SpecialRemoveCredentials::class,
+               'Userlogin' => \SpecialUserLogin::class,
+               'Userlogout' => \SpecialUserLogout::class,
+               'CreateAccount' => \SpecialCreateAccount::class,
+               'LinkAccounts' => \SpecialLinkAccounts::class,
+               'UnlinkAccounts' => \SpecialUnlinkAccounts::class,
+               'ChangeCredentials' => \SpecialChangeCredentials::class,
+               'RemoveCredentials' => \SpecialRemoveCredentials::class,
 
                // Users and rights
-               'Activeusers' => SpecialActiveUsers::class,
-               'Block' => SpecialBlock::class,
-               'Unblock' => SpecialUnblock::class,
-               'BlockList' => SpecialBlockList::class,
-               'AutoblockList' => SpecialAutoblockList::class,
-               'ChangePassword' => SpecialChangePassword::class,
-               'BotPasswords' => SpecialBotPasswords::class,
-               'PasswordReset' => SpecialPasswordReset::class,
-               'DeletedContributions' => DeletedContributionsPage::class,
-               'Preferences' => SpecialPreferences::class,
-               'ResetTokens' => SpecialResetTokens::class,
-               'Contributions' => SpecialContributions::class,
-               'Listgrouprights' => SpecialListGroupRights::class,
-               'Listgrants' => SpecialListGrants::class,
-               'Listusers' => SpecialListUsers::class,
-               'Listadmins' => SpecialListAdmins::class,
-               'Listbots' => SpecialListBots::class,
-               'Userrights' => UserrightsPage::class,
-               'EditWatchlist' => SpecialEditWatchlist::class,
-               'PasswordPolicies' => SpecialPasswordPolicies::class,
+               'Activeusers' => \SpecialActiveUsers::class,
+               'Block' => \SpecialBlock::class,
+               'Unblock' => \SpecialUnblock::class,
+               'BlockList' => \SpecialBlockList::class,
+               'AutoblockList' => \SpecialAutoblockList::class,
+               'ChangePassword' => \SpecialChangePassword::class,
+               'BotPasswords' => \SpecialBotPasswords::class,
+               'PasswordReset' => \SpecialPasswordReset::class,
+               'DeletedContributions' => \DeletedContributionsPage::class,
+               'Preferences' => \SpecialPreferences::class,
+               'ResetTokens' => \SpecialResetTokens::class,
+               'Contributions' => \SpecialContributions::class,
+               'Listgrouprights' => \SpecialListGroupRights::class,
+               'Listgrants' => \SpecialListGrants::class,
+               'Listusers' => \SpecialListUsers::class,
+               'Listadmins' => \SpecialListAdmins::class,
+               'Listbots' => \SpecialListBots::class,
+               'Userrights' => \UserrightsPage::class,
+               'EditWatchlist' => \SpecialEditWatchlist::class,
+               'PasswordPolicies' => \SpecialPasswordPolicies::class,
 
                // Recent changes and logs
-               'Newimages' => SpecialNewFiles::class,
-               'Log' => SpecialLog::class,
-               'Watchlist' => SpecialWatchlist::class,
-               'Newpages' => SpecialNewpages::class,
-               'Recentchanges' => SpecialRecentChanges::class,
-               'Recentchangeslinked' => SpecialRecentChangesLinked::class,
-               'Tags' => SpecialTags::class,
+               'Newimages' => \SpecialNewFiles::class,
+               'Log' => \SpecialLog::class,
+               'Watchlist' => \SpecialWatchlist::class,
+               'Newpages' => \SpecialNewpages::class,
+               'Recentchanges' => \SpecialRecentChanges::class,
+               'Recentchangeslinked' => \SpecialRecentChangesLinked::class,
+               'Tags' => \SpecialTags::class,
 
                // Media reports and uploads
-               'Listfiles' => SpecialListFiles::class,
-               'Filepath' => SpecialFilepath::class,
-               'MediaStatistics' => MediaStatisticsPage::class,
-               'MIMEsearch' => MIMEsearchPage::class,
-               'FileDuplicateSearch' => FileDuplicateSearchPage::class,
-               'Upload' => SpecialUpload::class,
-               'UploadStash' => SpecialUploadStash::class,
-               'ListDuplicatedFiles' => ListDuplicatedFilesPage::class,
+               'Listfiles' => \SpecialListFiles::class,
+               'Filepath' => \SpecialFilepath::class,
+               'MediaStatistics' => \MediaStatisticsPage::class,
+               'MIMEsearch' => \MIMEsearchPage::class,
+               'FileDuplicateSearch' => \FileDuplicateSearchPage::class,
+               'Upload' => \SpecialUpload::class,
+               'UploadStash' => \SpecialUploadStash::class,
+               'ListDuplicatedFiles' => \ListDuplicatedFilesPage::class,
 
                // Data and tools
-               'ApiSandbox' => SpecialApiSandbox::class,
-               'Statistics' => SpecialStatistics::class,
-               'Allmessages' => SpecialAllMessages::class,
-               'Version' => SpecialVersion::class,
-               'Lockdb' => SpecialLockdb::class,
-               'Unlockdb' => SpecialUnlockdb::class,
+               'ApiSandbox' => \SpecialApiSandbox::class,
+               'Statistics' => \SpecialStatistics::class,
+               'Allmessages' => \SpecialAllMessages::class,
+               'Version' => \SpecialVersion::class,
+               'Lockdb' => \SpecialLockdb::class,
+               'Unlockdb' => \SpecialUnlockdb::class,
 
                // Redirecting special pages
-               'LinkSearch' => LinkSearchPage::class,
-               'Randompage' => RandomPage::class,
-               'RandomInCategory' => SpecialRandomInCategory::class,
-               'Randomredirect' => SpecialRandomredirect::class,
-               'Randomrootpage' => SpecialRandomrootpage::class,
-               'GoToInterwiki' => SpecialGoToInterwiki::class,
+               'LinkSearch' => \LinkSearchPage::class,
+               'Randompage' => \RandomPage::class,
+               'RandomInCategory' => \SpecialRandomInCategory::class,
+               'Randomredirect' => \SpecialRandomredirect::class,
+               'Randomrootpage' => \SpecialRandomrootpage::class,
+               'GoToInterwiki' => \SpecialGoToInterwiki::class,
 
                // High use pages
-               'Mostlinkedcategories' => MostlinkedCategoriesPage::class,
-               'Mostimages' => MostimagesPage::class,
-               'Mostinterwikis' => MostinterwikisPage::class,
-               'Mostlinked' => MostlinkedPage::class,
-               'Mostlinkedtemplates' => MostlinkedTemplatesPage::class,
-               'Mostcategories' => MostcategoriesPage::class,
-               'Mostrevisions' => MostrevisionsPage::class,
+               'Mostlinkedcategories' => \MostlinkedCategoriesPage::class,
+               'Mostimages' => \MostimagesPage::class,
+               'Mostinterwikis' => \MostinterwikisPage::class,
+               'Mostlinked' => \MostlinkedPage::class,
+               'Mostlinkedtemplates' => \MostlinkedTemplatesPage::class,
+               'Mostcategories' => \MostcategoriesPage::class,
+               'Mostrevisions' => \MostrevisionsPage::class,
 
                // Page tools
-               'ComparePages' => SpecialComparePages::class,
-               'Export' => SpecialExport::class,
-               'Import' => SpecialImport::class,
-               'Undelete' => SpecialUndelete::class,
-               'Whatlinkshere' => SpecialWhatLinksHere::class,
-               'MergeHistory' => SpecialMergeHistory::class,
-               'ExpandTemplates' => SpecialExpandTemplates::class,
+               'ComparePages' => \SpecialComparePages::class,
+               'Export' => \SpecialExport::class,
+               'Import' => \SpecialImport::class,
+               'Undelete' => \SpecialUndelete::class,
+               'Whatlinkshere' => \SpecialWhatLinksHere::class,
+               'MergeHistory' => \SpecialMergeHistory::class,
+               'ExpandTemplates' => \SpecialExpandTemplates::class,
 
                // Other
-               'Booksources' => SpecialBookSources::class,
+               'Booksources' => \SpecialBookSources::class,
 
                // Unlisted / redirects
-               'ApiHelp' => SpecialApiHelp::class,
-               'Blankpage' => SpecialBlankpage::class,
-               'Diff' => SpecialDiff::class,
-               'EditTags' => SpecialEditTags::class,
-               'Emailuser' => SpecialEmailUser::class,
-               'Movepage' => MovePageForm::class,
-               'Mycontributions' => SpecialMycontributions::class,
-               'MyLanguage' => SpecialMyLanguage::class,
-               'Mypage' => SpecialMypage::class,
-               'Mytalk' => SpecialMytalk::class,
-               'Myuploads' => SpecialMyuploads::class,
-               'AllMyUploads' => SpecialAllMyUploads::class,
-               'PermanentLink' => SpecialPermanentLink::class,
-               'Redirect' => SpecialRedirect::class,
-               'Revisiondelete' => SpecialRevisionDelete::class,
-               'RunJobs' => SpecialRunJobs::class,
-               'Specialpages' => SpecialSpecialpages::class,
-               'PageData' => SpecialPageData::class,
+               'ApiHelp' => \SpecialApiHelp::class,
+               'Blankpage' => \SpecialBlankpage::class,
+               'Diff' => \SpecialDiff::class,
+               'EditTags' => \SpecialEditTags::class,
+               'Emailuser' => \SpecialEmailUser::class,
+               'Movepage' => \MovePageForm::class,
+               'Mycontributions' => \SpecialMycontributions::class,
+               'MyLanguage' => \SpecialMyLanguage::class,
+               'Mypage' => \SpecialMypage::class,
+               'Mytalk' => \SpecialMytalk::class,
+               'Myuploads' => \SpecialMyuploads::class,
+               'AllMyUploads' => \SpecialAllMyUploads::class,
+               'PermanentLink' => \SpecialPermanentLink::class,
+               'Redirect' => \SpecialRedirect::class,
+               'Revisiondelete' => \SpecialRevisionDelete::class,
+               'RunJobs' => \SpecialRunJobs::class,
+               'Specialpages' => \SpecialSpecialpages::class,
+               'PageData' => \SpecialPageData::class,
        ];
 
-       private static $list;
-       private static $aliases;
+       /** @var array Special page name => class name */
+       private $list;
+
+       /** @var array */
+       private $aliases;
+
+       /** @var Config */
+       private $config;
+
+       /** @var Language */
+       private $contLang;
 
        /**
-        * Reset the internal list of special pages. Useful when changing $wgSpecialPages after
-        * the internal list has already been initialized, e.g. during testing.
+        * @param Config $config
+        * @param Language $contLang
         */
-       public static function resetList() {
-               self::$list = null;
-               self::$aliases = null;
+       public function __construct( Config $config, Language $contLang ) {
+               $this->config = $config;
+               $this->contLang = $contLang;
        }
 
        /**
@@ -210,8 +236,8 @@ class SpecialPageFactory {
         *
         * @return string[]
         */
-       public static function getNames() {
-               return array_keys( self::getPageList() );
+       public function getNames() : array {
+               return array_keys( $this->getPageList() );
        }
 
        /**
@@ -219,49 +245,44 @@ class SpecialPageFactory {
         *
         * @return array
         */
-       private static function getPageList() {
-               global $wgSpecialPages;
-               global $wgDisableInternalSearch, $wgEmailAuthentication;
-               global $wgEnableEmail, $wgEnableJavaScriptTest;
-               global $wgPageLanguageUseDB, $wgContentHandlerUseDB;
-
-               if ( !is_array( self::$list ) ) {
-                       self::$list = self::$coreList;
+       private function getPageList() : array {
+               if ( !is_array( $this->list ) ) {
+                       $this->list = self::$coreList;
 
-                       if ( !$wgDisableInternalSearch ) {
-                               self::$list['Search'] = SpecialSearch::class;
+                       if ( !$this->config->get( 'DisableInternalSearch' ) ) {
+                               $this->list['Search'] = \SpecialSearch::class;
                        }
 
-                       if ( $wgEmailAuthentication ) {
-                               self::$list['Confirmemail'] = EmailConfirmation::class;
-                               self::$list['Invalidateemail'] = EmailInvalidation::class;
+                       if ( $this->config->get( 'EmailAuthentication' ) ) {
+                               $this->list['Confirmemail'] = \EmailConfirmation::class;
+                               $this->list['Invalidateemail'] = \EmailInvalidation::class;
                        }
 
-                       if ( $wgEnableEmail ) {
-                               self::$list['ChangeEmail'] = SpecialChangeEmail::class;
+                       if ( $this->config->get( 'EnableEmail' ) ) {
+                               $this->list['ChangeEmail'] = \SpecialChangeEmail::class;
                        }
 
-                       if ( $wgEnableJavaScriptTest ) {
-                               self::$list['JavaScriptTest'] = SpecialJavaScriptTest::class;
+                       if ( $this->config->get( 'EnableJavaScriptTest' ) ) {
+                               $this->list['JavaScriptTest'] = \SpecialJavaScriptTest::class;
                        }
 
-                       if ( $wgPageLanguageUseDB ) {
-                               self::$list['PageLanguage'] = SpecialPageLanguage::class;
+                       if ( $this->config->get( 'PageLanguageUseDB' ) ) {
+                               $this->list['PageLanguage'] = \SpecialPageLanguage::class;
                        }
-                       if ( $wgContentHandlerUseDB ) {
-                               self::$list['ChangeContentModel'] = SpecialChangeContentModel::class;
+                       if ( $this->config->get( 'ContentHandlerUseDB' ) ) {
+                               $this->list['ChangeContentModel'] = \SpecialChangeContentModel::class;
                        }
 
                        // Add extension special pages
-                       self::$list = array_merge( self::$list, $wgSpecialPages );
+                       $this->list = array_merge( $this->list, $this->config->get( 'SpecialPages' ) );
 
                        // This hook can be used to disable unwanted core special pages
                        // or conditionally register special pages.
-                       Hooks::run( 'SpecialPage_initList', [ &self::$list ] );
+                       Hooks::run( 'SpecialPage_initList', [ &$this->list ] );
 
                }
 
-               return self::$list;
+               return $this->list;
        }
 
        /**
@@ -270,19 +291,18 @@ class SpecialPageFactory {
         * All registered special pages are guaranteed to map to themselves.
         * @return array
         */
-       private static function getAliasList() {
-               $contLang = MediaWikiServices::getInstance()->getContentLanguage();
-               if ( is_null( self::$aliases ) ) {
-                       $aliases = $contLang->getSpecialPageAliases();
-                       $pageList = self::getPageList();
+       private function getAliasList() : array {
+               if ( is_null( $this->aliases ) ) {
+                       $aliases = $this->contLang->getSpecialPageAliases();
+                       $pageList = $this->getPageList();
 
-                       self::$aliases = [];
+                       $this->aliases = [];
                        $keepAlias = [];
 
                        // Force every canonical name to be an alias for itself.
                        foreach ( $pageList as $name => $stuff ) {
-                               $caseFoldedAlias = $contLang->caseFold( $name );
-                               self::$aliases[$caseFoldedAlias] = $name;
+                               $caseFoldedAlias = $this->contLang->caseFold( $name );
+                               $this->aliases[$caseFoldedAlias] = $name;
                                $keepAlias[$caseFoldedAlias] = 'canonical';
                        }
 
@@ -291,24 +311,24 @@ class SpecialPageFactory {
                                foreach ( $aliases as $realName => $aliasList ) {
                                        $aliasList = array_values( $aliasList );
                                        foreach ( $aliasList as $i => $alias ) {
-                                               $caseFoldedAlias = $contLang->caseFold( $alias );
+                                               $caseFoldedAlias = $this->contLang->caseFold( $alias );
 
-                                               if ( isset( self::$aliases[$caseFoldedAlias] ) &&
-                                                       $realName === self::$aliases[$caseFoldedAlias]
+                                               if ( isset( $this->aliases[$caseFoldedAlias] ) &&
+                                                       $realName === $this->aliases[$caseFoldedAlias]
                                                ) {
                                                        // Ignore same-realName conflicts
                                                        continue;
                                                }
 
                                                if ( !isset( $keepAlias[$caseFoldedAlias] ) ) {
-                                                       self::$aliases[$caseFoldedAlias] = $realName;
+                                                       $this->aliases[$caseFoldedAlias] = $realName;
                                                        if ( !$i ) {
                                                                $keepAlias[$caseFoldedAlias] = 'first';
                                                        }
                                                } elseif ( !$i ) {
                                                        wfWarn( "First alias '$alias' for $realName conflicts with " .
                                                                "{$keepAlias[$caseFoldedAlias]} alias for " .
-                                                               self::$aliases[$caseFoldedAlias]
+                                                               $this->aliases[$caseFoldedAlias]
                                                        );
                                                }
                                        }
@@ -316,7 +336,7 @@ class SpecialPageFactory {
                        }
                }
 
-               return self::$aliases;
+               return $this->aliases;
        }
 
        /**
@@ -327,13 +347,12 @@ class SpecialPageFactory {
         * @param string $alias
         * @return array Array( String, String|null ), or array( null, null ) if the page is invalid
         */
-       public static function resolveAlias( $alias ) {
+       public function resolveAlias( $alias ) {
                $bits = explode( '/', $alias, 2 );
 
-               $caseFoldedAlias = MediaWikiServices::getInstance()->getContentLanguage()->
-                       caseFold( $bits[0] );
+               $caseFoldedAlias = $this->contLang->caseFold( $bits[0] );
                $caseFoldedAlias = str_replace( ' ', '_', $caseFoldedAlias );
-               $aliases = self::getAliasList();
+               $aliases = $this->getAliasList();
                if ( isset( $aliases[$caseFoldedAlias] ) ) {
                        $name = $aliases[$caseFoldedAlias];
                } else {
@@ -355,10 +374,10 @@ class SpecialPageFactory {
         * @param string $name Name of a special page
         * @return bool True if a special page exists with this name
         */
-       public static function exists( $name ) {
-               list( $title, /*...*/ ) = self::resolveAlias( $name );
+       public function exists( $name ) {
+               list( $title, /*...*/ ) = $this->resolveAlias( $name );
 
-               $specialPageList = self::getPageList();
+               $specialPageList = $this->getPageList();
                return isset( $specialPageList[$title] );
        }
 
@@ -368,17 +387,17 @@ class SpecialPageFactory {
         * @param string $name Special page name, may be localised and/or an alias
         * @return SpecialPage|null SpecialPage object or null if the page doesn't exist
         */
-       public static function getPage( $name ) {
-               list( $realName, /*...*/ ) = self::resolveAlias( $name );
+       public function getPage( $name ) {
+               list( $realName, /*...*/ ) = $this->resolveAlias( $name );
 
-               $specialPageList = self::getPageList();
+               $specialPageList = $this->getPageList();
 
                if ( isset( $specialPageList[$realName] ) ) {
                        $rec = $specialPageList[$realName];
 
                        if ( is_callable( $rec ) ) {
                                // Use callback to instantiate the special page
-                               $page = call_user_func( $rec );
+                               $page = $rec();
                        } elseif ( is_string( $rec ) ) {
                                $className = $rec;
                                $page = new $className;
@@ -416,18 +435,14 @@ class SpecialPageFactory {
         * Return categorised listable special pages which are available
         * for the current user, and everyone.
         *
-        * @param User|null $user User object to check permissions, $wgUser will be used
-        *        if not provided
+        * @param User $user User object to check permissions
+        *  provided
         * @return array ( string => Specialpage )
         */
-       public static function getUsablePages( User $user = null ) {
+       public function getUsablePages( User $user ) : array {
                $pages = [];
-               if ( $user === null ) {
-                       global $wgUser;
-                       $user = $wgUser;
-               }
-               foreach ( self::getPageList() as $name => $rec ) {
-                       $page = self::getPage( $name );
+               foreach ( $this->getPageList() as $name => $rec ) {
+                       $page = $this->getPage( $name );
                        if ( $page ) { // not null
                                $page->setContext( RequestContext::getMain() );
                                if ( $page->isListed()
@@ -446,10 +461,10 @@ class SpecialPageFactory {
         *
         * @return array ( string => Specialpage )
         */
-       public static function getRegularPages() {
+       public function getRegularPages() : array {
                $pages = [];
-               foreach ( self::getPageList() as $name => $rec ) {
-                       $page = self::getPage( $name );
+               foreach ( $this->getPageList() as $name => $rec ) {
+                       $page = $this->getPage( $name );
                        if ( $page && $page->isListed() && !$page->isRestricted() ) {
                                $pages[$name] = $page;
                        }
@@ -462,17 +477,13 @@ class SpecialPageFactory {
         * Return categorised listable special pages which are available
         * for the current user, but not for everyone
         *
-        * @param User|null $user User object to use or null for $wgUser
+        * @param User $user User object to use
         * @return array ( string => Specialpage )
         */
-       public static function getRestrictedPages( User $user = null ) {
+       public function getRestrictedPages( User $user ) : array {
                $pages = [];
-               if ( $user === null ) {
-                       global $wgUser;
-                       $user = $wgUser;
-               }
-               foreach ( self::getPageList() as $name => $rec ) {
-                       $page = self::getPage( $name );
+               foreach ( $this->getPageList() as $name => $rec ) {
+                       $page = $this->getPage( $name );
                        if ( $page
                                && $page->isListed()
                                && $page->isRestricted()
@@ -500,7 +511,7 @@ class SpecialPageFactory {
         *
         * @return bool|Title
         */
-       public static function executePath( Title &$title, IContextSource &$context, $including = false,
+       public function executePath( Title &$title, IContextSource &$context, $including = false,
                LinkRenderer $linkRenderer = null
        ) {
                // @todo FIXME: Redirects broken due to this call
@@ -512,7 +523,7 @@ class SpecialPageFactory {
                        $par = $bits[1];
                }
 
-               $page = self::getPage( $name );
+               $page = $this->getPage( $name );
                if ( !$page ) {
                        $context->getOutput()->setArticleRelated( false );
                        $context->getOutput()->setRobotPolicy( 'noindex,nofollow' );
@@ -587,7 +598,7 @@ class SpecialPageFactory {
         * @param LinkRenderer|null $linkRenderer (since 1.28)
         * @return string HTML fragment
         */
-       public static function capturePath(
+       public function capturePath(
                Title $title, IContextSource $context, LinkRenderer $linkRenderer = null
        ) {
                global $wgTitle, $wgOut, $wgRequest, $wgUser, $wgLang;
@@ -622,7 +633,7 @@ class SpecialPageFactory {
                $main->setLanguage( $context->getLanguage() );
 
                // The useful part
-               $ret = self::executePath( $title, $context, true, $linkRenderer );
+               $ret = $this->executePath( $title, $context, true, $linkRenderer );
 
                // Restore old globals and context
                $wgTitle = $glob['title'];
@@ -646,16 +657,15 @@ class SpecialPageFactory {
         * @param string|bool $subpage
         * @return string
         */
-       public static function getLocalNameFor( $name, $subpage = false ) {
-               $contLang = MediaWikiServices::getInstance()->getContentLanguage();
-               $aliases = $contLang->getSpecialPageAliases();
-               $aliasList = self::getAliasList();
+       public function getLocalNameFor( $name, $subpage = false ) {
+               $aliases = $this->contLang->getSpecialPageAliases();
+               $aliasList = $this->getAliasList();
 
                // Find the first alias that maps back to $name
                if ( isset( $aliases[$name] ) ) {
                        $found = false;
                        foreach ( $aliases[$name] as $alias ) {
-                               $caseFoldedAlias = $contLang->caseFold( $alias );
+                               $caseFoldedAlias = $this->contLang->caseFold( $alias );
                                $caseFoldedAlias = str_replace( ' ', '_', $caseFoldedAlias );
                                if ( isset( $aliasList[$caseFoldedAlias] ) &&
                                        $aliasList[$caseFoldedAlias] === $name
@@ -676,7 +686,7 @@ class SpecialPageFactory {
                                        if ( strcasecmp( $name, $n ) === 0 ) {
                                                wfWarn( "Found alias defined for $n when searching for " .
                                                        "special page aliases for $name. Case mismatch?" );
-                                               return self::getLocalNameFor( $n, $subpage );
+                                               return $this->getLocalNameFor( $n, $subpage );
                                        }
                                }
                        }
@@ -691,7 +701,7 @@ class SpecialPageFactory {
                        $name = "$name/$subpage";
                }
 
-               return $contLang->ucfirst( $name );
+               return $this->contLang->ucfirst( $name );
        }
 
        /**
@@ -700,8 +710,8 @@ class SpecialPageFactory {
         * @param string $alias
         * @return Title|null Title or null if there is no such alias
         */
-       public static function getTitleForAlias( $alias ) {
-               list( $name, $subpage ) = self::resolveAlias( $alias );
+       public function getTitleForAlias( $alias ) {
+               list( $name, $subpage ) = $this->resolveAlias( $alias );
                if ( $name != null ) {
                        return SpecialPage::getTitleFor( $name, $subpage );
                } else {
diff --git a/includes/specialpage/SpecialPageFactory_deprecated.php b/includes/specialpage/SpecialPageFactory_deprecated.php
new file mode 100644 (file)
index 0000000..bc0c250
--- /dev/null
@@ -0,0 +1,96 @@
+<?php
+/**
+ * Factory for handling the special page list and generating SpecialPage 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 SpecialPage
+ * @defgroup SpecialPage SpecialPage
+ */
+
+use MediaWiki\Linker\LinkRenderer;
+use MediaWiki\MediaWikiServices;
+
+// phpcs:disable MediaWiki.Files.ClassMatchesFilename.NotMatch
+/**
+ * Wrapper for backward compatibility for old callers that used static methods.
+ *
+ * @deprecated since 1.32, use the SpecialPageFactory service instead
+ */
+class SpecialPageFactory {
+       public static function getNames() : array {
+               return MediaWikiServices::getInstance()->getSpecialPageFactory()->getNames();
+       }
+
+       public static function resolveAlias( $alias ) : array {
+               return MediaWikiServices::getInstance()->getSpecialPageFactory()->resolveAlias( $alias );
+       }
+
+       public static function exists( $name ) {
+               return MediaWikiServices::getInstance()->getSpecialPageFactory()->exists( $name );
+       }
+
+       public static function getPage( $name ) {
+               return MediaWikiServices::getInstance()->getSpecialPageFactory()->getPage( $name );
+       }
+
+       public static function getUsablePages( User $user = null ) : array {
+               global $wgUser;
+               $user = $user ?? $wgUser;
+               return MediaWikiServices::getInstance()->getSpecialPageFactory()->getUsablePages( $user );
+       }
+
+       public static function getRegularPages() : array {
+               return MediaWikiServices::getInstance()->getSpecialPageFactory()->getRegularPages();
+       }
+
+       public static function getRestrictedPages( User $user = null ) : array {
+               global $wgUser;
+               $user = $user ?? $wgUser;
+               return MediaWikiServices::getInstance()->getSpecialPageFactory()->getRestrictedPages( $user );
+       }
+
+       public static function executePath( Title &$title, IContextSource &$context, $including = false,
+               LinkRenderer $linkRenderer = null
+       ) {
+               return MediaWikiServices::getInstance()->getSpecialPageFactory()
+                       ->executePath( $title, $context, $including, $linkRenderer );
+       }
+
+       public static function capturePath(
+               Title $title, IContextSource $context, LinkRenderer $linkRenderer = null
+       ) {
+               return MediaWikiServices::getInstance()->getSpecialPageFactory()
+                       ->capturePath( $title, $context, $linkRenderer );
+       }
+
+       public static function getLocalNameFor( $name, $subpage = false ) {
+               return MediaWikiServices::getInstance()->getSpecialPageFactory()
+                       ->getLocalNameFor( $name, $subpage );
+       }
+
+       public static function getTitleForAlias( $alias ) {
+               return MediaWikiServices::getInstance()->getSpecialPageFactory()
+                       ->getTitleForAlias( $alias );
+       }
+
+       /**
+        * No-op since 1.32, call overrideMwServices() instead
+        */
+       public static function resetList() {
+       }
+}
index 2160312..d700c39 100644 (file)
@@ -64,8 +64,6 @@ class SpecialLog extends SpecialPage {
                $dateString = $this->getRequest()->getVal( 'wpdate' );
                if ( !empty( $dateString ) ) {
                        $dateStamp = MWTimestamp::getInstance( $dateString . ' 00:00:00' );
-                       $dateStamp->setTimezone( $this->getConfig()->get( 'Localtimezone' ) );
-
                        $opts->setValue( 'year', (int)$dateStamp->format( 'Y' ) );
                        $opts->setValue( 'month', (int)$dateStamp->format( 'm' ) );
                        $opts->setValue( 'day', (int)$dateStamp->format( 'd' ) );
index dfbacfc..eab09a1 100644 (file)
@@ -3014,7 +3014,7 @@ class Language {
         *
         * @return string
         */
-       function normalize( $s ) {
+       public function normalize( $s ) {
                global $wgAllUnicodeFixes;
                $s = UtfNormal\Validator::cleanUp( $s );
                if ( $wgAllUnicodeFixes ) {
index efdf5a2..f2ce178 100644 (file)
@@ -40,7 +40,7 @@ class LanguageAr extends Language {
         *
         * @return string
         */
-       function normalize( $s ) {
+       public function normalize( $s ) {
                global $wgFixArabicUnicode;
                $s = parent::normalize( $s );
                if ( $wgFixArabicUnicode ) {
index cf45762..176c64c 100644 (file)
@@ -41,7 +41,7 @@ class LanguageMl extends Language {
         *
         * @return string
         */
-       function normalize( $s ) {
+       public function normalize( $s ) {
                global $wgFixMalayalamUnicode;
                $s = parent::normalize( $s );
                if ( $wgFixMalayalamUnicode ) {
index 2422fa8..aaea4c7 100644 (file)
        "ns-specialprotected": "Les páxines especiales nun se puen editar.",
        "titleprotected": "Esti títulu ta protexíu escontra creación por [[User:$1|$1]].\nEl motivu conseñáu ye <em>$2</em>.",
        "filereadonlyerror": "Nun pudo camudase'l ficheru «$1» porque l'estoyu de ficheros «$2» ta en mou de sólo llectura.\n\nL'alministrador del sistema que lu bloquió dio esti motivu: «$3».",
+       "invalidtitle": "Títulu inválidu",
        "invalidtitle-knownnamespace": "Títulu inválidu col espaciu de nomes «$2» ya'l testu «$3»",
        "invalidtitle-unknownnamespace": "Títulu inválidu col númberu $1 d'espaciu de nomes desconocíu ya'l testu «$2»",
        "exception-nologin": "Nun aniciasti sesión",
        "filehist-filesize": "Tamañu del ficheru",
        "filehist-comment": "Comentariu",
        "imagelinks": "Usu del ficheru",
-       "linkstoimage": "{{PLURAL:$1|La páxina siguiente enllacia|Les páxines siguientes enllacien}} a esti ficheru:",
-       "linkstoimage-more": "Más de $1 {{PLURAL:$1|páxina enllacia|páxines enllacien}} a esti ficheru.\nLa llista siguiente amuesa{{PLURAL:$1|'l primer enllaz de páxina| los primeros $1 enllaces de páxina}} a esti ficheru namái.\nHai disponible una [[Special:WhatLinksHere/$2|llista completa]].",
-       "nolinkstoimage": "Nun hai páxines qu'enllacien a esti ficheru.",
+       "linkstoimage": "{{PLURAL:$1|La páxina siguiente usa|Les páxines siguientes usen}} esti ficheru:",
+       "linkstoimage-more": "Más de $1 {{PLURAL:$1|páxina usa|páxines usen}} esti ficheru.\nLa llista siguiente amuesa {{PLURAL:$1|la primer páxina qu'usa|les $1 primeres páxines qu'usen}} esti ficheru namái.\nHai disponible una [[Special:WhatLinksHere/$2|llista completa]].",
+       "nolinkstoimage": "Nun hai páxines qu'usen esti ficheru.",
        "morelinkstoimage": "Ver [[Special:WhatLinksHere/$1|más enllaces]] a esti ficheru.",
        "linkstoimage-redirect": "$1 (redireición de ficheru) $2",
        "duplicatesoffile": "{{PLURAL:$1|El siguiente ficheru ye un duplicáu|Los $1 ficheros siguientes son duplicaos}} d'esti ([[Special:FileDuplicateSearch/$2|más detalles]]):",
index 2913625..cb7fb23 100644 (file)
        "diff-multi-sameuser": "(ца {{PLURAL:$1|гайтина юккъера цхьа верси|гайтина юккъера цхьа версеш}} оьцу декъашхочун)",
        "diff-multi-otherusers": "(ца {{PLURAL:$1|гайтина юккъера верси|гайтина юккъера версеш}} {{PLURAL:$2|кхин цхьан декъашхочун|$2 декъашхойн}})",
        "diff-multi-manyusers": "({{PLURAL:$1|гайтина яц $1 юккъера верси, йина|гайтина яц $1 юккъера версеш, йина}} {{PLURAL:$2|$2 декъашхочо|$2 декъашхоша}})",
+       "difference-missing-revision": "{{PLURAL:$2|Цакарий}} {{PLURAL:$2|$2 верси}} ($1) дустарна.\n\nИштта хуьлу хьажорг шира хилча, дӀаяьккхина йолу.\nМадарра хила мега [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} дӀадаьхнарш долу тéптар] чохь.",
        "searchresults": "Карийнарш",
        "searchresults-title": "Лахар «$1»",
        "titlematches": "АгӀонийн цӀерш цхьаьнанисялар",
index 9398ee4..89eb5d7 100644 (file)
        "category-file-count": "{{PLURAL:$2|Diese Kategorie enthält nur folgende Datei.|Folgende {{PLURAL:$1|Datei ist|$1 Dateien sind}} in dieser Kategorie, von $2 insgesamt.}}",
        "category-file-count-limited": "Folgende {{PLURAL:$1|Datei ist|$1 Dateien sind}} in dieser Kategorie enthalten:",
        "listingcontinuesabbrev": "(Fortsetzung)",
-       "index-category": "Indexierte Seiten",
-       "noindex-category": "Nichtindexierte Seiten",
+       "index-category": "Seiten, die indexiert werden können",
+       "noindex-category": "Seiten, die nicht indexiert werden können",
        "broken-file-category": "Seiten mit defekten Dateilinks",
        "about": "Über",
        "article": "Seite",
        "post-expand-template-inclusion-warning": "Warnung: Die Größe eingebundener Vorlagen ist zu groß, einige Vorlagen können nicht eingebunden werden.",
        "post-expand-template-inclusion-category": "Seiten, in denen die maximale Größe eingebundener Vorlagen überschritten ist",
        "post-expand-template-argument-warning": "'''Warnung:''' Diese Seite enthält mindestens einen Parameter in einer Vorlage, der expandiert zu groß ist. Diese Parameter werden ignoriert.",
-       "post-expand-template-argument-category": "Seiten mit ignorierten Vorlagenparametern",
+       "post-expand-template-argument-category": "Seiten, die ignorierte Vorlagenparameter enthalten",
        "parser-template-loop-warning": "Vorlagenschleife entdeckt: [[$1]]",
        "template-loop-category": "Seiten mit Vorlagenschleifen",
        "template-loop-category-desc": "Die Seite enthält eine Vorlagenschleife, z.&nbsp;B. eine Vorlage, die sich selbst rekursiv aufruft.",
index 704cdc8..b0ea878 100644 (file)
        "search-nonefound": "Δεν υπάρχουν αποτελέσματα που να ικανοποιούν το ερώτημα.",
        "search-nonefound-thiswiki": "Δεν υπάρχουν αποτελέσματα που να ικανοποιούν το ερώτημα σε αυτόν τον ιστότοπο.",
        "powersearch-legend": "Αναλυτική αναζήτηση",
-       "powersearch-ns": "Î\91ναζήÏ\84ηÏ\83η Ï\83Ï\84ιÏ\82 Ï\80εÏ\81ιοÏ\87έÏ\82 Î¿Î½Î¿Î¼Î¬Ï\84Ï\89ν:",
+       "powersearch-ns": "Î\91ναζήÏ\84ηÏ\83η Ï\83Ï\84οÏ\85Ï\82 Î¿Î½Î¿Î¼Î±Ï\84οÏ\87Ï\8eÏ\81οÏ\85Ï\82:",
        "powersearch-togglelabel": "Έλεγχος:",
-       "powersearch-toggleall": "Î\8cλεÏ\82",
-       "powersearch-togglenone": "Î\9aαμία",
+       "powersearch-toggleall": "Î\8cλοι",
+       "powersearch-togglenone": "Î\9aανέναÏ\82",
        "powersearch-remember": "Διατήρηση επιλογής για μελλοντικές αναζητήσεις",
        "search-external": "Εξωτερική αναζήτηση",
        "searchdisabled": "Η αναζήτηση για τον ιστότοπο \"{{SITENAME}}\" είναι απενεργοποιημένη. Μπορείτε να αναζητήσετε μέσω του Google εν τω μεταξύ. Σημειώστε ότι οι κατάλογοί τους για το περιεχόμενο του ιστοτόπου \"{{SITENAME}}\" μπορεί να είναι απαρχαιωμένοι.",
index 35a9280..65fe679 100644 (file)
        "filehist-filesize": "Dimension del file",
        "filehist-comment": "Commento",
        "imagelinks": "Uso de iste file",
-       "linkstoimage": "Le sequente {{PLURAL:$1|pagina ha un ligamine|$1 paginas ha ligamines}} verso iste file:",
-       "linkstoimage-more": "Plus de $1 {{PLURAL:$1|pagina ha un ligamine|paginas ha ligamines}} verso iste file.\nLe sequente lista monstra le {{PLURAL:$1|prime pagina|prime $1 paginas}} que puncta a iste file specific.\nUn [[Special:WhatLinksHere/$2|lista complete]] es disponibile.",
-       "nolinkstoimage": "Nulle pagina usa iste file.",
+       "linkstoimage": "Le sequente {{PLURAL:$1|pagina|$1 paginas}} usa iste file:",
+       "linkstoimage-more": "Plus de $1 {{PLURAL:$1|pagina|paginas}} usa iste file.\nLe sequente lista monstra le {{PLURAL:$1|prime pagina|prime $1 paginas}} que usa iste file solmente.\nUn [[Special:WhatLinksHere/$2|lista complete]] es disponibile.",
+       "nolinkstoimage": "Il non ha paginas que usa iste file.",
        "morelinkstoimage": "Vider [[Special:WhatLinksHere/$1|plus ligamines]] a iste file.",
        "linkstoimage-redirect": "$1 (redirection de file) $2",
        "duplicatesoffile": "Le sequente {{PLURAL:$1|file es un duplicato|$1 files es duplicatos}} de iste file ([[Special:FileDuplicateSearch/$2|plus detalios]]):",
index 7544b72..a5e5ca5 100644 (file)
        "filehist-filesize": "ファイルサイズ",
        "filehist-comment": "コメント",
        "imagelinks": "ファイルの使用状況",
-       "linkstoimage": "以ä¸\8bã\81®{{PLURAL:$1|ã\83\9aã\83¼ã\82¸|â\80\8b&#32;$1 ã\83\9aã\83¼ã\82¸}}ã\81\8cã\81\93ã\81®ã\83\95ã\82¡ã\82¤ã\83«ã\81«ã\83ªã\83³ã\82¯しています:",
-       "linkstoimage-more": "ã\81\93ã\81®ã\83\95ã\82¡ã\82¤ã\83«ã\81¸ã\81¯ $1 ã\82\92è¶\85ã\81\88ã\82\8bæ\95°ã\81®ã\83\9aã\83¼ã\82¸ã\81\8bã\82\89ã\83ªã\83³ã\82¯ã\81\8cã\81\82ã\82\8aã\81¾ã\81\99ã\80\82\n以ä¸\8bã\81®ä¸\80覧ã\81§ã\81¯ã\81\93ã\81®ã\83\95ã\82¡ã\82¤ã\83«ã\81«ã\83ªã\83³ã\82¯している最初の $1 ページのみを表示しています。\n[[Special:WhatLinksHere/$2|完全な一覧]]も参照してください。",
-       "nolinkstoimage": "ã\81\93ã\81®ã\83\95ã\82¡ã\82¤ã\83«ã\81¸ã\83ªã\83³ã\82¯しているページはありません。",
+       "linkstoimage": "以ä¸\8bã\81®{{PLURAL:$1|ã\83\9aã\83¼ã\82¸|â\80\8b&#32;$1 ã\83\9aã\83¼ã\82¸}}ã\81\8cã\81\93ã\81®ã\83\95ã\82¡ã\82¤ã\83«ã\82\92使ç\94¨しています:",
+       "linkstoimage-more": "ã\81\93ã\81®ã\83\95ã\82¡ã\82¤ã\83«ã\81¸ã\81¯ $1 ã\82\92è¶\85ã\81\88ã\82\8bæ\95°ã\81®ã\83\9aã\83¼ã\82¸ã\81§ä½¿ç\94¨ã\81\95ã\82\8cã\81¦ã\81\84ã\81¾ã\81\99ã\80\82\n以ä¸\8bã\81®ä¸\80覧ã\81§ã\81¯ã\81\93ã\81®ã\83\95ã\82¡ã\82¤ã\83«ã\82\92使ç\94¨している最初の $1 ページのみを表示しています。\n[[Special:WhatLinksHere/$2|完全な一覧]]も参照してください。",
+       "nolinkstoimage": "ã\81\93ã\81®ã\83\95ã\82¡ã\82¤ã\83«ã\82\92使ç\94¨しているページはありません。",
        "morelinkstoimage": "このファイルへの[[Special:WhatLinksHere/$1|リンク元を更に]]を表示する。",
        "linkstoimage-redirect": "$1 (リダイレクト) $2",
        "duplicatesoffile": "以下の $1 {{PLURAL:$1|ファイル}}が、このファイルと重複しています ([[Special:FileDuplicateSearch/$2|詳細]]):",
index 85a4464..b51843c 100644 (file)
        "minoredit": "ဣဏအ်ဂှ် ဒှ်အရာ မပလေဝ်ဒါန် ညိည",
        "watchthis": "မင်မဲ မုက်လိက်ဏအ်",
        "savearticle": "ဂိုင်သိပ် မုက်လိက်",
-       "preview": "á\80\80á\80­á\80¯á\80\95á\80ºá\80\97á\80\97á\80µá\80¯",
-       "showpreview": "á\80\91á\80¹á\81\9cá\80¸ á\80\80á\80­á\80¯á\80\95á\80ºá\80\97á\80\97á\80µá\80¯",
+       "preview": "á\80\94á\80\99á\80°á\80\94á\80¬",
+       "showpreview": "á\80\91á\80¹á\81\9cá\80¸ á\80\94á\80\99á\80°á\80\94á\80¬",
        "showdiff": "ထ္ၜး အရာမပြံင်လှာဲ",
        "anoneditwarning": "<strong>သတိ</strong> မၞး ဟွံဂွံ လုပ်လံက်အေန်လဝ်ရ၊၊ IP address မၞး မံက်ဒၟံင်ရောင် ယဝ်ရ မၞးကၠောန်သ္ပ ပရေင်ပလေဝ်ပလေတ်မွဲမွဲမ္ဂး၊၊ ယဝ်ရ <strong>[$1 လုပ်လံက်အေန်]</strong> ဟွံသေင်မ္ဂး <strong>[$2 ခၞံကၠောန် အကံက်မွဲ]</strong>မ္ဂး၊ ပရေင်ပလေဝ်ဒါန်မၞး တြးပတိတ် နကဵု ယၟုသုင်စောဲ မၞးရောင်၊၊",
        "blockedtext": "<strong>ယၟုညးလွပ် ဟွံသေင်မ္ဂး ဌာန်ဒၟံင်အာင်ဒဳမၞး ဒးဒုင်ကၟာတ်စဵုဒၞာလဝ်</strong>\n\nပွမကၟာတ်စဵုဒၞာဂှ် ကၠောန်လဝ် နကဵု $1.\nဟိုတ်မဂွံကၟာတ်စဵုဒၞာဂှ် <em>$2</em>.\n\n* အခိင်မစကၟာတ်စဵုဒၞာ- $8\n* အခိင်မကၟာတ်စဵုဒၞာအိုတ်- $6\n* မရန်တၟအ် blockee- $7\n\nမၞး ဆက်ကဵု $1 ဟွံသေင်မ္ဂး ညးတၞဟ်သအာင် [[{{MediaWiki:Grouppage-sysop}}|administrator]] ယဝ်ရ မိက်ဂွံ ပတိုန်ဂလာန် စပ်ကဵု မဒးဒုင်ကၟာတ်စဵုဒၞာဂှ်ဂွံရ၊၊\nမၞး စကာ အဳမေလ် \"{{int:emailuser}}\" ဟွံဂွံရ၊၊ ဆဂး ယဝ်ရ ဌာန်ဒၟံင်အဳမေလ်ဂှ် ဒှ်အရာတၟေင် ပ္ဍဲ [[Special:Preferences|account preferences]] မၞး ကေုာံ မၞးဟွံဒးဒုင် ကၟာတ်စဵုဒၞာလဝ် နကဵုအဳမေဝ်ဂှ်မ္ဂး ဂွံမာန်ရ၊၊\nIP address မၞး လၟုဟ်ဂှ် ဒှ် $3, တုဲ ID မဒးဒုင်ကၟာတ်စဵုဒၞာဂှ် ဒှ် #$5 ရ၊၊ \nယဝ်ရ မၞးမိက်ဂွံ သၟာန်မ္ဂး တင်ဂၞင် ဗွဲလတူတအ် သီုဖအိုတ်ဂှ် ဗၟံက်ထ္ၜးကဵုညိ၊၊",
        "creating": "မခၞံကၠောန်ဒၟံင် $1",
        "editingsection": "ပလေဝ်ဒါန်ဒၟံင် (ဒကုတ်) $1",
        "templatesused": "{{PLURAL:$1|Template|Templates}} မသုင်စောဲ ပ္ဍဲ မုက်လိက်ဏအ်:",
-       "templatesusedpreview": "{{PLURAL:$1|Template|Templates}} á\80\99á\80\85á\80\80á\80¬á\80\9cá\80\9dá\80º á\80\95á\80¹á\80\8dá\80²á\80\80á\80­á\80¯á\80\95á\80ºá\80\97á\80\97á\80µá\80¯ဏအ်-",
+       "templatesusedpreview": "{{PLURAL:$1|Template|Templates}} á\80\99á\80\85á\80\80á\80¬á\80\9cá\80\9dá\80º á\80\95á\80¹á\80\8dá\80²á\80\94á\80\99á\80°á\80\94á\80¬ဏအ်-",
        "template-protected": "(စဵုဒၞာလဝ်)",
        "template-semiprotected": "(မစဵုဒၞာလဝ်-ကဝက်)",
        "hiddencategories": "မုက်လိက်ဏအ်ဂှ် ဒှ်ဂကောံ ကု{{PLURAL:$1|1 hidden category|$1 hidden categories}}:",
        "nextrevision": "မူမဒါန်လဝ် တၟိနူဂှ် →",
        "currentrevisionlink": "မူမဒါန်လဝ် လက္ကရဴအိုတ်",
        "cur": "ပစ္စုပ္ပန်",
-       "last": "á\80\80á\80­á\80¯á\80\95á\80ºá\80\97á\80\97á\80µá\80¯",
+       "last": "á\80\80á\80­á\80¯á\80\95á\80ºá\80\80á\81 á\80¬",
        "histlegend": "တၞဟ်န ဂွံပတောအ်ၜတ် အကြာမူမပလေဝ်ဒါန်လဝ်တအ်ဂှ် ကဵုစၟတ် ပ္ဍဲခံက်အင်ရေဒဳယော radio boxes တုဲ ဍဵုenter ဟွံသေင်မ္ဂး ဍဵု ကောန်ဍေင် သၟဝ်ဂှ်ညိ၊၊ <br />Legend: <strong>({{int:cur}})</strong> = အရာမတၞဟ်ခြာ ကုမူလက္ကရဴအိုတ် <strong>({{int:last}})</strong> = အရာမတၞဟ်ခြာ ကုမူကၠာနူဂှ်၊၊ <strong>{{int:minoreditletter}}</strong> = မပလေဝ်ဒါန်လဝ် ညိည၊၊",
        "history-fieldset-title": "ဂၠာဲ မူတြေံဂမၠိုင်",
        "histfirst": "တြေံအိုတ်",
        "tooltip-ca-nstab-category": "ဗဵု မုက်လိက်ကဏ္ဍ",
        "tooltip-minoredit": "ကဵုစၟတ် အရာဏအ် ဒဒှ်ရ မဒှ် အရာမပလေဝ်ဒါန် ညိည",
        "tooltip-save": "ဂိုင်သိပ် အရာမၞး မပြံင်လှာဲလဝ်",
-       "tooltip-preview": "á\80\80á\80­á\80¯á\80\95á\80ºá\80\97á\80\97á\80µá\80¯ အရာမၞး မပြံင်လှာဲလဝ်၊၊ ပဂုန်တုဲ ကၠာဟွံဂွံဂိုင်သိပ်ဂှ် ကၠောန်ကၠာညိ၊၊",
+       "tooltip-preview": "á\80\97á\80µá\80¯á\80\94á\80\99á\80°á\80\94á\80¬ အရာမၞး မပြံင်လှာဲလဝ်၊၊ ပဂုန်တုဲ ကၠာဟွံဂွံဂိုင်သိပ်ဂှ် ကၠောန်ကၠာညိ၊၊",
        "tooltip-diff": "ထ္ၜး ဒၞာဲ မလိက် မၞးမပြံင်လှာဲလဝ်ဂှ်ညိ",
        "tooltip-compareselectedversions": "ရံင် ဗီုတၞဟ်ခြာ အကြာ မူမပလေဝ်ဒါန်လဝ် ပ္ဍဲမုက်လိက်ဏအ် ဒၞာဲမရုဲစှ်လဝ် ၜါဂှ်",
        "tooltip-watch": "စုတ် မုက်လိက်ဏအ် ပ္ဍဲစရင်မမင်မဲ မၞး",
        "file-nohires": "resolution ခိုဟ် နူဏအ် ဟွံဂွံဆဵုရ၊၊",
        "svg-long-desc": "SVG ဝှာင်, မိက်ကဵုကသပ် $1 × $2 pixels, ဇမၞော် ဝှာင်: $3",
        "show-big-image": "ဝှာင် တမ်မူလ",
-       "show-big-image-preview": "á\80\87á\80\99á\81\9eá\80±á\80¬á\80º á\80\80á\80­á\80¯á\80\95á\80ºá\80\97á\80\97á\80µá\80¯ဏအ် - $1",
+       "show-big-image-preview": "á\80\87á\80\99á\81\9eá\80±á\80¬á\80º á\80\94á\80\99á\80°á\80\94á\80¬ ဏအ် - $1",
        "show-big-image-other": "တၞဟ် {{PLURAL:$2|resolution|resolutions}}: $1.",
        "show-big-image-size": "$1 × $2 pixels",
        "metadata": "Metadata",
index 459a65e..cffe621 100644 (file)
        "welcomecreation-msg": "Kontoen din har blitt opprettet.\nIkke glem å endre [[Special:Preferences|innstillingene dine]] på {{SITENAME}}.",
        "yourname": "Brukernavn:",
        "userlogin-yourname": "Brukernavn",
-       "userlogin-yourname-ph": "Fyll inn brukernavnet ditt",
+       "userlogin-yourname-ph": "Fyll inn ditt brukernavn",
        "createacct-another-username-ph": "Fyll inn brukernavnet",
        "yourpassword": "Passord:",
        "userlogin-yourpassword": "Passord",
        "filehist-filesize": "Filstørrelse",
        "filehist-comment": "Kommentar",
        "imagelinks": "Filbruk",
-       "linkstoimage": "Følgende {{PLURAL:$1|side|$1 sider}} har lenker til denne filen:",
-       "linkstoimage-more": "Mer enn $1 {{PLURAL:$1|side|sider}} lenker til denne filen.\nFølgende liste viser {{PLURAL:$1|den første siden|de $1 første sidene}}.\nEn [[Special:WhatLinksHere/$2|fullstendig liste]] er tilgjengelig.",
+       "linkstoimage": "{{PLURAL:$1|Den følgende siden|De følgende $1 sidene}} bruker denne filen:",
+       "linkstoimage-more": "Mer enn $1 {{PLURAL:$1|side|sider}} bruker denne filen.\nFølgende liste viser {{PLURAL:$1|den første siden|de $1 første sidene}} som kun bruker denne filen.\nEn [[Special:WhatLinksHere/$2|fullstendig liste]] er tilgjengelig.",
        "nolinkstoimage": "Det er ingen sider som bruker denne filen.",
        "morelinkstoimage": "Vis [[Special:WhatLinksHere/$1|flere lenker]] til denne filen.",
        "linkstoimage-redirect": "$1 (filomdirigering) $2",
index d91e6d6..1e8ddfd 100644 (file)
        "right-patrolmarks": "Podgląd znaczników patrolowania ostatnich zmian – oznaczania jako „sprawdzone”",
        "right-unwatchedpages": "Podgląd listy stron nieobserwowanych",
        "right-mergehistory": "Łączenie historii edycji stron",
-       "right-userrights": "Edycja uprawnień użytkownika",
-       "right-userrights-interwiki": "Edycja uprawnień użytkowników innych witryn wiki",
+       "right-userrights": "Edycja uprawnień użytkowników",
+       "right-userrights-interwiki": "Edycja uprawnień użytkowników na innych witrynach wiki",
        "right-siteadmin": "Blokowanie i odblokowywanie bazy danych",
        "right-override-export-depth": "Eksport stron wraz z linkowanymi do głębokości 5 linków",
        "right-sendemail": "Wysyłanie e‐maili do innych użytkowników",
index 2e7fb21..c22e638 100644 (file)
        "filehist-filesize": "Tamanho do ficheiro",
        "filehist-comment": "Comentário",
        "imagelinks": "Utilização local do ficheiro",
-       "linkstoimage": "{{PLURAL:$1|A seguinte página contém|As seguintes $1 páginas contêm}} hiperligações para este ficheiro:",
-       "linkstoimage-more": "Mais de {{PLURAL:$1|uma página contém|$1 páginas contêm}} hiperligações para este ficheiro.\nA lista abaixo apresenta apenas {{PLURAL:$1|a primeira página|as primeiras $1 páginas}}.\nEncontra-se disponível uma [[Special:WhatLinksHere/$2|lista completa]].",
-       "nolinkstoimage": "Não há nenhuma página que contenha hiperligações para este ficheiro.",
+       "linkstoimage": "{{PLURAL:$1|A seguinte página usa|As seguintes $1 páginas usam}} este ficheiro:",
+       "linkstoimage-more": "Mais de {{PLURAL:$1|uma página usa|$1 páginas usam}} este ficheiro.\nA lista abaixo apresenta apenas {{PLURAL:$1|a primeira página|as primeiras $1 páginas}}.\nEncontra-se disponível uma [[Special:WhatLinksHere/$2|lista completa]].",
+       "nolinkstoimage": "Não há nenhuma página que use este ficheiro.",
        "morelinkstoimage": "Ver a [[Special:WhatLinksHere/$1|lista completa]] de páginas que contêm hiperligações para este ficheiro.",
        "linkstoimage-redirect": "$1 (redirecionamento de ficheiro) $2",
        "duplicatesoffile": "{{PLURAL:$1|O seguinte ficheiro é duplicado|Os seguintes $1 ficheiros são duplicados}} deste ficheiro ([[Special:FileDuplicateSearch/$2|mais detalhes]]):",
index aabc640..d58c150 100644 (file)
@@ -26,7 +26,8 @@
                        "C.R.",
                        "Anomie",
                        "Pierpao",
-                       "Fitoschido"
+                       "Fitoschido",
+                       "Vlad5250"
                ]
        },
        "tog-underline": "Unnerline airtins:",
        "right-editcontentmodel": "Eedit the content model o ae page",
        "right-editinterface": "Eedit the uiser interface",
        "right-editusercss": "Eedit ither uisers' CSS files",
+       "right-edituserjson": "Eedit ither uisers' JSON files",
        "right-edituserjs": "Eedit ither uisers' JavaScript files",
        "right-editmyusercss": "Eidit yer ain uiser CSS files",
+       "right-editmyuserjson": "Eedit yer ain uiser JSON files",
        "right-editmyuserjs": "Eedit yer ain uiser JavaScript files",
        "right-viewmywatchlist": "See yer ain watchleet",
        "right-editmywatchlist": "Eedit yer ain watchleet. Mynd that some actions will still eik pages even wioot this richt.",
index 41df71d..0e8e391 100644 (file)
@@ -70,7 +70,7 @@
        "tog-oldsig": "Ваш постојећи потпис:",
        "tog-fancysig": "Сматрај потпис као викитекст (без самоповезивања)",
        "tog-uselivepreview": "Прикажи претпреглед без поновног учитавања странице",
-       "tog-forceeditsummary": "Упозори ме када не унесем опис измене",
+       "tog-forceeditsummary": "Упозори ме када не унесем резиме измене",
        "tog-watchlisthideown": "Сакриј моје измене са списка надгледања",
        "tog-watchlisthidebots": "Сакриј измене ботова са списка надгледања",
        "tog-watchlisthideminor": "Сакриј мање измене са списка надгледања",
        "media_tip": "Веза",
        "sig_tip": "Ваш потпис с временском ознаком",
        "hr_tip": "Водоравна линија (користите ретко)",
-       "summary": "Ð\9eпиÑ\81 Ð¸Ð·Ð¼ÐµÐ½е:",
+       "summary": "Резиме:",
        "subject": "Тема:",
        "minoredit": "Ово је мања измена",
        "watchthis": "Надгледај ову страницу",
        "blankarticle": "<strong>Упозорење:</strong> Страница коју правите је празна.\nАко још једном притиснете „$1”, страница ће бити направљена без икаквог садржаја.",
        "anoneditwarning": "<strong>Упозорење:</strong> Нисте пријављени. Ако објавите страницу, Ваша IP адреса ће бити јавно видљива у њеној историји измена и другде. Ако се <strong>[$1 пријавите]</strong> или <strong>[$2 отворите налог]</strong>, поред осталих погодности које добијате Ваше измене ће бити приписиване Вашем корисничком имену.",
        "anonpreviewwarning": "<em>Нисте пријављени. Ако објавите страницу, Ваша IP адреса ће бити јавно видљива у њеној историји измена и другде.</em>",
-       "missingsummary": "<strong>Ð\9fодÑ\81еÑ\82ник:</strong> Ð\9dиÑ\81Ñ\82е Ñ\83нели Ð¾Ð¿Ð¸Ñ\81 Ð¸Ð·Ð¼ÐµÐ½Ðµ.\nÐ\90ко Ð¿Ð¾Ð½Ð¾Ð²Ð¾ ÐºÐ»Ð¸ÐºÐ½ÐµÑ\82е Ð½Ð° â\80\9e$1â\80\9d, Ð\92аÑ\88а Ð¸Ð·Ð¼ÐµÐ½Ð° Ñ\9bе Ð±Ð¸Ñ\82и Ñ\81аÑ\87Ñ\83вана Ð±ÐµÐ· Ð¾Ð¿Ð¸Ñ\81а.",
+       "missingsummary": "<strong>Ð\9fодÑ\81еÑ\82ник:</strong> Ð½Ð¸Ñ\81Ñ\82е Ð½Ð°Ð²ÐµÐ»Ð¸ Ñ\80езиме Ð¸Ð·Ð¼ÐµÐ½Ðµ.\nÐ\90ко Ð¿Ð¾Ð½Ð¾Ð²Ð¾ ÐºÐ»Ð¸ÐºÐ½ÐµÑ\82е Ð½Ð° â\80\9e$1â\80\9d, Ð\92аÑ\88а Ð¸Ð·Ð¼ÐµÐ½Ð° Ñ\9bе Ð±Ð¸Ñ\82и Ñ\81аÑ\87Ñ\83вана Ð±ÐµÐ· Ñ\80езимеа.",
        "selfredirect": "<strong>Упозорење:</strong> Преусмеравате ову страницу на њу саму.\nМожда вам је одредишна страница за преусмерење погрешна или уређујете погрешну страницу.\nАко још једном притиснете „$1”, преусмерење ће свеједно бити направљено.",
        "missingcommenttext": "Молимо унесите коментар.",
        "missingcommentheader": "<strong>Напомена:</strong> Нисте унели наслов теме овог коментара.\nАко поново кликнете на „$1”, измена ће бити сачувана без наслова.",
-       "summary-preview": "Преглед описа измене:",
+       "summary-preview": "Преглед резимеа измене:",
        "subject-preview": "Преглед теме:",
        "previewerrortext": "Дошло је до грешке при покушају прегледа промена.",
        "blockedtitle": "Корисник је блокиран",
        "editpage-cannot-use-custom-model": "Модел садржаја ове странице се не може променити.",
        "longpageerror": "<strong>Грешка: текст који сте унели је величине {{PLURAL:$1|један килобајт|$1 килобајта}}, што је веће од {{PLURAL:$2|дозвољеног једног килобајта|дозвољена $2 килобајта|дозвољених $2 килобајта}}.</strong>\nСтраница не може бити сачувана.",
        "readonlywarning": "<strong>Упозорење: база података је закључана ради одржавања, тако да тренутно нећете моћи да сачувате измене.</strong>\nМожда бисте желели сачувати текст за касније у некој текстуалној датотеци.\n\nСистемски администратор је навео следеће објашњење: $1",
-       "protectedpagewarning": "<strong>УпозоÑ\80еÑ\9aе: Ð¾Ð²Ð° Ñ\81Ñ\82Ñ\80аниÑ\86а Ñ\98е Ð·Ð°Ñ\88Ñ\82иÑ\9bена, Ñ\82ако Ð´Ð° Ñ\81амо ÐºÐ¾Ñ\80иÑ\81ниÑ\86и Ñ\81 Ð°Ð´Ð¼Ð¸Ð½Ð¸Ñ\81Ñ\82Ñ\80аÑ\82оÑ\80Ñ\81ким Ð¾Ð²Ð»Ð°Ñ\88Ñ\9bеÑ\9aима Ð¼Ð¾Ð³Ñ\83 Ð´Ð° Ñ\98е Ð¼ÐµÑ\9aаÑ\98Ñ\83.</strong>\nÐ\9fоÑ\81ледÑ\9aи унос у евиденцији је наведен испод као референца:",
-       "semiprotectedpagewarning": "<strong>Ð\9dапомена:</strong> Ð¾Ð²Ð° Ñ\81Ñ\82Ñ\80аниÑ\86а Ñ\98е Ð·Ð°Ñ\88Ñ\82иÑ\9bена, Ñ\82ако Ð´Ð° Ñ\81амо Ð°Ñ\83Ñ\82омаÑ\82Ñ\81ки Ð¿Ð¾Ñ\82вÑ\80Ñ\92ени ÐºÐ¾Ñ\80иÑ\81ниÑ\86и Ð¼Ð¾Ð³Ñ\83 Ð´Ð° Ñ\98е Ñ\83Ñ\80еÑ\92Ñ\83Ñ\98Ñ\83.\nÐ\9fоÑ\81ледÑ\9aи унос у евиденцији је наведен испод као референца:",
-       "cascadeprotectedwarning": "<strong>Упозорење:</strong> Ова страница је заштићена тако да је могу уређивати само корисници са [[Special:ListGroupRights|одређеним правима]] (администратори), јер је иста укључена у {{PLURAL:$1|следећу страницу која је заштићена|следеће странице које су заштићене}} „преносивом” заштитом:",
-       "titleprotectedwarning": "<strong>УпозоÑ\80еÑ\9aе: Ð¾Ð²Ð° Ñ\81Ñ\82Ñ\80аниÑ\86а Ñ\98е Ð·Ð°Ñ\88Ñ\82иÑ\9bена, Ñ\82ако Ð´Ð° Ñ\81Ñ\83 Ð¿Ð¾Ñ\82Ñ\80ебна [[Special:ListGroupRights|поÑ\81ебна Ð¿Ñ\80ава]] Ð´Ð° Ñ\81е Ð¾Ð½Ð° Ð½Ð°Ð¿Ñ\80ави.</strong>\nÐ\9fоÑ\81ледÑ\9aи унос у евиденцији је наведен испод као референца:",
+       "protectedpagewarning": "<strong>УпозоÑ\80еÑ\9aе: Ð\9eва Ñ\81Ñ\82Ñ\80аниÑ\86а Ñ\98е Ð·Ð°Ñ\88Ñ\82иÑ\9bена, Ñ\82ако Ð´Ð° Ñ\81амо ÐºÐ¾Ñ\80иÑ\81ниÑ\86и Ñ\81а Ð°Ð´Ð¼Ð¸Ð½Ð¸Ñ\81Ñ\82Ñ\80аÑ\82оÑ\80Ñ\81ким Ð¾Ð²Ð»Ð°Ñ\88Ñ\9bеÑ\9aима Ð¼Ð¾Ð³Ñ\83 Ð´Ð° Ñ\98е Ñ\83Ñ\80еÑ\92Ñ\83Ñ\98Ñ\83.</strong>\nÐ\9dаÑ\98новиÑ\98и унос у евиденцији је наведен испод као референца:",
+       "semiprotectedpagewarning": "<strong>Ð\9dапомена:</strong> Ð\9eва Ñ\81Ñ\82Ñ\80аниÑ\86а Ñ\98е Ð·Ð°Ñ\88Ñ\82иÑ\9bена, Ñ\82ако Ð´Ð° Ñ\81амо Ð°Ñ\83Ñ\82омаÑ\82Ñ\81ки Ð¿Ð¾Ñ\82вÑ\80Ñ\92ени ÐºÐ¾Ñ\80иÑ\81ниÑ\86и Ð¼Ð¾Ð³Ñ\83 Ð´Ð° Ñ\98е Ñ\83Ñ\80еÑ\92Ñ\83Ñ\98Ñ\83.\nÐ\9dаÑ\98новиÑ\98и унос у евиденцији је наведен испод као референца:",
+       "cascadeprotectedwarning": "<strong>Упозорење:</strong> Ова страница је заштићена, тако да само корисници са [[Special:ListGroupRights|одређеним правима]] могу да је уређују, јер је она укључена у {{PLURAL:$1|следећу страницу која је заштићена|следеће странице које су заштићене}} преносивом заштитом:",
+       "titleprotectedwarning": "<strong>УпозоÑ\80еÑ\9aе: Ð\9eва Ñ\81Ñ\82Ñ\80аниÑ\86а Ñ\98е Ð·Ð°Ñ\88Ñ\82иÑ\9bена, Ñ\82ако Ð´Ð° Ñ\81Ñ\83 Ð¿Ð¾Ñ\82Ñ\80ебна [[Special:ListGroupRights|поÑ\81ебна Ð¿Ñ\80ава]] Ð´Ð° Ñ\81е Ð¾Ð½Ð° Ð½Ð°Ð¿Ñ\80ави.</strong>\nÐ\9dаÑ\98новиÑ\98и унос у евиденцији је наведен испод као референца:",
        "templatesused": "{{PLURAL:$1|Шаблон који се користи|Шаблони који се користе}} на овој страници:",
        "templatesusedpreview": "{{PLURAL:$1|Шаблон|Шаблони}} у овом претпрегледу:",
        "templatesusedsection": "{{PLURAL:$1|Шаблон|Шаблони}} у овом одељку:",
        "recreate-moveddeleted-warn": "<strong>Упозорење: поново правите страницу која је претходно обрисана.</strong>\n\nРазмотрите да ли је прикладно да наставите с уређивањем ове странице.\nОвде је наведена евиденција брисања и премештања с образложењем:",
        "moveddeleted-notice": "Ова страница је обрисана.\nЕвиденција брисања, заштите и премештања странице је наведена испод као референца.",
        "moveddeleted-notice-recent": "Жао нам је, ова страница је недавно обрисана (у последњих 24 сата).\nЕвиденција њеног брисања, заштите и премештања налази се испод:",
-       "log-fulllog": "Ð\9fогледаÑ\98 Ñ\86елÑ\83 Ð¸Ñ\81Ñ\82оÑ\80ију",
+       "log-fulllog": "Ð\9fогледаÑ\98 Ñ\86елÑ\83 ÐµÐ²Ð¸Ð´ÐµÐ½Ñ\86ију",
        "edit-hook-aborted": "Измену је прекинула кука.\nНије дато никакво образложење.",
        "edit-gone-missing": "Не могу да ажурирам страницу.\nИзгледа да је обрисана.",
        "edit-conflict": "Сукоб измена.",
        "duplicate-args-warning": "<strong>Упозорење:</strong> [[:$1]] позива [[:$2]] са више од једне вредности за параметар „$3“. Само последња наведена вредност ће бити коришћена.",
        "duplicate-args-category": "Странице с дуплираним аргументима код позива шаблона",
        "duplicate-args-category-desc": "Страница садржи позиве шаблона који користе двоструке аргументе, као што су <code><nowiki>{{foo|bar=1|bar=2}}</nowiki></code> или <code><nowiki>{{foo|bar|1=baz}}</nowiki></code>.",
-       "expensive-parserfunction-warning": "<strong>УпозоÑ\80еÑ\9aе:</strong> Ð¾Ð²Ð° Ñ\81Ñ\82Ñ\80аниÑ\86а Ñ\81адÑ\80жи Ð¿Ñ\80евиÑ\88е Ð¿Ð¾Ð·Ð¸Ð²а за рашчлањивање.\n\nТребало би да има мање од $2 {{PLURAL:$2|позив|позива}}, а сада има $1.",
+       "expensive-parserfunction-warning": "<strong>УпозоÑ\80еÑ\9aе:</strong> Ð\9eва Ñ\81Ñ\82Ñ\80аниÑ\86а Ñ\81адÑ\80жи Ð¿Ñ\80евиÑ\88е Ð¿Ð¾Ð·Ð¸Ð²Ð° Ð¾Ð¿Ñ\82еÑ\80еÑ\9bÑ\83Ñ\98Ñ\83Ñ\9bиÑ\85 Ñ\84Ñ\83нкÑ\86иÑ\98а за рашчлањивање.\n\nТребало би да има мање од $2 {{PLURAL:$2|позив|позива}}, а сада има $1.",
        "expensive-parserfunction-category": "Странице с превише позива за рашчлањивање",
        "post-expand-template-inclusion-warning": "<strong>Упозорење:</strong> величина обухваћеног шаблона је превелика.\nНеки шаблони неће бити обухваћени.",
        "post-expand-template-inclusion-category": "Странице где су обухваћени превелики шаблони",
-       "post-expand-template-argument-warning": "'''УпозоÑ\80еÑ\9aе:''' Ð¾Ð²Ð° Ñ\81Ñ\82Ñ\80аниÑ\86а Ñ\81адÑ\80жи Ð½Ð°Ñ\98маÑ\9aе Ñ\98едан Ð°Ñ\80гÑ\83менÑ\82 Ñ\83 Ñ\88аблонÑ\83 ÐºÐ¾Ñ\98и Ð¸Ð¼Ð° Ð¿Ñ\80евеликÑ\83 Ð²ÐµÐ»Ð¸Ñ\87инÑ\83.\nÐ\9eвакве Ð°Ñ\80гÑ\83менÑ\82е Ð±Ð¸ Ñ\82Ñ\80ебало Ð¸Ð·Ð±ÐµÐ³Ð°Ð²Ð°Ñ\82и.",
+       "post-expand-template-argument-warning": "'''УпозоÑ\80еÑ\9aе:''' Ð\9eва Ñ\81Ñ\82Ñ\80аниÑ\86а Ñ\81адÑ\80жи Ð½Ð°Ñ\98маÑ\9aе Ñ\98едан Ð°Ñ\80гÑ\83менÑ\82 Ñ\83 Ñ\88аблонÑ\83 ÐºÐ¾Ñ\98и Ð¸Ð¼Ð° Ð¿Ñ\80евеликÑ\83 Ð²ÐµÐ»Ð¸Ñ\87инÑ\83.\nÐ\9eвакви Ð°Ñ\80гÑ\83менÑ\82и Ñ\82Ñ\80ебаÑ\98Ñ\83 Ð´Ð° Ñ\81е Ð¸Ð·Ð±ÐµÐ³Ð°Ð²Ð°Ñ\98Ñ\83.",
        "post-expand-template-argument-category": "Странице које садрже изостављене аргументе у шаблону",
        "parser-template-loop-warning": "Откривена је петља шаблона: [[$1]]",
        "template-loop-category": "Странице са петљама шаблона",
        "revdelete-hide-text": "Текст ревизије",
        "revdelete-hide-image": "Сакриј садржај датотеке",
        "revdelete-hide-name": "Циљ и параметре",
-       "revdelete-hide-comment": "Ð\9eпиÑ\81 измене",
+       "revdelete-hide-comment": "Резиме измене",
        "revdelete-hide-user": "Корисничко име/IP адреса",
        "revdelete-hide-restricted": "Сакриј податке од администратора и других корисника",
        "revdelete-radio-same": "(не мењај)",
        "prefs-rc": "Скорашње измене",
        "prefs-watchlist": "Списак надгледања",
        "prefs-editwatchlist": "Уређивање списка надгледања",
-       "prefs-editwatchlist-label": "Уређивање списка:",
-       "prefs-editwatchlist-edit": "уреди списак",
-       "prefs-editwatchlist-raw": "уреди сиров списак",
+       "prefs-editwatchlist-label": "Уреди уносе на списку надгледања:",
+       "prefs-editwatchlist-edit": "погледајте и уклоните наслове са списка надгледања",
+       "prefs-editwatchlist-raw": "уреди сиров списак надгледања",
        "prefs-editwatchlist-clear": "очисти списак надгледања",
        "prefs-watchlist-days": "Број дана у списку надгледања:",
        "prefs-watchlist-days-max": "Највише $1 {{PLURAL:$1|дан|дана|дана}}",
        "prefs-help-variant": "Жељена варијанта или правопис за приказ страница са садржајем овог викија.",
        "yournick": "Нови потпис:",
        "prefs-help-signature": "Коментари на страницама за разговор треба да буду потписани са „<nowiki>~~~~</nowiki>“ које ће бити претворено у ваш потпис и временску ознаку.",
-       "badsig": "Ð\9dеиÑ\81пÑ\80аван сиров потпис.\nПроверите HTML тагове.",
+       "badsig": "Ð\9dеважеÑ\9bи сиров потпис.\nПроверите HTML тагове.",
        "badsiglength": "Ваш потпис је предугачак.\nНе сме бити дужи од $1 {{PLURAL:$1|знака|знака|знакова}}.",
        "yourgender": "Како желите да се представите?",
        "gender-unknown": "Кад вас спомиње, софтвер ће користити родно неутралне речи кад год је то могуће",
        "right-hideuser": "блокирање корисничког имена и његово сакривање од јавности",
        "right-ipblock-exempt": "заобилажење IP блокада, самоблокада и блокада опсега",
        "right-unblockself": "деблокирање самог себе",
-       "right-protect": "мењање степена заштите и уређивање страница под преносивом заштитом",
+       "right-protect": "мењање нивоа заштите и уређивање страница под преносивом заштитом",
        "right-editprotected": "уређивање страница под заштитом „{{int:protect-level-sysop}}“",
        "right-editsemiprotected": "уређивање страница под заштитом „{{int:protect-level-autoconfirmed}}“",
        "right-editcontentmodel": "мењање модела садржаја странице",
        "uploadlogpage": "Евиденција отпремања",
        "uploadlogpagetext": "Испод је списак недавних отпремања.\nПогледајте [[Special:NewFiles|галерију нових датотека]] за лепши преглед.",
        "filename": "Назив датотеке",
-       "filedesc": "Ð\9eпиÑ\81",
-       "fileuploadsummary": "Ð\9eпиÑ\81:",
+       "filedesc": "Резиме",
+       "fileuploadsummary": "Резиме:",
        "filereuploadsummary": "Промене датотеке:",
        "filestatus": "Статус ауторског права:",
        "filesource": "Извор:",
        "upload-disallowed-here": "Не можете да замените ову датотеку.",
        "filerevert": "Врати $1",
        "filerevert-legend": "Врати датотеку",
-       "filerevert-intro": "Враћате датотеку '''[[Media:$1|$1]]''' на [$4 издање од $2; $3].",
+       "filerevert-intro": "Враћате датотеку <strong>[[Media:$1|$1]]</strong> на [$4 верзију од $2; $3].",
        "filerevert-comment": "Разлог:",
        "filerevert-defaultcomment": "Враћено на верзију од $2, $1 ($3)",
        "filerevert-submit": "Врати",
-       "filerevert-success": "Датотека '''[[Media:$1|$1]]''' је враћена на [$4 издање од $2; $3].",
-       "filerevert-badversion": "Ð\9dе Ð¿Ð¾Ñ\81Ñ\82оÑ\98и Ñ\80аниÑ\98е Ð»Ð¾ÐºÐ°Ð»Ð½Ð¾ Ð¸Ð·Ð´Ð°Ñ\9aе Ð´Ð°Ñ\82оÑ\82еке Ñ\81 Ð½Ð°Ð²ÐµÐ´ÐµÐ½Ð¸Ð¼ Ð²Ñ\80еменÑ\81ким Ð¿Ð¾Ð´Ð°Ñ\86има.",
+       "filerevert-success": "Датотека <strong>[[Media:$1|$1]]</strong> је враћена на [$4 верзију од $2; $3].",
+       "filerevert-badversion": "Ð\9dе Ð¿Ð¾Ñ\81Ñ\82оÑ\98и Ñ\80аниÑ\98а Ð»Ð¾ÐºÐ°Ð»Ð½Ð° Ð²ÐµÑ\80зиÑ\98а Ð¾Ð²Ðµ Ð´Ð°Ñ\82оÑ\82еке Ñ\81а Ð½Ð°Ð²ÐµÐ´ÐµÐ½Ð¾Ð¼ Ð²Ñ\80еменÑ\81ком Ð¾Ð·Ð½Ð°ÐºÐ¾Ð¼.",
        "filerevert-identical": "Актуелна верзија датотеке је индентична изабраној.",
        "filedelete": "Обриши $1",
        "filedelete-legend": "Обриши датотеку",
        "filedelete-comment": "Разлог:",
        "filedelete-submit": "Обриши",
        "filedelete-success": "Датотека '''$1''' је обрисана.",
-       "filedelete-success-old": "Ð\98здаÑ\9aе '''[[Media:$1|$1]]''' Ð¾Ð´ $2, $3 Ñ\98е Ð¾Ð±Ñ\80иÑ\81ано.",
+       "filedelete-success-old": "Ð\92еÑ\80зиÑ\98а Ð´Ð°Ñ\82оÑ\82еке <strong>[[Media:$1|$1]]</strong> Ð¾Ð´ $2, $3 Ñ\98е Ð¾Ð±Ñ\80иÑ\81ана.",
        "filedelete-nofile": "Датотека '''$1''' не постоји.",
-       "filedelete-nofile-old": "Ð\9dе Ð¿Ð¾Ñ\81Ñ\82оÑ\98и Ð°Ñ\80Ñ\85ивиÑ\80ано Ð¸Ð·Ð´Ð°Ñ\9aе Ð´Ð°Ñ\82оÑ\82еке '''$1''' Ñ\81 наведеним особинама.",
+       "filedelete-nofile-old": "Ð\9dе Ð¿Ð¾Ñ\81Ñ\82оÑ\98и Ð°Ñ\80Ñ\85ивиÑ\80ана Ð²ÐµÑ\80зиÑ\98а Ð´Ð°Ñ\82оÑ\82еке <strong>$1</strong> Ñ\81а наведеним особинама.",
        "filedelete-otherreason": "Други/додатни разлог:",
        "filedelete-reason-otherlist": "Други разлог",
        "filedelete-reason-dropdown": "*Најчешћи разлози брисања\n** Кршење ауторских права\n** Дупликати датотека",
        "enotif_lastvisited": "За све промене од последње посете, погледајте $1.",
        "enotif_lastdiff": "Да бисте видели ову промену, погледајте $1.",
        "enotif_anon_editor": "анониман корисник $1",
-       "enotif_body": "Ð\9fоÑ\88Ñ\82овани $WATCHINGUSERNAME,\n \t\n$PAGEINTRO $NEWPAGE\n\nÐ\9eпиÑ\81: $PAGESUMMARY $PAGEMINOREDIT\n\nКонтакт:\nмејл: $PAGEEDITOR_EMAIL\nвики: $PAGEEDITOR_WIKI\n\nНеће бити других обавештења у случају даљих измена уколико не посетите ову страницу када сте пријављени.\nМожете и да поништите подешавања обавештења за све странице у вашем списку надгледања.\n\nСрдачан поздрав, {{SITENAME}}\n\n--\nДа бисте променили подешавања имејл обавештења, посетите\n{{canonicalurl:{{#special:Preferences}}}}\n\nДа бисте променили подешавања списка надгледања, посетите\n{{canonicalurl:{{#special:EditWatchlist}}}}\n\nДа бисте уклонили ову страницу са списка надгледања, посетите\n$UNWATCHURL\n\nПодршка и даља помоћ:\n$HELPPAGE",
+       "enotif_body": "Ð\9fоÑ\88Ñ\82овани $WATCHINGUSERNAME,\n \t\n$PAGEINTRO $NEWPAGE\n\nРезиме Ñ\83Ñ\80еÑ\92иваÑ\87а: $PAGESUMMARY $PAGEMINOREDIT\n\nКонтакт:\nмејл: $PAGEEDITOR_EMAIL\nвики: $PAGEEDITOR_WIKI\n\nНеће бити других обавештења у случају даљих измена уколико не посетите ову страницу када сте пријављени.\nМожете и да поништите подешавања обавештења за све странице у вашем списку надгледања.\n\nСрдачан поздрав, {{SITENAME}}\n\n--\nДа бисте променили подешавања имејл обавештења, посетите\n{{canonicalurl:{{#special:Preferences}}}}\n\nДа бисте променили подешавања списка надгледања, посетите\n{{canonicalurl:{{#special:EditWatchlist}}}}\n\nДа бисте уклонили ову страницу са списка надгледања, посетите\n$UNWATCHURL\n\nПодршка и даља помоћ:\n$HELPPAGE",
        "enotif_minoredit": "Ово је мања измена",
        "created": "направљена",
        "changed": "измењена",
        "rollback-missingrevision": "Не могу да учитам податке о ревизији.",
        "cantrollback": "Не могу да вратим измену.\nПоследњи аутор је уједно и једини.",
        "alreadyrolled": "Враћање последње измене странице [[:$1]] од стране {{GENDER:$2|корисника|кориснице|корисника}} [[User:$2|$2]] ([[User talk:$2|разговор]]{{int:pipe-separator}}[[Special:Contributions/$2|{{int:contribslink}}]]) није успело; неко други је у међувремену изменио или вратио страницу.\n\nПоследњу измену је {{GENDER:$3|направио|направила|направио}} [[User:$3|$3]] ([[User talk:$3|разговор]]{{int:pipe-separator}}[[Special:Contributions/$3|{{int:contribslink}}]]).",
-       "editcomment": "Ð\9eпиÑ\81 Ð¸Ð·Ð¼ÐµÐ½Ðµ: <em>$1</em>.",
+       "editcomment": "Резиме Ð¸Ð·Ð¼ÐµÐ½Ðµ Ñ\98е Ð±Ð¸Ð¾: <em>$1</em>.",
        "revertpage": "Враћене измене {{GENDER:$2|корисника|кориснице}} [[Special:Contributions/$2|$2]] ([[User talk:$2|разговор]]) на последњу ревизију {{GENDER:$1|корисника|кориснице}} [[User:$1|$1]]",
-       "revertpage-nouser": "Ð\98змене Ñ\81кÑ\80ивеног ÐºÐ¾Ñ\80иÑ\81ника Ñ\81Ñ\83 Ð²Ñ\80аÑ\9bене Ð½Ð° Ð¿Ð¾Ñ\81ледÑ\9aÑ\83 Ð¸Ð·Ð¼ÐµÐ½у {{GENDER:$1|корисника|кориснице}} [[User:$1|$1]]",
+       "revertpage-nouser": "Ð\92Ñ\80аÑ\9bене Ð¸Ð·Ð¼ÐµÐ½Ðµ Ñ\81кÑ\80ивеног ÐºÐ¾Ñ\80иÑ\81ника Ð½Ð° Ð¿Ð¾Ñ\81ледÑ\9aÑ\83 Ñ\80евизиÑ\98у {{GENDER:$1|корисника|кориснице}} [[User:$1|$1]]",
        "rollback-success": "Враћене измене {{GENDER:$1|корисника|кориснице}} {{GENDER:$3|$1}}  на последњу ревизију {{GENDER:$2|корисника|кориснице}} {{GENDER:$4|$2}}.",
        "rollback-success-notify": "Враћене измене корисника $1;\nвраћено на последњу ревизију корисника $2. [$3 Прикажи промене]",
        "sessionfailure-title": "Сесија је окончана",
        "protectedarticle-comment": "{{GENDER:$2|Заштићена}} страница [[$1]]",
        "modifiedarticleprotection-comment": "је {{GENDER:$2|променио|променила}} ниво заштите странице „[[$1]]”",
        "unprotectedarticle-comment": "{{GENDER:$2|Скинута}} заштита са [[$1]]",
-       "protect-title": "Промена степена заштите за страницу „$1“",
-       "protect-title-notallowed": "Преглед степена заштите за „$1“",
+       "protect-title": "Промена нивоа заштите странице „$1“",
+       "protect-title-notallowed": "Преглед нивоа заштите странице „$1“",
        "prot_1movedto2": "је преместио [[$1]] на [[$2]]",
        "protect-badnamespace-title": "Незаштитљив именски простор",
        "protect-badnamespace-text": "Странице у овом именском простору се не могу заштитити.",
        "imageinvalidfilename": "Циљано име датотеке је неважеће",
        "fix-double-redirects": "Ажурирајте сва преусмерења која воде до првобитног наслова",
        "move-leave-redirect": "Остави преусмерење",
-       "protectedpagemovewarning": "'''УпозоÑ\80еÑ\9aе:''' Ð¾Ð²Ð° Ñ\81Ñ\82Ñ\80аниÑ\86а Ñ\98е Ð·Ð°Ñ\88Ñ\82иÑ\9bена, Ñ\82ако Ð´Ð° Ñ\81амо ÐºÐ¾Ñ\80иÑ\81ниÑ\86и Ñ\81 Ð°Ð´Ð¼Ð¸Ð½Ð¸Ñ\81Ñ\82Ñ\80аÑ\82оÑ\80Ñ\81ким Ð¾Ð²Ð»Ð°Ñ\88Ñ\9bеÑ\9aима Ð¼Ð¾Ð³Ñ\83 Ð´Ð° Ñ\98е Ð¿Ñ\80емеÑ\81Ñ\82е.\nÐ\9fоÑ\81ледÑ\9aи унос у евиденцији је наведен испод као референца:",
-       "semiprotectedpagemovewarning": "<strong>Ð\9dапомена:</strong> Ð¾Ð²Ð° Ñ\81Ñ\82Ñ\80аниÑ\86а Ñ\98е Ð·Ð°Ñ\88Ñ\82иÑ\9bена, Ñ\82ако Ð´Ð° Ñ\81амо Ð°Ñ\83Ñ\82омаÑ\82Ñ\81ки Ð¿Ð¾Ñ\82вÑ\80Ñ\92ени ÐºÐ¾Ñ\80иÑ\81ниÑ\86и Ð¼Ð¾Ð³Ñ\83 Ð´Ð° Ñ\98е Ð¿Ñ\80емеÑ\81Ñ\82е.\nÐ\9fоÑ\81ледÑ\9aи унос у евиденцији је наведен испод као референца:",
+       "protectedpagemovewarning": "'''УпозоÑ\80еÑ\9aе:''' Ð\9eва Ñ\81Ñ\82Ñ\80аниÑ\86а Ñ\98е Ð·Ð°Ñ\88Ñ\82иÑ\9bена, Ñ\82ако Ð´Ð° Ñ\81амо ÐºÐ¾Ñ\80иÑ\81ниÑ\86и Ñ\81а Ð°Ð´Ð¼Ð¸Ð½Ð¸Ñ\81Ñ\82Ñ\80аÑ\82оÑ\80Ñ\81ким Ð¾Ð²Ð»Ð°Ñ\88Ñ\9bеÑ\9aима Ð¼Ð¾Ð³Ñ\83 Ð´Ð° Ñ\98е Ð¿Ñ\80емеÑ\81Ñ\82е.\nÐ\9dаÑ\98новиÑ\98и унос у евиденцији је наведен испод као референца:",
+       "semiprotectedpagemovewarning": "<strong>Ð\9dапомена:</strong> Ð\9eва Ñ\81Ñ\82Ñ\80аниÑ\86а Ñ\98е Ð·Ð°Ñ\88Ñ\82иÑ\9bена, Ñ\82ако Ð´Ð° Ñ\81амо Ð°Ñ\83Ñ\82омаÑ\82Ñ\81ки Ð¿Ð¾Ñ\82вÑ\80Ñ\92ени ÐºÐ¾Ñ\80иÑ\81ниÑ\86и Ð¼Ð¾Ð³Ñ\83 Ð´Ð° Ñ\98е Ð¿Ñ\80емеÑ\81Ñ\82е.\nÐ\9dаÑ\98новиÑ\98и унос у евиденцији је наведен испод као референца:",
        "move-over-sharedrepo": "[[:$1]] се налази на дељеном складишту. Ако преместите датотеку на овај наслов, то ће заменити дељену датотеку.",
        "file-exists-sharedrepo": "Наведени назив датотеке се већ користи у дељеном складишту.\nИзаберите други назив.",
        "export": "Извоз страница",
        "tooltip-recreate": "Поново направите страницу иако је обрисана",
        "tooltip-upload": "Започните отпремање",
        "tooltip-rollback": "„Врати“ враћа измене последњег доприносиоца ове странице једним кликом",
-       "tooltip-undo": "„Поништи” враћа ову измену и отвара образац за уређивање у претпрегледном моду. Дозвољава додавање разлога у опису измене.",
+       "tooltip-undo": "„Поништи” враћа ову измену и отвара образац за уређивање у претпрегледном моду. Дозвољава додавање разлога у резимеу.",
        "tooltip-preferences-save": "Сачувај подешавања",
-       "tooltip-summary": "Унесите кратак опис",
+       "tooltip-summary": "Унесите кратак резиме",
        "interlanguage-link-title": "$1 — $2",
        "interlanguage-link-title-nonlang": "$1 — $2",
        "common.css": "/* CSS постављен овде ће се одразити на све теме */",
        "exif-software": "Коришћени софтвер",
        "exif-artist": "Аутор",
        "exif-copyright": "Носилац ауторских права",
-       "exif-exifversion": "Exif Ð¸Ð·Ð´Ð°Ñ\9aе",
-       "exif-flashpixversion": "Ð\9fодÑ\80жано Ð¸Ð·Ð´Ð°Ñ\9aе FlashPix-а",
+       "exif-exifversion": "Exif Ð²ÐµÑ\80зиÑ\98а",
+       "exif-flashpixversion": "Ð\9fодÑ\80жана Ð²ÐµÑ\80зиÑ\98а FlashPix-а",
        "exif-colorspace": "Простор боје",
        "exif-componentsconfiguration": "Значење сваког дела",
        "exif-compressedbitsperpixel": "Режим сажимања слике",
        "exif-devicesettingdescription": "Опис поставки уређаја",
        "exif-subjectdistancerange": "Опсег удаљености објекта",
        "exif-imageuniqueid": "Назнака слике",
-       "exif-gpsversionid": "Ð\98здаÑ\9aе GPS ознаке",
+       "exif-gpsversionid": "Ð\92еÑ\80зиÑ\98а GPS ознаке",
        "exif-gpslatituderef": "Северна или јужна ширина",
        "exif-gpslatitude": "Ширина",
        "exif-gpslongituderef": "Источна или западна дужина",
        "exif-contact": "Подаци за контакт",
        "exif-writer": "Писац",
        "exif-languagecode": "Језик",
-       "exif-iimversion": "IIM Ð¸Ð·Ð´Ð°Ñ\9aе",
+       "exif-iimversion": "IIM Ð²ÐµÑ\80зиÑ\98а",
        "exif-iimcategory": "Категорија",
        "exif-iimsupplementalcategory": "Допунске категорије",
        "exif-datetimeexpires": "Не користи након",
        "exif-componentsconfiguration-4": "R",
        "exif-componentsconfiguration-5": "G",
        "exif-componentsconfiguration-6": "B",
-       "exif-exposureprogram-0": "Ð\9dеодÑ\80еÑ\92ено",
+       "exif-exposureprogram-0": "Ð\9dиÑ\98е Ð¾Ð´Ñ\80еÑ\92ен",
        "exif-exposureprogram-1": "Ручно",
        "exif-exposureprogram-2": "Нормалан програм",
        "exif-exposureprogram-3": "Приоритет отвора бленде",
        "exif-flash-function-1": "Нема функције за блиц",
        "exif-flash-redeye-1": "режим исправке црвених очију",
        "exif-focalplaneresolutionunit-2": "инчи",
-       "exif-sensingmethod-1": "Ð\9dеодÑ\80еÑ\92ено",
+       "exif-sensingmethod-1": "Ð\9dедеÑ\84иниÑ\81ан",
        "exif-sensingmethod-2": "Једнокристални матрични сензор",
        "exif-sensingmethod-3": "Двокристални матрични сензор",
        "exif-sensingmethod-4": "Трокристални матрични сензор",
        "scarytranscludefailed": "[Добављање шаблона за $1 није успело]",
        "scarytranscludefailed-httpstatus": "[Не могу да преузмем шаблон $1: HTTP $2]",
        "scarytranscludetoolong": "[URL адреса је предугачка]",
-       "deletedwhileediting": "<strong>УпозоÑ\80еÑ\9aе</strong>: Ð¾Ð²Ð° Ñ\81Ñ\82Ñ\80аниÑ\86а Ñ\98е Ð¾Ð±Ñ\80иÑ\81ана Ð½Ð°ÐºÐ¾Ð½ Ñ\88Ñ\82о Ñ\81Ñ\82е Ð¿Ð¾Ñ\87ели Ñ\81 уређивањем!",
+       "deletedwhileediting": "<strong>УпозоÑ\80еÑ\9aе</strong>: Ð\9eва Ñ\81Ñ\82Ñ\80аниÑ\86а Ñ\98е Ð¾Ð±Ñ\80иÑ\81ана Ð½Ð°ÐºÐ¾Ð½ Ñ\88Ñ\82о Ñ\81Ñ\82е Ð¿Ð¾Ñ\87ели Ñ\81а уређивањем!",
        "confirmrecreate": "{{GENDER:$1|Корисник|Корисница}} [[User:$1|$1]] ([[User talk:$1|разговор]]) је {{GENDER:$1|обрисао|обрисала}} ову страницу након што сте почели да је уређујете из следећег разлога:\n: <em>$2</em>\nПотврдите да стварно желите да направите страницу.",
        "confirmrecreate-noreason": "{{GENDER:$1|Корисник|Корисница}} [[User:$1|$1]] ([[User talk:$1|разговор]]) је {{GENDER:$1|обрисао|обрисала}} ову страницу након што сте почели да је уређујете. Потврдите да стварно желите да поново направите ову страницу.",
        "recreate": "Поново направи",
        "watchlistedit-raw-removed": "{{PLURAL:$1|1 наслов је уклоњен|Уклоњена су $1 наслова|Уклоњено је $1 наслова}}:",
        "watchlistedit-clear-title": "Чишћење списка надгледања",
        "watchlistedit-clear-legend": "Чишћење списка надгледања",
-       "watchlistedit-clear-explain": "Сви наслови ће бити уклоњени из вашег списка надгледања.",
+       "watchlistedit-clear-explain": "Сви наслови ће бити уклоњени из списка надгледања",
        "watchlistedit-clear-titles": "Наслови:",
        "watchlistedit-clear-submit": "Очисти списак надгледања (Ово је неповратно!)",
        "watchlistedit-clear-done": "Ваш списак надгледања је испражњен.",
        "version-ext-license": "Лиценца",
        "version-ext-colheader-name": "Додатак",
        "version-skin-colheader-name": "Тема",
-       "version-ext-colheader-version": "Ð\98здаÑ\9aе",
+       "version-ext-colheader-version": "Ð\92еÑ\80зиÑ\98а",
        "version-ext-colheader-license": "Лиценца",
        "version-ext-colheader-description": "Опис",
        "version-ext-colheader-credits": "Аутори",
        "version-license-info": "Медијавики је слободан софтвер можете га редистрибуирати и/или модификовати под условима ГНУ-ове опште јавне лиценце верзија 2 или сваке следеће коју објави Задужбина за слободан софтвер.\n\nМедијавики се редистрибуира у нади да ће бити од користи, али <em>БЕЗ ИКАКВЕ ГАРАНЦИЈЕ</em> чак и без <strong>ПОДРАЗУМЕВАНЕ ГАРАНЦИЈЕ ФУНКЦИОНАЛНОСТИ</strong> или <strong>ПРИКЛАДНОСТИ ЗА ОДРЕЂЕНЕУ НАМЕНУ</strong>. Погледајте ГНУ-ову општу јавну лиценцу за више информација.\n\nТребало би да сте добили [{{SERVER}}{{SCRIPTPATH}}/COPYING примерак ГНУ-ове опште јавне лиценце] заједно са овим програмом. Ако нисте, пишите на Free Software Foundation, Inc., 51 Franklin St, 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": "Ð\98здаÑ\9aе",
+       "version-software-version": "Ð\92еÑ\80зиÑ\98а",
        "version-entrypoints": "Адресе улазне тачке",
        "version-entrypoints-header-entrypoint": "Улазна тачка",
        "version-entrypoints-header-url": "Адреса",
        "intentionallyblankpage": "Ова страница је намерно остављена празном.",
        "external_image_whitelist": " #Оставите овај ред онаквим какав јесте<pre>\n#Испод додајте одломке регуларних израза (само део који се налази између //)\n#Они ће бити упоређени с адресама спољашњих слика\n#Оне које се поклапају биће приказане као слике, а преостале као везе до слика\n#Редови који почињу с тарабом се сматрају коментарима\n#Сви уноси су осетљиви на мала и велика слова\n\n#Додајте све одломке регуларних израза изнад овог реда. Овај ред не дирајте</pre>",
        "tags": "Важеће ознаке промена",
-       "tag-filter": "Филтер за [[Special:Tags|ознаке]]:",
+       "tag-filter": "Филтер [[Special:Tags|ознака]]:",
        "tag-filter-submit": "Филтрирај",
        "tag-list-wrapper": "([[Special:Tags|{{PLURAL:$1|ознака|ознаке}}]]: $2)",
        "tag-mw-contentmodelchange": "промена модела садржаја",
        "tags-activate": "активирај",
        "tags-deactivate": "деактивирај",
        "tags-hitcount": "$1 {{PLURAL:$1|промена|промене|промена}}",
-       "tags-manage-no-permission": "Немате дозволу да мењате ознаке.",
+       "tags-manage-no-permission": "Немате дозволу да управљате променама ознака.",
        "tags-manage-blocked": "Не можете да мењате ознаке промена док {{GENDER:$1|сте}} блокирани.",
-       "tags-create-heading": "Ð\9dова Ð¾Ð·Ð½Ð°ÐºÐ°",
+       "tags-create-heading": "Ð\9fÑ\80авÑ\99еÑ\9aе Ð½Ð¾Ð²Ðµ Ð¾Ð·Ð½Ð°ÐºÐµ",
        "tags-create-explanation": "По подразумеваним подешавањима нове ознаке моћи ће да користе корисници и ботови.",
        "tags-create-tag-name": "Назив ознаке:",
        "tags-create-reason": "Разлог:",
        "tags-create-submit": "Направи",
-       "tags-create-no-name": "Ð\9cоÑ\80аÑ\82е Ð½Ð°Ð²ÐµÑ\81Ñ\82и Ð½Ð°Ð·Ð¸Ð² ознаке.",
+       "tags-create-no-name": "Ð\9cоÑ\80аÑ\82е Ð´Ð° Ð½Ð°Ð²ÐµÐ´ÐµÑ\82е Ð¸Ð¼Ðµ ознаке.",
        "tags-create-already-exists": "Ознака „$1“ већ постоји.",
        "tags-create-warnings-below": "Правите нову ознаку, желите ли да наставите?",
        "tags-delete-title": "Брисање ознака",
        "logentry-suppress-event-legacy": "$1 је потајно {{GENDER:$2|променио|променила}} видљивост догађаја у евиденцији на страници „$3”",
        "logentry-suppress-revision-legacy": "$1 је тајно {{GENDER:$2|променио|променила}} видљивост ревизија на страници $3",
        "revdelete-content-hid": "садржај је сакривен",
-       "revdelete-summary-hid": "опис измене је сакривен",
+       "revdelete-summary-hid": "резиме измене је сакривен",
        "revdelete-uname-hid": "корисничко име је сакривено",
        "revdelete-content-unhid": "садржај је откривен",
-       "revdelete-summary-unhid": "опис измене је откривен",
+       "revdelete-summary-unhid": "резиме измене је откривен",
        "revdelete-uname-unhid": "корисничко име је откривено",
        "revdelete-restricted": "примењена ограничења за администраторе",
        "revdelete-unrestricted": "уклоњена ограничења за администраторе",
index 23ad3fb..0824294 100644 (file)
        "filehist-filesize": "దస్త్రపు పరిమాణం",
        "filehist-comment": "వ్యాఖ్య",
        "imagelinks": "దస్త్రపు వాడుక",
-       "linkstoimage": "కింది {{PLURAL:$1|పేజీ|$1 పేజీల}} నుండి ఈ ఫైలుకి లింకులు ఉన్నాయి:",
-       "linkstoimage-more": "à°\88 à°«à±\88à°²à±\81à°\95à±\81 $1 à°\95à°\82à°\9fà±\87 à°\8eà°\95à±\8dà°\95à±\81à°µ {{PLURAL:$1|à°ªà±\87à°\9cà±\80 à°²à°¿à°\82à°\95à±\88 à°\89à°\82ది|à°ªà±\87à°\9cà±\80à°²à±\81 à°²à°¿à°\82à°\95à±\88 à°\89à°¨à±\8dనాయి}}.\nà°\88 à°«à±\88à°²à±\81à°\95à°¿ à°®à°¾à°¤à±\8dà°°à°®à±\87 à°²à°¿à°\82à°\95à±\88 à°\89à°¨à±\8dà°¨ {{PLURAL:$1|à°®à±\8aà°¦à°\9fà°¿ à°ªà±\87à°\9cà±\80ని|à°®à±\8aà°¦à°\9fà°¿ $1 à°ªà±\87à°\9cà±\80లనà±\81}} à°\88 à°\95à±\8dà°°à°¿à°\82ది à°\9cాబితా à°\9aà±\82పిసà±\8dà°¤à±\81à°\82ది.\n[[Special:WhatLinksHere/$2|à°ªà±\82à°°à±\8dతి à°\9cాబితా]] à°\95à±\82à°¡à°¾ ఉంది.",
-       "nolinkstoimage": "à°\88 à°«à±\88à°²à±\81à°\95à±\81 à°²à°¿à°\82à°\95ున్న పేజీలు లేవు.",
+       "linkstoimage": "కింది {{PLURAL:$1|పేజీ|$1 పేజీలు}} ఈ ఫైలును వాడుతున్నాయి:",
+       "linkstoimage-more": "à°\88 à°«à±\88à°²à±\81à°¨à±\81 $1 à°\95à°\82à°\9fà±\87 à°\8eà°\95à±\8dà°\95à±\81à°µ {{PLURAL:$1|à°ªà±\87à°\9cà±\80 à°µà°¾à°¡à±\81à°¤à±\8bà°\82ది|à°ªà±\87à°\9cà±\80à°²à±\81 à°µà°¾à°¡à±\81à°¤à±\81à°¨à±\8dనాయి}}.\nà°\88 à°«à±\88à°²à±\81à°¨à±\81 à°®à°¾à°¤à±\8dà°°à°®à±\87 à°µà°¾à°¡à±\81à°¤à±\81à°¨à±\8dà°¨ {{PLURAL:$1|à°®à±\8aà°¦à°\9fà°¿ à°ªà±\87à°\9cà±\80ని|à°®à±\8aà°¦à°\9fà°¿ $1 à°ªà±\87à°\9cà±\80లనà±\81}} à°\88 à°\95à±\8dà°°à°¿à°\82ది à°\9cాబితా à°\9aà±\82పిసà±\8dà°¤à±\81à°\82ది.\n[[Special:WhatLinksHere/$2|à°ªà±\82à°°à±\8dతి à°\9cాబితా]] ఉంది.",
+       "nolinkstoimage": "à°\88 à°«à±\88à°²à±\81à°¨à±\81 à°µà°¾à°¡à±\81à°¤ున్న పేజీలు లేవు.",
        "morelinkstoimage": "ఈ ఫైలుకు ఉన్న మరిన్ని [[Special:WhatLinksHere/$1| లింకులను]] చూపించు",
        "linkstoimage-redirect": "$1 (దస్త్రపు దారిమార్పు) $2",
        "duplicatesoffile": "క్రింద పేర్కొన్న {{PLURAL:$1|ఫైలు ఈ ఫైలుకి నకలు|$1 ఫైళ్ళు ఈ ఫైలుకి నకళ్ళు}} ([[Special:FileDuplicateSearch/$2|మరిన్ని వివరాలు]]):",
        "wantedpages-badtitle": "ఫలితాల సమితిలో తప్పుడు శీర్షిక: $1",
        "wantedfiles": "కావలసిన ఫైళ్ళు",
        "wantedfiletext-cat": "కింది ఫైళ్ళను వాడారు, కానీ అవి ఉనికిలో లేవు. బయటి రిపాజిటరీలలోని ఫైళ్ళను, అవి ఉనికిలో ఉన్నప్పటికీ, చూపవచ్చు. అటువంటి తప్పు పాజిటివులు <del>కొట్టివేయబడతాయి</del>. పైగా, ఉనికిలో లేని ఫైళ్ళను ఇమిడ్చే పేజీలు [[:$1]] లో చేర్చబడతాయి.",
+       "wantedfiletext-cat-noforeign": "కింది దస్త్రాలు ఉనికిలో లేవు. కానీ, అవి వాడుకలో ఉన్నాయి. అదనంగా, ఉనికిలోనే లేని దస్త్రాలను వాడే పేజీల జాబితా [[:$1]] లో ఉంది.",
        "wantedfiletext-nocat": "కింది ఫైళ్ళను వాడారు, కానీ అవి ఉనికిలో లేవు. బయటి రిపాజిటరీలలోని ఫైళ్ళను, అవి ఉనికిలో ఉన్నప్పటికీ, చూపవచ్చు. అటువంటి తప్పు పాజిటివులు <del>కొట్టివేయబడతాయి</del>.",
        "wantedfiletext-nocat-noforeign": "ఈ క్రింది దస్త్రాలను వాడారు కానీ అవి లేనే లేవు.",
        "wantedtemplates": "కావాల్సిన మూసలు",
        "nopagetext": "మీరు అడిగిన పేజీ లేదు",
        "pager-newer-n": "{{PLURAL:$1|1 కొత్తది|$1 కొత్తవి}}",
        "pager-older-n": "{{PLURAL:$1|1 పాతది|$1 పాతవి}}",
-       "suppress": " పూర్తి తొలగింపు",
+       "suppress": "పూర్తి తొలగింపు",
        "querypage-disabled": "పనితీరు కారణాల వలన, ఈ ప్రత్యేకపేజీని అశక్తం చేసాం.",
        "apihelp": "API సహాయం",
        "apihelp-no-such-module": "\"$1\" మాడ్యూలు కనబడలేదు.",
        "anonymous": "{{SITENAME}} యొక్క అజ్ఞాత {{PLURAL:$1|వాడుకరి|వాడుకరులు}}",
        "siteuser": "{{SITENAME}} వాడుకరి $1",
        "anonuser": "{{SITENAME}} అజ్ఞాత వాడుకరి $1",
-       "lastmodifiedatby": "à°\88 à°ªà±\87à°\9cà±\80à°\95à°¿ $3 $2, $1à°¨ à°\9aివరి à°®à°¾à°°à±\8dà°ªà±\81 à°\9aà±\87సారà±\81.",
+       "lastmodifiedatby": "à°\88 à°ªà±\87à°\9cà±\80à°²à±\8b à°\9aివరి à°®à°¾à°°à±\8dà°ªà±\81 $1à°¨ à°\9aà±\87సారà±\81. à°\9aà±\87సినది: $3 $2.",
        "othercontribs": "$1 యొక్క కృతిపై ఆధారితం.",
        "others": "ఇతరాలు",
        "siteusers": "{{SITENAME}} {{PLURAL:$2|{{GENDER:$1|వాడుకరి}}|వాడుకరులు}} $1",
        "pageinfo-watchers": "పేజీ గమనింపుదారుల సంఖ్య",
        "pageinfo-visiting-watchers": "ఈ పేజీలో ఇటీవల జరిగిన దిద్దుబాట్లను చూసిన వీక్షకుల సంఖ్య",
        "pageinfo-few-watchers": "$1 {{PLURAL:$1|వీక్షకుడి|వీక్షకుల}} కంటే తక్కువ",
+       "pageinfo-few-visiting-watchers": "ఇటీవలి మార్పులను గమనిస్తూ ఉన్న వాడుకరి ఉండి ఉండవచ్చు, ఉండకపోనూ వచ్చు.",
        "pageinfo-redirects-name": "ఈ పేజీకి ఉన్న దారిమార్పుల సంఖ్య",
        "pageinfo-subpages-name": "ఈ పేజీకి ఉన్న ఉపపేజీల సంఖ్య",
        "pageinfo-subpages-value": "$1 ($2 {{PLURAL:$2|దారిమార్పు|దారిమార్పులు}}; $3 {{PLURAL:$3|దారిమార్పు కానిది|దారిమార్పు కానివి}})",
        "pageinfo-category-pages": "పేజీల సంఖ్య",
        "pageinfo-category-subcats": "ఉపవర్గాల సంఖ్య",
        "pageinfo-category-files": "దస్త్రాల సంఖ్య",
+       "pageinfo-user-id": "వాడుకరి ID",
+       "pageinfo-file-hash": "హ్యాష్ వ్యాల్యూ",
        "markaspatrolleddiff": "పరీక్షించినట్లుగా గుర్తు పెట్టు",
        "markaspatrolledtext": "ఈ వ్యాసాన్ని పరీక్షించినట్లుగా గుర్తు పెట్టు",
        "markedaspatrolled": "పరీక్షింపబడినట్లు గుర్తింపబడింది",
index 1621af6..0821219 100644 (file)
        "category_header": "«$1» төркемендәге битләр",
        "subcategories": "Төркемчәләр",
        "category-media-header": "«$1» төркемендәге файллар",
-       "category-empty": "''Бу төркем әлегә буш.''",
+       "category-empty": "<em>Бу төркем әлегә буш.</em>",
        "hidden-categories": "{{PLURAL:$1|1=Яшерен төркем|Яшерен төркемнәр}}",
        "hidden-category-category": "Яшерен төркемнәр",
        "category-subcat-count": "{{PLURAL:$2|1=Әлеге төркем бары тик бу астөркемне генә үз өченә ала.|Әлеге төркемдә $2 астөркемдән бары тик $1 {{PLURAL:$1|астөркем}} генә күрсәтелгән.}}",
        "viewtalkpage": "Бәхәс битен карау",
        "otherlanguages": "Башка телләрдә",
        "redirectedfrom": "($1 битеннән юнәлтелде)",
-       "redirectpagesub": "Ð\91аÑ\88ка Ð±Ð¸Ñ\82кÓ\99 Ñ\8eнәлтү бите",
+       "redirectpagesub": "Юнәлтү бите",
        "redirectto": "Шунда юнәлтелә:",
        "lastmodifiedat": "Бу бит соңгы тапкыр $2 $1 үзгәртелә.",
        "viewcount": "Бу биткә $1 {{PLURAL:$1|бер тапкыр|$1 тапкыр}} мөрәҗәгать иттеләр.",
        "rcshowhidecategorization": "битләрне төркемләүне $1",
        "rcshowhidecategorization-show": "Күрсәт",
        "rcshowhidecategorization-hide": "Яшер",
-       "rclinks": "Соңгы $2 көн эчендә ясалган $1 үзгәртүне күрсәт",
+       "rclinks": "Соңгы $2 көндә ясалган $1 үзгәртүне күрсәтергә",
        "diff": "аерма",
        "hist": "тарих",
        "hide": "Яшер",
        "listfiles-summary": "Әлеге махсус бит Сез йөкләгән бөтен файлларны күрсәтә.",
        "listfiles_search_for": "Файл исеме буенча эзләү:",
        "imgfile": "файл",
-       "listfiles": "СүÑ\80Ó\99Ñ\82лÓ\99р исемлеге",
+       "listfiles": "Файллар исемлеге",
        "listfiles_thumb": "Миниатюра",
        "listfiles_date": "Вакыт",
        "listfiles_name": "Файл исеме",
        "filehist-filesize": "Файлның зурлыгы",
        "filehist-comment": "Искәрмә",
        "imagelinks": "Файлны куллану",
-       "linkstoimage": "{{PLURAL:$1|Киләсе $1 бит|Киләсе $1 битләр|}} әлеге файлга сылтама ясый:",
-       "linkstoimage-more": "Ð\91Ñ\83 Ñ\84айлга ÐºÐ¸Ð¼ÐµÐ½Ð´Ó\99 $1 {{PLURAL:$1|биÑ\82}} Ñ\81Ñ\8bлÑ\82ама Ñ\8fÑ\81Ñ\8bй.\nÓ\98леге Ð¸Ñ\81емлекÑ\82Ó\99 Ð±Ñ\83 Ñ\84айлга {{PLURAL:$1| $1 Ñ\81Ñ\8bлÑ\82ама}} ÐºÐ¸Ñ\82еÑ\80елгән.\nШулай ук [[Special:WhatLinksHere/$2|тулы исемлекне]] дә карарга мөмкин.",
-       "nolinkstoimage": "Ð\91Ñ\83 Ñ\84айлга Ñ\81Ñ\8bлÑ\82аган битләр юк.",
+       "linkstoimage": "{{PLURAL:$1|Киләсе бит|Киләсе $1 бит}} әлеге файлны куллана:",
+       "linkstoimage-more": "Ð\91Ñ\83 Ñ\84айлнÑ\8b ÐºÐ¸Ð¼ÐµÐ½Ð´Ó\99 $1 {{PLURAL:$1|биÑ\82}} ÐºÑ\83ллана.\nÓ\98леге Ð¸Ñ\81емлекÑ\82Ó\99 Ð±Ñ\83 Ñ\84айлнÑ\8b ÐºÑ\83лланган {{PLURAL:$1| $1 Ð±Ð¸Ñ\82}} ÐºÒ¯Ñ\80Ñ\81Ó\99Ñ\82елгән.\nШулай ук [[Special:WhatLinksHere/$2|тулы исемлекне]] дә карарга мөмкин.",
+       "nolinkstoimage": "Ð\91Ñ\83 Ñ\84айлнÑ\8b ÐºÑ\83лланган битләр юк.",
        "linkstoimage-redirect": "$1 (файл юнәлтүе) $2",
        "duplicatesoffile": "{{PLURAL:$1|Әлеге $1 файл }} астагы файлның күчерелмәсе булып тора ([[Special:FileDuplicateSearch/$2|тулырак]]):",
        "sharedupload": "Бу файл $1 проектыннан һәм башка проектларда кулланырга мөмкин",
        "trackingcategories": "Күзәтелүче төркемнәр",
        "trackingcategories-msg": "Күзәтүче төркем",
        "trackingcategories-name": "Хат исеме",
-       "emailuser": "Ð\91Ñ\83 Ðºулланучыга хат",
+       "emailuser": "Ð\9aулланучыга хат",
        "emailuser-title-target": "{{GENDER:$1|Кулланучыга}} электрон хат язу",
        "emailuser-title-notarget": "Кулланучыга хат җибәрү",
        "emailpagetext": "Әлеге форма ярдәмендә {{GENDER:$1|кулланучының}} электрон почта адресына хат җибәрергә мөмкин. Җибәрелгән адрес исемендә Сезнең [[Special:Preferences|көйләнмәләрдә]] күрсәтелгән адресыгыз күрсәтеләчәк, шуның ярдәмендә Сез ул кулланучы белән турыдан-туры сөйләшә аласыз.",
        "pipe-separator": "&#32;|&#32;",
        "quotation-marks": "«$1»",
        "imgmultipageprev": "← алдагы бит",
-       "imgmultipagenext": "алдагÑ\8b бит →",
+       "imgmultipagenext": "килÓ\99Ñ\81е бит →",
        "imgmultigo": "Күчү!",
        "imgmultigoto": "$1 битенә күчү",
        "img-lang-go": "Башкару",
index 04aee80..9bfebce 100644 (file)
@@ -53,6 +53,9 @@ abstract class Benchmarker extends Maintenance {
                $this->startBench();
                $count = $this->getOption( 'count', $this->defaultCount );
                $verbose = $this->hasOption( 'verbose' );
+
+               // Normalise
+               $normBenchs = [];
                foreach ( $benchs as $key => $bench ) {
                        // Shortcut for simple functions
                        if ( is_callable( $bench ) ) {
@@ -64,6 +67,25 @@ abstract class Benchmarker extends Maintenance {
                                $bench['args'] = [];
                        }
 
+                       // Name defaults to name of called function
+                       if ( is_string( $key ) ) {
+                               $name = $key;
+                       } else {
+                               if ( is_array( $bench['function'] ) ) {
+                                       $name = get_class( $bench['function'][0] ) . '::' . $bench['function'][1];
+                               } else {
+                                       $name = strval( $bench['function'] );
+                               }
+                               $name = sprintf( "%s(%s)",
+                                       $name,
+                                       implode( ', ', $bench['args'] )
+                               );
+                       }
+
+                       $normBenchs[$name] = $bench;
+               }
+
+               foreach ( $normBenchs as $name => $bench ) {
                        // Optional setup called outside time measure
                        if ( isset( $bench['setup'] ) ) {
                                call_user_func( $bench['setup'] );
@@ -81,21 +103,6 @@ abstract class Benchmarker extends Maintenance {
                                $stat->addObservation( $t );
                        }
 
-                       // Name defaults to name of called function
-                       if ( is_string( $key ) ) {
-                               $name = $key;
-                       } else {
-                               if ( is_array( $bench['function'] ) ) {
-                                       $name = get_class( $bench['function'][0] ) . '::' . $bench['function'][1];
-                               } else {
-                                       $name = strval( $bench['function'] );
-                               }
-                               $name = sprintf( "%s(%s)",
-                                       $name,
-                                       implode( ', ', $bench['args'] )
-                               );
-                       }
-
                        $this->addResult( [
                                'name' => $name,
                                'count' => $stat->getCount(),
index 710d54a..3cc5f4a 100644 (file)
@@ -1299,7 +1299,6 @@ return [
        ],
        'mediawiki.ForeignStructuredUpload.BookletLayout' => [
                'scripts' => 'resources/src/mediawiki.ForeignStructuredUpload.BookletLayout/BookletLayout.js',
-               'styles' => 'resources/src/mediawiki.ForeignStructuredUpload.BookletLayout/BookletLayout.less',
                'dependencies' => [
                        'mediawiki.ForeignStructuredUpload',
                        'mediawiki.Upload.BookletLayout',
index 186ad17..3823395 100644 (file)
 
                // If the first argument is the function,
                // set filterFn to the first argument's value and ignore the second argument.
-               if ( $.isFunction( limit ) ) {
+               if ( typeof limit === 'function' ) {
                        filterFn = limit;
                        limit = undefined;
                // Either way, verify it is a function so we don't have to call
                // isFunction again after this.
-               } else if ( !filterFn || !$.isFunction( filterFn ) ) {
+               } else if ( !filterFn || typeof filterFn !== 'function' ) {
                        filterFn = undefined;
                }
 
index 39c601f..35c6a5d 100644 (file)
@@ -6,10 +6,6 @@
  *             $( '#textbox' ).suggestions( { option1: value1, option2: value2 } );
  *             $( '#textbox' ).suggestions( option, value );
  *
- * Get option:
- *
- *             value = $( '#textbox' ).suggestions( option );
- *
  * Initialize:
  *
  *             $( '#textbox' ).suggestions();
                        if ( context.data.timerID !== null ) {
                                clearTimeout( context.data.timerID );
                        }
-                       if ( $.isFunction( context.config.cancel ) ) {
+                       if ( typeof context.config.cancel === 'function' ) {
                                context.config.cancel.call( context.data.$textbox );
                        }
                },
 
        // See file header for method documentation
        $.fn.suggestions = function () {
-
                // Multi-context fields
-               var returnValue,
-                       args = arguments;
+               var args = arguments;
 
                $( this ).each( function () {
                        var context, key;
                                        if ( args.length > 1 ) {
                                                // Set property values
                                                $.suggestions.configure( context, args[ 0 ], args[ 1 ] );
-                                       } else if ( returnValue === null || returnValue === undefined ) {
-                                               // Get property values, but don't give access to internal data - returns only the first
-                                               returnValue = ( args[ 0 ] in context.config ? undefined : context.config[ args[ 0 ] ] );
                                        }
                                }
                        }
                        // Store the context for next time
                        $( this ).data( 'suggestions-context', context );
                } );
-               return returnValue !== undefined ? returnValue : $( this );
+               return this;
        };
 
        /**
index d38adcd..ae1b590 100644 (file)
 
                // These elements are filled with text in #initialize
                // TODO Refactor this to be in one place
-               this.$ownWorkMessage = $( '<p>' )
-                       .addClass( 'mw-foreignStructuredUpload-bookletLayout-license' );
+               this.$ownWorkMessage = $( '<p>' );
                this.$notOwnWorkMessage = $( '<p>' );
                this.$notOwnWorkLocal = $( '<p>' );
 
                        } ),
                        new OO.ui.FieldLayout( this.ownWorkCheckbox, {
                                align: 'inline',
-                               label: $( '<div>' ).append(
-                                       $( '<p>' ).text( mw.msg( 'upload-form-label-own-work' ) ),
-                                       this.$ownWorkMessage
-                               )
+                               label: mw.msg( 'upload-form-label-own-work' ),
+                               help: this.$ownWorkMessage,
+                               helpInline: true
                        } ),
                        new OO.ui.FieldLayout( this.messageLabel, {
                                align: 'top'
                this.filenameField = new OO.ui.FieldLayout( this.filenameWidget, {
                        label: mw.msg( 'upload-form-label-infoform-name' ),
                        align: 'top',
-                       classes: [ 'mw-foreignStructuredUploa-bookletLayout-small-notice' ],
-                       notices: [ mw.msg( 'upload-form-label-infoform-name-tooltip' ) ]
+                       help: mw.msg( 'upload-form-label-infoform-name-tooltip' ),
+                       helpInline: true
                } );
                this.descriptionField = new OO.ui.FieldLayout( this.descriptionWidget, {
                        label: mw.msg( 'upload-form-label-infoform-description' ),
                        align: 'top',
-                       classes: [ 'mw-foreignStructuredUploa-bookletLayout-small-notice' ],
-                       notices: [ mw.msg( 'upload-form-label-infoform-description-tooltip' ) ]
+                       help: mw.msg( 'upload-form-label-infoform-description-tooltip' ),
+                       helpInline: true
                } );
                this.categoriesField = new OO.ui.FieldLayout( this.categoriesWidget, {
                        label: mw.msg( 'upload-form-label-infoform-categories' ),
diff --git a/resources/src/mediawiki.ForeignStructuredUpload.BookletLayout/BookletLayout.less b/resources/src/mediawiki.ForeignStructuredUpload.BookletLayout/BookletLayout.less
deleted file mode 100644 (file)
index 24ca434..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-.mw-foreignStructuredUpload-bookletLayout-license {
-       font-size: 90%;
-       line-height: 1.4em;
-       color: #54595d;
-}
-
-.mw-foreignStructuredUploa-bookletLayout-small-notice {
-       .oo-ui-fieldLayout-messages-notice {
-               .oo-ui-iconWidget {
-                       display: none;
-               }
-
-               .oo-ui-labelWidget {
-                       line-height: 1.2em;
-                       font-size: 0.9em;
-                       color: #54595d;
-               }
-       }
-}
index ee3bac2..4510b2c 100644 (file)
@@ -47,7 +47,7 @@
                        showEventName += '.' + options.namespace;
                }
 
-               if ( $.isFunction( options.message ) ) {
+               if ( typeof options.message === 'function' ) {
                        message = options.message();
                } else {
                        message = options.message;
index 8157975..2f62371 100644 (file)
@@ -12,7 +12,7 @@
                                        fetch: function ( val ) {
                                                var $el = $( this );
                                                $el.suggestions( 'suggestions',
-                                                       $.grep( $el.data( 'autocomplete' ), function ( v ) {
+                                                       $el.data( 'autocomplete' ).filter( function ( v ) {
                                                                return v.indexOf( val ) === 0;
                                                        } )
                                                );
index b30a30e..cec537f 100644 (file)
                        var module = mw.loader.moduleRegistry[ moduleName ];
 
                        // Grep module's JavaScript
-                       if ( $.isFunction( module.script ) && pattern.test( module.script.toString() ) ) {
+                       if ( typeof module.script === 'function' && pattern.test( module.script.toString() ) ) {
                                return true;
                        }
 
index 437800a..b7fd6fd 100644 (file)
@@ -1,3 +1,4 @@
+/* eslint-disable no-restricted-properties */
 /*!
 * Experimental advanced wikitext parser-emitter.
 * See: https://www.mediawiki.org/wiki/Extension:UploadWizard/MessageParser for docs
@@ -20,7 +21,7 @@
                        },
                        // Whitelist for allowed HTML elements in wikitext.
                        // Self-closing tags are not currently supported.
-                       // Can be populated via setPrivateData().
+                       // Can be populated via setParserDefaults().
                        allowedHtmlElements: [],
                        // Key tag name, value allowed attributes for that tag.
                        // See Sanitizer::setupAttributeWhitelist
index b96bebc..cb4edc1 100644 (file)
@@ -1,3 +1,4 @@
+/* eslint-disable no-restricted-properties */
 ( function ( mw, $ ) {
        var ProtectionForm,
                reasonCodePointLimit = mw.config.get( 'wgCommentCodePointLimit' ),
index e7859cf..bd94f29 100644 (file)
@@ -1,3 +1,4 @@
+/* eslint-disable no-restricted-properties */
 /*!
  * Add search suggestions to the search form.
  */
index 7c0d232..52abb30 100644 (file)
@@ -1,3 +1,4 @@
+/* eslint-disable no-restricted-properties */
 ( function ( $, mw, OO ) {
        'use strict';
        var ApiSandbox, Util, WidgetMethods, Validators,
index 99e9dbe..43f0552 100644 (file)
@@ -19,7 +19,7 @@
                                auprefix: userInput[ 0 ].toUpperCase() + userInput.slice( 1 ),
                                aulimit: maxRows
                        } ).done( function ( data ) {
-                               var users = $.map( data.query.allusers, function ( userObj ) {
+                               var users = data.query.allusers.map( function ( userObj ) {
                                        return userObj.name;
                                } );
                                response( users );
index 6ee9595..44a7d61 100644 (file)
                                // Workaround T97096 by setting uselang=content
                                uselang: 'content'
                        } ).then( function ( data ) {
-                               return $.map( data.query.interwikimap, function ( interwiki ) {
+                               return data.query.interwikimap.map( function ( interwiki ) {
                                        return interwiki.prefix;
                                } );
                        } );
index 2f7a6c8..6972165 100644 (file)
@@ -947,7 +947,9 @@ abstract class MediaWikiTestCase extends PHPUnit\Framework\TestCase {
         * @return MediaWikiServices
         * @throws MWException
         */
-       protected function overrideMwServices( Config $configOverrides = null, array $services = [] ) {
+       protected static function overrideMwServices(
+               Config $configOverrides = null, array $services = []
+       ) {
                if ( !$configOverrides ) {
                        $configOverrides = new HashConfig();
                }
index 3c8fa25..dc32a6f 100644 (file)
@@ -785,6 +785,45 @@ class HtmlTest extends MediaWikiTestCase {
        public function testSrcSet( $images, $expected, $message ) {
                $this->assertEquals( Html::srcSet( $images ), $expected, $message );
        }
+
+       public static function provideInlineScript() {
+               return [
+                       'Empty' => [
+                               '',
+                               '<script></script>'
+                       ],
+                       'Simple' => [
+                               'EXAMPLE.label("foo");',
+                               '<script>EXAMPLE.label("foo");</script>'
+                       ],
+                       'Ampersand' => [
+                               'EXAMPLE.is(a && b);',
+                               '<script>/*<![CDATA[*/EXAMPLE.is(a && b);/*]]>*/</script>'
+                       ],
+                       'HTML' => [
+                               'EXAMPLE.label("<a>");',
+                               '<script>/*<![CDATA[*/EXAMPLE.label("<a>");/*]]>*/</script>'
+                       ],
+                       'Script closing string' => [
+                               'EXAMPLE.label("</script>");',
+                               // Broken: First </script> ends the script in HTML
+                               '<script>/*<![CDATA[*/EXAMPLE.label("</script>");/*]]>*/</script>'
+                       ],
+                       'CDATA string' => [
+                               'EXAMPLE.label("&> CDATA ]]>");',
+                               // Broken: Works in HTML, but is invalid XML.
+                               '<script>/*<![CDATA[*/EXAMPLE.label("&> CDATA ]]>");/*]]>*/</script>'
+                       ],
+               ];
+       }
+
+       /**
+        * @dataProvider provideInlineScript
+        * @covers Html::inlineScript
+        */
+       public function testInlineScript( $code, $expected ) {
+               $this->assertSame( Html::inlineScript( $code ), $expected );
+       }
 }
 
 class HtmlTestValue {
index 5606924..0e35767 100644 (file)
@@ -61,7 +61,7 @@ class PrefixSearchTest extends MediaWikiLangTestCase {
                $this->originalHandlers = TestingAccessWrapper::newFromClass( Hooks::class )->handlers;
                TestingAccessWrapper::newFromClass( Hooks::class )->handlers = [];
 
-               SpecialPageFactory::resetList();
+               $this->overrideMwServices();
        }
 
        public function tearDown() {
@@ -69,7 +69,7 @@ class PrefixSearchTest extends MediaWikiLangTestCase {
 
                TestingAccessWrapper::newFromClass( Hooks::class )->handlers = $this->originalHandlers;
 
-               SpecialPageFactory::resetList();
+               $this->overrideMwServices();
        }
 
        protected function searchProvision( array $results = null ) {
index 83df61a..41c1218 100644 (file)
@@ -69,7 +69,7 @@ class SearchEnginePrefixTest extends MediaWikiLangTestCase {
                $this->originalHandlers = TestingAccessWrapper::newFromClass( Hooks::class )->handlers;
                TestingAccessWrapper::newFromClass( Hooks::class )->handlers = [];
 
-               SpecialPageFactory::resetList();
+               $this->overrideMwServices();
        }
 
        public function tearDown() {
@@ -77,7 +77,7 @@ class SearchEnginePrefixTest extends MediaWikiLangTestCase {
 
                TestingAccessWrapper::newFromClass( Hooks::class )->handlers = $this->originalHandlers;
 
-               SpecialPageFactory::resetList();
+               $this->overrideMwServices();
        }
 
        protected function searchProvision( array $results = null ) {
index 1da6fb3..04a89d2 100644 (file)
@@ -21,22 +21,10 @@ use Wikimedia\ScopedCallback;
  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  * http://www.gnu.org/copyleft/gpl.html
  *
- * @covers SpecialPageFactory
+ * @covers \MediaWiki\Special\SpecialPageFactory
  * @group SpecialPage
  */
 class SpecialPageFactoryTest extends MediaWikiTestCase {
-
-       protected function tearDown() {
-               parent::tearDown();
-
-               SpecialPageFactory::resetList();
-       }
-
-       public function testResetList() {
-               SpecialPageFactory::resetList();
-               $this->assertContains( 'Specialpages', SpecialPageFactory::getNames() );
-       }
-
        public function testHookNotCalledTwice() {
                $count = 0;
                $this->mergeMwGlobalArrayValue( 'wgHooks', [
@@ -45,9 +33,10 @@ class SpecialPageFactoryTest extends MediaWikiTestCase {
                                        $count++;
                                }
                ] ] );
-               SpecialPageFactory::resetList();
-               SpecialPageFactory::getNames();
-               SpecialPageFactory::getNames();
+               $this->overrideMwServices();
+               $spf = MediaWikiServices::getInstance()->getSpecialPageFactory();
+               $spf->getNames();
+               $spf->getNames();
                $this->assertEquals( 1, $count );
        }
 
@@ -82,7 +71,7 @@ class SpecialPageFactoryTest extends MediaWikiTestCase {
         */
        public function testGetPage( $spec, $shouldReuseInstance ) {
                $this->mergeMwGlobalArrayValue( 'wgSpecialPages', [ 'testdummy' => $spec ] );
-               SpecialPageFactory::resetList();
+               $this->overrideMwServices();
 
                $page = SpecialPageFactory::getPage( 'testdummy' );
                $this->assertInstanceOf( SpecialPage::class, $page );
@@ -96,7 +85,7 @@ class SpecialPageFactoryTest extends MediaWikiTestCase {
         */
        public function testGetNames() {
                $this->mergeMwGlobalArrayValue( 'wgSpecialPages', [ 'testdummy' => SpecialAllPages::class ] );
-               SpecialPageFactory::resetList();
+               $this->overrideMwServices();
 
                $names = SpecialPageFactory::getNames();
                $this->assertInternalType( 'array', $names );
@@ -108,7 +97,7 @@ class SpecialPageFactoryTest extends MediaWikiTestCase {
         */
        public function testResolveAlias() {
                $this->setContentLang( 'de' );
-               SpecialPageFactory::resetList();
+               $this->overrideMwServices();
 
                list( $name, $param ) = SpecialPageFactory::resolveAlias( 'Spezialseiten/Foo' );
                $this->assertEquals( 'Specialpages', $name );
@@ -120,7 +109,7 @@ class SpecialPageFactoryTest extends MediaWikiTestCase {
         */
        public function testGetLocalNameFor() {
                $this->setContentLang( 'de' );
-               SpecialPageFactory::resetList();
+               $this->overrideMwServices();
 
                $name = SpecialPageFactory::getLocalNameFor( 'Specialpages', 'Foo' );
                $this->assertEquals( 'Spezialseiten/Foo', $name );
@@ -131,7 +120,7 @@ class SpecialPageFactoryTest extends MediaWikiTestCase {
         */
        public function testGetTitleForAlias() {
                $this->setContentLang( 'de' );
-               SpecialPageFactory::resetList();
+               $this->overrideMwServices();
 
                $title = SpecialPageFactory::getTitleForAlias( 'Specialpages/Foo' );
                $this->assertEquals( 'Spezialseiten/Foo', $title->getText() );
@@ -146,11 +135,11 @@ class SpecialPageFactoryTest extends MediaWikiTestCase {
        ) {
                $lang = clone MediaWikiServices::getInstance()->getContentLanguage();
                $lang->mExtendedSpecialPageAliases = $aliasesList;
-               $this->setContentLang( $lang );
                $this->setMwGlobals( 'wgSpecialPages',
                        array_combine( array_keys( $aliasesList ), array_keys( $aliasesList ) )
                );
-               SpecialPageFactory::resetList();
+               $this->overrideMwServices();
+               $this->setContentLang( $lang );
 
                // Catch the warnings we expect to be raised
                $warnings = [];
@@ -278,7 +267,7 @@ class SpecialPageFactoryTest extends MediaWikiTestCase {
                                }
                        ],
                ] );
-               SpecialPageFactory::resetList();
+               $this->overrideMwServices();
                SpecialPageFactory::getLocalNameFor( 'Specialpages' );
                $this->assertTrue( $called, 'Recursive call succeeded' );
        }
index f3f5a3f..296ee60 100644 (file)
@@ -1,32 +1,61 @@
 <?php
-/**
- * Based on LanguagMlTest
- * @file
- */
 
 /**
  * @covers LanguageAr
  */
 class LanguageArTest extends LanguageClassesTestCase {
+
        /**
         * @covers Language::formatNum
-        * @todo split into a test and a dataprovider
+        * @dataProvider provideFormatNum
         */
-       public function testFormatNum() {
-               $this->assertEquals( '١٬٢٣٤٬٥٦٧', $this->getLang()->formatNum( '1234567' ) );
-               $this->assertEquals( '-١٢٫٨٩', $this->getLang()->formatNum( -12.89 ) );
+       public function testFormatNum( $num, $formatted ) {
+               $this->assertEquals( $formatted, $this->getLang()->formatNum( $num ) );
+       }
+
+       public static function provideFormatNum() {
+               return [
+                       [ '1234567', '١٬٢٣٤٬٥٦٧' ],
+                       [ -12.89, '-١٢٫٨٩' ],
+               ];
+       }
+
+       /**
+        * @covers LanguageAr::normalize
+        * @covers Language::normalize
+        * @dataProvider provideNormalize
+        */
+       public function testNormalize( $input, $expected ) {
+               if ( $input === $expected ) {
+                       throw new Exception( 'Expected output must differ.' );
+               }
+
+               $this->setMwGlobals( 'wgFixArabicUnicode', true );
+               $this->assertSame( $expected, $this->getLang()->normalize( $input ), 'ar-normalised form' );
+
+               $this->setMwGlobals( 'wgFixArabicUnicode', false );
+               $this->assertSame( $input, $this->getLang()->normalize( $input ), 'regular normalised form' );
+       }
+
+       public static function provideNormalize() {
+               return [
+                       [
+                               'ﷅ',
+                               'صمم',
+                       ],
+               ];
        }
 
        /**
         * Mostly to test the raw ascii feature.
-        * @dataProvider providerSprintfDate
+        * @dataProvider provideSprintfDate
         * @covers Language::sprintfDate
         */
        public function testSprintfDate( $format, $date, $expected ) {
                $this->assertEquals( $expected, $this->getLang()->sprintfDate( $format, $date ) );
        }
 
-       public static function providerSprintfDate() {
+       public static function provideSprintfDate() {
                return [
                        [
                                'xg "vs" g',
index 673b5c7..59b7ba8 100644 (file)
 class LanguageMlTest extends LanguageClassesTestCase {
 
        /**
-        * @dataProvider providerFormatNum
-        * T31495
+        * @dataProvider provideFormatNum
         * @covers Language::formatNum
         */
        public function testFormatNum( $result, $value ) {
+               // For T31495
                $this->assertEquals( $result, $this->getLang()->formatNum( $value ) );
        }
 
-       public static function providerFormatNum() {
+       public static function provideFormatNum() {
                return [
                        [ '12,34,567', '1234567' ],
                        [ '12,345', '12345' ],
@@ -37,4 +37,30 @@ class LanguageMlTest extends LanguageClassesTestCase {
                        [ '', null ],
                ];
        }
+
+       /**
+        * @covers LanguageMl::normalize
+        * @covers Language::normalize
+        * @dataProvider provideNormalize
+        */
+       public function testNormalize( $input, $expected ) {
+               if ( $input === $expected ) {
+                       throw new Exception( 'Expected output must differ.' );
+               }
+
+               $this->setMwGlobals( 'wgFixMalayalamUnicode', true );
+               $this->assertSame( $expected, $this->getLang()->normalize( $input ), 'ml-normalised form' );
+
+               $this->setMwGlobals( 'wgFixMalayalamUnicode', false );
+               $this->assertSame( $input, $this->getLang()->normalize( $input ), 'regular normalised form' );
+       }
+
+       public static function provideNormalize() {
+               return [
+                       [
+                               'ല്‍',
+                               'ൽ',
+                       ],
+               ];
+       }
 }
index abf1cdd..47dbd2e 100644 (file)
@@ -14,11 +14,11 @@ class SpecialPageFatalTest extends MediaWikiTestCase {
 
        public static function setUpBeforeClass() {
                parent::setUpBeforeClass();
-               SpecialPageFactory::resetList();
+               self::overrideMwServices();
        }
 
        public static function tearDownAfterClass() {
-               SpecialPageFactory::resetList();
+               self::overrideMwServices();
                parent::tearDownAfterClass();
        }
 
index e125b8a..1917674 100644 (file)
@@ -73,6 +73,8 @@
                        <directory suffix=".php">../../maintenance</directory>
                        <exclude>
                                <directory suffix=".php">../../languages/messages</directory>
+                               <file>../../languages/data/normalize-ar.php</file>
+                               <file>../../languages/data/normalize-ml.php</file>
                        </exclude>
                </whitelist>
        </filter>
index 50fd581..e4cf446 100644 (file)
        QUnit.test( 'Match PHP parser', function ( assert ) {
                var tasks;
                mw.messages.set( mw.libs.phpParserData.messages );
-               tasks = $.map( mw.libs.phpParserData.tests, function ( test ) {
+               tasks = mw.libs.phpParserData.tests.map( function ( test ) {
                        var done = assert.async();
                        return function ( next, abort ) {
                                getMwLanguage( test.lang )
index 8a5e68a..f0a3543 100644 (file)
@@ -1,4 +1,4 @@
-( function ( mw, $ ) {
+( function ( mw ) {
        QUnit.module( 'mediawiki.user', QUnit.newMwEnvironment( {
                setup: function () {
                        this.server = this.sandbox.useFakeServer();
@@ -69,7 +69,7 @@
 
                result = mw.user.generateRandomSessionId();
                assert.strictEqual( typeof result, 'string', 'type' );
-               assert.strictEqual( $.trim( result ), result, 'no whitespace at beginning or end' );
+               assert.strictEqual( result.trim(), result, 'no whitespace at beginning or end' );
                assert.strictEqual( result.length, 16, 'size' );
 
                result2 = mw.user.generateRandomSessionId();
@@ -90,7 +90,7 @@
 
                result = mw.user.generateRandomSessionId();
                assert.strictEqual( typeof result, 'string', 'type' );
-               assert.strictEqual( $.trim( result ), result, 'no whitespace at beginning or end' );
+               assert.strictEqual( result.trim(), result, 'no whitespace at beginning or end' );
                assert.strictEqual( result.length, 16, 'size' );
 
                result2 = mw.user.generateRandomSessionId();
                var result = mw.user.sessionId(),
                        result2 = mw.user.sessionId();
                assert.strictEqual( typeof result, 'string', 'type' );
-               assert.strictEqual( $.trim( result ), result, 'no leading or trailing whitespace' );
+               assert.strictEqual( result.trim(), result, 'no leading or trailing whitespace' );
                assert.strictEqual( result2, result, 'retained' );
        } );
-}( mediaWiki, jQuery ) );
+}( mediaWiki ) );