Merge "rdbms: make runOnTransactionIdleCallbacks() reset DBO_TRX on exceptions"
authorjenkins-bot <jenkins-bot@gerrit.wikimedia.org>
Wed, 30 May 2018 21:47:27 +0000 (21:47 +0000)
committerGerrit Code Review <gerrit@wikimedia.org>
Wed, 30 May 2018 21:47:27 +0000 (21:47 +0000)
196 files changed:
.phpcs.xml
RELEASE-NOTES-1.32
autoload.php
docs/skin.txt
includes/AutoLoader.php
includes/DefaultSettings.php
includes/Defines.php
includes/EditPage.php
includes/GlobalFunctions.php
includes/Hooks.php
includes/Message.php
includes/OutputPage.php
includes/Preferences.php
includes/Setup.php
includes/Xml.php
includes/api/ApiBase.php
includes/api/ApiMessage.php
includes/api/ApiMessageTrait.php [new file with mode: 0644]
includes/api/ApiQuery.php
includes/api/ApiQueryUserContribs.php [new file with mode: 0644]
includes/api/ApiQueryUserContributions.php [deleted file]
includes/api/ApiRawMessage.php [new file with mode: 0644]
includes/api/ApiUsageException.php
includes/api/IApiMessage.php [new file with mode: 0644]
includes/api/UsageException.php [new file with mode: 0644]
includes/api/i18n/ar.json
includes/api/i18n/es.json
includes/api/i18n/fr.json
includes/api/i18n/pt.json
includes/api/i18n/ru.json
includes/api/i18n/zh-hant.json
includes/auth/Throttler.php
includes/compat/normal/UtfNormal.php
includes/compat/normal/UtfNormalDefines.php [deleted file]
includes/compat/normal/UtfNormalUtil.php [deleted file]
includes/installer/i18n/ar.json
includes/installer/i18n/ast.json
includes/installer/i18n/ba.json
includes/installer/i18n/be-tarask.json
includes/installer/i18n/bg.json
includes/installer/i18n/bn.json
includes/installer/i18n/br.json
includes/installer/i18n/de.json
includes/installer/i18n/el.json
includes/installer/i18n/es.json
includes/installer/i18n/eu.json
includes/installer/i18n/fa.json
includes/installer/i18n/fi.json
includes/installer/i18n/gl.json
includes/installer/i18n/he.json
includes/installer/i18n/hrx.json
includes/installer/i18n/hsb.json
includes/installer/i18n/hu.json
includes/installer/i18n/ia.json
includes/installer/i18n/id.json
includes/installer/i18n/it.json
includes/installer/i18n/ja.json
includes/installer/i18n/ko.json
includes/installer/i18n/ksh.json
includes/installer/i18n/lb.json
includes/installer/i18n/lij.json
includes/installer/i18n/mk.json
includes/installer/i18n/nap.json
includes/installer/i18n/nl.json
includes/installer/i18n/pl.json
includes/installer/i18n/pt-br.json
includes/installer/i18n/pt.json
includes/installer/i18n/sco.json
includes/installer/i18n/th.json
includes/installer/i18n/uk.json
includes/installer/i18n/vi.json
includes/installer/i18n/yi.json
includes/installer/i18n/zh-hans.json
includes/installer/i18n/zh-hant.json
includes/libs/rdbms/database/DBConnRef.php
includes/libs/rdbms/database/Database.php
includes/libs/rdbms/database/DatabaseMssql.php
includes/libs/rdbms/database/DatabaseMysqlBase.php
includes/libs/rdbms/database/DatabaseMysqli.php
includes/libs/rdbms/database/DatabasePostgres.php
includes/libs/rdbms/database/DatabaseSqlite.php
includes/libs/rdbms/database/IDatabase.php
includes/libs/rdbms/database/resultwrapper/FakeResultWrapper.php
includes/libs/rdbms/database/resultwrapper/ResultWrapper.php
includes/libs/rdbms/encasing/Blob.php
includes/libs/rdbms/exception/DBAccessError.php
includes/libs/rdbms/exception/DBConnectionError.php
includes/libs/rdbms/exception/DBError.php
includes/libs/rdbms/exception/DBExpectedError.php
includes/libs/rdbms/exception/DBQueryError.php
includes/libs/rdbms/exception/DBReadOnlyError.php
includes/libs/rdbms/exception/DBReplicationWaitError.php
includes/libs/rdbms/exception/DBTransactionError.php
includes/libs/rdbms/exception/DBTransactionSizeError.php
includes/libs/rdbms/exception/DBUnexpectedError.php
includes/libs/rdbms/field/Field.php
includes/libs/rdbms/lbfactory/LBFactory.php
includes/libs/rdbms/loadbalancer/LoadBalancer.php
includes/libs/rdbms/loadbalancer/LoadBalancerSingle.php
includes/parser/Parser.php
includes/preferences/DefaultPreferencesFactory.php
includes/preferences/PreferencesFactory.php
includes/resourceloader/ResourceLoader.php
includes/resourceloader/ResourceLoaderFileModule.php
includes/resourceloader/ResourceLoaderLessVarFileModule.php
includes/specials/SpecialCreateAccount.php
includes/specials/SpecialPasswordPolicies.php
includes/specials/SpecialPreferences.php
includes/specials/forms/PreferencesFormLegacy.php
includes/user/User.php
includes/utils/AutoloadGenerator.php
languages/Language.php
languages/classes/LanguageAr.php
languages/classes/LanguageMl.php
languages/data/normalize-ar.php [new file with mode: 0644]
languages/data/normalize-ml.php [new file with mode: 0644]
languages/i18n/ace.json
languages/i18n/as.json
languages/i18n/be-tarask.json
languages/i18n/bn.json
languages/i18n/btm.json [new file with mode: 0644]
languages/i18n/ca.json
languages/i18n/cv.json
languages/i18n/diq.json
languages/i18n/en.json
languages/i18n/es.json
languages/i18n/hak.json
languages/i18n/he.json
languages/i18n/hu.json
languages/i18n/inh.json
languages/i18n/it.json
languages/i18n/ko.json
languages/i18n/lb.json
languages/i18n/lez.json
languages/i18n/lfn.json
languages/i18n/ml.json
languages/i18n/my.json
languages/i18n/nap.json
languages/i18n/nds-nl.json
languages/i18n/nn.json
languages/i18n/oc.json
languages/i18n/pl.json
languages/i18n/pt-br.json
languages/i18n/pt.json
languages/i18n/qqq.json
languages/i18n/roa-tara.json
languages/i18n/ru.json
languages/i18n/sr-ec.json
languages/i18n/sr-el.json
languages/i18n/tr.json
languages/i18n/tt-cyrl.json
languages/i18n/uk.json
languages/i18n/vi.json
languages/i18n/yi.json
languages/i18n/yue.json
languages/i18n/zh-hant.json
maintenance/cleanupTitles.php
maintenance/language/generateNormalizerDataAr.php
maintenance/language/generateNormalizerDataMl.php
resources/Resources.php
resources/src/jquery/jquery.lengthLimit.js
resources/src/mediawiki.Uri/Uri.js
resources/src/mediawiki.action/mediawiki.action.edit.stash.js
resources/src/mediawiki.action/mediawiki.action.edit.styles.less
resources/src/mediawiki.htmlform.ooui.styles.less
resources/src/mediawiki.less/mediawiki.mixins.less
resources/src/mediawiki.page.image.pagination.js
resources/src/mediawiki/mediawiki.base.js [new file with mode: 0644]
resources/src/mediawiki/mediawiki.js
serialized/.gitignore
serialized/Makefile
serialized/normalize-ar.ser [deleted file]
serialized/normalize-ml.ser [deleted file]
tests/parser/ParserTestRunner.php
tests/parser/parserTests.txt
tests/phpunit/data/autoloader/psr4/TestFooBar.php [new file with mode: 0644]
tests/phpunit/data/registration/good.json
tests/phpunit/includes/AutoLoaderTest.php [new file with mode: 0644]
tests/phpunit/includes/HooksTest.php
tests/phpunit/includes/XmlTest.php
tests/phpunit/includes/api/ApiBaseTest.php
tests/phpunit/includes/api/ApiEditPageTest.php
tests/phpunit/includes/api/format/ApiFormatXmlTest.php
tests/phpunit/includes/api/query/ApiQueryUserContribsTest.php [new file with mode: 0644]
tests/phpunit/includes/api/query/ApiQueryUserContributionsTest.php [deleted file]
tests/phpunit/includes/auth/ThrottlerTest.php
tests/phpunit/includes/libs/rdbms/database/DatabaseSQLTest.php
tests/phpunit/includes/preferences/DefaultPreferencesFactoryTest.php
tests/phpunit/includes/registration/ExtensionRegistryTest.php
tests/phpunit/includes/resourceloader/ResourceLoaderTest.php
tests/phpunit/includes/user/UserTest.php
tests/phpunit/maintenance/deleteAutoPatrolLogsTest.php
tests/phpunit/structure/AutoLoaderStructureTest.php [new file with mode: 0644]
tests/phpunit/structure/AutoLoaderTest.php [deleted file]
tests/qunit/QUnitTestResources.php
tests/qunit/suites/resources/mediawiki.widgets/MediaSearch/mediawiki.widgets.APIResultsQueue.test.js [new file with mode: 0644]

index d22bfae..14bb494 100644 (file)
@@ -72,9 +72,6 @@
                        Whitelist existing violations, but enable the sniff to prevent
                        any new occurrences.
                -->
-               <exclude-pattern>*/includes/api/ApiQueryUserContributions\.php</exclude-pattern>
-               <exclude-pattern>*/includes/api/ApiMessage\.php</exclude-pattern>
-               <exclude-pattern>*/includes/api/ApiUsageException\.php</exclude-pattern>
                <exclude-pattern>*/includes/media/XCF\.php</exclude-pattern>
                <exclude-pattern>*/includes/Feed\.php</exclude-pattern>
                <exclude-pattern>*/includes/libs/xmp/XMP\.php</exclude-pattern>
index 146bcc6..3d193d4 100644 (file)
@@ -21,6 +21,9 @@ production.
   adds a defense-in-depth feature to stop an attacker who has found a bug in
   the parser allowing them to insert malicious attributes. Disabled by default,
   you can configure this via $wgCSPHeader and $wgCSPReportOnlyHeader.
+* New configuration variable has been added: $wgCookieSetOnIpBlock.
+  This determines whether to set a cookie when an IP user is blocked. Doing so means
+  that a blocked user, even after moving to a new IP address, will still be blocked.
 
 === New features in 1.32 ===
 * (T112474) Generalized the ResourceLoader mechanism for overriding modules
@@ -28,6 +31,8 @@ production.
 * Added 'ApiParseMakeOutputPage' hook.
 * (T174313) Added checkbox on Special:ListUsers to display only users in
   temporary user groups.
+* (T152462) A cookie can now be set when an IP user is blocked to track that user if
+  they move to a new IP address. This is disabled by default.
 
 === External library changes in 1.32 ===
 * …
@@ -113,6 +118,14 @@ because of Phabricator reports.
   any HTMLForm object rather than PreferencesForm.
 * The non namespaced TimestampException class, deprecated in 1.29, was removed.
   Use Wikimedia\Timestamp\TimestampException instead.
+* The global functions codepointToUtf8, hexSequenceToUtf8, utf8ToHexSequence,
+  utf8ToCodepoint, and escapeSingleString (deprecated in 1.25) were removed.
+  The UtfNormal\Utils class from the utfnormal library should be used instead.
+* The deprecated UTF8_ and UNICODE_ constants were removed. The class constants
+  from the UtfNormal\Constants class from the utfnormal library should be used
+* (T140807) The wgResourceLoaderLESSImportPaths configuration option was removed
+  from ResourceLoader. Instead, use `@import` statements in LESS to import
+  files directly from nearby directories within the same project.
 
 === Deprecations in 1.32 ===
 * Use of a StartProfiler.php file is deprecated in favour of placing
@@ -139,6 +152,8 @@ because of Phabricator reports.
   with the 'unwatch' action parameter instead.
 * IcuCollation::getICUVersion() is deprecated, as you can just use the PHP
   constant INTL_ICU_VERSION directly in all versions that MediaWiki supports.
+* Parser::fetchFile() is deprecated. Use ::fetchFileAndTitle() instead.
+* The ApiQueryContributions class has been renamed to ApiQueryUserContribs.
 
 === Other changes in 1.32 ===
 * Soft hyphens (U+00AD) are now automatically removed from titles; these
index 97c5b15..77144df 100644 (file)
@@ -64,7 +64,7 @@ $wgAutoloadLocalClasses = [
        'ApiManageTags' => __DIR__ . '/includes/api/ApiManageTags.php',
        'ApiMergeHistory' => __DIR__ . '/includes/api/ApiMergeHistory.php',
        'ApiMessage' => __DIR__ . '/includes/api/ApiMessage.php',
-       'ApiMessageTrait' => __DIR__ . '/includes/api/ApiMessage.php',
+       'ApiMessageTrait' => __DIR__ . '/includes/api/ApiMessageTrait.php',
        'ApiModuleManager' => __DIR__ . '/includes/api/ApiModuleManager.php',
        'ApiMove' => __DIR__ . '/includes/api/ApiMove.php',
        'ApiOpenSearch' => __DIR__ . '/includes/api/ApiOpenSearch.php',
@@ -93,7 +93,7 @@ $wgAutoloadLocalClasses = [
        'ApiQueryCategories' => __DIR__ . '/includes/api/ApiQueryCategories.php',
        'ApiQueryCategoryInfo' => __DIR__ . '/includes/api/ApiQueryCategoryInfo.php',
        'ApiQueryCategoryMembers' => __DIR__ . '/includes/api/ApiQueryCategoryMembers.php',
-       'ApiQueryContributions' => __DIR__ . '/includes/api/ApiQueryUserContributions.php',
+       'ApiQueryContributions' => __DIR__ . '/includes/api/ApiQueryUserContribs.php',
        'ApiQueryContributors' => __DIR__ . '/includes/api/ApiQueryContributors.php',
        'ApiQueryDeletedRevisions' => __DIR__ . '/includes/api/ApiQueryDeletedRevisions.php',
        'ApiQueryDeletedrevs' => __DIR__ . '/includes/api/ApiQueryDeletedrevs.php',
@@ -129,11 +129,12 @@ $wgAutoloadLocalClasses = [
        'ApiQueryStashImageInfo' => __DIR__ . '/includes/api/ApiQueryStashImageInfo.php',
        'ApiQueryTags' => __DIR__ . '/includes/api/ApiQueryTags.php',
        'ApiQueryTokens' => __DIR__ . '/includes/api/ApiQueryTokens.php',
+       'ApiQueryUserContribs' => __DIR__ . '/includes/api/ApiQueryUserContribs.php',
        'ApiQueryUserInfo' => __DIR__ . '/includes/api/ApiQueryUserInfo.php',
        'ApiQueryUsers' => __DIR__ . '/includes/api/ApiQueryUsers.php',
        'ApiQueryWatchlist' => __DIR__ . '/includes/api/ApiQueryWatchlist.php',
        'ApiQueryWatchlistRaw' => __DIR__ . '/includes/api/ApiQueryWatchlistRaw.php',
-       'ApiRawMessage' => __DIR__ . '/includes/api/ApiMessage.php',
+       'ApiRawMessage' => __DIR__ . '/includes/api/ApiRawMessage.php',
        'ApiRemoveAuthenticationData' => __DIR__ . '/includes/api/ApiRemoveAuthenticationData.php',
        'ApiResetPassword' => __DIR__ . '/includes/api/ApiResetPassword.php',
        'ApiResult' => __DIR__ . '/includes/api/ApiResult.php',
@@ -624,7 +625,7 @@ $wgAutoloadLocalClasses = [
        'Http' => __DIR__ . '/includes/http/Http.php',
        'HttpError' => __DIR__ . '/includes/exception/HttpError.php',
        'HttpStatus' => __DIR__ . '/includes/libs/HttpStatus.php',
-       'IApiMessage' => __DIR__ . '/includes/api/ApiMessage.php',
+       'IApiMessage' => __DIR__ . '/includes/api/IApiMessage.php',
        'IBufferingStatsdDataFactory' => __DIR__ . '/includes/libs/stats/IBufferingStatsdDataFactory.php',
        'ICacheHelper' => __DIR__ . '/includes/cache/CacheHelper.php',
        'IContextSource' => __DIR__ . '/includes/context/IContextSource.php',
@@ -917,72 +918,10 @@ $wgAutoloadLocalClasses = [
        'MediaWiki\\Logger\\Spi' => __DIR__ . '/includes/debug/logger/Spi.php',
        'MediaWiki\\MediaWikiServices' => __DIR__ . '/includes/MediaWikiServices.php',
        'MediaWiki\\OutputHandler' => __DIR__ . '/includes/OutputHandler.php',
-       'MediaWiki\\Preferences\\DefaultPreferencesFactory' => __DIR__ . '/includes/preferences/DefaultPreferencesFactory.php',
-       'MediaWiki\\Preferences\\PreferencesFactory' => __DIR__ . '/includes/preferences/PreferencesFactory.php',
        'MediaWiki\\ProcOpenError' => __DIR__ . '/includes/exception/ProcOpenError.php',
        'MediaWiki\\Search\\ParserOutputSearchDataExtractor' => __DIR__ . '/includes/search/ParserOutputSearchDataExtractor.php',
-       'MediaWiki\\Services\\CannotReplaceActiveServiceException' => __DIR__ . '/includes/services/CannotReplaceActiveServiceException.php',
-       'MediaWiki\\Services\\ContainerDisabledException' => __DIR__ . '/includes/services/ContainerDisabledException.php',
-       'MediaWiki\\Services\\DestructibleService' => __DIR__ . '/includes/services/DestructibleService.php',
-       'MediaWiki\\Services\\NoSuchServiceException' => __DIR__ . '/includes/services/NoSuchServiceException.php',
-       'MediaWiki\\Services\\SalvageableService' => __DIR__ . '/includes/services/SalvageableService.php',
-       'MediaWiki\\Services\\ServiceAlreadyDefinedException' => __DIR__ . '/includes/services/ServiceAlreadyDefinedException.php',
-       'MediaWiki\\Services\\ServiceContainer' => __DIR__ . '/includes/services/ServiceContainer.php',
-       'MediaWiki\\Services\\ServiceDisabledException' => __DIR__ . '/includes/services/ServiceDisabledException.php',
-       'MediaWiki\\Session\\BotPasswordSessionProvider' => __DIR__ . '/includes/session/BotPasswordSessionProvider.php',
-       'MediaWiki\\Session\\CookieSessionProvider' => __DIR__ . '/includes/session/CookieSessionProvider.php',
-       'MediaWiki\\Session\\ImmutableSessionProviderWithCookie' => __DIR__ . '/includes/session/ImmutableSessionProviderWithCookie.php',
-       'MediaWiki\\Session\\MetadataMergeException' => __DIR__ . '/includes/session/MetadataMergeException.php',
-       'MediaWiki\\Session\\PHPSessionHandler' => __DIR__ . '/includes/session/PHPSessionHandler.php',
-       'MediaWiki\\Session\\Session' => __DIR__ . '/includes/session/Session.php',
-       'MediaWiki\\Session\\SessionBackend' => __DIR__ . '/includes/session/SessionBackend.php',
-       'MediaWiki\\Session\\SessionId' => __DIR__ . '/includes/session/SessionId.php',
-       'MediaWiki\\Session\\SessionInfo' => __DIR__ . '/includes/session/SessionInfo.php',
-       'MediaWiki\\Session\\SessionManager' => __DIR__ . '/includes/session/SessionManager.php',
-       'MediaWiki\\Session\\SessionManagerInterface' => __DIR__ . '/includes/session/SessionManagerInterface.php',
-       'MediaWiki\\Session\\SessionProvider' => __DIR__ . '/includes/session/SessionProvider.php',
-       'MediaWiki\\Session\\SessionProviderInterface' => __DIR__ . '/includes/session/SessionProviderInterface.php',
-       'MediaWiki\\Session\\Token' => __DIR__ . '/includes/session/Token.php',
-       'MediaWiki\\Session\\UserInfo' => __DIR__ . '/includes/session/UserInfo.php',
        'MediaWiki\\ShellDisabledError' => __DIR__ . '/includes/exception/ShellDisabledError.php',
-       'MediaWiki\\Shell\\Command' => __DIR__ . '/includes/shell/Command.php',
-       'MediaWiki\\Shell\\CommandFactory' => __DIR__ . '/includes/shell/CommandFactory.php',
-       'MediaWiki\\Shell\\FirejailCommand' => __DIR__ . '/includes/shell/FirejailCommand.php',
-       'MediaWiki\\Shell\\Result' => __DIR__ . '/includes/shell/Result.php',
-       'MediaWiki\\Shell\\Shell' => __DIR__ . '/includes/shell/Shell.php',
        'MediaWiki\\Site\\MediaWikiPageNameNormalizer' => __DIR__ . '/includes/site/MediaWikiPageNameNormalizer.php',
-       'MediaWiki\\Sparql\\SparqlClient' => __DIR__ . '/includes/sparql/SparqlClient.php',
-       'MediaWiki\\Sparql\\SparqlException' => __DIR__ . '/includes/sparql/SparqlException.php',
-       'MediaWiki\\Storage\\BlobAccessException' => __DIR__ . '/includes/Storage/BlobAccessException.php',
-       'MediaWiki\\Storage\\BlobStore' => __DIR__ . '/includes/Storage/BlobStore.php',
-       'MediaWiki\\Storage\\BlobStoreFactory' => __DIR__ . '/includes/Storage/BlobStoreFactory.php',
-       'MediaWiki\\Storage\\IncompleteRevisionException' => __DIR__ . '/includes/Storage/IncompleteRevisionException.php',
-       'MediaWiki\\Storage\\MutableRevisionRecord' => __DIR__ . '/includes/Storage/MutableRevisionRecord.php',
-       'MediaWiki\\Storage\\MutableRevisionSlots' => __DIR__ . '/includes/Storage/MutableRevisionSlots.php',
-       'MediaWiki\\Storage\\NameTableAccessException' => __DIR__ . '/includes/Storage/NameTableAccessException.php',
-       'MediaWiki\\Storage\\NameTableStore' => __DIR__ . '/includes/Storage/NameTableStore.php',
-       'MediaWiki\\Storage\\RevisionAccessException' => __DIR__ . '/includes/Storage/RevisionAccessException.php',
-       'MediaWiki\\Storage\\RevisionArchiveRecord' => __DIR__ . '/includes/Storage/RevisionArchiveRecord.php',
-       'MediaWiki\\Storage\\RevisionFactory' => __DIR__ . '/includes/Storage/RevisionFactory.php',
-       'MediaWiki\\Storage\\RevisionLookup' => __DIR__ . '/includes/Storage/RevisionLookup.php',
-       'MediaWiki\\Storage\\RevisionRecord' => __DIR__ . '/includes/Storage/RevisionRecord.php',
-       'MediaWiki\\Storage\\RevisionSlots' => __DIR__ . '/includes/Storage/RevisionSlots.php',
-       'MediaWiki\\Storage\\RevisionSlotsUpdate' => __DIR__ . '/includes/Storage/RevisionSlotsUpdate.php',
-       'MediaWiki\\Storage\\RevisionStore' => __DIR__ . '/includes/Storage/RevisionStore.php',
-       'MediaWiki\\Storage\\RevisionStoreRecord' => __DIR__ . '/includes/Storage/RevisionStoreRecord.php',
-       'MediaWiki\\Storage\\SlotRecord' => __DIR__ . '/includes/Storage/SlotRecord.php',
-       'MediaWiki\\Storage\\SqlBlobStore' => __DIR__ . '/includes/Storage/SqlBlobStore.php',
-       'MediaWiki\\Storage\\SuppressedDataException' => __DIR__ . '/includes/Storage/SuppressedDataException.php',
-       'MediaWiki\\Tidy\\RaggettBase' => __DIR__ . '/includes/tidy/RaggettBase.php',
-       'MediaWiki\\Tidy\\RaggettExternal' => __DIR__ . '/includes/tidy/RaggettExternal.php',
-       'MediaWiki\\Tidy\\RaggettInternalHHVM' => __DIR__ . '/includes/tidy/RaggettInternalHHVM.php',
-       'MediaWiki\\Tidy\\RaggettInternalPHP' => __DIR__ . '/includes/tidy/RaggettInternalPHP.php',
-       'MediaWiki\\Tidy\\RaggettWrapper' => __DIR__ . '/includes/tidy/RaggettWrapper.php',
-       'MediaWiki\\Tidy\\RemexCompatFormatter' => __DIR__ . '/includes/tidy/RemexCompatFormatter.php',
-       'MediaWiki\\Tidy\\RemexCompatMunger' => __DIR__ . '/includes/tidy/RemexCompatMunger.php',
-       'MediaWiki\\Tidy\\RemexDriver' => __DIR__ . '/includes/tidy/RemexDriver.php',
-       'MediaWiki\\Tidy\\RemexMungerData' => __DIR__ . '/includes/tidy/RemexMungerData.php',
-       'MediaWiki\\Tidy\\TidyDriverBase' => __DIR__ . '/includes/tidy/TidyDriverBase.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',
@@ -1598,7 +1537,7 @@ $wgAutoloadLocalClasses = [
        'UploadStashWrongOwnerException' => __DIR__ . '/includes/upload/UploadStash.php',
        'UploadStashZeroLengthFileException' => __DIR__ . '/includes/upload/UploadStash.php',
        'UppercaseCollation' => __DIR__ . '/includes/collation/UppercaseCollation.php',
-       'UsageException' => __DIR__ . '/includes/api/ApiUsageException.php',
+       'UsageException' => __DIR__ . '/includes/api/UsageException.php',
        'User' => __DIR__ . '/includes/user/User.php',
        'UserArray' => __DIR__ . '/includes/user/UserArray.php',
        'UserArrayFromResult' => __DIR__ . '/includes/user/UserArrayFromResult.php',
index 0b4e0bd..8dff602 100644 (file)
@@ -58,7 +58,7 @@ These can also be customised on a per-user basis, by editing
 
 Several custom skins are available as of 2014.
 
-https://www.mediawiki.org/wiki/Category:All_skins
+https://www.mediawiki.org/wiki/Special:MyLanguage/Category:All_skins
 
 Installing a skin requires adding its files in a subdirectory under skins/ and
 adding an appropriate require_once line to LocalSettings.php, similarly to how
index f1a8945..9fc063a 100644 (file)
@@ -123,6 +123,7 @@ class AutoLoader {
         *
         * @see <http://www.php-fig.org/psr/psr-4/>
         * @private Only public for usage in AutoloadGenerator
+        * @codeCoverageIgnore
         * @since 1.31
         * @return string[]
         */
@@ -131,6 +132,13 @@ class AutoLoader {
                        'MediaWiki\\Edit\\' => __DIR__ . '/edit/',
                        'MediaWiki\\EditPage\\' => __DIR__ . '/editpage/',
                        'MediaWiki\\Linker\\' => __DIR__ .'/linker/',
+                       'MediaWiki\\Preferences\\' => __DIR__ .'/preferences/',
+                       'MediaWiki\\Services\\' => __DIR__ .'/services/',
+                       'MediaWiki\\Session\\' => __DIR__ .'/session/',
+                       'MediaWiki\\Shell\\' => __DIR__ .'/shell/',
+                       'MediaWiki\\Sparql\\' => __DIR__ .'/sparql/',
+                       'MediaWiki\\Storage\\' => __DIR__ .'/Storage/',
+                       'MediaWiki\\Tidy\\' => __DIR__ .'/tidy/',
                ];
        }
 }
index 853315f..562d887 100644 (file)
@@ -3778,23 +3778,6 @@ $wgResourceLoaderLESSVars = [
        'deviceWidthTablet' => '720px',
 ];
 
-/**
- * Default import paths for LESS modules. LESS files referenced in @import
- * statements will be looked up here first, and relative to the importing file
- * second. To avoid collisions, it's important for the LESS files in these
- * directories to have a common, predictable file name prefix.
- *
- * Extensions need not (and should not) register paths in
- * $wgResourceLoaderLESSImportPaths. The import path includes the path of the
- * currently compiling LESS file, which allows each extension to freely import
- * files from its own tree.
- *
- * @since 1.22
- */
-$wgResourceLoaderLESSImportPaths = [
-       "$IP/resources/src/mediawiki.less/",
-];
-
 /**
  * Whether ResourceLoader should attempt to persist modules in localStorage on
  * browsers that support the Web Storage API.
@@ -6032,6 +6015,15 @@ $wgSessionName = false;
  */
 $wgCookieSetOnAutoblock = false;
 
+/**
+ * Whether to set a cookie when a logged-out user is blocked. Doing so means that a blocked user,
+ * even after moving to a new IP address, will still be blocked. This cookie will contain an
+ * authentication code if $wgSecretKey is set, or otherwise will just be the block ID (in which
+ * case there is a possibility of an attacker discovering the names of revdeleted users, so it
+ * is best to use this in conjunction with $wgSecretKey being set).
+ */
+$wgCookieSetOnIpBlock = false;
+
 /** @} */ # end of cookie settings }
 
 /************************************************************************//**
index 087af39..e5261e7 100644 (file)
@@ -22,7 +22,6 @@
 
 require_once __DIR__ . '/libs/mime/defines.php';
 require_once __DIR__ . '/libs/rdbms/defines.php';
-require_once __DIR__ . '/compat/normal/UtfNormalDefines.php';
 
 use Wikimedia\Rdbms\IDatabase;
 
index 87fb711..bd44cf7 100644 (file)
@@ -587,6 +587,10 @@ class EditPage {
                $permErrors = $this->getEditPermissionErrors( $this->save ? 'secure' : 'full' );
                if ( $permErrors ) {
                        wfDebug( __METHOD__ . ": User can't edit\n" );
+
+                       // track block with a cookie if it doesn't exists already
+                       $this->context->getUser()->trackBlockWithCookie();
+
                        // Auto-block user's IP if the account was "hard" blocked
                        if ( !wfReadOnly() ) {
                                DeferredUpdates::addCallableUpdate( function () {
index 8c7e52a..6f49a14 100644 (file)
@@ -2670,6 +2670,28 @@ function wfGetPrecompiledData( $name ) {
        return false;
 }
 
+/**
+ * @since 1.32
+ * @param string[] $data Array with string keys/values to export
+ * @param string $header
+ * @return string PHP code
+ */
+function wfMakeStaticArrayFile( array $data, $header = 'Automatically generated' ) {
+       $format = "\t%s => %s,\n";
+       $code = "<?php\n"
+               . "// " . implode( "\n// ", explode( "\n", $header ) ) . "\n"
+               . "return [\n";
+       foreach ( $data as $key => $value ) {
+               $code .= sprintf(
+                       $format,
+                       var_export( $key, true ),
+                       var_export( $value, true )
+               );
+       }
+       $code .= "];\n";
+       return $code;
+}
+
 /**
  * Make a cache key for the local wiki.
  *
index c22dc97..d434120 100644 (file)
@@ -47,10 +47,6 @@ class Hooks {
         * @since 1.18
         */
        public static function register( $name, $callback ) {
-               if ( !isset( self::$handlers[$name] ) ) {
-                       self::$handlers[$name] = [];
-               }
-
                self::$handlers[$name][] = $callback;
        }
 
@@ -62,6 +58,7 @@ class Hooks {
         *
         * @since 1.21
         * @throws MWException If not in testing mode.
+        * @codeCoverageIgnore
         */
        public static function clear( $name ) {
                if ( !defined( 'MW_PHPUNIT_TEST' ) && !defined( 'MW_PARSER_TEST' ) ) {
index 7d05f41..fb6dcc5 100644 (file)
@@ -726,6 +726,8 @@ class Message implements MessageSpecifier, Serializable {
         * @throws MWException
         */
        public function inLanguage( $lang ) {
+               $previousLanguage = $this->language;
+
                if ( $lang instanceof Language ) {
                        $this->language = $lang;
                } elseif ( is_string( $lang ) ) {
@@ -740,7 +742,11 @@ class Message implements MessageSpecifier, Serializable {
                                . "passed a String or Language object; $type given"
                        );
                }
-               $this->message = null;
+
+               if ( $this->language !== $previousLanguage ) {
+                       // The language has changed. Clear the message cache.
+                       $this->message = null;
+               }
                $this->interface = false;
                return $this;
        }
index 7f72d36..564641a 100644 (file)
@@ -2413,10 +2413,6 @@ class OutputPage extends ContextSource {
                $response->header( 'Content-type: ' . $config->get( 'MimeType' ) . '; charset=UTF-8' );
                $response->header( 'Content-language: ' . $wgContLang->getHtmlCode() );
 
-               // Avoid Internet Explorer "compatibility view" in IE 8-10, so that
-               // jQuery etc. can work correctly.
-               $response->header( 'X-UA-Compatible: IE=Edge' );
-
                if ( !$this->mArticleBodyOnly ) {
                        $sk = $this->getSkin();
 
index 035b494..c458af0 100644 (file)
@@ -262,12 +262,12 @@ class Preferences {
         * @param IContextSource $context
         * @param string $formClass
         * @param array $remove Array of items to remove
-        * @return PreferencesForm|HTMLForm
+        * @return PreferencesFormLegacy|HTMLForm
         */
        public static function getFormObject(
                $user,
                IContextSource $context,
-               $formClass = PreferencesForm::class,
+               $formClass = PreferencesFormLegacy::class,
                array $remove = []
        ) {
                $preferencesFactory = self::getDefaultPreferencesFactory();
index 9d7a155..f73e686 100644 (file)
@@ -627,8 +627,6 @@ define( 'MW_SERVICE_BOOTSTRAP_COMPLETE', 1 );
 
 MWExceptionHandler::installHandler();
 
-require_once "$IP/includes/compat/normal/UtfNormalUtil.php";
-
 // T48998: Bail out early if $wgArticlePath is non-absolute
 foreach ( [ 'wgArticlePath', 'wgVariantArticlePath' ] as $varName ) {
        if ( $$varName && !preg_match( '/^(https?:\/\/|\/)/', $$varName ) ) {
index 10d0d8b..4f2720e 100644 (file)
@@ -49,7 +49,7 @@ class Xml {
                        if ( $allowShortTag && $contents === '' ) {
                                $out .= ' />';
                        } else {
-                               $out .= '>' . htmlspecialchars( $contents ) . "</$element>";
+                               $out .= '>' . htmlspecialchars( $contents, ENT_NOQUOTES ) . "</$element>";
                        }
                }
                return $out;
index b18bf58..02a635a 100644 (file)
@@ -761,10 +761,23 @@ abstract class ApiBase extends ContextSource {
         * value - validated value from user or default. limits will not be
         * parsed if $parseLimit is set to false; use this when the max
         * limit is not definitive yet, e.g. when getting revisions.
-        * @param bool $parseLimit True by default
+        * @param bool|array $options If a boolean, uses that as the value for 'parseLimit'
+        *  - parseLimit: (bool, default true) Whether to parse the 'max' value for limit types
+        *  - safeMode: (bool, default false) If true, avoid throwing for parameter validation errors.
+        *    Returned parameter values might be ApiUsageException instances.
         * @return array
         */
-       public function extractRequestParams( $parseLimit = true ) {
+       public function extractRequestParams( $options = [] ) {
+               if ( is_bool( $options ) ) {
+                       $options = [ 'parseLimit' => $options ];
+               }
+               $options += [
+                       'parseLimit' => true,
+                       'safeMode' => false,
+               ];
+
+               $parseLimit = (bool)$options['parseLimit'];
+
                // Cache parameters, for performance and to avoid T26564.
                if ( !isset( $this->mParamCache[$parseLimit] ) ) {
                        $params = $this->getFinalParams() ?: [];
@@ -778,9 +791,13 @@ abstract class ApiBase extends ContextSource {
                                if ( isset( $paramSettings[self::PARAM_TEMPLATE_VARS] ) ) {
                                        $toProcess[] = [ $paramName, $paramSettings[self::PARAM_TEMPLATE_VARS], $paramSettings ];
                                } else {
-                                       $results[$paramName] = $this->getParameterFromSettings(
-                                               $paramName, $paramSettings, $parseLimit
-                                       );
+                                       try {
+                                               $results[$paramName] = $this->getParameterFromSettings(
+                                                       $paramName, $paramSettings, $parseLimit
+                                               );
+                                       } catch ( ApiUsageException $ex ) {
+                                               $results[$paramName] = $ex;
+                                       }
                                }
                        }
 
@@ -826,7 +843,11 @@ abstract class ApiBase extends ContextSource {
 
                                                $newName = str_replace( $placeholder, $value, $name );
                                                if ( !$targets ) {
-                                                       $results[$newName] = $this->getParameterFromSettings( $newName, $settings, $parseLimit );
+                                                       try {
+                                                               $results[$newName] = $this->getParameterFromSettings( $newName, $settings, $parseLimit );
+                                                       } catch ( ApiUsageException $ex ) {
+                                                               $results[$newName] = $ex;
+                                                       }
                                                } else {
                                                        $newTargets = [];
                                                        foreach ( $targets as $k => $v ) {
@@ -842,6 +863,15 @@ abstract class ApiBase extends ContextSource {
                        $this->mParamCache[$parseLimit] = $results;
                }
 
+               $ret = $this->mParamCache[$parseLimit];
+               if ( !$options['safeMode'] ) {
+                       foreach ( $ret as $v ) {
+                               if ( $v instanceof ApiUsageException ) {
+                                       throw $v;
+                               }
+                       }
+               }
+
                return $this->mParamCache[$parseLimit];
        }
 
@@ -852,7 +882,14 @@ abstract class ApiBase extends ContextSource {
         * @return mixed Parameter value
         */
        protected function getParameter( $paramName, $parseLimit = true ) {
-               return $this->extractRequestParams( $parseLimit )[$paramName];
+               $ret = $this->extractRequestParams( [
+                       'parseLimit' => $parseLimit,
+                       'safeMode' => true,
+               ] )[$paramName];
+               if ( $ret instanceof ApiUsageException ) {
+                       throw $ret;
+               }
+               return $ret;
        }
 
        /**
index 3347128..6a8b7d0 100644 (file)
@@ -1,8 +1,5 @@
 <?php
 /**
- * Defines an interface for messages with additional machine-readable data for
- * use by the API, and provides concrete implementations of that interface.
- *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or
  * @file
  */
 
-/**
- * Interface for messages with machine-readable data for use by the API
- *
- * The idea is that it's a Message that has some extra data for the API to use when interpreting it
- * as an error (or, in the future, as a warning). Internals of MediaWiki often use messages (or
- * message keys, or Status objects containing messages) to pass information about errors to the user
- * (see e.g. Title::getUserPermissionsErrors()) and the API has to make do with that.
- *
- * @since 1.25
- * @note This interface exists to work around PHP's inheritance, so ApiMessage
- *  can extend Message and ApiRawMessage can extend RawMessage while still
- *  allowing an instanceof check for a Message object including this
- *  functionality. If for some reason you feel the need to implement this
- *  interface on some other class, that class must also implement all the
- *  public methods the Message class provides (not just those from
- *  MessageSpecifier, which as written is fairly useless).
- * @ingroup API
- */
-interface IApiMessage extends MessageSpecifier {
-       /**
-        * Returns a machine-readable code for use by the API
-        *
-        * If no code was specifically set, the message key is used as the code
-        * after removing "apiwarn-" or "apierror-" prefixes and applying
-        * backwards-compatibility mappings.
-        *
-        * @return string
-        */
-       public function getApiCode();
-
-       /**
-        * Returns additional machine-readable data about the error condition
-        * @return array
-        */
-       public function getApiData();
-
-       /**
-        * Sets the machine-readable code for use by the API
-        * @param string|null $code If null, uses the default (see self::getApiCode())
-        * @param array|null $data If non-null, passed to self::setApiData()
-        */
-       public function setApiCode( $code, array $data = null );
-
-       /**
-        * Sets additional machine-readable data about the error condition
-        * @param array $data
-        */
-       public function setApiData( array $data );
-}
-
-/**
- * Trait to implement the IApiMessage interface for Message subclasses
- * @since 1.27
- * @ingroup API
- */
-trait ApiMessageTrait {
-
-       /**
-        * Compatibility code mappings for various MW messages.
-        * @todo Ideally anything relying on this should be changed to use ApiMessage.
-        */
-       protected static $messageMap = [
-               'actionthrottledtext' => 'ratelimited',
-               'autoblockedtext' => 'autoblocked',
-               'badaccess-group0' => 'permissiondenied',
-               'badaccess-groups' => 'permissiondenied',
-               'badipaddress' => 'invalidip',
-               'blankpage' => 'emptypage',
-               'blockedtext' => 'blocked',
-               'cannotdelete' => 'cantdelete',
-               'cannotundelete' => 'cantundelete',
-               'cantmove-titleprotected' => 'protectedtitle',
-               'cantrollback' => 'onlyauthor',
-               'confirmedittext' => 'confirmemail',
-               'content-not-allowed-here' => 'contentnotallowedhere',
-               'deleteprotected' => 'cantedit',
-               'delete-toobig' => 'bigdelete',
-               'edit-conflict' => 'editconflict',
-               'imagenocrossnamespace' => 'nonfilenamespace',
-               'imagetypemismatch' => 'filetypemismatch',
-               'importbadinterwiki' => 'badinterwiki',
-               'importcantopen' => 'cantopenfile',
-               'import-noarticle' => 'badinterwiki',
-               'importnofile' => 'nofile',
-               'importuploaderrorpartial' => 'partialupload',
-               'importuploaderrorsize' => 'filetoobig',
-               'importuploaderrortemp' => 'notempdir',
-               'ipb_already_blocked' => 'alreadyblocked',
-               'ipb_blocked_as_range' => 'blockedasrange',
-               'ipb_cant_unblock' => 'cantunblock',
-               'ipb_expiry_invalid' => 'invalidexpiry',
-               'ip_range_invalid' => 'invalidrange',
-               'mailnologin' => 'cantsend',
-               'markedaspatrollederror-noautopatrol' => 'noautopatrol',
-               'movenologintext' => 'cantmove-anon',
-               'movenotallowed' => 'cantmove',
-               'movenotallowedfile' => 'cantmovefile',
-               'namespaceprotected' => 'protectednamespace',
-               'nocreate-loggedin' => 'cantcreate',
-               'nocreatetext' => 'cantcreate-anon',
-               'noname' => 'invaliduser',
-               'nosuchusershort' => 'nosuchuser',
-               'notanarticle' => 'missingtitle',
-               'nouserspecified' => 'invaliduser',
-               'ns-specialprotected' => 'unsupportednamespace',
-               'protect-cantedit' => 'cantedit',
-               'protectedinterface' => 'protectednamespace-interface',
-               'protectedpagetext' => 'protectedpage',
-               'range_block_disabled' => 'rangedisabled',
-               'rcpatroldisabled' => 'patroldisabled',
-               'readonlytext' => 'readonly',
-               'sessionfailure' => 'badtoken',
-               'systemblockedtext' => 'blocked',
-               'titleprotected' => 'protectedtitle',
-               'undo-failure' => 'undofailure',
-               'userrights-nodatabase' => 'nosuchdatabase',
-               'userrights-no-interwiki' => 'nointerwikiuserrights',
-       ];
-
-       protected $apiCode = null;
-       protected $apiData = [];
-
-       public function getApiCode() {
-               if ( $this->apiCode === null ) {
-                       $key = $this->getKey();
-                       if ( isset( self::$messageMap[$key] ) ) {
-                               $this->apiCode = self::$messageMap[$key];
-                       } elseif ( $key === 'apierror-missingparam' ) {
-                               /// @todo: Kill this case along with ApiBase::$messageMap
-                               $this->apiCode = 'no' . $this->getParams()[0];
-                       } elseif ( substr( $key, 0, 8 ) === 'apiwarn-' ) {
-                               $this->apiCode = substr( $key, 8 );
-                       } elseif ( substr( $key, 0, 9 ) === 'apierror-' ) {
-                               $this->apiCode = substr( $key, 9 );
-                       } else {
-                               $this->apiCode = $key;
-                       }
-               }
-               return $this->apiCode;
-       }
-
-       public function setApiCode( $code, array $data = null ) {
-               if ( $code !== null && !( is_string( $code ) && $code !== '' ) ) {
-                       throw new InvalidArgumentException( "Invalid code \"$code\"" );
-               }
-
-               $this->apiCode = $code;
-               if ( $data !== null ) {
-                       $this->setApiData( $data );
-               }
-       }
-
-       public function getApiData() {
-               return $this->apiData;
-       }
-
-       public function setApiData( array $data ) {
-               $this->apiData = $data;
-       }
-
-       public function serialize() {
-               return serialize( [
-                       'parent' => parent::serialize(),
-                       'apiCode' => $this->apiCode,
-                       'apiData' => $this->apiData,
-               ] );
-       }
-
-       public function unserialize( $serialized ) {
-               $data = unserialize( $serialized );
-               parent::unserialize( $data['parent'] );
-               $this->apiCode = $data['apiCode'];
-               $this->apiData = $data['apiData'];
-       }
-}
-
 /**
  * Extension of Message implementing IApiMessage
  * @since 1.25
@@ -266,36 +87,3 @@ class ApiMessage extends Message implements IApiMessage {
                $this->setApiCode( $code, $data );
        }
 }
-
-/**
- * Extension of RawMessage implementing IApiMessage
- * @since 1.25
- * @ingroup API
- */
-class ApiRawMessage extends RawMessage implements IApiMessage {
-       use ApiMessageTrait;
-
-       /**
-        * @param RawMessage|string|array $msg
-        *  - RawMessage: is cloned
-        *  - array: first element is $key, rest are $params to RawMessage::__construct
-        *  - string: passed to RawMessage::__construct
-        * @param string|null $code
-        * @param array|null $data
-        */
-       public function __construct( $msg, $code = null, array $data = null ) {
-               if ( $msg instanceof RawMessage ) {
-                       foreach ( get_class_vars( get_class( $this ) ) as $key => $value ) {
-                               if ( isset( $msg->$key ) ) {
-                                       $this->$key = $msg->$key;
-                               }
-                       }
-               } elseif ( is_array( $msg ) ) {
-                       $key = array_shift( $msg );
-                       parent::__construct( $key, $msg );
-               } else {
-                       parent::__construct( $msg );
-               }
-               $this->setApiCode( $code, $data );
-       }
-}
diff --git a/includes/api/ApiMessageTrait.php b/includes/api/ApiMessageTrait.php
new file mode 100644 (file)
index 0000000..18b6bc4
--- /dev/null
@@ -0,0 +1,145 @@
+<?php
+/**
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ */
+
+/**
+ * Trait to implement the IApiMessage interface for Message subclasses
+ * @since 1.27
+ * @ingroup API
+ */
+trait ApiMessageTrait {
+
+       /**
+        * Compatibility code mappings for various MW messages.
+        * @todo Ideally anything relying on this should be changed to use ApiMessage.
+        */
+       protected static $messageMap = [
+               'actionthrottledtext' => 'ratelimited',
+               'autoblockedtext' => 'autoblocked',
+               'badaccess-group0' => 'permissiondenied',
+               'badaccess-groups' => 'permissiondenied',
+               'badipaddress' => 'invalidip',
+               'blankpage' => 'emptypage',
+               'blockedtext' => 'blocked',
+               'cannotdelete' => 'cantdelete',
+               'cannotundelete' => 'cantundelete',
+               'cantmove-titleprotected' => 'protectedtitle',
+               'cantrollback' => 'onlyauthor',
+               'confirmedittext' => 'confirmemail',
+               'content-not-allowed-here' => 'contentnotallowedhere',
+               'deleteprotected' => 'cantedit',
+               'delete-toobig' => 'bigdelete',
+               'edit-conflict' => 'editconflict',
+               'imagenocrossnamespace' => 'nonfilenamespace',
+               'imagetypemismatch' => 'filetypemismatch',
+               'importbadinterwiki' => 'badinterwiki',
+               'importcantopen' => 'cantopenfile',
+               'import-noarticle' => 'badinterwiki',
+               'importnofile' => 'nofile',
+               'importuploaderrorpartial' => 'partialupload',
+               'importuploaderrorsize' => 'filetoobig',
+               'importuploaderrortemp' => 'notempdir',
+               'ipb_already_blocked' => 'alreadyblocked',
+               'ipb_blocked_as_range' => 'blockedasrange',
+               'ipb_cant_unblock' => 'cantunblock',
+               'ipb_expiry_invalid' => 'invalidexpiry',
+               'ip_range_invalid' => 'invalidrange',
+               'mailnologin' => 'cantsend',
+               'markedaspatrollederror-noautopatrol' => 'noautopatrol',
+               'movenologintext' => 'cantmove-anon',
+               'movenotallowed' => 'cantmove',
+               'movenotallowedfile' => 'cantmovefile',
+               'namespaceprotected' => 'protectednamespace',
+               'nocreate-loggedin' => 'cantcreate',
+               'nocreatetext' => 'cantcreate-anon',
+               'noname' => 'invaliduser',
+               'nosuchusershort' => 'nosuchuser',
+               'notanarticle' => 'missingtitle',
+               'nouserspecified' => 'invaliduser',
+               'ns-specialprotected' => 'unsupportednamespace',
+               'protect-cantedit' => 'cantedit',
+               'protectedinterface' => 'protectednamespace-interface',
+               'protectedpagetext' => 'protectedpage',
+               'range_block_disabled' => 'rangedisabled',
+               'rcpatroldisabled' => 'patroldisabled',
+               'readonlytext' => 'readonly',
+               'sessionfailure' => 'badtoken',
+               'systemblockedtext' => 'blocked',
+               'titleprotected' => 'protectedtitle',
+               'undo-failure' => 'undofailure',
+               'userrights-nodatabase' => 'nosuchdatabase',
+               'userrights-no-interwiki' => 'nointerwikiuserrights',
+       ];
+
+       protected $apiCode = null;
+       protected $apiData = [];
+
+       public function getApiCode() {
+               if ( $this->apiCode === null ) {
+                       $key = $this->getKey();
+                       if ( isset( self::$messageMap[$key] ) ) {
+                               $this->apiCode = self::$messageMap[$key];
+                       } elseif ( $key === 'apierror-missingparam' ) {
+                               /// @todo: Kill this case along with ApiBase::$messageMap
+                               $this->apiCode = 'no' . $this->getParams()[0];
+                       } elseif ( substr( $key, 0, 8 ) === 'apiwarn-' ) {
+                               $this->apiCode = substr( $key, 8 );
+                       } elseif ( substr( $key, 0, 9 ) === 'apierror-' ) {
+                               $this->apiCode = substr( $key, 9 );
+                       } else {
+                               $this->apiCode = $key;
+                       }
+               }
+               return $this->apiCode;
+       }
+
+       public function setApiCode( $code, array $data = null ) {
+               if ( $code !== null && !( is_string( $code ) && $code !== '' ) ) {
+                       throw new InvalidArgumentException( "Invalid code \"$code\"" );
+               }
+
+               $this->apiCode = $code;
+               if ( $data !== null ) {
+                       $this->setApiData( $data );
+               }
+       }
+
+       public function getApiData() {
+               return $this->apiData;
+       }
+
+       public function setApiData( array $data ) {
+               $this->apiData = $data;
+       }
+
+       public function serialize() {
+               return serialize( [
+                       'parent' => parent::serialize(),
+                       'apiCode' => $this->apiCode,
+                       'apiData' => $this->apiData,
+               ] );
+       }
+
+       public function unserialize( $serialized ) {
+               $data = unserialize( $serialized );
+               parent::unserialize( $data['parent'] );
+               $this->apiCode = $data['apiCode'];
+               $this->apiData = $data['apiData'];
+       }
+}
index e49024d..c68ec2b 100644 (file)
@@ -98,7 +98,7 @@ class ApiQuery extends ApiBase {
                'recentchanges' => ApiQueryRecentChanges::class,
                'search' => ApiQuerySearch::class,
                'tags' => ApiQueryTags::class,
-               'usercontribs' => ApiQueryContributions::class,
+               'usercontribs' => ApiQueryUserContribs::class,
                'users' => ApiQueryUsers::class,
                'watchlist' => ApiQueryWatchlist::class,
                'watchlistraw' => ApiQueryWatchlistRaw::class,
diff --git a/includes/api/ApiQueryUserContribs.php b/includes/api/ApiQueryUserContribs.php
new file mode 100644 (file)
index 0000000..140ff6d
--- /dev/null
@@ -0,0 +1,839 @@
+<?php
+/**
+ * Copyright © 2006 Yuri Astrakhan "<Firstname><Lastname>@gmail.com"
+ *
+ * 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
+ */
+
+/**
+ * This query action adds a list of a specified user's contributions to the output.
+ *
+ * @ingroup API
+ */
+class ApiQueryUserContribs extends ApiQueryBase {
+
+       public function __construct( ApiQuery $query, $moduleName ) {
+               parent::__construct( $query, $moduleName, 'uc' );
+       }
+
+       private $params, $multiUserMode, $orderBy, $parentLens, $commentStore;
+
+       private $fld_ids = false, $fld_title = false, $fld_timestamp = false,
+               $fld_comment = false, $fld_parsedcomment = false, $fld_flags = false,
+               $fld_patrolled = false, $fld_tags = false, $fld_size = false, $fld_sizediff = false;
+
+       public function execute() {
+               global $wgActorTableSchemaMigrationStage;
+
+               // Parse some parameters
+               $this->params = $this->extractRequestParams();
+
+               $this->commentStore = CommentStore::getStore();
+
+               $prop = array_flip( $this->params['prop'] );
+               $this->fld_ids = isset( $prop['ids'] );
+               $this->fld_title = isset( $prop['title'] );
+               $this->fld_comment = isset( $prop['comment'] );
+               $this->fld_parsedcomment = isset( $prop['parsedcomment'] );
+               $this->fld_size = isset( $prop['size'] );
+               $this->fld_sizediff = isset( $prop['sizediff'] );
+               $this->fld_flags = isset( $prop['flags'] );
+               $this->fld_timestamp = isset( $prop['timestamp'] );
+               $this->fld_patrolled = isset( $prop['patrolled'] );
+               $this->fld_tags = isset( $prop['tags'] );
+
+               // Most of this code will use the 'contributions' group DB, which can map to replica DBs
+               // with extra user based indexes or partioning by user. The additional metadata
+               // queries should use a regular replica DB since the lookup pattern is not all by user.
+               $dbSecondary = $this->getDB(); // any random replica DB
+
+               // TODO: if the query is going only against the revision table, should this be done?
+               $this->selectNamedDB( 'contributions', DB_REPLICA, 'contributions' );
+
+               $sort = ( $this->params['dir'] == 'newer' ? '' : ' DESC' );
+               $op = ( $this->params['dir'] == 'older' ? '<' : '>' );
+
+               // Create an Iterator that produces the UserIdentity objects we need, depending
+               // on which of the 'userprefix', 'userids', or 'user' params was
+               // specified.
+               $this->requireOnlyOneParameter( $this->params, 'userprefix', 'userids', 'user' );
+               if ( isset( $this->params['userprefix'] ) ) {
+                       $this->multiUserMode = true;
+                       $this->orderBy = 'name';
+                       $fname = __METHOD__;
+
+                       // Because 'userprefix' might produce a huge number of users (e.g.
+                       // a wiki with users "Test00000001" to "Test99999999"), use a
+                       // generator with batched lookup and continuation.
+                       $userIter = call_user_func( function () use ( $dbSecondary, $sort, $op, $fname ) {
+                               global $wgActorTableSchemaMigrationStage;
+
+                               $fromName = false;
+                               if ( !is_null( $this->params['continue'] ) ) {
+                                       $continue = explode( '|', $this->params['continue'] );
+                                       $this->dieContinueUsageIf( count( $continue ) != 4 );
+                                       $this->dieContinueUsageIf( $continue[0] !== 'name' );
+                                       $fromName = $continue[1];
+                               }
+                               $like = $dbSecondary->buildLike( $this->params['userprefix'], $dbSecondary->anyString() );
+
+                               $limit = 501;
+
+                               do {
+                                       $from = $fromName ? "$op= " . $dbSecondary->addQuotes( $fromName ) : false;
+
+                                       // For the new schema, pull from the actor table. For the
+                                       // old, pull from rev_user. For migration a FULL [OUTER]
+                                       // JOIN would be what we want, except MySQL doesn't support
+                                       // that so we have to UNION instead.
+                                       if ( $wgActorTableSchemaMigrationStage === MIGRATION_NEW ) {
+                                               $res = $dbSecondary->select(
+                                                       'actor',
+                                                       [ 'actor_id', 'user_id' => 'COALESCE(actor_user,0)', 'user_name' => 'actor_name' ],
+                                                       array_merge( [ "actor_name$like" ], $from ? [ "actor_name $from" ] : [] ),
+                                                       $fname,
+                                                       [ 'ORDER BY' => [ "user_name $sort" ], 'LIMIT' => $limit ]
+                                               );
+                                       } elseif ( $wgActorTableSchemaMigrationStage === MIGRATION_OLD ) {
+                                               $res = $dbSecondary->select(
+                                                       'revision',
+                                                       [ 'actor_id' => 'NULL', 'user_id' => 'rev_user', 'user_name' => 'rev_user_text' ],
+                                                       array_merge( [ "rev_user_text$like" ], $from ? [ "rev_user_text $from" ] : [] ),
+                                                       $fname,
+                                                       [ 'DISTINCT', 'ORDER BY' => [ "rev_user_text $sort" ], 'LIMIT' => $limit ]
+                                               );
+                                       } else {
+                                               // There are three queries we have to combine to be sure of getting all results:
+                                               //  - actor table (any rows that have been migrated will have empty rev_user_text)
+                                               //  - revision+actor by user id
+                                               //  - revision+actor by name for anons
+                                               $options = $dbSecondary->unionSupportsOrderAndLimit()
+                                                       ? [ 'ORDER BY' => [ "user_name $sort" ], 'LIMIT' => $limit ] : [];
+                                               $subsql = [];
+                                               $subsql[] = $dbSecondary->selectSQLText(
+                                                       'actor',
+                                                       [ 'actor_id', 'user_id' => 'COALESCE(actor_user,0)', 'user_name' => 'actor_name' ],
+                                                       array_merge( [ "actor_name$like" ], $from ? [ "actor_name $from" ] : [] ),
+                                                       $fname,
+                                                       $options
+                                               );
+                                               $subsql[] = $dbSecondary->selectSQLText(
+                                                       [ 'revision', 'actor' ],
+                                                       [ 'actor_id', 'user_id' => 'rev_user', 'user_name' => 'rev_user_text' ],
+                                                       array_merge(
+                                                               [ "rev_user_text$like", 'rev_user != 0' ],
+                                                               $from ? [ "rev_user_text $from" ] : []
+                                                       ),
+                                                       $fname,
+                                                       array_merge( [ 'DISTINCT' ], $options ),
+                                                       [ 'actor' => [ 'LEFT JOIN', 'rev_user = actor_user' ] ]
+                                               );
+                                               $subsql[] = $dbSecondary->selectSQLText(
+                                                       [ 'revision', 'actor' ],
+                                                       [ 'actor_id', 'user_id' => 'rev_user', 'user_name' => 'rev_user_text' ],
+                                                       array_merge(
+                                                               [ "rev_user_text$like", 'rev_user = 0' ],
+                                                               $from ? [ "rev_user_text $from" ] : []
+                                                       ),
+                                                       $fname,
+                                                       array_merge( [ 'DISTINCT' ], $options ),
+                                                       [ 'actor' => [ 'LEFT JOIN', 'rev_user_text = actor_name' ] ]
+                                               );
+                                               $sql = $dbSecondary->unionQueries( $subsql, false ) . " ORDER BY user_name $sort";
+                                               $sql = $dbSecondary->limitResult( $sql, $limit );
+                                               $res = $dbSecondary->query( $sql, $fname );
+                                       }
+
+                                       $count = 0;
+                                       $fromName = false;
+                                       foreach ( $res as $row ) {
+                                               if ( ++$count >= $limit ) {
+                                                       $fromName = $row->user_name;
+                                                       break;
+                                               }
+                                               yield User::newFromRow( $row );
+                                       }
+                               } while ( $fromName !== false );
+                       } );
+                       // Do the actual sorting client-side, because otherwise
+                       // prepareQuery might try to sort by actor and confuse everything.
+                       $batchSize = 1;
+               } elseif ( isset( $this->params['userids'] ) ) {
+                       if ( !count( $this->params['userids'] ) ) {
+                               $encParamName = $this->encodeParamName( 'userids' );
+                               $this->dieWithError( [ 'apierror-paramempty', $encParamName ], "paramempty_$encParamName" );
+                       }
+
+                       $ids = [];
+                       foreach ( $this->params['userids'] as $uid ) {
+                               if ( $uid <= 0 ) {
+                                       $this->dieWithError( [ 'apierror-invaliduserid', $uid ], 'invaliduserid' );
+                               }
+                               $ids[] = $uid;
+                       }
+
+                       $this->orderBy = 'id';
+                       $this->multiUserMode = count( $ids ) > 1;
+
+                       $from = $fromId = false;
+                       if ( $this->multiUserMode && !is_null( $this->params['continue'] ) ) {
+                               $continue = explode( '|', $this->params['continue'] );
+                               $this->dieContinueUsageIf( count( $continue ) != 4 );
+                               $this->dieContinueUsageIf( $continue[0] !== 'id' && $continue[0] !== 'actor' );
+                               $fromId = (int)$continue[1];
+                               $this->dieContinueUsageIf( $continue[1] !== (string)$fromId );
+                               $from = "$op= $fromId";
+                       }
+
+                       // For the new schema, just select from the actor table. For the
+                       // old and transitional schemas, select from user and left join
+                       // actor if it exists.
+                       if ( $wgActorTableSchemaMigrationStage === MIGRATION_NEW ) {
+                               $res = $dbSecondary->select(
+                                       'actor',
+                                       [ 'actor_id', 'user_id' => 'actor_user', 'user_name' => 'actor_name' ],
+                                       array_merge( [ 'actor_user' => $ids ], $from ? [ "actor_id $from" ] : [] ),
+                                       __METHOD__,
+                                       [ 'ORDER BY' => "user_id $sort" ]
+                               );
+                       } elseif ( $wgActorTableSchemaMigrationStage === MIGRATION_OLD ) {
+                               $res = $dbSecondary->select(
+                                       'user',
+                                       [ 'actor_id' => 'NULL', 'user_id' => 'user_id', 'user_name' => 'user_name' ],
+                                       array_merge( [ 'user_id' => $ids ], $from ? [ "user_id $from" ] : [] ),
+                                       __METHOD__,
+                                       [ 'ORDER BY' => "user_id $sort" ]
+                               );
+                       } else {
+                               $res = $dbSecondary->select(
+                                       [ 'user', 'actor' ],
+                                       [ 'actor_id', 'user_id', 'user_name' ],
+                                       array_merge( [ 'user_id' => $ids ], $from ? [ "user_id $from" ] : [] ),
+                                       __METHOD__,
+                                       [ 'ORDER BY' => "user_id $sort" ],
+                                       [ 'actor' => [ 'LEFT JOIN', 'actor_user = user_id' ] ]
+                               );
+                       }
+                       $userIter = UserArray::newFromResult( $res );
+                       $batchSize = count( $ids );
+               } else {
+                       $names = [];
+                       if ( !count( $this->params['user'] ) ) {
+                               $encParamName = $this->encodeParamName( 'user' );
+                               $this->dieWithError(
+                                       [ 'apierror-paramempty', $encParamName ], "paramempty_$encParamName"
+                               );
+                       }
+                       foreach ( $this->params['user'] as $u ) {
+                               if ( $u === '' ) {
+                                       $encParamName = $this->encodeParamName( 'user' );
+                                       $this->dieWithError(
+                                               [ 'apierror-paramempty', $encParamName ], "paramempty_$encParamName"
+                                       );
+                               }
+
+                               if ( User::isIP( $u ) || ExternalUserNames::isExternal( $u ) ) {
+                                       $names[$u] = null;
+                               } else {
+                                       $name = User::getCanonicalName( $u, 'valid' );
+                                       if ( $name === false ) {
+                                               $encParamName = $this->encodeParamName( 'user' );
+                                               $this->dieWithError(
+                                                       [ 'apierror-baduser', $encParamName, wfEscapeWikiText( $u ) ], "baduser_$encParamName"
+                                               );
+                                       }
+                                       $names[$name] = null;
+                               }
+                       }
+
+                       $this->orderBy = 'name';
+                       $this->multiUserMode = count( $names ) > 1;
+
+                       $from = $fromName = false;
+                       if ( $this->multiUserMode && !is_null( $this->params['continue'] ) ) {
+                               $continue = explode( '|', $this->params['continue'] );
+                               $this->dieContinueUsageIf( count( $continue ) != 4 );
+                               $this->dieContinueUsageIf( $continue[0] !== 'name' && $continue[0] !== 'actor' );
+                               $fromName = $continue[1];
+                               $from = "$op= " . $dbSecondary->addQuotes( $fromName );
+                       }
+
+                       // For the new schema, just select from the actor table. For the
+                       // old and transitional schemas, select from user and left join
+                       // actor if it exists then merge in any unknown users (IPs and imports).
+                       if ( $wgActorTableSchemaMigrationStage === MIGRATION_NEW ) {
+                               $res = $dbSecondary->select(
+                                       'actor',
+                                       [ 'actor_id', 'user_id' => 'actor_user', 'user_name' => 'actor_name' ],
+                                       array_merge( [ 'actor_name' => array_keys( $names ) ], $from ? [ "actor_id $from" ] : [] ),
+                                       __METHOD__,
+                                       [ 'ORDER BY' => "actor_name $sort" ]
+                               );
+                               $userIter = UserArray::newFromResult( $res );
+                       } else {
+                               if ( $wgActorTableSchemaMigrationStage === MIGRATION_OLD ) {
+                                       $res = $dbSecondary->select(
+                                               'user',
+                                               [ 'actor_id' => 'NULL', 'user_id', 'user_name' ],
+                                               array_merge( [ 'user_name' => array_keys( $names ) ], $from ? [ "user_name $from" ] : [] ),
+                                               __METHOD__
+                                       );
+                               } else {
+                                       $res = $dbSecondary->select(
+                                               [ 'user', 'actor' ],
+                                               [ 'actor_id', 'user_id', 'user_name' ],
+                                               array_merge( [ 'user_name' => array_keys( $names ) ], $from ? [ "user_name $from" ] : [] ),
+                                               __METHOD__,
+                                               [],
+                                               [ 'actor' => [ 'LEFT JOIN', 'actor_user = user_id' ] ]
+                                       );
+                               }
+                               foreach ( $res as $row ) {
+                                       $names[$row->user_name] = $row;
+                               }
+                               call_user_func_array(
+                                       $this->params['dir'] == 'newer' ? 'ksort' : 'krsort', [ &$names, SORT_STRING ]
+                               );
+                               $neg = $op === '>' ? -1 : 1;
+                               $userIter = call_user_func( function () use ( $names, $fromName, $neg ) {
+                                       foreach ( $names as $name => $row ) {
+                                               if ( $fromName === false || $neg * strcmp( $name, $fromName ) <= 0 ) {
+                                                       $user = $row ? User::newFromRow( $row ) : User::newFromName( $name, false );
+                                                       yield $user;
+                                               }
+                                       }
+                               } );
+                       }
+                       $batchSize = count( $names );
+               }
+
+               // During migration, force ordering on the client side because we're
+               // having to combine multiple queries that would otherwise have
+               // different sort orders.
+               if ( $wgActorTableSchemaMigrationStage === MIGRATION_WRITE_BOTH ||
+                       $wgActorTableSchemaMigrationStage === MIGRATION_WRITE_NEW
+               ) {
+                       $batchSize = 1;
+               }
+
+               // With the new schema, the DB query will order by actor so update $this->orderBy to match.
+               if ( $batchSize > 1 && $wgActorTableSchemaMigrationStage === MIGRATION_NEW ) {
+                       $this->orderBy = 'actor';
+               }
+
+               $count = 0;
+               $limit = $this->params['limit'];
+               $userIter->rewind();
+               while ( $userIter->valid() ) {
+                       $users = [];
+                       while ( count( $users ) < $batchSize && $userIter->valid() ) {
+                               $users[] = $userIter->current();
+                               $userIter->next();
+                       }
+
+                       // Ugh. We have to run the query three times, once for each
+                       // possible 'orcond' from ActorMigration, and then merge them all
+                       // together in the proper order. And preserving the correct
+                       // $hookData for each one.
+                       // @todo When ActorMigration is removed, this can go back to a
+                       //  single prepare and select.
+                       $merged = [];
+                       foreach ( [ 'actor', 'userid', 'username' ] as $which ) {
+                               if ( $this->prepareQuery( $users, $limit - $count, $which ) ) {
+                                       $hookData = [];
+                                       $res = $this->select( __METHOD__, [], $hookData );
+                                       foreach ( $res as $row ) {
+                                               $merged[] = [ $row, &$hookData ];
+                                       }
+                               }
+                       }
+                       $neg = $this->params['dir'] == 'newer' ? 1 : -1;
+                       usort( $merged, function ( $a, $b ) use ( $neg, $batchSize ) {
+                               if ( $batchSize === 1 ) { // One user, can't be different
+                                       $ret = 0;
+                               } elseif ( $this->orderBy === 'id' ) {
+                                       $ret = $a[0]->rev_user - $b[0]->rev_user;
+                               } elseif ( $this->orderBy === 'name' ) {
+                                       $ret = strcmp( $a[0]->rev_user_text, $b[0]->rev_user_text );
+                               } else {
+                                       $ret = $a[0]->rev_actor - $b[0]->rev_actor;
+                               }
+
+                               if ( !$ret ) {
+                                       $ret = strcmp(
+                                               wfTimestamp( TS_MW, $a[0]->rev_timestamp ),
+                                               wfTimestamp( TS_MW, $b[0]->rev_timestamp )
+                                       );
+                               }
+
+                               if ( !$ret ) {
+                                       $ret = $a[0]->rev_id - $b[0]->rev_id;
+                               }
+
+                               return $neg * $ret;
+                       } );
+                       $merged = array_slice( $merged, 0, $limit - $count + 1 );
+                       // (end "Ugh")
+
+                       if ( $this->fld_sizediff ) {
+                               $revIds = [];
+                               foreach ( $merged as $data ) {
+                                       if ( $data[0]->rev_parent_id ) {
+                                               $revIds[] = $data[0]->rev_parent_id;
+                                       }
+                               }
+                               $this->parentLens = Revision::getParentLengths( $dbSecondary, $revIds );
+                       }
+
+                       foreach ( $merged as $data ) {
+                               $row = $data[0];
+                               $hookData = &$data[1];
+                               if ( ++$count > $limit ) {
+                                       // We've reached the one extra which shows that there are
+                                       // additional pages to be had. Stop here...
+                                       $this->setContinueEnumParameter( 'continue', $this->continueStr( $row ) );
+                                       break 2;
+                               }
+
+                               $vals = $this->extractRowInfo( $row );
+                               $fit = $this->processRow( $row, $vals, $hookData ) &&
+                                       $this->getResult()->addValue( [ 'query', $this->getModuleName() ], null, $vals );
+                               if ( !$fit ) {
+                                       $this->setContinueEnumParameter( 'continue', $this->continueStr( $row ) );
+                                       break 2;
+                               }
+                       }
+               }
+
+               $this->getResult()->addIndexedTagName( [ 'query', $this->getModuleName() ], 'item' );
+       }
+
+       /**
+        * Prepares the query and returns the limit of rows requested
+        * @param User[] $users
+        * @param int $limit
+        * @param string $which 'actor', 'userid', or 'username'
+        * @return bool
+        */
+       private function prepareQuery( array $users, $limit, $which ) {
+               global $wgActorTableSchemaMigrationStage;
+
+               $this->resetQueryParams();
+               $db = $this->getDB();
+
+               $revQuery = Revision::getQueryInfo( [ 'page' ] );
+               $this->addTables( $revQuery['tables'] );
+               $this->addJoinConds( $revQuery['joins'] );
+               $this->addFields( $revQuery['fields'] );
+
+               $revWhere = ActorMigration::newMigration()->getWhere( $db, 'rev_user', $users );
+               if ( !isset( $revWhere['orconds'][$which] ) ) {
+                       return false;
+               }
+               $this->addWhere( $revWhere['orconds'][$which] );
+
+               if ( $wgActorTableSchemaMigrationStage === MIGRATION_NEW ) {
+                       $orderUserField = 'rev_actor';
+                       $userField = $this->orderBy === 'actor' ? 'revactor_actor' : 'actor_name';
+               } else {
+                       $orderUserField = $this->orderBy === 'id' ? 'rev_user' : 'rev_user_text';
+                       $userField = $revQuery['fields'][$orderUserField];
+               }
+               if ( $which === 'actor' ) {
+                       $tsField = 'revactor_timestamp';
+                       $idField = 'revactor_rev';
+               } else {
+                       $tsField = 'rev_timestamp';
+                       $idField = 'rev_id';
+               }
+
+               // Handle continue parameter
+               if ( !is_null( $this->params['continue'] ) ) {
+                       $continue = explode( '|', $this->params['continue'] );
+                       if ( $this->multiUserMode ) {
+                               $this->dieContinueUsageIf( count( $continue ) != 4 );
+                               $modeFlag = array_shift( $continue );
+                               $this->dieContinueUsageIf( $modeFlag !== $this->orderBy );
+                               $encUser = $db->addQuotes( array_shift( $continue ) );
+                       } else {
+                               $this->dieContinueUsageIf( count( $continue ) != 2 );
+                       }
+                       $encTS = $db->addQuotes( $db->timestamp( $continue[0] ) );
+                       $encId = (int)$continue[1];
+                       $this->dieContinueUsageIf( $encId != $continue[1] );
+                       $op = ( $this->params['dir'] == 'older' ? '<' : '>' );
+                       if ( $this->multiUserMode ) {
+                               $this->addWhere(
+                                       "$userField $op $encUser OR " .
+                                       "($userField = $encUser AND " .
+                                       "($tsField $op $encTS OR " .
+                                       "($tsField = $encTS AND " .
+                                       "$idField $op= $encId)))"
+                               );
+                       } else {
+                               $this->addWhere(
+                                       "$tsField $op $encTS OR " .
+                                       "($tsField = $encTS AND " .
+                                       "$idField $op= $encId)"
+                               );
+                       }
+               }
+
+               // Don't include any revisions where we're not supposed to be able to
+               // see the username.
+               $user = $this->getUser();
+               if ( !$user->isAllowed( 'deletedhistory' ) ) {
+                       $bitmask = Revision::DELETED_USER;
+               } elseif ( !$user->isAllowedAny( 'suppressrevision', 'viewsuppressed' ) ) {
+                       $bitmask = Revision::DELETED_USER | Revision::DELETED_RESTRICTED;
+               } else {
+                       $bitmask = 0;
+               }
+               if ( $bitmask ) {
+                       $this->addWhere( $db->bitAnd( 'rev_deleted', $bitmask ) . " != $bitmask" );
+               }
+
+               // Add the user field to ORDER BY if there are multiple users
+               if ( count( $users ) > 1 ) {
+                       $this->addWhereRange( $orderUserField, $this->params['dir'], null, null );
+               }
+
+               // Then timestamp
+               $this->addTimestampWhereRange( $tsField,
+                       $this->params['dir'], $this->params['start'], $this->params['end'] );
+
+               // Then rev_id for a total ordering
+               $this->addWhereRange( $idField, $this->params['dir'], null, null );
+
+               $this->addWhereFld( 'page_namespace', $this->params['namespace'] );
+
+               $show = $this->params['show'];
+               if ( $this->params['toponly'] ) { // deprecated/old param
+                       $show[] = 'top';
+               }
+               if ( !is_null( $show ) ) {
+                       $show = array_flip( $show );
+
+                       if ( ( isset( $show['minor'] ) && isset( $show['!minor'] ) )
+                               || ( isset( $show['patrolled'] ) && isset( $show['!patrolled'] ) )
+                               || ( isset( $show['autopatrolled'] ) && isset( $show['!autopatrolled'] ) )
+                               || ( isset( $show['autopatrolled'] ) && isset( $show['!patrolled'] ) )
+                               || ( isset( $show['top'] ) && isset( $show['!top'] ) )
+                               || ( isset( $show['new'] ) && isset( $show['!new'] ) )
+                       ) {
+                               $this->dieWithError( 'apierror-show' );
+                       }
+
+                       $this->addWhereIf( 'rev_minor_edit = 0', isset( $show['!minor'] ) );
+                       $this->addWhereIf( 'rev_minor_edit != 0', isset( $show['minor'] ) );
+                       $this->addWhereIf(
+                               'rc_patrolled = ' . RecentChange::PRC_UNPATROLLED,
+                               isset( $show['!patrolled'] )
+                       );
+                       $this->addWhereIf(
+                               'rc_patrolled != ' . RecentChange::PRC_UNPATROLLED,
+                               isset( $show['patrolled'] )
+                       );
+                       $this->addWhereIf(
+                               'rc_patrolled != ' . RecentChange::PRC_AUTOPATROLLED,
+                               isset( $show['!autopatrolled'] )
+                       );
+                       $this->addWhereIf(
+                               'rc_patrolled = ' . RecentChange::PRC_AUTOPATROLLED,
+                               isset( $show['autopatrolled'] )
+                       );
+                       $this->addWhereIf( $idField . ' != page_latest', isset( $show['!top'] ) );
+                       $this->addWhereIf( $idField . ' = page_latest', isset( $show['top'] ) );
+                       $this->addWhereIf( 'rev_parent_id != 0', isset( $show['!new'] ) );
+                       $this->addWhereIf( 'rev_parent_id = 0', isset( $show['new'] ) );
+               }
+               $this->addOption( 'LIMIT', $limit + 1 );
+
+               if ( isset( $show['patrolled'] ) || isset( $show['!patrolled'] ) ||
+                       isset( $show['autopatrolled'] ) || isset( $show['!autopatrolled'] ) || $this->fld_patrolled
+               ) {
+                       if ( !$user->useRCPatrol() && !$user->useNPPatrol() ) {
+                               $this->dieWithError( 'apierror-permissiondenied-patrolflag', 'permissiondenied' );
+                       }
+
+                       $isFilterset = isset( $show['patrolled'] ) || isset( $show['!patrolled'] ) ||
+                               isset( $show['autopatrolled'] ) || isset( $show['!autopatrolled'] );
+                       $this->addTables( 'recentchanges' );
+                       $this->addJoinConds( [ 'recentchanges' => [
+                               $isFilterset ? 'JOIN' : 'LEFT JOIN',
+                               [
+                                       // This is a crazy hack. recentchanges has no index on rc_this_oldid, so instead of adding
+                                       // one T19237 did a join using rc_user_text and rc_timestamp instead. Now rc_user_text is
+                                       // probably unavailable, so just do rc_timestamp.
+                                       'rc_timestamp = ' . $tsField,
+                                       'rc_this_oldid = ' . $idField,
+                               ]
+                       ] ] );
+               }
+
+               $this->addFieldsIf( 'rc_patrolled', $this->fld_patrolled );
+
+               if ( $this->fld_tags ) {
+                       $this->addTables( 'tag_summary' );
+                       $this->addJoinConds(
+                               [ 'tag_summary' => [ 'LEFT JOIN', [ $idField . ' = ts_rev_id' ] ] ]
+                       );
+                       $this->addFields( 'ts_tags' );
+               }
+
+               if ( isset( $this->params['tag'] ) ) {
+                       $this->addTables( 'change_tag' );
+                       $this->addJoinConds(
+                               [ 'change_tag' => [ 'INNER JOIN', [ $idField . ' = ct_rev_id' ] ] ]
+                       );
+                       $this->addWhereFld( 'ct_tag', $this->params['tag'] );
+               }
+
+               return true;
+       }
+
+       /**
+        * Extract fields from the database row and append them to a result array
+        *
+        * @param stdClass $row
+        * @return array
+        */
+       private function extractRowInfo( $row ) {
+               $vals = [];
+               $anyHidden = false;
+
+               if ( $row->rev_deleted & Revision::DELETED_TEXT ) {
+                       $vals['texthidden'] = true;
+                       $anyHidden = true;
+               }
+
+               // Any rows where we can't view the user were filtered out in the query.
+               $vals['userid'] = (int)$row->rev_user;
+               $vals['user'] = $row->rev_user_text;
+               if ( $row->rev_deleted & Revision::DELETED_USER ) {
+                       $vals['userhidden'] = true;
+                       $anyHidden = true;
+               }
+               if ( $this->fld_ids ) {
+                       $vals['pageid'] = intval( $row->rev_page );
+                       $vals['revid'] = intval( $row->rev_id );
+                       // $vals['textid'] = intval( $row->rev_text_id ); // todo: Should this field be exposed?
+
+                       if ( !is_null( $row->rev_parent_id ) ) {
+                               $vals['parentid'] = intval( $row->rev_parent_id );
+                       }
+               }
+
+               $title = Title::makeTitle( $row->page_namespace, $row->page_title );
+
+               if ( $this->fld_title ) {
+                       ApiQueryBase::addTitleInfo( $vals, $title );
+               }
+
+               if ( $this->fld_timestamp ) {
+                       $vals['timestamp'] = wfTimestamp( TS_ISO_8601, $row->rev_timestamp );
+               }
+
+               if ( $this->fld_flags ) {
+                       $vals['new'] = $row->rev_parent_id == 0 && !is_null( $row->rev_parent_id );
+                       $vals['minor'] = (bool)$row->rev_minor_edit;
+                       $vals['top'] = $row->page_latest == $row->rev_id;
+               }
+
+               if ( $this->fld_comment || $this->fld_parsedcomment ) {
+                       if ( $row->rev_deleted & Revision::DELETED_COMMENT ) {
+                               $vals['commenthidden'] = true;
+                               $anyHidden = true;
+                       }
+
+                       $userCanView = Revision::userCanBitfield(
+                               $row->rev_deleted,
+                               Revision::DELETED_COMMENT, $this->getUser()
+                       );
+
+                       if ( $userCanView ) {
+                               $comment = $this->commentStore->getComment( 'rev_comment', $row )->text;
+                               if ( $this->fld_comment ) {
+                                       $vals['comment'] = $comment;
+                               }
+
+                               if ( $this->fld_parsedcomment ) {
+                                       $vals['parsedcomment'] = Linker::formatComment( $comment, $title );
+                               }
+                       }
+               }
+
+               if ( $this->fld_patrolled ) {
+                       $vals['patrolled'] = $row->rc_patrolled != RecentChange::PRC_UNPATROLLED;
+                       $vals['autopatrolled'] = $row->rc_patrolled == RecentChange::PRC_AUTOPATROLLED;
+               }
+
+               if ( $this->fld_size && !is_null( $row->rev_len ) ) {
+                       $vals['size'] = intval( $row->rev_len );
+               }
+
+               if ( $this->fld_sizediff
+                       && !is_null( $row->rev_len )
+                       && !is_null( $row->rev_parent_id )
+               ) {
+                       $parentLen = isset( $this->parentLens[$row->rev_parent_id] )
+                               ? $this->parentLens[$row->rev_parent_id]
+                               : 0;
+                       $vals['sizediff'] = intval( $row->rev_len - $parentLen );
+               }
+
+               if ( $this->fld_tags ) {
+                       if ( $row->ts_tags ) {
+                               $tags = explode( ',', $row->ts_tags );
+                               ApiResult::setIndexedTagName( $tags, 'tag' );
+                               $vals['tags'] = $tags;
+                       } else {
+                               $vals['tags'] = [];
+                       }
+               }
+
+               if ( $anyHidden && $row->rev_deleted & Revision::DELETED_RESTRICTED ) {
+                       $vals['suppressed'] = true;
+               }
+
+               return $vals;
+       }
+
+       private function continueStr( $row ) {
+               if ( $this->multiUserMode ) {
+                       switch ( $this->orderBy ) {
+                               case 'id':
+                                       return "id|$row->rev_user|$row->rev_timestamp|$row->rev_id";
+                               case 'name':
+                                       return "name|$row->rev_user_text|$row->rev_timestamp|$row->rev_id";
+                               case 'actor':
+                                       return "actor|$row->rev_actor|$row->rev_timestamp|$row->rev_id";
+                       }
+               } else {
+                       return "$row->rev_timestamp|$row->rev_id";
+               }
+       }
+
+       public function getCacheMode( $params ) {
+               // This module provides access to deleted revisions and patrol flags if
+               // the requester is logged in
+               return 'anon-public-user-private';
+       }
+
+       public function getAllowedParams() {
+               return [
+                       'limit' => [
+                               ApiBase::PARAM_DFLT => 10,
+                               ApiBase::PARAM_TYPE => 'limit',
+                               ApiBase::PARAM_MIN => 1,
+                               ApiBase::PARAM_MAX => ApiBase::LIMIT_BIG1,
+                               ApiBase::PARAM_MAX2 => ApiBase::LIMIT_BIG2
+                       ],
+                       'start' => [
+                               ApiBase::PARAM_TYPE => 'timestamp'
+                       ],
+                       'end' => [
+                               ApiBase::PARAM_TYPE => 'timestamp'
+                       ],
+                       'continue' => [
+                               ApiBase::PARAM_HELP_MSG => 'api-help-param-continue',
+                       ],
+                       'user' => [
+                               ApiBase::PARAM_TYPE => 'user',
+                               ApiBase::PARAM_ISMULTI => true
+                       ],
+                       'userids' => [
+                               ApiBase::PARAM_TYPE => 'integer',
+                               ApiBase::PARAM_ISMULTI => true
+                       ],
+                       'userprefix' => null,
+                       'dir' => [
+                               ApiBase::PARAM_DFLT => 'older',
+                               ApiBase::PARAM_TYPE => [
+                                       'newer',
+                                       'older'
+                               ],
+                               ApiBase::PARAM_HELP_MSG => 'api-help-param-direction',
+                       ],
+                       'namespace' => [
+                               ApiBase::PARAM_ISMULTI => true,
+                               ApiBase::PARAM_TYPE => 'namespace'
+                       ],
+                       'prop' => [
+                               ApiBase::PARAM_ISMULTI => true,
+                               ApiBase::PARAM_DFLT => 'ids|title|timestamp|comment|size|flags',
+                               ApiBase::PARAM_TYPE => [
+                                       'ids',
+                                       'title',
+                                       'timestamp',
+                                       'comment',
+                                       'parsedcomment',
+                                       'size',
+                                       'sizediff',
+                                       'flags',
+                                       'patrolled',
+                                       'tags'
+                               ],
+                               ApiBase::PARAM_HELP_MSG_PER_VALUE => [],
+                       ],
+                       'show' => [
+                               ApiBase::PARAM_ISMULTI => true,
+                               ApiBase::PARAM_TYPE => [
+                                       'minor',
+                                       '!minor',
+                                       'patrolled',
+                                       '!patrolled',
+                                       'autopatrolled',
+                                       '!autopatrolled',
+                                       'top',
+                                       '!top',
+                                       'new',
+                                       '!new',
+                               ],
+                               ApiBase::PARAM_HELP_MSG => [
+                                       'apihelp-query+usercontribs-param-show',
+                                       $this->getConfig()->get( 'RCMaxAge' )
+                               ],
+                       ],
+                       'tag' => null,
+                       'toponly' => [
+                               ApiBase::PARAM_DFLT => false,
+                               ApiBase::PARAM_DEPRECATED => true,
+                       ],
+               ];
+       }
+
+       protected function getExamplesMessages() {
+               return [
+                       'action=query&list=usercontribs&ucuser=Example'
+                               => 'apihelp-query+usercontribs-example-user',
+                       'action=query&list=usercontribs&ucuserprefix=192.0.2.'
+                               => 'apihelp-query+usercontribs-example-ipprefix',
+               ];
+       }
+
+       public function getHelpUrls() {
+               return 'https://www.mediawiki.org/wiki/Special:MyLanguage/API:Usercontribs';
+       }
+}
+
+/**
+ * @since 1.9
+ * @deprecated since 1.32
+ */
+class_alias( ApiQueryUserContribs::class, 'ApiQueryContributions' );
diff --git a/includes/api/ApiQueryUserContributions.php b/includes/api/ApiQueryUserContributions.php
deleted file mode 100644 (file)
index 12f42ed..0000000
+++ /dev/null
@@ -1,832 +0,0 @@
-<?php
-/**
- * Copyright © 2006 Yuri Astrakhan "<Firstname><Lastname>@gmail.com"
- *
- * 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
- */
-
-/**
- * This query action adds a list of a specified user's contributions to the output.
- *
- * @ingroup API
- */
-class ApiQueryContributions extends ApiQueryBase {
-
-       public function __construct( ApiQuery $query, $moduleName ) {
-               parent::__construct( $query, $moduleName, 'uc' );
-       }
-
-       private $params, $multiUserMode, $orderBy, $parentLens;
-       private $fld_ids = false, $fld_title = false, $fld_timestamp = false,
-               $fld_comment = false, $fld_parsedcomment = false, $fld_flags = false,
-               $fld_patrolled = false, $fld_tags = false, $fld_size = false, $fld_sizediff = false;
-
-       public function execute() {
-               global $wgActorTableSchemaMigrationStage;
-
-               // Parse some parameters
-               $this->params = $this->extractRequestParams();
-
-               $this->commentStore = CommentStore::getStore();
-
-               $prop = array_flip( $this->params['prop'] );
-               $this->fld_ids = isset( $prop['ids'] );
-               $this->fld_title = isset( $prop['title'] );
-               $this->fld_comment = isset( $prop['comment'] );
-               $this->fld_parsedcomment = isset( $prop['parsedcomment'] );
-               $this->fld_size = isset( $prop['size'] );
-               $this->fld_sizediff = isset( $prop['sizediff'] );
-               $this->fld_flags = isset( $prop['flags'] );
-               $this->fld_timestamp = isset( $prop['timestamp'] );
-               $this->fld_patrolled = isset( $prop['patrolled'] );
-               $this->fld_tags = isset( $prop['tags'] );
-
-               // Most of this code will use the 'contributions' group DB, which can map to replica DBs
-               // with extra user based indexes or partioning by user. The additional metadata
-               // queries should use a regular replica DB since the lookup pattern is not all by user.
-               $dbSecondary = $this->getDB(); // any random replica DB
-
-               // TODO: if the query is going only against the revision table, should this be done?
-               $this->selectNamedDB( 'contributions', DB_REPLICA, 'contributions' );
-
-               $sort = ( $this->params['dir'] == 'newer' ? '' : ' DESC' );
-               $op = ( $this->params['dir'] == 'older' ? '<' : '>' );
-
-               // Create an Iterator that produces the UserIdentity objects we need, depending
-               // on which of the 'userprefix', 'userids', or 'user' params was
-               // specified.
-               $this->requireOnlyOneParameter( $this->params, 'userprefix', 'userids', 'user' );
-               if ( isset( $this->params['userprefix'] ) ) {
-                       $this->multiUserMode = true;
-                       $this->orderBy = 'name';
-                       $fname = __METHOD__;
-
-                       // Because 'userprefix' might produce a huge number of users (e.g.
-                       // a wiki with users "Test00000001" to "Test99999999"), use a
-                       // generator with batched lookup and continuation.
-                       $userIter = call_user_func( function () use ( $dbSecondary, $sort, $op, $fname ) {
-                               global $wgActorTableSchemaMigrationStage;
-
-                               $fromName = false;
-                               if ( !is_null( $this->params['continue'] ) ) {
-                                       $continue = explode( '|', $this->params['continue'] );
-                                       $this->dieContinueUsageIf( count( $continue ) != 4 );
-                                       $this->dieContinueUsageIf( $continue[0] !== 'name' );
-                                       $fromName = $continue[1];
-                               }
-                               $like = $dbSecondary->buildLike( $this->params['userprefix'], $dbSecondary->anyString() );
-
-                               $limit = 501;
-
-                               do {
-                                       $from = $fromName ? "$op= " . $dbSecondary->addQuotes( $fromName ) : false;
-
-                                       // For the new schema, pull from the actor table. For the
-                                       // old, pull from rev_user. For migration a FULL [OUTER]
-                                       // JOIN would be what we want, except MySQL doesn't support
-                                       // that so we have to UNION instead.
-                                       if ( $wgActorTableSchemaMigrationStage === MIGRATION_NEW ) {
-                                               $res = $dbSecondary->select(
-                                                       'actor',
-                                                       [ 'actor_id', 'user_id' => 'COALESCE(actor_user,0)', 'user_name' => 'actor_name' ],
-                                                       array_merge( [ "actor_name$like" ], $from ? [ "actor_name $from" ] : [] ),
-                                                       $fname,
-                                                       [ 'ORDER BY' => [ "user_name $sort" ], 'LIMIT' => $limit ]
-                                               );
-                                       } elseif ( $wgActorTableSchemaMigrationStage === MIGRATION_OLD ) {
-                                               $res = $dbSecondary->select(
-                                                       'revision',
-                                                       [ 'actor_id' => 'NULL', 'user_id' => 'rev_user', 'user_name' => 'rev_user_text' ],
-                                                       array_merge( [ "rev_user_text$like" ], $from ? [ "rev_user_text $from" ] : [] ),
-                                                       $fname,
-                                                       [ 'DISTINCT', 'ORDER BY' => [ "rev_user_text $sort" ], 'LIMIT' => $limit ]
-                                               );
-                                       } else {
-                                               // There are three queries we have to combine to be sure of getting all results:
-                                               //  - actor table (any rows that have been migrated will have empty rev_user_text)
-                                               //  - revision+actor by user id
-                                               //  - revision+actor by name for anons
-                                               $options = $dbSecondary->unionSupportsOrderAndLimit()
-                                                       ? [ 'ORDER BY' => [ "user_name $sort" ], 'LIMIT' => $limit ] : [];
-                                               $subsql = [];
-                                               $subsql[] = $dbSecondary->selectSQLText(
-                                                       'actor',
-                                                       [ 'actor_id', 'user_id' => 'COALESCE(actor_user,0)', 'user_name' => 'actor_name' ],
-                                                       array_merge( [ "actor_name$like" ], $from ? [ "actor_name $from" ] : [] ),
-                                                       $fname,
-                                                       $options
-                                               );
-                                               $subsql[] = $dbSecondary->selectSQLText(
-                                                       [ 'revision', 'actor' ],
-                                                       [ 'actor_id', 'user_id' => 'rev_user', 'user_name' => 'rev_user_text' ],
-                                                       array_merge(
-                                                               [ "rev_user_text$like", 'rev_user != 0' ],
-                                                               $from ? [ "rev_user_text $from" ] : []
-                                                       ),
-                                                       $fname,
-                                                       array_merge( [ 'DISTINCT' ], $options ),
-                                                       [ 'actor' => [ 'LEFT JOIN', 'rev_user = actor_user' ] ]
-                                               );
-                                               $subsql[] = $dbSecondary->selectSQLText(
-                                                       [ 'revision', 'actor' ],
-                                                       [ 'actor_id', 'user_id' => 'rev_user', 'user_name' => 'rev_user_text' ],
-                                                       array_merge(
-                                                               [ "rev_user_text$like", 'rev_user = 0' ],
-                                                               $from ? [ "rev_user_text $from" ] : []
-                                                       ),
-                                                       $fname,
-                                                       array_merge( [ 'DISTINCT' ], $options ),
-                                                       [ 'actor' => [ 'LEFT JOIN', 'rev_user_text = actor_name' ] ]
-                                               );
-                                               $sql = $dbSecondary->unionQueries( $subsql, false ) . " ORDER BY user_name $sort";
-                                               $sql = $dbSecondary->limitResult( $sql, $limit );
-                                               $res = $dbSecondary->query( $sql, $fname );
-                                       }
-
-                                       $count = 0;
-                                       $fromName = false;
-                                       foreach ( $res as $row ) {
-                                               if ( ++$count >= $limit ) {
-                                                       $fromName = $row->user_name;
-                                                       break;
-                                               }
-                                               yield User::newFromRow( $row );
-                                       }
-                               } while ( $fromName !== false );
-                       } );
-                       // Do the actual sorting client-side, because otherwise
-                       // prepareQuery might try to sort by actor and confuse everything.
-                       $batchSize = 1;
-               } elseif ( isset( $this->params['userids'] ) ) {
-                       if ( !count( $this->params['userids'] ) ) {
-                               $encParamName = $this->encodeParamName( 'userids' );
-                               $this->dieWithError( [ 'apierror-paramempty', $encParamName ], "paramempty_$encParamName" );
-                       }
-
-                       $ids = [];
-                       foreach ( $this->params['userids'] as $uid ) {
-                               if ( $uid <= 0 ) {
-                                       $this->dieWithError( [ 'apierror-invaliduserid', $uid ], 'invaliduserid' );
-                               }
-                               $ids[] = $uid;
-                       }
-
-                       $this->orderBy = 'id';
-                       $this->multiUserMode = count( $ids ) > 1;
-
-                       $from = $fromId = false;
-                       if ( $this->multiUserMode && !is_null( $this->params['continue'] ) ) {
-                               $continue = explode( '|', $this->params['continue'] );
-                               $this->dieContinueUsageIf( count( $continue ) != 4 );
-                               $this->dieContinueUsageIf( $continue[0] !== 'id' && $continue[0] !== 'actor' );
-                               $fromId = (int)$continue[1];
-                               $this->dieContinueUsageIf( $continue[1] !== (string)$fromId );
-                               $from = "$op= $fromId";
-                       }
-
-                       // For the new schema, just select from the actor table. For the
-                       // old and transitional schemas, select from user and left join
-                       // actor if it exists.
-                       if ( $wgActorTableSchemaMigrationStage === MIGRATION_NEW ) {
-                               $res = $dbSecondary->select(
-                                       'actor',
-                                       [ 'actor_id', 'user_id' => 'actor_user', 'user_name' => 'actor_name' ],
-                                       array_merge( [ 'actor_user' => $ids ], $from ? [ "actor_id $from" ] : [] ),
-                                       __METHOD__,
-                                       [ 'ORDER BY' => "user_id $sort" ]
-                               );
-                       } elseif ( $wgActorTableSchemaMigrationStage === MIGRATION_OLD ) {
-                               $res = $dbSecondary->select(
-                                       'user',
-                                       [ 'actor_id' => 'NULL', 'user_id' => 'user_id', 'user_name' => 'user_name' ],
-                                       array_merge( [ 'user_id' => $ids ], $from ? [ "user_id $from" ] : [] ),
-                                       __METHOD__,
-                                       [ 'ORDER BY' => "user_id $sort" ]
-                               );
-                       } else {
-                               $res = $dbSecondary->select(
-                                       [ 'user', 'actor' ],
-                                       [ 'actor_id', 'user_id', 'user_name' ],
-                                       array_merge( [ 'user_id' => $ids ], $from ? [ "user_id $from" ] : [] ),
-                                       __METHOD__,
-                                       [ 'ORDER BY' => "user_id $sort" ],
-                                       [ 'actor' => [ 'LEFT JOIN', 'actor_user = user_id' ] ]
-                               );
-                       }
-                       $userIter = UserArray::newFromResult( $res );
-                       $batchSize = count( $ids );
-               } else {
-                       $names = [];
-                       if ( !count( $this->params['user'] ) ) {
-                               $encParamName = $this->encodeParamName( 'user' );
-                               $this->dieWithError(
-                                       [ 'apierror-paramempty', $encParamName ], "paramempty_$encParamName"
-                               );
-                       }
-                       foreach ( $this->params['user'] as $u ) {
-                               if ( $u === '' ) {
-                                       $encParamName = $this->encodeParamName( 'user' );
-                                       $this->dieWithError(
-                                               [ 'apierror-paramempty', $encParamName ], "paramempty_$encParamName"
-                                       );
-                               }
-
-                               if ( User::isIP( $u ) || ExternalUserNames::isExternal( $u ) ) {
-                                       $names[$u] = null;
-                               } else {
-                                       $name = User::getCanonicalName( $u, 'valid' );
-                                       if ( $name === false ) {
-                                               $encParamName = $this->encodeParamName( 'user' );
-                                               $this->dieWithError(
-                                                       [ 'apierror-baduser', $encParamName, wfEscapeWikiText( $u ) ], "baduser_$encParamName"
-                                               );
-                                       }
-                                       $names[$name] = null;
-                               }
-                       }
-
-                       $this->orderBy = 'name';
-                       $this->multiUserMode = count( $names ) > 1;
-
-                       $from = $fromName = false;
-                       if ( $this->multiUserMode && !is_null( $this->params['continue'] ) ) {
-                               $continue = explode( '|', $this->params['continue'] );
-                               $this->dieContinueUsageIf( count( $continue ) != 4 );
-                               $this->dieContinueUsageIf( $continue[0] !== 'name' && $continue[0] !== 'actor' );
-                               $fromName = $continue[1];
-                               $from = "$op= " . $dbSecondary->addQuotes( $fromName );
-                       }
-
-                       // For the new schema, just select from the actor table. For the
-                       // old and transitional schemas, select from user and left join
-                       // actor if it exists then merge in any unknown users (IPs and imports).
-                       if ( $wgActorTableSchemaMigrationStage === MIGRATION_NEW ) {
-                               $res = $dbSecondary->select(
-                                       'actor',
-                                       [ 'actor_id', 'user_id' => 'actor_user', 'user_name' => 'actor_name' ],
-                                       array_merge( [ 'actor_name' => array_keys( $names ) ], $from ? [ "actor_id $from" ] : [] ),
-                                       __METHOD__,
-                                       [ 'ORDER BY' => "actor_name $sort" ]
-                               );
-                               $userIter = UserArray::newFromResult( $res );
-                       } else {
-                               if ( $wgActorTableSchemaMigrationStage === MIGRATION_OLD ) {
-                                       $res = $dbSecondary->select(
-                                               'user',
-                                               [ 'actor_id' => 'NULL', 'user_id', 'user_name' ],
-                                               array_merge( [ 'user_name' => array_keys( $names ) ], $from ? [ "user_name $from" ] : [] ),
-                                               __METHOD__
-                                       );
-                               } else {
-                                       $res = $dbSecondary->select(
-                                               [ 'user', 'actor' ],
-                                               [ 'actor_id', 'user_id', 'user_name' ],
-                                               array_merge( [ 'user_name' => array_keys( $names ) ], $from ? [ "user_name $from" ] : [] ),
-                                               __METHOD__,
-                                               [],
-                                               [ 'actor' => [ 'LEFT JOIN', 'actor_user = user_id' ] ]
-                                       );
-                               }
-                               foreach ( $res as $row ) {
-                                       $names[$row->user_name] = $row;
-                               }
-                               call_user_func_array(
-                                       $this->params['dir'] == 'newer' ? 'ksort' : 'krsort', [ &$names, SORT_STRING ]
-                               );
-                               $neg = $op === '>' ? -1 : 1;
-                               $userIter = call_user_func( function () use ( $names, $fromName, $neg ) {
-                                       foreach ( $names as $name => $row ) {
-                                               if ( $fromName === false || $neg * strcmp( $name, $fromName ) <= 0 ) {
-                                                       $user = $row ? User::newFromRow( $row ) : User::newFromName( $name, false );
-                                                       yield $user;
-                                               }
-                                       }
-                               } );
-                       }
-                       $batchSize = count( $names );
-               }
-
-               // During migration, force ordering on the client side because we're
-               // having to combine multiple queries that would otherwise have
-               // different sort orders.
-               if ( $wgActorTableSchemaMigrationStage === MIGRATION_WRITE_BOTH ||
-                       $wgActorTableSchemaMigrationStage === MIGRATION_WRITE_NEW
-               ) {
-                       $batchSize = 1;
-               }
-
-               // With the new schema, the DB query will order by actor so update $this->orderBy to match.
-               if ( $batchSize > 1 && $wgActorTableSchemaMigrationStage === MIGRATION_NEW ) {
-                       $this->orderBy = 'actor';
-               }
-
-               $count = 0;
-               $limit = $this->params['limit'];
-               $userIter->rewind();
-               while ( $userIter->valid() ) {
-                       $users = [];
-                       while ( count( $users ) < $batchSize && $userIter->valid() ) {
-                               $users[] = $userIter->current();
-                               $userIter->next();
-                       }
-
-                       // Ugh. We have to run the query three times, once for each
-                       // possible 'orcond' from ActorMigration, and then merge them all
-                       // together in the proper order. And preserving the correct
-                       // $hookData for each one.
-                       // @todo When ActorMigration is removed, this can go back to a
-                       //  single prepare and select.
-                       $merged = [];
-                       foreach ( [ 'actor', 'userid', 'username' ] as $which ) {
-                               if ( $this->prepareQuery( $users, $limit - $count, $which ) ) {
-                                       $hookData = [];
-                                       $res = $this->select( __METHOD__, [], $hookData );
-                                       foreach ( $res as $row ) {
-                                               $merged[] = [ $row, &$hookData ];
-                                       }
-                               }
-                       }
-                       $neg = $this->params['dir'] == 'newer' ? 1 : -1;
-                       usort( $merged, function ( $a, $b ) use ( $neg, $batchSize ) {
-                               if ( $batchSize === 1 ) { // One user, can't be different
-                                       $ret = 0;
-                               } elseif ( $this->orderBy === 'id' ) {
-                                       $ret = $a[0]->rev_user - $b[0]->rev_user;
-                               } elseif ( $this->orderBy === 'name' ) {
-                                       $ret = strcmp( $a[0]->rev_user_text, $b[0]->rev_user_text );
-                               } else {
-                                       $ret = $a[0]->rev_actor - $b[0]->rev_actor;
-                               }
-
-                               if ( !$ret ) {
-                                       $ret = strcmp(
-                                               wfTimestamp( TS_MW, $a[0]->rev_timestamp ),
-                                               wfTimestamp( TS_MW, $b[0]->rev_timestamp )
-                                       );
-                               }
-
-                               if ( !$ret ) {
-                                       $ret = $a[0]->rev_id - $b[0]->rev_id;
-                               }
-
-                               return $neg * $ret;
-                       } );
-                       $merged = array_slice( $merged, 0, $limit - $count + 1 );
-                       // (end "Ugh")
-
-                       if ( $this->fld_sizediff ) {
-                               $revIds = [];
-                               foreach ( $merged as $data ) {
-                                       if ( $data[0]->rev_parent_id ) {
-                                               $revIds[] = $data[0]->rev_parent_id;
-                                       }
-                               }
-                               $this->parentLens = Revision::getParentLengths( $dbSecondary, $revIds );
-                       }
-
-                       foreach ( $merged as $data ) {
-                               $row = $data[0];
-                               $hookData = &$data[1];
-                               if ( ++$count > $limit ) {
-                                       // We've reached the one extra which shows that there are
-                                       // additional pages to be had. Stop here...
-                                       $this->setContinueEnumParameter( 'continue', $this->continueStr( $row ) );
-                                       break 2;
-                               }
-
-                               $vals = $this->extractRowInfo( $row );
-                               $fit = $this->processRow( $row, $vals, $hookData ) &&
-                                       $this->getResult()->addValue( [ 'query', $this->getModuleName() ], null, $vals );
-                               if ( !$fit ) {
-                                       $this->setContinueEnumParameter( 'continue', $this->continueStr( $row ) );
-                                       break 2;
-                               }
-                       }
-               }
-
-               $this->getResult()->addIndexedTagName( [ 'query', $this->getModuleName() ], 'item' );
-       }
-
-       /**
-        * Prepares the query and returns the limit of rows requested
-        * @param User[] $users
-        * @param int $limit
-        * @param string $which 'actor', 'userid', or 'username'
-        * @return bool
-        */
-       private function prepareQuery( array $users, $limit, $which ) {
-               global $wgActorTableSchemaMigrationStage;
-
-               $this->resetQueryParams();
-               $db = $this->getDB();
-
-               $revQuery = Revision::getQueryInfo( [ 'page' ] );
-               $this->addTables( $revQuery['tables'] );
-               $this->addJoinConds( $revQuery['joins'] );
-               $this->addFields( $revQuery['fields'] );
-
-               $revWhere = ActorMigration::newMigration()->getWhere( $db, 'rev_user', $users );
-               if ( !isset( $revWhere['orconds'][$which] ) ) {
-                       return false;
-               }
-               $this->addWhere( $revWhere['orconds'][$which] );
-
-               if ( $wgActorTableSchemaMigrationStage === MIGRATION_NEW ) {
-                       $orderUserField = 'rev_actor';
-                       $userField = $this->orderBy === 'actor' ? 'revactor_actor' : 'actor_name';
-               } else {
-                       $orderUserField = $this->orderBy === 'id' ? 'rev_user' : 'rev_user_text';
-                       $userField = $revQuery['fields'][$orderUserField];
-               }
-               if ( $which === 'actor' ) {
-                       $tsField = 'revactor_timestamp';
-                       $idField = 'revactor_rev';
-               } else {
-                       $tsField = 'rev_timestamp';
-                       $idField = 'rev_id';
-               }
-
-               // Handle continue parameter
-               if ( !is_null( $this->params['continue'] ) ) {
-                       $continue = explode( '|', $this->params['continue'] );
-                       if ( $this->multiUserMode ) {
-                               $this->dieContinueUsageIf( count( $continue ) != 4 );
-                               $modeFlag = array_shift( $continue );
-                               $this->dieContinueUsageIf( $modeFlag !== $this->orderBy );
-                               $encUser = $db->addQuotes( array_shift( $continue ) );
-                       } else {
-                               $this->dieContinueUsageIf( count( $continue ) != 2 );
-                       }
-                       $encTS = $db->addQuotes( $db->timestamp( $continue[0] ) );
-                       $encId = (int)$continue[1];
-                       $this->dieContinueUsageIf( $encId != $continue[1] );
-                       $op = ( $this->params['dir'] == 'older' ? '<' : '>' );
-                       if ( $this->multiUserMode ) {
-                               $this->addWhere(
-                                       "$userField $op $encUser OR " .
-                                       "($userField = $encUser AND " .
-                                       "($tsField $op $encTS OR " .
-                                       "($tsField = $encTS AND " .
-                                       "$idField $op= $encId)))"
-                               );
-                       } else {
-                               $this->addWhere(
-                                       "$tsField $op $encTS OR " .
-                                       "($tsField = $encTS AND " .
-                                       "$idField $op= $encId)"
-                               );
-                       }
-               }
-
-               // Don't include any revisions where we're not supposed to be able to
-               // see the username.
-               $user = $this->getUser();
-               if ( !$user->isAllowed( 'deletedhistory' ) ) {
-                       $bitmask = Revision::DELETED_USER;
-               } elseif ( !$user->isAllowedAny( 'suppressrevision', 'viewsuppressed' ) ) {
-                       $bitmask = Revision::DELETED_USER | Revision::DELETED_RESTRICTED;
-               } else {
-                       $bitmask = 0;
-               }
-               if ( $bitmask ) {
-                       $this->addWhere( $db->bitAnd( 'rev_deleted', $bitmask ) . " != $bitmask" );
-               }
-
-               // Add the user field to ORDER BY if there are multiple users
-               if ( count( $users ) > 1 ) {
-                       $this->addWhereRange( $orderUserField, $this->params['dir'], null, null );
-               }
-
-               // Then timestamp
-               $this->addTimestampWhereRange( $tsField,
-                       $this->params['dir'], $this->params['start'], $this->params['end'] );
-
-               // Then rev_id for a total ordering
-               $this->addWhereRange( $idField, $this->params['dir'], null, null );
-
-               $this->addWhereFld( 'page_namespace', $this->params['namespace'] );
-
-               $show = $this->params['show'];
-               if ( $this->params['toponly'] ) { // deprecated/old param
-                       $show[] = 'top';
-               }
-               if ( !is_null( $show ) ) {
-                       $show = array_flip( $show );
-
-                       if ( ( isset( $show['minor'] ) && isset( $show['!minor'] ) )
-                               || ( isset( $show['patrolled'] ) && isset( $show['!patrolled'] ) )
-                               || ( isset( $show['autopatrolled'] ) && isset( $show['!autopatrolled'] ) )
-                               || ( isset( $show['autopatrolled'] ) && isset( $show['!patrolled'] ) )
-                               || ( isset( $show['top'] ) && isset( $show['!top'] ) )
-                               || ( isset( $show['new'] ) && isset( $show['!new'] ) )
-                       ) {
-                               $this->dieWithError( 'apierror-show' );
-                       }
-
-                       $this->addWhereIf( 'rev_minor_edit = 0', isset( $show['!minor'] ) );
-                       $this->addWhereIf( 'rev_minor_edit != 0', isset( $show['minor'] ) );
-                       $this->addWhereIf(
-                               'rc_patrolled = ' . RecentChange::PRC_UNPATROLLED,
-                               isset( $show['!patrolled'] )
-                       );
-                       $this->addWhereIf(
-                               'rc_patrolled != ' . RecentChange::PRC_UNPATROLLED,
-                               isset( $show['patrolled'] )
-                       );
-                       $this->addWhereIf(
-                               'rc_patrolled != ' . RecentChange::PRC_AUTOPATROLLED,
-                               isset( $show['!autopatrolled'] )
-                       );
-                       $this->addWhereIf(
-                               'rc_patrolled = ' . RecentChange::PRC_AUTOPATROLLED,
-                               isset( $show['autopatrolled'] )
-                       );
-                       $this->addWhereIf( $idField . ' != page_latest', isset( $show['!top'] ) );
-                       $this->addWhereIf( $idField . ' = page_latest', isset( $show['top'] ) );
-                       $this->addWhereIf( 'rev_parent_id != 0', isset( $show['!new'] ) );
-                       $this->addWhereIf( 'rev_parent_id = 0', isset( $show['new'] ) );
-               }
-               $this->addOption( 'LIMIT', $limit + 1 );
-
-               if ( isset( $show['patrolled'] ) || isset( $show['!patrolled'] ) ||
-                       isset( $show['autopatrolled'] ) || isset( $show['!autopatrolled'] ) || $this->fld_patrolled
-               ) {
-                       if ( !$user->useRCPatrol() && !$user->useNPPatrol() ) {
-                               $this->dieWithError( 'apierror-permissiondenied-patrolflag', 'permissiondenied' );
-                       }
-
-                       $isFilterset = isset( $show['patrolled'] ) || isset( $show['!patrolled'] ) ||
-                               isset( $show['autopatrolled'] ) || isset( $show['!autopatrolled'] );
-                       $this->addTables( 'recentchanges' );
-                       $this->addJoinConds( [ 'recentchanges' => [
-                               $isFilterset ? 'JOIN' : 'LEFT JOIN',
-                               [
-                                       // This is a crazy hack. recentchanges has no index on rc_this_oldid, so instead of adding
-                                       // one T19237 did a join using rc_user_text and rc_timestamp instead. Now rc_user_text is
-                                       // probably unavailable, so just do rc_timestamp.
-                                       'rc_timestamp = ' . $tsField,
-                                       'rc_this_oldid = ' . $idField,
-                               ]
-                       ] ] );
-               }
-
-               $this->addFieldsIf( 'rc_patrolled', $this->fld_patrolled );
-
-               if ( $this->fld_tags ) {
-                       $this->addTables( 'tag_summary' );
-                       $this->addJoinConds(
-                               [ 'tag_summary' => [ 'LEFT JOIN', [ $idField . ' = ts_rev_id' ] ] ]
-                       );
-                       $this->addFields( 'ts_tags' );
-               }
-
-               if ( isset( $this->params['tag'] ) ) {
-                       $this->addTables( 'change_tag' );
-                       $this->addJoinConds(
-                               [ 'change_tag' => [ 'INNER JOIN', [ $idField . ' = ct_rev_id' ] ] ]
-                       );
-                       $this->addWhereFld( 'ct_tag', $this->params['tag'] );
-               }
-
-               return true;
-       }
-
-       /**
-        * Extract fields from the database row and append them to a result array
-        *
-        * @param stdClass $row
-        * @return array
-        */
-       private function extractRowInfo( $row ) {
-               $vals = [];
-               $anyHidden = false;
-
-               if ( $row->rev_deleted & Revision::DELETED_TEXT ) {
-                       $vals['texthidden'] = true;
-                       $anyHidden = true;
-               }
-
-               // Any rows where we can't view the user were filtered out in the query.
-               $vals['userid'] = (int)$row->rev_user;
-               $vals['user'] = $row->rev_user_text;
-               if ( $row->rev_deleted & Revision::DELETED_USER ) {
-                       $vals['userhidden'] = true;
-                       $anyHidden = true;
-               }
-               if ( $this->fld_ids ) {
-                       $vals['pageid'] = intval( $row->rev_page );
-                       $vals['revid'] = intval( $row->rev_id );
-                       // $vals['textid'] = intval( $row->rev_text_id ); // todo: Should this field be exposed?
-
-                       if ( !is_null( $row->rev_parent_id ) ) {
-                               $vals['parentid'] = intval( $row->rev_parent_id );
-                       }
-               }
-
-               $title = Title::makeTitle( $row->page_namespace, $row->page_title );
-
-               if ( $this->fld_title ) {
-                       ApiQueryBase::addTitleInfo( $vals, $title );
-               }
-
-               if ( $this->fld_timestamp ) {
-                       $vals['timestamp'] = wfTimestamp( TS_ISO_8601, $row->rev_timestamp );
-               }
-
-               if ( $this->fld_flags ) {
-                       $vals['new'] = $row->rev_parent_id == 0 && !is_null( $row->rev_parent_id );
-                       $vals['minor'] = (bool)$row->rev_minor_edit;
-                       $vals['top'] = $row->page_latest == $row->rev_id;
-               }
-
-               if ( $this->fld_comment || $this->fld_parsedcomment ) {
-                       if ( $row->rev_deleted & Revision::DELETED_COMMENT ) {
-                               $vals['commenthidden'] = true;
-                               $anyHidden = true;
-                       }
-
-                       $userCanView = Revision::userCanBitfield(
-                               $row->rev_deleted,
-                               Revision::DELETED_COMMENT, $this->getUser()
-                       );
-
-                       if ( $userCanView ) {
-                               $comment = $this->commentStore->getComment( 'rev_comment', $row )->text;
-                               if ( $this->fld_comment ) {
-                                       $vals['comment'] = $comment;
-                               }
-
-                               if ( $this->fld_parsedcomment ) {
-                                       $vals['parsedcomment'] = Linker::formatComment( $comment, $title );
-                               }
-                       }
-               }
-
-               if ( $this->fld_patrolled ) {
-                       $vals['patrolled'] = $row->rc_patrolled != RecentChange::PRC_UNPATROLLED;
-                       $vals['autopatrolled'] = $row->rc_patrolled == RecentChange::PRC_AUTOPATROLLED;
-               }
-
-               if ( $this->fld_size && !is_null( $row->rev_len ) ) {
-                       $vals['size'] = intval( $row->rev_len );
-               }
-
-               if ( $this->fld_sizediff
-                       && !is_null( $row->rev_len )
-                       && !is_null( $row->rev_parent_id )
-               ) {
-                       $parentLen = isset( $this->parentLens[$row->rev_parent_id] )
-                               ? $this->parentLens[$row->rev_parent_id]
-                               : 0;
-                       $vals['sizediff'] = intval( $row->rev_len - $parentLen );
-               }
-
-               if ( $this->fld_tags ) {
-                       if ( $row->ts_tags ) {
-                               $tags = explode( ',', $row->ts_tags );
-                               ApiResult::setIndexedTagName( $tags, 'tag' );
-                               $vals['tags'] = $tags;
-                       } else {
-                               $vals['tags'] = [];
-                       }
-               }
-
-               if ( $anyHidden && $row->rev_deleted & Revision::DELETED_RESTRICTED ) {
-                       $vals['suppressed'] = true;
-               }
-
-               return $vals;
-       }
-
-       private function continueStr( $row ) {
-               if ( $this->multiUserMode ) {
-                       switch ( $this->orderBy ) {
-                               case 'id':
-                                       return "id|$row->rev_user|$row->rev_timestamp|$row->rev_id";
-                               case 'name':
-                                       return "name|$row->rev_user_text|$row->rev_timestamp|$row->rev_id";
-                               case 'actor':
-                                       return "actor|$row->rev_actor|$row->rev_timestamp|$row->rev_id";
-                       }
-               } else {
-                       return "$row->rev_timestamp|$row->rev_id";
-               }
-       }
-
-       public function getCacheMode( $params ) {
-               // This module provides access to deleted revisions and patrol flags if
-               // the requester is logged in
-               return 'anon-public-user-private';
-       }
-
-       public function getAllowedParams() {
-               return [
-                       'limit' => [
-                               ApiBase::PARAM_DFLT => 10,
-                               ApiBase::PARAM_TYPE => 'limit',
-                               ApiBase::PARAM_MIN => 1,
-                               ApiBase::PARAM_MAX => ApiBase::LIMIT_BIG1,
-                               ApiBase::PARAM_MAX2 => ApiBase::LIMIT_BIG2
-                       ],
-                       'start' => [
-                               ApiBase::PARAM_TYPE => 'timestamp'
-                       ],
-                       'end' => [
-                               ApiBase::PARAM_TYPE => 'timestamp'
-                       ],
-                       'continue' => [
-                               ApiBase::PARAM_HELP_MSG => 'api-help-param-continue',
-                       ],
-                       'user' => [
-                               ApiBase::PARAM_TYPE => 'user',
-                               ApiBase::PARAM_ISMULTI => true
-                       ],
-                       'userids' => [
-                               ApiBase::PARAM_TYPE => 'integer',
-                               ApiBase::PARAM_ISMULTI => true
-                       ],
-                       'userprefix' => null,
-                       'dir' => [
-                               ApiBase::PARAM_DFLT => 'older',
-                               ApiBase::PARAM_TYPE => [
-                                       'newer',
-                                       'older'
-                               ],
-                               ApiBase::PARAM_HELP_MSG => 'api-help-param-direction',
-                       ],
-                       'namespace' => [
-                               ApiBase::PARAM_ISMULTI => true,
-                               ApiBase::PARAM_TYPE => 'namespace'
-                       ],
-                       'prop' => [
-                               ApiBase::PARAM_ISMULTI => true,
-                               ApiBase::PARAM_DFLT => 'ids|title|timestamp|comment|size|flags',
-                               ApiBase::PARAM_TYPE => [
-                                       'ids',
-                                       'title',
-                                       'timestamp',
-                                       'comment',
-                                       'parsedcomment',
-                                       'size',
-                                       'sizediff',
-                                       'flags',
-                                       'patrolled',
-                                       'tags'
-                               ],
-                               ApiBase::PARAM_HELP_MSG_PER_VALUE => [],
-                       ],
-                       'show' => [
-                               ApiBase::PARAM_ISMULTI => true,
-                               ApiBase::PARAM_TYPE => [
-                                       'minor',
-                                       '!minor',
-                                       'patrolled',
-                                       '!patrolled',
-                                       'autopatrolled',
-                                       '!autopatrolled',
-                                       'top',
-                                       '!top',
-                                       'new',
-                                       '!new',
-                               ],
-                               ApiBase::PARAM_HELP_MSG => [
-                                       'apihelp-query+usercontribs-param-show',
-                                       $this->getConfig()->get( 'RCMaxAge' )
-                               ],
-                       ],
-                       'tag' => null,
-                       'toponly' => [
-                               ApiBase::PARAM_DFLT => false,
-                               ApiBase::PARAM_DEPRECATED => true,
-                       ],
-               ];
-       }
-
-       protected function getExamplesMessages() {
-               return [
-                       'action=query&list=usercontribs&ucuser=Example'
-                               => 'apihelp-query+usercontribs-example-user',
-                       'action=query&list=usercontribs&ucuserprefix=192.0.2.'
-                               => 'apihelp-query+usercontribs-example-ipprefix',
-               ];
-       }
-
-       public function getHelpUrls() {
-               return 'https://www.mediawiki.org/wiki/Special:MyLanguage/API:Usercontribs';
-       }
-}
diff --git a/includes/api/ApiRawMessage.php b/includes/api/ApiRawMessage.php
new file mode 100644 (file)
index 0000000..ed3537a
--- /dev/null
@@ -0,0 +1,52 @@
+<?php
+/**
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ */
+
+/**
+ * Extension of RawMessage implementing IApiMessage
+ * @since 1.25
+ * @ingroup API
+ */
+class ApiRawMessage extends RawMessage implements IApiMessage {
+       use ApiMessageTrait;
+
+       /**
+        * @param RawMessage|string|array $msg
+        *  - RawMessage: is cloned
+        *  - array: first element is $key, rest are $params to RawMessage::__construct
+        *  - string: passed to RawMessage::__construct
+        * @param string|null $code
+        * @param array|null $data
+        */
+       public function __construct( $msg, $code = null, array $data = null ) {
+               if ( $msg instanceof RawMessage ) {
+                       foreach ( get_class_vars( get_class( $this ) ) as $key => $value ) {
+                               if ( isset( $msg->$key ) ) {
+                                       $this->$key = $msg->$key;
+                               }
+                       }
+               } elseif ( is_array( $msg ) ) {
+                       $key = array_shift( $msg );
+                       parent::__construct( $key, $msg );
+               } else {
+                       parent::__construct( $msg );
+               }
+               $this->setApiCode( $code, $data );
+       }
+}
index c200dcb..7f8a26b 100644 (file)
  * @file
  */
 
-/**
- * This exception will be thrown when dieUsage is called to stop module execution.
- *
- * @ingroup API
- * @deprecated since 1.29, use ApiUsageException instead
- */
-class UsageException extends MWException {
-
-       private $mCodestr;
-
-       /**
-        * @var null|array
-        */
-       private $mExtraData;
-
-       /**
-        * @param string $message
-        * @param string $codestr
-        * @param int $code
-        * @param array|null $extradata
-        */
-       public function __construct( $message, $codestr, $code = 0, $extradata = null ) {
-               parent::__construct( $message, $code );
-               $this->mCodestr = $codestr;
-               $this->mExtraData = $extradata;
-
-               if ( !$this instanceof ApiUsageException ) {
-                       wfDeprecated( __METHOD__, '1.29' );
-               }
-
-               // This should never happen, so throw an exception about it that will
-               // hopefully get logged with a backtrace (T138585)
-               if ( !is_string( $codestr ) || $codestr === '' ) {
-                       throw new InvalidArgumentException( 'Invalid $codestr, was ' .
-                               ( $codestr === '' ? 'empty string' : gettype( $codestr ) )
-                       );
-               }
-       }
-
-       /**
-        * @return string
-        */
-       public function getCodeString() {
-               wfDeprecated( __METHOD__, '1.29' );
-               return $this->mCodestr;
-       }
-
-       /**
-        * @return array
-        */
-       public function getMessageArray() {
-               wfDeprecated( __METHOD__, '1.29' );
-               $result = [
-                       'code' => $this->mCodestr,
-                       'info' => $this->getMessage()
-               ];
-               if ( is_array( $this->mExtraData ) ) {
-                       $result = array_merge( $result, $this->mExtraData );
-               }
-
-               return $result;
-       }
-
-       /**
-        * @return string
-        */
-       public function __toString() {
-               return "{$this->getCodeString()}: {$this->getMessage()}";
-       }
-}
-
 /**
  * Exception used to abort API execution with an error
  *
diff --git a/includes/api/IApiMessage.php b/includes/api/IApiMessage.php
new file mode 100644 (file)
index 0000000..fee62c5
--- /dev/null
@@ -0,0 +1,69 @@
+<?php
+/**
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ */
+
+/**
+ * Interface for messages with machine-readable data for use by the API
+ *
+ * The idea is that it's a Message that has some extra data for the API to use when interpreting it
+ * as an error (or, in the future, as a warning). Internals of MediaWiki often use messages (or
+ * message keys, or Status objects containing messages) to pass information about errors to the user
+ * (see e.g. Title::getUserPermissionsErrors()) and the API has to make do with that.
+ *
+ * @since 1.25
+ * @note This interface exists to work around PHP's inheritance, so ApiMessage
+ *  can extend Message and ApiRawMessage can extend RawMessage while still
+ *  allowing an instanceof check for a Message object including this
+ *  functionality. If for some reason you feel the need to implement this
+ *  interface on some other class, that class must also implement all the
+ *  public methods the Message class provides (not just those from
+ *  MessageSpecifier, which as written is fairly useless).
+ * @ingroup API
+ */
+interface IApiMessage extends MessageSpecifier {
+       /**
+        * Returns a machine-readable code for use by the API
+        *
+        * If no code was specifically set, the message key is used as the code
+        * after removing "apiwarn-" or "apierror-" prefixes and applying
+        * backwards-compatibility mappings.
+        *
+        * @return string
+        */
+       public function getApiCode();
+
+       /**
+        * Returns additional machine-readable data about the error condition
+        * @return array
+        */
+       public function getApiData();
+
+       /**
+        * Sets the machine-readable code for use by the API
+        * @param string|null $code If null, uses the default (see self::getApiCode())
+        * @param array|null $data If non-null, passed to self::setApiData()
+        */
+       public function setApiCode( $code, array $data = null );
+
+       /**
+        * Sets additional machine-readable data about the error condition
+        * @param array $data
+        */
+       public function setApiData( array $data );
+}
diff --git a/includes/api/UsageException.php b/includes/api/UsageException.php
new file mode 100644 (file)
index 0000000..426ce91
--- /dev/null
@@ -0,0 +1,90 @@
+<?php
+/**
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ */
+
+/**
+ * This exception will be thrown when dieUsage is called to stop module execution.
+ *
+ * @ingroup API
+ * @deprecated since 1.29, use ApiUsageException instead
+ */
+class UsageException extends MWException {
+
+       private $mCodestr;
+
+       /**
+        * @var null|array
+        */
+       private $mExtraData;
+
+       /**
+        * @param string $message
+        * @param string $codestr
+        * @param int $code
+        * @param array|null $extradata
+        */
+       public function __construct( $message, $codestr, $code = 0, $extradata = null ) {
+               parent::__construct( $message, $code );
+               $this->mCodestr = $codestr;
+               $this->mExtraData = $extradata;
+
+               if ( !$this instanceof ApiUsageException ) {
+                       wfDeprecated( __METHOD__, '1.29' );
+               }
+
+               // This should never happen, so throw an exception about it that will
+               // hopefully get logged with a backtrace (T138585)
+               if ( !is_string( $codestr ) || $codestr === '' ) {
+                       throw new InvalidArgumentException( 'Invalid $codestr, was ' .
+                               ( $codestr === '' ? 'empty string' : gettype( $codestr ) )
+                       );
+               }
+       }
+
+       /**
+        * @return string
+        */
+       public function getCodeString() {
+               wfDeprecated( __METHOD__, '1.29' );
+               return $this->mCodestr;
+       }
+
+       /**
+        * @return array
+        */
+       public function getMessageArray() {
+               wfDeprecated( __METHOD__, '1.29' );
+               $result = [
+                       'code' => $this->mCodestr,
+                       'info' => $this->getMessage()
+               ];
+               if ( is_array( $this->mExtraData ) ) {
+                       $result = array_merge( $result, $this->mExtraData );
+               }
+
+               return $result;
+       }
+
+       /**
+        * @return string
+        */
+       public function __toString() {
+               return "{$this->getCodeString()}: {$this->getMessage()}";
+       }
+}
index 574c94b..dece40e 100644 (file)
@@ -28,6 +28,7 @@
        "apihelp-main-param-responselanginfo": "تشمل اللغات المستخدمة لأجل <var>uselang</var> and <var>errorlang</var> في النتيجة.",
        "apihelp-main-param-origin": "عند الوصول إلى API باستخدام طلب AJAX عبر النطاقات (CORS)، اضبطها على النطاق الأصلي، يجب تضمين هذا في أي طلب ما قبل الطيران، وبالتالي يجب أن يكون جزءا من طلب URI (وليس جسم POST). \n\nبالنسبة للطلبات المصادقة، يجب أن يتطابق هذا مع أحد المصادر الموجودة في الرأس<code>Origin</code> بالضبط; لذا يجب تعيينه على شيء مثل<kbd>https://en.wikipedia.org</kbd> أو <kbd>https://meta.wikimedia.org</kbd>، إذا لم يتطابق هذا الوسيط مع الرأس<code>Origin</code>، فسيتم إرجاع استجابة 403، إذا كان هذا الوسيط مطابقا للرأس <code>Origin</code>، ستتم إضافة الأصل إلى القائمة البيضاء، سيتم تعيين الرؤوس <code>Access-Control-Allow-Origin</code> و<code>Access-Control-Allow-Credentials</code>.\n\nبالنسبة للطلبات غير المصادقة، حدد القيمة <kbd>*</kbd>، سيؤدي ذلك إلى تعيين الرأس <code>Access-Control-Allow-Origin</code>، ولكن <code>Access-Control-Allow-Credentials</code> سيكون <code>false</code> وسيتم تقييد كل البيانات الخاصة بالمستخدم.",
        "apihelp-main-param-uselang": "اللغة المستخدمة لترجمة الرسائل. <kbd>[[Special:ApiHelp/query+siteinfo|action=query&meta=siteinfo]]</kbd> بـ<kbd>siprop=languages</kbd> يقوم بإرجاع قائمة أكواد اللغة، أو تحديد <kbd>user</kbd> لاستخدام تفضيل اللغة للمستخدم الحالي، أو تحديد <kbd>content</kbd> لاستخدام لغة محتوى الويكي هذا.",
+       "apihelp-main-param-errorformat": "تنسيق لاستخدامه في التحذير وإخراج نص الخطأ. \n; نص عادي: إزالة نص الويكي ذي وسوم HTML واستبدال الكيانات.\n; نص الويكي: نص ويكي غير مقتبس.\n; html: HTML.\n; خام: مفتاح ووسائط الرسالة.\n; لا شيء: لا يوجد إخراج نص، فقط رموز الخطأ.\n; bc: التنسيق المستخدم قبل ميدياويكي 1.29، يتم تجاهل <var>errorlang</var> و<var>errorsuselocal</var>.",
        "apihelp-main-param-errorlang": "لغة لاستخدامها في التحذيرات والأخطاء. <kbd>[[Special:ApiHelp/query+siteinfo|action=query&meta=siteinfo]]</kbd> بـ<kbd>siprop=languages</kbd> يقوم بإرجاع قائمة أكواد اللغة، أو تحديد <kbd>content</kbd> لاستخدام لغة محتوى الويكي هذا، أو تحديد <kbd>uselang</kbd> لاستخدام نفس القيمة كوسيط <var>uselang</var>.",
        "apihelp-main-param-errorsuselocal": "إذا ما أعطيت، النصوص الخطأ ستستخدم الرسائل المخصصة محليا من نطاق {{ns:MediaWiki}}.",
        "apihelp-block-summary": "منع مستخدم.",
        "apihelp-imagerotate-example-simple": "تدوير <kbd>File:Example.png</kbd> بمقدار <kbd>90</kbd> درجة.",
        "apihelp-imagerotate-example-generator": "تدوير جميع الصور في <kbd>Category:Flip</kbd> بمقدار <kbd>180</kbd> درجة.",
        "apihelp-import-summary": "استيراد صفحة من موقع ويكي آخر أو من ملف XML.",
+       "apihelp-import-extended-description": "لاحظ أنه يجب أن يتم إجراء POST HTTP كرفع ملف (أي باستخدام بيانات متعددة الأجزاء/النماذج) عند إرسال ملف للوسيط <var>xml</var>.",
        "apihelp-import-param-summary": "ملخص إدخال سجل الاستيراد.",
        "apihelp-import-param-xml": "ملف XML مرفوع.",
        "apihelp-import-param-interwikiprefix": "بالنسبة للواردات المرفوعة: بادئة إنترويكي لتطبيقها على أسماء مستخدمين غير معروفة (والمستخدمين المعروفين إذا تم تعيين <var>$1assignknownusers</var>).",
        "apihelp-logout-example-logout": "تسجيل خروج المستخدم الحالي.",
        "apihelp-managetags-summary": "أداء المهام الإدارية المتعلقة بتغيير الوسوم.",
        "apihelp-managetags-param-operation": "أي الإجراءات ستنفذ:\n؛ إنشاء: إنشاء وسم التغيير جديدة للاستخدام اليدوي.\n؛ حذف: إزالة وسم التغيير من قاعدة البيانات، بما في ذلك إزالة الوسم من كافة المراجعات، وإدخالات التغيير الأخيرة، وإدخالات السجل المستخدم.\n؛ تنشيط: تنشيط وسم التغيير، مما يسمح للمستخدمين بتطبيقه يدويا.\n; إلغاء: إلغاء تنشيط وسم التغيير، ومنع المستخدمين من تطبيقه يدويا.",
+       "apihelp-managetags-param-tag": "وسم لإنشاء أو حذف أو تنشيط أو إلغاء تنشيط. لإنشاء وسم; يجب ألا يكون الوسم موجودا، لحذف وسم; يجب أن يكون الوسم موجودا، لتنشيط وسم; يجب أن يكون الوسم موجودا وغير مستخدم بواسطة إضافة، لإلغاء تنشيط وسم; يجب أن يكون الوسم نشطا في الوقت الحالي ويتم تحديدها يدويا.",
        "apihelp-managetags-param-reason": "سبب اختياري لإنشاء، وحذف، وتفعيل أو تعطيل الوسم.",
        "apihelp-managetags-param-ignorewarnings": "إذا كان سيتم تجاهل أي تحذيرات تصدر خلال العملية.",
+       "apihelp-managetags-param-tags": "تغيير الوسوم لتطبيق الإدخال في سجل الحذف إدارة الوسوم.",
        "apihelp-managetags-example-create": "إنشاء وسم مسمى <kbd>spam</kbd> بسبب <kbd>For use in edit patrolling</kbd>",
        "apihelp-managetags-example-delete": "حذف <kbd>vandlaism</kbd> وسم بسبب <kbd>Misspelt</kbd>",
        "apihelp-managetags-example-activate": "تنشيط الوسم المسمى <kbd>spam</kbd> بسبب <kbd>For use in edit patrolling</kbd>",
        "apihelp-move-param-noredirect": "لا تنشئ تحويلة.",
        "apihelp-move-param-watch": "إضافة الصفحة والتحويلة إلى قائمة مراقبة المستخدم الحالي.",
        "apihelp-move-param-unwatch": "إزالة الصفحة والتحويلة إلى قائمة مراقبة المستخدم الحالي.",
+       "apihelp-move-param-watchlist": "إضافة أو إزالة الصفحة من قائمة مراقبة المستخدم الحالي أو استخدام التفضيلات أو عدم تغيير المراقبة دون قيد أو شرط.",
        "apihelp-move-param-ignorewarnings": "تجاهل أي تحذيرات.",
+       "apihelp-move-param-tags": "غير الوسوم لتطبيقها على الإدخال في سجل النقل وعلى النسخة الفارغة في الصفحة الوجهة.",
        "apihelp-move-example-move": "انقل <kbd>Badtitle</kbd> إلى <kbd>Goodtitle</kbd> دون ترك تحويلة.",
        "apihelp-opensearch-summary": "بحث الويكي باستخدام بروتوكول أوبن سيرش OpenSearch.",
        "apihelp-opensearch-param-search": "سطر البحث",
        "apihelp-opensearch-param-limit": "الحد الأقصى للنتائج المُرجعة",
-       "apihelp-opensearch-param-namespace": "النطاقات للبحث.",
+       "apihelp-opensearch-param-namespace": "النطاقات للبحث، يتم التجاهل إذا بدأ <var>$1search</var> ببادئة نطاق صالحة.",
        "apihelp-opensearch-param-suggest": "لا تفعل شيئا إذا كان <var>[[mw:Special:MyLanguage/Manual:$wgEnableOpenSearchSuggest|$wgEnableOpenSearchSuggest]]</var> خاطئا.",
+       "apihelp-opensearch-param-redirects": "كيفية التعامل مع التحويلات:\n;إرجاع: إرجاع التحويلة نفسها.\n;حل: إرجاع الصفحة الهدف، قد ترجع نتائج أقل من $1limit.\nلأسباب تاريخية; يكون الإعداد الافتراضي هو \"إرجاع\" لـ$1format=json و\"حل\" للتنسيقات الأخرى.",
        "apihelp-opensearch-param-format": "شكل الإخراج.",
        "apihelp-opensearch-param-warningsaserror": "إذا تم رفع التحذيرات ب<kbd>format=json</kbd>, أعد أخطاء API بدلا من تجاهلها.",
        "apihelp-opensearch-example-te": "العثور على صفحات تبدأ ب<kbd>Te</kbd>.",
+       "apihelp-options-summary": "تغيير تفضيلات المستخدم الحالي.",
+       "apihelp-options-extended-description": "لا يمكن تعيين سوى الخيارات المسجلة في النواة أو في أحد الملحقات المثبتة، أو الخيارات مع المفاتيح المسبوقة بـ<code>userjs-</code> (التي يُراد استخدامها من قبل سكريبتات المستخدم).",
        "apihelp-options-param-reset": "إعادة تعيين التفضيلات إلى إعدادات الموقع الإفتراضية.",
        "apihelp-options-param-resetkinds": "قائمة أنواع الخيارات لإعادة ضبطها عندما يتم تعيين خيار <var>$1reset</var>.",
+       "apihelp-options-param-change": "قائمة بالتغييرات، الاسم المنسق=value (مثل skin=vector)، إذا لم يتم تحديد أية قيمة (ولا حتى علامة المساواة)، على سبيل المثال، optionname|otheroption|..., ستتم إعادة تعيين الخيار إلى قيمته الافتراضية، إذا كانت أية قيمة تم تمريرها تحتوي على حرف الأنبوب(<kbd>|</kbd>)، فاستخدم [[Special:ApiHelp/main#main/datatypes| فاصل بديل متعدد القيم]] للعملية الصحيحة.",
        "apihelp-options-param-optionname": "اسم الخيار الذي ينبغي ضبطه إلى القيمة التي قدمها <var>$1optionvalue</var>.",
        "apihelp-options-param-optionvalue": "قيمة للخيار المحدد من قبل <var>$1optionname</var>.",
        "apihelp-options-example-reset": "إعادة تعيين كل التفضيلات.",
        "apihelp-options-example-change": "غير تفضيلات <kbd>skin</kbd> و<kbd>hideminor</kbd>.",
        "apihelp-options-example-complex": "إعادة تعيين جميع تفضيلات، ثم تعيين <kbd>skin</kbd> و<kbd>nickname</kbd>.",
        "apihelp-paraminfo-summary": "الحصول على معلومات حول وحدات API.",
+       "apihelp-paraminfo-param-modules": "قائمة بأسماء الوحدات (قيم الوسائط <var>action</var> أو <var>format</var> أو <kbd>main</kbd>)، يمكن تحديد الوحدات الفرعية التي تحتوي على <kbd>+</kbd>، أو كل الوحدات الفرعية التي تحتوي على <kbd>+*</kbd>، أو جميع الوحدات الفرعية بشكل متكرر بـ<kbd>+**</kbd>.",
        "apihelp-paraminfo-param-helpformat": "شكل سلاسل المساعدة.",
+       "apihelp-paraminfo-param-querymodules": "قائمة بأسماء وحدات الاستعلام (قيمة وسيط <var>prop</var> أو <var>meta</var> أو <var>list</var>)، استخدم <kbd>$1modules=query+foo</kbd> بدلا من <kbd>$1querymodules=foo</kbd>.",
        "apihelp-paraminfo-param-mainmodule": "الحصول على معلومات عن وحدة (المستوى الأعلى) الرئيسية أيضا. استخدم <kbd>$1modules=main</kbd> بدلا من ذلك.",
+       "apihelp-paraminfo-param-pagesetmodule": "الحصول على معلومات حول وحدة مجموعة الصفحة (يتم توفير titles= والأصدقاء) كذلك.",
        "apihelp-paraminfo-param-formatmodules": "قائمة بأسماء أشكال الوحدات (قيم الوسيط <var>format</var>). استخدم <var>$1modules</var> بدلا من ذلك.",
        "apihelp-paraminfo-example-1": "عرض معلومات عن <kbd>[[Special:ApiHelp/parse|action=parse]]</kbd> و<kbd>[[Special:ApiHelp/jsonfm|format=jsonfm]]</kbd> و<kbd>[[Special:ApiHelp/query+allpages|action=query&list=allpages]]</kbd> و<kbd>[[Special:ApiHelp/query+siteinfo|action=query&meta=siteinfo]]</kbd>.",
        "apihelp-paraminfo-example-2": "أظهر المعلومات لجميع الوحدات الفرعية ل<kbd>[[Special:ApiHelp/query|action=query]]</kbd>.",
+       "apihelp-parse-summary": "يوزع المحتوى ويرجع مخرجات المحلل.",
+       "apihelp-parse-extended-description": "راجع مختلف وحدات prop لـ<kbd>[[Special:ApiHelp/query|action=query]]</kbd>  للحصول على معلومات من الإصدار الحالي للصفحة.\n\nهناك عدة طرق لتحديد النص المراد تحليله: \n# حدد صفحة أو مراجعة، باستخدام <var>$1page</var> أو <var>$1pageid</var> أو <var>$1oldid</var>.\n# حدد المحتوى بشكل صريح، باستخدام <var>$1text</var> و<var>$1title</var> و<var>$1revid</var> و<var>$1contentmodel</var>.\n# تحديد ملخص للتحليل فقط، يجب إعطاء قيمة فارغة لـ<var>$1prop</var>.",
        "apihelp-parse-param-title": "عنوان الصفحة التي ينتمي النص إليها.إذا تم حذفها، <var>$1contentmodel</var> يجب أن تكون محددة، و[[API]] سيتم استخدامه كعنوان.",
        "apihelp-parse-param-text": "نص للتحليل. استخدم <var>$1title</var> أو <var>$1contentmodel</var> للتحكم في نموذج المحتوى.",
+       "apihelp-parse-param-revid": "معرف المراجعة، لـ<code><nowiki>{{REVISIONID}}</nowiki></code> ومتغيرات مشابهة.",
        "apihelp-parse-param-summary": "ملخص للتحليل.",
        "apihelp-parse-param-page": "تحليل محتوى هذه الصفحة. لا يمكن أن تُستخدَم بجانب <var>$1text</var> and <var>$1title</var>.",
        "apihelp-parse-param-pageid": "حلل محتوى هذه الصفحة. تجاوز <var>$1page</var>.",
        "apihelp-parse-param-redirects": "لو <var>$1page</var> أو <var>$1pageid</var> is تم تعيينها للتحويل، حلها.",
        "apihelp-parse-param-oldid": "تحليل مضمون هذا التعديل. تجاوز <var>$1page</var> و<var>$1pageid</var>.",
        "apihelp-parse-param-prop": "أي قطعة من المعلومات تريد الحصول عليها:",
+       "apihelp-parse-paramvalue-prop-text": "يعطي النص المعالج لنص الويكي.",
        "apihelp-parse-paramvalue-prop-langlinks": "يعطي وصلات اللغات في تحليل نصوص الويكي.",
        "apihelp-parse-paramvalue-prop-categories": "يعطي التصنيفات في تحليل نصوص الويكي.",
        "apihelp-parse-paramvalue-prop-categorieshtml": "يعطي إصدار HTML للتصنيفات.",
        "apihelp-parse-paramvalue-prop-images": "يعطي الصور في تحليل نصوص الويكي.",
        "apihelp-parse-paramvalue-prop-externallinks": "يعطي الوصلات الخارجية في تحليل نصوص الويكي.",
        "apihelp-parse-paramvalue-prop-sections": "يعطي الأقسام في تحليل نصوص الويكي.",
+       "apihelp-parse-paramvalue-prop-revid": "يضيف معرِف المراجعة للصفحة التي تم تحليلها.",
        "apihelp-parse-paramvalue-prop-displaytitle": "يضيف العنوان في تحليل نصوص الويكي.",
        "apihelp-parse-paramvalue-prop-headitems": "يعطي عناصر لوضعها في <code>&lt;head&gt;</code> الصفحة.",
        "apihelp-parse-paramvalue-prop-headhtml": "يعطي تحليل <code>&lt;head&gt;</code> الصفحة.",
+       "apihelp-parse-paramvalue-prop-modules": "يعطي وحدات ResourceLoader المستخدمة في الصفحة، للتحميل; استخدم <code>mw.loader.using()</code>، يجب طلب <kbd>jsconfigvars</kbd> أو <kbd>encodedjsconfigvars</kbd> بشكل مشترك مع <kbd>modules</kbd>.",
        "apihelp-parse-paramvalue-prop-jsconfigvars": "يعطي متغيرات تكوين جافا سكريبت الخاصة بهذه الصفحة. للتطبيق; استخدم <code>mw.config.set()</code>.",
        "apihelp-parse-paramvalue-prop-encodedjsconfigvars": "يعطي متغيرات تكوين جافا سكريبت الخاصة بهذه الصفحة كسلسلة JSON.",
        "apihelp-parse-paramvalue-prop-indicators": "يعطي HTML مؤشرات حالة الصفحة المستخدمة في الصفحة.",
        "apihelp-parse-paramvalue-prop-limitreportdata": "يعطي تقرير الحد بطريقة منظمة. لا يعطي أية بيانات، عندما يتم تعيين <var>$1disablelimitreport</var>.",
        "apihelp-parse-paramvalue-prop-limitreporthtml": "يعطي إصدار HTML لتقرير الحد. لا يعطي أية بيانات، عندما يتم تعيين<var>$1disablelimitreport</var>.",
        "apihelp-parse-paramvalue-prop-parsetree": "شجرة تحليل XML لمحتويات المراجعة (يتطلب نموذج محتوى <code>$1</code>)",
+       "apihelp-parse-paramvalue-prop-parsewarnings": "يعطي التحذيرات التي حدثت أثناء تحليل المحتوى.",
+       "apihelp-parse-param-wrapoutputclass": "فئة CSS لاستخدام التفاف إخراج المحلل.",
        "apihelp-parse-param-pst": "قم بتحويل قبل الحفظ على المدخلات قبل تحليل ذلك. صالح فقط عند استخدامه مع النص.",
+       "apihelp-parse-param-onlypst": "قم بإجراء تحويل ما قبل الحفظ (PST) على الإدخال، ولكن لا تقم بتحليله; لعرض نفس نص الويكي، بعد تطبيق PST، صالح فقط عند استخدامه مع <var>$1text</var>.",
        "apihelp-parse-param-effectivelanglinks": "يشمل وصلات لغة المقدمة بواسطة ملحقات (للاستخدام مع <kbd>$1prop=langlinks</kbd>).",
+       "apihelp-parse-param-section": "فقط تحليل محتوى رقم هذا القسم. \nعندما <kbd>new</kbd>، تحليل <var>$1text</var> و<var>$1sectiontitle</var> كما لو كانت إضافة قسم جديد إلى الصفحة.",
+       "apihelp-parse-param-sectiontitle": "عنوان قسم جديد عندما يكون <var>section</var> <kbd>new</kbd>.\n\nعلى عكس تحرير الصفحة، لا يرجع هذا إلى <var>summary</var> عند حذفه أو تفريغه.",
        "apihelp-parse-param-disablelimitreport": "تجاهل تقرير الحد (\"NewPP limit report\") من مخرجات المحلل.",
        "apihelp-parse-param-disablepp": "استخدم <var>$1disablelimitreport</var> بدلا من ذلك.",
        "apihelp-parse-param-disableeditsection": "تجاهل روابط تحرير الأقسام من مخرجات المحلل.",
        "apihelp-parse-param-disabletidy": "لا تشغل تنظيف HTML (على سبيل المثال مرتبة) على مخرجات المحلل.",
+       "apihelp-parse-param-disablestylededuplication": "لا تكرر أوراق الأنماط المضمنة في إخراج المحلل.",
        "apihelp-parse-param-generatexml": "توليد شجرة تحليل XML (يتطلب نموذج المحتوى <code>$1</code>; حل محلها <kbd>$2prop=parsetree</kbd>).",
        "apihelp-parse-param-preview": "تحليل في وضع المعاينة.",
        "apihelp-parse-param-sectionpreview": "تحليل في وضع معاينة القسم (يمكن وضع المعاينة أيضا).",
index 682de15..8328006 100644 (file)
        "apihelp-query+recentchanges-param-limit": "Cuántos cambios en total se devolverán.",
        "apihelp-query+recentchanges-param-type": "Cuántos tipos de cambios se mostrarán.",
        "apihelp-query+recentchanges-param-toponly": "Enumerar solo las modificaciones que sean las últimas revisiones.",
-       "apihelp-query+recentchanges-param-title": "Filtrar aquellas entradas que son relacionadas a una página",
+       "apihelp-query+recentchanges-param-title": "Filtrar entradas mostrando solo aquellas relacionadas con una página.",
        "apihelp-query+recentchanges-param-generaterevisions": "Cuando se utilice como generador, genera identificadores de revisión en lugar de títulos. Las entradas en la lista de cambios recientes que no tengan identificador de revisión asociado (por ejemplo, la mayoría de las entradas de registro) no generarán nada.",
        "apihelp-query+recentchanges-example-simple": "Lista de cambios recientes.",
        "apihelp-query+recentchanges-example-generator": "Obtener información de página de cambios recientes no patrullados.",
        "apierror-systemblocked": "Has sido bloqueado automáticamente por el software MediaWiki.",
        "apierror-templateexpansion-notwikitext": "La expansión de plantillas solo es compatible con el contenido en wikitexto. $1 usa el modelo de contenido $2.",
        "apierror-timeout": "El servidor no respondió en el plazo previsto.",
+       "apierror-toomanyvalues": "Se proporcionaron demasiados valores al parámetro <var>$1</var>. El límite es de $2.",
        "apierror-unknownaction": "La acción especificada, <kbd>$1</kbd>, no está reconocida.",
        "apierror-unknownerror-editpage": "Error de EditPage desconocido: $1.",
        "apierror-unknownerror-nocode": "Error desconocido.",
index cc31e7b..37ee993 100644 (file)
        "api-help-datatypes-header": "Type de données",
        "api-help-datatypes": "Les entrées dans MédiaWiki doivent être en UTF-8 à la norme NFC. MédiaWiki peut tenter de convertir d’autres types d’entrée, mais cela peut faire échouer certaines opérations (comme les [[Special:ApiHelp/edit|modifications]] avec contrôles MD5) to fail.\n\nCertains types de paramètre dans les requêtes de l’API nécessitent plus d’explication :\n;boolean\n:Les paramètres booléens fonctionnent comme des cases à cocher HTML : si le paramètre est spécifié, quelle que soit sa valeur, il est considéré comme vrai. Pour une valeur fausse, enlever complètement le paramètre.\n;timestamp\n:Les horodatages peuvent être spécifiés sous différentes formes. Date et heure ISO 8601 est recommandé. Toutes les heures sont en UTC, tout fuseau horaire inclus est ignoré.\n:* Date et heure ISO 8601, <kbd><var>2001</var>-<var>01</var>-<var>15</var>T<var>14</var>:<var>56</var>:<var>00</var>Z</kbd> (la ponctuation et <kbd>Z</kbd> sont facultatifs)\n:* Date et heure ISO 8601 avec fractions de seconde (ignorées), <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> (tirets, deux-points et <kbd>Z</kbd> sont facultatifs)\n:* Format MédiaWiki, <kbd><var>2001</var><var>01</var><var>15</var><var>14</var><var>56</var><var>00</var></kbd>\n:* Format numérique générique, <kbd><var>2001</var>-<var>01</var>-<var>15</var> <var>14</var>:<var>56</var>:<var>00</var></kbd> (fuseau horaire facultatif en <kbd>GMT</kbd>, <kbd>+<var>##</var></kbd>, ou <kbd>-<var>##</var></kbd> sont ignorés)\n:* Format EXIF, <kbd><var>2001</var>:<var>01</var>:<var>15</var> <var>14</var>:<var>56</var>:<var>00</var></kbd>\n:*Format RFC 2822 (le fuseau horaire est facultatif), <kbd><var>Mon</var>, <var>15</var> <var>Jan</var> <var>2001</var> <var>14</var>:<var>56</var>:<var>00</var></kbd>\n:* Format RFC 850 (le fuseau horaire est facultatif), <kbd><var>Monday</var>, <var>15</var>-<var>Jan</var>-<var>2001</var> <var>14</var>:<var>56</var>:<var>00</var></kbd>\n:* Format ctime C, <kbd><var>Mon</var> <var>Jan</var> <var>15</var> <var>14</var>:<var>56</var>:<var>00</var> <var>2001</var></kbd>\n:* Secondes depuis 1970-01-01T00:00:00Z sous forme d’entier de 1 à 13 chiffres (sans <kbd>0</kbd>)\n:* La chaîne <kbd>now</kbd>",
        "api-help-templatedparams-header": "Paramètres de modèle",
-       "api-help-templatedparams": "Les paramètres de modèle supportent les cas où un module d’API a besoin d’une valeur pour chaque valeur d’un autre paramètre quelconque. Par exemple, s’il y avait un module d’API pour demander un fruit, il pourrait avoir un paramètre <var>fruits</var> pour spécifier quels fruits sont demandés et un paramètre de modèle <var>{fruit}-quantité</var> pour spécifier combien de chaque fruit demander. Un client de l’API qui voudrait une pomme, cinq bananes et vingt fraises pourrait alors faire une requête comme <kbd>fruits=pommes|bananes|fraises&pommes-quantité=1&bananes-quantité=5&fraises-quantité=20</kbd>.",
+       "api-help-templatedparams": "Les paramètres de modèle supportent les cas où un module d’API a besoin d’une valeur pour chaque valeur d’un autre paramètre quelconque. Par exemple, s’il y avait un module d’API pour demander un fruit, il pourrait avoir un paramètre <var>fruits</var> pour spécifier quels fruits sont demandés et un paramètre de modèle <var>{fruit}-quantité</var> pour spécifier la quantité demandée de chaque fruit. Un client de l’API qui voudrait une pomme, cinq bananes et vingt fraises pourrait alors faire une requête comme <kbd>fruits=pommes|bananes|fraises&pommes-quantité=1&bananes-quantité=5&fraises-quantité=20</kbd>.",
        "api-help-param-type-limit": "Type : entier ou <kbd>max</kbd>",
        "api-help-param-type-integer": "Type : {{PLURAL:$1|1=entier|2=liste d’entiers}}",
        "api-help-param-type-boolean": "Type : booléen ([[Special:ApiHelp/main#main/datatypes|détails]])",
index b7e0e52..0f159fb 100644 (file)
        "apihelp-query+recentchanges-param-limit": "O número total de mudanças a serem devolvidas.",
        "apihelp-query+recentchanges-param-type": "Os tipos de mudanças a serem mostradas.",
        "apihelp-query+recentchanges-param-toponly": "Listar só as alterações que são a revisão mais recente.",
+       "apihelp-query+recentchanges-param-title": "Filtrar as entradas para produzir só as relacionadas com uma página.",
        "apihelp-query+recentchanges-param-generaterevisions": "Ao ser usado como gerador, gerar identificadores de revisões em vez de títulos. As entradas das mudanças recentes que não tenham identificadores de revisão associados (por exemplo, a maioria das entradas do registo) não geram nada.",
        "apihelp-query+recentchanges-example-simple": "Listar as mudanças recentes.",
        "apihelp-query+recentchanges-example-generator": "Obter informação de página acerca das mudanças recentes não patrulhadas.",
index e442d61..91aac43 100644 (file)
@@ -31,7 +31,8 @@
                        "Mouse21",
                        "Happy13241",
                        "Ole Yves",
-                       "AttemptToCallNil"
+                       "AttemptToCallNil",
+                       "Movses"
                ]
        },
        "apihelp-main-extended-description": "<div class=\"hlist plainlinks api-main-links\">\n* [[mw:Special:MyLanguage/API:Main_page|Документация]]\n* [[mw:Special:MyLanguage/API:FAQ|ЧаВО]]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api Почтовая рассылка]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api-announce Новости API]\n* [https://phabricator.wikimedia.org/maniphest/query/GebfyV4uCaLd/#R Ошибки и запросы]\n</div>\n<strong>Статус:</strong> MediaWiki API — зрелый и стабильный интерфейс, активно поддерживаемый и улучшаемый. Мы стараемся избегать ломающих изменений, однако изредка они могут быть необходимы. Подпишитесь на [https://lists.wikimedia.org/pipermail/mediawiki-api-announce/ почтовую рассылку mediawiki-api-announce], чтобы быть в курсе обновлений.\n\n<strong>Ошибочные запросы:</strong> Если API получает запрос с ошибкой, вернётся заголовок HTTP с ключом «MediaWiki-API-Error», после чего значение заголовка и код ошибки будут отправлены обратно и установлены в то же значение. Более подробную информацию см. [[mw:Special:MyLanguage/API:Errors_and_warnings|API: Ошибки и предупреждения]].\n\n<p class=\"mw-apisandbox-link\"><strong>Тестирование:</strong> для удобства тестирования API-запросов, см. [[Special:ApiSandbox]].</p>",
        "apihelp-query+recentchanges-param-limit": "Сколько правок вернуть.",
        "apihelp-query+recentchanges-param-type": "Какие типы правок показать.",
        "apihelp-query+recentchanges-param-toponly": "Перечислять только последние правки страниц.",
+       "apihelp-query+recentchanges-param-title": "Вернуть записи, связанные со страницей.",
        "apihelp-query+recentchanges-param-generaterevisions": "При использовании в качестве генератора, генерировать идентификаторы версий вместо их названий. Записи последних изменений без привязанного идентификатора версии (например, большинство записей журналов) не сгенерируют ничего.",
        "apihelp-query+recentchanges-example-simple": "Список последних изменений.",
        "apihelp-query+recentchanges-example-generator": "Получить информацию о последних страницах с неотпатрулированными изменениями.",
index 2f9b693..30a685b 100644 (file)
        "api-format-title": "MediaWiki API 結果",
        "api-format-prettyprint-header": "這是$1格式的HTML呈現。HTML適合用於除錯,但不適合應用程式使用。\n\n指定<var>format</var>參數以更改輸出格式。要檢視$1格式的非HTML呈現,設定<kbd>format=$2</kbd>。\n\n參考 [[mw:Special:MyLanguage/API|完整說明文件]] 或 [[Special:ApiHelp/main|API說明]] 以取得更多資訊。",
        "api-format-prettyprint-header-only-html": "這是用來除錯的HTML呈現,不適合實際應用。\n\n參見[[mw:Special:MyLanguage/API|完整文件]]或[[Special:ApiHelp/main|API幫助]]以取得更多資訊。",
+       "api-format-prettyprint-header-hyperlinked": "這是$1格式的HTML實現。HTML對除錯很有用,但不適合應用程式使用。\n\n指定<var>format</var>參數以更改輸出格式。要查看$1格式的非HTML實現,設置[$3 <kbd>format=$2</kbd>]。\n\n參見[[mw:API|完整文件]],或[[Special:ApiHelp/main|API幫助]]以獲取更多信息。",
        "api-format-prettyprint-status": "此回應將會傳回HTTP狀態$1 $2。",
        "api-pageset-param-titles": "要使用的標題清單。",
        "api-pageset-param-pageids": "要使用的頁面 ID 清單。",
index 3125bd3..717b592 100644 (file)
@@ -138,7 +138,7 @@ class Throttler implements LoggerAwareInterface {
                                $this->logRejection( [
                                        'throttle' => $this->type,
                                        'index' => $index,
-                                       'ip' => $ipKey,
+                                       'ipKey' => $ipKey,
                                        'username' => $username,
                                        'count' => $count,
                                        'expiry' => $expiry,
@@ -193,7 +193,7 @@ class Throttler implements LoggerAwareInterface {
 
        protected function logRejection( array $context ) {
                $logMsg = 'Throttle {throttle} hit, throttled for {expiry} seconds due to {count} attempts '
-                       . 'from username {username} and IP {ip}';
+                       . 'from username {username} and IP {ipKey}';
 
                // If we are hitting a throttle for >= warningLimit attempts, it is much more likely to be
                // an attack than someone simply forgetting their password, so log it at a higher level.
index 308bef6..bce1ea6 100644 (file)
@@ -57,6 +57,7 @@ class UtfNormal {
         * @return string a clean, shiny, normalized UTF-8 string
         */
        static function cleanUp( $string ) {
+               wfDeprecated( __METHOD__, '1.25' );
                return Validator::cleanUp( $string );
        }
 
@@ -69,6 +70,7 @@ class UtfNormal {
         * @return string a UTF-8 string in normal form C
         */
        static function toNFC( $string ) {
+               wfDeprecated( __METHOD__, '1.25' );
                return Validator::toNFC( $string );
        }
 
@@ -80,6 +82,7 @@ class UtfNormal {
         * @return string a UTF-8 string in normal form D
         */
        static function toNFD( $string ) {
+               wfDeprecated( __METHOD__, '1.25' );
                return Validator::toNFD( $string );
        }
 
@@ -92,6 +95,7 @@ class UtfNormal {
         * @return string a UTF-8 string in normal form KC
         */
        static function toNFKC( $string ) {
+               wfDeprecated( __METHOD__, '1.25' );
                return Validator::toNFKC( $string );
        }
 
@@ -104,6 +108,7 @@ class UtfNormal {
         * @return string a UTF-8 string in normal form KD
         */
        static function toNFKD( $string ) {
+               wfDeprecated( __METHOD__, '1.25' );
                return Validator::toNFKD( $string );
        }
 
@@ -114,6 +119,7 @@ class UtfNormal {
         * @return bool
         */
        static function quickIsNFC( $string ) {
+               wfDeprecated( __METHOD__, '1.25' );
                return Validator::quickIsNFC( $string );
        }
 
@@ -124,6 +130,7 @@ class UtfNormal {
         * @return bool
         */
        static function quickIsNFCVerify( &$string ) {
+               wfDeprecated( __METHOD__, '1.25' );
                return Validator::quickIsNFCVerify( $string );
        }
 }
diff --git a/includes/compat/normal/UtfNormalDefines.php b/includes/compat/normal/UtfNormalDefines.php
deleted file mode 100644 (file)
index 38ce855..0000000
+++ /dev/null
@@ -1,186 +0,0 @@
-<?php
-/**
- * Backwards-compatability constants which are now provided by the
- * UtfNormal library. They are hardcoded here since they are needed
- * before the composer autoloader is initialized.
- *
- * 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 UtfNormal
- */
-
-/**
- * @deprecated since 1.25, use UtfNormal\Constants instead
- */
-define( 'UNICODE_HANGUL_FIRST', 0xac00 );
-/**
- * @deprecated since 1.25, use UtfNormal\Constants instead
- */
-define( 'UNICODE_HANGUL_LAST', 0xd7a3 );
-
-/**
- * @deprecated since 1.25, use UtfNormal\Constants instead
- */
-define( 'UNICODE_HANGUL_LBASE', 0x1100 );
-/**
- * @deprecated since 1.25, use UtfNormal\Constants instead
- */
-define( 'UNICODE_HANGUL_VBASE', 0x1161 );
-/**
- * @deprecated since 1.25, use UtfNormal\Constants instead
- */
-define( 'UNICODE_HANGUL_TBASE', 0x11a7 );
-
-/**
- * @deprecated since 1.25, use UtfNormal\Constants instead
- */
-define( 'UNICODE_HANGUL_LCOUNT', 19 );
-/**
- * @deprecated since 1.25, use UtfNormal\Constants instead
- */
-define( 'UNICODE_HANGUL_VCOUNT', 21 );
-/**
- * @deprecated since 1.25, use UtfNormal\Constants instead
- */
-define( 'UNICODE_HANGUL_TCOUNT', 28 );
-/**
- * @deprecated since 1.25, use UtfNormal\Constants instead
- */
-define( 'UNICODE_HANGUL_NCOUNT', UNICODE_HANGUL_VCOUNT * UNICODE_HANGUL_TCOUNT );
-
-/**
- * @deprecated since 1.25, use UtfNormal\Constants instead
- */
-define( 'UNICODE_HANGUL_LEND', UNICODE_HANGUL_LBASE + UNICODE_HANGUL_LCOUNT - 1 );
-/**
- * @deprecated since 1.25, use UtfNormal\Constants instead
- */
-define( 'UNICODE_HANGUL_VEND', UNICODE_HANGUL_VBASE + UNICODE_HANGUL_VCOUNT - 1 );
-/**
- * @deprecated since 1.25, use UtfNormal\Constants instead
- */
-define( 'UNICODE_HANGUL_TEND', UNICODE_HANGUL_TBASE + UNICODE_HANGUL_TCOUNT - 1 );
-
-/**
- * @deprecated since 1.25, use UtfNormal\Constants instead
- */
-define( 'UNICODE_SURROGATE_FIRST', 0xd800 );
-/**
- * @deprecated since 1.25, use UtfNormal\Constants instead
- */
-define( 'UNICODE_SURROGATE_LAST', 0xdfff );
-/**
- * @deprecated since 1.25, use UtfNormal\Constants instead
- */
-define( 'UNICODE_MAX', 0x10ffff );
-/**
- * @deprecated since 1.25, use UtfNormal\Constants instead
- */
-define( 'UNICODE_REPLACEMENT', 0xfffd );
-
-/**
- * @deprecated since 1.25, use UtfNormal\Constants instead
- */
-define( 'UTF8_HANGUL_FIRST', "\xea\xb0\x80" /*codepointToUtf8( UNICODE_HANGUL_FIRST )*/ );
-/**
- * @deprecated since 1.25, use UtfNormal\Constants instead
- */
-define( 'UTF8_HANGUL_LAST', "\xed\x9e\xa3" /*codepointToUtf8( UNICODE_HANGUL_LAST )*/ );
-
-/**
- * @deprecated since 1.25, use UtfNormal\Constants instead
- */
-define( 'UTF8_HANGUL_LBASE', "\xe1\x84\x80" /*codepointToUtf8( UNICODE_HANGUL_LBASE )*/ );
-/**
- * @deprecated since 1.25, use UtfNormal\Constants instead
- */
-define( 'UTF8_HANGUL_VBASE', "\xe1\x85\xa1" /*codepointToUtf8( UNICODE_HANGUL_VBASE )*/ );
-/**
- * @deprecated since 1.25, use UtfNormal\Constants instead
- */
-define( 'UTF8_HANGUL_TBASE', "\xe1\x86\xa7" /*codepointToUtf8( UNICODE_HANGUL_TBASE )*/ );
-
-/**
- * @deprecated since 1.25, use UtfNormal\Constants instead
- */
-define( 'UTF8_HANGUL_LEND', "\xe1\x84\x92" /*codepointToUtf8( UNICODE_HANGUL_LEND )*/ );
-/**
- * @deprecated since 1.25, use UtfNormal\Constants instead
- */
-define( 'UTF8_HANGUL_VEND', "\xe1\x85\xb5" /*codepointToUtf8( UNICODE_HANGUL_VEND )*/ );
-/**
- * @deprecated since 1.25, use UtfNormal\Constants instead
- */
-define( 'UTF8_HANGUL_TEND', "\xe1\x87\x82" /*codepointToUtf8( UNICODE_HANGUL_TEND )*/ );
-
-/**
- * @deprecated since 1.25, use UtfNormal\Constants instead
- */
-define( 'UTF8_SURROGATE_FIRST', "\xed\xa0\x80" /*codepointToUtf8( UNICODE_SURROGATE_FIRST )*/ );
-/**
- * @deprecated since 1.25, use UtfNormal\Constants instead
- */
-define( 'UTF8_SURROGATE_LAST', "\xed\xbf\xbf" /*codepointToUtf8( UNICODE_SURROGATE_LAST )*/ );
-/**
- * @deprecated since 1.25, use UtfNormal\Constants instead
- */
-define( 'UTF8_MAX', "\xf4\x8f\xbf\xbf" /*codepointToUtf8( UNICODE_MAX )*/ );
-/**
- * @deprecated since 1.25, use UtfNormal\Constants instead
- */
-define( 'UTF8_REPLACEMENT', "\xef\xbf\xbd" /*codepointToUtf8( UNICODE_REPLACEMENT )*/ );
-# define( 'UTF8_REPLACEMENT', '!' );
-
-/**
- * @deprecated since 1.25, use UtfNormal\Constants instead
- */
-define( 'UTF8_OVERLONG_A', "\xc1\xbf" );
-/**
- * @deprecated since 1.25, use UtfNormal\Constants instead
- */
-define( 'UTF8_OVERLONG_B', "\xe0\x9f\xbf" );
-/**
- * @deprecated since 1.25, use UtfNormal\Constants instead
- */
-define( 'UTF8_OVERLONG_C', "\xf0\x8f\xbf\xbf" );
-
-# These two ranges are illegal
-/**
- * @deprecated since 1.25, use UtfNormal\Constants instead
- */
-define( 'UTF8_FDD0', "\xef\xb7\x90" /*codepointToUtf8( 0xfdd0 )*/ );
-/**
- * @deprecated since 1.25, use UtfNormal\Constants instead
- */
-define( 'UTF8_FDEF', "\xef\xb7\xaf" /*codepointToUtf8( 0xfdef )*/ );
-/**
- * @deprecated since 1.25, use UtfNormal\Constants instead
- */
-define( 'UTF8_FFFE', "\xef\xbf\xbe" /*codepointToUtf8( 0xfffe )*/ );
-/**
- * @deprecated since 1.25, use UtfNormal\Constants instead
- */
-define( 'UTF8_FFFF', "\xef\xbf\xbf" /*codepointToUtf8( 0xffff )*/ );
-
-/**
- * @deprecated since 1.25, use UtfNormal\Constants instead
- */
-define( 'UTF8_HEAD', false );
-/**
- * @deprecated since 1.25, use UtfNormal\Constants instead
- */
-define( 'UTF8_TAIL', true );
diff --git a/includes/compat/normal/UtfNormalUtil.php b/includes/compat/normal/UtfNormalUtil.php
deleted file mode 100644 (file)
index 0e29dd0..0000000
+++ /dev/null
@@ -1,104 +0,0 @@
-<?php
-/**
- * Some of these functions are adapted from places in MediaWiki.
- * Should probably merge them for consistency.
- *
- * Copyright © 2004 Brion Vibber <brion@pobox.com>
- * https://www.mediawiki.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- * http://www.gnu.org/copyleft/gpl.html
- *
- * @file
- * @ingroup UtfNormal
- */
-
-use UtfNormal\Utils;
-
-/**
- * Return UTF-8 sequence for a given Unicode code point.
- *
- * @param int $codepoint
- * @return string
- * @throws InvalidArgumentException if fed out of range data.
- * @public
- * @deprecated since 1.25, use UtfNormal\Utils directly
- */
-function codepointToUtf8( $codepoint ) {
-       wfDeprecated( __FUNCTION__, '1.25' );
-       return Utils::codepointToUtf8( $codepoint );
-}
-
-/**
- * Take a series of space-separated hexadecimal numbers representing
- * Unicode code points and return a UTF-8 string composed of those
- * characters. Used by UTF-8 data generation and testing routines.
- *
- * @param string $sequence
- * @return string
- * @throws InvalidArgumentException if fed out of range data.
- * @private
- * @deprecated since 1.25, use UtfNormal\Utils directly
- */
-function hexSequenceToUtf8( $sequence ) {
-       wfDeprecated( __FUNCTION__, '1.25' );
-       return Utils::hexSequenceToUtf8( $sequence );
-}
-
-/**
- * Take a UTF-8 string and return a space-separated series of hex
- * numbers representing Unicode code points. For debugging.
- *
- * @fixme this is private but extensions + maint scripts are using it
- * @param string $str UTF-8 string.
- * @return string
- * @private
- */
-function utf8ToHexSequence( $str ) {
-       wfDeprecated( __FUNCTION__, '1.25' );
-       $buf = '';
-       foreach ( preg_split( '//u', $str, -1, PREG_SPLIT_NO_EMPTY ) as $cp ) {
-               $buf .= sprintf( '%04x ', UtfNormal\Utils::utf8ToCodepoint( $cp ) );
-       }
-
-       return rtrim( $buf );
-}
-
-/**
- * Determine the Unicode codepoint of a single-character UTF-8 sequence.
- * Does not check for invalid input data.
- *
- * @param string $char
- * @return int
- * @public
- * @deprecated since 1.25, use UtfNormal\Utils directly
- */
-function utf8ToCodepoint( $char ) {
-       wfDeprecated( __FUNCTION__, '1.25' );
-       return Utils::utf8ToCodepoint( $char );
-}
-
-/**
- * Escape a string for inclusion in a PHP single-quoted string literal.
- *
- * @param string $string string to be escaped.
- * @return string escaped string.
- * @public
- * @deprecated since 1.25, use UtfNormal\Utils directly
- */
-function escapeSingleString( $string ) {
-       wfDeprecated( __FUNCTION__, '1.25' );
-       return Utils::escapeSingleString( $string );
-}
index dfac82e..b8a2f8f 100644 (file)
        "config-env-php": "بي إتش بي $1 مثبت.",
        "config-env-hhvm": "نصبت HHVM $1.",
        "config-unicode-using-intl": "باستخدام [https://pecl.php.net/intl امتداد intl PECL] لتسوية يونيكود.",
+       "config-unicode-pure-php-warning": "<strong>تحذير:</strong> لا يتوفر [https://pecl.php.net/intl امتداد intl PECL] للتعامل مع تطبيع يونيكود; حيث يتراجع لإبطاء تنفيذ Pure-Pure;\nإذا كنت تدير موقعا عالي الزيارات، فتجب عليك القراءة قليلا في [https://www.mediawiki.org/wiki/Special:MyLanguage/Unicode_normalization_considerations تطبيع يونيكود].",
+       "config-unicode-update-warning": "<strong>تحذير:</strong> يستخدم الإصدار المثبت من برنامج تطبيع نظام يونيكود إصدارًا قديما من مكتبة [http://site.icu-project.org/ مشروع ICU];\nتجب عليك [https://www.mediawiki.org/wiki/Special:MyLanguage/Unicode_normalization_considerations الترقية] إذا كنت مهتما باستخدام يونيكود.",
+       "config-no-db": "لا يمكن العثور على مشغل قاعدة بيانات مناسب! تحتاج إلى تثبيت مشغل قاعدة بيانات PHP، \n{{PLURAL:$2|نوع قاعدة البيانات التالي مدعوم|أنواع قاعدة البيانات التالية مدعومة}} البيانات التالية مدعومة: $1.\n\nإذا قمت بتجميع PHP بنفسك، فقم بتكوينها مع تمكين عميل قاعدة البيانات، على سبيل المثال، باستخدام <code>./configure --with-mysqli</code>.\nإذا قمت بتثبيت PHP من حزمة Debian أو Ubuntu، فستحتاج أيضا إلى تثبيت، على سبيل المثال، حزمة <code>php5-mysql</code>.",
        "config-outdated-sqlite": "<strong>تحذير:</strong> لديك SQLite $1, which وهو أقل من الحد الأدنى المطلوب للنسخة $2. SQLite سوف يكون غير متوفر.",
+       "config-no-fts3": "<strong>تحذير:</strong> يتم تجميع SQLite بدون [//sqlite.org/fts3.html FTS3 module]; ستكون ميزات البحث غير متوفرة في هذه الواجهة الخلفية.",
+       "config-pcre-old": "<strong>فادح:</strong> مطلوب PCRE $1 أو أحدث،\nترتبط ثنائية PHP الخاصة بك بـPCRE $2.\n[https://www.mediawiki.org/wiki/Manual:Errors_and_symptoms/PCRE مزيد من المعلومات].",
+       "config-pcre-no-utf8": "<strong>فادح:</strong> يبدو أن وحدة PCRE في PHP يتم تجميعها بدون دعم PCRE_UTF8، \nيتطلب ميدياويكي دعم UTF-8 ليعمل بشكل صحيح.",
+       "config-memory-raised": "<code>memory_limit</code> في PHP $1 ومرتفعة إلى $2.",
+       "config-memory-bad": "<strong>تحذير:</strong> في PHP <code>memory_limit</code> $1،\nهذا على الارجح منخفض جدا;\nقد يفشل التثبيت!",
        "config-apc": "تثبيت [https://secure.php.net/apc APC]",
-       "config-apcu": "تثبيت [https://secure.php.net/apcu APCu]",
+       "config-apcu": "[https://secure.php.net/apcu APCu] مثبت",
        "config-wincache": "تثبيت [https://www.iis.net/downloads/microsoft/wincache-extension WinCache]",
+       "config-no-cache-apcu": "<strong>تحذير:</strong> تعذر العثور على [https://secure.php.net/apcu APCu] أو [https://www.iis.net/downloads/microsoft/wincache-extension WinCache];\nكائن التخزين المؤقت غير ممكّّن.",
+       "config-mod-security": "<strong>تحذير:</strong> تم تمكين خادم الويب الخاص بك [https://modsecurity.org/ mod_security]/mod_security2، العديد من التكوينات الشائعة له سوف تتسبب في مشاكل لميدياويكي والبرامج الأخرى التي تسمح للمستخدمين بنشر محتوى عشوائي; \nإذا كان ذلك ممكنا، يجب تعطيل هذا، أو يمكنك الرجوع إلى [https://modsecurity.org/documentation/ توثيق mod_security] أو الاتصال بدعم مضيفك إذا واجهتك أخطاء عشوائية.",
        "config-diff3-bad": "جنو diff3 غير موجود.",
        "config-git": "العثور على برنامج التحكم في إصدار جت <code>$1</code>.",
        "config-git-bad": "برنامج التحكم في إصدار جت غير موجود.",
        "config-no-cli-uri": "<strong>تحذير:</strong> لم يتم تحديد <code>--scriptpath</code>، باستخدام الافتراضي: <code>$1</code>.",
        "config-using-server": "باستخدام اسم الخادم \"<nowiki>$1</nowiki\".",
        "config-using-uri": "باستخدام URL الخادم \"<nowiki>$1$2</nowiki>\".",
+       "config-uploads-not-safe": "<strong>تحذير:</strong>  الدليل الافتراضي للمرفوعات <code>$1</code> عرضة لتنفيذ سكريبتات عشوائية،\nعلى الرغم من أن ميدياويكي يتحقق من كل الملفات المرفوعة للتهديدات الأمنية، فمن المستحسن بشدة [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Security#Upload_security إغلاق هذه الثغرة الأمنية] قبل تمكين المرفوعات.",
+       "config-no-cli-uploads-check": "<strong>تحذير:</strong> لم يتم تحديد الدليل الافتراضي للمرفوعات (<code>$1</code>) للقابلية للتأثر\nلتنفيذ برنامج تعسفي أثناء تثبيت CLI.",
+       "config-brokenlibxml": "يحتوي نظامك على مجموعة من إصدارات PHP وlibxml2 ويمكن أن تسبب فسادا للبيانات في ميدياويكي وتطبيقات الويب الأخرى;\nقم بالترقية إلى libxml2 2.7.3 أو أحدث ([https://bugs.php.net/bug.php؟id=45996 تم تدقيم العلة مع PHP]); \nتم إحباط التثبيت.",
+       "config-suhosin-max-value-length": "تم تثبيت Suhosin وتقييد وسيط GET <code>length</code> إلى $1 بايت،\nسيعمل مكون ResourceLoader في ميدياويكي حول هذا الحد، لكن ذلك سيؤدي إلى انخفاض مستوى الأداء، \nإذا كان ذلك ممكنا، فيجب تعيين <code>suhosin.get.max_value_length</code> على 1024 أو أعلى في <code>php.ini</code>، وتعيين <code>$wgResourceLoaderMaxQueryLength</code> لنفس القيمة في <code>LocalSettings.php</code>.",
        "config-using-32bit": "<strong>تحذير:</strong> يبدو أن نظامك يعمل مع الأعداد الصحيحة 32 بت، هذا [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:32-bit لا يُنصَح به].",
        "config-db-type": "نوع قاعدة البيانات:",
        "config-db-host": "مضيف قاعدة البيانات:",
+       "config-db-host-help": "إذا كان خادم قاعدة البيانات موجودا في خادم مختلف، فأدخل اسم المضيف أو عنوان الآيبي هنا. \n\nإذا كنت تستخدم استضافة ويب مشتركة، فيجب أن يمنحك موفر الاستضافة اسم المضيف الصحيح في وثائقه. \n\nإذا كنت تقوم بالتثبيت على خادم ويندوز واستخدام MySQL، فإن استخدام \"localhost\" قد لا يعمل لاسم الخادم، إذا لم يتم ذلك، فجرب \"127.0.0.1\" لعنوان الآيبي المحلي. \n\nإذا كنت تستخدم PostgreSQL، فاترك هذا الحقل فارغا للاتصال عبر مقبس Unix.",
        "config-db-host-oracle": "قاعدة بيانات TNS:",
+       "config-db-host-oracle-help": "أدخل [http://download.oracle.com/docs/cd/B28359_01/network.111/b28317/tnsnames.htm اسم اتصال محلي] صالحا، يجب أن يكون ملف tnsnames.ora مرئيا لهذا التثبيت.<br />إذا كنت تستخدم مكتبات العملاء 10g أو أحدث، فيمكنك أيضا استخدام طريقة التسمية [http://download.oracle.com/docs/cd/E11882_01/network.112/e10836/naming.اتصال htm السهل].",
        "config-db-wiki-settings": "حدِّد هذا الويكي",
        "config-db-name": "اسم قاعدة البيانات",
        "config-db-name-help": "اختر الاسم الذي يعرف الويكي الخاص بك. لا يجب أن يحتوي على مسافات. إذا كنت تستخدم استضافة المواقع المشتركة، مزود الاستضافة إما سيعطيك اسم قاعدة بيانات محددة لاستخدامها أو سيتيح لك إنشاء قواعد بيانات عن طريق لوحة التحكم.",
        "config-db-name-oracle": "سكيما قاعدة البيانات:",
+       "config-db-account-oracle-warn": "هناك ثلاثة سيناريوهات مدعومة لتثبيت Oracle كقاعدة بيانات خلفية: \n\nإذا كنت ترغب في إنشاء حساب قاعدة بيانات كجزء من عملية التثبيت، فيُرجَى تقديم حساب بدور SYSDBA كحساب قاعدة بيانات للتثبيت وتحديد بيانات الاعتماد المطلوبة لحساب الوصول إلى الإنترنت، وإلا يمكنك إما إنشاء حساب الوصول إلى الويب يدويا وتزويد الحساب فقط (إذا كان يتطلب صلاحيات لإنشاء كائنات المخطط) أو توفير حسابين مختلفين، أحدهما له امتيازات إنشاء وامتياز مقيد للدخول إلى الويب. \n\nيمكن العثور على البرنامج النصي لإنشاء حساب له امتيازات مطلوبة في دليل \"maintenance/oracle/\" لهذا التثبيت، ضع في اعتبارك أن استخدام حساب مقيد سيؤدي إلى تعطيل جميع إمكانات الصيانة باستخدام الحساب الافتراضي.",
        "config-db-install-account": "حساب المستخدم للتنصيب",
        "config-db-username": "اسم مستخدم قاعدة البيانات:",
        "config-db-password": "كلمة سر قاعدة البيانات:",
        "config-db-schema-help": "هذا المخطط عادة يكون على ما يرام. غيره إذا كنت تعرف أنك في حاجة إلى هذا فقط.",
        "config-pg-test-error": "لا يمكن الاتصال بقاعدة البيانات <strong>$1</strong>: $2",
        "config-sqlite-dir": "دليل بيانات SQLite:",
+       "config-sqlite-dir-help": "يخزن SQLite جميع البيانات في ملف واحد. \n\nيجب أن يكون الدليل الذي توفره قابلا للكتابة بواسطة خادم الويب أثناء التثبيت. \n\nيجب أن يكون <strong>غير</strong> متاحا عبر الويب؛ هذا هو سبب عدم وضعه في مكان ملفات PHP الخاصة بك. \n\nسيقوم المثبت بكتابة ملف <code>.htaccess</code> معه، ولكن إذا فشل ذلك، يمكن لشخص ما الوصول إلى قاعدة بياناتك الأولية، \nيتضمن ذلك بيانات المستخدم الأولية (عناوين البريد الإلكتروني وكلمات المرور المجزأة) بالإضافة إلى المراجعات المحذوفة والبيانات المحظورة الأخرى على الويكي. \n\nفكر في وضع قاعدة البيانات في مكان آخر تماما، على سبيل المثال في <code>/var/lib/mediawiki/yourwiki</code.",
        "config-oracle-def-ts": "جدولية افتراضية:",
        "config-oracle-temp-ts": "جدولية مؤقتة:",
        "config-type-mysql": "MySQL (أو متوافق)",
        "config-type-oracle": "أوراكل",
        "config-type-mssql": "خادم SQL لميكروسوفت",
        "config-support-info": "ميدياويكي يدعم نظم قواعد البيانات التالية: $1 إذا كنت لا ترى نظام قاعدة البيانات الذي تحاول استخدامه مدرجًا أدناه، اتبع الإرشادات المرتبطة فوق لتمكين الدعم.",
+       "config-dbsupport-mysql": "* [{{int:version-db-mysql-url}} MySQL] هو الهدف الأساسي لميدياويكي وأفضل دعم له، يعمل ميدياويكي أيضا مع [{{int:version-db-mariadb-url}} MariaDB] و[{{int:version-db-percona-url}} Percona Server]، وهما متوافقان مع MySQL، ([https://secure.php.net/manual/en/mysqli.installation.php كيفية تجميع PHP مع دعم MySQL])",
+       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] هو نظام قاعدة بيانات مفتوح المصدر مشهور كبديل لـMySQL ([https://secure.php.net/manual/en/pgsql.installation.php كيفية تجميع PHP مع دعم PostgreSQL])",
+       "config-dbsupport-sqlite": "* [{{int:version-db-sqlite-url}} SQLite] هو نظام قاعدة بيانات خفيف مدعوم بشكل جيد. ([https://secure.php.net/manual/en/pdo.installation.php كيفية ترجمة PHP باستخدام دعم SQLite]، يستخدم PDO)",
+       "config-dbsupport-oracle": "* [{{int:version-db-oracle-url}} Oracle] هي قاعدة بيانات مؤسسة تجارية. ([https://secure.php.net/manual/en/oci8.installation.php كيفية تجميع PHP مع دعم OCI8])",
+       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] هي قاعدة بيانات مؤسسة تجارية لويندوز. ([https://secure.php.net/manual/en/sqlsrv.installation.php كيفية تجميع PHP مع دعم SQLSRV])",
        "config-header-mysql": "إعدادات MySQL",
        "config-header-postgres": "إعدادات PostgreSQL",
        "config-header-sqlite": "إعدادات SQLite",
        "config-missing-db-name": "يجب عليك إدخال قيمة ل\"{{int:config-db-name}}\".",
        "config-missing-db-host": "يجب إدخال قيمة لـ\"{{int:config-db-host}}\".",
        "config-missing-db-server-oracle": "يجب عليك إدخال قيمة ل\"{{int:config-db-host-oracle}}\".",
+       "config-invalid-db-server-oracle": "TNS قاعدة بيانات غير صالحة \"$1\";\nاستخدم إما \"اسم TNS\" أو سلسلة \"الاتصال السهل\" \"Easy Connect\" ([http://docs.oracle.com/cd/E11882_01/network.112/e10836/naming.htm طرقلتسمية في أوراكل]).",
+       "config-invalid-db-name": "اسم قاعدة بيانات غير صالح \"$1\". \nاستخدم فقط أحرف أسكي (az، AZ) وأرقاما (0-9) وشرطات سفلية (_).",
+       "config-invalid-db-prefix": "بادئة قاعدة بيانات غير صالحة \"$1\". \nاستخدم فقط أحرف أسكي (az، AZ) وأرقاما (0-9) وشرطات سفلية (_).",
        "config-connection-error": "$1.\nتحقق من المضيف، واسم المستخدم وكلمة المرور وحاول مرة أخرى.",
+       "config-invalid-schema": "مخطط غير صالح لميدياويكي \"$1\". \nاستخدم فقط أحرف أسكي (az، AZ) وأرقاما (0-9) وشرطات سفلية (_).",
        "config-db-sys-create-oracle": "المثبت يعتمد باستخدام حساب SYSDBA فقط لإنشاء حساب جديد.",
        "config-db-sys-user-exists-oracle": "حساب المستخدم \"$1\" موجود بالفعل; يمكن استخدام SYSDBA لإنشاء حساب جديد فقط!",
        "config-postgres-old": "PostgreSQL $1 أو لاحق مطلوب. لديك $2.",
        "config-mssql-old": "خادم Microsoft SQL $1 أو لاحق مطلوب. لديك $2.",
+       "config-sqlite-name-help": "اختر اسمًا يعرف الويكي الخاص بك، \nلا تستخدم مسافات أو شرطات، \nسيتم استخدام هذا لاسم ملف البيانات SQLite.",
+       "config-sqlite-parent-unwritable-group": "لا يمكن إنشاء دليل البيانات <code><nowiki>$1</nowiki></code>; لأن الدليل الأصلي <code><nowiki>$2</nowiki></code> غير قابل للكتابة بواسطة خادم الويب، \nحدد المثبت المستخدم الذي يعمل عليه خادم الويب الخاص بك،\nاجعل الدليل <code><nowiki>$3</nowiki></code> قابلا للكتابة بواسطته للمتابعة، \nفي نظام يونكس/لينوكس قم بـ: \n<pre>cd $2\nmkdir $3\nchgrp $4 $3\nchmod g+w $3</pre>",
+       "config-sqlite-parent-unwritable-nogroup": "لا يمكن إنشاء دليل البيانات <code><nowiki>$1</nowiki></code>; لأن الدليل الأصلي <code><nowiki>$2</nowiki></code> غير قابل للكتابة بواسطة خادم الويب، \nتعذر على المثبت تحديد المستخدم الذي يعمل عليه خادم الويب الخاص بك،\nاجعل الدليل <code><nowiki>$3</nowiki></code> قابلا للكتابة بواسطته للمتابعة، \nفي نظام يونكس/لينوكس قم بـ: \n\n<pre>cd $2\nmkdir $3\nchmod a+w $3</pre>",
        "config-sqlite-mkdir-error": "خطأ في إنشاء دليل البيانات \"$1\". تحقق من الموقع وحاول مرة أخرى.",
        "config-sqlite-dir-unwritable": "غير قادر على الكتابة إلى الدليل \"$1\";\nغيِّر أذوناته حتى يتمكن خادم الويب من الكتابة إليه، وحاول مرة أخرى.",
        "config-sqlite-connection-error": "$1.\nتحقق من اسم دليل البيانات وقواعد البيانات أدناه وحاول مرة أخرى.",
        "config-sqlite-cant-create-db": "لا يمكن إنشاء ملف قاعدة البيانات <code>$1</code>.",
        "config-sqlite-fts3-downgrade": "PHP يفتقد دعم FTS3، تخفيض الجداول.",
        "config-can-upgrade": "هناك جداول ميدياويكي في قاعدة البيانات هذه. للارتقاء بها إلى ميدياويكي $1; انقر على <strong>متابعة</strong>.",
+       "config-upgrade-done": "اكتملت الترقية; \n\nيمكنك الآن [$1 بدء استخدام الويكي الخاص بك]. \n\nإذا كنت ترغب في إعادة إنشاء ملف <code>LocalSettings.php</code>، فانقر فوق الزر أدناه،\n<strong>غير مستحسن</strong> في ما لم تكن تواجه مشاكل مع الويكي الخاص بك.",
        "config-upgrade-done-no-regenerate": "اكتملت الترقية;\n\nيمكنك الآن [$1 بدء استخدام الويكي الخاص بك].",
        "config-regenerate": "إعادة تكوين LocalSettings.php ←",
        "config-show-table-status": "<code> إظهار جدول الحالة </code> فشل الاستعلام!",
        "config-mysql-engine": "محرك التخزين",
        "config-mysql-innodb": "إنو دي بي",
        "config-mysql-myisam": "ماي إسام",
+       "config-mysql-myisam-dep": "<strong>تحذير:</strong> لقد اخترت MyISAM كمحرك تخزين لـMySQL، والذي لا يُنصَح باستخدامه مع ميدياويكي; لأنه:\n* بالكاد يدعم التزامن بسبب قفل الجدول \n* أكثر عرضة للفساد من المحركات الأخرى\n* لا يقوم الكود الأساسي لميدياويكي بمعالجة MyISAM دائما كما يجب\n\nإذا كان تثبيت MySQL يدعم InnoDB، فمن المستحسن جدا أن تختاره بدلا منه، \nإذا كان تثبيت MySQL لا يدعم InnoDB، فربما حان الوقت للترقية.",
+       "config-mysql-only-myisam-dep": "<strong>تحذير:</strong> MyISAMهو محرك التخزين الوحيد المتاح لـMySQL على هذا الجهاز، ولا يُنصَح باستخدامه مع ميدياويكي; لأنه:\n* بالكاد يدعم التزامن بسبب قفل الجدول \n* أكثر عرضة للفساد من المحركات الأخرى\n* لا يقوم الكود الأساسي لميدياويكي بمعالجة MyISAM دائما كما يجب\n\nتثبيت MySQL لا يدعم InnoDB; ربما حان الوقت للترقية.",
+       "config-mysql-engine-help": "<strong>InnoDB</strong> هو دائما الخيار الأفضل; لأنه يحتوي على دعم تزامن جيد.\n\nقد يكون <strong>MyISAM</strong> أسرع في تثبيت المستخدم الفردي أو للقراءة فقط،\nتميل قواعد بيانات MyISAM للتلف أكثر من قواعد بيانات InnoDB.",
        "config-mysql-charset": "مجموعة محارف قاعدة البيانات",
        "config-mysql-binary": "ثنائي",
        "config-mysql-utf8": "يو تي إف-8",
+       "config-mysql-charset-help": "في <strong>الوضع الثنائي</strong>، يقوم ميدياويكي بتخزين نص UTF-8 في قاعدة البيانات في الحقول الثنائية، \nهذا أكثر كفاءة من وضع UTF-8 الخاص بـMySQL، ويسمح لك باستخدام النطاق الكامل لأحرف يونيكود. \n\nفي <strong>وضع UTF-8</strong>، ستعرف MySQL ما هي مجموعة البيانات التي تقوم بها، ويمكنها تقديمها وتحويلها بشكل مناسب، ولكنها لن تسمح لك بتخزين الحروف فوق [https://en.wikipedia.org/wiki/Mapping_of_Unicode_character_planes Basic Multilingual Plane].",
        "config-mssql-auth": "نوع الاستيثاق:",
+       "config-mssql-install-auth": "حدد نوع المصادقة الذي سيتم استخدامه للاتصال بقاعدة البيانات أثناء عملية التثبيت. \nإذا حددت \"{{int:config-mssql-windowsauth}}\"، فسيتم استخدام بيانات اعتماد أي مستخدم يعمل عليه خادم الويب.",
+       "config-mssql-web-auth": "حدد نوع المصادقة الذي سيستخدمه خادم الويب للاتصال بخادم قاعدة البيانات، أثناء التشغيل العادي للويكي. \nإذا حددت \"{{int:config-mssql-windowsauth}}\"، فسيتم استخدام بيانات اعتماد أي مستخدم يعمل عليه خادم الويب.",
        "config-mssql-sqlauth": "مصادقة خادم SQL",
        "config-mssql-windowsauth": "مصادقة ويندوز",
        "config-site-name": "اسم الويكي:",
        "config-ns-site-name": "مثل اسم الويكي: $1",
        "config-ns-other": "أخرى (حدد)",
        "config-ns-other-default": "ماي ويكي",
+       "config-project-namespace-help": "مثال ويكيبيديا التالي، يبقي العديد من الويكيات صفحات سياساتها منفصلة عن صفحات محتواها، في '''نطاق المشروع'''، \nتبدأ جميع عناوين الصفحات في هذا النطاق ببادئة معينة، والتي يمكنك تحديدها هنا، \nعادة، يتم اشتقاق هذه البادئة من اسم الويكي، ولكنها لا يمكن أن تحتوي على أحرف ترقيم مثل \"#\" أو \":\".",
        "config-ns-invalid": "النطاق المحدد \"<nowiki>$1</nowiki>\" غير صالح.\nحدد نطاق مشروع مختلف.",
        "config-ns-conflict": "النطاق المحدد \"<nowiki>$1</ nowiki>\" يتعارض مع نطاق ميدياويكي الافتراضي. حدد نطاق مشروع مختلف.",
        "config-admin-box": "حساب إداري",
        "config-admin-error-password": "خطأ داخلي عند عند وضع كلمة مرور للإداري \"<nowiki>$1</nowiki>\": <pre>$2</pre>.",
        "config-admin-error-bademail": "لقد قمت بإدخال عنوان البريد الإلكتروني غير صالح.",
        "config-subscribe": "اشترك في [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce نشر إعلانات القائمة البريدية].",
+       "config-subscribe-help": "هذه قائمة بريدية ذات حجم منخفض تُستخدَم لإعلانات الإصدار، بما في ذلك إعلانات الأمان المهمة، \nيجب عليك الاشتراك فيها وتحديث تثبيت ميدياويكي الخاص بك عندما تظهر إصدارات جديدة.",
        "config-subscribe-noemail": "حاولت الاشتراك في القائمة البريدية الخاصة بإصدار إعلانات دون تقديم عنوان بريد إلكتروني. يُرجَى إدخال عنوان بريد إلكتروني إذا كنت ترغب في الاشتراك في القائمة البريدية.",
        "config-pingback": "تبادل البيانات حول هذا التثبيت مع مطوري ميدياويكي.",
+       "config-pingback-help": "إذا قمت بتحديد هذا الخيار، سيقوم ميدياويكي بشكل دوري باختبار https://www.mediawiki.org مع بيانات أساسية حول نسخة ميدياويكي، تتضمن هذه البيانات، على سبيل المثال، نوع النظام وإصدار PHP والواجهة الخلفية لقاعدة البيانات، تشارك مؤسسة ويكيميديا ​​هذه البيانات مع مطوري ميدياويكي للمساعدة في توجيه جهود التطوير المستقبلية، سيتم إرسال البيانات التالية لنظامك:\n<pre>$1</pre>",
        "config-almost-done": "لقد شارفت على الانتهاء! يمكنك الآن تخطي التكوين المتبقي وتثبيت الويكي الآن.",
        "config-optional-continue": "اسألني المزيد من الأسئلة",
        "config-optional-skip": "إنني أشعر بالملل بالفعل، فقط قم بتثبيت الويكي",
        "config-profile-no-anon": "إنشاء الحساب مطلوب",
        "config-profile-fishbowl": "المحررون المخولون فقط",
        "config-profile-private": "ويكي خاص",
+       "config-profile-help": "تعمل الويكيات بشكل أفضل عندما تسمح لأكبر عدد ممكن من الأشخاص بتحريرها قدر الإمكان، \nفي ميدياويكي، من السهل مراجعة التغييرات الأخيرة، وإعادة أي ضرر يحدث من قبل مستخدمين سذج أو ضارين، \n\nومع ذلك، وجد الكثيرون أن ميدياويكي مفيد في مجموعة متنوعة من الأدوار، وفي بعض الأحيان ليس من السهل إقناع الجميع بمزايا طريقة الويكي; \nلذلك لديك الخيار. \n\nيسمح النموذج <strong>{{int:config-profile-wiki}}</strong> لأي شخص بالتحرير، دون تسجيل الدخول. \nويكي بـ<strong>{{int:config-profile-no-anon}}</strong> يوفر مساءلة إضافية، ولكنه قد يمنع المساهمين العاديين. \n\nيسمح السيناريو <strong>{{int:config-profile-fishbowl}}</strong> للمستخدمين المعتمدين بالتحرير، ولكن يمكن للجمهور عرض الصفحات، بما في ذلك التاريخ.\nيتيح <strong>{{int:config-profile-private}}</strong> للمستخدمين المعتمدين فقط عرض الصفحات، مع السماح لنفس المجموعة بالتعديل. \n\nتتوفر تكوينات صلاحيات مستخدم أكثر تعقيدًا بعد التثبيت، راجع [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:User_rights إدخال الدليل ذي الصلة].",
        "config-license": "حقوق النسخ والترخيص:",
        "config-license-none": "لا تذييل ترخيص",
        "config-license-cc-by-sa": "المشاع الإبداعي النسبة للمؤلف المشاركة بالمثل",
        "config-license-gfdl": "رخصة جنو للوثائق الحرة 1.3 أو لاحقة",
        "config-license-pd": "ملكية عامة",
        "config-license-cc-choose": "اختر ترخيص مشاع إبداعي مخصص",
+       "config-license-help": "يضع العديد من الويكيات العامة جميع المساهمات تحت [https://freedomdefined.org/Definition خصة حرة]، \nوهذا يساعد على خلق شعور بالملكية المجتمعية ويشجع على المساهمة طويلة الأجل، \nليس من الضروري عموما استخدام ويكي خاص أو شركة. \n\nإذا كنت تريد أن تكون قادرا على استخدام النص من ويكيبيديا، وتريد أن تكون ويكيبيديا قادرة على قبول النص الذي تم نسخه من الويكي الخاص بك، فيجب عليك اختيار <strong>{{int:config-license-cc-by-sa}}</strong>. \n\nاستخدمت ويكيبيديا في السابق رخصة جنو للوثائق الحرة، \nGFDL هو ترخيص صالح، ولكن من الصعب فهمه، \nمن الصعب أيضا إعادة استخدام المحتوى المرخص بموجب GFDL.",
        "config-email-settings": "إعدادات البريد الإلكتروني",
        "config-enable-email": "تمكين البريد الإلكتروني الصادرة",
        "config-enable-email-help": "إذا كنت تريد إرسال بريد إلكتروني إلى العمل، [Config-dbsupport-oracle/manual/en/mail.configuration.php إعدات بريد PHP's] تحتاج لأن يتم تكوينها بشكل صحيح. إذا كنت لا تريد أيا من ميزات البريد الإلكتروني، يمكنك تعطيلها هنا.",
        "config-email-watchlist": "تمكين إشعارات قائمة المراقبة",
        "config-email-watchlist-help": "السماح للمستخدمين بالحصول على إشعارات حول صفحاتهم المراقبة إذا كانوا قد مكنوها في تفضيلاتهم.",
        "config-email-auth": "تمكين مصادقة البريد الإلكتروني",
+       "config-email-auth-help": "إذا تم تمكين هذا الخيار، يتعين على المستخدمين تأكيد عنوان بريدهم الإلكتروني باستخدام رابط يتم إرساله إليهم عند تعيينهم أو تغييره. \nيمكن لعناوين البريد الإلكتروني الموثوقة فقط تلقي رسائل البريد الإلكتروني من المستخدمين الآخرين أو تغيير رسائل الإشعارات الإلكترونية. \nيعد تعيين هذا الخيار <strong> موصى به</strong> لمواقع الويكي العامة بسبب احتمال إساءة استخدام ميزات البريد الإلكتروني.",
        "config-email-sender": "عنوان البريد الإلكتروني المُرسِل:",
+       "config-email-sender-help": "أدخل عنوان البريد الإلكتروني لاستخدامه كعنوان المرسل في البريد الإلكتروني الصادر، \nهذا هو المكان الذي سيتم إرساله إلى المستبعد،\nتتطلب العديد من خوادم البريد أن يكون جزء اسم النطاق صالحا على الأقل.",
        "config-upload-settings": "الصور وتحميل الملفات",
        "config-upload-enable": "تمكين تحميل الملفات",
+       "config-upload-help": "من المحتمل أن تؤدي عمليات رفع الملفات إلى تعريض الخادم لمخاطر أمنية. \nلمزيد من المعلومات; اقرأ [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Security قسم الأمن] في الدليل. \n\nلتمكين رفع الملفات; قم بتغيير الوضع في الدليل الفرعي <code>الصور</code> تحت الدليل الرئيسي لميدياويكي كي يتمكن خادم الويب من الكتابة إليه، \nثم قم بتمكين هذا الخيار.",
        "config-upload-deleted": "المجلد للملفات المحذوفة:",
        "config-upload-deleted-help": "اختر دليلا لأرشفة الملفات المحذوفة،\nمن الناحية المثالية، لا يمكن الوصول إلى هذا من الويب.",
        "config-logo": "مسار الشعار:",
+       "config-logo-help": "يحتوي المظهر الافتراضي لميدياويكي على مساحة لشعار 135x160 بكسل فوق قائمة الشريط الجانبي، \nارفع صورة بالحجم المناسب، وأدخل المسار هنا. \n\nيمكنك استخدام <code>$wgStylePath</code> أو <code>$wgScriptPath</code> إذا كان شعارك مرتبطا بتلك المسارات. \n\nإذا كنت لا تريد شعارا، فاترك هذا الصندوق فارغا.",
        "config-instantcommons": "تمكين الاستخدام الفوري لويكيميديا كومنز InstantCommons",
+       "config-instantcommons-help": "[https://www.mediawiki.org/wiki/InstantCommons كومنز الفوري] هي ميزة تسمح للويكي باستخدام الصور والأصوات والوسائط الأخرى الموجودة على موقع [https://commons.wikimedia.org/ ويكيميديا كومنز]،\nمن أجل القيام بذلك; يتطلب ميدياويكي الوصول إلى الإنترنت. \n\nلمزيد من المعلومات حول هذه الميزة، بما في ذلك تعليمات حول كيفية إعدادها لمواقع ويكي بخلاف ويكيميديا كومنز; يُرجَى الرجوع إلى [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:$wgForeignFileRepos الدليل].",
        "config-cc-error": "لم يعطِ منتقي رخصة المشاع الإبداعي أية نتيجة; أدخل اسم الترخيص يدويا.",
        "config-cc-again": "اختر مجددًا",
        "config-cc-not-chosen": "اختر أي ترخيص تريده ثم اضغط على \"متابعة\".",
        "config-advanced-settings": "ضبط متقدم",
        "config-cache-options": "إعدادات التخزين المؤقت الكائن:",
+       "config-cache-help": "يُستخدَم التخزين المؤقت للأداة لتحسين سرعة ميدياويكي عن طريق تخزين البيانات المستخدمة بشكل متكرر، \nيتم تشجيع المواقع المتوسطة والكبيرة إلى حد كبير على تمكينه، وستشاهد المواقع الصغيرة الفوائد أيضا.",
        "config-cache-none": "لا يوجد تخزين مؤقت (هذا لا يزيل أية وظيفة، لكن قد تتأثر السرعة على مواقع الويكي الكبيرة)",
        "config-cache-accel": "كائن التخزين المؤقت PHP (APC أو APCu أو  XCache أو XCache أو WinCache)",
        "config-cache-memcached": "استخدم Memcached (يتطلب إعدادت إضافية)",
        "config-install-pg-plpgsql": "التحقق من لغة PL/pgSQL",
        "config-pg-no-plpgsql": "تحتاج إلى تثبيت لغة PL/pgSQL في قاعدة البيانات $1",
        "config-pg-no-create-privs": "الحساب الذي حددته للتنزيل ليست لديه امتيازات كافية لإنشاء حساب.",
+       "config-pg-not-in-role": "الحساب الذي حددته لمستخدم الويب موجود بالفعل، \nالحساب الذي حددته للتثبيت ليس مستخدما متميزا وليس عضوا في دور مستخدم الويب; لذلك لا يمكنه إنشاء كائنات يملكها مستخدم الويب. \n\nميدياويكي حاليا يتطلب أن تكون الجداول مملوكة من قبل مستخدم الويب; يُرجَى تحديد اسم حساب ويب آخر، أو النقر فوق \"رجوع\" وتحديد مستخدم تثبيت متميز مناسب.",
        "config-install-user": "إنشاء مستخدم قاعدة البيانات",
        "config-install-user-alreadyexists": "المستخدم \"$1\" موجود بالفعل",
        "config-install-user-create-failed": "إنشاء مستخدم \"$1\" فشل:$2",
        "config-install-mainpage-failed": "لم يتمكن من إدراج الصفحة الرئيسية: $1",
        "config-install-done": "<strong>مبروك!</strong>\nلقد قمت بتثبيت ميدياوكي.\n\nقام المثبت بتوليد ملف <code>LocalSettings.php</code>.\nيحتوي هذا الملف على كل تضبيطاتك.\n\nسيتطلب تشغيل الويكي منك تنزيل هذا الملف ووضعه في مجلد التثبيت الخاص بالويكي (نفس المجلد المحتوي على <code>index.php</code>). سيبدأ التنزيل تلقائيا.\n\nلو لم يُعرض عليك التنزيل أو قمت أنت بالغائه، يمكنك تنزيله بالضغط على الوصلة أدناه:\n\n$3\n\n<strong>تنبيه:</strong> لو لم تقم بهذا الآن، لن يكن ملف الضبط متاحا لك لاحقا إذا غادرت التثبيت بدون تنزيله.\n\nعندما تنتهي من وضع الملف بمكانه، يمكنك <strong>[$2 دخول الويكي]</strong>.",
        "config-install-done-path": "<strong>مبروك!</strong>\nلقد قمت بتثبيت ميدياوكي.\n\nقام المثبت بتوليد ملف <code>LocalSettings.php</code>.\nيحتوي هذا الملف على كل تضبيطاتك.\n\nسيتطلب تشغيل الويكي منك تنزيل هذا الملف ووضعه في <code>$4</code> (نفس المجلد المحتوي على index.php). سيبدأ التنزيل تلقائيا.\n\nلو لم يُعرض عليك التنزيل أو قمت أنت بالغائه، يمكنك تنزيله بالضغط على الوصلة أدناه:\n\n$3\n\n<strong>تنبيه:</strong> لو لم تقم بهذا الآن، لن يكن ملف الضبط متاحا لك لاحقا إذا غادرت التثبيت بدون تنزيله.\n\nعندما تنتهي من وضع الملف بمكانه، يمكنك <code>[$2 دخول الويكي]</strong>.",
+       "config-install-success": "لقد تم تثبيت ميدياويكي بنجاح; يمكنك الآن \nزيارة <$1$2> لعرض الويكي الخاص بك. \nإذا كانت لديك أسئلة، فاطلع على قائمة الأسئلة الشائعة: \n<https://www.mediawiki.org/wiki/Manual:FAQ> أو استخدم أحد \nمنتديات الدعم المرتبطة بهذه الصفحة.",
        "config-download-localsettings": "تنزيل <code>LocalSettings.php</code>",
        "config-help": "مساعدة",
        "config-help-tooltip": "اضغط للتوسيع",
index 3e11263..b640402 100644 (file)
        "config-type-mysql": "MySQL (o compatible)",
        "config-type-mssql": "Microsoft SQL Server",
        "config-support-info": "MediaWiki ye compatible colos siguientes sistemes de bases de datos:\n\n$1\n\nSi nun atopes na llista el sistema de base de datos que tas intentando utilizar, sigue les instrucciones enllazaes enriba p'activar la compatibilidá.",
-       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] ye un sistema comercial de base de datos empresariales pa Windows. ([Config-dbsupport-oracle/manual/en/sqlsrv.installation.php Cómo compilar PHP con compatibilidá pa SQLSRV])",
+       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] ye un sistema comercial de base de datos empresariales pa Windows. ([https://secure.php.net/manual/en/sqlsrv.installation.php Cómo compilar PHP con compatibilidá pa SQLSRV])",
        "config-header-mysql": "Configuración de MySQL",
        "config-header-postgres": "Configuración de PostgreSQL",
        "config-header-sqlite": "Configuración de SQLite",
index 79c40ab..f08580f 100644 (file)
        "config-type-mssql": "Microsoft SQL Server",
        "config-support-info": "MediaWiki -ла түбәндәге СУБД бар:\n\n$1\n\nӘгәр мәғлүмәт һаҡлау системаһын исемлектә күрмәһәгеҙ, рөхсәт алыу өсөн өҫтәге һылтанмалағы инструкция буйынса эш итегеҙ.",
        "config-dbsupport-mysql": "* [{{int:version-db-mysql-url}} MySQL] — MediaWiki-ҙың иҫ яҡшы эшләгән төп мәғлүмәттәр базаһы.  MediaWiki шулай уҡ MySQL-тап килгән [{{int:version-db-mariadb-url}} MariaDB] һәм [{{int:version-db-percona-url}} Percona Server] менән эшләй. ([https://secure.php.net/manual/ru/mysql.installation.php MySQL-ярҙамында PHP туплау инструкцияһы])",
-       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] —  СУБД-ның популяр открыткаһы, MySQL өсөн альтернатива.\nТөҙәтелмәгән хаталар булыуы мөмкин, эш схемаһында ҡулланыу тәҡдим ителмәй. ([Config-dbsupport-oracle/manual/ru/pgsql.installation.php  PostgreSQL рөхсәт ителгән РНР йыйыу инструкцияһы]).",
+       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] —  СУБД-ның популяр открыткаһы, MySQL өсөн альтернатива.\nТөҙәтелмәгән хаталар булыуы мөмкин, эш схемаһында ҡулланыу тәҡдим ителмәй. ([https://secure.php.net/manual/en/pgsql.installation.php  PostgreSQL рөхсәт ителгән РНР йыйыу инструкцияһы]).",
        "config-dbsupport-sqlite": "* [{{int:version-db-sqlite-url}} SQLite] — яҡшы һәм еңел мәғлүмәт базаһы системаһы. ([http://www.php.net/manual/ru/pdo.installation.php  собрать PHP  SQLite]  PDO менән эшләй торған инструкция)",
        "config-dbsupport-oracle": "* [{{int:version-db-oracle-url}} Oracle] — предприятие масштабындаға коммерция базыһы. ([http://www.php.net/manual/ru/oci8.installation.php OCI8 ярҙамындағы РНР нисек йыйырға])",
-       "config-dbsupport-mssql": "* [{{int:version-db-oracle-url}} Oracle] — предприятие масштабындаға Windows өсөн коммерция базыһы. ([Config-dbsupport-oracle/manual/ru/oci8.installation.php OCI8 ярҙамындағы РНР нисек йыйырға])",
+       "config-dbsupport-mssql": "* [{{int:version-db-oracle-url}} Oracle] — предприятие масштабындаға Windows өсөн коммерция базыһы. ([https://secure.php.net/manual/en/sqlsrv.installation.php OCI8 ярҙамындағы РНР нисек йыйырға])",
        "config-header-mysql": "MySQL көйләү",
        "config-header-postgres": "PostgreSQL көйләү",
        "config-header-sqlite": "SQLite көйләү",
index 1f26359..ce9aabb 100644 (file)
        "config-type-mssql": "Microsoft SQL Server",
        "config-support-info": "MediaWiki падтрымлівае наступныя сыстэмы базаў зьвестак:\n\n$1\n\nКалі Вы ня бачыце сыстэму базаў зьвестак, якую Вы спрабуеце выкарыстоўваць ў сьпісе ніжэй, перайдзіце па спасылцы інструкцыі, якая знаходзіцца ніжэй, каб уключыць падтрымку.",
        "config-dbsupport-mysql": "* [{{int:version-db-mysql-url}} MySQL] зьяўляецца галоўнай мэтай MediaWiki і падтрымліваецца лепей за ўсё. MediaWiki таксама працуе з [{{int:version-db-mariadb-url}} MariaDB] і [{{int:version-db-percona-url}} Percona Server], якія сумяшчальныя з MySQL. ([https://secure.php.net/manual/en/mysqli.installation.php Як скампіляваць PHP з падтрымкай MySQL])",
-       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] — папулярная сыстэма базы зьвестак з адкрытым кодам, якая зьяўляецца альтэрнатывай MySQL. ([Config-dbsupport-oracle/manual/en/pgsql.installation.php Як кампіляваць PHP з падтрымкай PostgreSQL])",
-       "config-dbsupport-sqlite": "* [{{int:version-db-sqlite-url}} SQLite] — невялікая сыстэма базы зьвестак, якая мае вельмі добрую падтрымку. ([http://www.php.net/manual/en/pdo.installation.php Як кампіляваць PHP з падтрымкай SQLite], выкарыстоўвае PDO)",
+       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] — папулярная сыстэма базы зьвестак з адкрытым кодам, якая зьяўляецца альтэрнатывай MySQL. ([https://secure.php.net/manual/en/pgsql.installation.php Як кампіляваць PHP з падтрымкай PostgreSQL])",
+       "config-dbsupport-sqlite": "* [{{int:version-db-sqlite-url}} SQLite] — невялікая сыстэма базы зьвестак, якая мае вельмі добрую падтрымку. ([https://secure.php.net/manual/en/pdo.installation.php Як кампіляваць PHP з падтрымкай SQLite], выкарыстоўвае PDO)",
        "config-dbsupport-oracle": "* [{{int:version-db-oracle-url}} Oracle] зьяўляецца камэрцыйнай прафэсійнай базай зьвестак. ([http://www.php.net/manual/en/oci8.installation.php Як скампіляваць PHP з падтрымкай OCI8])",
-       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] — камэрцыйная база зьвестак для Windows. ([Config-dbsupport-oracle/manual/en/sqlsrv.installation.php Як скампіляваць PHP з падтрымкай SQLSRV])",
+       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] — камэрцыйная база зьвестак для Windows. ([https://secure.php.net/manual/en/sqlsrv.installation.php Як скампіляваць PHP з падтрымкай SQLSRV])",
        "config-header-mysql": "Налады MySQL",
        "config-header-postgres": "Налады PostgreSQL",
        "config-header-sqlite": "Налады SQLite",
index 5c9bfd7..4848bfb 100644 (file)
        "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] е популярна система за управление на бази от данни, алтернатива на MySQL. ([https://secure.php.net/manual/bg/pgsql.installation.php Как се компилира PHP с поддръжка на PostgreSQL])",
        "config-dbsupport-sqlite": "* [{{int:version-db-sqlite-url}} SQLite] е олекотена система за бази от данни, която е много добре поддържана. ([http://www.php.net/manual/bg/pdo.installation.php Как се компилира PHP с поддръжка на SQLite], използва PDO)",
        "config-dbsupport-oracle": "* [{{int:version-db-oracle-url}} Oracle] е комерсиална корпоративна база от данни. ([http://www.php.net/manual/en/oci8.installation.php Как се компилира PHP с поддръжка на OCI8])",
-       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] е комерсиална корпоративна база от данни за Windows. ([Config-dbsupport-oracle/manual/bg/sqlsrv.installation.php Как да се компилира PHP с поддръжка на SQLSRV])",
+       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] е комерсиална корпоративна база от данни за Windows. ([https://secure.php.net/manual/en/sqlsrv.installation.php Как да се компилира PHP с поддръжка на SQLSRV])",
        "config-header-mysql": "Настройки за MySQL",
        "config-header-postgres": "Настройки за PostgreSQL",
        "config-header-sqlite": "Настройки за SQLite",
index b6bbebb..76399c4 100644 (file)
@@ -65,7 +65,7 @@
        "config-oracle-def-ts": "পূর্বনির্ধারিত টেবিলস্পেস",
        "config-oracle-temp-ts": "সাময়কি টেবিলস্পেস:",
        "config-type-mssql": "মাইক্রোসফট এসকিউএল সার্ভার",
-       "config-dbsupport-postgres": "* MySQL-এর বিকল্প হিসেবে [{{int:version-db-postgres-url}} PostgreSQL] হচ্ছে একটি জনপ্রিয় ওপেন সোর্স ডাটাবেস ব্যবস্থা। ([Config-dbsupport-oracle/manual/en/pgsql.installation.php PostgreSQL সমর্থনসহ কিভাবে PHP সঙ্কলন করবেন])",
+       "config-dbsupport-postgres": "* MySQL-এর বিকল্প হিসেবে [{{int:version-db-postgres-url}} PostgreSQL] হচ্ছে একটি জনপ্রিয় ওপেন সোর্স ডাটাবেস ব্যবস্থা। ([https://secure.php.net/manual/en/pgsql.installation.php PostgreSQL সমর্থনসহ কিভাবে PHP সঙ্কলন করবেন])",
        "config-header-mysql": "মাইএসকিউএল সেটিংস",
        "config-header-postgres": "পোস্টগ্রেএসকিউএল সেটিংস",
        "config-header-sqlite": "এসকিউলাইট সেটিংস",
index 58c4e1c..96b3dae 100644 (file)
        "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] zo anezhi ur reizhiad diaz roadennoù frank a wirioù brudet-mat a c'haller ober gantañ e plas MySQL. ([https://secure.php.net/manual/en/pgsql.installation.php Penaos kempunañ PHP gant skor PostgreSQL])",
        "config-dbsupport-sqlite": "* [{{int:version-db-sqlite-url}} SQLite] zo anezhi ur reizhiad diaz roadennoù skañv skoret eus ar c'hentañ. ([http://www.php.net/manual/en/pdo.installation.php Penaos kempunañ PHP gant skor SQLite], implijout a ra PDO)",
        "config-dbsupport-oracle": "* Un embregerezh kenwerzhel diaz roadennoù eo [{{int:version-db-oracle-url}} Oracle]. ([http://www.php.net/manual/en/oci8.installation.php Penaos kempunañ PHP gant skor OCI8])",
-       "config-dbsupport-mssql": "* Un embregerezh kenwerzhel diaz roadennoù evit Windows eo [{{int:version-db-mssql-url}} Microsoft SQL Server]. ([Config-dbsupport-oracle/manual/en/sqlsrv.installation.php Penaos kempunañ PHP gant skor SQLSRV])",
+       "config-dbsupport-mssql": "* Un embregerezh kenwerzhel diaz roadennoù evit Windows eo [{{int:version-db-mssql-url}} Microsoft SQL Server]. ([https://secure.php.net/manual/en/sqlsrv.installation.php Penaos kempunañ PHP gant skor SQLSRV])",
        "config-header-mysql": "Arventennoù MySQL",
        "config-header-postgres": "Arventennoù PostgreSQL",
        "config-header-sqlite": "Arventennoù SQLite",
index 4c39ac0..add4c27 100644 (file)
        "config-nofile": "Die Datei „$1“ konnte nicht gefunden werden. Wurde sie gelöscht?",
        "config-extension-link": "Wusstest du, dass dein Wiki die Nutzung von [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Extensions Erweiterungen] unterstützt?\n\nDu kannst die [https://www.mediawiki.org/wiki/Special:MyLanguage/Category:Extensions_by_category Erweiterungen nach Kategorie] anzeigen oder die [https://www.mediawiki.org/wiki/Extension_Matrix Erweiterungs-Matrix] aufrufen, um eine vollständige Liste der Erweiterungen zu sehen.",
        "config-skins-screenshots": "$1 (Bildschirmfotos: $2)",
+       "config-skins-screenshot": "$1 ($2)",
        "config-extensions-requires": "$1 (erfordert $2)",
        "config-screenshot": "Bildschirmfoto",
        "mainpagetext": "<strong>MediaWiki wurde installiert.</strong>",
index acea1ea..f8ce568 100644 (file)
        "config-dbsupport-postgres": "* Η [{{int:version-db-postgres-url}} PostgreSQL] είναι δημοφιλές σύστημα βάσης δεδομένων ανοικτού κώδικα ως εναλλακτική της MySQL. ([https://secure.php.net/manual/en/pgsql.installation.php Πώς να μεταγλωττίσετε την PHP με υποστήριξη PostgreSQL])",
        "config-dbsupport-sqlite": "* Η [{{int:version-db-sqlite-url}} SQLite] είναι ένα ελαφρύ σύστημα βάσης δεδομένων που υποστηρίζεται πολύ καλά. ([http://www.php.net/manual/en/pdo.installation.php Πώς να μεταγλωττίσετε την PHP με υποστήριξη SQLite], χρησιμοποιεί PDO)",
        "config-dbsupport-oracle": "* Η [{{int:version-db-oracle-url}} Oracle] είναι εμπορική βάση δεδομένων για επιχειρήσεις. ([http://www.php.net/manual/en/oci8.installation.php Πώς να μεταγλωττίσετε την PHP με υποστήριξη OCI8])",
-       "config-dbsupport-mssql": "* Ο [{{int:version-db-mssql-url}} Microsoft SQL Server] είναι εμπορική βάση δεδομένων για επιχειρήσεις που λειτουργεί σε Windows. ([Config-dbsupport-oracle/manual/en/sqlsrv.installation.php Πώς να μεταγλωττίσετε την PHP με υποστήριξη SQLSRV])",
+       "config-dbsupport-mssql": "* Ο [{{int:version-db-mssql-url}} Microsoft SQL Server] είναι εμπορική βάση δεδομένων για επιχειρήσεις που λειτουργεί σε Windows. ([https://secure.php.net/manual/en/sqlsrv.installation.php Πώς να μεταγλωττίσετε την PHP με υποστήριξη SQLSRV])",
        "config-header-mysql": "Ρυθμίσεις MySQL",
        "config-header-postgres": "Ρυθμίσεις PostgreSQL",
        "config-header-sqlite": "Ρυθμίσεις SQLite",
index a5bd3bf..99be820 100644 (file)
        "config-support-info": "MediaWiki es compatible con los siguientes sistemas de bases de datos:\n\n$1\n\nSi no encuentras en el listado el sistema de base de datos que estás intentando utilizar, sigue las instrucciones enlazadas arriba para activar la compatibilidad.",
        "config-dbsupport-mysql": "* [{{int:version-db-mysql-url}} MySQL] es la base de datos mayoritaria para MediaWiki y la que goza de mayor compatibilidad. MediaWiki también funciona con [{{int:version-db-mariadb-url}} MariaDB] y [{{int:version-db-percona-url}} Percona Server], que son compatibles con MySQL. ([https://secure.php.net/manual/es/mysql.installation.php Cómo compilar PHP con compatibilidad MySQL])",
        "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] es un sistema de base de datos popular de código abierto, alternativa a MySQL. ([https://secure.php.net/manual/es/pgsql.installation.php Cómo compilar PHP con compatibilidad PostgreSQL]).",
-       "config-dbsupport-sqlite": "* [{{int:version-db-sqlite-url}} SQLite] es un sistema de base de datos ligero con gran compatibilidad con MediaWiki. ([http://www.php.net/manual/es/pdo.installation.php Cómo compilar PHP con compatibilidad SQLite], usando PDO)",
-       "config-dbsupport-oracle": "* [{{int:version-db-oracle-url}} Oracle] es una base de datos comercial a nivel empresarial. ([http://www.php.net/manual/es/oci8.installation.php Cómo compilar PHP con compatibilidad con OCI8])",
-       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] es un sistema comercial de base de datos empresariales para Windows. ([Config-dbsupport-oracle/manual/en/sqlsrv.installation.php Cómo compilar PHP con compatibilidad con SQLSRV])",
+       "config-dbsupport-sqlite": "* [{{int:version-db-sqlite-url}} SQLite] es un sistema de base de datos ligero con gran compatibilidad con MediaWiki. ([https://secure.php.net/manual/en/pdo.installation.php Cómo compilar PHP con compatibilidad SQLite], usando PDO)",
+       "config-dbsupport-oracle": "* [{{int:version-db-oracle-url}} Oracle] es una base de datos comercial a nivel empresarial. ([https://secure.php.net/manual/en/oci8.installation.php Cómo compilar PHP con compatibilidad con OCI8])",
+       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] es un sistema comercial de base de datos empresariales para Windows. ([https://secure.php.net/manual/en/sqlsrv.installation.php Cómo compilar PHP con compatibilidad con SQLSRV])",
        "config-header-mysql": "Configuración de MySQL",
        "config-header-postgres": "Configuración de PostgreSQL",
        "config-header-sqlite": "Configuración de SQLite",
index 2831396..07198f7 100644 (file)
        "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] iturburu irekiko datu basea sistema famatua da MySQL-rako alternatiba bezala. ([https://secure.php.net/manual/en/pgsql.installation.php How to compile PHP with PostgreSQL support])",
        "config-dbsupport-sqlite": "* [{{int:version-db-sqlite-url}} SQLite] oso ondo onartzen duen datu-basearen sistema arina da.\n ([http://www.php.net/manual/en/pdo.installation.php How to compile PHP with SQLite support], uses PDO)",
        "config-dbsupport-oracle": "* [{{int:version-db-oracle-url}} Oracle] enpresa komertzial baten datu-basea da. ([http://www.php.net/manual/en/oci8.installation.php How to compile PHP with OCI8 support])",
-       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] Windows-entzako enpresa komertzial baten datu-basea da.  ([Config-dbsupport-oracle/manual/en/sqlsrv.installation.php How to compile PHP with SQLSRV support])",
+       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] Windows-entzako enpresa komertzial baten datu-basea da.  ([https://secure.php.net/manual/en/sqlsrv.installation.php How to compile PHP with SQLSRV support])",
        "config-header-mysql": "MySQL hobespenak",
        "config-header-postgres": "PostgreSQL hobespenak",
        "config-header-sqlite": "SQLite hobespenak",
index 15bb39c..a94cae8 100644 (file)
        "config-type-mssql": "سرور مایکروسافت اس‌کیو‌ال",
        "config-support-info": "مدیاویکی سامانه‌های پایگاه اطلاعاتی زیر را حمایت می‌کند:\n$1\nاگر متوجه سامانه پایگاه اطلاعاتی که سعی دارید از فهرست زیر استفاده کنید، نمی‌شوید، بنابراین دستورالعمل‌های مرتبط در بالا را برای فعال کردن پشتیبانی دنبال کنید.",
        "config-dbsupport-mysql": "*[{{int:version-db-mysql-url}} MySQL] مهم‌ترین هدف برای مدیاویکی است و بهترین پشتیبانی. مدیاویکی همچنین کار می‌کند با [{{int:version-db-mariadb-url}} MariaDB] و [{{int:version-db-percona-url}} Percona Server] که با MySQL سازگار هستند.([https://secure.php.net/manual/en/mysqli.installation.php چگونه php را با MySQL کامپایل کنیم])",
-       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} پستگرس‌کیوال] یک سامانه پایگاه اطلاعات متن‌باز پر‌طرفدار است که جایگزینی برای مای‌اس‌کیوال است. ([Config-dbsupport-oracle/manual/en/pgsql.installation.php راهنمای تنظیم کردن پی‌اچ‌پی به همراه پستگرس‌کیوال])",
+       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} پستگرس‌کیوال] یک سامانه پایگاه اطلاعات متن‌باز پر‌طرفدار است که جایگزینی برای مای‌اس‌کیوال است. ([https://secure.php.net/manual/en/pgsql.installation.php راهنمای تنظیم کردن پی‌اچ‌پی به همراه پستگرس‌کیوال])",
        "config-dbsupport-sqlite": "*[{{int:version-db-sqlite-url}} اس‌کیولایت] یک سامانه پایگاه اطلاعاتی کم حجمی است که بسیار خوب پشتیبانی شده‌است.\n([http://www.php.net/manual/en/pdo.installation.php چگونگی کامپایل پی‌اچ‌پی با اس‌کیولایت]، از PDO استفاده می‌کند)",
        "config-dbsupport-oracle": "* [{{int:version-db-oracle-url}} Oracle] یک پایگاه اطلاعاتی کار تبلیغاتی است.\n([http://www.php.net/manual/en/oci8.installation.php How to compile PHP with OCI8 support])",
-       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] یک پایگاه اطلاعاتی موسسهٔ تبلیغاتی برای وینذوز است. ([Config-dbsupport-oracle/manual/en/sqlsrv.installation.php How to compile PHP with SQLSRV support])",
+       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] یک پایگاه اطلاعاتی موسسهٔ تبلیغاتی برای وینذوز است. ([https://secure.php.net/manual/en/sqlsrv.installation.php How to compile PHP with SQLSRV support])",
        "config-header-mysql": "تنظیمات مای‌اس‌کیو‌ال",
        "config-header-postgres": "تنظیمات پست‌گر‌اس‌کیو‌ال",
        "config-header-sqlite": "تنظیمات اس‌کیو‌لایت",
index 2a9bc33..5f47db4 100644 (file)
        "config-type-mssql": "Microsoft SQL Server",
        "config-support-info": "MediaWiki tukee seuraavia tietokantajärjestelmiä:\n\n$1\n\nJos et näe tietokantajärjestelmää, jota yrität käyttää, listattuna alhaalla, seuraa yläpuolella olevia ohjeita tuen aktivoimiseksi.",
        "config-dbsupport-mysql": "* [{{int:version-db-mysql-url}} MySQL] on MediaWikin ensisijainen kohde ja se on myös parhaiten tuettu. MediaWiki voi myös käyttää [{{int:version-db-mariadb-url}} MariaDB]- sekä [{{int:version-db-percona-url}} Percona Server]-järjestelmiä, jotka ovat MySQL-yhteensopivia. ([https://secure.php.net/manual/en/mysqli.installation.php Miten käännetään PHP MySQL-tuella])",
-       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] on suosittu avoimen lähdekoodin tietokantajärjestelmä vaihtoehtona MySQL:lle. ([Config-dbsupport-oracle/manual/en/pgsql.installation.php Kuinka käännetään PHP PostgreSQL-tuella])",
+       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] on suosittu avoimen lähdekoodin tietokantajärjestelmä vaihtoehtona MySQL:lle. ([https://secure.php.net/manual/en/pgsql.installation.php Kuinka käännetään PHP PostgreSQL-tuella])",
        "config-dbsupport-sqlite": "* [{{int:version-db-sqlite-url}} SQLite] on kevyt tietokantajärjestelmä, jota tuetaan hyvin. ([http://www.php.net/manual/en/pdo.installation.php Miten käännetään PHP SQLite-tuella], käyttää PDO:ta)",
        "config-dbsupport-oracle": "* [{{int:version-db-oracle-url}} Oracle] on kaupallinen yritystietokanta. ([http://www.php.net/manual/en/oci8.installation.php Kuinka käännetään PHP OCI8-tuella])",
-       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] on kaupallinen yritystietokanta Windowsille. ([Config-dbsupport-oracle/manual/en/sqlsrv.installation.php Miten käännetään PHP SQLSRV-tuella])",
+       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] on kaupallinen yritystietokanta Windowsille. ([https://secure.php.net/manual/en/sqlsrv.installation.php Miten käännetään PHP SQLSRV-tuella])",
        "config-header-mysql": "MySQL-asetukset",
        "config-header-postgres": "PostgreSQL-asetukset",
        "config-header-sqlite": "SQLite-asetukset",
index f30914b..c625b67 100644 (file)
        "config-type-mssql": "Microsoft SQL Server",
        "config-support-info": "MediaWiki soporta os seguintes sistemas de bases de datos:\n\n$1\n\nSe non ve listado a continuación o sistema de base de datos que intenta usar, siga as instrucións ligadas enriba para activar o soporte.",
        "config-dbsupport-mysql": "* [{{int:version-db-mysql-url}} MySQL] é o obxectivo principal para MediaWiki e está mellor soportado. MediaWiki tamén funciona con [{{int:version-db-mariadb-url}} MariaDB] e [{{int:version-db-percona-url}} Percona Server], que son compatibles con MySQL. ([https://secure.php.net/manual/en/mysqli.installation.php  Como compilar PHP con compatibilidade MySQL])",
-       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] é un sistema de base de datos popular e de código aberto como alternativa a MySQL. ([Config-dbsupport-oracle/manual/en/pgsql.installation.php Como compilar PHP con compatibilidade PostgreSQL])",
+       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] é un sistema de base de datos popular e de código aberto como alternativa a MySQL. ([https://secure.php.net/manual/en/pgsql.installation.php Como compilar PHP con compatibilidade PostgreSQL])",
        "config-dbsupport-sqlite": "* [{{int:version-db-sqlite-url}} SQLite] é un sistema de base de datos lixeiro moi ben soportado. ([http://www.php.net/manual/en/pdo.installation.php Como compilar o PHP con soporte SQLite], emprega PDO)",
        "config-dbsupport-oracle": "* [{{int:version-db-oracle-url}} Oracle] é un sistema comercial de xestión de base de datos de nivel empresarial. ([http://www.php.net/manual/en/oci8.installation.php Como compilar o PHP con compatibilidade OCI8])",
-       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] é un sistema comercial de xestión de base de datos de nivel empresarial para Windows. ([Config-dbsupport-oracle/manual/en/sqlsrv.installation.php Como compilar o PHP con compatibilidade SQLSRV])",
+       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] é un sistema comercial de xestión de base de datos de nivel empresarial para Windows. ([https://secure.php.net/manual/en/sqlsrv.installation.php Como compilar o PHP con compatibilidade SQLSRV])",
        "config-header-mysql": "Configuración do MySQL",
        "config-header-postgres": "Configuración do PostgreSQL",
        "config-header-sqlite": "Configuración do SQLite",
index ea28b58..36871b8 100644 (file)
        "config-type-mssql": "Microsoft SQL Server",
        "config-support-info": "מדיה־ויקי תומכת במערכות מסדי הנתונים הבאות:\n\n$1\n\nאם אינך רואה את מסד הנתונים שלך ברשימה, יש לעקוב אחר ההוראות המקושרות לעיל כדי להפעיל את התמיכה.",
        "config-dbsupport-mysql": "* [{{int:version-db-mysql-url}} MySQL] הוא היעד העיקרי עבור מדיה־ויקי ולו התמיכה הטובה ביותר. מדיה־ויקי עובדת גם עם [{{int:version-db-mariadb-url}} MariaDB] ועם [{{int:version-db-percona-url}} Percona Server], שתואמים ל־MySQL. (ר׳ [https://secure.php.net/manual/en/mysql.installation.php how to compile PHP with MySQL support])",
-       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] הוא מסד נתונים נפוץ בקוד פתוח והוא נפוץ בתור חלופה ל־MySQL. (ר׳ [Config-dbsupport-oracle/manual/en/pgsql.installation.php how to compile PHP with PostgreSQL support]).",
+       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] הוא מסד נתונים נפוץ בקוד פתוח והוא נפוץ בתור חלופה ל־MySQL. (ר׳ [https://secure.php.net/manual/en/pgsql.installation.php how to compile PHP with PostgreSQL support]).",
        "config-dbsupport-sqlite": "* [{{int:version-db-sqlite-url}} SQLite] הוא מסד נתונים קליל עם תמיכה טובה מאוד. (ר׳ [http://www.php.net/manual/en/pdo.installation.php How to compile PHP with SQLite support], משתמש ב־PDO)",
        "config-dbsupport-oracle": "* [{{int:version-db-oracle-url}} Oracle] הוא מסד נתונים עסקי מסחרי. (ר׳ [http://www.php.net/manual/en/oci8.installation.php How to compile PHP with OCI8 support])",
-       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] הוא מסד נתונים עסקי מסחרי לחלונות. ([Config-dbsupport-oracle/manual/en/sqlsrv.installation.php How to compile PHP with SQLSRV support])",
+       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] הוא מסד נתונים עסקי מסחרי לחלונות. ([https://secure.php.net/manual/en/sqlsrv.installation.php How to compile PHP with SQLSRV support])",
        "config-header-mysql": "הגדרות MySQL",
        "config-header-postgres": "הגדרות PostgreSQL",
        "config-header-sqlite": "הגדרות SQLite",
index 39c5353..ef58e56 100644 (file)
        "config-type-mssql": "Microsoft SQL Server",
        "config-support-info": "MediaWiki unnerstützt die follichenne Datebanksysteme:\n\n$1\n\nSoweit net das Datebanksystem oongezeicht weard, das verwennt werre soll, gebt das uwe en Link zu der Oonleitung mit Informatione, wie das aktiviert sin kann.",
        "config-dbsupport-mysql": "* [{{int:version-db-mysql-url}} MySQL] ist das von MediaWiki primär unterstützte Datebanksystem. MediaWiki funktioniert ooch mit [{{int:version-db-mariadb-url}} MariaDB] und [{{int:version-db-percona-url}} Percona Server], die MySQL-kompatibel sind. ([https://secure.php.net/manual/en/mysqli.installation.php Oonleitung zur Kompilierung von PHP mit MySQL-Unnerstützung] [englisch Sproch])",
-       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] ist en beliebtes Open-Source-Datebanksystem und ein Alternativ zu MySQL. Es gibt awer enche klenre Implementierungsfehler, so dass von der Nutzung in ener Produktivumgebung abgerat weard. ([Config-dbsupport-oracle/manual/de/pgsql.installation.php Oonnleitung zur Kompilierung von PHP mit PostgreSQL-Unterstützung])",
+       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] ist en beliebtes Open-Source-Datebanksystem und ein Alternativ zu MySQL. Es gibt awer enche klenre Implementierungsfehler, so dass von der Nutzung in ener Produktivumgebung abgerat weard. ([https://secure.php.net/manual/en/pgsql.installation.php Oonnleitung zur Kompilierung von PHP mit PostgreSQL-Unterstützung])",
        "config-dbsupport-sqlite": "* [{{int:version-db-sqlite-url}} SQLite] ist en verschlanktes Datebanksystem, das ooch gut unnerstützt weard ([http://www.php.net/manual/de/pdo.installation.php Oonleitung zur Kompilierung von PHP mit SQLite-Unterstützung], verwennt PHP Data Objects (PDO))",
        "config-dbsupport-oracle": "* [{{int:version-db-oracle-url}} Oracle] ist en kommerzielle Unnernehmensdatebank ([http://www.php.net/manual/en/oci8.installation.php Oonleitung zur Kompilierung von PHP mit OCI8-Unnerstützung (en)])",
        "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] ist en gewerbliche Unnernehmensdatebank für Windows. ([Config-dbsupport-oracle/manual/de/sqlsrv.installation.php Oonleitung zur Kompilierung von PHP mithilfe SQLSRV-Unnerstützung])",
index 8b7a124..3d898ea 100644 (file)
@@ -88,7 +88,7 @@
        "config-type-sqlite": "SQLite",
        "config-type-oracle": "Oracle",
        "config-dbsupport-mysql": "* [{{int:version-db-mysql-url}} MySQL] je primarny cil za MediaWiki a podpěruje so najlěpje. MediaWiki funguje tež z [{{int:version-db-mariadb-url}} MariaDB] a [{{int:version-db-percona-url}} Percona Server], kotrejž stej kompatibelnej z MySQL. ([https://secure.php.net/manual/en/mysqli.installation.php Nawod ke kompilowanju  PHP z  MySQL-podpěru])",
-       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] je popularny system datoweje banki zjawneho žórła jako alternatiwa k MySQL. Móhło hišće někotre zmylki eksistować, a njeporuča so jón w produktiwnej wokolinje wužiwać. ([Config-dbsupport-oracle/manual/en/pgsql.installation.php Nawod za kompilowanje PHP z podpěru PostgreSQL])",
+       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] je popularny system datoweje banki zjawneho žórła jako alternatiwa k MySQL. Móhło hišće někotre zmylki eksistować, a njeporuča so jón w produktiwnej wokolinje wužiwać. ([https://secure.php.net/manual/en/pgsql.installation.php Nawod za kompilowanje PHP z podpěru PostgreSQL])",
        "config-dbsupport-oracle": "* [{{int:version-db-oracle-url}} Oracle] je komercielna předewzaćelska datowa banka. ([http://www.php.net/manual/en/oci8.installation.php Nawod za kompilowanje PHP z OCI8-podpěru])",
        "config-header-mysql": "Nastajenja MySQL",
        "config-header-postgres": "Nastajenja PostgreSQL",
index 3f8a00f..93c95ab 100644 (file)
        "config-type-mssql": "Microsoft SQL Szerver",
        "config-support-info": "A MediaWiki a következő adatbázisrendszereket támogatja:\n\n$1\n\nHa az alábbi listán nem találod azt a rendszert, melyet használni szeretnél, a fenti linken található instrukciókat követve engedélyezheted a támogatását.",
        "config-dbsupport-mysql": "* A [{{int:version-db-mysql-url}} MySQL] a MediaWiki elsődleges célpontja, így a legjobban támogatott. A MediaWiki elfut [{{int:version-db-mariadb-url}} MariaDB-n] és [{{int:version-db-percona-url}} Percona Serveren] is, mivel ezek MySQL-kompatibilisek. ([https://secure.php.net/manual/en/mysql.installation.php Hogyan fordítható a PHP MySQL-támogatással])",
-       "config-dbsupport-postgres": "* A [{{int:version-db-postgres-url}} PostgreSQL] népszerű, nyílt forráskódú adatbázisrendszer, a MySQL alternatívája. ([Config-dbsupport-oracle/manual/en/pgsql.installation.php Hogyan fordítható a PHP PostgreSQL-támogatással])",
+       "config-dbsupport-postgres": "* A [{{int:version-db-postgres-url}} PostgreSQL] népszerű, nyílt forráskódú adatbázisrendszer, a MySQL alternatívája. ([https://secure.php.net/manual/en/pgsql.installation.php Hogyan fordítható a PHP PostgreSQL-támogatással])",
        "config-dbsupport-sqlite": "* Az [{{int:version-db-sqlite-url}} SQLite] egy könnyű, nagyon jól támogatott adatbázisrendszer. ([http://www.php.net/manual/en/pdo.installation.php Hogyan fordítható a PHP SQLite-támogatással], PDO-t használ)",
        "config-dbsupport-oracle": "* Az [{{int:version-db-oracle-url}} Oracle] kereskedelmi, vállalati adatbázisrendszer. ([http://www.php.net/manual/en/oci8.installation.php Hogyan fordítható a PHP OCI8-támogatással])",
-       "config-dbsupport-mssql": "* A [{{int:version-db-mssql-url}} Microsoft SQL Server] kereskedelmi, vállalati adatbázisrendszer. ([Config-dbsupport-oracle/manual/en/sqlsrv.installation.php Hogyan fordítható a PHP SQLSRV-támogatással])",
+       "config-dbsupport-mssql": "* A [{{int:version-db-mssql-url}} Microsoft SQL Server] kereskedelmi, vállalati adatbázisrendszer. ([https://secure.php.net/manual/en/sqlsrv.installation.php Hogyan fordítható a PHP SQLSRV-támogatással])",
        "config-header-mysql": "MySQL-beállítások",
        "config-header-postgres": "PostgreSQL-beállítások",
        "config-header-sqlite": "SQLite-beállítások",
index d9e2ad1..7ef9c2d 100644 (file)
        "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] es un systema de base de datos popular e open source, alternativa a MySQL. ([https://secure.php.net/manual/en/pgsql.installation.php Como compilar PHP con supporto de PostgreSQL])",
        "config-dbsupport-sqlite": "* [{{int:version-db-sqlite-url}} SQLite] es un systema de base de datos legier que es multo ben supportate. ([http://www.php.net/manual/en/pdo.installation.php Como compilar PHP con supporto de SQLite], usa PDO)",
        "config-dbsupport-oracle": "* [{{int:version-db-oracle-url}} Oracle] es un banca de datos commercial pro interprisas. ([http://www.php.net/manual/en/oci8.installation.php Como compilar PHP con supporto de OCI8])",
-       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] es un base de datos de interprisa commercial pro Windows. ([Config-dbsupport-oracle/manual/en/sqlsrv.installation.php Como compilar PHP con supporto de SQLSRV])",
+       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] es un base de datos de interprisa commercial pro Windows. ([https://secure.php.net/manual/en/sqlsrv.installation.php Como compilar PHP con supporto de SQLSRV])",
        "config-header-mysql": "Configuration de MySQL",
        "config-header-postgres": "Configuration de PostgreSQL",
        "config-header-sqlite": "Configuration de SQLite",
index 786bdeb..7605f85 100644 (file)
        "config-type-mssql": "Microsoft SQL Server",
        "config-support-info": "MediaWiki mendukung sistem basis data berikut:\n\n$1\n\nJika Anda tidak melihat sistem basis data yang Anda gunakan tercantum di bawah ini, ikuti petunjuk terkait di atas untuk mengaktifkan dukungan.",
        "config-dbsupport-mysql": "* [{{int:version-db-mysql-url}} MySQL] adalah target utama MediaWiki dan memiliki dukungan terbaik. MediaWiki juga berjalan dengan [{{int:version-db-mariadb-url}} MariaDB] dan [{{int:version-db-percona-url}} Server Percona], yang kompatibel dengan MySQL. ([https://secure.php.net/manual/en/mysql.installation.php Cara mengompilasi PHP dengan dukungan MySQL])",
-       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] adalah sistem basis data sumber terbuka populer sebagai alternatif MySQL.([Config-dbsupport-oracle/manual/en/pgsql.installation.php Bagaimana mengompilasikan PHP dengan dukungan PostgreSQL])",
+       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] adalah sistem basis data sumber terbuka populer sebagai alternatif MySQL.([https://secure.php.net/manual/en/pgsql.installation.php Bagaimana mengompilasikan PHP dengan dukungan PostgreSQL])",
        "config-dbsupport-sqlite": "* [{{int:version-db-sqlite-url}} SQLite] adalah sistem basis data yang ringan yang sangat baik dukungannya. ([http://www.php.net/manual/en/pdo.installation.php cara mengompilasi PHP dengan dukungan SQLite], menggunakan PDO)",
        "config-dbsupport-oracle": "* [{{int:version-db-oracle-url}} Oracle] adalah basis data komersial untuk perusahaan. ([http://www.php.net/manual/en/oci8.installation.php cara mengompilasi PHP dengan dukungan OCI8])",
-       "config-dbsupport-mssql": "[{{int:version-db-mssql-url}} Microsoft SQL Server] adalah database perusahaan komersial untuk Windows. ([Config-dbsupport-oracle/manual/en/sqlsrv.installation.php Bagaimana cara mengkompilasi PHP dengan dukungan SQLSRV])",
+       "config-dbsupport-mssql": "[{{int:version-db-mssql-url}} Microsoft SQL Server] adalah database perusahaan komersial untuk Windows. ([https://secure.php.net/manual/en/sqlsrv.installation.php Bagaimana cara mengkompilasi PHP dengan dukungan SQLSRV])",
        "config-header-mysql": "Pengaturan MySQL",
        "config-header-postgres": "Pengaturan PostgreSQL",
        "config-header-sqlite": "Pengaturan SQLite",
index 40bcff5..35adc1c 100644 (file)
@@ -78,7 +78,7 @@
        "config-memory-raised": "Il valore <code>memory_limit</code> di PHP è $1, aumentato a $2.",
        "config-memory-bad": "''Attenzione:''' Il valore di <code>memory_limit</code> di PHP è $1.\nProbabilmente è troppo basso.\nL'installazione potrebbe non riuscire!",
        "config-apc": "[https://secure.php.net/apc APC] è installato",
-       "config-apcu": "[https://secure.php.net/apc APC] è installato",
+       "config-apcu": "[https://secure.php.net/apcu APCu] è installato",
        "config-wincache": "[https://www.iis.net/downloads/microsoft/wincache-extension WinCache] è installato",
        "config-no-cache-apcu": "'''Attenzione:''' [https://secure.php.net/apcu APCu], [http://xcache.lighttpd.net/ XCache] o [https://www.iis.net/downloads/microsoft/wincache-extension WinCache] non sono stati trovati.\nLa caching degli oggetti non è attivata.",
        "config-mod-security": "<strong>Attenzione:</strong> Il tuo server web ha il [https://modsecurity.org/ mod_security] abilitato. Se non correttamente configurato, può creare problemi a MediaWiki o ad altro software che permette agli utenti di pubblicare contenuto.\nFai riferimento alla [https://modsecurity.org/documentation/ documentazione sul mod_security] o contatta il supporto tecnico del tuo provider di hosting se si verificano errori.",
        "config-type-mssql": "Microsoft SQL Server",
        "config-support-info": "MediaWiki supporta i seguenti sistemi di database:\n\n$1\n\nSe fra quelli elencati qui sotto non vedi il sistema di database che vorresti utilizzare, seguire le istruzioni linkate sopra per abilitare il supporto.",
        "config-dbsupport-mysql": "* [{{int:version-db-mysql-url}} MySQL] è la configurazione preferibile per MediaWiki ed è quella meglio supportata. MediaWiki funziona anche con [{{int:version-db-mariadb-url}} MariaDB] e [{{int:version-db-percona-url}} Percona Server], che sono compatibili con MySQL.([https://secure.php.net/manual/en/mysqli.installation.php Come compilare PHP con supporto MySQL])",
-       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] è un popolare sistema di database open source come alternativa a MySQL. ([Config-dbsupport-oracle/manual/en/pgsql.installation.php Come compilare PHP con supporto PostgreSQL])",
+       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] è un popolare sistema di database open source come alternativa a MySQL. ([https://secure.php.net/manual/en/pgsql.installation.php Come compilare PHP con supporto PostgreSQL])",
        "config-dbsupport-sqlite": "* [{{int:version-db-sqlite-url}} SQLite]  è un sistema di database leggero, che è supportato molto bene. ([https://secure.php.net/manual/en/pdo.installation.php Come compilare PHP con supporto SQLite], utilizza PDO)",
        "config-dbsupport-oracle": "* [{{int:version-db-oracle-url}} Oracle] è un database di un'impresa commerciale. ([https://secure.php.net/manual/en/oci8.installation.php Come compilare PHP con supporto OCI8])",
-       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] è un database di un'impresa commerciale per Windows. ([Config-dbsupport-oracle/manual/en/sqlsrv.installation.php Come compilare PHP con supporto SQLSRV])",
+       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] è un database di un'impresa commerciale per Windows. ([https://secure.php.net/manual/en/sqlsrv.installation.php Come compilare PHP con supporto SQLSRV])",
        "config-header-mysql": "Impostazioni MySQL",
        "config-header-postgres": "Impostazioni PostgreSQL",
        "config-header-sqlite": "Impostazioni SQLite",
index 44fac37..838eaae 100644 (file)
        "config-type-mssql": "マイクロソフト SQL Server",
        "config-support-info": "MediaWiki は以下のデータベース システムに対応しています:\n\n$1\n\n使用しようとしているデータベース システムが下記の一覧にない場合は、上記リンク先の手順に従ってインストールしてください。",
        "config-dbsupport-mysql": "* [{{int:version-db-mysql-url}} MySQL]はMediaWikiの主要な対象であり、最もよくサポートされています。MediaWikiはMySQLと互換性のある[{{int:version-db-mariadb-url}} MariaDB]、[{{int:version-db-percona-url}} Percona Server]でも動きます。 ([https://secure.php.net/manual/ja/mysqli.installation.php PHPをMySQLサポート付きでコンパイルする方法])",
-       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] は、MySQLの代替として人気がある公開のデータベースシステムです。([Config-dbsupport-oracle/manual/en/pgsql.installation.php PHPをPostgreSQLサポート付きでコンパイルする方法])",
+       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] は、MySQLの代替として人気がある公開のデータベースシステムです。([https://secure.php.net/manual/en/pgsql.installation.php PHPをPostgreSQLサポート付きでコンパイルする方法])",
        "config-dbsupport-sqlite": "* [{{int:version-db-sqlite-url}} SQLite]は、良くサポートされている、軽量データベースシステムです。([http://www.php.net/manual/ja/pdo.installation.php SQLiteに対応したPHPをコンパイルする方法]、PDOを使用)",
        "config-dbsupport-oracle": "* [{{int:version-db-oracle-url}} Oracle]は商業企業のデータベースです。([http://www.php.net/manual/en/oci8.installation.php OCI8サポートなPHPをコンパイルする方法])",
-       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server]は商業企業のWindows用データベースです。([Config-dbsupport-oracle/manual/en/sqlsrv.installation.php SQLSRVサポートなPHPをコンパイルする方法])",
+       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server]は商業企業のWindows用データベースです。([https://secure.php.net/manual/en/sqlsrv.installation.php SQLSRVサポートなPHPをコンパイルする方法])",
        "config-header-mysql": "MySQL の設定",
        "config-header-postgres": "PostgreSQL の設定",
        "config-header-sqlite": "SQLite の設定",
index a376b61..d97c55f 100644 (file)
        "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL]은 MySQL의 대안으로서 인기 있는 오픈 소스 데이터베이스 시스템입니다. ([https://secure.php.net/manual/en/pgsql.installation.php PostgreSQL 지원으로 PHP를 컴파일하는 방법])",
        "config-dbsupport-sqlite": "*  [{{int:version-db-sqlite-url}} SQLite]는 매우 잘 지원되고 가벼운 데이터베이스 시스템입니다. ([http://www.php.net/manual/en/pdo.installation.php SQLite 지원으로 PHP를 컴파일하는 방법], PDO 사용)",
        "config-dbsupport-oracle": "*  [{{int:version-db-oracle-url}} Oracle]은 상용 기업 데이터베이스입니다. ([http://www.php.net/manual/en/oci8.installation.php OCI8 지원으로 PHP를 컴파일하는 방법])",
-       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL 서버]는 Windows용 상용 기업 데이터베이스입니다. ([Config-dbsupport-oracle/manual/en/sqlsrv.installation.php SQLSRV 지원으로 PHP를 컴파일하는 방법])",
+       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL 서버]는 Windows용 상용 기업 데이터베이스입니다. ([https://secure.php.net/manual/en/sqlsrv.installation.php SQLSRV 지원으로 PHP를 컴파일하는 방법])",
        "config-header-mysql": "MySQL 설정",
        "config-header-postgres": "PostgreSQL 설정",
        "config-header-sqlite": "SQLite 설정",
index 030cecf..4b89b41 100644 (file)
        "config-dbsupport-postgres": "* <i lang=\"en\">[{{int:version-db-postgres-url}} PostgreSQL]</i> es e bikannt Daatebangksüßtehm met offe Quälltäxde, un ed es och en Wahl nävve <i lang=\"en\">MySQL</i>. Et sinn_er ävver paa klein Fählersche bekannt, um mer künne et em Momang för et reschtijje Werke nit ämfähle. ([https://secure.php.net/manual/de/pgsql.installation.php Aanleidung för et Övversäze un Enreeschte von PHP met <i lang=\"en\">PostgreSQL</i> dobei, op Deutsch])",
        "config-dbsupport-sqlite": "* <i lang=\"en\">[{{int:version-db-sqlite-url}} SQLite]</i> es e eijfach Daatebangksüßtehm, wat joot en Schoß jehallde weed. ([http://www.php.net/manual/de/pdo.installation.php Aanleidong för et Övversäze un Enreeschte von PHP met <i lang=\"en\">SQLite</i> dobei, op Deutsch])",
        "config-dbsupport-oracle": "* <i lang=\"en\">[{{int:version-db-oracle-url}} Oracle]</i> es e jeschäfflesch Daatebangksüßtehm för Ferme. ([http://www.php.net/manual/de/oci8.installation.php Aanleidong för et Övversäze un Enreeschte von PHP met <i lang=\"en\" xml:lang=\"en\">OCI8</i> dobei, op Deutsch])",
-       "config-dbsupport-mssql": "* Dä <i lang=\"en\" xml:lang=\"en\">[{{int:version-db-mssql-url}} Microsoft SQL Server]</i> es e jeschäfflesch Dahtebangksüßtehm för Rääschner met <i lang=\"en\" xml:lang=\"en\">Windows</i>. ([Config-dbsupport-oracle/manual/de/sqlsrv.installation.php Aanleidong för et Övversäze un Enreeschte von <i lang=\"en\" xml:lang=\"en\" dir=\"ltr\" title=\"PHP Hypertext Preprocessor\">PHP</i> met <i lang=\"en\" xml:lang=\"en\">SQLSRV </i> dobei, op Deutsch])",
+       "config-dbsupport-mssql": "* Dä <i lang=\"en\" xml:lang=\"en\">[{{int:version-db-mssql-url}} Microsoft SQL Server]</i> es e jeschäfflesch Dahtebangksüßtehm för Rääschner met <i lang=\"en\" xml:lang=\"en\">Windows</i>. ([https://secure.php.net/manual/en/sqlsrv.installation.php Aanleidong för et Övversäze un Enreeschte von <i lang=\"en\" xml:lang=\"en\" dir=\"ltr\" title=\"PHP Hypertext Preprocessor\">PHP</i> met <i lang=\"en\" xml:lang=\"en\">SQLSRV </i> dobei, op Deutsch])",
        "config-header-mysql": "De Enshtällunge för de <i lang=\"en\">MySQL</i> Daatebangk",
        "config-header-postgres": "De Enshtällunge för de <i lang=\"en\">PostgreSQL</i> Daatebangk",
        "config-header-sqlite": "De Enshtällunge för de <i lang=\"en\">SQLite</i> Daatebangk",
index a2c250c..92adf7b 100644 (file)
@@ -84,7 +84,7 @@
        "config-type-sqlite": "SQLite",
        "config-type-oracle": "Oracle",
        "config-type-mssql": "Microsoft SQL Server",
-       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] ass e beléiften Open-Source-Datebanksystem an eng Alternativ zu MySQL. ([Config-dbsupport-oracle/manual/de/pgsql.installation.php Uleedung fir d'Kompilatoun vu PHP mat PostgreSQL-Ënnerstëtzung])",
+       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] ass e beléiften Open-Source-Datebanksystem an eng Alternativ zu MySQL. ([https://secure.php.net/manual/en/pgsql.installation.php Uleedung fir d'Kompilatoun vu PHP mat PostgreSQL-Ënnerstëtzung])",
        "config-dbsupport-oracle": "* [{{int:version-db-oracle-url}} Oracle] ass eng kommerziell Datebank-Software. ([http://www.php.net/manual/en/oci8.installation.php How to compile PHP mat OCI8 Ënnerstëtzung])",
        "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] ass eng kommerziell Datebank-Software fir Windows. ([https://secure.php.net/manual/en/sqlsrv.installation.php Wéi PHP mat SQLSRV Ënnerstëtzung kompiléieren])",
        "config-header-mysql": "MySQL-Astellungen",
index 01884d9..130dbda 100644 (file)
        "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] o l'è un popolare scistema de database open source comme alternativa a MySQL. ([https://secure.php.net/manual/en/pgsql.installation.php Comme compilâ PHP con suporto PostgreSQL])",
        "config-dbsupport-sqlite": "* [{{int:version-db-sqlite-url}} SQLite] o l'è un scistema de database leggio, ch'o l'è suportou molto ben. ([http://www.php.net/manual/en/pdo.installation.php Comme compilâ PHP con suporto SQLite], o l'utilizza PDO)",
        "config-dbsupport-oracle": "* [{{int:version-db-oracle-url}} Oracle] o l'è un database de un'impreiza comerciâ. ([http://www.php.net/manual/en/oci8.installation.php Comme compilâ PHP con suporto OCI8])",
-       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] o l'è un database de un'impreiza commerciâ per Windows. ([Config-dbsupport-oracle/manual/en/sqlsrv.installation.php Comme compilâ PHP con supporto SQLSRV])",
+       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] o l'è un database de un'impreiza commerciâ per Windows. ([https://secure.php.net/manual/en/sqlsrv.installation.php Comme compilâ PHP con supporto SQLSRV])",
        "config-header-mysql": "Impostaçioin MySQL",
        "config-header-postgres": "Impostaçioin PostgreSQL",
        "config-header-sqlite": "Impostaçioin SQLite",
index 38b024c..829a543 100644 (file)
        "config-type-mssql": "Microsoft SQL Server",
        "config-support-info": "МедијаВики ги поддржува следниве системи на бази на податоци:\n\n$1\n\nАко системот што сакате да го користите не е наведен подолу, тогаш проследете ја горенаведената врска со инструкции за да овозможите поддршка за тој систем.",
        "config-dbsupport-mysql": "* [{{int:version-db-mysql-url}} MySQL] е главната цел на МедијаВики и најдобро е поддржан. МедијаВики работи и со [{{int:version-db-mariadb-url}} MariaDB] и [{{int:version-db-percona-url}} Percona], кои се складни со MySQL. ([https://secure.php.net/manual/en/mysqli.installation.php Како да срочите PHP со поддршка за MySQL])",
-       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] е популарен систем на бази на податоци со отворен код кој претставува алтернатива на MySQL ([Config-dbsupport-oracle/manual/en/pgsql.installation.php како да составите PHP со поддршка за PostgreSQL]). ([Config-dbsupport-oracle/manual/en/pgsql.installation.php Како да срочите PHP со поддршка за PostgreSQL])",
+       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] е популарен систем на бази на податоци со отворен код кој претставува алтернатива на MySQL ([https://secure.php.net/manual/en/pgsql.installation.php како да составите PHP со поддршка за PostgreSQL]). ([https://secure.php.net/manual/en/pgsql.installation.php Како да срочите PHP со поддршка за PostgreSQL])",
        "config-dbsupport-sqlite": "* [{{int:version-db-sqlite-url}} SQLite] е лесен систем за бази на податоци кој е многу добро поддржан. ([https://secure.php.net/manual/en/pdo.installation.php Како да составите PHP со поддршка за SQLite], користи PDO)",
        "config-dbsupport-oracle": "* [{{int:version-db-oracle-url}} Oracle] е база на податоци на комерцијално претпријатие. ([https://secure.php.net/manual/en/oci8.installation.php Како да составите PHP со поддршка за OCI8])",
-       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server]  е база на податоци на комерцијално претпријатиe за Windows ([Config-dbsupport-oracle/manual/en/sqlsrv.installation.php How to compile PHP with SQLSRV поддршка])",
+       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server]  е база на податоци на комерцијално претпријатиe за Windows ([https://secure.php.net/manual/en/sqlsrv.installation.php How to compile PHP with SQLSRV поддршка])",
        "config-header-mysql": "Нагодувања на MySQL",
        "config-header-postgres": "Нагодувања на PostgreSQL",
        "config-header-sqlite": "Нагодувања на SQLite",
index 377056f..5cacc89 100644 (file)
        "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] è nu sistema canusciuto 'e database open source ca fosse n'alternativa a MySQL. Putess'avé cocch'errore p'arricettà, e nun è cunzigliato 'e ll'ausà dint'a n'ambiente 'e produziona. ([https://secure.php.net/manual/en/pgsql.installation.php Comme s'avess'a cumpilà PHP cu suppuorto PostgreSQL])",
        "config-dbsupport-sqlite": "* [{{int:version-db-sqlite-url}} SQLite]  è nu sistema 'e database leggero, ca fosse assaje buono suppurtato. ([http://www.php.net/manual/en/pdo.installation.php Comme cumpilà PHP cu suppuorto SQLite], aùsa PDO)",
        "config-dbsupport-oracle": "* [{{int:version-db-oracle-url}} Oracle] è nu database 'e na fraveca commerciale. ([http://www.php.net/manual/en/oci8.installation.php Comme cumpilà PHP cu suppuorto OCI8])",
-       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] è nu database 'e na fraveca commerciale p' 'o Windows. ([Config-dbsupport-oracle/manual/en/sqlsrv.installation.php Comme cumpilà PHP cu suppuorto SQLSRV])",
+       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] è nu database 'e na fraveca commerciale p' 'o Windows. ([https://secure.php.net/manual/en/sqlsrv.installation.php Comme cumpilà PHP cu suppuorto SQLSRV])",
        "config-header-mysql": "Mpustaziune MySQL",
        "config-header-postgres": "Mpustaziune PostgreSQL",
        "config-header-sqlite": "Mpustaziune SQLite",
index c5ebb88..607926e 100644 (file)
        "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] is een populair open source databasesysteem als alternatief voor MySQL.([https://secure.php.net/manual/en/pgsql.installation.php Hoe u PHP kunt compileren met ondersteuning voor PostgreSQL])",
        "config-dbsupport-sqlite": "* [{{int:version-db-sqlite-url}} SQLite] is een zeer goed ondersteund lichtgewicht databasesysteem ([http://www.php.net/manual/en/pdo.installation.php hoe PHP gecompileerd moet zijn met ondersteuning voor SQLite]; gebruikt PDO).",
        "config-dbsupport-oracle": "* [{{int:version-db-oracle-url}} Oracle] is een commerciële database voor grote bedrijven ([http://www.php.net/manual/en/oci8.installation.php PHP compileren met ondersteuning voor OCI8]).",
-       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] is een commerciële enterprisedatabase voor Windows ([Config-dbsupport-oracle/manual/en/sqlsrv.installation.php PHP compileren met ondersteuning voor SQLSRV]).",
+       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] is een commerciële enterprisedatabase voor Windows ([https://secure.php.net/manual/en/sqlsrv.installation.php PHP compileren met ondersteuning voor SQLSRV]).",
        "config-header-mysql": "MySQL-instellingen",
        "config-header-postgres": "PostgreSQL-instellingen",
        "config-header-sqlite": "SQLite-instellingen",
index c4cb8a6..f1003c6 100644 (file)
@@ -80,7 +80,7 @@
        "config-pcre-no-utf8": "'''Błąd krytyczny''' – wydaje się, że moduł PCRE w PHP został skompilowany bez wsparcia dla UTF‐8.\nMediaWiki wymaga wsparcia dla UTF‐8 do prawidłowego działania.",
        "config-memory-raised": "PHP <code>memory_limit</code> było ustawione na $1, zostanie zwiększone do $2.",
        "config-memory-bad": "'''Uwaga:''' PHP <code>memory_limit</code> jest ustawione na $1.\nTo jest prawdopodobnie zbyt mało.\nInstalacja może się nie udać!",
-       "config-apc": "[Http://www.php.net/apc APC] jest zainstalowany",
+       "config-apc": "[https://secure.php.net/apc APC] jest zainstalowany",
        "config-apcu": "[https://secure.php.net/apcu APCu] jest zainstalowany",
        "config-wincache": "[https://www.iis.net/downloads/microsoft/wincache-extension WinCache] jest zainstalowany",
        "config-no-cache-apcu": "<strong>Ostrzeżenie:</strong> Nie można było znaleźć [https://secure.php.net/apcu APCu] ani [https://www.iis.net/downloads/microsoft/wincache-extension WinCache].\nPamięć podręczna obiektów nie została włączona.",
        "config-type-mssql": "Microsoft SQL Server",
        "config-support-info": "MediaWiki może współpracować z następującymi systemami baz danych:\n\n$1\n\nPoniżej wyświetlone są systemy baz danych gotowe do użycia. Jeżeli poniżej brakuje bazy danych, z której chcesz skorzystać, oznacza to, że brakuje odpowiedniego oprogramowania lub zostało ono niepoprawnie skonfigurowane. Powyżej znajdziesz odnośniki do dokumentacji, która pomoże w konfiguracji odpowiednich komponentów.",
        "config-dbsupport-mysql": "* [{{int:version-db-mysql-url}} MySQL] jest bazą danych, na której rozwijane jest oprogramowanie MediaWiki. MediaWiki działa również z [{{int:version-db-mariadb-url}} MariaDB] i [{{int:version-db-percona-url}} Percona Server], które są zgodne z MySQL. ([https://secure.php.net/manual/en/mysqli.installation.php Zobacz, jak skompilować PHP ze wsparciem dla MySQL])",
-       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] jest popularnym systemem baz danych, często stosowanym zamiast MySQL. ([https://secure.php.net/manual/pl/pgsql.installation.php Zobacz, jak skompilować PHP z obsługą PostgreSQL])",
+       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] jest popularnym, otawrtym systemem baz danych, często stosowanym jako alternatywa dla MySQL. ([https://secure.php.net/manual/en/pgsql.installation.php Zobacz, jak skompilować PHP z obsługą PostgreSQL])",
        "config-dbsupport-sqlite": "* [{{int:version-db-sqlite-url}} SQLite] jest niewielkim systemem bazy danych, z którym MediaWiki bardzo dobrze współpracuje. ([https://secure.php.net/manual/pl/pdo.installation.php Zobacz, jak skompilować PHP ze wsparciem dla SQLite], korzystając z PDO)",
        "config-dbsupport-oracle": "* [{{int:version-db-oracle-url}} Oracle] jest komercyjną profesjonalną bazą danych. ([https://secure.php.net/manual/pl/oci8.installation.php Jak skompilować PHP ze wsparciem dla OCI8])",
        "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] jest komercyjną profesjonalną bazą danych. ([https://secure.php.net/manual/pl/sqlsrv.installation.php Jak skompilować PHP ze wsparciem dla SQLSRV])",
        "config-nofile": "Nie udało się odnaleźć pliku \"$1\". Czy nie został usunięty?",
        "config-extension-link": "Czy wiesz, że twoja wiki obsługuje [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Extensions rozszerzenia]?\n\nMożesz przejrzeć [https://www.mediawiki.org/wiki/Category:Extensions_by_category rozszerzenia według kategorii] lub [https://www.mediawiki.org/wiki/Extension_Matrix Extension Matrix], aby zobaczyć pełną listę rozszerzeń.",
        "config-skins-screenshots": "$1 (zrzut ekranu: $2)",
+       "config-extensions-requires": "$1 (wymaga $2)",
        "config-screenshot": "zrzut ekranu",
        "mainpagetext": "<strong>Instalacja MediaWiki powiodła się.</strong>",
        "mainpagedocfooter": "Zapoznaj się z [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Contents Podręcznikiem użytkownika] zawierającym informacje o tym jak korzystać z oprogramowania wiki.\n\n== Na początek ==\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Configuration_settings Lista ustawień konfiguracyjnych]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ MediaWiki FAQ]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce Komunikaty o nowych wersjach MediaWiki (lista dyskusyjna)]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Localisation#Translation_resources Przetłumacz MediaWiki na swój język]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Combating_spam Dowiedz się, jak walczyć ze spamem na swojej wiki]"
index 03bcf64..3eeb672 100644 (file)
        "config-type-oracle": "Oracle",
        "config-type-mssql": "Microsoft SQL Server",
        "config-support-info": "O MediaWiki suporta os sistemas de banco de dados a seguir:\n\n$1\n\nSe você não vê o sistema de banco de dados que você está tentando usar listados abaixo, siga as instruções relacionadas acima, para ativar o suporte.",
-       "config-dbsupport-mysql": "* [{{int:version-db-mysql-url}} MySQL] é o principal alvo para o MediaWiki e é melhor suportado. O MediaWiki também funciona com [{{int:version-db-mariadb-url}} MariaDB] e [{{int:version-db-percona-url}} Percona Server], que são compatíveis com MySQL. ([Http://www.php.net/manual/en/mysqli.installation.php Como compilar PHP com suporte a MySQL])",
+       "config-dbsupport-mysql": "* O [{{int:version-db-mysql-url}} MySQL] é a base de dados preferida para o MediaWiki e a melhor suportada. O MediaWiki também trabalha com [{{int:version-db-mariadb-url}} MariaDB] e [{{int:version-db-percona-url}} Percona Server], que são compatíveis com MySQL. ([https://secure.php.net/manual/en/mysqli.installation.php Como compilar PHP com suporte para MySQL].)",
        "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] é um popular sistema de banco de dados de código aberto como uma alternativa para o MySQL. ([https://secure.php.net/manual/en/pgsql.installation.php Como compilar o PHP com suporte PostgreSQL])",
-       "config-dbsupport-sqlite": "* [{{int:version-db-sqlite-url}} SQLite] é um sistema de banco de dados leve que é muito bem suportado. ([http://www.php.net/manual/en/pdo.installation.php como compilar o PHP com suporte a SQLite], usa DOP)",
-       "config-dbsupport-oracle": "* [{{int:version-db-oracle-url}} Oracle] é um banco de dados comercial de empresas. ([http://www.php.net/manual/en/oci8.installation.php Como compilar o PHP com suporte OCI8])",
-       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] é uma banco de dados comercial do Windows para empresas. ([Config-dbsupport-oracle/manual/en/sqlsrv.installation.php Como compilar o PHP com suporte SQLSRV])",
+       "config-dbsupport-sqlite": "* O [{{int:version-db-sqlite-url}} SQLite] é uma plataforma de base de dados ligeira muito bem suportada. ([https://secure.php.net/manual/en/pdo.installation.php Como compilar PHP com suporte para SQLite], usa PDO.)",
+       "config-dbsupport-oracle": "* A [{{int:version-db-oracle-url}} Oracle] é uma base de dados comercial para empresas. ([https://secure.php.net/manual/en/oci8.installation.php Como compilar PHP com suporte para OCI8].)",
+       "config-dbsupport-mssql": "* O [{{int:version-db-mssql-url}} Microsoft SQL Server] é uma base de dados comercial do Windows para empresas. ([https://secure.php.net/manual/en/sqlsrv.installation.php Como compilar PHP com suporte para SQLSRV].)",
        "config-header-mysql": "Configurações MySQL",
        "config-header-postgres": "Configurações PostgreSQL",
        "config-header-sqlite": "Configurações SQLite",
index dcf39b0..26931f8 100644 (file)
        "config-type-oracle": "Oracle",
        "config-type-mssql": "Microsoft SQL Server",
        "config-support-info": "O MediaWiki suporta as seguintes plataformas de base de dados:\n\n$1\n\nSe a plataforma que pretende usar não está listada abaixo, siga as instruções nas hiperligações acima para ativar o suporte.",
-       "config-dbsupport-mysql": "* [{{int:version-db-mysql-url}} MySQL] é a plataforma primária do MediaWiki e é a melhor suportada. O MediaWiki também trabalha com [{{int:version-db-mariadb-url}} MariaDB] e [{{int:version-db-percona-url}} Percona Server], que são compatíveis com MySQL. ([https://secure.php.net/manual/en/mysql.installation.php Como compilar PHP com suporte a MySQL])",
-       "config-dbsupport-postgres": "* O [{{int:version-db-postgres-url}} PostgreSQL] é uma plataforma popular de base de dados de código aberto, alternativa ao MySQL. ([https://secure.php.net/manual/en/pgsql.installation.php Como compilar o PHP com suporte PostgreSQL])",
-       "config-dbsupport-sqlite": "* O [{{int:version-db-sqlite-url}} SQLite] é uma plataforma de base de dados ligeira muito bem suportada. ([http://www.php.net/manual/en/pdo.installation.php Como compilar o PHP com suporte SQLite], usa PDO)",
-       "config-dbsupport-oracle": "* [{{int:version-db-oracle-url}} Oracle] é uma base de dados comercial para empresas. ([http://www.php.net/manual/en/oci8.installation.php Como compilar o PHP com suporte OCI8])",
-       "config-dbsupport-mssql": "* O [{{int:version-db-mssql-url}} Microsoft SQL Server] é uma base de dados comercial do Windows para empresas. ([Config-dbsupport-oracle/manual/en/sqlsrv.installation.php Como compilar o PHP com suporte SQLSRV])",
+       "config-dbsupport-mysql": "* O [{{int:version-db-mysql-url}} MySQL] é a base de dados preferida para o MediaWiki e a melhor suportada. O MediaWiki também trabalha com [{{int:version-db-mariadb-url}} MariaDB] e [{{int:version-db-percona-url}} Percona Server], que são compatíveis com MySQL. ([https://secure.php.net/manual/en/mysqli.installation.php Como compilar PHP com suporte para MySQL].)",
+       "config-dbsupport-postgres": "* O [{{int:version-db-postgres-url}} PostgreSQL] é uma plataforma popular de base de dados de código aberto, alternativa ao MySQL. ([https://secure.php.net/manual/en/pgsql.installation.php Como compilar PHP com suporte para PostgreSQL].)",
+       "config-dbsupport-sqlite": "* O [{{int:version-db-sqlite-url}} SQLite] é uma plataforma de base de dados ligeira muito bem suportada. ([https://secure.php.net/manual/en/pdo.installation.php Como compilar PHP com suporte para SQLite], usa PDO.)",
+       "config-dbsupport-oracle": "* A [{{int:version-db-oracle-url}} Oracle] é uma base de dados comercial para empresas. ([https://secure.php.net/manual/en/oci8.installation.php Como compilar PHP com suporte para OCI8].)",
+       "config-dbsupport-mssql": "* O [{{int:version-db-mssql-url}} Microsoft SQL Server] é uma base de dados comercial do Windows para empresas. ([https://secure.php.net/manual/en/sqlsrv.installation.php Como compilar PHP com suporte para SQLSRV].)",
        "config-header-mysql": "Definições MySQL",
        "config-header-postgres": "Definições PostgreSQL",
        "config-header-sqlite": "Definições SQLite",
        "config-license-help": "Muitas wikis de acesso público licenciam todas as colaborações com uma [https://freedomdefined.org/Definition licença livre].\nIsto ajuda a criar um sentido de propriedade da comunidade e encoraja as colaborações a longo prazo.\nTal não é geralmente necessário nas wikis privadas ou corporativas.\n\nSe pretende que seja possível usar textos da Wikipédia na sua wiki e que seja possível a Wikipédia aceitar textos copiados da sua wiki, deve escolher a licença <strong>{{int:config-license-cc-by-sa}}</strong>..\n\nA licença anterior da Wikipédia era a licença GNU Free Documentation License.\nA GFDL é uma licença válida, mas de difícil compreensão.\nTambém é difícil reutilizar conteúdos licenciados com a GFDL.",
        "config-email-settings": "Definições do correio eletrónico",
        "config-enable-email": "Ativar mensagens eletrónicas de saída",
-       "config-enable-email-help": "Se quer que o correio eletrónico funcione, as [Config-dbsupport-oracle/manual/en/mail.configuration.php definições de correio eletrónico do PHP] têm de estar configuradas corretamente.\nSe não pretende viabilizar qualquer funcionalidade de correio eletrónico, pode desativá-lo aqui.",
+       "config-enable-email-help": "Se quer que o correio eletrónico funcione, as [https://secure.php.net/manual/en/mail.configuration.php definições de correio eletrónico do PHP] têm de estar configuradas corretamente.\nSe não pretende viabilizar qualquer funcionalidade de correio eletrónico, pode desativá-lo aqui.",
        "config-email-user": "Ativar mensagens eletrónicas entre utilizadores",
        "config-email-user-help": "Permitir que todos os utilizadores troquem entre si mensagens de correio eletrónico, se tiverem ativado esta funcionalidade nas suas preferências.",
        "config-email-usertalk": "Ativar notificações de alterações à página de discussão dos utilizadores",
index 89a72d4..d0e3dc8 100644 (file)
        "config-type-mssql": "Micræsaff SQL Server",
        "config-support-info": "MediaWiki supports the follaein database systems:\n\n$1\n\nGif ye dinna see the database system ye'r tryin tae uise listed ablow, than follae the instructions linked abuin tae enable support.",
        "config-dbsupport-mysql": "* [{{int:version-db-mysql-url}} MySQL] is the primarie tairget fer MediaWiki n is best supported. MediaWiki warks forby wi [{{int:version-db-mariadb-url}} MariaDB] n [{{int:version-db-percona-url}} Percona Server], thir ar MySQL compatible. ([https://secure.php.net/manual/en/mysqli.installation.php Hou tae compile PHP wi MySQL support])",
-       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] is ae popular apen soorce database system aes aen alternative til MySQL. Thaur micht be some wee bugs still hingin roond, n it's na recommendit fer uiss in ae production environment. ([Config-dbsupport-oracle/manual/en/pgsql.installation.php Hou tae compile PHP wi PostgreSQL support])",
+       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] is ae popular apen soorce database system aes aen alternative til MySQL. Thaur micht be some wee bugs still hingin roond, n it's na recommendit fer uiss in ae production environment. ([https://secure.php.net/manual/en/pgsql.installation.php Hou tae compile PHP wi PostgreSQL support])",
        "config-dbsupport-sqlite": "* [{{int:version-db-sqlite-url}} SQLite] is ae lichtweicht database system that is ver weel supportit. ([http://www.php.net/manual/en/pdo.installation.php Hou tae compile PHP wi SQLite support], uises PDO)",
        "config-dbsupport-oracle": "* [{{int:version-db-oracle-url}} Oracle] is ae commercial enterprise database. ([http://www.php.net/manual/en/oci8.installation.php Hou tae compile PHP wi OCI8 support])",
-       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] is ae commercial enterprise database fer Windows. ([Config-dbsupport-oracle/manual/en/sqlsrv.installation.php Hou tae compile PHP wi SQLSRV support])",
+       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] is ae commercial enterprise database fer Windows. ([https://secure.php.net/manual/en/sqlsrv.installation.php Hou tae compile PHP wi SQLSRV support])",
        "config-header-mysql": "MaSQL settins",
        "config-header-postgres": "PostgreSQL settins",
        "config-header-sqlite": "SQLite settins",
index bdd1ff8..4c3a32d 100644 (file)
        "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] คือระบบฐานข้อมูลแบบโอเพนซอร์สที่ได้รับความนิยมสูงที่สามารถใช้แทน MySQL ได้ ([https://secure.php.net/manual/en/pgsql.installation.php วิธีการคอมไพล์ PHP ด้วยการสนับสนุน PostgreSQL])",
        "config-dbsupport-sqlite": "* [{{int:version-db-sqlite-url}} SQLite] คือระบบฐานข้อมูลขนาดเล็กที่ได้รับการสนับสนุนดีมาก ([http://www.php.net/manual/en/pdo.installation.php วิธีการคอมไพล์ PHP ด้วยการสนับสนุน SQLite], ใช้ PDO)",
        "config-dbsupport-oracle": "* [{{int:version-db-oracle-url}} Oracle] คือฐานข้อมูลสำหรับองค์กรพาณิชย์ ([http://www.php.net/manual/en/oci8.installation.php วิธีการคอมไพล์ PHP ด้วยการสนับสนุน OCI8])",
-       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] คือฐานข้อมูลสำหรับองค์กรพาณิชย์สำหรับ Windows. ([Config-dbsupport-oracle/manual/en/sqlsrv.installation.php วิธีการคอมไพล์ PHP ด้วยการสนับสนุน SQLSRV])",
+       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] คือฐานข้อมูลสำหรับองค์กรพาณิชย์สำหรับ Windows. ([https://secure.php.net/manual/en/sqlsrv.installation.php วิธีการคอมไพล์ PHP ด้วยการสนับสนุน SQLSRV])",
        "config-header-mysql": "การตั้งค่า MySQL",
        "config-header-postgres": "การตั้งค่า PostgreSQL",
        "config-header-sqlite": "การตั้งค่า SQLite",
index 4caa2ff..9d890f7 100644 (file)
        "config-type-mssql": "Microsoft SQL Server",
        "config-support-info": "MediaWiki підтримує такі системи баз даних:\n\n$1\n\nЯкщо Ви не бачите серед перерахованих систему баз даних, яку використовуєте, виконайте вказівки, вказані вище, щоб увімкнути підтримку.",
        "config-dbsupport-mysql": "* [{{int:version-db-mysql-url}} MySQL] є основною для MediaWiki і найкраще підтримується.  MediaWiki також працює із [{{int:version-db-mariadb-url}} MariaDB] та [{{int:version-db-percona-url}} Percona Server], які сумісні з MySQL.  ([https://secure.php.net/manual/en/mysqli.installation.php як зібрати PHP з допомогою MySQL])",
-       "config-dbsupport-postgres": "*  [{{int:version-db-postgres-url}} PostgreSQL] — популярна відкрита СУБД, альтернатива MySQL. ([Config-dbsupport-oracle/manual/en/pgsql.installation.php як зібрати PHP з допомогою PostgreSQL]).",
+       "config-dbsupport-postgres": "*  [{{int:version-db-postgres-url}} PostgreSQL] — популярна відкрита СУБД, альтернатива MySQL. ([https://secure.php.net/manual/en/pgsql.installation.php як зібрати PHP з допомогою PostgreSQL]).",
        "config-dbsupport-sqlite": "*  [{{int:version-db-sqlite-url}} SQLite] — легка система баз даних, яка дуже добре підтримується. ([http://www.php.net/manual/en/pdo.installation.php Як зібрати PHP з допомогою SQLite], що використовує PDO)",
        "config-dbsupport-oracle": "*  [{{int:version-db-oracle-url}} Oracle] — комерційна база даних масштабу підприємства. ([http://www.php.net/manual/en/oci8.installation.php Як зібрати PHP з підтримкою OCI8])",
-       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] — це комерційна база даних для Windows масштабу підприємства. ([Config-dbsupport-oracle/manual/ru/sqlsrv.installation.php Як зібрати PHP з підтримкою SQLSRV])",
+       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] — це комерційна база даних для Windows масштабу підприємства. ([https://secure.php.net/manual/en/sqlsrv.installation.php Як зібрати PHP з підтримкою SQLSRV])",
        "config-header-mysql": "Налаштування MySQL",
        "config-header-postgres": "Налаштування PostgreSQL",
        "config-header-sqlite": "Налаштування SQLite",
index 29ce143..1c2861a 100644 (file)
        "config-type-mssql": "Microsoft SQL Server",
        "config-support-info": "MediaWiki hỗ trợ các hệ thống cơ sở dữ liệu sau đây:\n\n$1\n\nNếu bạn không thấy hệ thống cơ sở dữ liệu mà bạn đang muốn sử dụng được liệt kê dưới đây, thì hãy theo chỉ dẫn được liên kết ở trên để kích hoạt tính năng hỗ trợ.",
        "config-dbsupport-mysql": "* [{{int:version-db-mysql-url}} MySQL] là mục tiêu chính cho MediaWiki và được hỗ trợ tốt nhất. MediaWiki cũng làm việc với [{{int:version-db-mariadb-url}} MariaDB] và [{{int:version-db-percona-url}} Percona Server], là những cơ sở dữ liệu tương thích với MySQL. ([https://secure.php.net/manual/en/mysqli.installation.php Làm thế nào để biên dịch PHP với sự hỗ trợ của MySQL])",
-       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] là một hệ thống cơ sở dữ liệu mã nguồn mở phổ biến như là một thay thế cho MySQL. ([Config-dbsupport-oracle/manual/en/pgsql.installation.php Làm thế nào để biên dịch PHP với sự hỗ trợ của PostgreSQL])",
-       "config-dbsupport-sqlite": "* [{{int:version-db-sqlite-url}} SQLite] là một hệ thống cơ sở dữ liệu dung lượng nhẹ được hỗ trợ rất tốt. ([http://www.php.net/manual/en/pdo.installation.php Làm thế nào để biên dịch PHP với sự hỗ trợ của SQLite], sử dụng PDO)",
-       "config-dbsupport-oracle": "* [{{int:version-db-oracle-url}} Oracle] là một cơ sở dữ liệu doanh nghiệp thương mại. ([http://www.php.net/manual/en/oci8.installation.php Làm thế nào để biên dịch PHP với sự hỗ trợ của OCI8])",
-       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] là một cơ sở dữ liệu doanh nghiệp thương mại cho Windows. ([Config-dbsupport-oracle/manual/en/sqlsrv.installation.php Làm thế nào để biên dịch PHP với sự hỗ trợ của SQLSRV])",
+       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] là một hệ thống cơ sở dữ liệu mã nguồn mở phổ biến như là một thay thế cho MySQL. ([https://secure.php.net/manual/en/pgsql.installation.php Làm thế nào để biên dịch PHP với sự hỗ trợ của PostgreSQL])",
+       "config-dbsupport-sqlite": "* [{{int:version-db-sqlite-url}} SQLite] là một hệ thống cơ sở dữ liệu dung lượng nhẹ được hỗ trợ rất tốt. ([https://secure.php.net/manual/en/pdo.installation.php Làm thế nào để biên dịch PHP với sự hỗ trợ của SQLite], sử dụng PDO)",
+       "config-dbsupport-oracle": "* [{{int:version-db-oracle-url}} Oracle] là một cơ sở dữ liệu doanh nghiệp thương mại. ([https://secure.php.net/manual/en/oci8.installation.php Làm thế nào để biên dịch PHP với sự hỗ trợ của OCI8])",
+       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] là một cơ sở dữ liệu doanh nghiệp thương mại cho Windows. ([https://secure.php.net/manual/en/sqlsrv.installation.php Làm thế nào để biên dịch PHP với sự hỗ trợ của SQLSRV])",
        "config-header-mysql": "Thiết lập MySQL",
        "config-header-postgres": "Thiết lập PostgreSQL",
        "config-header-sqlite": "Thiết lập SQLite",
        "config-license-help": "Nhiều wiki công khai phát hành tất cả các đóng góp theo một [https://freedomdefined.org/Definition/Vi?uselang=vi giấy phép tự do].\nĐiều này giúp tạo nên thái độ cộng đồng sở hữu và ủng hộ sự đóng góp lâu dài.\nNói chung, một wiki riêng tư hoặc của công ty không nhất thiết phải sử dụng một giấy phép tự do.\n\nNếu bạn muốn được phép sử dụng văn bản từ Wikipedia và muốn Wikipedia nhận được những văn bản được sao chép từ wiki của bạn, bạn nên chọn <strong>{{int:config-license-cc-by-sa}}</strong>.\n\nWikipedia từng sử dụng Giấy phép Tài liệu Tự do GNU.\nGFDL là một giấy phép hợp lệ nhưng khó hiểu trên thực tế.\nNội dung được phát hành theo GFDL cũng khó tái sử dụng.",
        "config-email-settings": "Thiết lập thư điện tử",
        "config-enable-email": "Cho phép gửi thư điện tử đi",
-       "config-enable-email-help": "Nếu bạn muốn khả năng gửi thư điện tử, [Config-dbsupport-oracle/manual/en/mail.configuration.php thiết lập mail của PHP] cần phải được cấu hình đúng.\nNếu bạn không muốn sử dụng bất kỳ tính năng thư điện tử nào, bạn có thể vô hiệu chúng ở đây.",
+       "config-enable-email-help": "Nếu bạn muốn khả năng gửi thư điện tử, [https://secure.php.net/manual/en/mail.configuration.php thiết lập mail của PHP] cần phải được cấu hình đúng.\nNếu bạn không muốn sử dụng bất kỳ tính năng thư điện tử nào, bạn có thể vô hiệu chúng ở đây.",
        "config-email-user": "Cho phép người dùng gửi thư điện tử cho người dùng khác",
        "config-email-user-help": "Cho phép tất cả người dùng gửi thư điện tử cho nhau, nếu họ đã kích hoạt nó trong cài đặt tùy chọn của họ.",
        "config-email-usertalk": "Gửi thư thông báo về tin nhắn mới",
        "config-cache-options": "Thiết lập bộ nhớ đệm đối tượng:",
        "config-cache-help": "Lưu vào bộ nhớ đệm đối tượng được sử dụng để cải thiện tốc độ của MediaWiki bằng cách lưu vào bộ nhớ đệm những dữ liệu thường xuyên sử dụng.\nCác trang web từ trung bình cho đến các trang web lớn rất được khuyến khích kích hoạt tính năng này, và các trang web nhỏ cũng sẽ nhìn thấy lợi ích tương tự.",
        "config-cache-none": "Không lưu vào bộ nhớ đệm (không có chức năng nhiệm vụ sẽ được loại bỏ, nhưng tốc độ có thể bị ảnh hưởng trên các trang web wiki lớn hơn)",
-       "config-cache-accel": "Bộ nhớ đệm đối tượng PHP (APC, APCu, XCache, hoặc WinCache)",
+       "config-cache-accel": "Bộ nhớ đệm đối tượng PHP (APC, APCu, hoặc WinCache)",
        "config-cache-memcached": "Sử dụng Memcached (cần thiết lập và cấu hình thêm)",
        "config-memcached-servers": "Máy chủ Memcached:",
        "config-memcached-help": "Danh sách các địa chỉ IP để sử dụng cho Memcached .\nNên xác định trên một dòng và chỉ định các cổng được sử dụng. Ví dụ:\n 127.0.0.1:11211\n 192.168.1.25:1234",
        "config-install-mainpage-failed": "Không thể chèn trang đầu: $1",
        "config-install-done": "<strong>Xin chúc mừng!</strong>\nBạn đã cài đặt MediaWiki.\n\nBộ cài đặt đã tạo ra một tập tin <code>LocalSettings.php</code>.\nTập tin này chứa tất cả các cấu hình của bạn.\n\nBạn sẽ cần phải tải nó về và đặt nó trong thư mục cài đặt wiki của bạn (cùng thư mục với index.php). Việc tải về có lẽ sẽ được khởi động tự động.\n\nNếu bản tải về không được cung cấp, hoặc nếu bạn hủy bỏ nó, bạn có thể khởi động lại tải về bằng cách nhấn vào liên kết dưới đây:\n\n$3\n\n<strong>Lưu ý:</strong> Nếu bạn không làm điều này ngay bây giờ, điều này sẽ tạo ra tập tin cấu hình sẽ không có giá trị cho bạn sau này nếu bạn thoát khỏi trình cài đặt mà không tải nó về.\n\nKhi đã việc tải về đã hoàn thành, bạn có thể <strong>[$2 truy cập trang wiki của bạn]</strong>.",
        "config-install-done-path": "<strong>Xin chúc mừng!</strong>\nBạn đã cài đặt MediaWiki.\n\nBộ cài đặt đã tạo ra một tập tin <code>LocalSettings.php</code>.\nTập tin này chứa tất cả các cấu hình của bạn.\n\nBạn sẽ cần phải tải nó về và đặt nó tại <code>$4</code>. Việc tải về có lẽ sẽ được khởi động tự động.\n\nNếu bản tải về không được cung cấp, hoặc nếu bạn hủy bỏ nó, bạn có thể khởi động lại tải về bằng cách nhấn vào liên kết dưới đây:\n\n$3\n\n<strong>Lưu ý:</strong> Nếu bạn không làm điều này ngay bây giờ, điều này sẽ tạo ra tập tin cấu hình sẽ không có giá trị cho bạn sau này nếu bạn thoát khỏi trình cài đặt mà không tải nó về.\n\nKhi đã việc tải về đã hoàn thành, bạn có thể <strong>[$2 truy cập trang wiki của bạn]</strong>.",
+       "config-install-success": "MediaWiki đã được cài đặt thành công. Bây giờ bạn có thể mở <$1$2> để xem wiki của bạn.\nNếu bạn có thắc mắc, hãy đọc các câu thường hỏi:\n<https://www.mediawiki.org/wiki/Manual:FAQ?uselang=vi> hoặc ghé vào một diễn đàn hỗ trợ được liệt kê tại trang đó.",
        "config-download-localsettings": "Tải về <code>LocalSettings.php</code>",
        "config-help": "Trợ giúp",
        "config-help-tooltip": "nhấn chuột để mở rộng",
        "config-nofile": "Không tìm thấy tập tin “$1”. Nó có phải bị xóa không?",
        "config-extension-link": "Bạn có biết rằng wiki của bạn có hỗ trợ [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Extensions mở rộng]?\n\nBạn có thể truy cập [https://www.mediawiki.org/wiki/Special:MyLanguage/Category:Extensions_by_category phần mở rộng theo thể loại] hoặc [https://www.mediawiki.org/wiki/Extension_Matrix Ma trận Mở rộng] để xem danh sách đầy đủ các phần mở rộng.",
        "config-skins-screenshots": "$1 (ảnh chụp màn hình: $2)",
+       "config-extensions-requires": "$1 (cần $2)",
        "config-screenshot": "ảnh chụp màn hình",
        "mainpagetext": "'''MediaWiki đã được cài đặt.'''",
        "mainpagedocfooter": "Xin đọc [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Contents Hướng dẫn sử dụng] để biết thêm thông tin về cách sử dụng phần mềm wiki.\n\n== Để bắt đầu ==\n\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Configuration_settings Danh sách các thiết lập cấu hình]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ Các câu hỏi thường gặp MediaWiki]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce Danh sách gửi thư về việc phát hành MediaWiki]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Combating_spam Tìm hiểu cách chống spam tại wiki của bạn]"
index f85ef6e..c4892e7 100644 (file)
@@ -39,8 +39,8 @@
        "config-env-bad": "מ'האט קאנטראלירט די סביבה.\nאיר קענט נישט אינסטאלירן מעדיעוויקי.",
        "config-env-php": "PHP $1 איז אינצטאלירט.",
        "config-env-hhvm": "HHVM $1 איז אינסטאלירט.",
-       "config-apc": "[https://secure.php.net/apc APC] איז אינסטאלירט",
-       "config-wincache": "[https://www.iis.net/downloads/microsoft/wincache-extension WinCache] איז אינסטאלירט",
+       "config-apc": "[https://secure.php.net/apc APC] איז אינסטאַלירט",
+       "config-wincache": "[https://www.iis.net/downloads/microsoft/wincache-extension WinCache] איז אינסטאַלירט",
        "config-diff3-bad": "GNU diff3 נישט געטראפן.",
        "config-using-server": "באניצן סארווער־נאמען \"<nowiki>$1</nowiki>\".",
        "config-using-uri": "באניצן סארווער־אדרעס \"<nowiki>$1$2</nowiki>\".",
index 01eeba1..d75f45e 100644 (file)
        "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL]是一种流行的开源数据库系统,可作为MySQL的替代。([https://secure.php.net/manual/en/pgsql.installation.php 如何将对PostgreSQL的支持编译进PHP中])",
        "config-dbsupport-sqlite": "* [{{int:version-db-sqlite-url}} SQLite]是一种轻量级的数据库系统,能被良好地支持。([https://secure.php.net/manual/en/pdo.installation.php 如何将对SQLite的支持编译进PHP中],须使用PDO)",
        "config-dbsupport-oracle": "* [{{int:version-db-oracle-url}} Oracle]是一种商用企业级的数据库。([https://secure.php.net/manual/en/oci8.installation.php 如何将对OCI8的支持编译进PHP中])",
-       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server]是一个适用于Windows的商业性企业数据库。([Config-dbsupport-oracle/manual/en/sqlsrv.installation.php 如何编译带有SQLSRV支持的PHP])",
+       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server]是一个适用于Windows的商业性企业数据库。([https://secure.php.net/manual/en/sqlsrv.installation.php 如何编译带有SQLSRV支持的PHP])",
        "config-header-mysql": "MySQL设置",
        "config-header-postgres": "PostgreSQL设置",
        "config-header-sqlite": "SQLite设置",
index cebd383..7c3b00c 100644 (file)
        "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] 是一套受歡迎的開源資料庫系統,可用來替代 MySQL。([https://secure.php.net/manual/en/pgsql.installation.php 如何編譯支援 PostgreSQL 的 PHP])。",
        "config-dbsupport-sqlite": "* [{{int:version-db-sqlite-url}} SQLite] 是一套輕量級的資料庫系統,MediaWiki 可在此資料庫系統上良好的運作。([https://secure.php.net/manual/en/pdo.installation.php 如何編譯支援 SQLite 的 PHP],須透過 PDO)",
        "config-dbsupport-oracle": "* [{{int:version-db-oracle-url}} Oracle] 是一套商用企業級的資料庫。([https://secure.php.net/manual/en/oci8.installation.php 如何編譯支援 OCI8 的 PHP])",
-       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] 是一套 Windows 專用的商用企業級的資料庫。 ([Config-dbsupport-oracle/manual/en/sqlsrv.installation.php 如何編譯支援 SQLSRV 的 PHP])",
+       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] 是一套 Windows 專用的商用企業級的資料庫。 ([https://secure.php.net/manual/en/sqlsrv.installation.php 如何編譯支援 SQLSRV 的 PHP])",
        "config-header-mysql": "MySQL 設定",
        "config-header-postgres": "PostgreSQL 設定",
        "config-header-sqlite": "SQLite 設定",
index 9de16c4..dedf6ea 100644 (file)
@@ -33,7 +33,7 @@ class DBConnRef implements IDatabase {
                $this->lb = $lb;
                if ( $conn instanceof Database ) {
                        $this->conn = $conn; // live handle
-               } elseif ( count( $conn ) >= 4 && $conn[self::FLD_DOMAIN] !== false ) {
+               } elseif ( is_array( $conn ) && count( $conn ) >= 4 && $conn[self::FLD_DOMAIN] !== false ) {
                        $this->params = $conn;
                } else {
                        throw new InvalidArgumentException( "Missing lazy connection arguments." );
@@ -639,4 +639,8 @@ class DBConnRef implements IDatabase {
        }
 }
 
+/**
+ * @since 1.22
+ * @deprecated since 1.29
+ */
 class_alias( DBConnRef::class, 'DBConnRef' );
index efef121..1f92c47 100644 (file)
@@ -1169,27 +1169,21 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
 
                if ( $ret === false ) {
                        if ( $this->trxLevel ) {
-                               if ( !$this->wasKnownStatementRollbackError() ) {
-                                       # Either the query was aborted or all queries after BEGIN where aborted.
-                                       if ( $this->explicitTrxActive() || $priorWritesPending ) {
-                                               # In the first case, the only options going forward are (a) ROLLBACK, or
-                                               # (b) ROLLBACK TO SAVEPOINT (if one was set). If the later case, the only
-                                               # option is ROLLBACK, since the snapshots would have been released.
-                                               $this->trxStatus = self::STATUS_TRX_ERROR;
-                                               $this->trxStatusCause =
-                                                       $this->makeQueryException( $lastError, $lastErrno, $sql, $fname );
-                                               $tempIgnore = false; // cannot recover
-                                       } else {
-                                               # Nothing prior was there to lose from the transaction,
-                                               # so just roll it back.
-                                               $this->rollback( __METHOD__ . " ($fname)", self::FLUSHING_INTERNAL );
-                                       }
-                                       $this->trxStatusIgnoredCause = null;
-                               } else {
+                               if ( $this->wasKnownStatementRollbackError() ) {
                                        # We're ignoring an error that caused just the current query to be aborted.
-                                       # But log the cause so we can log a deprecation notice if a
-                                       # caller actually does ignore it.
+                                       # But log the cause so we can log a deprecation notice if a caller actually
+                                       # does ignore it.
                                        $this->trxStatusIgnoredCause = [ $lastError, $lastErrno, $fname ];
+                               } else {
+                                       # Either the query was aborted or all queries after BEGIN where aborted.
+                                       # In the first case, the only options going forward are (a) ROLLBACK, or
+                                       # (b) ROLLBACK TO SAVEPOINT (if one was set). If the later case, the only
+                                       # option is ROLLBACK, since the snapshots would have been released.
+                                       $this->trxStatus = self::STATUS_TRX_ERROR;
+                                       $this->trxStatusCause =
+                                               $this->makeQueryException( $lastError, $lastErrno, $sql, $fname );
+                                       $tempIgnore = false; // cannot recover
+                                       $this->trxStatusIgnoredCause = null;
                                }
                        }
 
@@ -4639,5 +4633,12 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
        }
 }
 
-class_alias( Database::class, 'DatabaseBase' ); // b/c for old name
-class_alias( Database::class, 'Database' ); // b/c global alias
+/**
+ * @deprecated since 1.28
+ */
+class_alias( Database::class, 'DatabaseBase' );
+
+/**
+ * @deprecated since 1.29
+ */
+class_alias( Database::class, 'Database' );
index 4c187f2..768e0c6 100644 (file)
@@ -1418,4 +1418,7 @@ class DatabaseMssql extends Database {
        }
 }
 
+/**
+ * @deprecated since 1.29
+ */
 class_alias( DatabaseMssql::class, 'DatabaseMssql' );
index 0472139..953f63d 100644 (file)
@@ -1580,4 +1580,7 @@ abstract class DatabaseMysqlBase extends Database {
        }
 }
 
+/**
+ * @deprecated since 1.29
+ */
 class_alias( DatabaseMysqlBase::class, 'DatabaseMysqlBase' );
index 0a5450c..31cdd7c 100644 (file)
@@ -341,4 +341,7 @@ class DatabaseMysqli extends DatabaseMysqlBase {
        }
 }
 
+/**
+ * @deprecated since 1.29
+ */
 class_alias( DatabaseMysqli::class, 'DatabaseMysqli' );
index 9610839..807d9cc 100644 (file)
@@ -1444,4 +1444,7 @@ SQL;
        }
 }
 
+/**
+ * @deprecated since 1.29
+ */
 class_alias( DatabasePostgres::class, 'DatabasePostgres' );
index a6a153a..5f37c1d 100644 (file)
@@ -1106,4 +1106,7 @@ class DatabaseSqlite extends Database {
        }
 }
 
+/**
+ * @deprecated since 1.29
+ */
 class_alias( DatabaseSqlite::class, 'DatabaseSqlite' );
index ca3fd52..2145129 100644 (file)
@@ -2117,4 +2117,7 @@ interface IDatabase {
        public function setIndexAliases( array $aliases );
 }
 
+/**
+ * @deprecated since 1.29
+ */
 class_alias( IDatabase::class, 'IDatabase' );
index 12e59b5..aeb5d8d 100644 (file)
@@ -62,4 +62,7 @@ class FakeResultWrapper extends ResultWrapper {
        }
 }
 
+/**
+ * @deprecated since 1.29
+ */
 class_alias( FakeResultWrapper::class, 'FakeResultWrapper' );
index df354af..1355e22 100644 (file)
@@ -119,4 +119,7 @@ class ResultWrapper implements IResultWrapper {
        }
 }
 
+/**
+ * @deprecated since 1.29
+ */
 class_alias( ResultWrapper::class, 'ResultWrapper' );
index 7bc3eac..6a28e35 100644 (file)
@@ -18,4 +18,7 @@ class Blob implements IBlob {
        }
 }
 
+/**
+ * @deprecated since 1.29
+ */
 class_alias( Blob::class, 'Blob' );
index 97e03b2..aa545cd 100644 (file)
@@ -31,4 +31,7 @@ class DBAccessError extends DBUnexpectedError {
        }
 }
 
+/**
+ * @deprecated since 1.29
+ */
 class_alias( DBAccessError::class, 'DBAccessError' );
index 91d98dc..4c5bc9a 100644 (file)
@@ -38,4 +38,7 @@ class DBConnectionError extends DBExpectedError {
        }
 }
 
+/**
+ * @deprecated since 1.29
+ */
 class_alias( DBConnectionError::class, 'DBConnectionError' );
index aad219d..1a5f4a3 100644 (file)
@@ -43,4 +43,7 @@ class DBError extends RuntimeException {
        }
 }
 
+/**
+ * @deprecated since 1.29
+ */
 class_alias( DBError::class, 'DBError' );
index 7e46420..73bc1f1 100644 (file)
@@ -55,4 +55,7 @@ class DBExpectedError extends DBError implements MessageSpecifier {
        }
 }
 
+/**
+ * @deprecated since 1.29
+ */
 class_alias( DBExpectedError::class, 'DBExpectedError' );
index e6870a7..0be08cd 100644 (file)
@@ -67,4 +67,7 @@ class DBQueryError extends DBExpectedError {
        }
 }
 
+/**
+ * @deprecated since 1.29
+ */
 class_alias( DBQueryError::class, 'DBQueryError' );
index 4393343..cdde1a7 100644 (file)
@@ -27,4 +27,7 @@ namespace Wikimedia\Rdbms;
 class DBReadOnlyError extends DBExpectedError {
 }
 
+/**
+ * @deprecated since 1.29
+ */
 class_alias( DBReadOnlyError::class, 'DBReadOnlyError' );
index 457431e..c5dd8ae 100644 (file)
@@ -28,4 +28,7 @@ namespace Wikimedia\Rdbms;
 class DBReplicationWaitError extends DBExpectedError {
 }
 
+/**
+ * @deprecated since 1.29
+ */
 class_alias( DBReplicationWaitError::class, 'DBReplicationWaitError' );
index 62a078c..34b4c91 100644 (file)
@@ -27,4 +27,7 @@ namespace Wikimedia\Rdbms;
 class DBTransactionError extends DBExpectedError {
 }
 
+/**
+ * @deprecated since 1.29
+ */
 class_alias( DBTransactionError::class, 'DBTransactionError' );
index d2622e1..b3f464b 100644 (file)
@@ -30,4 +30,7 @@ class DBTransactionSizeError extends DBTransactionError {
        }
 }
 
+/**
+ * @deprecated since 1.29
+ */
 class_alias( DBTransactionSizeError::class, 'DBTransactionSizeError' );
index 9c67eb5..2c506ca 100644 (file)
@@ -27,4 +27,7 @@ namespace Wikimedia\Rdbms;
 class DBUnexpectedError extends DBError {
 }
 
+/**
+ * @deprecated since 1.29
+ */
 class_alias( DBUnexpectedError::class, 'DBUnexpectedError' );
index 7918f36..48d5546 100644 (file)
@@ -32,4 +32,7 @@ interface Field {
        function isNullable();
 }
 
+/**
+ * @deprecated since 1.29
+ */
 class_alias( Field::class, 'Field' );
index 7f5990d..e8ec250 100644 (file)
@@ -713,4 +713,7 @@ abstract class LBFactory implements ILBFactory {
        }
 }
 
+/**
+ * @deprecated since 1.29
+ */
 class_alias( LBFactory::class, 'LBFactory' );
index 360be42..eabcbbd 100644 (file)
@@ -1952,4 +1952,7 @@ class LoadBalancer implements ILoadBalancer {
        }
 }
 
+/**
+ * @deprecated since 1.29
+ */
 class_alias( LoadBalancer::class, 'LoadBalancer' );
index be80cc5..d29258f 100644 (file)
@@ -77,4 +77,7 @@ class LoadBalancerSingle extends LoadBalancer {
        }
 }
 
+/**
+ * @deprecated since 1.29
+ */
 class_alias( LoadBalancerSingle::class, 'LoadBalancerSingle' );
index 4e39537..dfd9602 100644 (file)
@@ -3138,11 +3138,8 @@ class Parser {
                                for ( $i = 0; $i < $argsLength; $i++ ) {
                                        $funcArgs[] = $args->item( $i );
                                }
-                               try {
-                                       $result = $this->callParserFunction( $frame, $func, $funcArgs );
-                               } catch ( Exception $ex ) {
-                                       throw $ex;
-                               }
+
+                               $result = $this->callParserFunction( $frame, $func, $funcArgs );
 
                                // Extract any forwarded flags
                                if ( isset( $result['title'] ) ) {
@@ -3692,8 +3689,10 @@ class Parser {
         * @param Title $title
         * @param array $options Array of options to RepoGroup::findFile
         * @return File|bool
+        * @deprecated since 1.32, use fetchFileAndTitle instead
         */
        public function fetchFile( $title, $options = [] ) {
+               wfDeprecated( __METHOD__, '1.32' );
                return $this->fetchFileAndTitle( $title, $options )[0];
        }
 
index 755d108..62973d9 100644 (file)
@@ -45,7 +45,7 @@ use MWTimestamp;
 use OutputPage;
 use Parser;
 use ParserOptions;
-use PreferencesForm;
+use PreferencesFormLegacy;
 use Psr\Log\LoggerAwareTrait;
 use Psr\Log\NullLogger;
 use Skin;
@@ -1488,7 +1488,7 @@ class DefaultPreferencesFactory implements PreferencesFactory {
        public function getForm(
                User $user,
                IContextSource $context,
-               $formClass = PreferencesForm::class,
+               $formClass = PreferencesFormLegacy::class,
                array $remove = []
        ) {
                if ( SpecialPreferences::isOouiEnabled( $context ) ) {
@@ -1723,9 +1723,8 @@ class DefaultPreferencesFactory implements PreferencesFactory {
        protected function submitForm( array $formData, HTMLForm $form ) {
                $res = $this->saveFormData( $formData, $form );
 
-               if ( $res ) {
+               if ( $res === true ) {
                        $context = $form->getContext();
-
                        $urlOptions = [];
 
                        if ( $res === 'eauth' ) {
@@ -1749,7 +1748,7 @@ class DefaultPreferencesFactory implements PreferencesFactory {
                        $context->getOutput()->redirect( $url );
                }
 
-               return Status::newGood();
+               return ( $res === true ? Status::newGood() : $res );
        }
 
        /**
index 685f78c..478edce 100644 (file)
@@ -28,8 +28,8 @@ use User;
  * A PreferencesFactory is a MediaWiki service that provides the definitions of preferences for a
  * given user. These definitions are in the form of an HTMLForm descriptor.
  *
- * PreferencesForm (a subclass of HTMLForm) is used to generate the Preferences form, and handles
- * generic submission, CSRF protection, layout and other logic in a reusable manner.
+ * PreferencesFormLegacy (a subclass of HTMLForm) is used to generate the Preferences form, and
+ * handles generic submission, CSRF protection, layout and other logic in a reusable manner.
  *
  * In order to generate the form, the HTMLForm object needs an array structure detailing the
  * form fields available, and that's what this implementations of this interface provide. Each
@@ -62,7 +62,7 @@ interface PreferencesFactory {
        public function getForm(
                User $user,
                IContextSource $contextSource,
-               $formClass = \PreferencesForm::class,
+               $formClass = \PreferencesFormLegacy::class,
                array $remove = []
        );
 
index bb7207d..f3b6a70 100644 (file)
@@ -1704,12 +1704,14 @@ MESSAGE;
         * Returns LESS compiler set up for use with MediaWiki
         *
         * @since 1.27
-        * @param array $extraVars Associative array of extra (i.e., other than the
-        *   globally-configured ones) that should be used for compilation.
+        * @param array $vars Associative array of variables that should be used
+        *  for compilation. Since 1.32, this method no longer automatically includes
+        *  global LESS vars from ResourceLoader::getLessVars (T191937).
         * @throws MWException
         * @return Less_Parser
         */
-       public function getLessCompiler( $extraVars = [] ) {
+       public function getLessCompiler( $vars = [] ) {
+               global $IP;
                // When called from the installer, it is possible that a required PHP extension
                // is missing (at least for now; see T49564). If this is the case, throw an
                // exception (caught by the installer) to prevent a fatal error later on.
@@ -1718,10 +1720,10 @@ MESSAGE;
                }
 
                $parser = new Less_Parser;
-               $parser->ModifyVars( array_merge( $this->getLessVars(), $extraVars ) );
-               $parser->SetImportDirs(
-                       array_fill_keys( $this->config->get( 'ResourceLoaderLESSImportPaths' ), '' )
-               );
+               $parser->ModifyVars( $vars );
+               $parser->SetImportDirs( [
+                       "$IP/resources/src/mediawiki.less/" => '',
+               );
                $parser->SetOption( 'relativeUrls', false );
 
                return $parser;
index f2f3383..7f8c7f5 100644 (file)
@@ -959,9 +959,12 @@ class ResourceLoaderFileModule extends ResourceLoaderModule {
                        $cache = ObjectCache::getLocalServerInstance( CACHE_ANYTHING );
                }
 
-               // Construct a cache key from the LESS file name and a hash digest
+               $vars = array_merge(
+                       $context->getResourceLoader()->getLessVars(),
+                       $this->getLessVars( $context )
+               );
+               // Construct a cache key from the LESS file name, and a hash digest
                // of the LESS variables used for compilation.
-               $vars = $this->getLessVars( $context );
                ksort( $vars );
                $varsHash = hash( 'md4', serialize( $vars ) );
                $cacheKey = $cache->makeGlobalKey( 'LESS', $fileName, $varsHash );
index 17d00e0..c4e517a 100644 (file)
@@ -4,10 +4,21 @@
  * Subclass with context specific LESS variables
  */
 class ResourceLoaderLessVarFileModule extends ResourceLoaderFileModule {
-       protected $lessVariables = [
-               'collapsible-collapse',
-               'collapsible-expand',
-       ];
+       protected $lessVariables = [];
+
+       /**
+        * @inheritDoc
+        */
+       public function __construct(
+               $options = [],
+               $localBasePath = null,
+               $remoteBasePath = null
+       ) {
+               if ( isset( $options['lessMessages'] ) ) {
+                       $this->lessVariables = $options['lessMessages'];
+               }
+               parent::__construct( $options, $localBasePath, $remoteBasePath );
+       }
 
        /**
         * @inheritDoc
@@ -19,6 +30,7 @@ class ResourceLoaderLessVarFileModule extends ResourceLoaderFileModule {
 
        /**
         * Exclude a set of messages from a JSON string representation
+        *
         * @param string $blob
         * @param array $exclusions
         * @return array $blob
@@ -29,7 +41,7 @@ class ResourceLoaderLessVarFileModule extends ResourceLoaderFileModule {
                foreach ( $exclusions as $key ) {
                        unset( $data[$key] );
                }
-               return $data;
+               return (object)$data;
        }
 
        /**
@@ -45,6 +57,7 @@ class ResourceLoaderLessVarFileModule extends ResourceLoaderFileModule {
         * (ModifyVars) method so that the variable can be loaded and made available to stylesheets.
         * Note this does not take care of CSS escaping. That will be taken care of as part
         * of CSS Janus.
+        *
         * @param string $msg
         * @return string wrapped LESS variable definition
         */
@@ -53,14 +66,16 @@ class ResourceLoaderLessVarFileModule extends ResourceLoaderFileModule {
        }
 
        /**
-        * @param \ResourceLoaderContext $context
+        * Get language-specific LESS variables for this module.
+        *
+        * @param ResourceLoaderContext $context
         * @return array LESS variables
         */
-       protected function getLessVars( \ResourceLoaderContext $context ) {
+       protected function getLessVars( ResourceLoaderContext $context ) {
                $blob = parent::getMessageBlob( $context );
                $lessMessages = $this->excludeMessagesFromBlob( $blob, $this->messages );
 
-               $vars = [];
+               $vars = parent::getLessVars( $context );
                foreach ( $lessMessages as $msgKey => $value ) {
                        $vars['msg-' . $msgKey] = self::wrapAndEscapeMessage( $value );
                }
index 73beafc..2f87c47 100644 (file)
@@ -63,6 +63,10 @@ class SpecialCreateAccount extends LoginSignupSpecialPage {
                $user = $this->getUser();
                $status = AuthManager::singleton()->checkAccountCreatePermissions( $user );
                if ( !$status->isGood() ) {
+                       // track block with a cookie if it doesn't exists already
+                       if ( $user->isBlockedFromCreateAccount() ) {
+                               $user->trackBlockWithCookie();
+                       }
                        throw new ErrorPageError( 'createacct-error', $status->getMessage() );
                }
        }
index 415f973..0a3a679 100644 (file)
@@ -44,7 +44,8 @@ class SpecialPasswordPolicies extends SpecialPage {
                $out = $this->getOutput();
                $out->addModuleStyles( 'mediawiki.special' );
 
-               $this->addHelpLink( 'Help:Password policies' );
+               // TODO: Have specific user documentation page for this feature
+               $this->addHelpLink( 'Manual:$wgPasswordPolicy' );
 
                $out->addHTML(
                        Xml::openElement( 'table', [ 'class' => 'wikitable mw-passwordpolicies-table' ] ) .
index 27b6a07..0490cbb 100644 (file)
@@ -163,7 +163,7 @@ class SpecialPreferences extends SpecialPage {
         * Get the preferences form to use.
         * @param User $user The user.
         * @param IContextSource $context The context.
-        * @return PreferencesForm|HTMLForm
+        * @return PreferencesFormLegacy|HTMLForm
         */
        protected function getFormObject( $user, IContextSource $context ) {
                $preferencesFactory = MediaWikiServices::getInstance()->getPreferencesFactory();
@@ -184,9 +184,7 @@ class SpecialPreferences extends SpecialPage {
 
                $context = new DerivativeContext( $this->getContext() );
                $context->setTitle( $this->getPageTitle( 'reset' ) ); // Reset subpage
-               $htmlForm = HTMLForm::factory(
-                       $this->oouiEnabled ? 'ooui' : 'vform', [], $context, 'prefs-restore'
-               );
+               $htmlForm = HTMLForm::factory( 'ooui', [], $context, 'prefs-restore' );
 
                $htmlForm->setSubmitTextMsg( 'restoreprefs' );
                $htmlForm->setSubmitDestructive();
index 8193c5a..48bded4 100644 (file)
@@ -144,9 +144,10 @@ class PreferencesFormLegacy extends HTMLForm {
        }
 }
 
-// Retain the old class name for backwards compatibility.
-// In the future, this alias will be changed to point to PreferencesFormOOUI.
-class PreferencesForm extends PreferencesFormLegacy {
-}
-// Phan doesn't understand class_alias()?
-// class_alias( PreferencesFormLegacy::class, 'PreferencesForm' );
+/**
+ * Retain the old class name for backwards compatibility.
+ * In the future, this alias will be changed to point to PreferencesFormOOUI.
+ *
+ * @deprecated since 1.32
+ */
+class_alias( PreferencesFormLegacy::class, 'PreferencesForm' );
index 7189bea..b5fa97f 100644 (file)
@@ -1345,32 +1345,54 @@ class User implements IDBAccessObject, UserIdentity {
                $user = $session->getUser();
                if ( $user->isLoggedIn() ) {
                        $this->loadFromUserObject( $user );
-
-                       // If this user is autoblocked, set a cookie to track the Block. This has to be done on
-                       // every session load, because an autoblocked editor might not edit again from the same
-                       // IP address after being blocked.
-                       $config = RequestContext::getMain()->getConfig();
-                       if ( $config->get( 'CookieSetOnAutoblock' ) === true ) {
-                               $block = $this->getBlock();
-                               $shouldSetCookie = $this->getRequest()->getCookie( 'BlockID' ) === null
-                                       && $block
-                                       && $block->getType() === Block::TYPE_USER
-                                       && $block->isAutoblocking();
-                               if ( $shouldSetCookie ) {
-                                       wfDebug( __METHOD__ . ': User is autoblocked, setting cookie to track' );
-                                       $block->setCookie( $this->getRequest()->response() );
-                               }
+                       if ( $user->isBlocked() ) {
+                               // If this user is autoblocked, set a cookie to track the Block. This has to be done on
+                               // every session load, because an autoblocked editor might not edit again from the same
+                               // IP address after being blocked.
+                               $this->trackBlockWithCookie();
                        }
 
                        // Other code expects these to be set in the session, so set them.
                        $session->set( 'wsUserID', $this->getId() );
                        $session->set( 'wsUserName', $this->getName() );
                        $session->set( 'wsToken', $this->getToken() );
+
                        return true;
                }
+
                return false;
        }
 
+       /**
+        * Set the 'BlockID' cookie depending on block type and user authentication status.
+        */
+       public function trackBlockWithCookie() {
+               $block = $this->getBlock();
+               if ( $block && $this->getRequest()->getCookie( 'BlockID' ) === null ) {
+                       $config = RequestContext::getMain()->getConfig();
+                       $shouldSetCookie = false;
+
+                       if ( $this->isAnon() && $config->get( 'CookieSetOnIpBlock' ) ) {
+                               // If user is logged-out, set a cookie to track the Block
+                               $shouldSetCookie = in_array( $block->getType(), [
+                                       Block::TYPE_IP, Block::TYPE_RANGE
+                               ] );
+                               if ( $shouldSetCookie ) {
+                                       $block->setCookie( $this->getRequest()->response() );
+
+                                       // temporary measure the use of cookies on ip blocks
+                                       $stats = MediaWikiServices::getInstance()->getStatsdDataFactory();
+                                       $stats->increment( 'block.ipblock.setCookie.success' );
+                               }
+                       } elseif ( $this->isLoggedIn() && $config->get( 'CookieSetOnAutoblock' ) ) {
+                               $shouldSetCookie = $block->getType() === Block::TYPE_USER && $block->isAutoblocking();
+                               if ( $shouldSetCookie ) {
+                                       $block->setCookie( $this->getRequest()->response() );
+                               }
+                       }
+               }
+       }
+
        /**
         * Load user and user_group data from the database.
         * $this->mId must be set, this is how the user is identified.
@@ -1896,12 +1918,24 @@ class User implements IDBAccessObject, UserIdentity {
                        // An ID was found in the cookie.
                        $tmpBlock = Block::newFromID( $blockCookieId );
                        if ( $tmpBlock instanceof Block ) {
-                               // Check the validity of the block.
-                               $blockIsValid = $tmpBlock->getType() == Block::TYPE_USER
-                                       && !$tmpBlock->isExpired()
-                                       && $tmpBlock->isAutoblocking();
                                $config = RequestContext::getMain()->getConfig();
-                               $useBlockCookie = ( $config->get( 'CookieSetOnAutoblock' ) === true );
+
+                               switch ( $tmpBlock->getType() ) {
+                                       case Block::TYPE_USER:
+                                               $blockIsValid = !$tmpBlock->isExpired() && $tmpBlock->isAutoblocking();
+                                               $useBlockCookie = ( $config->get( 'CookieSetOnAutoblock' ) === true );
+                                               break;
+                                       case Block::TYPE_IP:
+                                       case Block::TYPE_RANGE:
+                                               // If block is type IP or IP range, load only if user is not logged in (T152462)
+                                               $blockIsValid = !$tmpBlock->isExpired() && !$this->isLoggedIn();
+                                               $useBlockCookie = ( $config->get( 'CookieSetOnIpBlock' ) === true );
+                                               break;
+                                       default:
+                                               $blockIsValid = false;
+                                               $useBlockCookie = false;
+                               }
+
                                if ( $blockIsValid && $useBlockCookie ) {
                                        // Use the block.
                                        return $tmpBlock;
index 98d2c0e..b437653 100644 (file)
@@ -389,7 +389,7 @@ class ClassCollector {
                        return;
                }
                // Note: When changing class name discovery logic,
-               // AutoLoaderTest.php may also need to be updated.
+               // AutoLoaderStructureTest.php may also need to be updated.
                switch ( $token[0] ) {
                        case T_NAMESPACE:
                        case T_CLASS:
index be0c037..1320a57 100644 (file)
@@ -2990,8 +2990,8 @@ class Language {
                global $wgAllUnicodeFixes;
                $s = UtfNormal\Validator::cleanUp( $s );
                if ( $wgAllUnicodeFixes ) {
-                       $s = $this->transformUsingPairFile( 'normalize-ar.ser', $s );
-                       $s = $this->transformUsingPairFile( 'normalize-ml.ser', $s );
+                       $s = $this->transformUsingPairFile( 'normalize-ar.php', $s );
+                       $s = $this->transformUsingPairFile( 'normalize-ml.php', $s );
                }
 
                return $s;
@@ -3011,12 +3011,10 @@ class Language {
         * @throws MWException
         * @return string
         */
-       function transformUsingPairFile( $file, $string ) {
+       protected function transformUsingPairFile( $file, $string ) {
                if ( !isset( $this->transformData[$file] ) ) {
-                       $data = wfGetPrecompiledData( $file );
-                       if ( $data === false ) {
-                               throw new MWException( __METHOD__ . ": The transformation file $file is missing" );
-                       }
+                       global $IP;
+                       $data = require "$IP/languages/data/{$file}";
                        $this->transformData[$file] = new ReplacementArray( $data );
                }
                return $this->transformData[$file]->replace( $string );
index 90e3751..efdf5a2 100644 (file)
@@ -44,7 +44,7 @@ class LanguageAr extends Language {
                global $wgFixArabicUnicode;
                $s = parent::normalize( $s );
                if ( $wgFixArabicUnicode ) {
-                       $s = $this->transformUsingPairFile( 'normalize-ar.ser', $s );
+                       $s = $this->transformUsingPairFile( 'normalize-ar.php', $s );
                }
                return $s;
        }
index df894a1..cf45762 100644 (file)
@@ -45,7 +45,7 @@ class LanguageMl extends Language {
                global $wgFixMalayalamUnicode;
                $s = parent::normalize( $s );
                if ( $wgFixMalayalamUnicode ) {
-                       $s = $this->transformUsingPairFile( 'normalize-ml.ser', $s );
+                       $s = $this->transformUsingPairFile( 'normalize-ml.php', $s );
                }
                return $s;
        }
diff --git a/languages/data/normalize-ar.php b/languages/data/normalize-ar.php
new file mode 100644 (file)
index 0000000..c1daf20
--- /dev/null
@@ -0,0 +1,735 @@
+<?php
+// File created by maintenance/generateNormalizerDataAr.php
+return [
+       'ﭐ' => 'ٱ',
+       'ﭑ' => 'ٱ',
+       'ﭒ' => 'ٻ',
+       'ﭓ' => 'ٻ',
+       'ﭔ' => 'ٻ',
+       'ﭕ' => 'ٻ',
+       'ﭖ' => 'پ',
+       'ﭗ' => 'پ',
+       'ﭘ' => 'پ',
+       'ﭙ' => 'پ',
+       'ﭚ' => 'ڀ',
+       'ﭛ' => 'ڀ',
+       'ﭜ' => 'ڀ',
+       'ﭝ' => 'ڀ',
+       'ﭞ' => 'ٺ',
+       'ﭟ' => 'ٺ',
+       'ﭠ' => 'ٺ',
+       'ﭡ' => 'ٺ',
+       'ﭢ' => 'ٿ',
+       'ﭣ' => 'ٿ',
+       'ﭤ' => 'ٿ',
+       'ﭥ' => 'ٿ',
+       'ﭦ' => 'ٹ',
+       'ﭧ' => 'ٹ',
+       'ﭨ' => 'ٹ',
+       'ﭩ' => 'ٹ',
+       'ﭪ' => 'ڤ',
+       'ﭫ' => 'ڤ',
+       'ﭬ' => 'ڤ',
+       'ﭭ' => 'ڤ',
+       'ﭮ' => 'ڦ',
+       'ﭯ' => 'ڦ',
+       'ﭰ' => 'ڦ',
+       'ﭱ' => 'ڦ',
+       'ﭲ' => 'ڄ',
+       'ﭳ' => 'ڄ',
+       'ﭴ' => 'ڄ',
+       'ﭵ' => 'ڄ',
+       'ﭶ' => 'ڃ',
+       'ﭷ' => 'ڃ',
+       'ﭸ' => 'ڃ',
+       'ﭹ' => 'ڃ',
+       'ﭺ' => 'چ',
+       'ﭻ' => 'چ',
+       'ﭼ' => 'چ',
+       'ﭽ' => 'چ',
+       'ﭾ' => 'ڇ',
+       'ﭿ' => 'ڇ',
+       'ﮀ' => 'ڇ',
+       'ﮁ' => 'ڇ',
+       'ﮂ' => 'ڍ',
+       'ﮃ' => 'ڍ',
+       'ﮄ' => 'ڌ',
+       'ﮅ' => 'ڌ',
+       'ﮆ' => 'ڎ',
+       'ﮇ' => 'ڎ',
+       'ﮈ' => 'ڈ',
+       'ﮉ' => 'ڈ',
+       'ﮊ' => 'ژ',
+       'ﮋ' => 'ژ',
+       'ﮌ' => 'ڑ',
+       'ﮍ' => 'ڑ',
+       'ﮎ' => 'ک',
+       'ﮏ' => 'ک',
+       'ﮐ' => 'ک',
+       'ﮑ' => 'ک',
+       'ﮒ' => 'گ',
+       'ﮓ' => 'گ',
+       'ﮔ' => 'گ',
+       'ﮕ' => 'گ',
+       'ﮖ' => 'ڳ',
+       'ﮗ' => 'ڳ',
+       'ﮘ' => 'ڳ',
+       'ﮙ' => 'ڳ',
+       'ﮚ' => 'ڱ',
+       'ﮛ' => 'ڱ',
+       'ﮜ' => 'ڱ',
+       'ﮝ' => 'ڱ',
+       'ﮞ' => 'ں',
+       'ﮟ' => 'ں',
+       'ﮠ' => 'ڻ',
+       'ﮡ' => 'ڻ',
+       'ﮢ' => 'ڻ',
+       'ﮣ' => 'ڻ',
+       'ﮤ' => 'ۀ',
+       'ﮥ' => 'ۀ',
+       'ﮦ' => 'ہ',
+       'ﮧ' => 'ہ',
+       'ﮨ' => 'ہ',
+       'ﮩ' => 'ہ',
+       'ﮪ' => 'ھ',
+       'ﮫ' => 'ھ',
+       'ﮬ' => 'ھ',
+       'ﮭ' => 'ھ',
+       'ﮮ' => 'ے',
+       'ﮯ' => 'ے',
+       'ﮰ' => 'ۓ',
+       'ﮱ' => 'ۓ',
+       'ﯓ' => 'ڭ',
+       'ﯔ' => 'ڭ',
+       'ﯕ' => 'ڭ',
+       'ﯖ' => 'ڭ',
+       'ﯗ' => 'ۇ',
+       'ﯘ' => 'ۇ',
+       'ﯙ' => 'ۆ',
+       'ﯚ' => 'ۆ',
+       'ﯛ' => 'ۈ',
+       'ﯜ' => 'ۈ',
+       'ﯝ' => 'ٷ',
+       'ﯞ' => 'ۋ',
+       'ﯟ' => 'ۋ',
+       'ﯠ' => 'ۅ',
+       'ﯡ' => 'ۅ',
+       'ﯢ' => 'ۉ',
+       'ﯣ' => 'ۉ',
+       'ﯤ' => 'ې',
+       'ﯥ' => 'ې',
+       'ﯦ' => 'ې',
+       'ﯧ' => 'ې',
+       'ﯨ' => 'ى',
+       'ﯩ' => 'ى',
+       'ﯪ' => 'ئا',
+       'ﯫ' => 'ئا',
+       'ﯬ' => 'ئە',
+       'ﯭ' => 'ئە',
+       'ﯮ' => 'ئو',
+       'ﯯ' => 'ئو',
+       'ﯰ' => 'ئۇ',
+       'ﯱ' => 'ئۇ',
+       'ﯲ' => 'ئۆ',
+       'ﯳ' => 'ئۆ',
+       'ﯴ' => 'ئۈ',
+       'ﯵ' => 'ئۈ',
+       'ﯶ' => 'ئې',
+       'ﯷ' => 'ئې',
+       'ﯸ' => 'ئې',
+       'ﯹ' => 'ئى',
+       'ﯺ' => 'ئى',
+       'ﯻ' => 'ئى',
+       'ﯼ' => 'ی',
+       'ﯽ' => 'ی',
+       'ﯾ' => 'ی',
+       'ﯿ' => 'ی',
+       'ﰀ' => 'ئج',
+       'ﰁ' => 'ئح',
+       'ﰂ' => 'ئم',
+       'ﰃ' => 'ئى',
+       'ﰄ' => 'ئي',
+       'ﰅ' => 'بج',
+       'ﰆ' => 'بح',
+       'ﰇ' => 'بخ',
+       'ﰈ' => 'بم',
+       'ﰉ' => 'بى',
+       'ﰊ' => 'بي',
+       'ﰋ' => 'تج',
+       'ﰌ' => 'تح',
+       'ﰍ' => 'تخ',
+       'ﰎ' => 'تم',
+       'ﰏ' => 'تى',
+       'ﰐ' => 'تي',
+       'ﰑ' => 'ثج',
+       'ﰒ' => 'ثم',
+       'ﰓ' => 'ثى',
+       'ﰔ' => 'ثي',
+       'ﰕ' => 'جح',
+       'ﰖ' => 'جم',
+       'ﰗ' => 'حج',
+       'ﰘ' => 'حم',
+       'ﰙ' => 'خج',
+       'ﰚ' => 'خح',
+       'ﰛ' => 'خم',
+       'ﰜ' => 'سج',
+       'ﰝ' => 'سح',
+       'ﰞ' => 'سخ',
+       'ﰟ' => 'سم',
+       'ﰠ' => 'صح',
+       'ﰡ' => 'صم',
+       'ﰢ' => 'ضج',
+       'ﰣ' => 'ضح',
+       'ﰤ' => 'ضخ',
+       'ﰥ' => 'ضم',
+       'ﰦ' => 'طح',
+       'ﰧ' => 'طم',
+       'ﰨ' => 'ظم',
+       'ﰩ' => 'عج',
+       'ﰪ' => 'عم',
+       'ﰫ' => 'غج',
+       'ﰬ' => 'غم',
+       'ﰭ' => 'فج',
+       'ﰮ' => 'فح',
+       'ﰯ' => 'فخ',
+       'ﰰ' => 'فم',
+       'ﰱ' => 'فى',
+       'ﰲ' => 'في',
+       'ﰳ' => 'قح',
+       'ﰴ' => 'قم',
+       'ﰵ' => 'قى',
+       'ﰶ' => 'قي',
+       'ﰷ' => 'كا',
+       'ﰸ' => 'كج',
+       'ﰹ' => 'كح',
+       'ﰺ' => 'كخ',
+       'ﰻ' => 'كل',
+       'ﰼ' => 'كم',
+       'ﰽ' => 'كى',
+       'ﰾ' => 'كي',
+       'ﰿ' => 'لج',
+       'ﱀ' => 'لح',
+       'ﱁ' => 'لخ',
+       'ﱂ' => 'لم',
+       'ﱃ' => 'لى',
+       'ﱄ' => 'لي',
+       'ﱅ' => 'مج',
+       'ﱆ' => 'مح',
+       'ﱇ' => 'مخ',
+       'ﱈ' => 'مم',
+       'ﱉ' => 'مى',
+       'ﱊ' => 'مي',
+       'ﱋ' => 'نج',
+       'ﱌ' => 'نح',
+       'ﱍ' => 'نخ',
+       'ﱎ' => 'نم',
+       'ﱏ' => 'نى',
+       'ﱐ' => 'ني',
+       'ﱑ' => 'هج',
+       'ﱒ' => 'هم',
+       'ﱓ' => 'هى',
+       'ﱔ' => 'هي',
+       'ﱕ' => 'يج',
+       'ﱖ' => 'يح',
+       'ﱗ' => 'يخ',
+       'ﱘ' => 'يم',
+       'ﱙ' => 'يى',
+       'ﱚ' => 'يي',
+       'ﱛ' => 'ذٰ',
+       'ﱜ' => 'رٰ',
+       'ﱝ' => 'ىٰ',
+       'ﱞ' => ' ٌّ',
+       'ﱟ' => ' ٍّ',
+       'ﱠ' => ' َّ',
+       'ﱡ' => ' ُّ',
+       'ﱢ' => ' ِّ',
+       'ﱣ' => ' ّٰ',
+       'ﱤ' => 'ئر',
+       'ﱥ' => 'ئز',
+       'ﱦ' => 'ئم',
+       'ﱧ' => 'ئن',
+       'ﱨ' => 'ئى',
+       'ﱩ' => 'ئي',
+       'ﱪ' => 'بر',
+       'ﱫ' => 'بز',
+       'ﱬ' => 'بم',
+       'ﱭ' => 'بن',
+       'ﱮ' => 'بى',
+       'ﱯ' => 'بي',
+       'ﱰ' => 'تر',
+       'ﱱ' => 'تز',
+       'ﱲ' => 'تم',
+       'ﱳ' => 'تن',
+       'ﱴ' => 'تى',
+       'ﱵ' => 'تي',
+       'ﱶ' => 'ثر',
+       'ﱷ' => 'ثز',
+       'ﱸ' => 'ثم',
+       'ﱹ' => 'ثن',
+       'ﱺ' => 'ثى',
+       'ﱻ' => 'ثي',
+       'ﱼ' => 'فى',
+       'ﱽ' => 'في',
+       'ﱾ' => 'قى',
+       'ﱿ' => 'قي',
+       'ﲀ' => 'كا',
+       'ﲁ' => 'كل',
+       'ﲂ' => 'كم',
+       'ﲃ' => 'كى',
+       'ﲄ' => 'كي',
+       'ﲅ' => 'لم',
+       'ﲆ' => 'لى',
+       'ﲇ' => 'لي',
+       'ﲈ' => 'ما',
+       'ﲉ' => 'مم',
+       'ﲊ' => 'نر',
+       'ﲋ' => 'نز',
+       'ﲌ' => 'نم',
+       'ﲍ' => 'نن',
+       'ﲎ' => 'نى',
+       'ﲏ' => 'ني',
+       'ﲐ' => 'ىٰ',
+       'ﲑ' => 'ير',
+       'ﲒ' => 'يز',
+       'ﲓ' => 'يم',
+       'ﲔ' => 'ين',
+       'ﲕ' => 'يى',
+       'ﲖ' => 'يي',
+       'ﲗ' => 'ئج',
+       'ﲘ' => 'ئح',
+       'ﲙ' => 'ئخ',
+       'ﲚ' => 'ئم',
+       'ﲛ' => 'ئه',
+       'ﲜ' => 'بج',
+       'ﲝ' => 'بح',
+       'ﲞ' => 'بخ',
+       'ﲟ' => 'بم',
+       'ﲠ' => 'به',
+       'ﲡ' => 'تج',
+       'ﲢ' => 'تح',
+       'ﲣ' => 'تخ',
+       'ﲤ' => 'تم',
+       'ﲥ' => 'ته',
+       'ﲦ' => 'ثم',
+       'ﲧ' => 'جح',
+       'ﲨ' => 'جم',
+       'ﲩ' => 'حج',
+       'ﲪ' => 'حم',
+       'ﲫ' => 'خج',
+       'ﲬ' => 'خم',
+       'ﲭ' => 'سج',
+       'ﲮ' => 'سح',
+       'ﲯ' => 'سخ',
+       'ﲰ' => 'سم',
+       'ﲱ' => 'صح',
+       'ﲲ' => 'صخ',
+       'ﲳ' => 'صم',
+       'ﲴ' => 'ضج',
+       'ﲵ' => 'ضح',
+       'ﲶ' => 'ضخ',
+       'ﲷ' => 'ضم',
+       'ﲸ' => 'طح',
+       'ﲹ' => 'ظم',
+       'ﲺ' => 'عج',
+       'ﲻ' => 'عم',
+       'ﲼ' => 'غج',
+       'ﲽ' => 'غم',
+       'ﲾ' => 'فج',
+       'ﲿ' => 'فح',
+       'ﳀ' => 'فخ',
+       'ﳁ' => 'فم',
+       'ﳂ' => 'قح',
+       'ﳃ' => 'قم',
+       'ﳄ' => 'كج',
+       'ﳅ' => 'كح',
+       'ﳆ' => 'كخ',
+       'ﳇ' => 'كل',
+       'ﳈ' => 'كم',
+       'ﳉ' => 'لج',
+       'ﳊ' => 'لح',
+       'ﳋ' => 'لخ',
+       'ﳌ' => 'لم',
+       'ﳍ' => 'له',
+       'ﳎ' => 'مج',
+       'ﳏ' => 'مح',
+       'ﳐ' => 'مخ',
+       'ﳑ' => 'مم',
+       'ﳒ' => 'نج',
+       'ﳓ' => 'نح',
+       'ﳔ' => 'نخ',
+       'ﳕ' => 'نم',
+       'ﳖ' => 'نه',
+       'ﳗ' => 'هج',
+       'ﳘ' => 'هم',
+       'ﳙ' => 'هٰ',
+       'ﳚ' => 'يج',
+       'ﳛ' => 'يح',
+       'ﳜ' => 'يخ',
+       'ﳝ' => 'يم',
+       'ﳞ' => 'يه',
+       'ﳟ' => 'ئم',
+       'ﳠ' => 'ئه',
+       'ﳡ' => 'بم',
+       'ﳢ' => 'به',
+       'ﳣ' => 'تم',
+       'ﳤ' => 'ته',
+       'ﳥ' => 'ثم',
+       'ﳦ' => 'ثه',
+       'ﳧ' => 'سم',
+       'ﳨ' => 'سه',
+       'ﳩ' => 'شم',
+       'ﳪ' => 'شه',
+       'ﳫ' => 'كل',
+       'ﳬ' => 'كم',
+       'ﳭ' => 'لم',
+       'ﳮ' => 'نم',
+       'ﳯ' => 'نه',
+       'ﳰ' => 'يم',
+       'ﳱ' => 'يه',
+       'ﳲ' => 'ـَّ',
+       'ﳳ' => 'ـُّ',
+       'ﳴ' => 'ـِّ',
+       'ﳵ' => 'طى',
+       'ﳶ' => 'طي',
+       'ﳷ' => 'عى',
+       'ﳸ' => 'عي',
+       'ﳹ' => 'غى',
+       'ﳺ' => 'غي',
+       'ﳻ' => 'سى',
+       'ﳼ' => 'سي',
+       'ﳽ' => 'شى',
+       'ﳾ' => 'شي',
+       'ﳿ' => 'حى',
+       'ﴀ' => 'حي',
+       'ﴁ' => 'جى',
+       'ﴂ' => 'جي',
+       'ﴃ' => 'خى',
+       'ﴄ' => 'خي',
+       'ﴅ' => 'صى',
+       'ﴆ' => 'صي',
+       'ﴇ' => 'ضى',
+       'ﴈ' => 'ضي',
+       'ﴉ' => 'شج',
+       'ﴊ' => 'شح',
+       'ﴋ' => 'شخ',
+       'ﴌ' => 'شم',
+       'ﴍ' => 'شر',
+       'ﴎ' => 'سر',
+       'ﴏ' => 'صر',
+       'ﴐ' => 'ضر',
+       'ﴑ' => 'طى',
+       'ﴒ' => 'طي',
+       'ﴓ' => 'عى',
+       'ﴔ' => 'عي',
+       'ﴕ' => 'غى',
+       'ﴖ' => 'غي',
+       'ﴗ' => 'سى',
+       'ﴘ' => 'سي',
+       'ﴙ' => 'شى',
+       'ﴚ' => 'شي',
+       'ﴛ' => 'حى',
+       'ﴜ' => 'حي',
+       'ﴝ' => 'جى',
+       'ﴞ' => 'جي',
+       'ﴟ' => 'خى',
+       'ﴠ' => 'خي',
+       'ﴡ' => 'صى',
+       'ﴢ' => 'صي',
+       'ﴣ' => 'ضى',
+       'ﴤ' => 'ضي',
+       'ﴥ' => 'شج',
+       'ﴦ' => 'شح',
+       'ﴧ' => 'شخ',
+       'ﴨ' => 'شم',
+       'ﴩ' => 'شر',
+       'ﴪ' => 'سر',
+       'ﴫ' => 'صر',
+       'ﴬ' => 'ضر',
+       'ﴭ' => 'شج',
+       'ﴮ' => 'شح',
+       'ﴯ' => 'شخ',
+       'ﴰ' => 'شم',
+       'ﴱ' => 'سه',
+       'ﴲ' => 'شه',
+       'ﴳ' => 'طم',
+       'ﴴ' => 'سج',
+       'ﴵ' => 'سح',
+       'ﴶ' => 'سخ',
+       'ﴷ' => 'شج',
+       'ﴸ' => 'شح',
+       'ﴹ' => 'شخ',
+       'ﴺ' => 'طم',
+       'ﴻ' => 'ظم',
+       'ﴼ' => 'اً',
+       'ﴽ' => 'اً',
+       'ﵐ' => 'تجم',
+       'ﵑ' => 'تحج',
+       'ﵒ' => 'تحج',
+       'ﵓ' => 'تحم',
+       'ﵔ' => 'تخم',
+       'ﵕ' => 'تمج',
+       'ﵖ' => 'تمح',
+       'ﵗ' => 'تمخ',
+       'ﵘ' => 'جمح',
+       'ﵙ' => 'جمح',
+       'ﵚ' => 'حمي',
+       'ﵛ' => 'حمى',
+       'ﵜ' => 'سحج',
+       'ﵝ' => 'سجح',
+       'ﵞ' => 'سجى',
+       'ﵟ' => 'سمح',
+       'ﵠ' => 'سمح',
+       'ﵡ' => 'سمج',
+       'ﵢ' => 'سمم',
+       'ﵣ' => 'سمم',
+       'ﵤ' => 'صحح',
+       'ﵥ' => 'صحح',
+       'ﵦ' => 'صمم',
+       'ﵧ' => 'شحم',
+       'ﵨ' => 'شحم',
+       'ﵩ' => 'شجي',
+       'ﵪ' => 'شمخ',
+       'ﵫ' => 'شمخ',
+       'ﵬ' => 'شمم',
+       'ﵭ' => 'شمم',
+       'ﵮ' => 'ضحى',
+       'ﵯ' => 'ضخم',
+       'ﵰ' => 'ضخم',
+       'ﵱ' => 'طمح',
+       'ﵲ' => 'طمح',
+       'ﵳ' => 'طمم',
+       'ﵴ' => 'طمي',
+       'ﵵ' => 'عجم',
+       'ﵶ' => 'عمم',
+       'ﵷ' => 'عمم',
+       'ﵸ' => 'عمى',
+       'ﵹ' => 'غمم',
+       'ﵺ' => 'غمي',
+       'ﵻ' => 'غمى',
+       'ﵼ' => 'فخم',
+       'ﵽ' => 'فخم',
+       'ﵾ' => 'قمح',
+       'ﵿ' => 'قمم',
+       'ﶀ' => 'لحم',
+       'ﶁ' => 'لحي',
+       'ﶂ' => 'لحى',
+       'ﶃ' => 'لجج',
+       'ﶄ' => 'لجج',
+       'ﶅ' => 'لخم',
+       'ﶆ' => 'لخم',
+       'ﶇ' => 'لمح',
+       'ﶈ' => 'لمح',
+       'ﶉ' => 'محج',
+       'ﶊ' => 'محم',
+       'ﶋ' => 'محي',
+       'ﶌ' => 'مجح',
+       'ﶍ' => 'مجم',
+       'ﶎ' => 'مخج',
+       'ﶏ' => 'مخم',
+       'ﶒ' => 'مجخ',
+       'ﶓ' => 'همج',
+       'ﶔ' => 'همم',
+       'ﶕ' => 'نحم',
+       'ﶖ' => 'نحى',
+       'ﶗ' => 'نجم',
+       'ﶘ' => 'نجم',
+       'ﶙ' => 'نجى',
+       'ﶚ' => 'نمي',
+       'ﶛ' => 'نمى',
+       'ﶜ' => 'يمم',
+       'ﶝ' => 'يمم',
+       'ﶞ' => 'بخي',
+       'ﶟ' => 'تجي',
+       'ﶠ' => 'تجى',
+       'ﶡ' => 'تخي',
+       'ﶢ' => 'تخى',
+       'ﶣ' => 'تمي',
+       'ﶤ' => 'تمى',
+       'ﶥ' => 'جمي',
+       'ﶦ' => 'جحى',
+       'ﶧ' => 'جمى',
+       'ﶨ' => 'سخى',
+       'ﶩ' => 'صحي',
+       'ﶪ' => 'شحي',
+       'ﶫ' => 'ضحي',
+       'ﶬ' => 'لجي',
+       'ﶭ' => 'لمي',
+       'ﶮ' => 'يحي',
+       'ﶯ' => 'يجي',
+       'ﶰ' => 'يمي',
+       'ﶱ' => 'ممي',
+       'ﶲ' => 'قمي',
+       'ﶳ' => 'نحي',
+       'ﶴ' => 'قمح',
+       'ﶵ' => 'لحم',
+       'ﶶ' => 'عمي',
+       'ﶷ' => 'كمي',
+       'ﶸ' => 'نجح',
+       'ﶹ' => 'مخي',
+       'ﶺ' => 'لجم',
+       'ﶻ' => 'كمم',
+       'ﶼ' => 'لجم',
+       'ﶽ' => 'نجح',
+       'ﶾ' => 'جحي',
+       'ﶿ' => 'حجي',
+       'ﷀ' => 'مجي',
+       'ﷁ' => 'فمي',
+       'ﷂ' => 'بحي',
+       'ﷃ' => 'كمم',
+       'ﷄ' => 'عجم',
+       'ﷅ' => 'صمم',
+       'ﷆ' => 'سخي',
+       'ﷇ' => 'نجي',
+       'ﷰ' => 'صلے',
+       'ﷱ' => 'قلے',
+       'ﷲ' => 'الله',
+       'ﷳ' => 'اكبر',
+       'ﷴ' => 'محمد',
+       'ﷵ' => 'صلعم',
+       'ﷶ' => 'رسول',
+       'ﷷ' => 'عليه',
+       'ﷸ' => 'وسلم',
+       'ﷹ' => 'صلى',
+       'ﷺ' => 'صلى الله عليه وسلم',
+       'ﷻ' => 'جل جلاله',
+       '﷼' => 'ریال',
+       'ﹰ' => ' ً',
+       'ﹱ' => 'ـً',
+       'ﹲ' => ' ٌ',
+       'ﹴ' => ' ٍ',
+       'ﹶ' => ' َ',
+       'ﹷ' => 'ـَ',
+       'ﹸ' => ' ُ',
+       'ﹹ' => 'ـُ',
+       'ﹺ' => ' ِ',
+       'ﹻ' => 'ـِ',
+       'ﹼ' => ' ّ',
+       'ﹽ' => 'ـّ',
+       'ﹾ' => ' ْ',
+       'ﹿ' => 'ـْ',
+       'ﺀ' => 'ء',
+       'ﺁ' => 'آ',
+       'ﺂ' => 'آ',
+       'ﺃ' => 'أ',
+       'ﺄ' => 'أ',
+       'ﺅ' => 'ؤ',
+       'ﺆ' => 'ؤ',
+       'ﺇ' => 'إ',
+       'ﺈ' => 'إ',
+       'ﺉ' => 'ئ',
+       'ﺊ' => 'ئ',
+       'ﺋ' => 'ئ',
+       'ﺌ' => 'ئ',
+       'ﺍ' => 'ا',
+       'ﺎ' => 'ا',
+       'ﺏ' => 'ب',
+       'ﺐ' => 'ب',
+       'ﺑ' => 'ب',
+       'ﺒ' => 'ب',
+       'ﺓ' => 'ة',
+       'ﺔ' => 'ة',
+       'ﺕ' => 'ت',
+       'ﺖ' => 'ت',
+       'ﺗ' => 'ت',
+       'ﺘ' => 'ت',
+       'ﺙ' => 'ث',
+       'ﺚ' => 'ث',
+       'ﺛ' => 'ث',
+       'ﺜ' => 'ث',
+       'ﺝ' => 'ج',
+       'ﺞ' => 'ج',
+       'ﺟ' => 'ج',
+       'ﺠ' => 'ج',
+       'ﺡ' => 'ح',
+       'ﺢ' => 'ح',
+       'ﺣ' => 'ح',
+       'ﺤ' => 'ح',
+       'ﺥ' => 'خ',
+       'ﺦ' => 'خ',
+       'ﺧ' => 'خ',
+       'ﺨ' => 'خ',
+       'ﺩ' => 'د',
+       'ﺪ' => 'د',
+       'ﺫ' => 'ذ',
+       'ﺬ' => 'ذ',
+       'ﺭ' => 'ر',
+       'ﺮ' => 'ر',
+       'ﺯ' => 'ز',
+       'ﺰ' => 'ز',
+       'ﺱ' => 'س',
+       'ﺲ' => 'س',
+       'ﺳ' => 'س',
+       'ﺴ' => 'س',
+       'ﺵ' => 'ش',
+       'ﺶ' => 'ش',
+       'ﺷ' => 'ش',
+       'ﺸ' => 'ش',
+       'ﺹ' => 'ص',
+       'ﺺ' => 'ص',
+       'ﺻ' => 'ص',
+       'ﺼ' => 'ص',
+       'ﺽ' => 'ض',
+       'ﺾ' => 'ض',
+       'ﺿ' => 'ض',
+       'ﻀ' => 'ض',
+       'ﻁ' => 'ط',
+       'ﻂ' => 'ط',
+       'ﻃ' => 'ط',
+       'ﻄ' => 'ط',
+       'ﻅ' => 'ظ',
+       'ﻆ' => 'ظ',
+       'ﻇ' => 'ظ',
+       'ﻈ' => 'ظ',
+       'ﻉ' => 'ع',
+       'ﻊ' => 'ع',
+       'ﻋ' => 'ع',
+       'ﻌ' => 'ع',
+       'ﻍ' => 'غ',
+       'ﻎ' => 'غ',
+       'ﻏ' => 'غ',
+       'ﻐ' => 'غ',
+       'ﻑ' => 'ف',
+       'ﻒ' => 'ف',
+       'ﻓ' => 'ف',
+       'ﻔ' => 'ف',
+       'ﻕ' => 'ق',
+       'ﻖ' => 'ق',
+       'ﻗ' => 'ق',
+       'ﻘ' => 'ق',
+       'ﻙ' => 'ك',
+       'ﻚ' => 'ك',
+       'ﻛ' => 'ك',
+       'ﻜ' => 'ك',
+       'ﻝ' => 'ل',
+       'ﻞ' => 'ل',
+       'ﻟ' => 'ل',
+       'ﻠ' => 'ل',
+       'ﻡ' => 'م',
+       'ﻢ' => 'م',
+       'ﻣ' => 'م',
+       'ﻤ' => 'م',
+       'ﻥ' => 'ن',
+       'ﻦ' => 'ن',
+       'ﻧ' => 'ن',
+       'ﻨ' => 'ن',
+       'ﻩ' => 'ه',
+       'ﻪ' => 'ه',
+       'ﻫ' => 'ه',
+       'ﻬ' => 'ه',
+       'ﻭ' => 'و',
+       'ﻮ' => 'و',
+       'ﻯ' => 'ى',
+       'ﻰ' => 'ى',
+       'ﻱ' => 'ي',
+       'ﻲ' => 'ي',
+       'ﻳ' => 'ي',
+       'ﻴ' => 'ي',
+       'ﻵ' => 'لآ',
+       'ﻶ' => 'لآ',
+       'ﻷ' => 'لأ',
+       'ﻸ' => 'لأ',
+       'ﻹ' => 'لإ',
+       'ﻺ' => 'لإ',
+       'ﻻ' => 'لا',
+       'ﻼ' => 'لا',
+];
diff --git a/languages/data/normalize-ml.php b/languages/data/normalize-ml.php
new file mode 100644 (file)
index 0000000..ca89a5a
--- /dev/null
@@ -0,0 +1,10 @@
+<?php
+// File created by maintenance/generateNormalizerDataMl.php
+return [
+       'ണ്‍' => 'ൺ',
+       'ന്‍' => 'ൻ',
+       'ര്‍' => 'ർ',
+       'ല്‍' => 'ൽ',
+       'ള്‍' => 'ൾ',
+       'ക്‍' => 'ൿ',
+];
index 52d4caf..4bbbe6f 100644 (file)
        "actionthrottled": "Buet geupeubataih",
        "actionthrottledtext": "Sibagoe saboh seunipat lawan-spam, droeneuh geupeubataih nibak neupeulaku buet nyoe le that gö lam watèë paneuk, ngön droeneuh ka leubèh nibak bataih.\nNeuci lom lam padum minèt.",
        "protectedpagetext": "Laman nyoe ka geupeulindông mangat bèk jeuet geuandam",
-       "viewsourcetext": "Droëneuh  jeuët neu’eu",
+       "viewsourcetext": "Droeneuh jeuet neueu ngön neusalén nè nibak mieng nyoe.",
        "viewyourtext": "Droëneuh meuidzin kalön ngön neucok nè andam droëneuh u laman nyoë",
        "protectedinterface": "Halaman nyoe na tèks muka keu muka keu peukakaih leumiëk ngön geupeulindông mangat bek jeuet jipeureuloh.\nKeu neuk tamah atawa ubah teujeumah keu ban dum wiki, neungui [https://translatewiki.net/ translatewiki.net], proyek lokalisasi MediaWiki.",
        "mycustomcssprotected": "Droëneuh hana hak neuandam halaman CSS nyoe.",
        "missingcommenttext": "Neupasoë beunalah di yup.",
        "summary-preview": "Eu neuringkaih neuandam:",
        "blockedtitle": "Ureueng ngui geutheun",
-       "blockedtext": "'''Nan ureuëng nguy atawa alamat IP Droëneuh  ka geutheun.'''\n\nGeutheun lé $1. Dalèh jih nakeuh ''$2''.\n\n* Geutheun yôh: $8\n* Neutheun maté tanggay bak: $6\n* Nyang geutheun: $7\n\nDroëneuh   jeuët neutanyong bak $1 atawa [[{{MediaWiki:Grouppage-sysop}}|nyang urôh nyang la’én]] keu peugah haba bhah nyoë.\n\nDroëneuh   h’an jeuët neunguy alat 'Kirém surat-e ureuëng nguy nyoë' keucuali ka neupasoë alamat surat-e nyang sah di [[Special:Preferences|Geunalak]] Droëneuh ngön Droëneuh ka geutheun keu nguy nyan.\n\nAlamat IP Droëneuh nakeuh $3, ngön ID neutheun nakeuh $5. Tulông peuseureuta salah saboh atawa ban duwa beurita nyoë bak tiëp teunanyöng nyang neupeugöt.",
+       "blockedtext": "<strong>Nan ureueng ngui atawa alamat IP Droeneuh ka geutheun.</strong>\n\nTeuneuheuen geupeugöt lé $1. \nAlasan nyang geubri nakeuh <em>$2</em>.\n\n* Phôn mula geutheun: $8\n* Maté tanggai teuneuheun: $6\n* Ureueng nyang geutheun: $7\n\nDroeneuh jeuet neutanyöng bak $1 atawa [[{{MediaWiki:Grouppage-sysop}}|ureueng urôih]] nyang la’én bhaih teuneuheun nyoe.\nDroeneuh h`an jeuet neungui alat \"{{int:emailuser}}\" keucuali meunyo alamat surat-e nyang sah na neupasoe bak [[Special:Preferences|Neuatô akun]] ngön Droeneuh hana geutheun keu neungui atra nyan.\nAlamat IP Droeneuh jinoe nakeuh $3, ngön ID teuneuheun nakeuh $5.\nNeutulông pasoe ban dum keutrangan di ateueh lam tiep teunanyöng nyang neupeugöt.",
        "autoblockedtext": "'''Nan ureuëng nguy atawa alamat IP Droëneuh  ka geutheun.'''\n\nGeutheun lé $1. Dalèh jih nakeuh ''$2''.\n\n* Geutheun yôh: $8\n* Neutheun maté tanggay bak: $6\n* Nyang geutheun: $7\n\nDroëneuh   jeuët neutanyong bak $1 atawa [[{{MediaWiki:Grouppage-sysop}}|nyang urôh nyang la’én]] keu peugah haba bhah nyoë.\n\nDroëneuh   h’an jeuët neunguy alat 'Kirém surat-e ureuëng nguy nyoë' keucuali ka neupasoë alamat surat-e nyang sah di [[Special:Preferences|Geunalak]] Droëneuh ngön Droëneuh ka geutheun keu nguy nyan.\n\nAlamat IP Droëneuh nakeuh $3, ngön ID neutheun nakeuh $5. Tulông peuseureuta salah saboh atawa ban duwa beurita nyoë bak tiëp teunanyöng nyang neupeugöt.",
        "blockednoreason": "hana dalèh nyang geubri",
        "whitelistedittext": "Droeneuh suwah $1 keu neuandam ôn.",
        "search-result-category-size": "{{PLURAL:$1|1 anggeeta|$1 anggeeta}} ({{PLURAL:$2|1 aneuk kawan|$2 aneuk kawan}}, {{PLURAL:$3|1 beureukaih|$3 beureukaih}})",
        "search-redirect": "(geupupinah nibak $1)",
        "search-section": "(bideuëng $1)",
+       "search-file-match": "(reumbang ngön asoe beureukaih)",
        "search-suggest": "Kadang meukeusud Droëneuh nakeuh: $1",
        "search-interwiki-caption": "Buët la’én",
        "search-interwiki-default": "Hasé nibak $1:",
        "recentchanges-label-plusminus": "Seunipat miëng geugantoë lé jeumeulah bita nyoë",
        "recentchanges-legend-heading": "<strong>Hareutoë:</strong>",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (eu cit [[Special:NewPages|dapeuta laman barô]])",
-       "rcnotefrom": "Di yup nyoë nakeuh neuubah yôh <strong>$2</strong> (geupeudeuh trôh ‘an <strong>$1</strong> neuubah).",
+       "rcnotefrom": "Di yup nyoe nakeuh {{PLURAL:$5|neuubah}} yôh <strong>$3, $4</strong> (trôk 'an <strong>$1</strong> geupeudeuih).",
        "rclistfrom": "Peudeuih neuubah barô yôh $3 $2 kön",
        "rcshowhideminor": "$1 andam bacut",
        "rcshowhideminor-show": "Peuleumah",
        "rcshowhidebots-show": "Peuleumah",
        "rcshowhidebots-hide": "Peusom",
        "rcshowhideliu": "$1 ureuëng ngui tamöng",
+       "rcshowhideliu-show": "Peudeuih",
        "rcshowhideliu-hide": "Peusom",
        "rcshowhideanons": "$1 ureuëng ngui hana nan",
        "rcshowhideanons-show": "Peuleumah",
        "recentchangeslinked-feed": "Neuubah meuhubông",
        "recentchangeslinked-toolbox": "Neuubah teukaw'èt",
        "recentchangeslinked-title": "Neuubah nyang meukaw'èt ngön $1",
-       "recentchangeslinked-summary": "Neupasoe saboh nan mieng keu neueu neuubah bak mieng nyang mupawôt u atawa nibak mieng nyan. (Keu neueu anggèeta nibak saboh kawan, neupasoe Kawan:Nan kawan). Neuubah bak mieng bak [[Special:Watchlist|dapeuta keunalön]] teutuléh <strong>teubai</strong>.",
+       "recentchangeslinked-summary": "Neupasoe saboh nan mieng keu neueu neuubah bak mieng nyang mupawôt u atawa nibak mieng nyan. (Keu neueu anggèeta nibak saboh kawan, neupasoe {{ns:category}}:Nan kawan). Neuubah bak mieng nyang na bak [[Special:Watchlist|dapeuta keunalön]] teutuléh <strong>teubai</strong>.",
        "recentchangeslinked-page": "Nan miëng:",
        "recentchangeslinked-to": "Peuleumah neuubah nibak laman-laman nyang mupawôt ngön laman nyang geubri",
        "upload": "Peutamöng beureukaih",
        "sp-contributions-search": "Mita soë nyang tuléh",
        "sp-contributions-username": "Alamat IP atawa nan ureuëng ngui:",
        "sp-contributions-toponly": "Peuleumah geunantoe nyang baro mantong",
+       "sp-contributions-newonly": "Peudeuih pumeugöt mieng mantöng",
        "sp-contributions-submit": "Mita",
        "whatlinkshere": "Peunawôt balék",
        "whatlinkshere-title": "Laman nyang mupawôt u $1",
        "tooltip-summary": "Pasoë éhtisa paneuk",
        "interlanguage-link-title": "$1 – $2",
        "simpleantispam-label": "Paréksa anti-spam.\n<strong>BÈK</strong> neupasoë!",
+       "pageinfo-title": "Keutrangan keu \"$1\"",
+       "pageinfo-watchers": "Jumeulah ureueng kalön mieng",
        "pageinfo-toolboxlink": "Keutrangan miëng",
        "previousdiff": "← Bida awai",
        "nextdiff": "Geunantoë lheuëh nyan →",
        "file-info-size": "$1 × $2 piksel, rayek beureukaih: $3, MIME jeunèh: $4",
+       "file-info-size-pages": "$1 × $2 piksel, seunipat beureukaih: $3, jeunèh MIME: $4, $5 {{PLURAL:$5|mieng}}",
        "file-nohires": "Hana resolusi nyang leubèh manyang.",
        "svg-long-desc": "Beureukah SVG, nominal $1 x $2 piksel, rayek beureukah: $3",
        "show-big-image": "Beureukaih aseuli",
        "confirm-unwatch-button": "Ka göt",
        "confirm-unwatch-top": "Sampôh laman nyoë nibak dapeuta keunalön droëneuh?",
        "imgmultipageprev": "← laman sigohlomjih",
+       "imgmultigo": "Jak!",
+       "imgmultigoto": "Jak u mieng $1",
        "autosumm-new": "Geupeugöt laman ngön asoë '$1'",
        "watchlisttools-view": "Peudeuh neuubah meukaw'èt",
        "watchlisttools-edit": "Peudeuh ngön andam dapeuta keunalön",
        "tag-list-wrapper": "([[Special:Tags|{{PLURAL:$1|Tag}}]]: $2)",
        "logentry-delete-delete": "$1 {{GENDER:$2|geusampôh}} miëng $3",
        "logentry-move-move": "$1 {{GENDER:$2|geupinah}} mieng $3 u $4",
+       "logentry-move-move-noredirect": "$1 {{GENDER:$2|geupinah}} mieng $3 u $4 hana geubôh peuninah",
        "logentry-newusers-create": "$1 {{GENDER:$2|geupeugöt}} akun ureuëng ngui",
        "logentry-upload-upload": "$1 {{GENDER:$2|geupasoe}} $3",
        "searchsuggest-search": "Mita {{SITENAME}}",
index 0ba8531..f7772e1 100644 (file)
        "copyrightwarning2": "অনুগ্ৰহ কৰি মন কৰক যে {{SITENAME}}লৈ কৰা সকলো বৰঙণি আন সদস্যই সম্পাদনা কৰিব, সলনি কৰিব অথবা মচি পেলাব পাৰে ।\nআপুনি যদি আপোনাৰ লিখনি নিৰ্দয়ভাৱে সম্পাদনা কৰা ভাল নাপায়, তেনেহলে নিজৰ লিখনি ইয়াত নিদিব ।<br />\nইয়াত আপোনাৰ লিখনি দিয়াৰ লগে লগে আপুনি আপোনা-আপুনি প্ৰতিশ্ৰুতি দিছে যে এই লিখনিটো আপোনাৰ মৌলিক লিখনি, বা কোনো স্বত্বাধিকাৰ নথকা বা কোনো ৰাজহুৱা ৱেবছাইট বা তেনে কোনো মুকলি উৎসৰ পৰা আহৰণ কৰা । (অধিক জানিবলৈ $1 চাওক)\n\n'''স্বত্বাধিকাৰযুক্ত কোনো সমল অনুমতি অবিহনে দাখিল নকৰে যেন!'''",
        "longpageerror": "'''ভুল: আপুনি জমা দিয়া পাঠ {{PLURAL:$1|এক কিলো-বাইট|$1 কিলো-বাইট}} আকাৰৰ, যি {{PLURAL:$2|এক কিলো-বাইট|$2 কিলো-বাইট}} সীমাতকৈ বেছি।'''\nইয়াক সাঁচিব পৰা নাযাব।",
        "readonlywarning": "'''সতৰ্কবাণী: চোৱা-চিতাৰ হেতু এই তথ্যকোষ বন্ধ কৰি ৰখা হৈছে, গতিকে আপুনি এই মূহুৰ্তত আপোনাৰ সম্পাদনা সাঁচিব নোৱাৰিব।'''\nআপুনি লেখাটো টেক্সট-ফাইলত কপী-পে'ষ্ট কৰি পিছলৈ ব্যৱহাৰৰ বাবে সাঁচি ৰাখিব পাৰে।\n\nতথ্যকোষ বন্ধ কৰি ৰখা প্ৰশাসকজনে এই ব্যাখ্যা দিছে: $1",
-       "protectedpagewarning": "'''সতৰ্কবাণী: এই পৃষ্ঠা বন্ধ ৰখা হৈছে; কেৱল প্ৰশাসকৰৰ মৰ্যদাৰ সদস্যইহে সম্পাদনা কৰিব পাৰিব ।'''\nআপোনাৰ সুবিধাৰ বাবে পৃষ্ঠাৰ সাম্প্ৰতিক ল'গ সংৰক্ষণ তলত দিয়া হ'ল ।",
+       "protectedpagewarning": "<strong>সতৰ্কবাণী: এই পৃষ্ঠা সুৰক্ষিত কৰা হৈছে; কেৱল প্ৰশাসনিক মৰ্যাদাৰ সদস্যইহে ইয়াক সম্পাদনা কৰিব পাৰিব।</strong>\nআপোনাৰ সুবিধাৰ বাবে পৃষ্ঠাৰ সাম্প্ৰতিক ল'গ অন্তৰ্ভুক্তি তলত দিয়া হ'ল ।",
        "semiprotectedpagewarning": "টোকা: এই পৃষ্ঠা বন্ধ ৰখা হৈছে; কেৱল পঞ্জীভূত সদস্যই হে সম্পাদনা কৰিব পাৰিব ।\nআপোনাৰ সুবিধাৰ বাবে পৃষ্ঠাৰ সাম্প্ৰতিক ল'গ সংৰক্ষণ তলত দিয়া হ'ল ।",
        "cascadeprotectedwarning": "<strong>সতৰ্কবাণী:</strong> এই পৃষ্ঠাটো সুৰক্ষিত কৰি ৰখা হৈছে যাতে কেৱল প্ৰশাসনিক ক্ষমতা থকা সদস্যই ইয়াক সম্পাদনা কৰিব পাৰে, কাৰণ ই প্ৰপাতাকাৰ-সুৰক্ষিত  {{PLURAL:$1|পৃষ্ঠাটোৰ|পৃষ্ঠাবোৰৰ}} অন্তৰ্ভুক্ত:",
        "titleprotectedwarning": "'''সতৰ্কবাণী: এই পৃষ্ঠাটো সুৰক্ষিত কৰা হৈছে যাতে কেৱল [[Special:ListGroupRights|specific rights]] সদস্যই ইয়াক তৈয়াৰ কৰিব পাৰে ।'''\nআপোনাৰ সুবিধাৰ্থে অভিলেখৰ শেহতীয়া ভৰ্তি তলত দিয়া হ’ল।",
        "undo-failure": "এই সম্পাদনা মধ্যৱৰ্তী সম্পাদনাসমূহৰ দ্বন্দৰ কাৰণে পূৰ্ববৎ কৰা নহ'ব ।",
        "undo-norev": "এই সম্পাদনাটো ৰদ কৰিব নোৱাৰি, কাৰণ এইটো আৰু নাই বা ইয়াক বিলোপ কৰা হ'ল।",
        "undo-nochange": "সম্পাদনাটো ইতিমধ্যেই বাতিল কৰা হৈছে।",
-       "undo-summary": "[[Special:Contributions/$2|$2]] ([[User talk:$2|আলোচনা]]) সম্পাদিত $1 সংশোধনটি বাতিল কৰক",
+       "undo-summary": "[[Special:Contributions/$2|$2]] ([[User talk:$2|আলোচনা]])-ই কৰা $1 নম্বৰ সম্পাদনাটো বাতিল কৰা হৈছে",
        "undo-summary-username-hidden": "এজন গোপন ব্যৱহাৰকাৰীয়ে কৰা $1 সংশোধন বাতিল কৰক",
        "cantcreateaccount-text": "আই পি ঠিকনা ('''$1''')ৰ পৰা একাউণ্ট সৃষ্টিত [[User:$3|$3]]’য়ে বাধা প্ৰদান কৰিছে ।\n\n$3 য়ে আগবঢ়োৱা ইয়াৰ কাৰণ হৈছে ''$2''",
        "cantcreateaccount-range-text": "[[User:$3|$3]]য়ে <strong>$1</strong> পৰিসীমাৰ আই পি ঠিকনাৰ পৰা একাউণ্ট সৃষ্টি বাৰণ কৰিছে যাৰ ভিতৰত আপোনাৰ আই ই ঠিকনাও (<strong>$4</strong>) আছে।\n\n $3য়ে <em>$2</em> বুলি কাৰণ দৰ্শাইছে",
        "rcfilters-legend-heading": "<strong>সংক্ষিপ্ত ৰূপৰ তালিকা:</strong>",
        "rcfilters-other-review-tools": "আন পুনৰীক্ষণ সঁজুলি",
        "rcfilters-quickfilters": "সঞ্চিত পৰিস্ৰাৱক",
+       "rcfilters-quickfilters-placeholder-title": "এতিয়ালৈকে কোনো ছেকনী সাঁচি থোৱা নাই",
+       "rcfilters-quickfilters-placeholder-description": "আপোনাৰ ছেকনীৰ ছেটিংছ সাঁচি থ'বলৈ আৰু পাছত সেয়া ব্যৱহাৰ কৰিবলৈ তলত থকা সক্ৰিয় পৰিস্ৰাৱক ক্ষেত্ৰৰ বুক্‌মাৰ্ক চিহ্নটো ক্লিক কৰক।",
        "rcfilters-savedqueries-defaultlabel": "সঞ্চিত পৰিস্ৰাৱক",
+       "rcfilters-show-new-changes": "নতুন সালসলনিবোৰ চাওক",
        "rcfilters-search-placeholder": "পৰিৱৰ্তনসমূহ ছেকক (ছেকনীৰ নামৰ বাবে মেন্যু বা সন্ধান ব্যৱহাৰ কৰক)",
        "rcfilters-highlightbutton-title": "ফলাফলসমূহ উজ্জ্বল কৰক",
        "rcfilters-filter-editsbyself-label": "আপুনি কৰা সালসলনিসমূহ",
index 0916b94..2e353e6 100644 (file)
        "passwordpolicies-group": "Група",
        "passwordpolicies-policies": "Палітыкі",
        "passwordpolicies-policy-minimalpasswordlength": "Пароль мусіць мець даўжыню найменей $1 {{PLURAL:$1|сымбаль|сымбалі|сымбаляў}}",
-       "passwordpolicies-policy-minimumpasswordlengthtologin": "Пароль мусіць мець даўжыню найменш $1 {{PLURAL:$1|сымбаль|сымбалі|сымбаляў}}, каб уваходзіць у сыстэму"
+       "passwordpolicies-policy-minimumpasswordlengthtologin": "Пароль мусіць мець даўжыню найменш $1 {{PLURAL:$1|сымбаль|сымбалі|сымбаляў}}, каб уваходзіць у сыстэму",
+       "passwordpolicies-policy-passwordcannotmatchusername": "Пароль ня можа супадаць зь імем ўдзельніка",
+       "passwordpolicies-policy-passwordcannotmatchblacklist": "Пароль ня можа супадаць з паролямі з чорнага сьпісу",
+       "passwordpolicies-policy-maximalpasswordlength": "Пароль мусіць быць даўжынёй менш за $1 {{PLURAL:$1|сымбаль|сымбалі|сымбаляў}}"
 }
index 191250f..d92ed63 100644 (file)
        "prefs-preview": "প্রাকদর্শন",
        "prefs-advancedrc": "উচ্চতর পছন্দগুলি",
        "prefs-opt-out": "উন্নতি অনির্বাচন",
-       "prefs-advancedrendering": "à¦\89à¦\9aà§\8dà¦\9aতর à¦\85পশন",
+       "prefs-advancedrendering": "à¦\89à¦\9aà§\8dà¦\9aতর à¦¬à¦¿à¦\95লà§\8dপà¦\97à§\81লি",
        "prefs-advancedsearchoptions": "উচ্চতর পছন্দগুলি",
-       "prefs-advancedwatchlist": "à¦\89à¦\9aà§\8dà¦\9aতর à¦\85পশন",
+       "prefs-advancedwatchlist": "à¦\89à¦\9aà§\8dà¦\9aতর à¦¬à¦¿à¦\95লà§\8dপà¦\97à§\81লি",
        "prefs-displayrc": "প্রদর্শনীর পছন্দগুলি",
        "prefs-displaywatchlist": "প্রদর্শনী অপশন",
        "prefs-tokenwatchlist": "টোকেন",
        "userrights-cannot-shorten-expiry": "\"$1\" দলটির সদস্যতার মেয়াদোত্তীর্ণ হবার সময় ও তারিখ আপনি পূর্ববর্তী কোন সময়ে এগিয়ে নিয়ে আসতে পারবেন না। যেসব ব্যবহারকারীর এই দলটি যোগ বা অপসারণ করার অনুমতি আছে, কেবল তারাই মেয়াদোত্তীর্ণ হবার সময় ও তারিখ এগিয়ে নিয়ে আসতে পারবেন।",
        "userrights-conflict": "ব্যবহারকারী অধিকার দ্বন্দ্ব! অনুগ্রহ করে নিশ্চিত হোন এবং পুনরায় চেষ্টা করুন।",
        "group": "দল:",
-       "group-user": "ব্যবহারকারীগণ",
+       "group-user": "ব্যবহারকারী",
        "group-autoconfirmed": "স্বয়ংনিশ্চিতকৃত ব্যবহারকারী",
        "group-bot": "বট",
        "group-sysop": "প্রশাসক",
diff --git a/languages/i18n/btm.json b/languages/i18n/btm.json
new file mode 100644 (file)
index 0000000..dff32b6
--- /dev/null
@@ -0,0 +1,629 @@
+{
+       "@metadata": {
+               "authors": [
+                       "Simartampua",
+                       "Apundung"
+               ]
+       },
+       "sunday": "Akad",
+       "monday": "Sinayan",
+       "tuesday": "Salasa",
+       "wednesday": "Rabu",
+       "thursday": "Kamis",
+       "friday": "Jumahat",
+       "saturday": "Sabtu",
+       "sun": "Aka",
+       "mon": "Sin",
+       "tue": "Sal",
+       "wed": "Rab",
+       "thu": "Kam",
+       "fri": "Jum",
+       "sat": "Sab",
+       "january": "Januari",
+       "february": "Februari",
+       "march": "Maret",
+       "april": "April",
+       "may_long": "Mei",
+       "june": "Juni",
+       "july": "Juli",
+       "august": "Agustus",
+       "september": "September",
+       "october": "Oktober",
+       "november": "November",
+       "december": "Desember",
+       "january-gen": "Januari",
+       "february-gen": "Februari",
+       "march-gen": "Maret",
+       "april-gen": "April",
+       "may-gen": "Mei",
+       "june-gen": "Juni",
+       "july-gen": "Juli",
+       "august-gen": "Agustus",
+       "september-gen": "September",
+       "october-gen": "Oktober",
+       "november-gen": "November",
+       "december-gen": "Desember",
+       "jan": "Jan",
+       "feb": "Feb",
+       "mar": "Mar",
+       "apr": "Apr",
+       "may": "Mei",
+       "jun": "Jun",
+       "jul": "Jul",
+       "aug": "Agu",
+       "sep": "Sep",
+       "oct": "Okt",
+       "nov": "Nov",
+       "dec": "Des",
+       "pagecategories": "{{PLURAL:$1|Category|Kategori}}",
+       "category_header": "Alaman i kategori \"$1\"",
+       "subcategories": "Subkategori",
+       "category-media-header": "Media i kategori \"$1\"",
+       "category-empty": "<em>Kategori on sonnari indadong alaman dot media.</em>",
+       "hidden-categories": "{{PLURAL:$1|Hidden category|Kategori monjap}}",
+       "category-subcat-count": "{{PLURAL:$2|Kategori on umna puna subkategori ima.|Kategori on puna ima {{PLURAL:$1|subkategori|$1 subkategori}}, tingon bahat $2.}}",
+       "category-article-count": "{{PLURAL:$2|Kategori on umna marisi alaman ima.|Onma{{PLURAL:$1|alaman ima|$1 alaman}} i kategori on, tingon bahat $2.}}",
+       "category-file-count": "{{PLURAL:$2|Kategori on umna marisi alaman ima.|Onma{{PLURAL:$1|alaman ima|$1 alaman}} i kategori on, tingon bahat $2.}}",
+       "listingcontinuesabbrev": "Sat",
+       "noindex-category": "Alaman naso tarindeks",
+       "broken-file-category": "Alaman dot link berkas sega",
+       "about": "Satontang",
+       "newwindow": "(bukak i tingkap nabaru)",
+       "cancel": "Antai",
+       "mytalk": "Dokon",
+       "navigation": "Navigasi",
+       "and": "&#32;dot",
+       "namespaces": "Ruang gorar",
+       "variants": "Mocoman",
+       "navigation-heading": "Menu Navigasi",
+       "returnto": "Keimulak tu $1",
+       "tagline": "Tingon {{SITENAME}}",
+       "help": "Tolong",
+       "search": "Jalaki",
+       "searchbutton": "Jalaki",
+       "searcharticle": "Kehe",
+       "history": "Sejarah alaman",
+       "history_short": "Sejarah",
+       "printableversion": "Versi cetak",
+       "permalink": "Tautan permanen",
+       "view": "Sise",
+       "view-foreign": "Sise i $1",
+       "edit": "Pature",
+       "create": "Baen",
+       "create-local": "Baen deskripsi lokal",
+       "delete": "Apus",
+       "newpage": "Alaman baru",
+       "talkpagelinktext": "Dokon",
+       "personaltools": "Alat pribadi",
+       "talk": "Marpokat",
+       "views": "Sise",
+       "toolbox": "Parkuas",
+       "otherlanguages": "I saro nalain",
+       "redirectedfrom": "(Ialihkon tingon $1)",
+       "redirectpagesub": "Alihkon alaman",
+       "redirectto": "Alihkon tu:",
+       "lastmodifiedat": "Alamanon parabisan ipature i $1, i $2.",
+       "jumpto": "Lumpat tu:",
+       "jumptonavigation": "navigasi",
+       "jumptosearch": "jalaki",
+       "aboutsite": "Satontang {{SITENAME}}",
+       "aboutpage": "Project:Satontang",
+       "copyright": "Konten tarsadio itoru $1 lainkon adong parnyataan nalain.",
+       "copyrightpage": "{{ns:project}}:Hak cipta",
+       "currentevents": "Namasa sonnari",
+       "currentevents-url": "Project:Kajadian nabaru",
+       "disclaimers": "Panulakan",
+       "disclaimerpage": "Project:Panulakan umum",
+       "edithelp": "Bantuan pangeditan",
+       "mainpage": "Alaman Utamo",
+       "mainpage-description": "Alaman utamo",
+       "portal": "Portal komunitas",
+       "portal-url": "Project:Portal komunitas",
+       "privacy": "Kabijakan privasi",
+       "privacypage": "Project:Kabijakan privasi",
+       "retrievedfrom": "Dapot tingon \"$1\"",
+       "youhavenewmessages": "{{PLURAL:$3|Amu puna}} $1 ($2).",
+       "youhavenewmessagesfromusers": "{{PLURAL:$4|Amu puna}} $1 tingon {{PLURAL:$3|another user|$3 pamake}} ($2).",
+       "newmessageslinkplural": "{{PLURAL:$1|a new message|999=tona na baru}}",
+       "newmessagesdifflinkplural": "Parpudi {{PLURAL:$1|change|999=parubaan}}",
+       "editsection": "Pature",
+       "editold": "Pature",
+       "viewsourceold": "Sise sumber",
+       "editlink": "Pature",
+       "viewsourcelink": "Sise sumber",
+       "editsectionhint": "Pature bagian:$1",
+       "toc": "Isi",
+       "site-atom-feed": "$1 Umpan atom",
+       "page-atom-feed": "\"$1\" Umpan atom",
+       "red-link-title": "$1 (alaman inda adong)",
+       "nstab-main": "Alaman",
+       "nstab-user": "Alaman pamake",
+       "nstab-special": "Alaman istimewa",
+       "nstab-project": "Alaman proyek",
+       "nstab-image": "Berkas",
+       "nstab-mediawiki": "Tona",
+       "nstab-template": "Templat",
+       "nstab-category": "Kategori",
+       "mainpage-nstab": "Alaman utamo",
+       "nosuchspecialpage": "Inda adong alaman husus songon i",
+       "nospecialpagetext": "<strong>Amu madung mangido alaman husus naso valid.</strong>\n\nDaftar alaman husus bisa iligi i[[Special:SpecialPages|{{int:specialpages}}]].",
+       "badtitle": "Judul na jat",
+       "badtitletext": "Judul alaman na naipaido inda valid, kosong, sanga judul antar-saro sanga antar-wiki na sala ikaitkon. On mungkin marisi sada sanga lobi karakter na inda bisa ipake i judul.",
+       "viewsource": "Sise sumber",
+       "viewsource-title": "Sise sumber ni $1",
+       "viewsourcetext": "Amu bisa manyise dot mangkopi sumber ni alaman on",
+       "userlogin-yourname": "Gorar pamake",
+       "userlogin-yourname-ph": "Pamusuk gorar pamakemu",
+       "userlogin-yourpassword": "Hata kunci",
+       "userlogin-yourpassword-ph": "Pamasuk hata kunci",
+       "createacct-yourpassword-ph": "Pamasuk hata kunci",
+       "createacct-yourpasswordagain": "Konfirmasi hata kunci",
+       "createacct-yourpasswordagain-ph": "Pamasuk hata kunci mulak",
+       "userlogin-remembermypassword": "Jago totop masuk log",
+       "login": "Masuk log",
+       "userlogin-noaccount": "Ulang adong akun",
+       "userlogin-joinproject": "Martop {{SITENAME}}",
+       "createaccount": "Baen akun",
+       "userlogin-resetpassword-link": "Lupa hata kuncimu?",
+       "userlogin-helplink2": "Tolong dot masuk log",
+       "createacct-emailoptional": "Alamat email (opsional)",
+       "createacct-email-ph": "Pamasuk alamat emailmu",
+       "createacct-submit": "Baen akunmu",
+       "createacct-benefit-heading": "{{SITENAME}} ibaen ni alak songon kamuon.",
+       "createacct-benefit-body1": "{{PLURAL:$1|edit|pature}}",
+       "createacct-benefit-body2": "{{PLURAL:$1|page|alaman}}",
+       "createacct-benefit-body3": "{{PLURAL:$1|contributor|kontributor}} baru",
+       "loginlanguagelabel": "Saro: $1",
+       "pt-login": "Masuk log",
+       "pt-login-button": "Masuk log",
+       "pt-createaccount": "Baen akun",
+       "pt-userlogout": "Kaluar log",
+       "botpasswords-label-needsreset": "(sandi porlu isitel mulak)",
+       "botpasswords-needs-reset": "Hata sandi bot tu gorar bot \"$2\" ni {{GENDER:$1|user}} \"$1\" angkon na isitel mulak.",
+       "passwordreset": "Gonti hata kunci",
+       "bold_sample": "Teks naapal",
+       "bold_tip": "Teks naapal",
+       "italic_sample": "Teks Italic",
+       "italic_tip": "Teks italic",
+       "link_sample": "Judul tautan",
+       "link_tip": "Pranala",
+       "extlink_sample": "http://www.example.com judul tautan",
+       "extlink_tip": "Tautan ruar (ingot http://prefix)",
+       "headline_sample": "Teks judul",
+       "headline_tip": "Judul tingkat 2",
+       "nowiki_sample": "Pamasuk teks naso iformat tuson",
+       "nowiki_tip": "Nangkon roaon pamformatan wiki",
+       "image_tip": "Berkas naisematkon",
+       "media_tip": "Tautan berkas",
+       "sig_tip": "Tekenanmu dot tando woktu",
+       "hr_tip": "Garis horizontal (pake dohot denggan)",
+       "summary": "Ringkasan:",
+       "minoredit": "On suntingan namenek",
+       "watchthis": "Pamatai alamanon",
+       "savearticle": "Simpan alaman",
+       "preview": "Cimak",
+       "showpreview": "Patidaon pratayang",
+       "showdiff": "Patidaon parubaan",
+       "anoneditwarning": "<strong> Paringatan: </ strong> Amu indape masuk. Alamat IP Muyu nangkan tarida sacara publik molo Amu mambaen pangeditan. Molo Amu <strong> [$1 masuk] </ strong> sanga<strong> [$2 mambaen akun] </ strong>, hasil pangeditan Muyu nangkan ikaitkon dohot gorar pamake Muyu, rap dohot manfaat lainna.",
+       "blockedtext": "<strong>Alamat IP muyu madung iblokir sacara otomatis arani ipake ni pamake nalain,.</strong>\n\nNa iblokir ni $1.\nPamvlokiran ibaen arani <em>$2</em>.\n\n* Iblokir sian: $8\n* Blokir kadaluarsa i: $6\n* Sasarab pamblokiran: $7\n\nAmu bisa mayapai $1 sanga [[{{MediaWiki:Grouppage-sysop}}|administrator]] lainna tuna mamokatkon hal on.\n\nAmu inda bisa mamake fitur \"{{int:emailuser}}\" kacuali amu madung mamasukkon alamat surel na sah i [[Special:Preferences|preferensi akun]] dot amu inda iblokir mamakena.\n\nAlama IP muyu saonnari ima $3, dot ID pamblokiran ima #$5.\nTolong baen informasi-informasi in i satiop parsapaan muyu.",
+       "autoblockedtext": "Alamat IP mu nangkan otomatis iblokir arani ipake pamake nalain, na madung iblokir ni $1.\nAlasanna ima:\n\n:<em>$2</em>\n\n* Muloi i blokir: $8\n* Kadaluarsa blokir: $6\n* Blokir na ituju: $7\n\nSapai amuma $1 sanga sada tingon nalainnai [[{{MediaWiki:Grouppage-sysop}}|administrators]] giot mamokatkon blokiran on.\n\nRoaon molo Amu inda tola mamake fitur \"{{int: emailuser}}\" kacuali Amu puna alamat surel valid na tardaftar i [[Special:Preferences|preferensi pamake]] dot Amu indape iblokir mamakena.\n\nAlamat IP mu sonnari ima $3, dot blokir ID ima #$5.\nIaropkon baen sude rincian na iginjang singkop molo mambaen parsaapaan na ibaen muyu.",
+       "loginreqlink": "Masuk log",
+       "newarticletext": "Amu madung paiut tautan tu alaman na so adong dope. Giot mambaen alaman, muloima mangetik i kotak i toru on (ligin [$1 alaman bantuan] giot info lobi lanjut). Molo Amu adong i son arani kasalahan, klik tombol <strong> mulam </ strong> i browser Muyu.",
+       "anontalkpagetext": "---- \n\n<em> on ima alaman marpokat tu pangguna anonim naso mambaen akun dope, sanga na inda mamakena. </em> Arani i ami angkon mamake alamat IP numerik tu mangidentifikasi ia. Songon alamat IP bisa ibagi ni bahat pengguna. Molo Amu ima pangguna anonim dot marasa molo komentar na inda relevan madung iarahkon tu Amu, kehemamu [[Special:CreateAccount|baen akun]] sanga [[Special:UserLogin|masuk log]] tu mangilakkon gamang i tu jolo niari dohot pengguna anonim laina.",
+       "noarticletext": "Saonnari inda adong teks i alaman on. Amu bisa [[Special:Search/{{PAGENAME}}|manjalai judul alaman on]] i alaman lain, <span class = \"plainlinks\"> [{{fullurl: {{# Special: Log}} | page = { {FULLPAGENAMEE}}}} telusuri log terkait], atau [{{fullurl: {{FULLPAGENAME}} | action = edit}} baen alaman on] </ span>.",
+       "noarticletext-nopermission": "Saonnari inda adong teks i alaman on. Amu bisa [[Special:Search/{{PAGENAME}}|manjalai judul alaman on]] i alaman lain, sanga <span class = \"plainlinks\"> [{{fullurl:{{#Special:Log}}|alaman={{FULLPAGENAMEE}}}} jalai log tarkait] </ span>, tai Amu inda puna izin giot mambaen alaman on.",
+       "userpage-userdoesnotexist-view": "Akun pangguna ''$1'' inda tardaftar",
+       "clearyourcache": "<strong> Catatan: </strong> Sidung manyimpan, Amu mungkin angkon malewati cache browser Muyu anso mangida parubaanna. \n* <strong> Firefox/Safari:</strong> Tahan <em> Shift </em> atia mangklik <em> Reload </em>, sanga pisat <em> Ctrl-F5 </em> sanga <em> Ctrl-R </em> (<em> ⌘-R </ em> pada Mac) \n* <strong> Google Chrome: </strong> Pisat <em> Ctrl-Shift-R </em> (<em> ⌘ -Shift-R </em> i Mac) \n* <strong> Internet Explorer: </strong> Tahan <em> Ctrl </em> atia mangklik <em> Segarkon </em>, sanga pisat <em> Ctrl-F5 </em> \n* <strong> Opera: </ strong> Kei tu <em> Menu → Pangaturan </em> (<em> Opera → Preferensi </ em> i Mac) dot sidungi ke <em> Privasi & kaamanan → Apus data panjalajahan → Tembolok gambar dot file </em>.",
+       "previewnote": "<strong> Ingot molo on umna pratinjau. </strong> Parubaan Muyu indape isimpan!",
+       "continue-editing": "Kei tu ganan pangeditan",
+       "editing": "Mangedit $1",
+       "creating": "Baen $1",
+       "editingsection": "Patureon $1 (bagian)",
+       "templatesused": "{{PLURAL:$1|Template|Templat}} baen tu alaman on:",
+       "templatesusedpreview": "{{PLURAL:$1|Template|Templat}} ipake i pratinjau on:",
+       "template-protected": "Larangan",
+       "template-semiprotected": "(satonga-larangan)",
+       "hiddencategories": "Alaman on ima anggota {{PLURAL:$1|1 kategori namonjap|$1 kategori namonjap}}:",
+       "permissionserrors": "Santabi sega",
+       "permissionserrorstext-withaction": "Amu inda iizinkon $2, tu naonan {{PLURAL:$1|reason|alasan}}:",
+       "recreate-moveddeleted-warn": "<strong> Paringotan: Amu mambaen mulak laman na unjung ihapus. </strong> Amu angkon mapartimbangkon sanga sasue giot malanjutkon mangedit alaman on. Log pangapusan dot pamindahan tu alaman on isadioon i son so tagi:",
+       "moveddeleted-notice": "Alaman on nangkan iapus. \nCatatan pangapusan, palarangan, dot pamindahan tu alaman ilehen i toru on manjadi referensi.",
+       "content-model-wikitext": "Tekswiki",
+       "undo-failure": "Pangeditan inda bisa iantai arani pangeditan dompak na konflik.",
+       "viewpagelogs": "Sise log ni alaman on",
+       "currentrev-asof": "Parubaan parpudi ima $1",
+       "revisionasof": "Revisi par $1",
+       "revision-info": "Revisi par $1 by {{GENDER:$6|$2}}$7",
+       "previousrevision": "← Revisi na lobi onok",
+       "nextrevision": "Revisi tarbaru →",
+       "currentrevisionlink": "Revisi parpudi",
+       "cur": "Sonnari",
+       "last": "Cimak",
+       "histlegend": "Seleksi Diff: Tandai kotak radio tingon revisi giot mambandingkon dot pisat enter sanga tombol naitoru.<br />\nLegend: <strong>({{int:cur}})</strong> = parbedaan dohot revisi tarbaru, <strong>({{int:last}})</strong> = parbedaan dohot revisi naparjolo, <strong>{{int:minoreditletter}}</strong> = pengeditan menek.",
+       "history-fieldset-title": "Jalai revisi",
+       "histfirst": "Naonok",
+       "histlast": "Nabaru",
+       "history-feed-title": "Sejarah revisi",
+       "history-feed-description": "Sejarah revisi tu alaman i wiki",
+       "history-feed-item-nocomment": "$1 i $2",
+       "rev-delundel": "Uba visibilitas",
+       "mergelog": "Pasada log",
+       "history-title": "Sejarah Revisi ni \"$1\"",
+       "difference-title": "Parbedaan antara revisi \"$1\"",
+       "lineno": "Baris $1:",
+       "compareselectedversions": "Bandingkon dot revisi tarpili",
+       "editundo": "Mambuka",
+       "diff-empty": "(Inda dong parbedaan)",
+       "diff-multi-sameuser": "({{PLURAL:$1|Sada revisi manonga|$1 revisi manonga}} ni pangguna na sarupo inda ipatidaon)",
+       "diff-multi-otherusers": "({{PLURAL:$1|Sada revisi sedang|$1 revisi sedang}} ibaen {{PLURAL:$2|sada pangguna lainna|$2 pangguna}} inda ipatidaon)",
+       "searchresults": "Jalaki sude hasil",
+       "searchresults-title": "Jalaki sude hasil tu \"$1\"",
+       "prevn": "Cimak {{PLURAL:$1|$1}}",
+       "nextn": "Satorusna {{PLURAL:$1|$1}}",
+       "prevn-title": "Cimak $1 {{PLURAL:$1|result|hasil}}",
+       "nextn-title": "Satorusna $1 {{PLURAL:$1|result|hasil}}",
+       "shown-title": "Patidaon $1 {{PLURAL:$1|result|hasil}} par alaman",
+       "viewprevnext": "Sise ($1 {{int:pipe-separator}} $2) ($3)",
+       "searchmenu-exists": "<strong>Adong gorar ni alaman \"[[:$1]]\" i wiki on.</strong> {{PLURAL:$2|0=|Ligin juo panjalakan napasuo.}}",
+       "searchmenu-new": "<strong> Baen alaman \"[[:$1]]\" i wiki on! </strong> {{PLURAL:$2|0=|Ligin juo alaman na dapot dohot panjalakan Muyu.|Ligin juo hasil panjalakan na dapot.}}",
+       "searchprofile-articles": "Isi nialaman",
+       "searchprofile-images": "Multimedia",
+       "searchprofile-everything": "Sanga aha",
+       "searchprofile-advanced": "Torus",
+       "searchprofile-articles-tooltip": "Jalaki i $1",
+       "searchprofile-images-tooltip": "Jalai berkas",
+       "searchprofile-everything-tooltip": "Jalai sude tontang (ibagasan alaman parpokatan)",
+       "searchprofile-advanced-tooltip": "Jalaki i ruang gorar kustom",
+       "search-result-size": "$1 ({{PLURAL:$2|1 word|$2 hata}})",
+       "search-result-category-size": "{{PLURAL:$1|1 member|$1 anggota}} ({{PLURAL:$2|1 subcategory|$2 subkategori}}, {{PLURAL:$3|1 file|$3 berkas}})",
+       "search-redirect": "(alihkon tingon $1)",
+       "search-section": "(bagian $1)",
+       "search-file-match": "(isi berkas na cocok)",
+       "search-suggest": "On do na imaksudmi:$1",
+       "searchall": "Sude",
+       "search-showingresults": "{{PLURAL:$4|Hasil<strong>$1</strong> tingon <strong>$3</strong>|Hasil <strong>$1 – $2</strong> tingon <strong>$3</strong>}}",
+       "search-nonefound": "Inda adong hasil na cocok dohot kueri.",
+       "mypreferences": "Preferensi",
+       "group-bot": "Bot",
+       "group-sysop": "Administrator",
+       "grouppage-bot": "{{ns:project}}:Bot",
+       "grouppage-sysop": "{{ns:project}}:Administrator",
+       "right-writeapi": "Pamakean ni API tulis",
+       "newuserlogpage": "Log pambaenan pamake",
+       "rightslog": "Log hak pangguna",
+       "action-edit": "Pature alaman on",
+       "action-createaccount": "baen akun pamake on",
+       "enhancedrc-history": "sejarah",
+       "recentchanges": "Parubaan tarbaru",
+       "recentchanges-legend": "Opsi parubaan tarbaru",
+       "recentchanges-summary": "Lacak parubaan tarbaru i wiki i alaman on.",
+       "recentchanges-noresult": "Inda adong parubaan saonok periode na ilehen sasuae dohot kriteria on.",
+       "recentchanges-feed-description": "Jalaki parubaan tarbaru i wiki i umpan on.",
+       "recentchanges-label-newpage": "Editan on mammbaen alaman baru",
+       "recentchanges-label-minor": "On edit na menek",
+       "recentchanges-label-bot": "Naipature ni bot",
+       "recentchanges-label-unpatrolled": "Suntingan on indape ipareso",
+       "recentchanges-label-plusminus": "Ukuran alamanon iuba dohot bahatni byte",
+       "recentchanges-legend-heading": "<strong>Tando:</strong>",
+       "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (ligin juo [[Special:NewPages|daftar alaman nabaru]])",
+       "rcnotefrom": "Itoru {{PLURAL:$5|is the change|ima parubaan}} saonok<strong>$3, $4</strong> (sampe tu <strong>$1</strong> patidaon).",
+       "rclistfrom": "Patidaon parubaan tarbaru imuloi tingon $2, $3",
+       "rcshowhideminor": "$1 pature namenek",
+       "rcshowhideminor-show": "Patidaon",
+       "rcshowhideminor-hide": "Bunion",
+       "rcshowhidebots": "$1 bot",
+       "rcshowhidebots-show": "Patidaon",
+       "rcshowhidebots-hide": "Bunion",
+       "rcshowhideliu": "$1 pamake tardaftar",
+       "rcshowhideliu-show": "Patidaon",
+       "rcshowhideliu-hide": "Bunion",
+       "rcshowhideanons": "$1 pamake anonim",
+       "rcshowhideanons-show": "Patidaon",
+       "rcshowhideanons-hide": "Bunion",
+       "rcshowhidepatr": "$1 edit nai pareso",
+       "rcshowhidemine": "$1 naupature",
+       "rcshowhidemine-show": "Patidaon",
+       "rcshowhidemine-hide": "Bunion",
+       "rclinks": "Patidaon sude $1 parubaan $2 ari",
+       "diff": "diff",
+       "hist": "hist",
+       "hide": "Bunion",
+       "show": "Alaman pamake",
+       "minoreditletter": "m",
+       "newpageletter": "B",
+       "boteditletter": "b",
+       "rc-change-size-new": "$1 {{PLURAL:$1|byte|bytes}} sidung iuba",
+       "rc-old-title": "Aslina ibaen i ''$1''",
+       "recentchangeslinked": "Parubaan tarkait",
+       "recentchangeslinked-feed": "Parubaan tarkait",
+       "recentchangeslinked-toolbox": "Parubaan tarkait",
+       "recentchangeslinked-title": "Parubaan tarkait tu \"$1\"",
+       "recentchangeslinked-summary": "Pamasuk gorar alaman giot maligi parubaaan i alaman na tarsambung tu sanga tingon alaman i. (Giot mangaligi anggota kategori, pamasuk {{ns: category}}: Gorar kategori). Parubaan i alaman [[Special:Watchlist|Daftar Naipamatai mu]] adong i <strong> bold </ strong>.",
+       "recentchangeslinked-page": "Gorar alaman:",
+       "recentchangeslinked-to": "Patidaon parubaaan tu alaman na itautkon tu alaman na baen",
+       "upload": "Unggah berkas",
+       "uploadlogpage": "Unggah log",
+       "filedesc": "Ringkasan",
+       "license": "Ilisensi",
+       "license-header": "Lisensi",
+       "imgfile": "Berkas",
+       "listfiles": "Daftar berkas",
+       "file-anchor-link": "Berkas",
+       "filehist": "Sejarah berkas",
+       "filehist-help": "Klik tanggal / woktu giot maligi file songon na na i woktu i.",
+       "filehist-revert": "Mulak",
+       "filehist-current": "Saonnari",
+       "filehist-datetime": "Tangagal/Woktu",
+       "filehist-thumb": "Gambar",
+       "filehist-thumbtext": "Gambar tu versi par $1",
+       "filehist-nothumb": "Inda adong gambar",
+       "filehist-user": "Pamake",
+       "filehist-dimensions": "Ukuran",
+       "filehist-comment": "Komentar",
+       "imagelinks": "Berkas ipake",
+       "linkstoimage": "Onma {{PLURAL:$1|page links|$1 tautan alaman}} tu berkas on:",
+       "linkstoimage-more": "Lobi tingon $1 {{PLURAL:$1|page links|tautan alaman}} tu berkas on. Daftar naonan patidaon {{PLURAL:$1|first page link|tautan alaman parjolo $1}} tu berkas on sajo. A [[Special:WhatLinksHere/$2|daftar singkop]] tarsadio.",
+       "nolinkstoimage": "Inda adong alaman na martaut tu berkason",
+       "linkstoimage-redirect": "$1 (pangalihan berkas) $2",
+       "sharedupload-desc-here": "File on tingon $1 dot bisa ipake ni proyek lain. Deskripsi i [alaman deskripsi file $2] i sadun ipatidaon naitoruon.",
+       "filepage-nofile": "Inda adong berkas dohot gorar on.",
+       "upload-disallowed-here": "Amu inda bisa manimpo berkas on.",
+       "randompage": "Gaor alaman",
+       "statistics": "Statistik",
+       "double-redirect-fixer": "Papas Pangalihan",
+       "nbytes": "$1 {{PLURAL:$1|byte|bytes}}",
+       "nmembers": "$1 {{PLURAL:$1|member|anggota}}",
+       "prefixindex": "Sude alaman na prefix",
+       "listusers": "Daptar pamake",
+       "newpages": "Alaman baru",
+       "move": "Pindah",
+       "pager-newer-n": "{{PLURAL:$1|newer 1|nabaru $1}}",
+       "pager-older-n": "{{PLURAL:$1|older 1|parpudi $1}}",
+       "booksources": "Sumber buku",
+       "booksources-search-legend": "Jalai tu sumber buku",
+       "booksources-search": "Jalai",
+       "specialloguserlabel": "Panampil:",
+       "speciallogtitlelabel": "Target (judul sanga {{ns:user}}:gorar pangguna tu pangguna):",
+       "log": "Masuk",
+       "all-logs-page": "Sude log",
+       "alllogstext": "Tampilan gabungan tingon sude log na tarsadio tingon {{SITENAME}}. Amu bisa mamparsompit tampilan dohot mamili jenis log, gorar pangguna (sensitif huruf), sanga alaman na tarpangaruh (juo kasus-sensitive).",
+       "logempty": "Inda adong item nacocok i log",
+       "allpages": "Sude alaman",
+       "allarticles": "Sude alaman",
+       "allpagessubmit": "Kehe",
+       "allpages-hide-redirects": "Bunion pangalihan",
+       "categories": "Kategori",
+       "listgrouprights-members": "(daftar anggota)",
+       "emailuser": "Email ni pamake on",
+       "usermessage-editor": "Tona ni sistem",
+       "watchlist": "Pamataan",
+       "mywatchlist": "Pamatai",
+       "watchlistfor2": "Tu $1 $2",
+       "watch": "Pamatai",
+       "unwatch": "Inda ipamatai",
+       "watchlist-details": "{{PLURAL:$1|$1 page is|$1 alaman}} i pamataanmu (dot alaman parkobaran).",
+       "wlheader-showupdated": "Laman na madung iubah sian parpudi Amu ligi, ipatidaon i huruf <strong> naapal </strong>.",
+       "wlnote": "Itoruon {{PLURAL:$1|is the last change|ima parpudi<strong>$1</strong> parubaan}} i {{PLURAL:$2|hour|<strong>$2</strong> jom}}, i $3, $4.",
+       "wlshowlast": "Patidaon parpudi $1 jom $2 ari",
+       "watchlist-options": "Opsi pamataan",
+       "enotif_reset": "Tandai sude alaman namadung iligi",
+       "dellogpage": "Apus log",
+       "rollbacklink": "balikkon",
+       "rollbacklinkcount": "Paulak $1 {{PLURAL:$1|edit|edits}}",
+       "protectlogpage": "Log nai jago",
+       "protectedarticle": "larangan \"[[$1]]\"",
+       "modifiedarticleprotection": "Gonti tingkat larangan tu ''[[$1]]''",
+       "protect-default": "Patola sude pangguna",
+       "restriction-edit": "Pature",
+       "restriction-move": "Pindah",
+       "namespace": "Ruanggorar:",
+       "invert": "Pilian sabalikna",
+       "tooltip-invert": "Centang kotak on giot mambunion parubaan tu alaman i ruang gorar na ipili (dot ruang gorar tarkait molo icentang)",
+       "namespace_association": "Kumpulan ruang gorar",
+       "tooltip-namespace_association": "Centang kotak on giot mambunion ruang gorar pangecean sanga subjek na tarkait dohot ruang gorar na ipili",
+       "blanknamespace": "(Utamo)",
+       "contributions": "{{GENDER:$1|User}} kontribusi",
+       "contributions-title": "Kontribusi pangguna tu $1",
+       "mycontris": "Kontribusi",
+       "anoncontribs": "Kontribusingku",
+       "contribsub2": "Tu {{GENDER:$3|$1}} ($2)",
+       "nocontribs": "Inda adong parubaan na sasue dohot kriteria on.",
+       "uctop": "(sonnari)",
+       "month": "Tingon bulan (dot nasolpu)",
+       "year": "Tingon taon (dot nasolpu)",
+       "sp-contributions-newbies": "Patidaon kontribusi ni akun nabaru sajope",
+       "sp-contributions-blocklog": "Log blokir",
+       "sp-contributions-uploads": "Unggah",
+       "sp-contributions-logs": "Log",
+       "sp-contributions-talk": "Dokon",
+       "sp-contributions-search": "Jalaki kontribusi",
+       "sp-contributions-username": "Alama IP Pangguna",
+       "sp-contributions-toponly": "Umna patidaon editan revisi parpudi",
+       "sp-contributions-newonly": "Umna patidaon alaman naibuat",
+       "sp-contributions-submit": "Jalaki",
+       "whatlinkshere": "Tautan aha ison",
+       "whatlinkshere-title": "Alaman puna tautan tu \"$1\"",
+       "whatlinkshere-page": "Alaman:",
+       "linkshere-2": "Onma alaman namartaut tu <strong>$1</strong>:",
+       "nolinkshere-2": "Inda adong alaman na martaut tu <strong>$1</strong>.",
+       "isredirect": "Alaman pangalihan",
+       "istemplate": "transklusi",
+       "isimage": "Tautan berkas",
+       "whatlinkshere-prev": "{{PLURAL:$1|previous|parjolo $1}}",
+       "whatlinkshere-next": "{{PLURAL:$1|next|satorusna $1}}",
+       "whatlinkshere-links": "← tautan",
+       "whatlinkshere-hideredirs": "$1 ialihkon",
+       "whatlinkshere-hidetrans": "$1 transklusi",
+       "whatlinkshere-hidelinks": "$1 tautan",
+       "whatlinkshere-hideimages": "$1 tautan berkas",
+       "whatlinkshere-filters": "Saringan",
+       "ipboptions": "2 jom:2 hours,1 ari:1 day,3 ari:3 days,1 poken:1 week,2 poken:2 weeks,1 bulan:1 month,3 bulan:3 months,6 bulan:6 months,1 taon:1 year,onok:infinite",
+       "infiniteblock": "Inda tarbatas",
+       "blocklink": "blokir",
+       "contribslink": "Kontributor",
+       "blocklogpage": "Blokir log",
+       "blocklogentry": "blokir [[$1]] dot woktu kadaluarsa $2 $3",
+       "reblock-logentry": "Gonti sitelan blokir tu [[$1]] dot maso kadaluarsa tu $2 $3",
+       "block-log-flags-nocreate": "Pambaenan akun inonaktipkon",
+       "proxyblocker": "Blokir proxi",
+       "movelogpage": "Pindah log",
+       "export": "Expor alaman",
+       "thumbnail-more": "Pagodang",
+       "importlogpage": "Log impor",
+       "tooltip-pt-userpage": "{{GENDER:|Your user}} alaman",
+       "tooltip-pt-mytalk": "{{GENDER:|Your}} alaman parkobaran",
+       "tooltip-pt-preferences": "{{GENDER:|Your}} preferensi",
+       "tooltip-pt-watchlist": "Daftar nialaman na parubaanna ipamataimu",
+       "tooltip-pt-mycontris": "Daftar {{GENDER:|your}} kontribusi",
+       "tooltip-pt-login": "Amu iaropkon masuk, tai inda wajib",
+       "tooltip-pt-logout": "Kaluar log",
+       "tooltip-pt-createaccount": "Amu iaropkon mambaen akun dot masuk; taiba, i inda wajib",
+       "tooltip-ca-talk": "Pokat satontang isi ni alaman",
+       "tooltip-ca-edit": "Pature alamanon",
+       "tooltip-ca-addsection": "Baen bagian nabaru",
+       "tooltip-ca-viewsource": "Alaman on ilarang.\nAmu bisa manyise sumber",
+       "tooltip-ca-history": "Revisi parpudi ni alaman on",
+       "tooltip-ca-protect": "Jago alamanon",
+       "tooltip-ca-delete": "Apus alaman on",
+       "tooltip-ca-move": "Papindah alamanon",
+       "tooltip-ca-watch": "Baen alamanon tu pamataanmu",
+       "tooltip-ca-unwatch": "Apus alaman on tingon pamataanmu",
+       "tooltip-search": "Jalaki {{SITENAME}}",
+       "tooltip-search-go": "Kehe tu alaman dohot gorar naonan molo adong.",
+       "tooltip-search-fulltext": "Jalaki alaman tu teks on",
+       "tooltip-p-logo": "Ligin alaman utamo",
+       "tooltip-n-mainpage": "Kehe tu alaman utamo",
+       "tooltip-n-mainpage-description": "Kei tu alaman utamo",
+       "tooltip-n-portal": "Satontang proyek, aha ma bisa ibaen kamu, anso dapot",
+       "tooltip-n-currentevents": "Jalai latar bolakang satontang kajadian tarbaru",
+       "tooltip-n-recentchanges": "Daftar parubaan tarbaru i Wikion",
+       "tooltip-n-randompage": "Muat alaman sumbarang",
+       "tooltip-n-help": "Inganan anso binoto",
+       "tooltip-t-whatlinkshere": "Daftar alaman wiki na martaut tuson",
+       "tooltip-t-recentchangeslinked": "Parubaan tarbaru i sude alaman namartautan tu alaman on",
+       "tooltip-feed-atom": "Umpan atom ni alamaon",
+       "tooltip-t-contributions": "Daftar kontribusi ni {{GENDER:$1|pamake on}}",
+       "tooltip-t-emailuser": "Kirim email tu {{GENDER:$1|pamake on}}",
+       "tooltip-t-upload": "Unggah berkas-berkas",
+       "tooltip-t-specialpages": "Daftar ni sude alaman spesial",
+       "tooltip-t-print": "Versi cetak ni alamanon",
+       "tooltip-t-permalink": "Tautan permanen tu revisi ni alamanon",
+       "tooltip-ca-nstab-main": "Sise isi ni alaman",
+       "tooltip-ca-nstab-user": "Sise alaman pamake",
+       "tooltip-ca-nstab-special": "On alaman husus, dot on inda bisa ipature",
+       "tooltip-ca-nstab-project": "Sise alaman proyek",
+       "tooltip-ca-nstab-image": "Sise alaman berkas",
+       "tooltip-ca-nstab-mediawiki": "Sise sistem tona",
+       "tooltip-ca-nstab-template": "Sise templat",
+       "tooltip-ca-nstab-category": "Sise kategori ni alaman",
+       "tooltip-minoredit": "Tandai on pangeditan namenek",
+       "tooltip-save": "Simpan parubaanmu",
+       "tooltip-preview": "Pareso naiubamu. Pake jolo on dompak so isimpan",
+       "tooltip-diff": "Patidaon sanga dia teks naiubamu",
+       "tooltip-compareselectedversions": "Ligin parbedaan antara dua revisi naipili ni alaman on",
+       "tooltip-watch": "Baen alamanon tu pamataanmu",
+       "tooltip-rollback": "\"Balikkon\" paulak pangedit kontributor parpudi tu alaman on dohot sa klik",
+       "tooltip-undo": "\"Undo\" pamulak pangeditan on dot mambuka formulir edit i mode pratinjau. On mamungkinkon manambaon alasan i ringkasan.",
+       "tooltip-summary": "Baen ringkasan pondok",
+       "simpleantispam-label": "Pareso Anti-spam.\nBaen <strong>inda</strong> isi ison!",
+       "pageinfo-title": "Informasi tu ''$1''",
+       "pageinfo-header-basic": "Informasi dasor",
+       "pageinfo-header-edits": "Sejarah edit",
+       "pageinfo-header-restrictions": "Alaman larangan",
+       "pageinfo-header-properties": "Parkuas alaman",
+       "pageinfo-display-title": "Judul tampilan",
+       "pageinfo-default-sort": "Kunci panyortiran default",
+       "pageinfo-length": "Lanjang alaman (i byte)",
+       "pageinfo-article-id": "ID alaman",
+       "pageinfo-language": "Saro isi ni alaman",
+       "pageinfo-content-model": "Model konten alaman",
+       "pageinfo-robot-policy": "Pangindeksan ni robot",
+       "pageinfo-robot-index": "Iizinkon",
+       "pageinfo-robot-noindex": "Inda iizinkon",
+       "pageinfo-watchers": "Bahatni alaman naipamatai",
+       "pageinfo-few-watchers": "Urang tingon $1 {{PLURAL:$1|pamatai|napamatai}}",
+       "pageinfo-redirects-name": "Bahatni pangalihan tu alaman on",
+       "pageinfo-subpages-name": "Bahatni sub alaman ni alaman on",
+       "pageinfo-subpages-value": "$1 ($2 {{PLURAL:$2|redirect|pangalihan}}; $3 {{PLURAL:$3|non-redirect|inda pangalihan}})",
+       "pageinfo-firstuser": "Pambaen alaman",
+       "pageinfo-firsttime": "Tanggal ibaen alaman",
+       "pageinfo-lastuser": "Pangedit parpudi",
+       "pageinfo-lasttime": "Tanggal edit parpudi",
+       "pageinfo-edits": "Bahat ni edit",
+       "pageinfo-authors": "Bahatni sude panulis namarbeda",
+       "pageinfo-recent-edits": "Bahat pangeditan tarbaru (i $1 pardudi)",
+       "pageinfo-recent-authors": "Bahat ni panulis namarbeda i ari nalewat",
+       "pageinfo-magic-words": "Ajaib {{PLURAL:$1|word|hata}} ($1)",
+       "pageinfo-hidden-categories": "Bunion {{PLURAL:$1|category|Kategori}} ($1)",
+       "pageinfo-templates": "Transklusi {{PLURAL:$1|template|templat}} ($1)",
+       "pageinfo-toolboxlink": "Informasi alaman",
+       "pageinfo-contentpage": "Ietong manjadi sada alaman",
+       "pageinfo-contentpage-yes": "Olo",
+       "patrol-log-page": "Log patroli",
+       "previousdiff": "← editan nasolpu",
+       "nextdiff": "Edit tarbaru →",
+       "widthheightpage": "$1 × $2, $3 {{PLURAL:$3|page|alaman}}",
+       "file-info-size": "$1 × $2 piksel, ukuran berkas: $3, Type MIME: $4",
+       "file-info-size-pages": "$1 × $2 piksel, ukuran berkas: $3, tipe MIME : $4, $5 {{PLURAL:$5|page|alaman}}",
+       "file-nohires": "Indadongbe resolusi naum ginjang",
+       "svg-long-desc": "Berkas SVG, nominall $1 × $2 piksel, ukuran berkas: $3",
+       "show-big-image": "Berkas asli",
+       "show-big-image-preview": "Ukuran ni pratayang:$1",
+       "show-big-image-other": "Lainna {{PLURAL:$2|resolution|resolusi}}: $1.",
+       "show-big-image-size": "$1 × $2 piksel",
+       "metadata": "Metadata",
+       "metadata-help": "Berkas on marisi informasi tambahan, mungkin itambaon tingon kamera digital sanga pamindai na ipake tu mambaen sanga mandigitalkonna. Molo berkas madung imodifikasi tingon kaadaan aslina, sadebana detail mungkin inda sudena mancerminkon berkas na imodifikasi.",
+       "metadata-fields": "Bidang metadata gambar na tarcantum i tona on nangkan ibaenkon i tampilan alaman gambar atia tabel metadata iciutkon. \nNalain nangkan ibunion sacara default.\n* make\n* model\n* datetimeoriginal\n* exposuretime\n* fnumber\n* isospeedratings\n* focallength\n* artist\n* copyright\n* imagedescription\n* gpslatitude\n* gpslongitude\n* gpsaltitude",
+       "exif-orientation": "Orientasi",
+       "exif-xresolution": "Resolusi horizontal",
+       "exif-yresolution": "Resolusi vertikal",
+       "exif-datetime": "Parubaan tanggal dot woktu berkas",
+       "exif-make": "Pambaen kamera",
+       "exif-model": "Model kamera",
+       "exif-software": "Perangkat lunak nai pake",
+       "exif-exifversion": "Model Exif",
+       "exif-colorspace": "Ruang warna",
+       "exif-datetimeoriginal": "Tanggal dot waktu pambuatan data",
+       "exif-datetimedigitized": "Tanggal dot woktu idigitalisasi",
+       "exif-orientation-1": "Biaso",
+       "namespacesall": "Sude",
+       "monthsall": "Sude",
+       "imgmultipagenext": "alaman satorusna →",
+       "imgmultigo": "Kei!",
+       "imgmultigoto": "Kei tu alaman $1",
+       "watchlisttools-clear": "Paias pamataan",
+       "watchlisttools-view": "Sise parubaan na pas",
+       "watchlisttools-edit": "Sise dot pature pamataan",
+       "watchlisttools-raw": "Pature daptar pamataan",
+       "signature": "[[{{ns:user}}:$1|$2]] ([[{{ns:user_talk}}:$1|obarkon]])",
+       "redirect": "Pangalihan ni berkas, pamake, alaman, revisi, sanga log ID",
+       "redirect-summary": "Alaman husus on mangalihkon tu berkas (ilehen gorar berkas), alaman (ilehen ID revisi sanga ID alaman), alaman pangguna (ilehen ID pangguna numerik), sanga entri log (ilehen ID log). Pamakean:\n[[{{#Special:Redirect}}/file/Example.jpg]], [[{{#Special:Redirect}}/page/64308]], [[{{#Special:Redirect}}/revision/328429]], [[{{#Special:Redirect}}/user/101]], sanga [[{{#Special:Redirect}}/logid/186]].",
+       "redirect-submit": "Kei",
+       "redirect-lookup": "Ligima:",
+       "redirect-value": "Nilai:",
+       "redirect-user": "ID pangguna",
+       "redirect-page": "ID alaman",
+       "redirect-revision": "Revisi alaman",
+       "redirect-file": "Gorarberkas:",
+       "specialpages": "Alaman husus",
+       "tag-filter": "[[Special:Tags|Tag]] saring:",
+       "tag-list-wrapper": "([[Special:Tags|{{PLURAL:$1|Tag|Tags}}]]:$2)",
+       "tags-active-yes": "Olo",
+       "tags-active-no": "Inda",
+       "tags-hitcount": "$1 {{PLURAL:$1|change|parubaan}}",
+       "logentry-delete-delete": "$1 {{GENDER:$2|iapus}} alaman $3",
+       "logentry-delete-restore": "$1 {{GENDER:$2|restored}} alaman $3 ($4)",
+       "logentry-delete-revision": "$1 {{GENDER:$2|iuba}} visibilitas {{PLURAL:$5|a revision|$5 revisi}} i alaman $3: $4",
+       "revdelete-content-hid": "Isi naibunion",
+       "logentry-move-move": "$1 {{GENDER:$2|pindah}} alam $3 to $4",
+       "logentry-move-move-noredirect": "$1 {{GENDER:$2|pindah}} alaman $3 tu $4 inda maninggalkon pangalihan",
+       "logentry-move-move_redir": "$1 {{GENDER:$2|papindah}} alaman $3 tu $4 pangalihan lobi",
+       "logentry-patrol-patrol-auto": "$1 otomatis {{GENDER:$2|itandai}} revisi $4 ni alaman $3 naipatroli",
+       "logentry-newusers-create": "Akun pamake $1 ima {{GENDER:$2|baen}}",
+       "logentry-newusers-autocreate": "Akun pangguna $1 madung {{GENDER:$2|ibaen}} otomatis",
+       "logentry-upload-upload": "$1 {{GENDER:$2|maiunggah}} $3",
+       "logentry-upload-overwrite": "$1 {{GENDER:$2|iunggah}} versi nabaru tingon $3",
+       "searchsuggest-search": "Jalaki {{SITENAME}}",
+       "duration-days": "$1 {{PLURAL:$1|day|ari}}",
+       "randomrootpage": "Gaor alaman urat"
+}
index fb10a20..d4b37fc 100644 (file)
        "histlegend": "Simbologia: (act) = diferència amb la versió actual,\n(prev) = diferència amb la versió anterior, m = modificació menor",
        "history-fieldset-title": "Cerca revisions",
        "history-show-deleted": "Només revisions esborrades",
-       "histfirst": "més antigues",
-       "histlast": "més noves",
+       "histfirst": "les més antigues",
+       "histlast": "les més noves",
        "historysize": "({{PLURAL:$1|1 octet|$1 octets}})",
        "historyempty": "(buit)",
        "history-feed-title": "Historial de revisió",
index 18fd2f6..eaa60c0 100644 (file)
        "toc": "Тупмалли",
        "showtoc": "кăтартмалла",
        "hidetoc": "кӑтартмалла мар",
+       "collapsible-expand": "Çавăр",
        "thisisdeleted": "$1 пăхса каялла тавăрмалла-и?",
        "viewdeleted": "$1 пăхар-и?",
        "restorelink": "{{PLURAL:$1|кăларса пăрахнă тӳрлетнине|$1 кăларса пăрахнă тӳрлетнисене}}",
        "searchprofile-articles": "Статьясем",
        "searchprofile-images": "Мультимедиа",
        "searchprofile-everything": "Пур ҫӗрте",
-       "searchprofile-advanced": "Ð\90нлÓ\91лаÑ\82нÓ\91",
+       "searchprofile-advanced": "СаÑ\80лакаÑ\80аÑ\85",
        "searchprofile-articles-tooltip": "$1 -ре шырани",
        "searchprofile-images-tooltip": "Файăлсене шырани",
        "searchprofile-everything-tooltip": "Мӗнпур элсенче (сӳтсе явнинче те) шыра",
-       "searchprofile-advanced-tooltip": "ЯÑ\82аÑ\80лÓ\91 Ñ\8fÑ\82 Ñ\82алккÓ\91Ñ\88Ó\97сенче шыра",
+       "searchprofile-advanced-tooltip": "Ð\9fанÄ\83 Ñ\8fÑ\82 Ñ\85Ñ\83Ñ\88Ñ\88исенче шыра",
        "search-result-size": "$1 ({{PLURAL:$2|1 сăмах|$2 сăмах}})",
        "search-category": "(категори $1)",
        "search-interwiki-caption": "Тăван проектсем",
        "searchrelated": "çыхăнă",
        "showingresults": "Аяларах эсир <strong>$2</strong> пуçласа кăтартнă <strong>$1</strong> йĕркене куратăр.",
        "powersearch-legend": "Анлă шырав",
+       "powersearch-ns": "Ят хушшисенче шыра:",
+       "powersearch-togglelabel": "Тĕрĕсреххи:",
+       "powersearch-toggleall": "Пурне те",
        "powersearch-togglenone": "Нимĕнте",
        "search-external": "Тулти шырамалли",
        "preferences": "Ĕнерлевсем",
        "recentchanges-legend-plusminus": "(<em>±123</em>)",
        "recentchanges-submit": "Кăтарт",
        "rcfilters-legend-heading": "<strong>Кĕскетнисем:</strong>",
+       "rcfilters-other-review-tools": "Урăх пăхмаллисем",
+       "rcfilters-filterlist-title": "Фильтрсем",
+       "rcfilters-filter-editsbyself-label": "Хăвăр улăштарнисем",
+       "rcfilters-filter-editsbyother-label": "Урăххисем улăштарнисем",
        "rcfilters-filter-user-experience-level-newcomer-label": "Çĕнĕ хутшăнакансем",
+       "rcfilters-filter-user-experience-level-learner-label": "Вĕренекенсем",
+       "rcfilters-filtergroup-automated": "Автоматлă хушнисем",
+       "rcfilters-filter-bots-label": "Бот",
+       "rcfilters-filter-humans-label": "Çын (бот мар)",
+       "rcfilters-filtergroup-significance": "Пĕлтерни",
+       "rcfilters-filter-minor-label": "Кăштах тӳрлетнисем",
+       "rcfilters-filter-major-label": "Ахаль тӳрлетнисем",
+       "rcfilters-filter-categorization-label": "Категорине улăштарнисем",
+       "rcfilters-filtergroup-lastRevision": "Юлашки версисем",
+       "rcfilters-filter-lastrevision-label": "Хальхи верси",
+       "rcfilters-filter-previousrevision-label": "Юлашки верси мар",
        "rclistfrom": "$2, $3 тытăнса çĕнĕ улăшăнисене кăтартни",
        "rcshowhideminor": "пĕчĕк тӳрлетнисене $1",
        "rcshowhideminor-show": "кăтартмалла",
        "longpages": "Вăрăм страницăсем",
        "deadendpages": "Нимĕнпе те çыхăнман страницăсем",
        "protectedpages": "Хӳтĕленĕ страницăсем",
+       "protectedpages-filters": "Фильтрсем:",
        "protectedtitles": "Юраман ятсем",
        "listusers": "Хутшăнакансен списокĕ",
        "newpages": "Çĕнĕ страницăсем",
        "whatlinkshere-links": "← каçаканнисем",
        "whatlinkshere-hideredirs": "куçарнисене $1",
        "whatlinkshere-hidelinks": "Каçаканнисене $1",
-       "whatlinkshere-filters": "Ð\90ласем",
+       "whatlinkshere-filters": "ФилÑ\8cÑ\82Ñ\80сем",
        "whatlinkshere-submit": "Ту",
        "blockip": "{{GENDER:$1|хутшăнакана}} чар",
        "ipaddressorusername": "IP адрес е усă куракан ят:",
        "tooltip-pt-watchlist": "Эсир пăхакан страницисем",
        "tooltip-pt-mycontris": "Сирĕн хушнисем",
        "tooltip-pt-anoncontribs": "Ку IP адреспа тӳрлетнисем",
-       "tooltip-pt-login": "Ð\9aÓ\97ме ÐºÐ¸Ñ\80леÑ\85 Ð¼Ð°Ñ\80\85а Ñ\82а, Ð°Ñ\80а Ð°Ð²Ð°Ð½Ñ\80аÑ\85.",
+       "tooltip-pt-login": "Ð\90ккаÑ\83нÑ\82 Ñ\82Ñ\83Ñ\81а ÐºÄ\95Ñ\80Ä\95Ñ\80, ÐºÄ\95меÑ\81Ä\95Ñ\80 Ñ\82е Ñ\8eÑ\80аÑ\82Ñ\8c",
        "tooltip-pt-logout": "Сеансне пĕтер",
-       "tooltip-pt-createaccount": "Ð\90ккаÑ\83нÑ\82 Ñ\82Ñ\83 Ñ\82а Ñ\81иÑ\81Ñ\82емÓ\91на ÐºÓ\97Ñ\80. Ð\9fаллаÑ\85, Ñ\83нÑ\81Ó\91Ñ\80аÑ\85 Ñ\82а Ñ\8eÑ\80аÑ\82Ñ\8c, Ð°Ð½Ñ\87аÑ\85 Ñ\82а Ð°ÐºÐºÐ°Ñ\83нÑ\82па ÐºÓ\97ни Ð»Ð°Ð¹Ó\91Ñ\85Ñ\80аÑ\85.",
+       "tooltip-pt-createaccount": "Ð\9aÄ\95ме Ð°ÐºÐºÐ°Ñ\83нÑ\82 Ñ\82Ä\83вÄ\83Ñ\80, ÐºÄ\95меÑ\81Ä\95Ñ\80 Ñ\82е Ñ\8eÑ\80аÑ\82Ñ\8c",
        "tooltip-ca-talk": "Статьяна сӳтсе явасси",
        "tooltip-ca-edit": "Кăна тӳрлет",
        "tooltip-ca-addsection": "Çĕнĕ пай ту",
index f80e87f..dac9e07 100644 (file)
        "february": "Gucige",
        "march": "Adar",
        "april": "Nisane",
-       "may_long": "Gulan",
+       "may_long": "Gulane",
        "june": "Heziran",
        "july": "Temuz",
        "august": "Tebaxe",
        "february-gen": "Sıbat",
        "march-gen": "Adar",
        "april-gen": "Nisane",
-       "may-gen": "Gulan",
+       "may-gen": "Gulane",
        "june-gen": "Heziran",
        "july-gen": "Temuz",
        "august-gen": "Tebaxe",
        "jan": "Çel",
        "feb": "Sbt",
        "mar": "Adr",
-       "apr": "Lsn",
-       "may": "Gln",
+       "apr": "Nsn",
+       "may": "Gul",
        "jun": "Hez",
        "jul": "Tmz",
        "aug": "Tbx",
        "february-date": "$1 Sıbat",
        "march-date": "$1 Adar",
        "april-date": "$1 Nisane",
-       "may-date": "$1 Gulan",
+       "may-date": "$1 Gulane",
        "june-date": "$1 Heziran",
        "july-date": "$1 Temuze",
        "august-date": "$1 Tebaxe",
index f36c8ed..837e3b5 100644 (file)
        "unregistered-user-config": "For security reasons JavaScript, CSS and JSON user subpages cannot be loaded for unregistered users.",
        "passwordpolicies": "Password policies",
        "passwordpolicies-summary": "This is a list of the effective password policies for the user groups defined in this wiki.",
-       "passwordpolicies-helppage": "Manual:$wgPasswordPolicy",
        "passwordpolicies-group": "Group",
        "passwordpolicies-policies": "Policies",
        "passwordpolicies-policy-display": "<span class=\"passwordpolicies-policy\">$1 <code>($2)</code></span>",
index a9014c7..2fac3ff 100644 (file)
        "createacct-another-realname-tip": "El nombre real es opcional.\nSi lo proporcionas, se usará para dar atribución al trabajo del usuario.",
        "pt-login": "Acceder",
        "pt-login-button": "Acceder",
-       "pt-login-continue-button": "Continuar inicio de sesión",
+       "pt-login-continue-button": "Continuar con el acceso",
        "pt-createaccount": "Crear una cuenta",
        "pt-userlogout": "Salir",
        "php-mail-error-unknown": "Error desconocido en la función mail() de PHP.",
        "prefs-watchlist-edits": "Número máximo de ediciones a mostrar en la lista de seguimiento:",
        "prefs-watchlist-edits-max": "Cantidad máxima: 1000",
        "prefs-watchlist-token": "Clave de lista de seguimiento:",
-       "prefs-watchlist-managetokens": "Administrar tokens",
+       "prefs-watchlist-managetokens": "Gestionar fichas",
        "prefs-misc": "Varias",
        "prefs-resetpass": "Cambiar contraseña",
        "prefs-changeemail": "Cambiar o eliminar la dirección de correo electrónico",
index 9f97204..1ad9597 100644 (file)
@@ -15,7 +15,8 @@
                        "LNDDYL",
                        "唐吉訶德的侍從",
                        "飞舞回堂前",
-                       "Macofe"
+                       "Macofe",
+                       "Ruthven"
                ]
        },
        "tog-underline": "Lièn-chiap kâ-tái sien:",
index c5a9183..da04a90 100644 (file)
        "undelete-error": "שגיאה בשחזור דף",
        "undelete-error-short": "שגיאה בשחזור הקובץ: $1",
        "undelete-error-long": "שגיאות שאירעו בעת שחזור הקובץ:\n\n$1",
-       "undelete-show-file-confirm": "×\94×\90×\9d ×\90ת×\9d ×\91×\98×\95×\97×\99×\9d ×©×\91רצ×\95× ×\9b×\9d לצפות בגרסה המחוקה של הקובץ \"<nowiki>$1</nowiki>\" מ־$3, $2?",
+       "undelete-show-file-confirm": "×\94×\90×\9d ×\91רצ×\95× ×\9a לצפות בגרסה המחוקה של הקובץ \"<nowiki>$1</nowiki>\" מ־$3, $2?",
        "undelete-show-file-submit": "כן",
        "namespace": "מרחב שם:",
        "invert": "ללא מרחב זה",
        "tooltip-invert": "יש לסמן תיבה זו כדי להסתיר שינויים בדפים בתוך מרחב השם שנבחר (ובתוך מרחב השם הצמוד, אם הוא סומן)",
-       "tooltip-whatlinkshere-invert": "יש לסמן תיבה זו כדי להסתיר קישורים מדפים בתוך מרחב השם שנבחר",
+       "tooltip-whatlinkshere-invert": "יש לסמן תיבה זו כדי להסתיר קישורים מדפים בתוך מרחב השם שנבחר.",
        "namespace_association": "מרחב שם צמוד",
        "tooltip-namespace_association": "יש לסמן תיבה זו כדי לכלול גם את מרחב דפי השיחה או דפי הנושא המשויכים למרחב השם הנבחר",
        "blanknamespace": "(ראשי)",
        "sp-contributions-newonly": "הצגת עריכות שהן יצירות של דפים בלבד",
        "sp-contributions-hideminor": "הסתרת עריכות משניות",
        "sp-contributions-submit": "חיפוש",
-       "sp-contributions-outofrange": "לא ניתן להציג תוצאות. טווח ה־IP המבוקש גדול יותר ממגבלת ה־CIDR, שהיא /$1.",
+       "sp-contributions-outofrange": "לא ניתן להציג תוצאות. טווח ה־IP המבוקש גדול יותר ממגבלת ה־CIDR, שהיא <span dir=\"ltr\">/$1</span>.",
        "whatlinkshere": "דפים המקושרים לכאן",
        "whatlinkshere-title": "דפים המקשרים לדף \"$1\"",
        "whatlinkshere-page": "דף:",
-       "linkshere-2": "×\94×\93פ×\99×\9d ×©×\9c×\94×\9c×\9f ×\9eק×\95שר×\99×\9d ×\9c×\93×£ '''$1''':",
-       "nolinkshere-2": "×\90×\99×\9f ×\93פ×\99×\9d ×\94×\9eק×\95שר×\99×\9d ×\9c×\93×£ '''$1'''.",
-       "nolinkshere-ns-2": "×\90×\99×\9f ×\93פ×\99×\9d ×\94×\9eק×\95שר×\99×\9d ×\9c×\93×£ '''$1''' במרחב השם שנבחר.",
+       "linkshere-2": "×\94×\93פ×\99×\9d ×©×\9c×\94×\9c×\9f ×\9eקשר×\99×\9d ×\9c×\93×£ <strong>$1</strong>:",
+       "nolinkshere-2": "×\90×\99×\9f ×\93פ×\99×\9d ×\94×\9eקשר×\99×\9d ×\9c×\93×£ <strong>$1</strong>.",
+       "nolinkshere-ns-2": "×\90×\99×\9f ×\93פ×\99×\9d ×\94×\9eקשר×\99×\9d ×\9c×\93×£ <strong>$1</strong> במרחב השם שנבחר.",
        "isredirect": "דף הפניה",
        "istemplate": "הכללה",
        "isimage": "קישור לקובץ",
        "whatlinkshere-hidetrans": "$1 הכללות",
        "whatlinkshere-hidelinks": "$1 קישורים",
        "whatlinkshere-hideimages": "$1 קישורים לקובץ",
-       "whatlinkshere-filters": "×\9eסננ×\99×\9d",
+       "whatlinkshere-filters": "ס×\99× ×\95×\9f",
        "whatlinkshere-submit": "הצגה",
        "autoblockid": "חסימה אוטומטית #$1",
        "block": "חסימת משתמש",
        "unblock": "שחרור חסימה של משתמש",
        "blockip": "חסימת ה{{GENDER:$1|משתמש|משתמשת}}",
-       "blockiptext": "×\94שת×\9eש×\95 ×\91×\98×\95פס ×©×\9c×\94×\9c×\9f ×\9b×\93×\99 ×\9c×\97ס×\95×\9d ×\90ת ×\94רש×\90×\95ת ×\94×\9bת×\99×\91×\94 ×\9e×\9bת×\95×\91ת IP ×\90×\95 ×\9eשת×\9eש ×\9eס×\95×\99×\9e×\99×\9d.\n×\97ס×\99×\9e×\95ת ×\9b×\90×\9c×\94 ×¦×¨×\99×\9b×\95ת ×\9c×\94ת×\91צע ×¨×§ ×\9b×\93×\99 ×\9c×\9e× ×\95×¢ ×\94ש×\97ת×\94, ×\95×\91×\94ת×\90×\9d ×\9c[[{{MediaWiki:Policy-url}}|× ×\94×\9c×\99×\9d]].\n×\90× ×\90 ×\9e×\9c×\90×\95 ×\90ת ×\94ס×\99×\91×\94 ×\94פר×\98× ×\99ת ×\9c×\97ס×\99×\9e×\94 ×\9c×\94×\9c×\9f (×\9c×\93×\95×\92×\9e×\94, ×\91×\90×\9eצע×\95ת ×¦×\99×\95×\9f ×\93פ×\99×\9d ×\9eס×\95×\99×\9e×\99×\9d ×©×\94ש×\97×\99ת ×\94×\9eשת×\9eש).\n×\91×\90פשר×\95ת×\9b×\9d לחסום טווחי כתובות IP באמצעות תחביר [https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing CIDR]; הטווח הגדול ביותר שניתן לחסום הוא <span dir=\"ltr\">/$1</span> עבור IPv4 ו־<span dir=\"ltr\">/$2</span> עבור IPv6.",
+       "blockiptext": "× ×\99ת×\9f ×\9c×\94שת×\9eש ×\91×\98×\95פס ×©×\9c×\94×\9c×\9f ×\9b×\93×\99 ×\9c×\97ס×\95×\9d ×\90ת ×\94רש×\90×\95ת ×\94×\9bת×\99×\91×\94 ×\9e×\9bת×\95×\91ת IP ×\9eס×\95×\99×\9eת ×\90×\95 ×\9eש×\9d ×\9eשת×\9eש ×\9eס×\95×\99×\9d.\n×\97ס×\99×\9e×\95ת ×\9b×\90×\9c×\94 ×¦×¨×\99×\9b×\95ת ×\9c×\94ת×\91צע ×¨×§ ×\9b×\93×\99 ×\9c×\9e× ×\95×¢ ×\94ש×\97ת×\94, ×\95×\91×\94ת×\90×\9d ×\9c[[{{MediaWiki:Policy-url}}|× ×\94×\9c×\99×\9d]].\n×\99ש ×\9c×\9e×\9c×\90 ×\90ת ×\94ס×\99×\91×\94 ×\94פר×\98× ×\99ת ×\9c×\97ס×\99×\9e×\94 ×\9c×\94×\9c×\9f (×\9c×\93×\95×\92×\9e×\94, ×\91×\90×\9eצע×\95ת ×¦×\99×\95×\9f ×\93פ×\99×\9d ×\9eס×\95×\99×\9e×\99×\9d ×©×\94ש×\97×\99ת ×\94×\9eשת×\9eש).\n×\91×\90פשר×\95ת×\9a לחסום טווחי כתובות IP באמצעות תחביר [https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing CIDR]; הטווח הגדול ביותר שניתן לחסום הוא <span dir=\"ltr\">/$1</span> עבור IPv4 ו־<span dir=\"ltr\">/$2</span> עבור IPv6.",
        "ipaddressorusername": "כתובת IP או שם משתמש:",
        "ipbexpiry": "פקיעה:",
        "ipbreason": "סיבה:",
        "ipb-disableusertalk": "ביטול האפשרות של המשתמש לערוך את דף השיחה של עצמו בעת החסימה",
        "ipb-change-block": "חסימת המשתמש מחדש עם הגדרות אלה",
        "ipb-confirm": "אישור החסימה",
-       "badipaddress": "×\9eשת×\9eש ×\90×\95 ×\9bת×\95×\91ת IP ×©×\92×\95×\99×\99×\9d.",
+       "badipaddress": "×\9bת×\95×\91ת IP ×©×\92×\95×\99×\94",
        "blockipsuccesssub": "החסימה הושלמה בהצלחה",
-       "blockipsuccesstext": "{{GENDER:$1|המשתמש|המשתמשת}} [[Special:Contributions/$1|$1]] {{GENDER:$1|נחסם|נחסמה}}.\n\nראו את [[Special:BlockList|רשימת החסומים]] כדי לצפות בחסימות.",
-       "ipb-blockingself": "{{GENDER:|אתה עומד|את עומדת|אתם עומדים}} לחסום את {{GENDER:|עצמך|עצמך|עצמכם}}! האם {{GENDER:|אתה בטוח שאתה רוצה|את בטוחה שאת רוצה|אתם בטוחים שאתם רוצים}} לעשות את זה?",
-       "ipb-confirmhideuser": "{{GENDER:|אתה עומד|את עומדת|אתם עומדים}} לחסום משתמש עם האפשרות \"הסתרת משתמש\". זה יעלים את שם המשתמש בכל הרשימות ופעולות היומן. האם {{GENDER:|אתה בטוח שברצונך|את בטוחה שברצונך|אתם בטוחים שברצונכם}} לעשות את זה?",
+       "blockipsuccesstext": "{{GENDER:$1|המשתמש|המשתמשת}} [[Special:Contributions/$1|$1]] {{GENDER:$1|נחסם|נחסמה}}.<br />\nניתן לעיין ב[[Special:BlockList|רשימת החסומים]] כדי לצפות בחסימות.",
+       "ipb-blockingself": "החשבון שלך ייחסם! האם ברצונך לעשות זאת?",
+       "ipb-confirmhideuser": "החשבון ייחסם עם האפשרות \"הסתרת משתמש\". זה יעלים את שם המשתמש בכל הרשימות ופעולות היומן. האם ברצונך לעשות זאת?",
        "ipb-confirmaction": "אם {{GENDER:|אתה בטוח שברצונך|את בטוחה שברצונך|אתם בטוחים שברצונכם}} לעשות זאת, אנא {{GENDER:|סמן|סמני|סמנו}} את השדה \"{{int:ipb-confirm}}\" שמופיע למטה.",
        "ipb-edit-dropdown": "עריכת סיבות החסימה",
        "ipb-unblock-addr": "שחרור חסימה של $1",
index 31cf225..7c4f579 100644 (file)
        "protectedtitles-submit": "Leírások mutatása",
        "listusers": "Szerkesztők",
        "listusers-editsonly": "Csak a szerkesztéssel rendelkező szerkesztők mutatása",
+       "listusers-temporarygroupsonly": "Csak az ideiglenes szerkesztői csoportokban szereplő szerkesztők mutatása",
        "listusers-creationsort": "Rendezés létrehozási dátum szerint",
        "listusers-desc": "Rendezés csökkenő sorrendben",
        "usereditcount": "{{PLURAL:$1|egy|$1}} szerkesztés",
        "watchlistanontext": "Jelentkezz be a figyelőlistád megtekintéséhez és szerkesztéséhez.",
        "watchnologin": "Nem vagy bejelentkezve",
        "addwatch": "Hozzáadás a figyelőlistához",
-       "addedwatchtext": "A(z) „[[:$1]]” lapot és vitalapját hozzáadtam a [[Special:Watchlist|figyelőlistádhoz]].",
-       "addedwatchtext-talk": "A(z) „[[:$1]]” lapot és a hozzá tartozó tartalmi lapot hozzáadtam a [[Special:Watchlist|figyelőlistádhoz]].",
+       "addedwatchtext": "A(z) „[[:$1]]” lap és vitalapja hozzáadva a [[Special:Watchlist|figyelőlistádhoz]].",
+       "addedwatchtext-talk": "A(z) „[[:$1]]” lap és a hozzá tartozó tartalmi lap hozzáadva a [[Special:Watchlist|figyelőlistádhoz]].",
        "addedwatchtext-short": "Az oldal: \"$1\" hozzá lett adva a figyelőlistádhoz.",
        "removewatch": "Eltávolítás a figyelőlistáról",
-       "removedwatchtext": "A(z) „[[:$1]]” lapot és vitalapját eltávolítottam a [[Special:Watchlist|figyelőlistáról]].",
-       "removedwatchtext-talk": "A(z) „[[:$1]]” lapot és a hozzá tartozó tartalmi lapot eltávolítottam a [[Special:Watchlist|figyelőlistáról]].",
+       "removedwatchtext": "A(z) „[[:$1]]” lap és vitalapja eltávolítva a [[Special:Watchlist|figyelőlistádról]].",
+       "removedwatchtext-talk": "A(z) „[[:$1]]” lap és a hozzá tartozó tartalmi lap eltávolítva a [[Special:Watchlist|figyelőlistádról]].",
        "removedwatchtext-short": "Az oldal: \"$1\" el lett távolítva a figyelőlistádról.",
        "watch": "Lap figyelése",
        "watchthispage": "Lap figyelése",
        "watchlistedit-normal-legend": "Lapok eltávolítása a figyelőlistáról",
        "watchlistedit-normal-explain": "A figyelőlistádra felvett lapok címei alább láthatóak.\nHa el szeretnél távolítani egy címet, pipáld ki a mellette található jelölőnégyzetet, majd kattints „{{int:Watchlistedit-normal-submit}}” gombra.\nLehetőséged van a [[Special:EditWatchlist/raw|figyelőlista nyers változatának]] szerkesztésére is.",
        "watchlistedit-normal-submit": "A kijelöltek eltávolítása",
-       "watchlistedit-normal-done": "{{PLURAL:$1|A következő|A következő $1}} cikket eltávolítottam a figyelőlistádról:",
+       "watchlistedit-normal-done": "{{PLURAL:$1|A következő|A következő $1}} cikket eltávolítottuk a figyelőlistádról:",
        "watchlistedit-raw-title": "A nyers figyelőlista szerkesztése",
        "watchlistedit-raw-legend": "A nyers figyelőlista szerkesztése",
        "watchlistedit-raw-explain": "A figyelőlistádra felvett lapok az alábbi listában találhatók. A lista szerkeszthető;\nminden egyes sor egy figyelt lap címe. Ha kész vagy, kattints a lista alatt található\n„{{int:Watchlistedit-raw-submit}}” feliratú gombra. Használhatod a [[Special:EditWatchlist|hagyományos listaszerkesztőt]] is.",
        "watchlistedit-raw-titles": "A figyelőlistádon található cikkek:",
        "watchlistedit-raw-submit": "Mentés",
        "watchlistedit-raw-done": "A figyelőlistád változtatásait elmentettem.",
-       "watchlistedit-raw-added": "A {{PLURAL:$1|következő|következő $1}} cikket hozzáadtam a figyelőlistádhoz:",
-       "watchlistedit-raw-removed": "A {{PLURAL:$1|következő|következő $1}} cikket eltávolítottam a figyelőlistádról:",
+       "watchlistedit-raw-added": "A {{PLURAL:$1|következő|következő $1}} cikket hozzáadtuk a figyelőlistádhoz:",
+       "watchlistedit-raw-removed": "A {{PLURAL:$1|következő|következő $1}} cikket eltávolítottuk a figyelőlistádról:",
        "watchlistedit-clear-title": "A figyelőlista kiürítése",
        "watchlistedit-clear-legend": "Figyelőlista kiürítése",
        "watchlistedit-clear-explain": "Minden cím el lesz távolítva a figyelőlistádról",
        "unlinkaccounts-success": "A fiókok szétkapcsolva.",
        "authenticationdatachange-ignored": "A hitelesítő adatok változtatása nincs kezelve. Talán nincs beállítva szolgáltató?",
        "userjsispublic": "Figyelem: JavaScript-allapokon ne tárolj bizalmas adatokat, mivel minden felhasználó számára láthatóak.",
+       "userjsonispublic": "Figyelem: JSON-allapokon ne tárolj bizalmas adatokat, mivel minden felhasználó számára láthatóak.",
        "usercssispublic": "Figyelem: CSS-allapokon ne tárolj bizalmas adatokat, mivel minden felhasználó számára láthatóak.",
        "restrictionsfield-badip": "Érvénytelen IP-cím vagy -tartomány: $1",
        "restrictionsfield-label": "Engedélyezett IP-tartományok:",
        "pagedata-bad-title": "Érvénytelen cím: $1.",
        "unregistered-user-config": "Biztonsági okokból JavaScript, CSS és JSON szerkesztői alapok nem töltődnek be regisztrálatlan felhasználóknak.",
        "passwordpolicies": "Jelszóirányelvek",
+       "passwordpolicies-summary": "Ez egy lista a hatékony jelszóirányelvekről a wikin használt felhasználói csoportok szerint.",
        "passwordpolicies-group": "Csoport",
        "passwordpolicies-policies": "Irányelvek",
        "passwordpolicies-policy-minimalpasswordlength": "A jelszónak legalább $1 karakterből kell állnia",
        "passwordpolicies-policy-minimumpasswordlengthtologin": "A jelszónak legalább $1 karakterből kell állnia a bejelentkezéshez",
        "passwordpolicies-policy-passwordcannotmatchusername": "A jelszó nem lehet azonos a felhasználónévvel",
+       "passwordpolicies-policy-passwordcannotmatchblacklist": "A jelszó nem lehet azonos a feketelistán szereplő jelszavakkal.",
        "passwordpolicies-policy-maximalpasswordlength": "A jelszó legfeljebb $1 karakter hosszú lehet"
 }
index 19ad62b..1400381 100644 (file)
        "tog-hidecategorization": "Къайлаяха оагӀоний оагӀаташ",
        "tog-extendwatchlist": "Хьашеръе зéма хьаязъяьр шедола хувцамаш юкъелоацаш, тIехьара даь хувцамаш хинна ца Iеш.",
        "tog-usenewrc": "Хувцамех тоабаш е керда нийсдарашка а зéма хьаязъяьра чу а",
-       "tog-numberheadings": "Ше-шегIа номераш увттае кепакертошта",
+       "tog-numberheadings": "Ши-шегIа номераш увттае кепакертошта",
        "tog-showtoolbar": "Кечала панель хьахьокха хувцам беча хана",
-       "tog-editondblclick": "Ð\9dиÑ\81Ñ\8aе Ð¾Ð°Ð³Ó\80онаÑ\88 Ñ\88озза IоÑ\82Ó\80аÑ\82оÓ\80аеча (JavaScript)",
-       "tog-editsectiononrightclick": "Ð\9dийÑ\81де Ð´Ã¡ÐºÑ\8aа Ñ\88озза Ð´Ð°Ñ\85ка Ð°Ñ\8cÑ\82Ñ\82еÑ\85Ñ\8cаÑ\80а Ñ\82оIаеÑ\80 Ñ\82Ó\80аÑ\82оÓ\80айиÑ\87а Ð´Ã¡ÐºÑ\8aа Ñ\86IеÑ\80а Ñ\82Iа (JavaScript)",
-       "tog-watchcreations": "Зем беш йола оагIонашта а файлашта а тIатоха аз хьаяь оагIонаши чуяьккха файлаши",
-       "tog-watchdefault": "Зем беш йола оагIонашта а файлашта а тIатоха аз хийца оагIонаши файлай йоазонца сурташ оттадари",
-       "tog-watchmoves": "Зем беш йола оагIонашта а файлашта а тIатоха аз цIи хийца оагIонаши файлаши",
+       "tog-editondblclick": "Тоае Ð¾Ð°Ð³Ó\80онаÑ\88 Ñ\88озза Ñ\82Ó\80аÑ\82оÓ\80айича (JavaScript)",
+       "tog-editsectiononrightclick": "Тоаде Ð¾Ð°Ð³Iон Ð´Ã¡ÐºÑ\8aа Ñ\86Ñ\83н ÐºÐµÐ¿Ð°ÐºÐµÑ\80Ñ\82á Ð´Ð°Ñ\85килга Ð°Ñ\8cÑ\82Ñ\82еÑ\85Ñ\8cаÑ\80а Ñ\82оIаеÑ\80г Ñ\82Ó\80аÑ\82оÓ\80айиÑ\87а (JavaScript)",
+       "tog-watchcreations": "Зем беш йолча оагIонашта а файлашта а тIатоха аз хьаяь оагIонаши чуяьха хинна файлаши",
+       "tog-watchdefault": "Зем беш йолча оагIонашта а файлашта а тIатоха аз хийца оагIонаши файлах лаьцараши",
+       "tog-watchmoves": "Зем беш йолча оагIонашта а файлашта а тIатоха аз цIи хийца оагIонаши файлаши",
        "tog-watchdeletion": "Зем беш йола оагIонашта а файлашта а тIатоха аз дIаяьккха оагIонаши файлаши",
        "tog-minordefault": "Массаза зIамига долаш санна белгалде хувцамаш.",
        "tog-previewontop": "Хьалххе бӀаргтохар хьагойта хувцама кора хьалхашкахь",
        "tog-previewonfirst": "Хувцам бе аьнна дехьаваьлча хьалххе бӀаргтохар хьахьокха",
-       "tog-enotifwatchlistpages": "ЭлекÑ\82Ñ\80онни Ð¿Ð¾Ñ\87Ñ\82е Ð³Iолла Ñ\85оам Ð±Ðµ Ñ\81ога Ð½Ð°Ð³Ð°Ñ\85Ñ\8c аз зем беш йола оагIонаши файлаши цхьанне хийцача",
+       "tog-enotifwatchlistpages": "ЭлекÑ\82Ñ\80онни Ð¿Ð¾Ñ\88Ñ\82е Ð³Iолла Ñ\85оамбе Ñ\81ога аз зем беш йола оагIонаши файлаши цхьанне хийцача",
        "tog-enotifusertalkpages": "Электронни почте гIолла хоам бе сога са дувца оттадара оагIув хийцача",
        "tog-enotifminoredits": "ОагIонаштеи файлаштеи даь хинна хувцамаш геттара зIамига дале а хоам бе сога",
        "tog-enotifrevealaddr": "ДӀабӀаргадайта са поштан цӀай нахá дӀатӀаухача цхьа хӀама хайташ долча хоамаш чу",
        "tog-shownumberswatching": "Ер оагIув шоаш зембеча оагIонашта юкъеяьккха болча доакьошхой таьрахь хьагойта",
-       "tog-oldsig": "Хьа карара кулг яздар:",
-       "tog-fancysig": "Ð\9aÑ\83лг Ñ\8fздаÑ\80а Ñ\88ий Ð¹Ð¾Ð»Ð° Ð²Ð¸ÐºÐ¸-Ñ\80азмеÑ\82ка (авÑ\82омаÑ\82иÑ\87еÑ\81ки Ñ\82IаÑ\85Ñ\8cожаÑ\8fÑ\80г Ð¹оацаш)",
+       "tog-oldsig": "Хьа карара кулг яздар иштта да:",
+       "tog-fancysig": "Ð\9aÑ\83лг Ñ\8fздаÑ\80а Ñ\85Ñ\8cа Ñ\85Ñ\8cай Ð²Ð¸ÐºÐ¸-Ñ\80азмеÑ\82ка (Ñ\88и-Ñ\88егIа Ð±Ð¾Ð»Ð° Ñ\82IаÑ\82овжам Ð±оацаш)",
        "tog-uselivepreview": "Хьахьокха хьалххе бӀаргтохар оагӀув юха хьа а ца елаш",
        "tog-forceeditsummary": "ДIахьалхадаккха, нагахьа санна хувцама йоазонца сурт оттадара моттиг хьалъйизанза яле",
        "tog-watchlisthideown": "Аз даь хувцамаш зéма хьаязъяьра чура къайладаха",
        "tog-watchlisthidebots": "Боташ даь хувцамаш зéма хьаязъяьра чура къайладаха",
        "tog-watchlisthideminor": "ЗIамига хувцамаш зéма хьаязъяьра чура къайладаха",
        "tog-watchlisthideliu": "Ражача чубаьннабоацача доакъошхоша даь хувцамаш къайладаха зема хьаязъяьра чура",
-       "tog-watchlisthideanons": "ЦIийоацача доакъошхоша хувцамаш къайладаха зем бара хьаязъяьр чура",
+       "tog-watchlistreloadautomatically": "Ши-шегIа кердаювлийта зема хьаязъяьр фильтр хувц мел луча хана (JavaScript эша)",
+       "tog-watchlistunwatchlinks": "ТIатоха укх тайпара ({{int:Watchlist-unwatch}}/{{int:Watchlist-unwatch-undo}}) маркераш зем беш йола оагIонаш зема хьаязъяьрá чуяккха а цу чура араяккха а атта торо хургьйолаш (JavaScript эша)",
+       "tog-watchlisthideanons": "Дагара йоазув доацача доакъошхоша даь хувцамаш къайладаха зема хьаязъяьра чура",
        "tog-watchlisthidepatrolled": "Ха даь дола хувцамаш къайладаха зéма хьаязъяьра чу",
        "tog-watchlisthidecategorization": "ОагӀонашта оагIаташ тохар къайладаккха",
        "tog-ccmeonemails": "Сона хьатIаахийта аз доакъашхошта дIадахийта дола каьхатий кепаш",
-       "tog-diffonly": "Ма гойта оагIон чулоацам ши верси вIашидистара кIал",
+       "tog-diffonly": "Ма гойта оагIон чулоацам ши эрш вIаши юстача хана",
        "tog-showhiddencats": "Гойта къайла оагIаташ",
        "tog-useeditwarning": "Хоамбе хьадаь хувцамаш дӀа а ца яздеш аз болх дӀаберзабеча хана",
        "underline-always": "Даиман",
        "print": "Зарба тоха",
        "view": "Хьажар",
        "view-foreign": "Укх $1 сайта чу хьажа",
-       "edit": "Тоае",
+       "edit": "Тоаде",
        "edit-local": "Хувца локальни йоазонца сурт оттадар",
        "create": "Хьакхолла",
        "create-local": "ТIатоха локальни йоазонца сурт оттадар",
        "newmessageslinkplural": "{{PLURAL:$1|керда хоам}}",
        "newmessagesdifflinkplural": "{{PLURAL:$1|тӀехьара хувцам|999=тӀехьара хувцамаш}}",
        "youhavenewmessagesmulti": "Хьога кхаьчад керда хоамаш $1 чу",
-       "editsection": "нийсде",
+       "editsection": "тоае",
        "editold": "хувца",
        "viewsourceold": "Хьажа дIадолалу ко́дага",
        "editlink": "хувца",
        "nstab-special": "ГIулакха оагӀув",
        "nstab-project": "Проектах лаьца",
        "nstab-image": "Файл",
-       "nstab-mediawiki": "Хоамбар",
+       "nstab-mediawiki": "Хоам",
        "nstab-template": "Ло",
        "nstab-help": "Новкъостал",
        "nstab-category": "ОагӀат",
        "loginerror": "Доакъашхо вовзара гIалат",
        "mailmypassword": "Пароль тIеракхоссар",
        "mailerror": "Каьхат дIадохьийтача хана гӀалат хилар: $1",
+       "emailauthenticated": "Хьа электронни пошта цIай бакъдаьд (тIатоадаьд) укх хана: $3, $2.",
        "emailconfirmlink": "Бакъде хьай электронни пошта цIай",
        "loginlanguagelabel": "Мотт: $1",
        "pt-login": "Чувала/яла",
        "passwordreset-username": "Доакъашхочун цӀи:",
        "passwordreset-domain": "Домен:",
        "passwordreset-email": "Электронни почта адрес:",
+       "changeemail": "дIахувца е дIаяккха электронни пошт",
        "resettokens-tokens": "Токенаш:",
        "bold_sample": "Сома йоазон текст",
        "bold_tip": "Сома йоазон текст",
        "previousrevision": "← XьалхайоагIа",
        "nextrevision": "ТIехьайоагIа →",
        "currentrevisionlink": "ХIанзара верси",
-       "cur": "хӀанза.",
+       "cur": "карара",
        "next": "тӀехь.",
-       "last": "хьалха.",
+       "last": "хьалхара",
        "page_first": "цхьоаллагIа",
        "page_last": "тӀехьара",
        "histlegend": "Эрший хоржам: хьабелгалъе шун вIаши йиста безам бола оагIон эршаш, тIаккха тоIае '''{{int:compare-submit}}'''.<br />\nКхетавар: '''({{int:cur}})''' — карарча эршаи хержача эршаи юкъе йола башхалонаш; '''({{int:last}})''' — хьалха йоагIача эршаи хержача эршаи юкъе йола башхалонаш; '''{{int:minoreditletter}}''' — зIамига хувцамаш.",
        "searchresults": "Лахар чакхдоалаш корадаьр",
        "searchresults-title": "«$1» лахар",
        "notextmatches": "ОагIоний тексташта чу цхьатара хилар дац",
-       "prevn": "{{PLURAL:$1|1=Ñ\85Ñ\8cалÑ\85айогIаÑ\80\85Ñ\8cалÑ\85айогIаÑ\80аÑ\88}} $1",
-       "nextn": "{{PLURAL:$1|1=Ñ\82IеÑ\85Ñ\8cайоагIаÑ\80\82IеÑ\85Ñ\8cайоагIаÑ\80аÑ\88}} $1",
+       "prevn": "{{PLURAL:$1|1=Ñ\85Ñ\8cалÑ\85айогIаÑ\87а|Ñ\85Ñ\8cалÑ\85айогIаÑ\87а}} $1-ннега",
+       "nextn": "{{PLURAL:$1|1=Ñ\82IеÑ\85Ñ\8cайоагIаÑ\87а|Ñ\82IеÑ\85Ñ\8cайоагIаÑ\87а}} $1-ннега",
        "prevn-title": "{{PLURAL:$1|ХьалхадоагIа $1 дIаяздар}}",
        "nextn-title": "{{PLURAL:$1|ТIадоагIа $1 яздар|ТIадоагIа $1 яздараш}}",
        "shown-title": "Гойта $1 {{PLURAL:$1|яздаьр|яздаьраш}} укх оáгIон тIа",
        "searchprofile-images-tooltip": "Файлаш лахар",
        "searchprofile-everything-tooltip": "Массайолча оагIонаш тIа лахар (дувцара оагIонаш чу а лоацаш)",
        "searchprofile-advanced-tooltip": "Лаха хьахержача цIерий аренашка",
-       "search-result-size": "$1 ({{PLURAL:$2|$2 дош|$2 дешаш}})",
+       "search-result-size": "$1 ({{PLURAL:$2|$2 дош}})",
        "search-result-category-size": "$1 {{PLURAL:$1|юкъедахар}} ($2 {{PLURAL:$2|кIалоагIат}}, $3 {{PLURAL:$3|файл}})",
        "search-redirect": "($1 яхача оагIон тIара дIа-хьа хьожадар)",
        "search-section": "(дáкъа «$1»)",
        "powersearch-toggleall": "Деррига",
        "powersearch-togglenone": "Цхьаккха",
        "powersearch-remember": "Дагалáца хержар кхы тӀехьагӀа лохача хана накъадаргдолаш",
-       "preferences": "Ð\93IиÑ\80Ñ\81 Ñ\82оаÑ\8fÑ\80аш",
+       "preferences": "Ð\9eÑ\82Ñ\82амаш",
        "mypreferences": "Оттамаш",
+       "prefs-edits": "Тоадарий дукхал:",
        "prefs-skin": "ТIера кийчдара тема",
        "skin-preview": "Хьалххе бIаргтохар",
        "prefs-user-pages": "Доакъашхочун оагIонаш",
-       "prefs-personal": "Доакъашхочун дараш",
-       "prefs-rc": "Керда нийсдараш",
-       "prefs-watchlist": "Зéма хьаязъяьр",
+       "prefs-personal": "Доакъашхочун хьакъехьа",
+       "prefs-rc": "Дукха ха йоаццаш тоадаьр",
+       "prefs-watchlist": "Зем",
+       "prefs-editwatchlist": "Зема хьаязъяьр хувцар",
+       "prefs-editwatchlist-label": "Шун зема хьаязъяьра чура яздараш хувцар",
+       "prefs-editwatchlist-edit": "Хьа зема хьаязъяьра чура цIерашка хьажар а уж дIаяхар",
+       "prefs-editwatchlist-raw": "Текст санна зема хьаязъяьр хувцар",
+       "prefs-editwatchlist-clear": "IоцIенъе зема хьаязъяьр",
        "prefs-watchlist-days": "Дéной дукхал:",
-       "prefs-resetpass": "Хувца къайладIоагIа",
+       "prefs-watchlist-edits": "Эггара дукхагIа тоадаьрий массал, зема хьаязъяьра чу хьахьокха йиш йола",
+       "prefs-watchlist-edits-max": "Эггара дукхагIа: 1000",
+       "prefs-watchlist-token": "Зема хьаязъяьра токен:",
+       "prefs-resetpass": "ДIахувца пароль",
+       "prefs-changeemail": "дIахувца е дIаяккха электронни пошт",
+       "prefs-setemail": "Электронни пошта цIай дӀаоттадар",
+       "prefs-email": "Электронни поштан оттамаш",
        "prefs-rendering": "ТIера куц",
        "saveprefs": "ДIаязде",
-       "prefs-editing": "Хувцам",
+       "restoreprefs": "Юхадоаладе юххьанцара хинна оттамаш",
+       "prefs-editing": "Тоадар",
        "searchresultshead": "Лахаp",
+       "stub-threshold": "Кечамий тIатовжамаш хьакийчдар оттадарá доазув ($1):",
+       "stub-threshold-sample-link": "масала",
+       "recentchangesdays": "Масса дийнахь даь керда хувцамаш хьахьокха деза:",
+       "recentchangescount": "Тайп-тайпара хьаязъяьрашка хьагуш дола тоадаьрий дукхал",
+       "prefs-help-recentchangescount": "Эггара дукхагIа: 1000",
+       "prefs-help-watchlist-token2": "Ер хьа зема хьаязъяьра веб-канала къайла дIоагIа да.\nИз дIайханачунна аьттув хургба хьа зема хьаязъяьр еша, цу бахьан дIа ма хайта из кхычарга.\nЭшаш дале нагахь санна, [[Special:ResetTokens|хьа йиш из тIеракхосса]].",
        "timezonelegend": "Сахьата оаса:",
-       "localtime": "Моттига ха:",
+       "localtime": "Меттигара ха:",
+       "timezoneuseserverdefault": "Сервера ($1) оттамаш леладе",
+       "timezoneuseoffset": "Кхыдар (белгалде ха меттахьялар)",
+       "servertime": "Сервера ха:",
+       "guesstimezone": "Браузера чура оттамаш леладе",
        "timezoneregion-africa": "Африка",
        "timezoneregion-america": "Америка",
        "timezoneregion-antarctica": "Антарктика",
        "timezoneregion-arctic": "Арктика",
        "timezoneregion-asia": "Ази",
-       "timezoneregion-atlantic": "Ð\9cалÑ\85бÑ\83зеÑ\80а Ð¾ÐºÐµÐ°Ð½",
+       "timezoneregion-atlantic": "Ð\9cалÑ\85бÑ\83зеÑ\80а Ð¾Ð°ÐºÐ°Ñ\84оÑ\80д",
        "timezoneregion-australia": "Астрали",
        "timezoneregion-europe": "Европа",
-       "timezoneregion-indian": "ХIиндий океан",
-       "timezoneregion-pacific": "Тийна океан",
+       "timezoneregion-indian": "ХIиндий оакафорд",
+       "timezoneregion-pacific": "Тийна оакафорд",
+       "allowemail": "Могадайта кхыча доакъашхошка сайна каьхат ахийта электронни поште гIолла",
+       "email-allow-new-users-label": "Могадайта дукха ха яьланза кердача доакъашхошка сайна каьхат ахийта электронни поште гIолла",
+       "email-blacklist-label": "ХьатIа ма ахийта сона каьхаташ электронни поште гIолла укх доакъашхошкара:",
        "prefs-searchoptions": "Лахар",
        "prefs-namespaces": "ЦIерий моттигаш",
+       "default": "юххьанцара хиннача тайпара",
        "prefs-files": "Файлаш",
-       "youremail": "Электронни почта:",
+       "prefs-custom-css": "Доалахь йола CSS",
+       "prefs-custom-js": "Доалахь йола JS",
+       "prefs-common-config": "Юкъара йола CSS/JSON/JavaScript массайолча кийчдара темашта:",
+       "prefs-emailconfirm-label": "Электронни пошт тIатоаяр:",
+       "youremail": "Электронни пошт:",
        "username": "{{GENDER:$1|Доакъашхочун цӀи}}:",
+       "prefs-memberingroups": "{{GENDER:$2|Дáкъа лоацаш ва|Дáкъа лоацаш я}} {{PLURAL:$1|1=укх тоаба чу|укх тоабашка}}:",
+       "prefs-registration": "Дагара йоазув кхелла ха:",
        "yourrealname": "Бокъонца йола цIи:",
        "yourlanguage": "Мотт:",
+       "yournick": "Керда кулг яздар:",
+       "prefs-help-signature": "Дувцара оагIонаш чу шоай къамаьла тIехьа кулг язде деза ер «<nowiki>~~~~</nowiki>» диъ хьарак оттадаь, цунах тIаккха хьахул шун кулг яздари хаи (сахьати миноташи).",
+       "yourgender": "Мишта аьлча бакъахьа да хьох?",
+       "gender-unknown": "МаIа е кхал хилар белгалцадахар",
        "gender-male": "ВикиоагIонаш тоаеш ва из",
        "gender-female": "ВикиоагIонаш тоаеш я из",
+       "prefs-help-gender": "Укхаза оттадаьр ражо леладергда шуга йистхулача хана шо маIа да е кхал да хьежжа.\nМассанена ховш а бIаргагуш а хургда уж оттамаш.",
        "email": "Email",
        "prefs-help-email": "Электронни почта адрес оттаде параз дац, амма из эшаш хургда, нагахьа санна хьона хьа къайладIоагIа дицлой.",
        "prefs-help-email-others": "Иштта цунца кхыболча доакъашхошта аьттув хургба шоаца бувзам бе а, шун оагIон тIа е шун дувца оттадара оагIон тIа йола тIахьожаяргаца.\nШун электронни почта адрес цхьаннена гуш хургъяц.",
+       "prefs-info": "Кертера дараш",
+       "prefs-i18n": "Меттаца дувзаденнар",
        "prefs-signature": "Кулг яздар",
+       "prefs-dateformat": "Таьрахьа формат",
+       "prefs-timeoffset": "Хáна оттамаш",
+       "prefs-advancedediting": "Юкъара параметраш",
+       "prefs-developertools": "Кийчдархочун кечалаш",
        "prefs-preview": "Хьалххе бIаргтохар",
+       "prefs-advancedrc": "Кхыдола шердаь оттамаш",
+       "prefs-opt-out": "Алсамдалар тIацаэцар",
+       "prefs-advancedrendering": "Кхыдола шердаь оттамаш",
+       "prefs-advancedsearchoptions": "Шердаь оттамаш",
+       "prefs-advancedwatchlist": "Кхыдола шердаь оттамаш",
+       "prefs-diffs": "Эрший башхало",
        "userrights-user-editname": "Iочуязъе доакъашхочун цӀи:",
        "editusergroup": "Йотта доакъашхой тоабаш",
        "saveusergroups": "ДIаязъе {{GENDER:$1|доакъашхочун}} тоабаш",
        "userrights-unchangeable-col": "Хьа хувца йиш йоаца тоабаш",
        "group": "Тоаба:",
        "group-user": "Доакъашхой",
+       "group-autoconfirmed": "АвтохьатӀаийца доакъашхой",
        "group-bot": "Бóташ",
        "group-sysop": "Администратораш",
+       "group-bureaucrat": "Бюрократаш",
        "group-all": "(деррига)",
        "group-user-member": "{{GENDER:$1|доакъашхо}}",
+       "group-autoconfirmed-member": "{{GENDER:$1|автохьатӀаийца доакъашхо}}",
        "group-bot-member": "{{GENDER:$1|бот}}",
        "group-sysop-member": "{{GENDER:$1|администратор}}",
        "grouppage-user": "{{ns:project}}:Доакъашхой",
+       "grouppage-autoconfirmed": "{{ns:project}}:АвтохьатӀаийца доакъашхой",
        "grouppage-bot": "{{ns:project}}:Боташ",
        "grouppage-sysop": "{{ns:project}}:Администратораш",
+       "grouppage-bureaucrat": "{{ns:project}}:Бюрократаш",
        "right-read": "оагӀонашка хьажар",
        "right-edit": "оагӀонаш нийсъяр",
        "right-createtalk": "дувца оттадара оагӀонаш кхоллар",
        "recentchanges-label-plusminus": "байташкахь боарам хувцар",
        "recentchanges-legend-heading": "<strong>Легенда:&nbsp;</strong>",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (хьажа иштта [[Special:NewPages|керда оагIонашка]])",
+       "rcfilters-activefilters": "Хьалотаяь фильтраш",
+       "rcfilters-advancedfilters": "Шеръяь фильтраш",
+       "rcfilters-quickfilters": "Ӏалашъяь фильтраш",
+       "rcfilters-quickfilters-placeholder-title": "Ӏалашъяь фильтраш хIанзехьа яц",
+       "rcfilters-quickfilters-placeholder-description": "Фильтра оттамаш дIаяздергдолаши тIехьагIа царех юха а пайда эцаргболаши, лохегIа «Активни фильтр» яздаьча моттиге юкъеехкарг белгалъеча хьарака IотIатоIае.",
+       "rcfilters-savedqueries-defaultlabel": "Ӏалашъяь фильтраш",
+       "rcfilters-savedqueries-rename": "ЦIи хувца",
+       "rcfilters-savedqueries-setdefault": "Ше хиннача тайпара дIаоттаде",
+       "rcfilters-savedqueries-unsetdefault": "Ше хиннача тайпах яр дIаяккха",
+       "rcfilters-savedqueries-remove": "ДIаяккха",
+       "rcfilters-savedqueries-new-name-label": "ЦIи",
+       "rcfilters-filter-bots-label": "Бот",
+       "rcfilters-filter-bots-description": "Авто-кечалашца даь тоадар.",
+       "rcfilters-filter-humans-label": "Саг ва (бот яц)",
+       "rcfilters-filter-pageedits-label": "ОагӀона тоадаьраш",
+       "rcfilters-filter-newpages-label": "JагӀонаш кхоллар",
+       "rcfilters-filter-newpages-description": "Керда оагӀонаш кхолла аьнна даь тоадар.",
+       "rcfilters-liveupdates-button": "Ше-шегIа кердадахийта",
+       "rcfilters-liveupdates-button-title-on": "ДIадоаде ше-шегIа кердадахар",
+       "rcfilters-liveupdates-button-title-off": "Керда хувцам бешше хьахьокха",
+       "rcfilters-preference-label": "Къайлаяккха «Керда хувцамий» толашагIа йола эрш",
+       "rcfilters-preference-help": "Юхатотта 2017 шера хинна интерфейса редизайн а цу хана тӀатеха кечалаш а.",
        "rcnotefrom": "КIалхагIа {{PLURAL:$5|хувцам белгалбаьккхаб}} <strong>$3, $4</strong> тIера (хьахьекхабац <strong>$1</strong>-л дукхагIа).",
        "rclistfrom": "$3 $2 денза даь хувцамаш хьахьокха",
-       "rcshowhideminor": "$1 Ð·Iамига Ð½Ð¸Ð¹Ñ\81даÑ\80аÑ\88",
+       "rcshowhideminor": "$1 Ð·Iамига Ð´Ð¾Ð»Ð° Ñ\82оадаÑ\80",
        "rcshowhideminor-show": "Хьахьокха",
        "rcshowhideminor-hide": "Къайладаккха",
        "rcshowhidebots": "$1 боташ",
        "rcshowhideliu": "$1 ражача дӏаэтта доакъашхой",
        "rcshowhideliu-show": "Хьахьокха",
        "rcshowhideliu-hide": "Къайлабаха",
-       "rcshowhideanons": "$1 цIияккханза доакъашхой",
+       "rcshowhideanons": "$1 Ñ\88оай Ñ\86IиÑ\8fккÑ\85анза Ð´Ð¾Ð°ÐºÑ\8aаÑ\88Ñ\85ой",
        "rcshowhideanons-show": "Хьахьокха",
        "rcshowhideanons-hide": "Къайлабаха",
        "rcshowhidepatr": "$1 техка хувцамаш",
        "rcshowhidepatr-show": "Хьахьокха",
        "rcshowhidepatr-hide": "Къайладаккха",
-       "rcshowhidemine": "$1 хьа нийсдараш",
+       "rcshowhidemine": "$1 Iайха тоадаьраш",
        "rcshowhidemine-show": "Хьахьокха",
        "rcshowhidemine-hide": "Къайладаккха",
        "rclinks": "Хьахьокха $2 дийнахь даь хинна тIеххьара $1 хувцамаш",
        "recentchangeslinked": "ВIашагIдувзаденна нийсдараш",
        "recentchangeslinked-feed": "ВIашагIдувзаденна нийсдараш",
        "recentchangeslinked-toolbox": "ВIашагIдувзаденна хувцамаш",
-       "recentchangeslinked-title": "$1ца вIашидувзаденна хувцамаш",
+       "recentchangeslinked-title": "$1ца вIаши дувзаденна хувцамаш",
        "recentchangeslinked-summary": "Ӏочуязъе оагӀон цӀи, цунна тӀатовжаш йолча оагӀонаш чу даь дола хувцамаш бӀаргагургдолаш (ОагӀата доакъашхой бӀаргагургболаш Ӏочуязъе {{ns:category}}:ОагӀата цӀи).\n[[Special:Watchlist|Хьа зéма хьаязъяьрá]] юкъейоагӀача оагӀонаш чу даь хувцамаш <strong>сомача лапӀазаца</strong> белгалдаь да.",
        "recentchangeslinked-page": "ОагIон цIи",
        "recentchangeslinked-to": "Вешта, белгаляьккха оагIон тIахьожавеш дола оагIонашта даь хувцамаш хьахьокха.",
        "statistics": "ГӀулакх-хьал",
        "statistics-articles": "Статьяш",
        "statistics-pages": "ОагIонаш",
+       "statistics-users-active": "Хьинаре доакъашхой",
        "double-redirect-fixer": "ДӀа-хьа хьожавара оагIонаш тоаер",
        "brokenredirects-edit": "нийсъе",
        "brokenredirects-delete": "дӀаяккха",
        "withoutinterwiki-submit": "Хьахьокха",
        "nbytes": "$1 {{PLURAL:$1|байт}}",
        "nmembers": "$1 {{PLURAL:$1|объект}}",
-       "prefixindex": "Ð\9eагÓ\80оний Ñ\86Ó\80еÑ\80ий Ð´ÐµÑ\88Ñ\85Ñ\8cалÑ\85ех хьахокхар",
+       "prefixindex": "Ð\9eагÓ\80онаÑ\88 Ñ\88оай Ñ\86Ó\80еÑ\80ий Ñ\85Ñ\8cалÑ\85аÑ\80Ñ\87а Ð°Ð»Ð°Ð¿Ð°х хьахокхар",
        "prefixindex-namespace": "ОагӀоний цӀераш шоай дешхьалхех хьахьокхар (цIерий моттиг «{{ns:$1}}»)",
+       "prefixindex-submit": "Хьахьокха",
+       "prefixindex-strip": "ДIакъайлаяха хьелехача оагIоний дешхьалхенаш (префиксаш)",
        "shortpages": "Лоаца оагIонаш",
        "longpages": "ЙIаьха оагIонаш",
        "protectedpages-page": "ОагIув",
        "allpagesto": "Хьахьокхар соцадé укхун тӀа:",
        "allarticles": "Еррига оагIонаш",
        "allpagessubmit": "Кхоачашде",
+       "allpagesprefix": "Хьалаха оагӀонаш, дӀайолалуш йола укх алапах:",
        "allpages-hide-redirects": "ДIакъайладаха дӀа-хьа хьожавераш",
        "categories": "ОагӀаташ",
+       "categories-submit": "Хьахьокха",
        "linksearch": "Арахьара тIахьожаяргаш лахар",
        "linksearch-ns": "ЦIерий моттигаш:",
        "linksearch-ok": "Хьалаха",
        "linksearch-line": "$1 яхача оагIонна тIатовжам $2 чура",
+       "activeusers": "Хьинаре доакъашхой",
+       "activeusers-submit": "Хьахьокха хьинаре бола доакъашхой",
+       "listgrouprights": "Доакъашхой тоабай бокъонаш",
        "listgrouprights-members": "(доакъашхой хьаязъяьр)",
        "listgrouprights-namespaceprotection-namespace": "ЦIерий моттиг",
        "emailuser": "Доакъашхочоа каьхат",
        "delete-legend": "ДӀаяккхар",
        "confirmdeletetext": "Оаш дIадийхад бIарчча дIадаккхар оагIон а (е сурта), цун деррига хувцара истори а. '''Дехар да''', бакъде шоай из бокъонца де безам болаш долга а, из дича хургдар кхеташ долга а, из дар укх [[{{MediaWiki:Policy-url}}|бокъонашца]] долга.",
        "actioncomplete": "Ардам кхоачашдаьд",
-       "actionfailed": "Ð\90Ñ\80дам Ðºхоачашдаьдац",
+       "actionfailed": "Ð\9aхоачашдаьдац",
        "deletedtext": "«$1» дIаяьккхай.\nХьажа $2 тIехьара дIадаккхарий хьаязъяьрга бIаргтохаргболаш.",
        "dellogpage": "ДӀадаккхарий тептар",
        "deletecomment": "Бахьан:",
        "protect-cantedit": "Хьа хувца йиш яц укх оагIон лорадара лагIа, цун хувцам бе хьа бокъо ца хиларах.",
        "restriction-type": "Бокъонаш:",
        "restriction-level": "ТIакхоачилга лагIа:",
-       "restriction-edit": "Хувцам",
+       "restriction-edit": "Хувцар",
        "restriction-move": "ЦIи хувцаp",
        "restriction-create": "Хьакхоллар",
        "restriction-upload": "Доттар",
        "isredirect": "дIа-хьа хьожавара оагIув",
        "istemplate": "юкъейоалаяр",
        "isimage": "Файлови тӏатовжам",
-       "whatlinkshere-prev": "{{PLURAL:$1|1=хьалхайоагIа|хьалхайоагIараш}} $1",
-       "whatlinkshere-next": "{{PLURAL:$1|1=Ñ\82IеÑ\85Ñ\8cайоагIаÑ\80\82IеÑ\85Ñ\8cайоагIаÑ\80аÑ\88}} $1",
+       "whatlinkshere-prev": "{{PLURAL:$1|1=хьалхайоагIача|хьалхайоагIача}} $1-ннега",
+       "whatlinkshere-next": "{{PLURAL:$1|1=Ñ\82IеÑ\85Ñ\8cайоагIаÑ\87а|Ñ\82IеÑ\85Ñ\8cайоагIаÑ\87а}} $1-ннега",
        "whatlinkshere-links": "← тӏатовжамаш",
        "whatlinkshere-hideredirs": "$1 дӀа-хьа хьожавараш",
        "whatlinkshere-hidetrans": "$1 юкъедоаладаьраш",
        "tooltip-ca-nstab-help": "Новкъостала оагIув",
        "tooltip-ca-nstab-category": "ОагӀата оагӀув",
        "tooltip-minoredit": "Ер хувцар кIезига дар санна белгалде",
-       "tooltip-save": "Ð¥Ñ\8cа Ñ\85Ñ\83вÑ\86амаÑ\88 Ð»Ð¾Ñ\80адеÑ\88 Ð´IаÑ\8fзде",
+       "tooltip-save": "Ð\94IаÑ\8fзде Ñ\85Ñ\8cай Ñ\85Ñ\83вÑ\86амаÑ\88",
        "tooltip-preview": "ОагIонна хьалххе бIаргтохар.\nДехар да, оагӀув дIаязъелехь хьажа из мишта я!",
        "tooltip-diff": "Чухьнахьара текстаца даь хувцамаш хьахьокха",
        "tooltip-compareselectedversions": "Укх оагIон хержа шин версешта юкъе йола башхалога хьажа.",
        "patrol-log-page": "ТӀахьожама тептар",
        "previousdiff": "← КъаьнагIа дола нийсдаьр",
        "nextdiff": "КердагӀа дола нийсдаьр →",
+       "imagemaxsize": "Сурта боарамá доазув тохар:<br />''(Файлах лаьца дувцача оагӀона)''",
+       "thumbsize": "Сурта зIамагIа йолча эрша боарам:",
        "widthheightpage": "$1 × $2, $3 {{PLURAL:$3|оагӀув}}",
        "file-info-size": "$1 × $2 {{PLURAL:$2|пиксель}}, файла боарам: $3, MIME-тайпа: $4",
        "file-info-size-pages": "$1 × $2 пиксель, файлан боарам: $3, MIME-тайп: $4, $5 {{PLURAL:$5|1=оагӀув}}",
        "imgmultigo": "Дехьавала!",
        "imgmultigoto": "$1 оагIон тIа дехьавала",
        "table_pager_limit_submit": "Кхоачашде",
+       "watchlistedit-normal-title": "Зема хьаязъяьр хувцар",
        "watchlisttools-clear": "IоцIанъе зем бара хьаязъяьр",
        "watchlisttools-view": "Хьаязъяьр чура оагIонаш тIа дола хувцамаш",
        "watchlisttools-edit": "Хьажа а хувца а хьаязъяьр",
        "specialpages-group-users": "Доакъашхойи бокъонаши",
        "specialpages-group-pages": "ОагIонай хьаязъяьраш",
        "specialpages-group-pagetools": "ОагIонашта эша кечалаш",
+       "specialpages-group-developer": "Кийчдархочун кечалаш",
        "external_image_whitelist": "#Ер мугI ший болча тайпара бита<pre>\n#Укхаз оттаде кастта дувлача выражений фрагменташ (// юкъе дола дакъа)\n#арахьара суртий URL адресашца дIанийсалургда уш.\n#Мегаргдола сурташ санна хьахьекха хургда, дIаходараш, сурташта тIахьожаяргаш санна хьахьекха хургда.\n#Укханца # долалуш дола могIараш алараш санна лоархIаш да.\n#МогIараш регистраца кIаьда дац\n\n#Укх могIара лакхе оттаде кастта дувлача выражений фрагменташ. Ер мугI ший болча тайпара бита</pre>",
        "tag-filter": "[[Special:Tags|Белгалонай]] фильтр:",
        "tag-filter-submit": "Литта",
        "tags-delete": "дӀаяккха",
        "tags-hitcount": "$1 {{PLURAL:$1|1=хувцам|хувцамаш}}",
        "tags-create-submit": "Хьакхолла",
+       "tags-deactivate-submit": "ДӀайоае",
        "compare-page1": "ЦхьоаллагIа оагIув",
        "compare-page2": "ШоллагIа оагӀув",
        "compare-rev1": "Хьалхара эрш",
        "duration-days": "{{PLURAL:$1|ди}}",
        "expand_templates_preview": "Хьалххе бIаргтохар",
        "pagelang-name": "ОагIув",
+       "pagelang-language": "Мотт",
        "special-characters-group-latin": "Латиний",
        "special-characters-group-greek": "Эллиной",
        "special-characters-group-cyrillic": "Кириллица",
index 255781a..71eeb45 100644 (file)
        "recentchangescount": "Numero di modifiche da mostrare nelle ultime modifiche, cronologie e registri, per impostazione predefinita:",
        "prefs-help-recentchangescount": "Numero massimo: 1000",
        "prefs-help-watchlist-token2": "Questa è la chiave segreta per il feed web dei tuoi osservati speciali.\nChiunque la conosce sarà in grado di leggere i tuoi osservati speciali, per cui non condividerla. Se necessario, [[Special:ResetTokens|puoi reimpostarla]].",
-       "prefs-help-tokenmanagement": "Puoi visualizzare e reimpostare la chiave segreta per la tua utenza con cui puoi accedere al feed web dei tuoi osservati speciali. Chiunque conosce la chiave sarà in grado di leggere i tuoi osservati speciali, quindi non condividerla.",
+       "prefs-help-tokenmanagement": "Puoi visualizzare e reimpostare la chiave segreta per la tua utenza con cui puoi accedere al feed web dei tuoi osservati speciali. Chiunque conosca la chiave sarà in grado di leggere i tuoi osservati speciali, quindi non condividerla.",
        "savedprefs": "Le preferenze sono state salvate.",
        "savedrights": "I gruppi utente di {{GENDER:$1|$1}} sono stati salvati.",
        "timezonelegend": "Fuso orario:",
        "protectedtitles-submit": "Mostra titoli",
        "listusers": "Elenco degli utenti",
        "listusers-editsonly": "Mostra solo utenti con dei contributi",
+       "listusers-temporarygroupsonly": "Mostra solo utenti in gruppi utenti temporanei",
        "listusers-creationsort": "Ordina per data di creazione",
        "listusers-desc": "Ordina in senso decrescente",
        "usereditcount": "$1 {{PLURAL:$1|contributo|contributi}}",
        "pagedata-not-acceptable": "Nessun formato corrispondente trovato. Tipi MIME supportati: $1",
        "pagedata-bad-title": "Titolo non valido: $1.",
        "unregistered-user-config": "Per motivi di sicurezza, non è possibile caricare sottopagine utente JavaScript, CSS e JSON per utenti non registrati.",
-       "passwordpolicies-group": "Gruppo"
+       "passwordpolicies-group": "Gruppo",
+       "passwordpolicies-policy-minimalpasswordlength": "La password deve essere lunga almeno $1 {{PLURAL:$1|carattere|caratteri}}",
+       "passwordpolicies-policy-minimumpasswordlengthtologin": "La password deve essere lunga almeno $1 {{PLURAL:$1|carattere|caratteri}} per poter accedere",
+       "passwordpolicies-policy-passwordcannotmatchusername": "La password non può essere uguale al nome utente",
+       "passwordpolicies-policy-passwordcannotmatchblacklist": "La password non può corrispondere a password specificate nell'elenco delle password proibite",
+       "passwordpolicies-policy-maximalpasswordlength": "La password deve essere lunga meno di $1 {{PLURAL:$1|carattere|caratteri}}",
+       "passwordpolicies-policy-passwordcannotbepopular": "La password non può essere {{PLURAL:$1|la password più popolare|nell'elenco delle $1 password più popolari}}"
 }
index aa1d5a5..ab3733a 100644 (file)
@@ -70,7 +70,8 @@
                        "렌즈",
                        "CYAN",
                        "Nuevo Paso",
-                       "Doyoon1995"
+                       "Doyoon1995",
+                       "Jay94ks"
                ]
        },
        "tog-underline": "링크에 밑줄 긋기:",
        "subject-preview": "주제 미리 보기:",
        "previewerrortext": "변경사항을 미리보기하는 도중 오류가 발생했습니다.",
        "blockedtitle": "사용자가 차단됨",
-       "blockedtext": "'''사용자 계정 또는 IP 주소가 차단되었습니다.'''\n\n차단한 사람은 $1입니다.\n차단한 이유는 다음과 같습니다: $2\n\n* 차단이 시작된 시간: $8\n* 차단이 끝나는 시간: $6\n* 차단된 사용자: $7\n\n$1 또는 [[{{MediaWiki:Grouppage-sysop}}|다른 관리자]]에게 차단에 대해 문의할 수 있습니다.\n[[Special:Preferences|계정 환경 설정]]에 올바른 이메일 주소가 있어야만 '이메일 보내기' 기능을 사용할 수 있습니다. 또 이메일 보내기 기능이 차단되어 있으면 이메일을 보낼 수 없습니다.\n현재 당신의 IP 주소는 $3이고, 차단 ID는 #$5입니다.\n문의할 때에 이 정보를 같이 알려주세요.",
-       "autoblockedtext": "당신의 IP 주소는 $1님이 차단한 사용자가 사용했던 IP이기 때문에 자동으로 차단되었습니다.\n차단된 이유는 다음과 같습니다:\n\n:$2\n\n* 차단이 시작된 시간: $8\n* 차단이 끝나는 시간: $6\n* 차단된 사용자: $7\n\n$1 또는 [[{{MediaWiki:Grouppage-sysop}}|다른 관리자]]에게 차단에 대해 문의할 수 있습니다.\n\n[[Special:Preferences|사용자 환경 설정]]에 올바른 이메일 주소가 있어야만 \"이메일 보내기\" 기능을 사용할 수 있습니다. 또한 이메일 보내기 기능이 차단되어 있으면 이메일을 보낼 수 없습니다.\n\n현재 IP 주소는 $3이고, 차단 ID는 #$5입니다.\n문의할 때에 이 정보를 같이 알려주세요.",
+       "blockedtext": "'''사용자 계정 또는 IP 주소가 차단되었습니다.'''\n\n차단한 사람은 $1입니다.\n차단한 이유는 다음과 같습니다: <em>$2</em>.\n\n* 차단이 시작된 시간: $8\n* 차단이 끝나는 시간: $6\n* 차단된 사용자: $7\n\n$1 또는 [[{{MediaWiki:Grouppage-sysop}}|다른 관리자]]에게 차단에 대해 문의할 수 있습니다.\n[[Special:Preferences|계정 환경 설정]]에 올바른 이메일 주소가 있어야만 '이메일 보내기' 기능을 사용할 수 있습니다. 또 이메일 보내기 기능이 차단되어 있으면 이메일을 보낼 수 없습니다.\n현재 당신의 IP 주소는 $3이고, 차단 ID는 #$5입니다.\n문의할 때에 이 정보를 같이 알려주세요.",
+       "autoblockedtext": "당신의 IP 주소는 $1님이 차단한 사용자가 사용했던 IP이기 때문에 자동으로 차단되었습니다.\n차단된 이유는 다음과 같습니다:\n\n:<em>$2</em>\n\n* 차단이 시작된 시간: $8\n* 차단이 끝나는 시간: $6\n* 차단된 사용자: $7\n\n$1 또는 [[{{MediaWiki:Grouppage-sysop}}|다른 관리자]]에게 차단에 대해 문의할 수 있습니다.\n\n[[Special:Preferences|사용자 환경 설정]]에 올바른 이메일 주소가 있어야만 \"이메일 보내기\" 기능을 사용할 수 있습니다. 또한 이메일 보내기 기능이 차단되어 있으면 이메일을 보낼 수 없습니다.\n\n현재 IP 주소는 $3이고, 차단 ID는 #$5입니다.\n문의할 때에 이 정보를 같이 알려주세요.",
        "systemblockedtext": "당신의 사용자 이름 또는 IP 주소가 자동으로 미디어위키에 의해 차단되었습니다.\n이유는 다음과 같습니다:\n\n:<em>$2</em>\n\n* 차단 시작: $8\n* 차단 만료: $6\n* 차단 대상: $7\n\n당신의 현재 IP 주소는 $3입니다.\n문의에 대해 상기의 상세 설명을 모두 포함해 주십시오.",
        "blockednoreason": "이유를 입력하지 않음",
        "whitelistedittext": "문서를 편집하기 전에 $1해야 합니다.",
        "uploadstash-bad-path-bad-format": "\"$1\" 키는 적절한 포맷이 아닙니다.",
        "uploadstash-file-not-found": "저장소에서 \"$1\" 키를 찾지 못했습니다.",
        "uploadstash-file-not-found-no-thumb": "섬네일을 가져오지 못했습니다.",
+       "uploadstash-file-not-found-no-local-path": "썸네일을 가르키는 로컬 경로가 없습니다.",
        "uploadstash-file-not-found-no-object": "섬네일을 위한 로컬 파일 객체를 만들 수 없습니다.",
        "uploadstash-file-not-found-no-remote-thumb": "섬네일 가져오기를 실패했습니다: $1\nURL = $2",
        "uploadstash-file-not-found-missing-content-type": "content-type 헤더가 없습니다.",
        "apisandbox-dynamic-parameters-add-label": "변수 추가:",
        "apisandbox-dynamic-parameters-add-placeholder": "변수 이름",
        "apisandbox-dynamic-error-exists": "\"$1\"이라는 변수 이름은 이미 존재합니다.",
+       "apisandbox-templated-parameter-reason": "이 [[Special:ApiHelp/main#main/templatedparams|템플릿 매개 변수]]는 $2의 {{PLURAL:$1|value|values}}에 따라 제공됩니다.",
        "apisandbox-deprecated-parameters": "앞으로 제거될 변수",
        "apisandbox-fetch-token": "토큰 자동 채우기",
        "apisandbox-add-multi": "추가",
index 764e56e..68d5273 100644 (file)
        "previewnote": "'''Denkt drun datt dëst nëmmen eng net gespäichert Versioun ass.'''\nÄr Ännerunge sinn nach net gespäichert!",
        "continue-editing": "Gitt weider an de Beräich fir z'änneren",
        "previewconflict": "Dir gesitt an dem ieweschten Textfeld wéi den Text ausgesi wäert, wann Dir späichert.",
-       "session_fail_preview": "Är Ännerung konnt net gespäichert gi well d'Date vun Ärer Sessioun verluergaange sinn.\nDir gouft eventuell ausgeloggt. <strong>Iwwerpréift w.e.g. ob Dir nach ageloggt sidd a probéiert nach eng Kéier</strong>.\nWann de Problem dann ëmmer nach bestoe sollt, da versicht Iech [[Special:UserLogout|auszeloggen]] an dann erëm anzeloggen an iwwerpréift datt Äre Browser Cookië vun dësem Site  akzeptéiert.",
-       "session_fail_preview_html": "Är Ännerung konnt net gespäichert gi well d'Date vun Ärer Sessioun verluergaange sinn.\n\n<em>Well op {{SITENAME}} 'raw HTML' aktivéiert ass, gouf d'Uweise vun der nach net gespäicherter Versioun ausgeblennt fir JavaScript-Attacken ze vermeiden.</em>\n\n<strong>Wann Dir eng berechtegt Ännerung maache wëllt, da versicht et w.e.g. nach eng Kéier.</strong>\n\nWann de Problem dann ëmmer nach bestoe sollt, versicht Iech [[Special:UserLogout|auszeloggen]] an dann erëm anzeloggen a vergewëssert Iech datt Äre Browser d^Späichere vu Cookieë vun dësem Site zouléisst.",
+       "session_fail_preview": "Är Ännerung konnt net gespäichert gi well d'Date vun Ärer Sessioun verluergaange sinn.\nDir gouft eventuell ausgeloggt. <strong>Iwwerpréift w.e.g. ob Dir nach ageloggt sidd a probéiert nach eng Kéier</strong>.\nWann de Problem dann ëmmer nach bestoe sollt, da versicht Iech [[Special:UserLogout|auszeloggen]] an dann erëm anzeloggen an iwwerpréift ob Äre Browser Cookië vun dësem Site  akzeptéiert.",
+       "session_fail_preview_html": "Är Ännerung konnt net gespäichert gi well d'Date vun Ärer Sessioun verluergaange sinn.\n\n<em>Well op {{SITENAME}} 'raw HTML' aktivéiert ass, gouf d'Uweise vun der nach net gespäicherter Versioun ausgeblennt fir JavaScript-Attacken ze vermeiden.</em>\n\n<strong>Wann Dir eng berechtegt Ännerung maache wëllt, da versicht et w.e.g. nach eng Kéier.</strong>\n\nWann de Problem dann ëmmer nach bestoe sollt, versicht Iech [[Special:UserLogout|auszeloggen]] an dann erëm anzeloggen a vergewëssert Iech ob Äre Browser d'Späichere vu Cookieë vun dësem Site zouléisst.",
        "token_suffix_mismatch": "'''Är Ännerung gouf refuséiert, well Äre Browser Zeechen am Ännerungs-Identifiant verännert huet.'''\nD'Ännerung gouf refuséiert, fir ze verhënneren datt den Text op der Säit onliesbar gëtt.\nDëst geschitt heiansdo wann Dir en anonyme Proxy-Service um Internet benotzt.",
        "edit_form_incomplete": "'''En Deel vum Ännerungsformulaire koum net um Server un; iwwerpréift w.e.g ob Är Ännerunge komplett sinn a probéiert nach emol.'''",
        "editing": "Ännere vu(n) $1",
index 2b857b1..cb38f8a 100644 (file)
        "noarticletext-nopermission": "Исятда и ччина са текстни авач.\nКвевай [[Special:Search/{{PAGENAME}}| и тӀвар алай ччин]] муькуь ччинра жугъуриз ва я\n<span class=\"plainlinks\"> [{{fullurl: {{# Special:Log}} | page = {{FULLPAGENAMEE}}}} журналрин талукь тир кхьей затӀар жугъуриз] жеда.",
        "blocked-notice-logextract": "И уртах алайчIава блокарнава.\nАгъадихъ блокарунин журналдикай эхиримжи кхьинар къалурнава:",
        "previewnote": "'''Рикlел хуьх хьи, им анжах сифтедин килигун я.'''  \nКуь масакIавилер гьеле хвенвач!",
-       "editing": "$1 Ð\94уьзар хъувун",
+       "editing": "$1 Ð´уьзар хъувун",
        "editingsection": "Дуьзар хъувун $1  (пай)",
        "editingcomment": "$1 дуьзар хъувун (цIийи пай)",
        "editconflict": "Дуьзар хъувунрин акьунар: $1",
index 9edaaa8..ec4d570 100644 (file)
        "listusers-submit": "Mostra",
        "listusers-noresult": "No usor trovada.",
        "listusers-blocked": "(impedida)",
-       "activeusers": "Lista ativa de usores",
+       "activeusers": "Lista de usores ativa",
        "activeusers-intro": "Esta es un lista de usores ci ia es ativa en alga modo en la {{PLURAL:$1|dia|dias}} la plu resente.",
        "activeusers-count": "$1 {{PLURAL:$1|ata|atas}} en la {{PLURAL:$3|dia|$3 dias}} la plu resente.",
        "activeusers-from": "Mostra usores comensante a:",
index 75bf700..9d1ac9a 100644 (file)
        "stub-threshold-disabled": "നിർജ്ജീവമാക്കപ്പെട്ടിരിക്കുന്നു",
        "recentchangesdays": "പുതിയ മാറ്റങ്ങളിൽ കാണിക്കേണ്ട ദിവസങ്ങളുടെ എണ്ണം:",
        "recentchangesdays-max": "പരമാവധി {{PLURAL:$1|ഒരു ദിവസം|$1 ദിവസങ്ങൾ}}",
-       "recentchangescount": "സമàµ\80à´ªà´\95ാലമാറàµ\8dà´±à´\99àµ\8dà´\99ളിലàµ\81à´\82 à´¤à´¾à´³àµ\81à´\95à´³àµ\81à´\9fàµ\86 à´¨à´¾àµ¾à´ªàµ\8dപതിപàµ\8dà´ªàµ\81à´\95ളിലàµ\81à´\82 à´°àµ\87à´\96à´\95ളിലàµ\81à´\82 à´¸àµ\8dവതàµ\87 à´ªàµ\8dരദർശിപàµ\8dപിà´\95àµ\8dà´\95àµ\87à´£àµ\8dà´\9f à´¤à´¿à´°àµ\81à´¤àµ\8dതലàµ\81à´\95à´³àµ\81à´\9fàµ\86 à´\8eà´£àµ\8dà´£à´\82:",
+       "recentchangescount": "സമീപകാലമാറ്റങ്ങളിലും താളുകളുടെ നാൾപ്പതിപ്പുകളിലും രേഖകളിലും സ്വതേ പ്രദർശിപ്പിക്കേണ്ട തിരുത്തുകളുടെ എണ്ണം:",
        "prefs-help-recentchangescount": "പരമാവധി എണ്ണം: 1000",
        "prefs-help-watchlist-token2": "ഇത് താങ്കൾ ശ്രദ്ധിക്കുന്നവയുടെ  പട്ടികയുടെ വെബ്‌ഫീഡിനുള്ള രഹസ്യചാവിയാണ്.\nഇത് അറിയാവുന്നവർക്ക് താങ്കൾ ശ്രദ്ധിക്കുന്നവയെന്താണെന്ന് വായിക്കാനാവുമെന്നതിനാൽ, പങ്ക് വെയ്ക്കാതിരിക്കുക.\nതാങ്കൾക്കാവശ്യമെങ്കിൽ [[Special:ResetTokens|ഇത് പുനസജ്ജീകരിക്കാവുന്നതാണ്]].",
        "savedprefs": "താങ്കളുടെ ക്രമീകരണങ്ങൾ കാത്തുസൂക്ഷിച്ചിരിക്കുന്നു.",
index 912a2b6..ca80b0b 100644 (file)
        "bold_tip": "စာလုံးမည်း",
        "italic_sample": "စာလုံး အစောင်း",
        "italic_tip": "စာလုံး အစောင်း",
-       "link_sample": "လင့် ခေါင်းစဉ်",
-       "link_tip": "အတွင်းပိုင်း လင့်",
-       "extlink_sample": "http://www.example.com လင့် ခေါင်းစဉ်",
+       "link_sample": "လင့်ခ် ခေါင်းစဉ်",
+       "link_tip": "အတွင်းပိုင်း လင့်ခ်",
+       "extlink_sample": "http://www.example.com လင့်ခ် ခေါင်းစဉ်",
        "extlink_tip": "ပြင်ပလင့်များ (http:// ကို ရှေ့ဆုံးမှ ထည့်ရေးရန် မမေ့ပါနှင့်)",
        "headline_sample": "ခေါင်းကြီးစာသား",
        "headline_tip": "အဆင့် ၂ ခေါင်းစီး",
        "summary-preview": "တည်းဖြတ်အကျဉ်းချုပ် နမူနာ:",
        "subject-preview": "အကြောင်းအရာ နမူနာ:",
        "blockedtitle": "အသုံးပြုသူကို ပိတ်ပင်ထားသည်",
-       "blockedtext": "<strong>သင်၏ အသုံးပြုသူအမည် သို့မဟုတ် အိုင်ပီလိပ်စာသည် ပိတ်ပင်ခြင်း ခံထားရသည်။</strong>\n\nဤပိတ်ပင်မှုအား $1 က ဆောင်ရွက်ခဲ့သည်။\nအကြောင်းရင်းမှာ <em>$2</em> ဖြစ်သည်။\n\n* ပိတ်ပင်ခြင်း စတင်ချိန်: $8\n* ပိတ်ပင်ခြင်း သက်တမ်းကုန်ချိန်: $6\n* ရည်ရွယ်ရာ blockee: $7\n\nသင်သည် ပိတ်ပင်မှုအတွက် ဆွေးနွေးရန် $1 သို့မဟုတ် အခြား [[{{MediaWiki:Grouppage-sysop}}|စီမံခန့်ခွဲသူ]] အား ဆက်သွယ်နိုင်သည်။\nသင့်အနေဖြင့် [[Special:Preferences|အကောင့်၏ ရွေးချယ်စရာများ]]ထဲတွင် ရေရာသော အီးမေးလိပ်စာအား မထည့်သွင်းထားပါက \"ဤအသုံးပြုသူအား အီးမေးပို့ပါ\" လုပ်ဆောင်ချက်ကို အသုံးပြုနိုင်မည် မဟုတ်ပါ။ အလားတူ ယင်းလုပ်ဆောင်ချက်ကို ပိတ်ပင်မခံရမှ လုပ်ဆောင်နိုင်မည်ဖြစ်သည်။\nသင်၏ လက်ရှိ အိုင်ပီလိပ်စာမှာ $3 ဖြစ်ပြီး၊ ပိတ်ပင်မှုအိုင်ဒီမှာ #$5 ဖြစ်သည်။\nသင်ပြုလုပ်မည့် စုံစမ်းမေးမြန်းမှုများတွင် အထက်ပါ အချက်များ အားလုံး ပါဝင်နေပါစေ။",
+       "blockedtext": "<strong>သင်၏ အသုံးပြုသူအမည် သို့မဟုတ် အိုင်ပီလိပ်စာသည် ပိတ်ပင်ခြင်း ခံထားရသည်။</strong>\n\nဤပိတ်ပင်မှုအား $1 က ဆောင်ရွက်ခဲ့သည်။\nအကြောင်းရင်းမှာ <em>$2</em> ဖြစ်သည်။\n\n* ပိတ်ပင်ခြင်း စတင်ချိန်: $8\n* ပိတ်ပင်ခြင်း သက်တမ်းကုန်ချိန်: $6\n* ရည်ရွယ်ရာ blockee: $7\n\nသင်သည် ပိတ်ပင်မှုအတွက် ဆွေးနွေးရန် $1 သို့မဟုတ် အခြား [[{{MediaWiki:Grouppage-sysop}}|စီမံခန့်ခွဲသူ]] အား ဆက်သွယ်နိုင်သည်။\nသင့်အနေဖြင့် [[Special:Preferences|အကောင့်၏ ရွေးချယ်စရာများ]]ထဲတွင် ရေရာသော အီးမေးလိပ်စာအား မထည့်သွင်းထားပါက \"{{int:emailuser}}\" လုပ်ဆောင်ချက်ကို အသုံးပြုနိုင်မည် မဟုတ်ပါ။ အလားတူ ယင်းလုပ်ဆောင်ချက်ကို ပိတ်ပင်မခံရမှ လုပ်ဆောင်နိုင်မည်ဖြစ်သည်။\nသင်၏ လက်ရှိ အိုင်ပီလိပ်စာမှာ $3 ဖြစ်ပြီး၊ ပိတ်ပင်မှုအိုင်ဒီမှာ #$5 ဖြစ်သည်။\nသင်ပြုလုပ်မည့် စုံစမ်းမေးမြန်းမှုများတွင် အထက်ပါ အချက်များ အားလုံး ပါဝင်နေပါစေ။",
        "blockednoreason": "အကြောင်းပြချက် မပေးထားပါ",
        "whitelistedittext": "စာမျက်နှာများကို တည်းဖြတ်ရန် $1ရမည်။",
        "nosuchsectiontitle": "အပိုင်းကို ရှာမရနိုင်ပါ",
        "recentchangeslinked-feed": "ဆက်စပ်သော ​အ​ပြောင်း​အ​လဲ​များ​",
        "recentchangeslinked-toolbox": "ဆက်စပ်သော အပြောင်းအလဲများ",
        "recentchangeslinked-title": "\"$1\" နှင့် ဆက်စပ်သော အပြောင်းအလဲများ",
-       "recentchangeslinked-summary": "ဤစာမျက်နှာမှ သို့မဟုတ် ဤစာမျက်နှာသို့ ချိတ်ဆက်ထားသော စာမျက်နှာများ၏ ပြောင်းလဲမှုများကို ကြည့်ရှုနိုင်ရန် စာမျက်နှာအမည်တစ်ခုကို ထည့်သွင်းပါ။ (ကဏ္ဍတစ်ခု၏ အဖွဲ့ဝင်များကို ကြည့်ရှုရန် Category:ကဏ္ဍအမည် ကို ရိုက်ထည့်ပါ။) [[Special:Watchlist|သင့်စောင့်ကြည့်စာရင်း]]ရှိ စာမျက်နှာများ၏ ပြောင်းလဲမှုများကို <strong>စာလုံးအထူ</strong>ဖြင့် ပြထားသည်။",
+       "recentchangeslinked-summary": "ဤစာမျက်နှာမှ သို့မဟုတ် ဤစာမျက်နှာသို့ ချိတ်ဆက်ထားသော စာမျက်နှာများ၏ ပြောင်းလဲမှုများကို ကြည့်ရှုနိုင်ရန် စာမျက်နှာအမည်တစ်ခုကို ထည့်သွင်းပါ။ (ကဏ္ဍတစ်ခု၏ အဖွဲ့ဝင်များကို ကြည့်ရှုရန် {{ns:category}}:ကဏ္ဍအမည် ကို ရိုက်ထည့်ပါ။) [[Special:Watchlist|သင့်စောင့်ကြည့်စာရင်း]]ရှိ စာမျက်နှာများ၏ ပြောင်းလဲမှုများကို <strong>စာလုံးအထူ</strong>ဖြင့် ပြထားသည်။",
        "recentchangeslinked-page": "စာမျက်နှာ အမည် -",
        "recentchangeslinked-to": "ပေးထားသော စာမျက်နှာများအစား လင့်များနှင့် ဆက်စပ်နေသာ စာမျက်နှာများ၏ အပြောင်းအလဲများကို ပြရန်",
        "recentchanges-page-added-to-category": "ကဏ္ဍထဲသို့ [[:$1]] ကို ပေါင်းထည့်ခဲ့သည်",
        "whatlinkshere-title": "\"$1\" သို့ ချိတ်ဆက်ထားသော စာမျက်နှာများ",
        "whatlinkshere-page": "စာမျက်နှာ -",
        "linkshere-2": "အောက်ပါစာမျက်နှာများသည် <strong>$1</strong> သို့ ချိတ်ဆက်ထားသည် -",
-       "nolinkshere-2": "'''$1''' သို့ လင့်ထားသော စာမျက်နှာ မရှိပါ။",
+       "nolinkshere-2": "<strong>$1</strong> သို့ လင့်ခ်ထားသော စာမျက်နှာ မရှိပါ။",
        "isredirect": "ပြန်ညွှန်းသော စာမျက်နှာ",
        "istemplate": "ထည့်သွင်းကူးယူချက်",
        "isimage": "ဖိုင်လင့်",
        "whatlinkshere-prev": "{{PLURAL:$1|နောက်သို့|နောက်သို့ $1}}",
        "whatlinkshere-next": "{{PLURAL:$1|ရှေ့သို့|ရှေ့သို့ $1}}",
-       "whatlinkshere-links": "← လင့်များ",
+       "whatlinkshere-links": "â\86\90 á\80\9cá\80\84á\80·á\80ºá\80\81á\80ºá\80\99á\80»á\80¬á\80¸",
        "whatlinkshere-hideredirs": "ပြန်ညွှန်းများ $1",
        "whatlinkshere-hidetrans": "ထည့်သွင်းကူးယူချက် $1",
        "whatlinkshere-hidelinks": "လင့်ခ်များ $1 ခု",
        "blocklist-nousertalk": "မိမိ၏ဆွေးနွေးချက်စာမျက်နှာကို တည်းဖြတ်မရနိုင်ပါ",
        "ipblocklist-empty": "ပိတ်ပင်ထားမှုစာရင်းသည် ဗလာဖြစ်နေသည်။",
        "blocklink": "ပိတ်ပင်",
-       "unblocklink": "á\80\9cá\80\84á\80·á\80º á\80\95á\80¼á\80\94á\80ºá\80\96á\80¼á\80±ရန်",
+       "unblocklink": "á\80\99á\80\95á\80­á\80\90á\80ºá\80\95á\80\84á\80ºá\80\90á\80±á\80¬á\80·ရန်",
        "change-blocklink": "စာကြောင်းအမည် ပြောင်းရန်",
        "contribslink": "ပံ့ပိုး",
        "blocklogpage": "ပိတ်ပင်တားဆီးမှု မှတ်တမ်း",
        "newimages-label": "ဖိုင်အမည် (သို့ ယင်း၏အစိတ်အပိုင်း) -",
        "noimages": "ကြည့်စရာဘာမှ မရှိပါ။",
        "ilsubmit": "ရှာဖွေရန်",
-       "bydate": "á\80\9bá\80\80á\80ºá\80\85á\80½á\80²á\80\96á\80¼á\80­á\80\84á\80·á\80º",
+       "bydate": "ရက်စွဲဖြင့်",
        "sp-newimages-showfrom": "$1 နေ့ $2 အချိန်ကစသော ဖိုင်အသစ်များကို ပြရန်",
        "bad_image_list": "ဖောမတ်ပုံစံမှာ အောက်ပါအတိုင်းဖြစ်သည်။\n\nစာရင်းတွင်ထည့်သွင်းထားသော အရာများကိုသာ ထည့်သွင်းစဉ်းစားမည်။ (ခရေပွင့် * ဖြင့်စသော စာကြောင်းများ)\nစာကြောင်း၏ ပထမဆုံး လင့်သည် ဖိုင်ညံ့ ဖြစ်ရမည်။\nယင်းစာကြောင်းတွင်ပင် နောက်ထပ်လာသောလင့်များကို ချွင်းချက်အဖြစ် စဉ်းစားမည်။ ဆိုလိုသည်မှာ ၎င်းလင့်များတွင်လည်း အဆိုပါ ဖိုင်ညံ့ ပါကောင်း ပါဝင်နေမည်။",
        "metadata": "Metadata",
        "specialpages-group-maintenance": "ထိန်းသိမ်းမှု အစီရင်ခံချက်များ",
        "specialpages-group-other": "အခြားအထူးစာမျက်နှာများ",
        "specialpages-group-login": "Log in ဝင်ရန်/ အကောင့် ဖန်တီးရန်",
-       "specialpages-group-changes": "လတ်တလောအေပြောင်းအလဲနှင့် မှတ်တမ်းများ",
+       "specialpages-group-changes": "လတ်တလော အပြောင်းအလဲနှင့် မှတ်တမ်းများ",
        "specialpages-group-media": "မီဒီယာ အစီရင်ခံချက်များနှင့် Upload တင်ထားသည်များ",
        "specialpages-group-users": "အသုံးပြုသူများနှင့် အခွင့်အရေးများ",
        "specialpages-group-highuse": "အသုံးများသော စာမျက်နှာများ",
index 443bb11..e7b4c82 100644 (file)
        "viewsource": "Vere sorgente",
        "viewsource-title": "Vere surgente 'e $1",
        "actionthrottled": "Azione ritardata",
-       "actionthrottledtext": "Comme misura anti-abuse, site lemmetato 'a ffà st'azione troppe vote dint'a nu curto spazio 'e tiempo, e mò stu lèmmeto è stato superato.\nPe' piacere pruvate n'ata vota dint'a cocche minuto.",
+       "actionthrottledtext": "Comme mesùra anti-abuse, site lemmetato 'a ffà st'azione troppe vote dint'a nu curto spazio 'e tiempo, e mo stu lèmmeto l'avite superato.\nPe piacere pruvate n'ata vota dint'a quacche minuto.",
        "protectedpagetext": "Sta paggena s'è prutetta pe' ne bloccà 'a mudifeca o n'ata azione.",
        "viewsourcetext": "Putite vedé e copià 'o codece surgiva 'e sta paggena.",
        "viewyourtext": "Putite vedé e copià 'o codice surgiva d' 'e <strong>cagnamiénte vuoste</strong> a sta paggena.",
        "virus-scanfailed": "scanziona fallita (codece $1)",
        "virus-unknownscanner": "antivirus scanusciuto:",
        "logouttext": "'''Site asciùte.'''\n\nNota ca arcune paggene putessero cuntinuà ad cumparì comme se 'o logout nun fosse affettuato fin quanno nun sarrà pulezzata 'a cache d\"o proprio browser.",
-       "cannotlogoutnow-title": "Nun se pò ascì mò",
+       "cannotlogoutnow-title": "Mo nun se pò ascì",
        "cannotlogoutnow-text": "'A disconessione nun è possibbele quanno s'ausa $1.",
        "welcomeuser": "Bemmenuto, $1!",
        "welcomecreation-msg": "'O cunto vuosto è stato criato.\nMo' putite cagnà 'e [[Special:Preferences|preferenze 'e {{SITENAME}}]].",
        "userlogin-signwithsecure": "Usa na conessione sicura",
        "cannotlogin-title": "Nun se pò trasì",
        "cannotlogin-text": "Trasì nun è possibbele mò.",
-       "cannotloginnow-title": "Nun se pò trasì mò",
+       "cannotloginnow-title": "Mo nun se pò trasì",
        "cannotloginnow-text": "'A connessione nun è possibbele quanno s'ausa $1.",
        "cannotcreateaccount-title": "Nun se ponno crià cunte",
        "cannotcreateaccount-text": "'A criazione diretta 'e cunte è stutata int'a stu wiki.",
        "password-login-forbidden": "L'uso 'e stu nomme utente e password è stato proibito.",
        "mailmypassword": "Riabbìa 'a password",
        "passwordremindertitle": "Nnova password temporale pe' {{SITENAME}}",
-       "passwordremindertext": "Cocche perzona (pussibbilmente tu, cu n'innerizzo IP $1) ha dimmannato l'invio 'e na password d'accieso nova pe' {{SITENAME}} ($4).\nNa password temporanea e' l'utente \"$2\" s'è abbiata comme \"$3\".\nSi chest'è stata l'intenzione toja, allora hè a trasì dint'o sito e cagnà 'a password mò. 'A password temporanea scade aropp'a {{PLURAL:$5|nu juorno|$5 ghiuorne}}.\n\nSi nun sì stato tu a dimannà 'a password, o pure hè truvat'a password e nun 'a bbuò cagnà cchiù, allora nun fà niente e continua a usare 'a password viecchia.",
+       "passwordremindertext": "Quaccheduno (pussibbilmente tu, cu n'innerizzo IP $1) ha dimmannato l'invio 'e na password d'accieso nova pe {{SITENAME}} ($4).\nNa password temporanea 'e l'utente \"$2\" s'è abbiata comme \"$3\".\nSi chest'è stata l'intenzione toja, allora hè a trasì dint'o sito e cagnà 'a password primm'e mo. 'A password temporanea scade aropp'a {{PLURAL:$5|nu juorno|$5 ghiuorne}}.\n\nSi nun sì stato tu a dimannà 'a password, o pure hê truvat'a password e nun 'a bbuò cagnà cchiù, allora nun fà niente e continua a usare 'a password viecchia.",
        "noemail": "Nun ce sta indirizzo e-mail pe' l'utente \"$1\".",
        "noemailcreate": "S'add'appruviggiunà n'indirizzo e-mail buono.",
        "passwordsent": "Na password nova è stata inviata a l'innerizzo e-mail riggistrato 'a ll'utente \"$1\".\nPe' piacere, trasite appena avite ricevuta sta password.",
        "eauthentsent": "Na mmasciata 'e conferma t'è stata mannata a l'indirizzo e-mail nzignàto.\nApprimm' 'e te mannà n'atu mail, hè 'a stà 'a ffà 'e struzione dint'a l'e-mail, pe' cunfermà ca 'o cunto fosse d' 'o tujo overo.",
        "throttled-mailpassword": "S'è mannata na mail pe te' riabbià 'a password 'a meno 'e {{PLURAL:$1|n'ora|$1 ore}}.\nPe' ce sparagnà abbuse, 'a funzione 'e riabbiamento d' 'a password se può usa sulamente na vota ogne {{PLURAL:$1|ora|$1 ore}}.",
        "mailerror": "Errore pe' tramente ca se mannava na mmasciata: $1",
-       "acct_creation_throttle_hit": "'E vvisite a sta wiki ausanno l'IP tuoja se so' mise a crià {{PLURAL:$1|1 registrazzione|$1 registrazzione}} int'a ll'urdeme juorne ($2), chesto fosse 'o massimo premmesso pe' stu periodo 'e tiempo.\nPerciò, 'e utente ca ausano chisto innerezzo IP nun se ponno riggistrà ancora mò mò.",
+       "acct_creation_throttle_hit": "'E vvisite a sta wiki ausanno l'IP tuoja se so' mise a crià {{PLURAL:$1|1 registrazzione|$1 registrazzione}} int'a ll'urdeme juorne ($2), chesto fosse 'o massimo premmesso pe' stu periodo 'e tiempo.\nPerciò, ll'utente ca ausano chisto innerezzo IP nun se ponno riggistrà mo.",
        "emailauthenticated": "'O ndirizzo email è stato cunfermato 'o $2 a 'e $3.",
        "emailnotauthenticated": "'O ndirizzo 'e posta elettronica nun è stat'ancora cunfermato.\nNun se mannarranno mmasciate e-mail p' ' funzione ccà abbascio.",
        "noemailprefs": "Avite 'a specificà nu ndirizzo e-mail pe ll'attivà sti funzione.",
        "blockedtitle": "Utente bloccato.",
        "blockedtext": "<strong>'O nomme utente o ll'IP vuosto è stato bloccato.</strong>\n\n'O blocco è stato mpustato 'a $1. 'O mutivo d' 'o blocco è chisto: ''$2''\n\n* Abbiàta d' 'o blocco: $8\n* Ammaturità d' 'o blocco: $6\n* Tiempo 'e blocco: $7\n\nPutite cuntattà $1 o n'atu [[{{MediaWiki:Grouppage-sysop}}|ammenistratore]] pe discutere d'ô blocco.\n\nVedite c' 'a funzione \"{{int:emailuser}}\" nun è attiva si nun s'ave riggistrato 'o ndirizzo e-mail buono dint' 'e [[Special:Preferences|preferenze]] o pùre si ll'uso 'e tale funzione è stato bloccato.\n\n'O ndirizzo IP 'e mo è $3, 'o nummero ID d' 'o blocco è #$5.\nPe piacere avite 'a specificà tutte sti dettaglie quanno facite carche dumanna.",
        "autoblockedtext": "Ll'IP vuosto è stato bloccato pecché 'o steva piglianno n'atu utente, ch'è stato bloccato pe' $1.\n\n'O mutivo d' 'o blocco è chesto:\n\n:''$2''\n\n* Abbiàta d' 'o blocco: $8\n* Ammaturità d' 'o blocco: $6\n* Tiempo 'e blocco: $7\n\nPutite cuntattà $1 o n'atu [[{{MediaWiki:Grouppage-sysop}}|ammenistratore]] pe' discutere 'o blocco.\n\nVedite c' 'a funzione 'Scrivete a ll'utente' nun è attiva si nun s'è riggistrato 'o ndirizzo e-mail buono dint' 'e [[Special:Preferences|preferenze]] o pùre si ll'uso 'e tale funzione è stato bloccato.\n\n'O ndirizzo IP attuale è $3, 'o nummero ID d' 'o blocco è #$5.\nPe' piacere avite 'e specificà tutte sti dettaglie ccà ncoppa quanno facite cocche dumanna.",
-       "systemblockedtext": "'O nomme utente d' 'o vuosto o ll'IP address fosse stata automaticamente bluccata 'a MediaWiki.\n'O mutivo fosse chesto:\n\n:<em>$2</em>\n\n* Inizio d' 'o blocco: $8\n* Ammatura 'o blocco: $6\n* Intervall' 'e blocco: $7\n\n'O indirizzo IP 'e mò fosse $3.\nPe' piacere, facite specifice tuttuquante 'e ddettaglie ccà quanno iate a ghienchere na richiesta 'e chiarimiente.",
+       "systemblockedtext": "'O nomme utente d' 'o vuosto o ll'IP address songo stati automaticamente bluccati 'a MediaWiki.\n'O mutivo fosse chesto:\n\n:<em>$2</em>\n\n* Inizio d' 'o blocco: $8\n* Ammatura 'o blocco: $6\n* Intervall' 'e blocco: $7\n\n'O indirizzo IP fusse $3.\nPe piacere, facite specifice tutt' 'e ddettaglie ccà quanno iate a fà na richiesta 'e chiarimiente.",
        "blockednoreason": "nisciuna ragione è stata indicata",
        "whitelistedittext": "Pe' cagnà 'e ppaggene è necessario $1.",
        "confirmedittext": "Pe puté cagnà paggene avite 'a cunfermà l'indirizzo e-mail.\nPe' piacere abbiate e ffà 'a validazione d' 'o ndirizzo e-mail pe' bbìa d' 'e [[Special:Preferences|preferenze d'utente]].",
        "editingsection": "Cagnamiénto 'e $1 (sezzione)",
        "editingcomment": "Cagnamiénto 'e $1 (nova sezzione)",
        "editconflict": "Conflitto d'edizzione: $1",
-       "explainconflict": "N'at'utente ave sarvato na nova verziona d' 'a paggena pe' tramente ca stevate a fà 'e cagnamiente.\n'A cascia 'e mudifeca ncoppa cuntene 'o testo d' 'a paggena ca mò sta online, accussì comme è stato agghiurnato a l'at'utente.\n'A verziona ch' 'e cagnamiente vuoste è stata mmece riportata dint'a cascia 'e mudifeca abbascio.\nSi 'e vulite cunfermà avite 'a ripurtà 'e cagnamiente d' 'e vuoste dint'o testo ca esiste (dint'a cascia ncoppa).\nSpremmendo 'o buttón '$1', sarrà sarvato '''sulamente''' 'o testo cuntenuto dint'a cascia 'e cagnamiento ncoppa.",
+       "explainconflict": "N'at'utente ave sarvato na verziona nova d' 'a paggena pe tramente ca stevate a ffà 'e cagnamiente.\n'A cascia 'e mmudifeca ncoppa tene 'o testo d' 'a paggena ca sta online mo, accussì comme fuje agghiurnato pe ll'at'utente.\n'A verziona ch' 'e cagnamiente vuoste è stata mmece riportata dint'a cascia 'e mudifeca abbascio.\nSi 'e vulite cunfermà, avite 'a ripurtà 'e cagnamiente d' 'e vuoste dint'o testo ca esiste (dint'a cascia ncoppa).\nSpremmendo 'o buttón '$1', sarrà sarvato '''sulamente''' 'o testo cuntenuto dint'a cascia 'e cagnamiento ncoppa.",
        "yourtext": "'O testo vuosto",
-       "storedversion": "A verziona 'n memoria",
+       "storedversion": "A verziona int'a memoria",
        "editingold": "'''Attenziò: staje cagnanno na verziona nun agghiurnata d' 'a paggena. Si 'a sarve accussì, tutte 'e cagnamiente fatte aropp'a sta verziona sarranno sperdute.'''",
        "yourdiff": "Differenze",
        "copyrightwarning": "Pe' piacere tenite a mmente ca tutte 'e contribbute a {{SITENAME}} songo cunziderate pubbrecate dint'e térmene d'uso d' 'a licienza $2 (vedite $1 pe n'avé cchiù dettaglie).\nSi nun vulite ca 'e testi vuoste fossero cagnate e distribuite 'a uno qualunque senza lémmeto, nun 'e mannate ccà.<br />\nMannanno stu testo dichiarate pùre, sott'a responsabilità vuosta, ch'è stato scritto 'a vuje perzunalmente o pure ca è stato copiato 'a na fonte n pubblico dominio o similarmente libbera.\n'''Nun mannate materiale prutetto 'a copyright senz'avé autorizzaziona!'''",
        "permissionserrors": "Nun haje 'e premmesse abbastante.",
        "permissionserrorstext": "Nun haje premmesse pe lle ffà st'azziune, {{PLURAL:$1|'o mutivo è chesto|'e mutive so' chiste}}:",
        "permissionserrorstext-withaction": "Nun haje premmesse abbastante pe' $2, {{PLURAL:$1|'o mutivo è chesto|'e mutive so' chiste}}:",
-       "contentmodelediterror": "Vuje nun putite cagnà sta verziona pecché 'o mudell' 'e cuntenute è <code>$1</code>, ca cagnasse nu poco nfacc' 'o mudell' 'e mò d' 'a paggena è <code>$2</code>.",
+       "contentmodelediterror": "Vuje nun putite cagnà sta verziona pecché 'o mudello d' 'e cuntenute è <code>$1</code>, ca cagnasse nu poco nfacc' 'o mudello d' 'a paggena  <code>$2</code> 'e mo.",
        "recreate-moveddeleted-warn": "'''Attenziò: staje a crià na paggena scancellata già.'''\n\nVire si è bbuono 'e cuntinuà a cagnà sta paggena. L'elenco ch' 'e relative scancellamiente e spustamente s'è scritto ccà abbascio pe' ffà comodo:",
        "moveddeleted-notice": "Sta paggena è stata scancellata.\n'A lista d' 'e relative scancellamiente e spustamente sta cca 'bbascio pe' n'avé 'nfurmazione.",
        "moveddeleted-notice-recent": "Scusate, sta mmasciata è stata scancellata mo mo (dint'a sti 24 ore).\n\nL'aziune 'e scancellazione e spustamento pe' sta paggena so dispunibbele ccà p' 'a cumpretezza.",
        "rev-showdeleted": "faje vedé",
        "revisiondelete": "Scancella o ripiglia verziune",
        "revdelete-nooldid-title": "Verziona nun specificata",
-       "revdelete-nooldid-text": "Nun avite specificato nu target 'e verziona addò s'avess'apprecà sta funzione, o 'a verziona specificata nun esiste o pure jate truvanno 'annascónnere 'a verziona 'e mò.",
+       "revdelete-nooldid-text": "Nun avite specificato nisciuna verzione 'e target addò s'aviss'apprecà sta funzione, o 'a verziona specificata nun esiste o pure jate truvanno 'annascùnnere 'a verziona 'e mo.",
        "revdelete-no-file": "'O file specificato nun esiste.",
        "revdelete-show-file-confirm": "Sì sicuro/a ca vulite veré 'a verziona scancellata d' 'o file \"<nowiki>$1</nowiki>\" d' 'o $2 a 'e $3?",
        "revdelete-show-file-submit": "Sì",
        "revdelete-edit-reasonlist": "Càgna 'e mutive pe' fà 'o scancellamiento",
        "revdelete-offender": "Autore d' 'a verziona:",
        "suppressionlog": "Riggistro 'e luvamiente",
-       "suppressionlogtext": "Ccà abbascio ce sta n'alenco ch' 'e scancellamiente e blocche ca teneno cuntenute annascunnuto a l'ammenistrature.\nVide l'[[Special:BlockList|elenco d' 'e blocche]] pe' l'elenco e banne e blocche attive 'e mò.",
+       "suppressionlogtext": "Ccà abbascio ce sta n'alenco 'e scancellamiente e blocche ca teneno cuntenute annascunnuti â ll'ammenistrature.\nVide l'[[Special:BlockList|elenco d' 'e blocche]] pe ll'elenco e banne e blocche attive ca ce stanno mo.",
        "mergehistory": "Aunisce 'e cronologgie",
        "mergehistory-header": "Sta paggena te permette d'aunì 'e verziune d' 'a cronologgia 'e na paggena origgine a na paggena nova.\nVedite ca s'avesse 'a nchiantà stu cagnamiento senza scassà 'a continuità storeca d' 'a paggena.",
        "mergehistory-box": "Aunisce 'a cronologgia 'e ddoje ppaggene:",
        "right-suppressrevision": "Vide, annascunne e ripiglia 'e verziune specifiche d' 'e paggene a cocherun'utente",
        "right-viewsuppressed": "Vide 'e verziune annascunnute a coccherun'utente",
        "right-suppressionlog": "Vide 'e riggistre private",
-       "right-block": "Blocca 'e cagnamiente 'a parte 'e l'at'utente",
-       "right-blockemail": "Blocca n'utente a mannà e-mail",
+       "right-block": "Nun fa fa' cagnamienti a ll'at'utente",
+       "right-blockemail": "Nun fa mannà e-mail a n'utente",
        "right-hideuser": "Blocca n'utente e fallo sparì 'a 'o pubbreco",
        "right-ipblock-exempt": "Ignora 'e blocche 'e l'IP, 'e blocche automatece e li blocche 'e range 'e l'IP",
        "right-unblockself": "Sblocca se stesso",
        "grant-group-administration": "Secuta aziune ammenistrative",
        "grant-group-private-information": "Tràse dint' 'e date private ncopp'a tte",
        "grant-group-other": "Attività differénte",
-       "grant-blockusers": "Blocca e sblocca utente",
+       "grant-blockusers": "Fremma e lassa i ll'utenti",
        "grant-createaccount": "Crìa cunte",
        "grant-createeditmovepage": "Créa, cagna e móve paggene",
        "grant-delete": "Scancella paggene, verziune, trasute 'e riggistro",
        "action-undelete": "arripiglia chista paggena",
        "action-suppressrevision": "rivedé e arripiglià 'e cagnamiente annascunnute",
        "action-suppressionlog": "vide stu riggistro privato",
-       "action-block": "blocca 'e cagnamiente 'a parte 'e st'utente",
+       "action-block": "fremma st'utente 'e fa' cagnamiente",
        "action-protect": "cagna 'e livelle 'e prutezione pe' sta paggena",
        "action-rollback": "annulla ampresso 'e cagnamiente 'e ll'urdem'utente c'avesse cagnato na paggena particulare",
        "action-import": "carreca paggene 'a n'ata wiki",
        "tmp-write-error": "Errore a scrivere nu file temporaneo.",
        "large-file": "S'arraccumanna 'e nun appassà 'e diminsione 'e $1 p'ogne file; stu file è gruosso $2.",
        "largefileserver": "Stu file appassa 'e dimensiune permesse 'a la configurazione d' 'o server",
-       "emptyfile": "'O file carrecato mò mò pare abbacante. Può darse ch'è stato n'errore int' 'o nomme d' 'o file. Cuntrullate ca vulite overamente carrecà stu file.",
+       "emptyfile": "'O file c'avite carrecato pare avvacante. Può essere ch'è stato n'errore int' 'o nomme d' 'o file. Cuntrullate ca vulite overamente carrecà stu file.",
        "windows-nonascii-filename": "Chista wiki nun supporta nomme d' 'e file cu carattere spiciale",
        "fileexists": "Nu file cu stu nomme esiste già.\nPe' piacere cuntrullate primma <strong>[[:$1]]</strong> si nun site sicure ca 'o vulite cagnà.\n[[$1|thumb]]",
        "filepageexists": "'A paggena 'e descrizione 'e stu file è stata già criata a l'indirizzo <strong>[[:$1]]</strong>, pùre si nun esiste ancora nu file cu stu nomme. 'A descrizione 'e l'oggetto nzertàta 'n fase 'e carreca nun cumparerrà ncopp' 'a paggena 'e descrizione. Pe' ffà l'oggetto cumparì ncopp' 'a paggena 'e descrizione, l'avisseve 'a cagnà manualmente.\n[[$1|thumb]]",
        "uploaded-animate-svg": "Truvato 'o tag \"animate\" ca putesse stà a cagnà href, ausanno l'attribbuto \"from\" <code>&lt;$1 $2=\"$3\"&gt;</code> int' 'o file carrecato SVG.",
        "uploaded-setting-event-handler-svg": "Mpustà n'attributo event-handler è bluccato, truvato <code>&lt;$1 $2=\"$3\"&gt;</code> int' 'o fie carrecato SVG.",
        "uploaded-setting-href-svg": "Ausà 'o tag \"set\" pe' putè azzeccà attribbute \"href\" a l'elemento parente è bluccato.",
-       "uploaded-wrong-setting-svg": "D'ausà 'o tag \"set\" pe' putè azzeccà nu target remoto/date/script a n'attribbuto mò è bluccato. Truvato 'o code>&lt;set to=\"$1\"&gt;</code> dint' 'o file SVG carrecato.",
+       "uploaded-wrong-setting-svg": "D'ausà 'o tag \"set\" pe putè azzeccà nu target remoto/date/script a n'attribbuto mo sta bluccato. Truvato 'o code>&lt;set to=\"$1\"&gt;</code> dint' 'o file SVG carrecato.",
        "uploaded-setting-handler-svg": "'o SVG ca mpustasse l'attribbuto \"handler\" cu nu remoto/date/script è bluccato. Truvato <code>$1=\"$2\"</code> dint' 'o file SVG carrecato.",
        "uploaded-remote-url-svg": "SVG ca mpustasse n'attribbuto 'e stile cu n'URL remota bluccata. Truvate <code>$1=\"$2\"</code> int' 'o file carrecato SVG.",
        "uploaded-image-filter-svg": "Truvato filtro immaggene cu n'URL: <code>&lt;$1 $2=\"$3\"&gt;</code> int' 'o file SVG carrecato.",
        "backend-fail-read": "Nun se può lieggere 'o file \"$1\".",
        "backend-fail-create": "Nun se può scrivere 'o file \"$1\"",
        "backend-fail-maxsize": "Nun se può scrivere 'o file \"$1\" pecché chist'è cchiù gruosso 'e {{PLURAL:$2|nu byte|$2 byte}}",
-       "backend-fail-readonly": "L'archivio 'e rezza \"$1\" è mò mò 'n sola-lettura. 'O mutivo è: <em>$2</em>",
+       "backend-fail-readonly": "L'archivio 'e rezza \"$1\" sta mo c'â sola-lettura. 'O mutivo è: <em>$2</em>",
        "backend-fail-synced": "'O file \"$1\" è int' 'a nu stato ncunzistente dint'a l'archivie nterne.",
        "backend-fail-connect": "Nun se può cunnettà â memoria 'e rezza \"$1\".",
        "backend-fail-internal": "N'errore scanusciuto s'è verificato int'a l'archivie 'e rezza \"$1\".",
        "filerevert-submit": "Arrepiglia",
        "filerevert-success": "'''[[Media:$1|$1]]''' è stat'arripigliato â verziona [$4 d' 'e $3 d' 'o $2].",
        "filerevert-badversion": "Nun ce sta na virziona lucale 'e stu file cu l'orario addimannato.",
-       "filerevert-identical": "'A verziona 'e mò d' 'o file è già eguale eguale a chilla scigliuta.",
+       "filerevert-identical": "'A verziona 'e mo d' 'o file è già eguale eguale a chella scigliuta.",
        "filedelete": "Scancella $1",
        "filedelete-legend": "Scancella 'o file",
        "filedelete-intro": "State pe' scancellà 'o file '''[[Media:$1|$1]]''' cu tutta 'a cronologgia 'e chisto.",
        "deadendpagestext": "'E paggene ccà abbascio nun spontano a n'ati paggene ncopp'a {{SITENAME}}.",
        "protectedpages": "Paggene prutette",
        "protectedpages-indef": "Sulamente prutezziune a tiempo nun definito",
-       "protectedpages-summary": "Sta paggena elenca 'e paggene ch'esisteno e ca songo prutette mò. Pe n'avé n'elenco 'e titule prutette â criazione, vedite [[{{#special:ProtectedTitles}}|{{int:protectedtitles}}]].",
+       "protectedpages-summary": "Sta paggena elenca 'e paggene ch'esisteno e ca mo stanne prutette. P'avé n'elenco 'e titule prutette â criazione, vedite [[{{#special:ProtectedTitles}}|{{int:protectedtitles}}]].",
        "protectedpages-cascade": "Sulamente prutezziune ricurzive",
        "protectedpages-noredirect": "Annascunne redirect",
-       "protectedpagesempty": "Nisciuna paggena è prutetta pe mò cu sti parametre.",
+       "protectedpagesempty": "Nisciuna paggena è prutetta pe mo cu sti parametre.",
        "protectedpages-timestamp": "Data e ora",
        "protectedpages-page": "Paggena",
        "protectedpages-expiry": "Ammatura",
        "protectedpages-unknown-performer": "Utente scanusciuto",
        "protectedtitles": "Paggene prutette",
        "protectedtitles-summary": "Sta paggena elenca 'e titule ca song'attualmente prutette 'a criazione. Pe' n'avé n'elenco 'e paggene prutette ch'esisteno, vedite [[{{#special:ProtectedPages}}|{{int:protectedpages}}]].",
-       "protectedtitlesempty": "Nisciunu titolo è prutetto pe mò cu sti parametre.",
+       "protectedtitlesempty": "Nisciuno titolo è prutetto pe mo cu sti parametre.",
        "protectedtitles-submit": "Mmusta titule",
        "listusers": "Lista 'e l'utente",
        "listusers-editsonly": "Fà vedé sulamente l'utente cu cagnamiente fatte",
        "apisandbox-dynamic-parameters-add-label": "Azzecca nu parametro:",
        "apisandbox-dynamic-parameters-add-placeholder": "Nomme d' 'o parametro",
        "apisandbox-dynamic-error-exists": "Nu parametro denommenato \"$1\" esiste già.",
-       "apisandbox-deprecated-parameters": "Parametre mò obsoleti",
+       "apisandbox-deprecated-parameters": "Parametri obsoleti",
        "apisandbox-fetch-token": "Auto-ghienche 'o token",
        "apisandbox-submit-invalid-fields-title": "Cocche campo nun è buono",
        "apisandbox-submit-invalid-fields-message": "Pe' piacere curriggite 'e campe nzegnàte e tentate n'ata vota.",
        "whatlinkshere-filters": "Filtre",
        "whatlinkshere-submit": "Vaje",
        "autoblockid": "Autoblocco #$1",
-       "block": "Blocca l'utente",
+       "block": "Fremma st'utente.",
        "unblock": "Sblocca l'utente",
-       "blockip": "Blocca {{GENDER:$1|utente}}",
+       "blockip": "Fremma {{GENDER:$1|utente}}",
        "blockiptext": "Ausa 'o modulo ccà abbascio pe' bluccà l'acciesso 'e scrittura a n'indirizzo IP o utente.\nChisto s'avesse 'a ffà sulamente pe' se pruteggere d' 'o vandalismo, d'accordo ch' [[{{MediaWiki:Policy-url}}|'e reole]].\nMettite pure nu mutivo specifico ccà abbascio (p'esempio, facenno 'o nomme 'e paggene addò se so' fatte 'e vandalisme).\nPutite bluccà ntervalle IP ausanno 'a sintasse [https://it.wikipedia.org/wiki/CIDR CIDR]; l'intervallo cchiù ampio cunzentito è /$1 pe' IPv4 e /$2 pe' IPv6.",
        "ipaddressorusername": "Nnerizzo IP o nomme utente",
        "ipbexpiry": "Ammatura:",
        "ipbreason-dropdown": "* Mutive comune pe' ffà 'o blocco\n** Steva nzertanno nfurmaziune fauze\n** Steva a luvà cuntenute d' 'e paggene\n** Steva a fà spam 'e cullegamiente a 'e site 'e fore\n** Steva a nzertà robbe senza senso dint' 'e paggene\n** Minacce e ntimidaziune\n** Abbuso 'e cunte utente multiple\n** Nomme utente inaccettabbele",
        "ipb-hardblock": "Nun permettere 'o cagnamiento a l'utente riggistrate ca veneno 'a st'indirizzo IP",
        "ipbcreateaccount": "Nun fà crià 'o cunto",
-       "ipbemailban": "Blocca utente a mannà e-mail",
-       "ipbenableautoblock": "Automaticamende blocca l'urdeme indirizze IP ausate 'a st'utente, e pure tutte l'IP c'ausasse pe' pruvà 'e fà ati cagnamiente",
-       "ipbsubmit": "Blocca st'utente",
+       "ipbemailban": "Nun fa mannà e-mail a st'utente",
+       "ipbenableautoblock": "Fremma automaticamende l'urdeme indirizze IP ausate 'a st'utente, e pùre tutte ll'IP c'ausasse pe pruvà 'e fà ati cagnamienti",
+       "ipbsubmit": "Fremma st'utente",
        "ipbother": "N'ata durata:",
        "ipboptions": "2 ore:2 hours,1 juorno:1 day,3 juorne:3 days,1 semmana:1 week,2 semmane:2 weeks,1 mese:1 month,3 mise:3 months,6 mise:6 months,1 anno:1 year,infinito:infinite",
        "ipbhidename": "Annascunne 'o nomme utente d' 'a lista 'e cagnamiente e l'ati liste",
        "ipbwatchuser": "Fà vedé 'a paggena utente e le chiacchieriate 'e st'utente",
        "ipb-disableusertalk": "Nun permettere a st'utente edità 'a paggena 'e chiacchiera d' 'a soja pe' tramente ch'e bloccato",
-       "ipb-change-block": "Blocca n'ata vota l'utente cu sti mpustaziune",
+       "ipb-change-block": "Fremma n'ata vota ll'utente cu ste mpustaziune",
        "ipb-confirm": "Cunferma 'o blocco",
        "badipaddress": "Indirizzo IP nun valido",
        "blockipsuccesssub": "Blocco aseguito",
        "cant-see-hidden-user": "L'utente ca state a bluccà è stato già bluccato e annascunnuto. Si nun tenite 'o deritto ''hideuser'', nun putite veré stu blocco d'utente.",
        "ipbblocked": "Nun putite bloccà o sbluccà utente pecche vuje stesso site bluccato.",
        "ipbnounblockself": "Nun avite permesso a ve bluccà vuje stesso.",
-       "lockdb": "Blocca 'o database",
+       "lockdb": "Nzerra 'o database",
        "unlockdb": "Sblocca 'o database",
        "lockdbtext": "Bluccanno 'o database se luvarranno l'abbilità 'e tutte l'utente 'e cagnà 'e paggene, cagnà 'e preferenze lloro, cagnà 'a lista 'e paggene cuntrullate e ati cose ca richiedessero cagnamiente ô database.\nPe' piacere cunfermate ca chisto e chello ca vulite fà, e ca luvarrate 'o blocco ô database quanno sta manutenziona sarrà fernuta.",
        "unlockdbtext": "Sbluccanno 'o database se s'arrepigliarranno l'abbilità 'e tutte l'utente 'e cagnà 'e paggene, cagnà 'e preferenze lloro, cagnà 'a lista 'e paggene cuntrullate e ati cose ca richiedessero cagnamiente ô database.\nPe' piacere cunfermate ca chisto e chello ca vulite fà.",
        "lockconfirm": "Sì, overo vulesse bluccà 'o database.",
        "unlockconfirm": "Sì, overo vulesse sbluccà 'o database.",
-       "lockbtn": "Blocca 'o database",
+       "lockbtn": "Nzerra 'o database",
        "unlockbtn": "Sblocca 'o database",
        "locknoconfirm": "Nun avite scigliuto 'a casciulella 'e cunferma.",
        "lockdbsuccesssub": "Blocco d' 'o database secutato",
        "months": "{{PLURAL:$1|$1 mese|$1 mese}}",
        "years": "{{PLURAL:$1|$1 anno|$1 anne}}",
        "ago": "$1 fà",
-       "just-now": "mò mò",
+       "just-now": "mo mmo",
        "hours-ago": "$1 {{PLURAL:$1|ora|ore}} fà",
        "minutes-ago": "$1 {{PLURAL:$1|minuto|minute}} fà",
        "seconds-ago": "$1 {{PLURAL:$1|secondo|seconde}} fà",
        "confirmemail": "Cunfermate 'o nderizzo mail",
        "confirmemail_noemail": "Nun tenite nu nderizzo e-mail bbuono pe' ve putè configurà ncopp' 'e [[Special:Preferences|preferenze vuoste]].",
        "confirmemail_text": "{{SITENAME}} bbuò ca vuje validasseve 'o nderizzo e-mail vuosto apprimm' 'e putè ausà 'e ffunziune 'e-mail.\nSpremmete 'o buttone 'e sotto pe' mannà na mmasciata e-mail 'e cunferma a l'indirizzo vuosto.\n'A mmasciata e-mail ca v'arreverrà tenesse nu cullegamento cu nu codece; carrecate 'o cullegamiento dint' 'a nu navigatóre web pe' ve putè cunfermà cu stu ndirizzo e nce ffà assapé 'o sito ch' 'è bbuono.",
-       "confirmemail_pending": "Nu codece 'e cunferma è stato gia mannato a l'email vuosto;\nSi mò mò nu cunto utente avite criato, allora putite aspettà cocche minuto ca chist'arriva, apprimm' 'e pruvà n'ata vota 'addimannà nu codece nuovo.",
+       "confirmemail_pending": "Nu codece 'e cunferma è stato mannato ggià a ll'email vuosto;\nSi avite criato 'a poco nu cunto utente, allòra putite aspettà quacche minuto ca chist'arriva, primm' 'e pruvà n'ata vota a 'ddimannà nu codece nuovo.",
        "confirmemail_send": "Manna nu codece 'e cunferma",
        "confirmemail_sent": "Mmasciata e-mail 'e cunferma mannata.",
        "confirmemail_oncreate": "'O codece 'e cunferma è stato mannato al'indirizzo e-mail d' 'o vuosto.\nStu codece nun è addimannato pe' ve putè fà trasì, ma vuje n'avite abbesuogno 'e l'avé apprimm' 'e putè ausà cocche funziune 'e chille ca facessero l'uso d' 'o cunto e-mail ncopp'a sta wiki.",
        "confirmemail_sendfailed": "{{SITENAME}} nun può mannà 'a mmasciata e-mail d' 'a vuosta 'e cunferma.\nPe' piacere cuntrullate si 'o nderizzo e-mail c'avite scritto tenesse cocche carattere nvalido.\n\nMmasciata d'errore a 'o mailer: $1",
        "confirmemail_invalid": "'O codece 'e cunferma nun è bbuono.\n'O codece fosse ammaturato.",
        "confirmemail_needlogin": "Abbesognate $1 pe cunfirmà 'o nnerizzo 'e e-mail d''o vuosto.",
-       "confirmemail_success": "'O ndirizzo e-mail d' 'o vuosto è stato cunfermato.\nVuje mò ne putite [[Special:UserLogin|trasì]] e ve putite spassà ncopp' 'a wiki.",
+       "confirmemail_success": "'O ndirizzo e-mail d' 'o vuosto è stato cunfermato.\nMo putite [[Special:UserLogin|trasì]] e ve putite spassà ncopp' 'a wiki.",
        "confirmemail_loggedin": "'O nnerizzo 'e e-mail è vàleto",
        "confirmemail_subject": "Indirizzo e-mail 'e cunferma pe' {{SITENAME}}",
        "confirmemail_body": "Coccheruno, può darse ca site vuje, 'a l'indirizzo IP $1,\nha riggistrato nu cunto utente \"$2\" cu st'indirizzo e-mail ncopp'a {{SITENAME}}.\n\nPe' putè cunfermà ca stu cunto è stato overo criato e vuje e ve putè apiccià 'a funziona e-mail 'e {{SITENAME}}, arapite stu cullegamento dint' 'o navigatóre web d' 'o vuosto:\n\n$3\n\nSi vuje *NUN* avite riggistrato 'o cunto utente, secutate stu cullegamento pe' ve scancellà st'indirizzo e-mail utente:\n\n$5\n\nStu codece 'e cunferma murarrà 'o $4.",
        "invalidateemail": "Scancella 'a cunferma 'e l'e-mail",
        "notificationemail_subject_changed": "L'indirizzo email riggistrato ncopp'a {{SITENAME}} è stato cagnato",
        "notificationemail_subject_removed": "L'indirizzo email riggistrato dint'a {{SITENAME}} è stato luvato",
-       "notificationemail_body_changed": "Coccheruno, probbabilmente vuje, 'a ll'indirizzo IP $1,\nave cagnato l'indirizze e-mail d' 'o cunto \"$2\" a \"$3\" ncopp'a {{SITENAME}}.\n\nSi nun eravate vuje, pe' piacere tuzzuliate mò mò n'ammenistratore.",
-       "notificationemail_body_removed": "Coccheruno, probbabilmente vuje, 'a ll'indirizzo IP $1,\nave luvato l'indirizze e-mail d' 'o cunto \"$2\" ncopp'a {{SITENAME}}.\n\nSi nun eravate vuje, pe' piacere tuzzuliate mò mò n'ammenistratore.",
+       "notificationemail_body_changed": "Coccheruno, probbabilmente vuje, a ll'indirizzo IP $1,\nave cagnato 'o ndirizzo e-mail d' 'o cunto \"$2\" a \"$3\" ncopp'a {{SITENAME}}.\n\nSi nun eravate vuje, pe piacere tuzzuliate a n'ammenistratore primma 'e mo.",
+       "notificationemail_body_removed": "Coccheruno, probbabilmente vuje, 'a ll'indirizzo IP $1,\nave luvato l'indirizze e-mail d' 'o cunto \"$2\" ncopp'a {{SITENAME}}.\n\nSi nun eravate vuje, pe piacere tuzzuliate a n'ammenistratore.",
        "scarytranscludedisabled": "['A funziona cullegamiento nfra site wiki è stata stutata]",
        "scarytranscludefailed": "[L'analisi d' 'o template s'è scassato pe' $1]",
        "scarytranscludefailed-httpstatus": "[L'analisi d' 'o template s'è scassato pe' $1: HTTP $2]",
        "timezone-local": "Lucale",
        "duplicate-defaultsort": "<strong>Attenziò:</strong> A chiave d'arricetto \"$2\" se miette ncuollo a nu valore 'e primma \"$1\".",
        "duplicate-displaytitle": "<strong>Attenziò:</strong> A chiave d'arricetto \"$2\" se scagna p' 'o valore 'e primma \"$1\".",
-       "restricted-displaytitle": "<strong>Attenziò:</strong> 'O titolo ccà \"$1\" è stato lassato perdere pecché nun fosse eguale a 'o titolo 'e mò d' 'a paggena.",
+       "restricted-displaytitle": "<strong>Attenziò:</strong> 'O titolo ccà \"$1\" è stato lassato perdere pecché nun fosse eguale a 'o titolo 'e mo d' 'a paggena.",
        "invalid-indicator-name": "<strong>Errore:</strong> attribbuto <code>name</code> 'e ll'innecature d' 'o stato d' 'a paggena nu può rummanè abbacante.",
        "version": "Verziona",
        "version-extensions": "Estenziune installate",
        "specialpages-group-maintenance": "Report 'e manutenzione",
        "specialpages-group-other": "Ati paggene speciale",
        "specialpages-group-login": "Trasite o criate n'acciesso nuovo",
-       "specialpages-group-changes": "Cagnamiente 'e mò mò e riggistre",
+       "specialpages-group-changes": "Urdeme cagnamiénte e riggistre",
        "specialpages-group-media": "Riepileghe 'e media e carreche",
        "specialpages-group-users": "Utente e deritte",
        "specialpages-group-highuse": "Pàggene ausate assaje proprio",
        "tags-create-warnings-below": "Vulite cuntinuà a crià 'o tag?",
        "tags-delete-title": "Scancella tag",
        "tags-delete-explanation-initial": "State pe' scancellà 'o tag \"$1\" d' 'o database.",
-       "tags-delete-explanation-in-use": "Sarrà luvato d' 'o {{PLURAL:$2|$2 verziona o d' 'o riggistro|tutt' 'e verziune $2 e/o 'e nutarelle int' 'o riggistro}} ô quale fosse azzeccato mò mò.",
+       "tags-delete-explanation-in-use": "Sarrà luvato d' 'o {{PLURAL:$2|$2 verziona o d' 'o riggistro|tutt' 'e verziune $2 e/o 'e nutarelle int' 'o riggistro}} addò stesse azzeccato.",
        "tags-delete-explanation-warning": "St'aziona è <strong>irreversibbele</strong> e <strong>nun se pò turnà arreto</strong>, pure 'a ll'ammenistrature d' 'o database. Faciteve capace ca stu tag è chillu ca vulite scancellà.",
        "tags-delete-explanation-active": "<strong>'O tag \"$1\" è ancora attivo, e sarrà apprecato int' 'o futuro.</strong> Pe' fernì cu st'attività, jate, a lloco addò 'o tag s'è apprecato, e stutate llànno.",
        "tags-delete-reason": "Mutivo:",
        "dberr-info": "(Nun se può trasì 'o database: $1)",
        "dberr-info-hidden": "(Nun se può trasì 'o database)",
        "dberr-usegoogle": "Pe' tramente putite pruvà 'ascianno ncoppa Google.",
-       "dberr-outofdate": "Vedite ca l'indice lloro d' 'e cuntenute nuoste ponno nun essere agghiurnate mò mò.",
+       "dberr-outofdate": "Vedite ca ll'indice lloro d'ê cuntenute nuoste ponno essere passate.",
        "dberr-cachederror": "Chest'è na copia \"cache\" d' 'a paggena c'avite asciato, e putesse nun essere agghiurnata.",
        "htmlform-invalid-input": "Ce sta cocche probblema cu l'input c'avite miso.",
        "htmlform-select-badoption": "'O valore c'avite specificato nun è n'opziona bbuona.",
        "logentry-delete-delete": "$1 {{GENDER:$2|scancellaje}} 'a paggena $3",
        "logentry-delete-restore": "$1 {{GENDER:$2|arrepigliaje}} 'a paggena $3 ($4)",
        "logentry-delete-event": "$1 {{GENDER:$2|cagnaie}} 'a vesibbiletà 'e {{PLURAL:$5|n'azione d' 'o riggistro|$5 aziune d' 'o riggistro}} ncopp' 'a 'a $3: $4",
-       "logentry-delete-revision": "$1 {{GENDER:$2|cagnaie}} 'a vesibbiletà 'e {{PLURAL:$5|na verziona|$5 verziune}} ncopp' 'a 'a $3: $4",
-       "logentry-delete-event-legacy": "$1 {{GENDER:$2|cagnaie}} 'a vesibbiletà 'e l'aziune dint' 'o riggistro ncopp' 'a $3: $4",
-       "logentry-delete-revision-legacy": "$1 {{GENDER:$2|cagnaie}} 'a vesibbiletà d' 'e verziune ncopp' 'a $3",
+       "logentry-delete-revision": "$1 {{GENDER:$2|cagnaie}} 'a vesibbiletà 'e {{PLURAL:$5|na verziona|$5 verziune}} ncopp'a $3: $4",
+       "logentry-delete-event-legacy": "$1 {{GENDER:$2|cagnaie}} 'a vesibbiletà 'e l'aziune int' 'o riggistro ncopp'a $3: $4",
+       "logentry-delete-revision-legacy": "$1 {{GENDER:$2|cagnaie}} 'a vesibbiletà d'ê verziune ncopp'a $3",
        "logentry-suppress-delete": "$1 {{GENDER:$2|luvaje pe' sempe}} 'a paggena $3",
        "logentry-suppress-event": "$1 {{GENDER:$2|annascunnuto cagnaie|annascunnuta cagnaie}} 'a vesibbiletà 'e {{PLURAL:$5|n'azione d' 'o riggistro|$5 aziune d' 'o riggistro}} ncopp' 'a 'a $3: $4",
        "logentry-suppress-revision": "$1 {{GENDER:$2|annascunnuto cagnaie|annascunnuta cagnaie}} 'a vesibbiletà 'e {{PLURAL:$5|na verziona|$5 verziune}} ncopp' 'a 'a $3: $4",
-       "logentry-suppress-event-legacy": "$1 {{GENDER:$2|annascunnuto cagnaie|annascunnuta cagnaie}} 'a vesibbiletà 'e l'aziune 'e riggistro ncopp' 'a $3",
-       "logentry-suppress-revision-legacy": "$1 {{GENDER:$2|annascunnuto cagnaie|annascunnuta cagnaie}} 'a vesibbiletà d' 'e verziune ncopp' 'a $3",
+       "logentry-suppress-event-legacy": "$1 cagnaie {{GENDER:$2|annascunnuto|annascunnuta}} 'a vesibbiletà 'e l'aziune 'e riggistro ncopp' 'a $3",
+       "logentry-suppress-revision-legacy": "$1 cagnaie {{GENDER:$2|annascunnuto|annascunnuta}} 'a vesibbiletà d' 'e verziune ncopp'a $3",
        "revdelete-content-hid": "cuntenute annascunnute",
        "revdelete-summary-hid": "riepilego 'e cagnamiente annascunnute",
        "revdelete-uname-hid": "nomme utente annascunnuto",
        "log-name-pagelang": "Cagna 'o riggistro d' 'a lengua",
        "log-description-pagelang": "Chest'è nu riggistro 'e cagnamiente 'e lengua d' 'e paggene.",
        "logentry-pagelang-pagelang": "$1 {{GENDER:$2|ave cagnato}} 'a lengua d' 'a paggena $3 'a $4 a $5.",
-       "default-skin-not-found": "Oops! 'A skin predefinta ' 'o wiki vuosto, definita 'n <code dir=\"ltr\">$wgDefaultSkin</code> comme <code>$1</code>, nun se tròva.\n\n'A installazione pare ca tenesse {{PLURAL:$4|'a skin|'e skin}} ccà abbascio. Vedite [https://www.mediawiki.org/wiki/Manual:Skin_configuration Manuale: configurazione skin] pe' n'avè cchiù nfurmaziune ncopp' 'a manera {{PLURAL:$4|'e ll'abbià}} o scegliere chilla predefinita.\n\n$2\n\n; Si avite installato MediaWiki mò mò:\n: Probabbilmente l'avite installato 'a git, o direttamente 'a 'o codece sorgente ausanno cocch'atu metodo. Chesto era permesso. Verite 'e installà cocche skin 'a [https://www.mediawiki.org/wiki/Category:All_skins directory ncoppa mediawiki.org], tramite:\n:* Scarrecanno 'o [https://www.mediawiki.org/wiki/Download programma 'e installazione tarball], ca venesse fornito ch' 'e diverze skin ed estenziune. Putite fare copia-azzecca d' 'a directory <code dir=\"ltr\">skins/</code>.\n:* Scarrecanne 'e tarballs individuale 'e skin 'a [https://www.mediawiki.org/wiki/Special:SkinDistributor mediawiki.org].\n:* [https://www.mediawiki.org/wiki/Download_from_Git#Using_Git_to_download_MediaWiki_skins Ausanno Git pe' scarrecà skin].\n: Facenno accussì nun se mmescasse 'o repository git vuosto si site sviluppatore MediaWiki.\n\n; Si avite MediaWiki agghiurnato MediaWiki mò mò:\n: MediaWiki 1.24 e verziune appriesso nun abbìa automatecamente 'e skin installate (vedite [https://www.mediawiki.org/wiki/Manual:Skin_autodiscovery Manuale: rilevamento automateco skin]). Putite copià {{PLURAL:$5|'a linea|'e linee}} ccà abbascio dint' 'o <code>LocalSettings.php</code> pe' putè appiccià {{PLURAL:$5|'o|tutt' 'e}} {{PLURAL:$5|skin}} installate mò mò:\n\n<pre dir=\"ltr\">$3</pre>\n\n; Si avite cagnato mò mò <code>LocalSettings.php</code>:\n: Cuntrullate 'e nomme d' 'e skin n'ata vota pe' ve sparagnà cocch'errore 'e battitura.",
+       "default-skin-not-found": "Mannàggia! 'A skin predefinta ' 'o wiki vuosto, definita 'n <code dir=\"ltr\">$wgDefaultSkin</code> comme <code>$1</code>, nun se tròva.\n\n'A installazione pare ca tenesse {{PLURAL:$4|'a skin|'e skin}} ccà abbascio. Vedite [https://www.mediawiki.org/wiki/Manual:Skin_configuration Manuale: configurazione skin] pe n'avè cchiù nfurmaziune ncopp' 'a manera {{PLURAL:$4|'e ll'abbià}} o seleziunà chella predefinita.\n\n$2\n\n; Si avite installato MediaWiki mo mo:\n: Probabbilmente l'avite installato 'a git, o direttamente ro codece sorgente ausanno quacch'atu metodo. Ne putiva fà. Verite 'e installà quacche skin 'a [https://www.mediawiki.org/wiki/Category:All_skins directory ncoppa mediawiki.org], tramite:\n:* Scarrecanno 'o [https://www.mediawiki.org/wiki/Download programma 'e installazione tarball], ca venesse dato cu 'e diverze skin e estenziune. Putite fà copia-azzecca d' 'a directory <code dir=\"ltr\">skins/</code>.\n:* Scarrecanne 'e tarballs individuale 'e skin 'a [https://www.mediawiki.org/wiki/Special:SkinDistributor mediawiki.org].\n:* [https://www.mediawiki.org/wiki/Download_from_Git#Using_Git_to_download_MediaWiki_skins Ausanno Git pe' scarrecà skin].\n: Facenno accussì nun se mmescasse 'o repository git vuosto si site sviluppatore MediaWiki.\n\n; Si avite MediaWiki agghiurnato MediaWiki mò mò:\n: MediaWiki 1.24 e verziune appriesso nun abbìa automatecamente 'e skin installate (vedite [https://www.mediawiki.org/wiki/Manual:Skin_autodiscovery Manuale: rilevamento automateco skin]). Putite copià {{PLURAL:$5|'a linea|'e linee}} ccà abbascio dint' 'o <code>LocalSettings.php</code> pe' putè appiccià {{PLURAL:$5|'o|tutt' 'e}} {{PLURAL:$5|skin}} installate mo mmo:\n\n<pre dir=\"ltr\">$3</pre>\n\n; Si avite cagnato mo mo <code>LocalSettings.php</code>:\n: Cuntrullate 'e nomme d' 'e skin n'ata vota pe' ve sparagnà ciert'errure 'e battitura.",
        "default-skin-not-found-no-skins": "oops! 'O skin predefinito p' 'a wiki vuosta, definito int'a <code>$wgDefaultSkin</code> comm'a <code>$1</code>, nun è a disposizione.\n\nVuje nun tenite nisciuno skin installato.\n\n; Si avite installato o agghiurnato MediaWiki mo' mo':\n: È possibbele ca l'avite installato 'a git, o direttamente d' 'o codece sorgente ausanno n'atu metodo. Chesto s'aspettava. Mediawiki 1.24 o cchiù nuova nun include nisciuno skin dint' 'o repositorio prencepale. Tentate 'e installà cocche skin 'a [https://www.mediawiki.org/wiki/Category:All_skins sta cartella 'e mediawiki.org], facenno:\n:* Scarreca 'e [https://www.mediawiki.org/wiki/Download tarball installer], ca venesse cu nu cuofeno 'e skin e estensiune. Vuje putite cupià e azzeccà 'a cartella <code>skins/</code> 'a chiste.\n:* Scarrecanno tarball 'e skin individuale 'a [https://www.mediawiki.org/wiki/Special:SkinDistributor mediawiki.org].\n:* [https://www.mediawiki.org/wiki/Download_from_Git#Using_Git_to_download_MediaWiki_skins Ausanno Git pe' puté scarrecà skin].\n: A ffà chesto nun avesse nteferì c' 'o repositorio d' 'o git vuosto, si vuje site sviluppatore MediaWiki. Vedite [https://www.mediawiki.org/wiki/Manual:Skin_configuration Manuale: Mpustaziona skin] pe' n'avé nfurmaziune ncopp'a comme s'avesser'appiccià skin e scegliere 'o valore predefinito.",
        "default-skin-not-found-row-enabled": "* <code>$1</code> / $2 (funzione appicciata)",
        "default-skin-not-found-row-disabled": "* <code>$1</code> / $2 (<strong>funzione stutata</strong>)",
        "authmanager-authplugin-setpass-denied": "'O plugin autenticazione nun premmettesse 'e cagnà 'e password.",
        "authmanager-authplugin-setpass-bad-domain": "Dominio invalido.",
        "authmanager-autocreate-noperm": "'A criazione automatica 'e ll'utenza nun fosse premmessa.",
-       "authmanager-autocreate-exception": "Criazione 'e cunte automatica mò mò è stutata pe' bbìa 'e ll'errure precedenti.",
+       "authmanager-autocreate-exception": "Criazione 'e cunte automatica stutata pe nu poc'ê tiempo pe vvìa 'e ll'errure precedenti.",
        "authmanager-userdoesnotexist": "'O cunto utente \"$1\" nun è riggistrato.",
        "authmanager-userlogin-remembermypassword-help": "Si 'a pasword adda essere arricurdata cchiù a luongo cu rispett'a tutt' 'a durata d' 'a sessione.",
        "authmanager-username-help": "Nomme utente pe' ll'autenticaziona.",
        "authmanager-provider-password": "Autenticaziona basata ncopp' 'a password",
        "authmanager-provider-password-domain": "Autenticaziona cu' password e basata ncopp'a nu dominio",
        "authmanager-provider-temporarypassword": "Password a tiempo determinato",
-       "authprovider-confirmlink-message": "Verenno 'e tentative d'acciesso mò, l'utente ccà putessero avé nu cullegamento c' 'o cunto wiki d' 'o vuosto. A ffà cullegamento premmettesse appiccià 'o sistema 'e trasuta pe' bbìa 'e sti cunte. Pe' piacere sciglite 'e cunte addò vulite fà cullegamento.",
+       "authprovider-confirmlink-message": "Verenno 'e tentative d'acciesso, chisti cunte ccà putessero avé nu cullegamento c' 'o cunto wiki d' 'o vuosto. Jontanneli premmettesse appiccià 'o sistema 'e trasuta cu sti cunte. Pe piacere sciglite 'e cunte ca vulite jontà.",
        "authprovider-confirmlink-request-label": "Cunte ca s'avesser'a cullegà",
        "authprovider-confirmlink-success-line": "$1: cullegato e apposto.",
        "authprovider-confirmlink-failed": "'O cullegamento 'e ll'utenza nun è ngarrato sano sano: $1",
index c7cc0c6..944031d 100644 (file)
        "rc-enhanced-hide": "Details verbargen",
        "rc-old-title": "oorspronkelik an-emaakt as \"$1\"",
        "recentchangeslinked": "Soortgelyke wysigingen",
-       "recentchangeslinked-feed": "Volg verwiezigingen",
-       "recentchangeslinked-toolbox": "Volg verwiezigingen",
+       "recentchangeslinked-feed": "Volg verwysingen",
+       "recentchangeslinked-toolbox": "Volg verwysingen",
        "recentchangeslinked-title": "Wiezigingen verwaant an $1",
        "recentchangeslinked-summary": "Op disse spesiale zied steet n lieste mit de leste wieziginen op ziejen waornaor verwezen wördt. Ziejen op [[Special:Watchlist|joew volglieste]] staon '''vet'''.",
        "recentchangeslinked-page": "Ziednaam:",
index 5b70e43..c9862b6 100644 (file)
        "rcfilters-invalid-filter": "Ugyldig filter",
        "rcfilters-empty-filter": "Ingen aktive filter. Alle bidrag er viste.",
        "rcfilters-filterlist-title": "Filter",
+       "rcfilters-filterlist-whatsthis": "Korleis verkar desse?",
        "rcfilters-filterlist-feedbacklink": "Gje attendemelding på dei nye (beta)filtera",
        "rcfilters-highlightbutton-title": "Uthev resultat",
        "rcfilters-highlightmenu-title": "Vel ein farge",
index 993924c..1b14a70 100644 (file)
        "rcfilters-activefilters": "Filtres actius",
        "rcfilters-advancedfilters": "Filtres avançats",
        "rcfilters-limit-title": "Resultats d'affichar",
+       "rcfilters-days-title": "Darrièrs jorns",
        "rcfilters-hours-title": "Darrièras oras",
        "rcfilters-days-show-days": "($1 {{PLURAL:$1|jorn|jorns}})",
        "rcfilters-days-show-hours": "$1 {{PLURAL:$1|ora|oras}}",
+       "rcfilters-highlighted-filters-list": "Mes en evidéncia: $1",
        "rcfilters-quickfilters": "Filtres salvats",
        "rcfilters-quickfilters-placeholder-title": "Pas encara de filtre salvagardat",
        "rcfilters-quickfilters-placeholder-description": "Per salvagardar los paramètres de los vòstres filtres e tornar los utilizar mai tard , clicatz sus l'icòna dels favorits dins l'airal de Filtres Actius, dejós.",
        "rcfilters-highlightmenu-help": "Causir una color per valorar aquesta proprietat",
        "rcfilters-filterlist-noresults": "Cap de filtre pas trobat",
        "rcfilters-noresults-conflict": "S'es pas trobat cap de resultat perque los critèris de cèrca son en conflicte",
+       "rcfilters-state-message-subset": "Aquel filtre fonciona pas perque los seus resultats son inclús dins los resultats de la cerca seguenta , {{PLURAL:$2|filtre mai larg |filtres mai larges}} (ensajatz de los destriar amb la mesa en forma): $1",
+       "rcfilters-state-message-fullcoverage": "Seleccionar totes los filtres d'aquel grop es equivalent a una seleccion voida, doncas aquel filtre a pas d'efèit. Lo grop compren: $1",
        "rcfilters-filtergroup-authorship": "Paternitat de las contribucions",
        "rcfilters-filter-editsbyself-label": "Modificacions faitas per vos",
        "rcfilters-filter-editsbyself-description": "Vòstras pròprias contribucions.",
        "rcfilters-filter-editsbyother-label": "Modificacions faitas pels autres.",
+       "rcfilters-filter-editsbyother-description": "Totes los cambiaments a l'excepcion de los vòstres.",
+       "rcfilters-filtergroup-userExpLevel": "Registrament dels usatgièrs e experiéncia",
        "rcfilters-filter-user-experience-level-registered-label": "Connectat",
        "rcfilters-filter-user-experience-level-registered-description": "Editors connectats.",
        "rcfilters-filter-user-experience-level-unregistered-label": "Pas connectat",
        "rcfilters-filter-user-experience-level-unregistered-description": "Editors que son pas connectats.",
        "rcfilters-filter-user-experience-level-newcomer-label": "Novèls arribants",
+       "rcfilters-filter-user-experience-level-newcomer-description": "Editors registrats qu'an fait mens de 10 cambiaments o que son actius dempuèi mens de 4 jorns.",
        "rcfilters-filter-user-experience-level-learner-label": "Aprenents",
+       "rcfilters-filter-user-experience-level-learner-description": "Editors registrats, que lor nivèl d'experiéncia es entre \"Utilizaire novelari\" e \"Utilizaire experimentat.\"",
        "rcfilters-filter-user-experience-level-experienced-label": "Utilizaires experimentats",
+       "rcfilters-filter-user-experience-level-experienced-description": "Editors registrats amb mai de 500 cambiaments e 30 jorns d'activitat.",
        "rcfilters-filtergroup-automated": "Contribucions automatizadas",
        "rcfilters-filter-bots-label": "Robòt",
+       "rcfilters-filter-bots-description": "Cambiaments faits per d'aisinas automaticas",
        "rcfilters-filter-humans-label": "Èsser uman (pas robòt)",
        "rcfilters-filter-humans-description": "Modificacions faitas per d'editors umans.",
+       "rcfilters-filtergroup-reviewstatus": "Estat de revision",
+       "rcfilters-filter-reviewstatus-unpatrolled-description": "Cambiaments que son pas marcats coma revisats manualament o automaticament.",
        "rcfilters-filter-reviewstatus-unpatrolled-label": "Pas patrolhat",
+       "rcfilters-filter-reviewstatus-manual-description": "Cambiaments manuals marcats coma revisats",
+       "rcfilters-filter-reviewstatus-manual-label": "Verificat manualament",
+       "rcfilters-filter-reviewstatus-auto-description": "Edicions per d'usatgièrs experimentats que lor trabalh es marcat automaticament coma verificat.",
+       "rcfilters-filter-reviewstatus-auto-label": "Verificat automaticament",
        "rcfilters-filtergroup-significance": "Significacion",
        "rcfilters-filter-minor-label": "Cambiaments menors",
        "rcfilters-filter-minor-description": "Modificacions que l'autor a marcadas coma menoras.",
        "rcfilters-filter-major-label": "Modificacions pas menoras",
        "rcfilters-filter-major-description": "Modificacions pas marcadas coma menoras.",
+       "rcfilters-filtergroup-watchlist": "Paginas de la lista de seguiment",
+       "rcfilters-filter-watchlist-watched-label": "Sus la lista de seguiment",
+       "rcfilters-filter-watchlist-watched-description": "Cambiaments faits sus las paginas de la vòstra lista de seguiment.",
+       "rcfilters-filter-watchlist-watchednew-label": "Cambiaments novèls dins la lista de seguiment",
+       "rcfilters-filter-watchlist-watchednew-description": "Cambiaments dins las paginas en seguiment qu'avètz pas vistas dempuèi que de cambiaments foguèron faits.",
+       "rcfilters-filter-watchlist-notwatched-label": "Es pas sus la lista de seguiment",
+       "rcfilters-filter-watchlist-notwatched-description": "Tot a l'excepcion de cambiaments faits sus las vòstras paginas de seguiment.",
+       "rcfilters-filtergroup-watchlistactivity": "Activitat sus la lista de seguiment",
+       "rcfilters-filter-watchlistactivity-unseen-label": "Cambiaments pas vists",
+       "rcfilters-filter-watchlistactivity-unseen-description": "Cambiaments dins las paginas en seguiment qu'avètz pas vistas dempuèi que de cambiaments foguèron faits.",
+       "rcfilters-filter-watchlistactivity-seen-label": "Cambiaments qu'avètz ja vistes",
+       "rcfilters-filter-watchlistactivity-seen-description": "Cambiaments dins las paginas  qu'avètz vistas dempuèi que de cambiaments foguèron faits.",
        "rcfilters-filtergroup-changetype": "Tipe de cambiament",
        "rcfilters-filter-pageedits-label": "Modificacions de pagina",
        "rcfilters-filter-pageedits-description": "Modificacions del contengut del wiki, de las discussions, de las descripcions de las categorias...",
        "rcfilters-filter-newpages-label": "Creacions de pagina",
        "rcfilters-filter-newpages-description": "Modificacions a l'origina de paginas novèlas.",
        "rcfilters-filter-categorization-label": "Cambiaments de categoria",
+       "rcfilters-filter-categorization-description": "Registraments de paginas apondudas o suprimidas de las categorias.",
        "rcfilters-filter-logactions-label": "Accions traçadas",
        "rcfilters-filter-logactions-description": "Accions dels administrators, creacions de comptes, supressions de paginas, telecargaments...",
+       "rcfilters-hideminor-conflicts-typeofchange": "D'unes tipes de cambiament pòdon pas èsser designats coma  \"minors\", doncas aqueste filtre es en conflicte amb los filtres  de Tipe de cambiament seguent: $1",
+       "rcfilters-typeofchange-conflicts-hideminor": "Aqueste filtre «Tipe de cambiament» es en conflicte amb lo filtre «Edicions minoras». D'unes tipes de cambiaments  pòdon pas èstre considerats coma «minors».",
+       "rcfilters-filtergroup-lastRevision": "Darrièras revisions",
+       "rcfilters-filter-lastrevision-label": "Darrièra revision",
+       "rcfilters-filter-lastrevision-description": "Sonque lo cambiament de pagina lo mai recent.",
+       "rcfilters-filter-previousrevision-label": "Pas la darrièra revision",
+       "rcfilters-filter-previousrevision-description": "Totes los cambiaments que son pas «la darrièra revision».",
+       "rcfilters-filter-excluded": "Exclús",
+       "rcfilters-tag-prefix-namespace-inverted": "<strong>:Pas</strong> $1",
+       "rcfilters-exclude-button-off": "Exclure los seleccionats",
+       "rcfilters-exclude-button-on": "Seleccionats excluses",
+       "rcfilters-view-tags": "Cambiaments marcats",
+       "rcfilters-view-namespaces-tooltip": "Resultat del filtratge per espaci de noms",
+       "rcfilters-view-tags-tooltip": "Resultat del filtratge per etiqueta d'edicion",
+       "rcfilters-view-return-to-default-tooltip": "Tornar al menut de filtres principal",
+       "rcfilters-view-tags-help-icon-tooltip": "Ne saber mai suls cambiaments marcats",
+       "rcfilters-liveupdates-button": "Actualizacion en dirècte",
+       "rcfilters-liveupdates-button-title-on": "Desactivar los cambiaments en dirècte",
        "rcnotefrom": "Çaijós {{PLURAL:$5|la modificacion efectuada|las modificacions efectuadas}} dempuèi lo <strong>$3, $4</strong> (afichadas fins a <strong>$1</strong>).",
        "rclistfrom": "Afichar las modificacions novèlas dempuèi lo $3 $2",
        "rcshowhideminor": "$1 los cambiaments menors",
index 8158169..70e089a 100644 (file)
        "botpasswords-restriction-failed": "Logowanie nie powiodło się z powodu ograniczeń na hasło bota.",
        "botpasswords-invalid-name": "Określona nazwa użytkownika nie zawiera separatora hasła bota (\"$1\").",
        "botpasswords-not-exist": "Użytkownik \"$1\" nie ma hasła dla bota o nazwie \"$2\".",
+       "botpasswords-needs-reset": "Hasło dla bota o nazwie „$2” {{GENDER:$1|użytkownika|użytkowniczki}} „$1” musi zostać zresetowane.",
        "resetpass_forbidden": "Hasła nie mogą zostać zmienione",
        "resetpass_forbidden-reason": "Hasła nie mogą zostać zmienione: $1",
        "resetpass-no-info": "Musisz być zalogowany, by uzyskać bezpośredni dostęp do tej strony.",
index a229e76..4bcde5e 100644 (file)
        "passwordpolicies-policy-minimumpasswordlengthtologin": "A senha deve ter pelo menos $1 {{PLURAL:$1|caráter|caracteres}} para poder entrar",
        "passwordpolicies-policy-passwordcannotmatchusername": "Senha não pode ser o mesmo que nome de usuário",
        "passwordpolicies-policy-passwordcannotmatchblacklist": "A senha não pode corresponder senhas especificamente na lista negra",
-       "passwordpolicies-policy-maximalpasswordlength": "A senha deve ser menor que $1 {{PLURAL:$1|caráter|caracteres}}"
+       "passwordpolicies-policy-maximalpasswordlength": "A senha deve ser menor que $1 {{PLURAL:$1|caráter|caracteres}}",
+       "passwordpolicies-policy-passwordcannotbepopular": "A senha não pode {{PLURAL:$1|ser a mais popular|estar na lista das $1 palavras-passe mais populares}}"
 }
index 700d01a..011b3cf 100644 (file)
        "protectedtitles-submit": "Mostrar títulos",
        "listusers": "Utilizadores",
        "listusers-editsonly": "Mostrar apenas utilizadores com edições",
+       "listusers-temporarygroupsonly": "Mostrar apenas os utilizadores em grupos de utilizadores temporários",
        "listusers-creationsort": "Ordenar por data de criação",
        "listusers-desc": "Ordenar de forma decrescente",
        "usereditcount": "$1 {{PLURAL:$1|edição|edições}}",
        "pagedata-bad-title": "Título inválido: $1.",
        "unregistered-user-config": "Por razões de segurança as subpáginas de utilizador com JavaScript, CSS e JSON não podem ser carregadas para utilizadores não registados.",
        "passwordpolicies": "Regras para palavras-passe",
+       "passwordpolicies-summary": "Esta lista contém as normas efetivas para palavras-passe dos grupos de utilizadores definidos nesta wiki.",
        "passwordpolicies-group": "Grupo",
-       "passwordpolicies-policies": "Normas e recomendações"
+       "passwordpolicies-policies": "Normas e recomendações",
+       "passwordpolicies-policy-minimalpasswordlength": "A palavra-passe tem de ter pelo menos $1 {{PLURAL:$1|carácter|caracteres}}",
+       "passwordpolicies-policy-minimumpasswordlengthtologin": "A palavra-passe tem de ter pelo menos $1 {{PLURAL:$1|carácter|caracteres}} para poder iniciar sessão",
+       "passwordpolicies-policy-passwordcannotmatchusername": "A palavra-passe não pode ser igual ao nome de utilizador",
+       "passwordpolicies-policy-passwordcannotmatchblacklist": "A palavra-passe não pode corresponder às especificamente bloqueadas pela lista negra",
+       "passwordpolicies-policy-maximalpasswordlength": "A palavra-passe tem de ter menos de $1 {{PLURAL:$1|carácter|caracteres}}",
+       "passwordpolicies-policy-passwordcannotbepopular": "A palavra-passe não pode {{PLURAL:$1|ser a mais popular|estar na lista das $1 palavras-passe mais populares}}"
 }
index 417e0f7..139c91c 100644 (file)
        "unregistered-user-config": "Shown when viewing a user JS, CSS or JSON subpage with ?action=raw&ctype=<mime type> where there is no such user. It is shown as a paragraph after a header saying 'Forbidden'.",
        "passwordpolicies": "The name of the special page [[Special:PasswordPolicies]].",
        "passwordpolicies-summary": "The description used on [[Special:PasswordPolicies]].\n\nRefers to {{msg-mw|Passwordpolicies-helppage}}.",
-       "passwordpolicies-helppage": "The link used on [[Special:PasswordPolicies]].",
        "passwordpolicies-group": "The title of the column in the table, about user groups (like you are in the ''translator'' group).\n\n{{Identical|Group}}\n{{Related|Passwordpolicies}}",
        "passwordpolicies-policies": "The title of the column in the table, about password policies.\n{{Related|Passwordpolicies}}",
        "passwordpolicies-policy-display": "{{optional}}\nParameters:\n* $1 - the text from the \"passwordpolicies-policy-...\" messages, i.e. {{msg-mw|passwordpolicies-policy-minimalpasswordlength}}\n* $2 - the name of this password policy",
index 740c9f2..cb006f0 100644 (file)
@@ -9,7 +9,8 @@
                        "C.R.",
                        "Macofe",
                        "Purodha",
-                       "Fitoschido"
+                       "Fitoschido",
+                       "Ruthven"
                ]
        },
        "tog-underline": "Collegaminde sottolinèate:",
index b5331b2..25063c8 100644 (file)
        "pagetitle-view-mainpage": "{{SITENAME}}",
        "backlinksubtitle": "← $1",
        "retrievedfrom": "Источник — «$1»",
-       "youhavenewmessages": "Вы получили $1 ($2).",
+       "youhavenewmessages": "{{PLURAL:$3|Вы получили}} $1 ($2).",
        "youhavenewmessagesfromusers": "{{PLURAL:$4|Вы получили}} $1 от {{PLURAL:$3|$3 участника|$3 участников|1=другого участника}} ($2).",
        "youhavenewmessagesmanyusers": "Вы получили $1 от множества пользователей ($2).",
        "newmessageslinkplural": "{{PLURAL:$1|1=новое сообщение|999=новые сообщения}}",
        "nextn-title": "{{PLURAL:$1|Следующая $1 запись|Следующие $1 записи|Следующие $1 записей}}",
        "shown-title": "Показывать $1 {{PLURAL:$1|запись|записи|записей}} на странице",
        "viewprevnext": "Просмотреть ($1 {{int:pipe-separator}} $2) ($3)",
-       "searchmenu-exists": "'''В этой вики есть страница «[[:$1]]»'''",
+       "searchmenu-exists": "<strong>В этой вики есть страница «[[:$1]]».</strong> {{PLURAL:$2|0=|См. также другие результаты поиска.}}",
        "searchmenu-new": "<strong>Создать страницу «[[:$1]]» в этом вики-проекте!</strong>\n{{PLURAL:$2|0=|См. также страницу, найденную по результатами вашего поиска.|См. также найденные результаты поиска.}}",
        "searchprofile-articles": "Основные страницы",
        "searchprofile-images": "Мультимедиа",
        "tag-mw-changed-redirect-target-description": "Правки, которые изменяют цель перенаправления",
        "tag-mw-blank": "очистка",
        "tag-mw-blank-description": "Правки, очищающие страницу",
-       "tag-mw-replace": "заменено",
+       "tag-mw-replace": "замена",
        "tag-mw-replace-description": "Правки, которые удаляют более 90 % содержимого страницы",
        "tag-mw-rollback": "откат",
        "tag-mw-rollback-description": "Правки, которые откатывают предыдущие правки по нажатию ссылки отката",
index e7a03f1..d802e94 100644 (file)
        "permissionserrorstext-withaction": "Немате дозволу за $2 из {{PLURAL:$1|следећег|следећих}} разлога:",
        "contentmodelediterror": "Не можете уредити ову измену јер је њен модел садржаја <code>$1</code>, што се разликује од тренутног модела садржаја странице <code>$2</code>.",
        "recreate-moveddeleted-warn": "<strong>Упозорење: поново правите страницу која је претходно обрисана.</strong>\n\nРазмотрите да ли је прикладно да наставите с уређивањем ове странице.\nОвде је наведена историја брисања и премештања с образложењем:",
-       "moveddeleted-notice": "Ð\9eва Ñ\81Ñ\82Ñ\80аниÑ\86а Ñ\98е Ð¾Ð±Ñ\80иÑ\81ана.\nÐ\98Ñ\81Ñ\82оÑ\80иÑ\98а Ñ\9aеног Ð±Ñ\80иÑ\81аÑ\9aа, Ð·Ð°Ñ\88Ñ\82иÑ\82е Ð¸ Ð¿Ñ\80емеÑ\88Ñ\82аÑ\9aа Ð½Ð°Ð»Ð°Ð·Ð¸ Ñ\81е Ð¸Ñ\81под:",
+       "moveddeleted-notice": "Ð\9eва Ñ\81Ñ\82Ñ\80аниÑ\86а Ñ\98е Ð¾Ð±Ñ\80иÑ\81ана.\nÐ\94невник Ð±Ñ\80иÑ\81аÑ\9aа, Ð·Ð°Ñ\88Ñ\82иÑ\82е Ð¸ Ð¿Ñ\80емеÑ\88Ñ\82аÑ\9aа Ñ\81Ñ\82Ñ\80аниÑ\86е Ð½Ð°Ð»Ð°Ð·Ð¸ Ñ\81е Ð¸Ñ\81под.",
        "moveddeleted-notice-recent": "Жао нам је, ова страница је недавно обрисана (у последњих 24 сата).\nИсторија њеног брисања, заштите и премештања налази се испод:",
        "log-fulllog": "Погледај целу историју",
        "edit-hook-aborted": "Измену је прекинула кука.\nНије дато никакво образложење.",
index d947d2a..ddd4b1e 100644 (file)
        "noindex-category": "Neindeksirane stranice",
        "broken-file-category": "Stranice s neispravnim vezama do datoteka",
        "about": "O nama",
-       "article": "Stranica sa sadržajem",
+       "article": "Članak",
        "newwindow": "(otvara se u novom prozoru)",
        "cancel": "Otkaži",
        "moredotdotdot": "Više…",
        "permissionserrorstext": "Nemate ovlašćenje za ovu radnju iz {{PLURAL:$1|1=sledećeg|sledećih}} razloga:",
        "permissionserrorstext-withaction": "Nemate dozvolu za $2 iz {{PLURAL:$1|sledećeg|sledećih}} razloga:",
        "recreate-moveddeleted-warn": "<strong>Upozorenje: ponovo pravite stranicu koja je prethodno obrisana.</strong>\n\nRazmotrite da li je prikladno da nastavite s uređivanjem ove stranice.\nOvde je navedena istorija brisanja i premeštanja s obrazloženjem:",
-       "moveddeleted-notice": "Ova stranica je obrisana.\nIstorija njenog brisanja i premeštanja nalazi se ispod:",
+       "moveddeleted-notice": "Ova stranica je obrisana.\nDnevnik brisanja, zaštite i premeštanja stranice nalazi se ispod.",
        "moveddeleted-notice-recent": "Žao nam je, ova stranica je nedavno obrisana (u poslednjih 24 sata).\nOvde je navedena istorija brisanja i premeštanja s obrazloženjem.",
        "log-fulllog": "Pogledaj celu istoriju",
        "edit-hook-aborted": "Izmenu je prekinula kuka.\nNije dato nikakvo obrazloženje.",
index fcbe9af..7e5c073 100644 (file)
        "savechanges": "Değişiklikleri kaydet",
        "publishpage": "Sayfayı yayımla",
        "publishchanges": "Değişiklikleri yayımla",
+       "savearticle-start": "Sayfayı kaydet...",
+       "savechanges-start": "Değişiklikleri kaydet...",
+       "publishpage-start": "Sayfayı yayımla...",
+       "publishchanges-start": "Değişiklikleri yayımla...",
        "preview": "Önizleme",
        "showpreview": "Önizlemeyi göster",
        "showdiff": "Değişiklikleri göster",
        "postedit-confirmation-created": "Sayfa oluşturuldu.",
        "postedit-confirmation-restored": "Sayfa geri yüklendi.",
        "postedit-confirmation-saved": "Değişikliğiniz kaydedildi.",
+       "postedit-confirmation-published": "Değişikliğiniz yayımlandı.",
        "edit-already-exists": "Yeni sayfa oluşturulamıyor.\nSayfa zaten mevcut.",
        "defaultmessagetext": "Varsayılan mesaj metni",
        "content-failed-to-parse": "$1 modeli için $2 içerik türü çözümlenemedi: $3",
        "invalid-content-data": "Geçersiz içerik verisi",
        "content-not-allowed-here": "\"$1\" içeriğine, [[$2]] sayfasında izin verilmemekte.",
        "editwarning-warning": "Bu sayfadan ayrılmak yaptığınız herhangi bir değişikliği kaybetmenize sebep olabilir.\nEğer giriş yaptıysanız, bu uyarıyı, tercihlerinizin \"{{int:prefs-editing}}\" bölümünde devre dışı bırakabilirsiniz.",
+       "editpage-invalidcontentmodel-title": "İçerik modeli desteklenmiyor",
        "editpage-invalidcontentmodel-text": "\"$1\" içerik modeli desteklenmemektedir.",
        "editpage-notsupportedcontentformat-title": "İçerik biçimi desteklenmiyor",
        "editpage-notsupportedcontentformat-text": "$1 içerik biçimi $2 içerik modeli tarafından desteklenmiyor.",
        "content-model-css": "CSS",
        "content-json-empty-object": "Boş nesne",
        "content-json-empty-array": "Boş dizi",
+       "deprecated-self-close-category": "Kendiliğinden geçersiz HTML etiketlerini kullanan sayfalar",
        "duplicate-args-warning": "<strong>Uyarı:</strong>[[:$1]] [[:$2]] şablonunu \"$3\" parametresi için birden fazla değerle çağırıyor. Sadece sağlanan son değer kullanılacak.",
        "duplicate-args-category": "Yinelenen şablon değişkenleri kullanan sayfalar",
        "duplicate-args-category-desc": "Sayfada içeren şablonları çağırmak için bu terimler kullanılır <code><nowiki>{{foo|bar=1|bar=2}}</nowiki></code> or <code><nowiki>{{foo|bar|1=baz}}</nowiki></code>.",
        "post-expand-template-argument-warning": "'''Uyarı:''' Bu sayfa çok fazla genişleme boyutuna sahip en az bir şablon değişkeni içeriyor.\nBu değişkenler atlandı.",
        "post-expand-template-argument-category": "Geçersiz şablon değiştirgenleri içeren sayfalar",
        "parser-template-loop-warning": "Şablon düğümü tespit edildi: [[$1]]",
+       "template-loop-category": "Şablon döngülü sayfalar",
        "parser-template-recursion-depth-warning": "Şablon özyineleme yoğunluğu sınırı aşıldı ($1)",
        "language-converter-depth-warning": "Dil çevirici derinlik sınırı aşıldı ($1)",
        "node-count-exceeded-category": "Düğüm sayısı aşılan sayfalar",
        "right-applychangetags": "Değişiklikleriyle beraber [[Special:Tags|etiketleri]] uygula",
        "right-changetags": "Tekil sürümler ve günlük kayıtlarına rastgele [[Special:Tags|etiket]] ekleme veya çıkarma",
        "grant-group-email": "E-posta gönder",
+       "grant-group-other": "Çeşitli aktivite",
        "grant-createeditmovepage": "Sayfaları oluşturma, düzenleme ve taşıma",
        "grant-editmycssjs": "Kullanıcı CSS/JavaScript'ini düzenle",
        "grant-editmyoptions": "Kullanıcı tercihlerini Düzenle",
index 1a68426..b262214 100644 (file)
@@ -59,7 +59,7 @@
        "tog-shownumberswatching": "Битне күзәтү исемлекләренә өстәгән кулланучылар санын күрсәтелсен",
        "tog-oldsig": "Хәзерге имзагыз:",
        "tog-fancysig": "Имзаның шәхси вики-билгеләмәсе (автоматик сылтамасыз)",
-       "tog-uselivepreview": "Тиз карап алуны куллану",
+       "tog-uselivepreview": "Ð\91иÑ\82не Ñ\8fңаÑ\80Ñ\82мÑ\8bйÑ\87а Ñ\82из карап алуны куллану",
        "tog-forceeditsummary": "Үзгәртүләрне тасвирлау юлы тутырылмаган булса, кисәтү",
        "tog-watchlisthideown": "Минем үзгәртүләрем күзәтү исемлегеннән яшерелсен",
        "tog-watchlisthidebots": "Бот үзгәртүләре күзәтү исемлегеннән яшерелсен",
        "virus-scanfailed": "сканерлау хатасы ($1 коды)",
        "virus-unknownscanner": "билгесез антивирус:",
        "logouttext": "<strong>Сез хисап язмагыздан чыктыгыз.</strong>\n\nКайбер битләр Сез кергән кебек күрсәтелергә мөмкин. Моны бетерү өчен браузер кэшын чистартыгыз.",
+       "cannotlogoutnow-title": "Хәзер үк чыгып булмый",
        "welcomeuser": "Рәхим итегез, $1!",
        "yourname": "Кулланучы исеме:",
        "userlogin-yourname": "Кулланучы исеме",
        "createacct-yourpasswordagain-ph": "Серсүзне кабаттан кертегез",
        "userlogin-remembermypassword": "Системада калырга",
        "userlogin-signwithsecure": "Якланган кушылу",
+       "cannotlogin-title": "Чыгып булмый",
+       "cannotlogin-text": "Системага керү мөмкин түгел.",
+       "cannotloginnow-title": "Хәзер үк кереп булмый",
        "yourdomainname": "Доменыгыз:",
        "password-change-forbidden": "Сез бу викидә серсүзне үзгәртә алмыйсыз.",
        "externaldberror": "Тышкы мәгълүмат базасы ярдәмендә аутентификация үткәндә хата чыкты, яисә тышкы хисап язмагызга үзгәрешләр кертү хокукыгыз юк.",
        "nosuchusershort": "$1 исемле кулланучы юк. Язылышыгызны тикшерегез.",
        "nouserspecified": "Сез теркәү исмегезне күрсәтергә тиешсез.",
        "login-userblocked": "Бу кулланучы тыелды. Керү тыелган.",
-       "wrongpassword": "ЯзÑ\8bлган Ñ\81еÑ\80Ñ\81үз Ð´Ó©Ñ\80еÑ\81 Ñ\82үгел. Ð¢Ð°Ð³Ñ\8bн Ð±ÐµÑ\80 Ñ\82апкÑ\8bÑ\80 Ñ\81Ñ\8bнагыз.",
+       "wrongpassword": "СеÑ\80Ñ\81үз Ñ\8fиÑ\81Ó\99 ÐºÑ\83лланÑ\83Ñ\87Ñ\8b Ð¸Ñ\81еме Ð´Ó©Ñ\80еÑ\81 Ñ\82үгел. Ð¯Ò£Ð°Ð´Ð°Ð½ Ò\97Ñ\8bеп ÐºÐ°Ñ\80агыз.",
        "wrongpasswordempty": "Серсүз юлы буш булырга тиеш түгел.",
        "passwordtooshort": "Сезсүз кимендә $1 {{PLURAL:$1|символдан}} торырга тиеш.",
        "password-name-match": "Кертелгән серсүз кулланучы исеменнән аерылырга тиеш.",
        "nowiki_tip": "Вики-форматлауны исәпкә алмау",
        "image_sample": "Мисал.jpg",
        "image_tip": "Куелган файл",
+       "media_sample": "Мисал.ogg",
        "media_tip": "Файлга сылтама",
        "sig_tip": "Имза һәм вакыт",
        "hr_tip": "Горизонталь сызык (еш кулланмагыз)",
        "savechanges": "Үзгәртүләрне саклау",
        "publishpage": "Бит ясау",
        "publishchanges": "Битне бастыру",
+       "savearticle-start": "Битне саклау...",
+       "savechanges-start": "Үзгәртүләрне саклау...",
+       "publishpage-start": "Битне бастыру...",
+       "publishchanges-start": "Төзәтмәләрне бастыру...",
        "preview": "Алдан карау",
        "showpreview": "Алдан карау",
        "showdiff": "Кертелгән үзгәртүләр",
        "anoneditwarning": "<strong>Игътибар!</strong> Сез сайтта теркәлмәдегез. Әгәрдә сез нинди дә булсә төзәтмәләр яисә үзгәртүләр кертсәгез, сезнең IP-адрес башка кулланучыларга да билгеле булачак. Сайтка <strong>[$1 керсәгез]</strong> яисә <strong>[$2 кулланучы язмасын төзесәгез]</strong>, сез керткән үзгәртүләр сезнең кулланучы язмагызга бәйләнгән булачак, шулай ук башка мөмкинлекләр дә туачак.",
        "anonpreviewwarning": "''Сез системада теркәлмәдегез.Сезнең тарафтан эшләнгән барлык үзгәртүләр дә сезнең IP-юлламагызны саклауга китерә.''",
        "missingsummary": "'''Искәртү.''' Сез үзгәртүгә кыскача тасвирлау язмадыгыз. Сез «Битне саклау» төймәсенә тагын бер тапкыр бассагыз, үзгәртүләр тасвирламасыз сакланачак.",
-       "missingcommenttext": "Ð\90Ñ\81ка Ñ\82аÑ\81виÑ\80лама язуыгыз сорала.",
+       "missingcommenttext": "Ð\9aомменÑ\82 язуыгыз сорала.",
        "missingcommentheader": "<strong>Искәртү:</strong> Сез шәрехнең темасын күрсәтмәгәнсез.\n«$1» төймәсенә кабат бассагыз, үзгәртүләр темасыз язылачак.",
        "summary-preview": "Төзәтмәләрне карап чыгу:",
        "subject-preview": "Башисемне алдан карау:",
        "search-interwiki-caption": "Тугандаш проектлар нәтиҗәсе",
        "search-interwiki-default": "$1 нәтиҗә:",
        "search-interwiki-more": "(тагын)",
+       "search-interwiki-more-results": "күбрәк нәтиҗәләр",
        "search-relatedarticle": "Бәйле",
        "searchrelated": "бәйле",
        "searchall": "барлык",
        "prefs-watchlist-edits": "Киңәйтелгән күзәтү исемлегендә күрсәтелүче төзәтмәләрнең максималь саны:",
        "prefs-watchlist-edits-max": "Максимум сан: 1000",
        "prefs-watchlist-token": "Күзәтү исемлеге токены:",
+       "prefs-watchlist-managetokens": "Токеннар беләр идарә итү",
        "prefs-misc": "Башка көйләнмәләр",
        "prefs-resetpass": "Серсүзне үзгәртү",
        "prefs-changeemail": "Электрон әрҗә адресын үзгәртү яисә бетерү",
+       "prefs-setemail": "Электрон почта адресын көйләү",
        "prefs-email": "E-mail көйләнмәләре",
        "prefs-rendering": "Күренеш",
        "saveprefs": "Саклау",
        "recentchangesdays": "Соңгы үзгәртүләрне күрсәтүче көннәр саны:",
        "recentchangesdays-max": "(иң күбе $1 {{PLURAL:$1|көн}})",
        "recentchangescount": "Төп буларак кулланучы үзгәртүләр саны:",
-       "prefs-help-recentchangescount": "Үз өченә үзгәртүләрне, битләрнең тарихын һәм язлу көндәлеген дә кертә.",
+       "prefs-help-recentchangescount": "Максимум сан: 1000",
        "prefs-help-watchlist-token2": "Бу сезнең кузәтү исемлеге өчен ясалган веб-агымының серле ачкычы.\nАны белгән һәркем сезнең күзәтү исемлегегезне карый ала, шуңа да башкаларга аны күрсәтмәгез. [[Special:ResetTokens|Ачкычны ташларга теләсәгез, әлеге юрамага басыгыз]].",
        "savedprefs": "Көйләнмәләрегез сакланды.",
        "timezonelegend": "Сәгать поясы:",
        "timezoneregion-europe": "Аурупа",
        "timezoneregion-indian": "Һинд океаны",
        "timezoneregion-pacific": "Тын океан",
-       "allowemail": "Ð\91аÑ\88ка ÐºÑ\83лланÑ\83Ñ\87Ñ\8bлаÑ\80дан Ñ\85аÑ\82лаÑ\80 Ð°Ð»Ñ\8bÑ\80га Ñ\80Ó©Ñ\85Ñ\81Ó\99Ñ\82 Ð¸Ñ\82елÑ\81ен",
+       "allowemail": "Ð\91аÑ\88ка ÐºÑ\83лланÑ\83Ñ\87Ñ\8bлаÑ\80га Ð¼Ð¸Ò£Ð° Ñ\85аÑ\82лаÑ\80 Ñ\8fзаÑ\80га Ñ\80Ó©Ñ\85Ñ\81Ó\99Ñ\82 Ð¸Ñ\82Ò¯",
        "prefs-searchoptions": "Эзләү",
        "prefs-namespaces": "Исемнәр мәйданы",
        "default": "килешү буенча",
        "prefs-files": "Файллар",
        "prefs-custom-css": "Шәхси CSS",
+       "prefs-custom-json": "Кулланма JSON",
        "prefs-custom-js": "Шәхси JS",
-       "prefs-common-config": "Барлык бизәлешләр өчен гомуми CSS/JS:",
+       "prefs-common-config": "Барлык бизәлешләр өчен гомуми CSS/JSON/JavaScript:",
        "prefs-reset-intro": "Бу бит сезнең көйләнмәләрегезне бетерү өчен кулланыла. Бу эшне башкару нәтиҗәсендә сез яңадан үз көйләнмәләрне яңадан кайтара алмыйсыз.",
        "prefs-emailconfirm-label": "E-mail раслау",
        "youremail": "Электрон почта:",
        "username": "{{GENDER:$1|Кулланучы исеме}}:",
        "prefs-memberingroups": "{{PLURAL:$1|Төркем}} {{GENDER:$2|әгъзасы}}:",
        "prefs-memberingroups-type": "$1",
+       "group-membership-link-with-expiry": "$1 ($2 кадәр)",
        "prefs-registration": "Теркәлү вакыты:",
        "prefs-registration-date-time": "$1",
        "yourrealname": "Чын исем:",
        "prefs-dateformat": "Вакытың форматы",
        "prefs-timeoffset": "Вакыт билгеләнеше",
        "prefs-advancedediting": "Гомуми көйләүләр",
+       "prefs-developertools": "Девелопер кораллары",
        "prefs-editor": "Мөхәррир",
        "prefs-preview": "Алдан карау",
        "prefs-advancedrc": "Киңәйтелгән көйләүләр",
        "userrights-changeable-col": "Сезнең тарафтан үзгәртелми торган төркемнәр",
        "userrights-unchangeable-col": "Сезнең тарафтан үзгәртелми торган төркемнәр",
        "userrights-irreversible-marker": "$1*",
+       "userrights-expiry": "Бетә:",
+       "userrights-expiry-othertime": "Башка вакыт:",
+       "userrights-expiry-options": "1 көн:1 day,1 атна:1 week,1 ай:1 month,3 ай:3 months,6 ай:6 months,1 ел:1 year",
        "userrights-conflict": "Кулланучы хокукларын үзгәртү конфликты! Төзәтмәләрегезне тикшерегез, аннары кабатлагыз.",
        "group": "Төркем:",
        "group-user": "Кулланучылар",
        "recentchanges-legend-heading": "<strong>Аңлатма:</strong>",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (шулай ук [[Special:NewPages|яңа битләр исемлеген]] карагыз)",
        "recentchanges-submit": "Күрсәт",
+       "rcfilters-legend-heading": "<strong>Кыскартулар тезмәсе:&nbsp;</strong>",
        "rcfilters-activefilters": "Актив фильтрлар",
        "rcfilters-limit-title": "Күрсәтү өчен үзгәртүләр",
        "rcfilters-days-title": "Соңгы көннәр",
        "rcfilters-hours-title": "Соңгы сәгатьләр",
-       "rcfilters-days-show-days": "$1 көн",
-       "rcfilters-days-show-hours": "$1 сәгать",
+       "rcfilters-days-show-days": "$1 {{PLURAL:$1|көн}}",
+       "rcfilters-days-show-hours": "$1 {{PLURAL:$1|сәгать}}",
        "rcfilters-quickfilters": "Сакланган фильтрлар",
+       "rcfilters-savedqueries-remove": "Бетерү",
+       "rcfilters-savedqueries-new-name-label": "Исем",
+       "rcfilters-savedqueries-cancel-label": "Баш тарту",
        "rcfilters-savedqueries-add-new-title": "Хәзерге фильтр көйләнмәләрен саклау",
        "rcfilters-clear-all-filters": "Барлык филтерләрне чистарту",
        "rcfilters-search-placeholder": "Фильтрланы соңгы үзгәртү (карау яисә кертүне башлау)",
        "rcfilters-filter-editsbyself-label": "Сезнең үзгәртүләр",
        "rcfilters-filter-editsbyself-description": "Сезнең кертемегез.",
        "rcfilters-filter-editsbyother-label": "Башка кулланучыларның үзгәртүләре",
-       "rcfilters-filter-user-experience-level-registered-label": "Теркәлгән",
+       "rcfilters-filter-user-experience-level-registered-label": "Теркәлүчеләр",
        "rcfilters-filter-user-experience-level-registered-description": "Теркәлгән мөхәррирләр.",
        "rcfilters-filter-user-experience-level-unregistered-label": "Теркәлмәгәннәр",
        "rcfilters-filter-user-experience-level-unregistered-description": "Системага кермәгән мөхәррирләр.",
        "rcfilters-filter-user-experience-level-experienced-label": "Тәҗрибәле кулланучылар",
        "rcfilters-filter-user-experience-level-experienced-description": "Төзәтүләре 500 дән күбрәк һәм актив эш көннәре 30 дан артык теркәлгән мөхәррирләр",
        "rcfilters-filtergroup-automated": "Автоматлаштырылган кертем",
+       "rcfilters-filter-bots-label": "Бот",
        "rcfilters-filter-bots-description": "Автоматлаштырылган кораллар ярдәмендә ясалган үзгәртүләр.",
        "rcfilters-filter-humans-label": "Кеше (бот түгел)",
        "rcfilters-filter-humans-description": "Кешеләр ясаган үзгәртүләр.",
+       "rcfilters-filtergroup-reviewstatus": "Тикшерү статусы",
        "rcfilters-filter-minor-label": "Кече үзгәртүләр",
        "rcfilters-filter-minor-description": "«Кече үзгәртү» дип тамгаланган үзгәртүләр",
        "rcfilters-filter-major-label": "Гади үзгәртүләр",
        "rcfilters-filter-previousrevision-description": "«Соңгы юрама» булмаган барлык үзгәртүләр.",
        "rcfilters-view-tags": "Тәгләнгән үзгәртүләр",
        "rcfilters-liveupdates-button": "Автоматик яңарту",
+       "rcfilters-watchlist-markseen-button": "Бар үзгәртүләрне каралган дип билгеләргә",
+       "rcfilters-watchlist-edit-watchlist-button": "Күзәтү исемлегегезне үзгәртү",
        "rcnotefrom": "Астарак <strong>$3, $4</strong> өчен {{PLURAL:$5|үзгәртүләр күрсәтелгән}} (<strong>$1</strong> артык түгел).",
        "rclistfrom": "$3 $2 башлап яңа үзгәртүләрне күрсәт",
        "rcshowhideminor": "кече үзгәртүләрне $1",
        "recentchangeslinked-feed": "Бәйләнешле үзгәртүләр",
        "recentchangeslinked-toolbox": "Бәйләнешле үзгәртүләр",
        "recentchangeslinked-title": "\"$1\" битенә бәйләнешле үзгәртүләр",
-       "recentchangeslinked-summary": "Ð\91Ñ\83 ÐºÒ¯Ñ\80Ñ\81Ó\99Ñ\82елгÓ\99н Ð±Ð¸Ñ\82 Ð±ÐµÐ»Ó\99н Ñ\81Ñ\8bлÑ\82алган (йÓ\99 ÐºÒ¯Ñ\80Ñ\81Ó\99Ñ\82елгÓ\99н Ñ\82Ó©Ñ\80кемгÓ\99 ÐºÐµÑ\80Ñ\82кÓ\99н) Ð±Ð¸Ñ\82лÓ\99Ñ\80нең Ò¯Ð·Ð³Ó\99Ñ\80Ñ\82елмÓ\99лÓ\99Ñ\80е Ð¸Ñ\81емлеге. [[Special:Watchlist|Күзәтү исемлегегезгә]] керә торган битләр '''калын''' итеп күрсәтелгән.",
+       "recentchangeslinked-summary": "Ð\91Ñ\83 Ð±Ð¸Ñ\82Ñ\82Ñ\82Ó\99н Ñ\8fиÑ\81Ó\99 Ð±Ñ\83 Ð±Ð¸Ñ\82кÓ\99 Ñ\81Ñ\8bлÑ\82аган Ð±Ð¸Ñ\82лÓ\99Ñ\80дÓ\99ге Ò¯Ð·Ð³Ó\99Ñ\80Ñ\82мÓ\99ле ÐºÐ°Ñ\80аÑ\83 Ó©Ñ\87ен Ð±Ð¸Ñ\82нең Ð¸Ñ\81емен ÐºÐµÑ\80Ñ\82егез. (Ð\91илгеле Ð±ÐµÑ\80 Ñ\82Ó©Ñ\80кемгÓ\99 ÐºÐ°Ñ\80аган Ð±Ð¸Ñ\82лÓ\99Ñ\80не ÐºÐ°Ñ\80аÑ\83 Ó©Ñ\87ен {{ns:category}}:ТөÑ\80кем Ð¸Ñ\81емен Ñ\8fзÑ\8bгÑ\8bз).[[Special:Watchlist|Күзәтү исемлегегезгә]] керә торган битләр '''калын''' итеп күрсәтелгән.",
        "recentchangeslinked-page": "Битнең исеме:",
        "recentchangeslinked-to": "Моның урынына бу биткә бәйле булган битләрдәге үзгәртүләрне күрсәтү",
        "upload": "Файл йөкләү",
index c20ce59..e62ebec 100644 (file)
@@ -75,7 +75,8 @@
                        "Renamerr",
                        "Avatar6",
                        "Fitoschido",
-                       "Movses"
+                       "Movses",
+                       "Esk78"
                ]
        },
        "tog-underline": "Підкреслювання посилань:",
        "tog-watchlisthideminor": "Приховати незначні редагування у списку спостереження",
        "tog-watchlisthideliu": "Приховати редагування зареєстрованих дописувачів у списку спостереження",
        "tog-watchlistreloadautomatically": "Перезавантажувати список спостереження автоматично кожного разу, коли зміниться фільтр (вимагається JavaScript)",
-       "tog-watchlistunwatchlinks": "Ð\94одаÑ\82и Ð¼Ð¾Ð¶Ð»Ð¸Ð²Ñ\96Ñ\81Ñ\82Ñ\8c Ð´Ð»Ñ\8f Ð²Ð¸ÐºÐ»Ñ\8eÑ\87еннÑ\8f Ñ\81Ñ\82оÑ\80Ñ\96нок Ð¿Ñ\80Ñ\8fмо Ð·Ñ\96 Ñ\81Ñ\82оÑ\80Ñ\96нки Ñ\81пиÑ\81кÑ\83 Ñ\81поÑ\81Ñ\82еÑ\80еженнÑ\8f (потрібен JavaScript для функціонування)",
+       "tog-watchlistunwatchlinks": "Ð\94одаÑ\82и Ð¿Ñ\80Ñ\8fмÑ\96 Ð¼Ð°Ñ\80кеÑ\80и Ð²ÐºÐ»Ñ\8eÑ\87еннÑ\8f/виклÑ\8eÑ\87еннÑ\8f Ð·Ñ\96 Ñ\81пиÑ\81кÑ\83 Ñ\81поÑ\81Ñ\82еÑ\80еженнÑ\8f ({{int:Watchlist-unwatch}}/{{int:Watchlist-unwatch-undo}}) Ð´Ð»Ñ\8f Ñ\81Ñ\82еженнÑ\8f Ð·Ð° Ñ\81Ñ\82оÑ\80Ñ\96нками Ñ\96з Ð·Ð¼Ñ\96нами (потрібен JavaScript для функціонування)",
        "tog-watchlisthideanons": "Приховати редагування анонімних користувачів у списку спостереження",
        "tog-watchlisthidepatrolled": "Приховати відпатрульовані редагування у списку спостереження",
        "tog-watchlisthidecategorization": "Приховати категоризацію сторінок",
        "botpasswords-existing": "Існуючі паролі бота",
        "botpasswords-createnew": "Створити новий пароль бота",
        "botpasswords-editexisting": "Редагувати існуючий пароль бота",
+       "botpasswords-label-needsreset": "(необхідно скинути пароль)",
        "botpasswords-label-appid": "Назва бота:",
        "botpasswords-label-create": "Створити",
        "botpasswords-label-update": "Оновити",
        "botpasswords-restriction-failed": "Вхід не було здійснено через обмеження для паролю бота.",
        "botpasswords-invalid-name": "Вказане ім'я користувача не містить роздільник для пароля бота («$1»).",
        "botpasswords-not-exist": "У користувача «$1» нема пароля для бота «$2».",
+       "botpasswords-needs-reset": "Пароль бота з ім'ям «$2» {{GENDER:$1|користувача|користувачки}} «$1» необхідно скинути.",
        "resetpass_forbidden": "Пароль не можна змінити",
        "resetpass_forbidden-reason": "Пароль не можна змінити: $1",
        "resetpass-no-info": "Щоб звертатися безпосередньо до цієї сторінки, вам слід увійти до системи.",
        "previewerrortext": "Сталася помилка при спробі попереднього перегляду Ваших змін.",
        "blockedtitle": "Користувача заблоковано",
        "blockedtext": "<strong>Ваш обліковий запис або IP-адреса заблоковані.</strong>\n\nБлокування виконане адміністратором $1.\nПричина блокування: <em>$2</em>.\n\n* Початок блокування: $8\n* Закінчення блокування: $6\n* Діапазон блокування: $7\n\nВи можете надіслати листа користувачеві $1 або будь-якому іншому [[{{MediaWiki:Grouppage-sysop}}|адміністратору]], щоб обговорити блокування.\n\nЗверніть увагу, що ви не зможете використати функцію \"{{int:emailuser}}\", якщо ви не зареєстровані або не підтвердили свою електронну адресу в [[Special:Preferences|особистих налаштуваннях]], а також якщо вам було заборонено надсилати листи при блокуванні.\n\nВаша поточна IP-адреса — $3, ідентифікатор блокування — #$5. Будь ласка, зазначайте ці дані у своїх запитах.",
-       "autoblockedtext": "Ð\92аÑ\88а IP-адÑ\80еÑ\81а Ð°Ð²Ñ\82омаÑ\82иÑ\87но Ð·Ð°Ð±Ð»Ð¾ÐºÐ¾Ð²Ð°Ð½Ð° Ñ\83 Ð·Ð²'Ñ\8fзкÑ\83 Ð· Ñ\82им, Ñ\89о Ð²Ð¾Ð½Ð° Ñ\80анÑ\96Ñ\88е Ð²Ð¸ÐºÐ¾Ñ\80иÑ\81Ñ\82овÑ\83валаÑ\81Ñ\8f ÐºÐ¸Ð¼Ð¾Ñ\81Ñ\8c Ñ\96з Ð·Ð°Ð±Ð»Ð¾ÐºÐ¾Ð²Ð°Ð½Ð¸Ñ\85 ÐºÐ¾Ñ\80иÑ\81Ñ\82Ñ\83ваÑ\87Ñ\96в. Ð\90дмÑ\96нÑ\96Ñ\81Ñ\82Ñ\80аÑ\82оÑ\80 ($1), Ñ\89о Ñ\97Ñ\97 Ð·Ð°Ð±Ð»Ð¾ÐºÑ\83вав, Ð·Ð°Ð·Ð½Ð°Ñ\87ив Ð½Ð°Ñ\81Ñ\82Ñ\83пнÑ\83 Ð¿Ñ\80иÑ\87инÑ\83 Ð±Ð»Ð¾ÐºÑ\83ваннÑ\8f:\n\n:''$2''\n\n* Ð\9fоÑ\87аÑ\82ок Ð±Ð»Ð¾ÐºÑ\83ваннÑ\8f: $8\n* Ð\97акÑ\96нÑ\87еннÑ\8f Ð±Ð»Ð¾ÐºÑ\83ваннÑ\8f: $6\n* Ð\91локÑ\83ваннÑ\8f Ð²Ð¸ÐºÐ¾Ð½Ð°Ð²: $7\n\nÐ\92и Ð¼Ð¾Ð¶ÐµÑ\82е Ð½Ð°Ð´Ñ\96Ñ\81лаÑ\82и Ð»Ð¸Ñ\81Ñ\82а ÐºÐ¾Ñ\80иÑ\81Ñ\82Ñ\83ваÑ\87евÑ\96 $1 Ð°Ð±Ð¾ Ð±Ñ\83дÑ\8c\8fкомÑ\83 Ñ\96нÑ\88омÑ\83 [[{{MediaWiki:Grouppage-sysop}}|адмÑ\96нÑ\96Ñ\81Ñ\82Ñ\80аÑ\82оÑ\80Ñ\83]], Ñ\89об Ð¾Ð±Ð³Ð¾Ð²Ð¾Ñ\80иÑ\82и Ð±Ð»Ð¾ÐºÑ\83ваннÑ\8f.\n\nÐ\97веÑ\80нÑ\96Ñ\82Ñ\8c Ñ\83вагÑ\83, Ñ\89о Ð²Ð¸ Ð½Ðµ Ð·Ð¼Ð¾Ð¶ÐµÑ\82е Ð½Ð°Ð´Ñ\96Ñ\81лаÑ\82и Ð»Ð¸Ñ\81Ñ\82а Ð°Ð´Ð¼Ñ\96нÑ\96Ñ\81Ñ\82Ñ\80аÑ\82оÑ\80овÑ\96, Ñ\8fкÑ\89о Ð²Ð¸ Ð½Ðµ Ð·Ð°Ñ\80еÑ\94Ñ\81Ñ\82Ñ\80ованÑ\96 Ñ\83 Ð¿Ñ\80оекÑ\82Ñ\96 Ð°Ð±Ð¾ Ð½Ðµ Ð¿Ñ\96дÑ\82веÑ\80дили Ñ\81воÑ\8e ÐµÐ»ÐµÐºÑ\82Ñ\80оннÑ\83 Ð°Ð´Ñ\80еÑ\81Ñ\83 Ð² [[Special:Preferences|оÑ\81обиÑ\81Ñ\82иÑ\85 Ð½Ð°Ð»Ð°Ñ\88Ñ\82Ñ\83ваннÑ\8fÑ\85]], Ð° Ñ\82акож Ñ\8fкÑ\89о Ð²Ð°Ð¼ Ð±Ñ\83ло Ð·Ð°Ð±Ð¾Ñ\80онено Ð½Ð°Ð´Ñ\81илаÑ\82и Ð»Ð¸Ñ\81Ñ\82и Ð¿Ñ\80и Ð±Ð»Ð¾ÐºÑ\83ваннÑ\96.\n\nÐ\92аÑ\88а Ð¿Ð¾Ñ\82оÑ\87на IP-адÑ\80еÑ\81а â\80\94 $3, Ñ\96денÑ\82иÑ\84Ñ\96каÑ\82оÑ\80 Ð±Ð»Ð¾ÐºÑ\83ваннÑ\8f â\80\94 #$5. Ð\91Ñ\83дÑ\8c Ð»Ð°Ñ\81ка, Ð·Ð°Ð·Ð½Ð°Ñ\87айÑ\82е Ð¹Ð¾Ð³Ð¾ у своїх запитах.",
+       "autoblockedtext": "Ð\92аÑ\88а IP-адÑ\80еÑ\81а Ð°Ð²Ñ\82омаÑ\82иÑ\87но Ð·Ð°Ð±Ð»Ð¾ÐºÐ¾Ð²Ð°Ð½Ð° Ñ\83 Ð·Ð²'Ñ\8fзкÑ\83 Ð· Ñ\82им, Ñ\89о Ð²Ð¾Ð½Ð° Ñ\80анÑ\96Ñ\88е Ð²Ð¸ÐºÐ¾Ñ\80иÑ\81Ñ\82овÑ\83валаÑ\81Ñ\8f ÐºÐ¸Ð¼Ð¾Ñ\81Ñ\8c Ñ\96з ÐºÐ¾Ñ\80иÑ\81Ñ\82Ñ\83ваÑ\87Ñ\96в, Ñ\8fкого Ð·Ð°Ð±Ð»Ð¾ÐºÑ\83вав $1.\nÐ\9fÑ\80иÑ\87ина Ð±Ð»Ð¾ÐºÑ\83ваннÑ\8f Ð±Ð»Ð¾ÐºÑ\83ваннÑ\8f:\n\n:<em>$2</em>\n\n* Ð\9fоÑ\87аÑ\82ок Ð±Ð»Ð¾ÐºÑ\83ваннÑ\8f: $8\n* Ð\97акÑ\96нÑ\87еннÑ\8f Ð±Ð»Ð¾ÐºÑ\83ваннÑ\8f: $6\n* Ð\91локÑ\83ваннÑ\8f Ð²Ð¸ÐºÐ¾Ð½Ð°Ð²: $7\n\nÐ\92и Ð¼Ð¾Ð¶ÐµÑ\82е Ð½Ð°Ð´Ñ\96Ñ\81лаÑ\82и Ð»Ð¸Ñ\81Ñ\82а ÐºÐ¾Ñ\80иÑ\81Ñ\82Ñ\83ваÑ\87евÑ\96 $1 Ð°Ð±Ð¾ Ð±Ñ\83дÑ\8c\8fкомÑ\83 Ñ\96нÑ\88омÑ\83 [[{{MediaWiki:Grouppage-sysop}}|адмÑ\96нÑ\96Ñ\81Ñ\82Ñ\80аÑ\82оÑ\80Ñ\83]], Ñ\89об Ð¾Ð±Ð³Ð¾Ð²Ð¾Ñ\80иÑ\82и Ð±Ð»Ð¾ÐºÑ\83ваннÑ\8f.\n\nÐ\97веÑ\80нÑ\96Ñ\82Ñ\8c Ñ\83вагÑ\83, Ñ\89о Ð²Ð¸ Ð½Ðµ Ð·Ð¼Ð¾Ð¶ÐµÑ\82е Ñ\81коÑ\80иÑ\81Ñ\82аÑ\82иÑ\81Ñ\8f Ñ\84Ñ\83нкÑ\86Ñ\96Ñ\94Ñ\8e \"{{int:emailuser}}\", Ñ\82ак Ñ\8fк Ð½Ðµ Ð¼Ð°Ñ\94Ñ\82е Ð´Ñ\96йÑ\81ноÑ\97 ÐµÐ»ÐµÐºÑ\82Ñ\80онноÑ\97 Ð¿Ð¾Ñ\88Ñ\82и, Ð·Ð°Ñ\80еÑ\94Ñ\81Ñ\82Ñ\80ованоÑ\97 Ð² [[Special:Preferences|оÑ\81обиÑ\81Ñ\82иÑ\85 Ð½Ð°Ð»Ð°Ñ\88Ñ\82Ñ\83ваннÑ\8fÑ\85]], Ð° Ñ\82акож Ñ\8fкÑ\89о Ð²Ð°Ð¼ Ð±Ñ\83ло Ð·Ð°Ð±Ð¾Ñ\80онено Ð½Ð°Ð´Ñ\81илаÑ\82и Ð»Ð¸Ñ\81Ñ\82и Ð¿Ñ\80и Ð±Ð»Ð¾ÐºÑ\83ваннÑ\96.\n\nÐ\92аÑ\88а Ð¿Ð¾Ñ\82оÑ\87на IP-адÑ\80еÑ\81а â\80\94 $3, Ñ\96денÑ\82иÑ\84Ñ\96каÑ\82оÑ\80 Ð±Ð»Ð¾ÐºÑ\83ваннÑ\8f â\80\94 #$5. Ð\91Ñ\83дÑ\8c Ð»Ð°Ñ\81ка, Ð·Ð°Ð·Ð½Ð°Ñ\87айÑ\82е Ñ\86Ñ\96 Ð´Ð°Ð½Ñ\96 у своїх запитах.",
        "systemblockedtext": "Ваше ім'я користувача або IP-адресу було автоматично заблоковано MediaWiki.\nВказана причина:\n\n:<em>$2</em>\n\n* Початок блокування: $8\n* Закінчення блокування: $6\n* Ціль блокування: $7\n\nВаша поточна IP-адреса — $3.\nБудь ласка, додайте всі вказані подробиці до будь-яких запитів, які Ви будете робити.",
        "blockednoreason": "не вказано причини",
        "whitelistedittext": "Ви повинні $1, щоб редагувати сторінки.",
        "longpageerror": "'''Помилка: Поданий вами текст становить $1 {{PLURAL:$1|кілобайт|кілобайти|кілобайтів}}, що більше за встановлену межу у {{PLURAL:$2|кілобайт|кілобайти|кілобайтів}}.'''\nЙого неможливо зберегти.",
        "readonlywarning": "<strong>Попередження: База даних заблокована на обслуговування, тому, на даний момент, ви не можете записати ваші зміни.\n</strong>\nМожливо, вам варто скопіювати текст у файл на вашому комп'ютері й зберегти його на пізніше.\n\nАдміністратор, що заблокував базу даних, залишив наступне пояснення: $1",
        "protectedpagewarning": "'''Попередження: Ця сторінка була захищена від змін так, що тільки користувачі з правами адміністратора можуть її редагувати.'''\nОстанній запис журналу наведений нижче для довідки:",
-       "semiprotectedpagewarning": "'''Зауваження:''' Ця сторінка захищена так, що її можуть редагувати тільки зареєстровані користувачі.\nОстанній запис журналу наведений нижче для довідки:",
+       "semiprotectedpagewarning": "<strong>Зауваження:</strong> Ця сторінка захищена так, що її можуть редагувати тільки зареєстровані користувачі.\nОстанній запис журналу наведений нижче для довідки:",
        "cascadeprotectedwarning": "<strong>Попередження:</strong> Цю сторінку можуть редагувати лише користувачі зі [[Special:ListGroupRights|специфічними правами]], оскільки вона включена на {{PLURAL:$1|1=сторінці|сторінках}}, де встановлено каскадний захист:",
        "titleprotectedwarning": "'''Попередження. Ця сторінка була захищена так, що для її створення потрібні [[Special:ListGroupRights|особливі права]].'''\nОстанній запис журналу наведений нижче для довідки:",
        "templatesused": "{{PLURAL:$1|1=Шаблон, використаний|Шаблони, використані}} на цій сторінці:",
        "prefs-watchlist-edits": "Максимальна кількість змін, яку можна виводити у списку спостереження:",
        "prefs-watchlist-edits-max": "Максимально: 1000",
        "prefs-watchlist-token": "Токен списку спостереження:",
+       "prefs-watchlist-managetokens": "Управління токенами",
        "prefs-misc": "Інші налаштування",
        "prefs-resetpass": "Змінити пароль",
        "prefs-changeemail": "Змінити або вилучити адресу електронної пошти",
        "recentchangescount": "Кількість редагувань для показу за замовчуванням на сторінках нових редагувань, історій сторінок та в журналах:",
        "prefs-help-recentchangescount": "Максимальна кількість: 1000",
        "prefs-help-watchlist-token2": "Це секретний ключ до веб-каналу вашого списку спостереження.\nБудь-хто, хто його знає, матиме можливість читати ваш список спостереження, тому не поширюйте його.\nЯкщо вам потрібно, [[Special:ResetTokens|ви можете скинути його]].",
+       "prefs-help-tokenmanagement": "Ви можете переглянути і скинути секретний ключ свого облікового запису, який дає доступ до веб-каналу вашого списку спостереження. Кожен, хто його знає, матиме можливість читати ваш список спостереження, тому не поширюйте його.",
        "savedprefs": "Ваші налаштування збережено.",
        "savedrights": "Групи {{GENDER:$1|користувача $1|користувачки $1}} було збережено.",
        "timezonelegend": "Часовий пояс:",
        "prefs-dateformat": "Формат дати",
        "prefs-timeoffset": "Зсув часу",
        "prefs-advancedediting": "Загальні параметри",
+       "prefs-developertools": "Інструменти розробника",
        "prefs-editor": "Редактор",
        "prefs-preview": "Попередній перегляд",
        "prefs-advancedrc": "Розширені налаштування",
        "rcfilters-filter-humans-label": "Людина (не бот)",
        "rcfilters-filter-humans-description": "Редагування, зроблені людиною.",
        "rcfilters-filtergroup-reviewstatus": "Статус перевірки",
+       "rcfilters-filter-reviewstatus-unpatrolled-description": "Зміни, не позначені вручну або автоматично як патрульовані.",
        "rcfilters-filter-reviewstatus-unpatrolled-label": "Неперевірені",
+       "rcfilters-filter-reviewstatus-manual-description": "Зміни, позначені вручну як патрульовані.",
+       "rcfilters-filter-reviewstatus-manual-label": "Патрульовані вручну",
+       "rcfilters-filter-reviewstatus-auto-description": "Зміни довірених користувачів, які відмічаються як автопатрульовані.",
+       "rcfilters-filter-reviewstatus-auto-label": "Автопатрульовані",
        "rcfilters-filtergroup-significance": "Важливість",
        "rcfilters-filter-minor-label": "Незначні редагування",
        "rcfilters-filter-minor-description": "Редагування, позначені авторами як незначні.",
        "deadendpages": "Сторінки без посилань",
        "deadendpagestext": "Наступні сторінки не містять посилань на інші сторінки цієї вікі.",
        "protectedpages": "Захищені сторінки",
+       "protectedpages-filters": "Фільтри:",
        "protectedpages-indef": "Тільки безстроково захищені",
        "protectedpages-summary": "На цій сторінці перераховані сторінки, які на цей момент захищені. Список назв, які захищені від створення див.  [[{{#special:ProtectedTitles}}|{{int:protectedtitles}}]].",
        "protectedpages-cascade": "Тільки каскадний захист",
        "protectedtitles-submit": "Показувати заголовки",
        "listusers": "Список користувачів",
        "listusers-editsonly": "Показати лише користувачів, які зробили принаймні одне редагування",
+       "listusers-temporarygroupsonly": "Показувати лише користувачів із тимчасових груп",
        "listusers-creationsort": "Сортувати за датою створення",
        "listusers-desc": "Сортувати за спадним порядком",
        "usereditcount": "$1 {{PLURAL:$1|редагування|редагування|редагувань}}",
        "apisandbox-dynamic-parameters-add-label": "Додати параметр:",
        "apisandbox-dynamic-parameters-add-placeholder": "Назва параметра",
        "apisandbox-dynamic-error-exists": "Параметр з назвою «$1» вже існує.",
+       "apisandbox-templated-parameter-reason": "Цей [[Special:ApiHelp/main#main/templatedparams|шаблонний параметр]] запропонований на основі  {{PLURAL:$1|значення|значень}} з $2.",
        "apisandbox-deprecated-parameters": "Застарілі параметри",
        "apisandbox-fetch-token": "Автозаповнення токена",
+       "apisandbox-add-multi": "Додати",
        "apisandbox-submit-invalid-fields-title": "Деякі поля недійсні",
        "apisandbox-submit-invalid-fields-message": "Будь ласка, виправте відмічені поля і спробуйте знову.",
        "apisandbox-results": "Результати",
        "fix-double-redirects": "Виправити всі перенаправлення на попередню назву",
        "move-leave-redirect": "Залишити перенаправлення",
        "protectedpagemovewarning": "'''Попередження:''' Ця сторінка захищена так, що її можуть перейменовувати тільки адміністратори.\nОстанній запис журналу наведений нижче для довідки:",
-       "semiprotectedpagemovewarning": "'''Зауваження:''' Ця сторінка захищена так, що перейменовувати її можуть тільки зареєстровані користувачі.\nОстанній запис журналу наведений нижче для довідки:",
+       "semiprotectedpagemovewarning": "<strong>Зауваження:</strong> Ця сторінка захищена так, що перемістити її можуть тільки зареєстровані користувачі.\nОстанній запис журналу наведений нижче для довідки:",
        "move-over-sharedrepo": "У спільному сховищі існує [[:$1]]. Перейменування файлу на цю назву призведе до перекриття файлу зі спільного сховища.",
        "file-exists-sharedrepo": "Обрана назва файлу вже використовується у спільному сховищі.\nБудь ласка, оберіть іншу назву.",
        "export": "Експорт статей",
        "version-specialpages": "Спеціальні сторінки",
        "version-parserhooks": "Перехоплювачі синтаксичного аналізатора",
        "version-variables": "Змінні",
+       "version-editors": "Редактори",
        "version-antispam": "Захист від спаму",
        "version-api": "API",
        "version-other": "Інше",
        "pagedata-title": "Дані сторінки",
        "pagedata-text": "Ця сторінка надає сторінкам інтерфейс даних. Будь ласка, вкажіть назву сторінки в URL-адресі, скориставшись синтаксисом підсторінок.\n* Переговори щодо контенту застосовуються на основі прийнятних форматів Вашого клієнта. Це означає, що дані сторінки будуть надані в тому форматі, якому віддає перевагу Ваш клієнт.",
        "pagedata-not-acceptable": "Не знайдено підхожого формату. Підтримувані MIME-типи: $1",
-       "pagedata-bad-title": "Недійсна назва: $1."
+       "pagedata-bad-title": "Недійсна назва: $1.",
+       "unregistered-user-config": "З міркувань безпеки користувальницькі підсторінки JavaScript, CSS та JSON не можуть бути завантажені для незареєстрованих учасників.",
+       "passwordpolicies": "Політика щодо паролів",
+       "passwordpolicies-summary": "Це список ефективних правил щодо паролів для груп користувачів, визначених у цій вікі.",
+       "passwordpolicies-group": "Група",
+       "passwordpolicies-policies": "Політика",
+       "passwordpolicies-policy-minimalpasswordlength": "Пароль має містити принаймні $1 {{PLURAL:$1|символ|символи|символів}}",
+       "passwordpolicies-policy-minimumpasswordlengthtologin": "Пароль має містити принаймні $1 {{PLURAL:$1|символ|символи|символів}} щоб мати можливість увійти до свого облікового запису",
+       "passwordpolicies-policy-passwordcannotmatchusername": "Пароль не може збігатися з назвою облікового запису",
+       "passwordpolicies-policy-passwordcannotmatchblacklist": "Пароль не може збігатися з паролями із чорного списку",
+       "passwordpolicies-policy-maximalpasswordlength": "Пароль повинен бути коротшим $1 {{PLURAL:$1|символа|символів}}",
+       "passwordpolicies-policy-passwordcannotbepopular": "Пароль не може бути {{PLURAL:$1|часто вживаним|будь-яким з $1 часто вживаних паролів}}"
 }
index 4f95d36..097cc73 100644 (file)
@@ -79,7 +79,7 @@
        "tog-watchlisthideminor": "Ẩn các sửa đổi nhỏ khỏi danh sách theo dõi",
        "tog-watchlisthideliu": "Ẩn sửa đổi của thành viên đã đăng nhập khỏi danh sách theo dõi",
        "tog-watchlistreloadautomatically": "Tự động tải lại danh sách theo dõi khi nào bộ lọc được thay đổi (cần JavaScript)",
-       "tog-watchlistunwatchlinks": "Thêm liên kết ngừng theo dõi/theo dõi trực tiếp vào mục trong danh sách theo dõi (cần JavaScript để bật/tắt)",
+       "tog-watchlistunwatchlinks": "Thêm nút ngừng theo dõi/theo dõi ({{int:Watchlist-unwatch}}/{{int:Watchlist-unwatch-undo}}) trực tiếp vào trang theo dõi có thay đổi (cần JavaScript để bật/tắt)",
        "tog-watchlisthideanons": "Ẩn sửa đổi của người dùng vô danh khỏi danh sách theo dõi",
        "tog-watchlisthidepatrolled": "Ẩn sửa đổi đã tuần tra trong danh sách theo dõi",
        "tog-watchlisthidecategorization": "Ẩn việc xếp thể loại",
        "cascadeprotected": "Trang này đã bị khóa không cho sửa đổi, vì nó được nhúng vào {{PLURAL:$1|trang|những trang}} đã bị khóa với tùy chọn “khóa theo tầng” được kích hoạt:\n$2",
        "namespaceprotected": "Bạn không có quyền sửa các trang trong không gian tên '''$1'''.",
        "customcssprotected": "Bạn không có quyền sửa đổi trang CSS này vì nó chứa các tùy chọn cá nhân của một thành viên khác.",
+       "customjsonprotected": "Bạn không có quyền sửa đổi trang JSON này vì nó chứa các tùy chọn cá nhân của một thành viên khác.",
        "customjsprotected": "Bạn không có quyền sửa đổi trang JavaScript này vì nó chứa các tùy chọn cá nhân của một thành viên khác.",
        "mycustomcssprotected": "Bạn không có quyền sửa đổi trang CSS này.",
+       "mycustomjsonprotected": "Bạn không có quyền sửa đổi trang JSON này.",
        "mycustomjsprotected": "Bạn không có quyền sửa đổi trang JavaScript này.",
        "myprivateinfoprotected": "Bạn không có quyền sửa đổi thông tin cá nhân của bạn.",
        "mypreferencesprotected": "Bạn không có quyền thay đổi tùy chọn của bạn.",
        "password-login-forbidden": "Tên đăng nhập và mật khẩu này đã bị cấm không được sử dụng.",
        "mailmypassword": "Tái tạo mật khẩu",
        "passwordremindertitle": "Mật khẩu tạm thời cho {{SITENAME}}",
-       "passwordremindertext": "Ai đó (có thể là bạn, có địa chỉ IP $1) đã yêu cầu chúng tôi gửi mật khẩu mới của {{SITENAME}} ($4). Chúng tôi đã tạo một mật khẩu tạm “$3” cho thành viên “$2”. Nếu bạn chính là người đã yêu cầu mật khẩu, bạn cần phải đăng nhập và thay đổi mật khẩu ngay bây giờ. Mật khẩu tạm sẽ hết hạn trong vòng {{PLURAL:$5|một ngày|$5 ngày}}.\n\nNếu bạn không yêu cầu gửi mật khẩu mới, hoặc bạn đã nhớ ra mật khẩu cũ của mình và không còn muốn đổi nó nữa, bạn có thể bỏ qua bức thư này và tiếp tục sử dụng mật khẩu cũ của bạn.",
+       "passwordremindertext": "Ai đó (có địa chỉ IP $1) đã yêu cầu chúng tôi gửi mật khẩu mới của {{SITENAME}} ($4). Chúng tôi đã tạo một mật khẩu tạm “$3” cho thành viên “$2”. Nếu bạn chính là người đã yêu cầu mật khẩu, bạn cần phải đăng nhập và thay đổi mật khẩu ngay bây giờ. Mật khẩu tạm sẽ hết hạn trong vòng {{PLURAL:$5|một ngày|$5 ngày}}.\n\nNếu bạn không yêu cầu gửi mật khẩu mới, hoặc bạn đã nhớ ra mật khẩu cũ của mình và không còn muốn đổi nó nữa, bạn có thể bỏ qua bức thư này và tiếp tục sử dụng mật khẩu cũ của bạn.",
        "noemail": "Thành viên “$1” không ghi thư điện tử.",
        "noemailcreate": "Bạn cần cung cấp một địa chỉ thư điện tử hợp lệ",
        "passwordsent": "Mật khẩu mới đã được gửi tới thư điện tử của thành viên “$1”. Xin đăng nhập lại sau khi nhận thư.",
        "botpasswords-existing": "Mật khẩu bot hiện tại",
        "botpasswords-createnew": "Tạo một mật khẩu mới bot",
        "botpasswords-editexisting": "Chỉnh sửa một mật khẩu hiện tại của bot",
+       "botpasswords-label-needsreset": "(mật khẩu cần được đặt lại)",
        "botpasswords-label-appid": "Tên bot:",
        "botpasswords-label-create": "Tạo",
        "botpasswords-label-update": "Cập nhật",
        "botpasswords-label-grants": "Các quyền có liên quan:",
        "botpasswords-help-grants": "Các lượt cấp phép cho phép truy cập các quyền lợi mà tài khoản của bạn đã có. Việc cấp phép tại đây không có cho phép truy cập quyền nào mà tài khoản của bạn thường không có. Xem thêm thông tin trong [[Special:ListGrants|bảng cấp phép]].",
        "botpasswords-label-grants-column": "Cấp quyền",
-       "botpasswords-bad-appid": "Bot có tên \"$1\" không hợp lệ.",
+       "botpasswords-bad-appid": "Tên bot “$1” không hợp lệ.",
        "botpasswords-insert-failed": "Không thể thêm tên bot \"$1\". Nó đã được thêm vào chưa?",
        "botpasswords-update-failed": "Không thể khi cập nhật bot có tên “$1”. Có phải nó đã bị xóa?",
        "botpasswords-created-title": "Mật khẩu bot đã được tạo",
-       "botpasswords-created-body": "Đã tạo mật khẩu cho bot tên \"$1\" của {{GENDER:$2|thành viên}} \"$2\".",
+       "botpasswords-created-body": "Đã tạo mật khẩu cho bot tên “$1” của thành viên “$2”.",
        "botpasswords-updated-title": "Mật khẩu Bot đã được cập nhật",
-       "botpasswords-updated-body": "Đã cập nhật mật khẩu cho bot tên \"$1\" của {{GENDER:$2|thành viên}} \"$2\".",
+       "botpasswords-updated-body": "Đã cập nhật mật khẩu cho bot tên “$1” của thành viên “$2”.",
        "botpasswords-deleted-title": "Mật khẩu bot đã bị xóa",
-       "botpasswords-deleted-body": "Đã xóa mật khẩu cho bot tên \"$1\" của {{GENDER:$2|thành viên}} \"$2\".",
+       "botpasswords-deleted-body": "Đã xóa mật khẩu cho bot tên “$1” của thành viên “$2”.",
        "botpasswords-newpassword": "Mật khẩu mới để đăng nhập như <strong>$1</strong> là <strong>$2</strong>. <em>Xin hãy ghi lại mật khẩu này để mai mốt tham khảo.</em> <br> (Các bot cũ cần tên đăng nhập khớp với tên người dùng cuối cùng có thể sử  dụng tên người dùng <strong>$3</strong> và mật khẩu <strong>$4</strong>.)",
        "botpasswords-no-provider": "BotPasswordsSessionProvider không có sẵn.",
        "botpasswords-restriction-failed": "Mật khẩu bot giới hạn ngăn chặn đăng nhập này.",
        "botpasswords-invalid-name": "Tên người dùng đã chỉ định không chứa dấu tách mật khẩu bot (\"$1\").",
        "botpasswords-not-exist": "Người dùng \"$1\" không có mật khẩu bot có tên \"$2\".",
+       "botpasswords-needs-reset": "Mật khẩu bot của bot tên “$2” của người dùng “$1” cần được đặt lại.",
        "resetpass_forbidden": "Không được đổi mật khẩu",
        "resetpass_forbidden-reason": "Không thể đổi mật khẩu: $1",
        "resetpass-no-info": "Bạn phải đăng nhập mới có thể truy cập trực tiếp trang này.",
        "savechanges": "Lưu các thay đổi",
        "publishpage": "Đăng trang",
        "publishchanges": "Đăng thay đổi",
-       "savearticle-start": "Lưu trang...",
-       "savechanges-start": "Lưu thay đổi...",
-       "publishpage-start": "Đăng trang...",
-       "publishchanges-start": "Đăng thay đổi...",
+       "savearticle-start": "Lưu trang",
+       "savechanges-start": "Lưu các thay đổi…",
+       "publishpage-start": "Đăng trang",
+       "publishchanges-start": "Đăng các thay đổi…",
        "preview": "Xem trước",
        "showpreview": "Xem trước",
        "showdiff": "Xem thay đổi",
        "subject-preview": "Xem trước đề mục:",
        "previewerrortext": "Có lỗi xảy ra khi xem trước những thay đổi của bạn.",
        "blockedtitle": "Thành viên bị cấm",
-       "blockedtext": "'''Tên người dùng hoặc địa chỉ IP của bạn đã bị cấm.'''\n\nNgười thực hiện cấm là $1.\nLý do được cung cấp là ''$2''.\n\n* Bắt đầu cấm: $8\n* Kết thúc cấm: $6\n* Mục tiêu cấm: $7\n\nBạn có thể liên hệ với $1 hoặc một [[{{MediaWiki:Grouppage-sysop}}|bảo quản viên]] khác để thảo luận về việc cấm.\nBạn không thể sử dụng tính năng “gửi thư cho người này” trừ khi bạn đã ghi một địa chỉ thư điện tử hợp lệ trong [[Special:Preferences|tùy chọn tài khoản]] và bạn không bị khóa chức năng đó.\nĐịa chỉ IP hiện tại của bạn là $3, và mã số cấm là #$5.\nXin hãy ghi kèm tất cả các thông tin trên vào thư yêu cầu của bạn.",
-       "autoblockedtext": "Địa chỉ IP của bạn đã bị tự động cấm vì một người nào đó đã sử dụng nó, $1 là thành viên đã thực hiện cấm.\nLý do được cung cấp là:\n\n:''$2''\n\n* Bắt đầu cấm: $8\n* Kết thúc cấm: $6\n* Mục tiêu cấm: $7\n\nBạn có thể liên hệ với $1 hoặc một trong số các\n[[{{MediaWiki:Grouppage-sysop}}|bảo quản viên]] khác để thảo luận về việc cấm.\n\nChú ý rằng bạn sẽ không dùng được chức năng “gửi thư cho người này” trừ khi bạn đã ghi một địa chỉ thư điện tử hợp lệ trong [[Special:Preferences|tùy chọn]] và bạn không bị cấm dùng chức năng đó.\n\nĐịa chỉ IP hiện tại của bạn là $3, mã số cấm là $5.\nXin hãy ghi kèm tất cả các chi tiết trên vào thư yêu cầu của bạn.",
+       "blockedtext": "<strong>Tên người dùng hoặc địa chỉ IP của bạn đã bị cấm.</strong>\n\nNgười thực hiện cấm là $1.\nLý do được cung cấp là <em>$2</em>.\n\n* Bắt đầu cấm: $8\n* Kết thúc cấm: $6\n* Mục tiêu cấm: $7\n\nBạn có thể liên hệ với $1 hoặc một [[{{MediaWiki:Grouppage-sysop}}|bảo quản viên]] khác để thảo luận về việc cấm.\nBạn không thể sử dụng tính năng “{{int:emailuser}}” trừ khi bạn đã ghi một địa chỉ thư điện tử hợp lệ trong [[Special:Preferences|tùy chọn tài khoản]] và bạn không bị khóa chức năng đó.\nĐịa chỉ IP hiện tại của bạn là $3, và mã số cấm là #$5.\nXin hãy ghi kèm tất cả các thông tin trên vào thư yêu cầu của bạn.",
+       "autoblockedtext": "Địa chỉ IP của bạn đã bị tự động cấm vì một người nào đó đã sử dụng nó, $1 là thành viên đã thực hiện cấm.\nLý do được cung cấp là:\n\n:<em>$2</em>\n\n* Bắt đầu cấm: $8\n* Kết thúc cấm: $6\n* Mục tiêu cấm: $7\n\nBạn có thể liên hệ với $1 hoặc một trong số các\n[[{{MediaWiki:Grouppage-sysop}}|bảo quản viên]] khác để thảo luận về việc cấm.\n\nChú ý rằng bạn sẽ không dùng được chức năng “{{int:emailuser}}” trừ khi bạn đã ghi một địa chỉ thư điện tử hợp lệ trong [[Special:Preferences|tùy chọn]] và bạn không bị cấm dùng chức năng đó.\n\nĐịa chỉ IP hiện tại của bạn là $3, mã số cấm là $5.\nXin hãy ghi kèm tất cả các chi tiết trên vào thư yêu cầu của bạn.",
        "systemblockedtext": "Tên người dùng hoặc địa chỉ IP của bạn bị MediaWiki cấm tự động.\nLý do được cung cấp là:\n\n:<em>$2</em>\n\n* Bắt đầu cấm: $8\n* Kết thúc cấm: $6\n* Mục tiêu cấm: $7\n\nĐịa chỉ IP hiện tại của bạn là $3.\nXin vui lòng bao gồm tất cả các chi tiết bên trên khi nào hỏi về tác vụ này.",
        "blockednoreason": "không đưa ra lý do",
        "whitelistedittext": "Bạn phải $1 để sửa trang.",
        "blocked-notice-logextract": "Người dùng này hiện đang bị cấm sửa đổi. Nhật trình cấm gần nhất được ghi ở dưới để tiện theo dõi:",
        "clearyourcache": "<strong>Chú ý:</strong> Sau khi lưu trang, có thể bạn sẽ phải xóa bộ nhớ đệm của trình duyệt để xem các thay đổi.\n* <strong>Firefox / Safari:</strong> Nhấn giữ phím <em>Shift</em> trong khi nhấn <em>Tải lại</em> (<em>Reload</em>), hoặc nhấn tổ hợp <em>Ctrl-F5</em> hay <em>Ctrl-R</em> (⌘R trên Mac)\n* <strong>Google Chrome:</strong> Nhấn tổ hợp <em>Ctrl-Shift-R</em> (⇧⌘R trên Mac)\n* <strong>Internet Explorer:</strong> Nhấn giữ phím <em>Ctrl</em> trong khi nhấn <em>Làm tươi</em>, hoặc nhấn tổ hợp <em>Ctrl-F5</em>\n* <strong>Opera:</strong> Mở <em>Menu → Cài đặt</em> (<em>Opera → Tùy chỉnh</em> trên Mac), mở tab <em>Quyền riêng tư & bảo mật</em>, bấm <em>Xóa dữ liệu duyệt web</em> và đánh hộp kiểm <em>Hình ảnh và tệp trong cache</em>.",
        "usercssyoucanpreview": "'''Mẹo:''' Sử dụng nút “{{int:showpreview}}” để kiểm thử bản CSS của bạn trước khi lưu trang.",
+       "userjsonyoucanpreview": "'''Mẹo:''' Sử dụng nút “{{int:showpreview}}” để kiểm thử bản JSON của bạn trước khi lưu trang.",
        "userjsyoucanpreview": "'''Mẹo:''' Sử dụng nút “{{int:showpreview}}” để kiểm thử bản JS của bạn trước khi lưu trang.",
        "usercsspreview": "'''Hãy nhớ rằng bạn chỉ đang xem trước trang CSS cá nhân của bạn.\nNó chưa được lưu!'''",
+       "userjsonpreview": "<strong>Nhớ rằng bạn chỉ đang kiểm thử/xem trước cấu hình JSON, nó chưa được lưu!</strong>",
        "userjspreview": "'''Nhớ rằng bạn chỉ đang kiểm thử/xem trước trang JavaScript, nó chưa được lưu!'''",
        "sitecsspreview": "'''Nhớ rằng bạn chỉ đang xem trước bản CSS này.'''\n'''Nó chưa được lưu!'''",
+       "sitejsonpreview": "<strong>Nhớ rằng bạn chỉ đang xem trước cấu hình JSON này.\nNó chưa được lưu!</strong>",
        "sitejspreview": "'''Nhớ rằng bạn chỉ đang xem trước bản JavaScript này.\n'''Nó chưa được lưu!'''",
-       "userinvalidconfigtitle": "'''Cảnh báo:''' Không có skin “$1”. Hãy nhớ rằng các trang .css và .js tùy chỉnh sử dụng tiêu đề chữ thường, như {{ns:user}}:Ví&nbsp;dụ/vector.css chứ không phải {{ns:user}}:Ví&nbsp;dụ/Vector.css.",
+       "userinvalidconfigtitle": "<strong>Cảnh báo:</strong> Không có skin “$1”. Các trang .css, .json, và .js tùy chỉnh sử dụng tiêu đề chữ thường, như {{ns:user}}:Ví&nbsp;dụ/vector.css chứ không phải {{ns:user}}:Ví&nbsp;dụ/Vector.css.",
        "updated": "(Cập nhật)",
        "note": "'''Ghi chú:'''",
        "previewnote": "'''Đây chỉ mới là bản xem trước.'''\nCác thay đổi của bạn vẫn chưa được lưu!",
        "longpageerror": "'''Lỗi: Văn bạn mà bạn muốn lưu dài $1 kilôbyte, dài hơn độ dài tối đa cho phép $2 kilôbyte.'''\nKhông thể lưu trang.",
        "readonlywarning": "<strong>CẢNH BÁO: Cơ sở dữ liệu đã bị khóa để bảo dưỡng, do đó bạn không thể lưu các sửa đổi của mình. Bạn nên cắt-dán đoạn bạn vừa sửa vào một tập tin và lưu nó lại để sửa đổi sau này.</strong>\n\nQuản trị viên hệ thống khi khóa dữ liệu đã đưa ra lý do: $1",
        "protectedpagewarning": "'''Cảnh báo: Trang này đã bị khóa và chỉ có các thành viên có quyền quản lý mới có thể sửa được.'''\nThông tin mới nhất trong nhật trình được ghi dưới đây để tiện theo dõi:",
-       "semiprotectedpagewarning": "'''Lưu ý:''' Trang này đã bị khóa nên chỉ có các thành viên có tài khoản mới có thể sửa đổi được.\nThông tin mới nhất trong nhật trình được ghi dưới đây để tiện theo dõi:",
+       "semiprotectedpagewarning": "<strong>Lưu ý:</strong> Trang này đã bị khóa nên chỉ có các thành viên tự xác nhận có thể sửa đổi được.\nThông tin mới nhất trong nhật trình được ghi dưới đây để tiện theo dõi:",
        "cascadeprotectedwarning": "'''Cảnh báo:''' Trang này đã bị khóa, chỉ có thành viên có [[Special:ListGroupRights|quyền quản lý]] mới có thể sửa đổi, vì nó được nhúng vào {{PLURAL:$1|trang|những trang}} bị khóa theo tầng sau:",
        "titleprotectedwarning": "'''Cảnh báo:  Trang này đã bị khóa và bạn phải có một số [[Special:ListGroupRights|quyền nhất định]] mới có thể tạo trang.'''\nThông tin mới nhất trong nhật trình được ghi dưới đây để tiện theo dõi:",
        "templatesused": "{{PLURAL:$1|Bản mẫu|Các bản mẫu}} dùng trong trang này:",
        "diff-multi-sameuser": "(Không hiển thị {{PLURAL:$1||$1}} phiên bản của cùng người dùng ở giữa)",
        "diff-multi-otherusers": "(Không hiển thị {{PLURAL:$1||$1}} phiên bản của {{PLURAL:$2|một người dùng khác|$2 người dùng}} ở giữa)",
        "diff-multi-manyusers": "(Không hiển thị {{PLURAL:$1||$1}} phiên bản của hơn $2 thành viên ở giữa)",
+       "diff-paragraph-moved-tonew": "Đoạn văn được chuyển đến vị trí mới. Nhấn chuột để nhảy tới vị trí mới.",
+       "diff-paragraph-moved-toold": "Đoạn văn được chuyển từ vị trí khác. Nhấn chuột để nhảy tới vị trí cũ.",
        "difference-missing-revision": "Không tìm thấy {{PLURAL:$2|một phiên bản|$2 phiên bản}} trong khác biệt này ($1).\n\nLỗi này thường xuất hiện đối khi theo dõi liên kết lỗi thời đến khác biệt giữa các bản của trang đã bị xóa.\nXem chi tiết trong [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} nhật trình xóa].",
        "searchresults": "Kết quả tìm kiếm",
        "searchresults-title": "Kết quả tìm kiếm “$1”",
        "stub-threshold-disabled": "Tắt",
        "recentchangesdays": "Số ngày hiển thị trong thay đổi gần đây:",
        "recentchangesdays-max": "(tối đa $1 ngày)",
-       "recentchangescount": "Số sửa đổi hiển thị mặc định:",
-       "prefs-help-recentchangescount": "Số này bao gồm các thay đổi gần đây, lịch sử trang, và nhật trình.",
+       "recentchangescount": "Số sửa đổi để hiển thị trong thay đổi gần đây, lịch sử trang, và nhật trình theo mặc định:",
+       "prefs-help-recentchangescount": "Con số tối đa: 1.000",
        "prefs-help-watchlist-token2": "Đây là chìa khóa bí mật cho nguồn cấp dữ liệu danh sách theo dõi của bạn.\nBất cứ ai biết nó sẽ có thể để đọc danh sách theo dõi của bạn, vì vậy đừng chia sẻ nó.\nNếu cần, [[Special:ResetTokens|bạn có thể thiết lập lại nó]].",
        "savedprefs": "Đã lưu các tùy chọn cá nhân.",
        "savedrights": "Đã lưu các nhóm người dùng của {{GENDER:$1}}$1.",
        "default": "mặc định",
        "prefs-files": "Tập tin",
        "prefs-custom-css": "sửa CSS",
+       "prefs-custom-json": "JSON tùy biến",
        "prefs-custom-js": "sửa JS",
-       "prefs-common-config": "CSS/JavaScript chung cho mọi giao diện:",
+       "prefs-common-config": "CSS/JSON/JavaScript chung cho mọi giao diện:",
        "prefs-reset-intro": "Có thể mặc định lại toàn bộ tùy chọn dùng trang này. Điều này không thể hoàn tác.",
        "prefs-emailconfirm-label": "Xác nhận thư điện tử:",
        "youremail": "Thư điện tử:",
        "right-editcontentmodel": "Sửa kiểu nội dung của trang",
        "right-editinterface": "Sửa giao diện người dùng",
        "right-editusercss": "Sửa tập tin CSS của người dùng khác",
+       "right-edituserjson": "Sửa tập tin JSON của người dùng khác",
        "right-edituserjs": "Sửa đổi tập tin JavaScript của người dùng khác",
        "right-editmyusercss": "Sửa đổi tập tin CSS cá nhân của mình",
+       "right-editmyuserjson": "Sửa đổi tập tin JSON cá nhân của mình",
        "right-editmyuserjs": "Sửa đổi tập tin JavaScript cá nhân của mình",
        "right-viewmywatchlist": "Xem danh sách theo dõi của mình",
        "right-editmywatchlist": "Sửa đổi danh sách theo dõi của mình – một số tác vụ có thể thêm trang vào danh sách bất chấp quyền này",
        "grant-createaccount": "Mở tài khoản",
        "grant-createeditmovepage": "Tạo, sửa đổi, và di chuyển trang",
        "grant-delete": "Xóa trang, phiên bản, và mục nhật trình",
-       "grant-editinterface": "Sửa không gian tên MediaWiki và CSS/JavaScript cá nhân",
-       "grant-editmycssjs": "Sửa đổi CSS/JavaScript cá nhân của bạn",
+       "grant-editinterface": "Sửa không gian tên MediaWiki và CSS/JSON/JavaScript cá nhân",
+       "grant-editmycssjs": "Sửa đổi CSS/JSON/JavaScript cá nhân của bạn",
        "grant-editmyoptions": "Sửa đổi tùy chọn cá nhân của bạn",
        "grant-editmywatchlist": "Sửa danh sách theo dõi của bạn",
        "grant-editpage": "Sửa đổi các trang đã tồn tại",
        "rcfilters-advancedfilters": "Bộ lọc nâng cao",
        "rcfilters-limit-title": "Số kết quả hiển thị",
        "rcfilters-limit-and-date-label": "$1 thay đổi, $2",
+       "rcfilters-date-popup-title": "Thời gian tìm kiếm",
        "rcfilters-days-title": "Những ngày gần đây",
        "rcfilters-hours-title": "Số giờ gần đây",
        "rcfilters-days-show-days": "$1 ngày",
        "rcfilters-restore-default-filters": "Mặc định lại các bộ lọc",
        "rcfilters-clear-all-filters": "Xóa sạch các bộ lọc",
        "rcfilters-show-new-changes": "Xem các thay đổi mới nhất",
-       "rcfilters-search-placeholder": "Lọc các thay đổi gần đây (duyệt hoặc bắt đầu đánh chữ)",
+       "rcfilters-search-placeholder": "Lọc các thay đổi gần đây (sử dụng trình đơn hoặc tìm tên bộ lọc)",
        "rcfilters-invalid-filter": "Bộ lọc không hợp lệ",
        "rcfilters-empty-filter": "Không có bộ lọc hiện hành. Tất cả các đóng góp được hiển thị.",
        "rcfilters-filterlist-title": "Bộ lọc",
        "rcfilters-filter-user-experience-level-unregistered-label": "Vô danh",
        "rcfilters-filter-user-experience-level-unregistered-description": "Người dùng chưa đăng nhập.",
        "rcfilters-filter-user-experience-level-newcomer-label": "Người mới đến",
-       "rcfilters-filter-user-experience-level-newcomer-description": "Người dùng đã đăng nhập có ít hơn 10 sửa đổi  4 ngày hoạt động.",
+       "rcfilters-filter-user-experience-level-newcomer-description": "Người dùng đã đăng nhập có ít hơn 10 sửa đổi hoặc 4 ngày hoạt động.",
        "rcfilters-filter-user-experience-level-learner-label": "Người đang tập",
        "rcfilters-filter-user-experience-level-learner-description": "Người dùng đã đăng nhập có nhiều kinh nghiệm hơn “Người mới đến” mà ít hơn “Người có kinh nghiệm”.",
        "rcfilters-filter-user-experience-level-experienced-label": "Người có kinh nghiệm",
        "rcfilters-filter-humans-label": "Con người (không phải bot)",
        "rcfilters-filter-humans-description": "Các sửa đổi của người thật.",
        "rcfilters-filtergroup-reviewstatus": "Tình trạng tuần tra",
+       "rcfilters-filter-reviewstatus-unpatrolled-description": "Các sửa đổi không được đánh dấu tuần tra thủ công hoặc tự động.",
        "rcfilters-filter-reviewstatus-unpatrolled-label": "Chưa được tuần tra",
+       "rcfilters-filter-reviewstatus-manual-description": "Các sửa đổi được đánh dấu tuần tra thủ công.",
+       "rcfilters-filter-reviewstatus-manual-label": "Đánh dấu tuần tra thủ công",
+       "rcfilters-filter-reviewstatus-auto-description": "Sửa đổi của người dùng nâng cao được đánh dấu tuần tra tự động.",
+       "rcfilters-filter-reviewstatus-auto-label": "Tự đánh dấu tuần tra",
        "rcfilters-filtergroup-significance": "Sự quan trọng",
        "rcfilters-filter-minor-label": "Sửa đổi nhỏ",
        "rcfilters-filter-minor-description": "Các sửa đổi được tác giả đánh dấu là nhỏ.",
        "rcfilters-watchlist-edit-watchlist-button": "Sửa danh sách trang theo dõi",
        "rcfilters-watchlist-showupdated": "Thay đổi mới trên các trang kể lần cuối bạn xem trang được in <strong>đậm</strong> và có dấu tô màu.",
        "rcfilters-preference-label": "Ẩn phiên bản cải tiến của trang Thay đổi Gần đây",
+       "rcfilters-filter-showlinkedfrom-label": "Xem các thay đổi tại trang có liên kết từ",
+       "rcfilters-filter-showlinkedfrom-option-label": "<strong>Trang có liên kết từ</strong> trang được chọn",
+       "rcfilters-filter-showlinkedto-label": "Xem các thay đổi tại trang có liên kết đến",
+       "rcfilters-filter-showlinkedto-option-label": "<strong>Trang có liên kết đến</strong> trang được chọn",
        "rcfilters-target-page-placeholder": "Nhập tên trang (hoặc thể loại)",
        "rcnotefrom": "Dưới đây là {{PLURAL:$5|thay đổi duy nhất|các thay đổi}} từ <strong>$3 $4</strong> (hiển thị tối đa <strong>$1</strong> thay đổi).",
        "rclistfromreset": "Đặt lại lựa chọn ngày",
        "recentchangeslinked-feed": "Thay đổi liên quan",
        "recentchangeslinked-toolbox": "Thay đổi liên quan",
        "recentchangeslinked-title": "Thay đổi liên quan tới “$1”",
-       "recentchangeslinked-summary": "Nhập tên trang để xem các thay đổi được thực hiện tại những trang được liên kết với trang đó. (Để xem các trang được xếp vào một thể loại nào đó, nhập Thể loại:Tên thể loại). Các thay đổi được thực hiện tại trang trong [[Special:Watchlist|danh sách bạn theo dõi]] được '''tô đậm'''.",
+       "recentchangeslinked-summary": "Nhập tên trang để xem các thay đổi được thực hiện tại những trang được liên kết với trang đó. (Để xem các trang được xếp vào một thể loại nào đó, nhập {{ns:category}}:Tên thể loại). Các thay đổi được thực hiện tại trang trong [[Special:Watchlist|danh sách bạn theo dõi]] được '''tô đậm'''.",
        "recentchangeslinked-page": "Tên trang:",
        "recentchangeslinked-to": "Hiện thay đổi tại những trang có liên kết đến trang này thay thế",
        "recentchanges-page-added-to-category": "[[:$1]] được xếp vào thể loại",
        "uploaded-script-svg": "Tìm thấy phần tử “$1” có khả năng chạy kịch bản trong tập tin SVG được tải lên.",
        "uploaded-hostile-svg": "Tìm thấy CSS nguy hiểm trong phần tử style của tập tin SVG được tải lên.",
        "uploaded-event-handler-on-svg": "Không cho phép đặt thuộc tính xử lý sự kiện <code>$1=\"$2\"</code> trong tập tin SVG.",
-       "uploaded-href-attribute-svg": "Các đặc tính href trong tập tin SVG chỉ được phép dẫn đến các trang http:// hoặc https://, nhưng gặp phải <code>&lt;$1 $2=\"$3\"&gt;</code>.",
+       "uploaded-href-attribute-svg": "Phần tử <a> chỉ có thể liên kết (đặc tính href) đến đích data: (tập tin nhúng), http:// hay https://, hoặc mảnh (#, cùng trang). Đối với các phần tử khác như <image>, chỉ cho phép data: và mảnh. Hãy thử nhúng hình ảnh khi xuất hình SVG. Đã tìm thấy <code>&lt;$1 $2=\"$3\"&gt;</code>.",
        "uploaded-href-unsafe-target-svg": "Tìm thấy href đến đích URI data: không an toàn <code>&lt;$1 $2=\"$3\"&gt;</code> trong tập tin SVG được tải lên.",
        "uploaded-animate-svg": "Tìm thấy thẻ “animate” có thể thay đổi href qua thuộc tính “from” <code>&lt;$1 $2=\"$3\"&gt;</code> trong tập tin SVG được tải lên.",
        "uploaded-setting-event-handler-svg": "Đã ngăn cản việc đặt thuộc tính xử lý sự kiện khi tìm thấy <code>&lt;$1 $2=\"$3\"&gt;</code> trong tập tin SVG được tải lên.",
        "lockmanager-fail-closelock": "Không thể đóng tập tin khóa cho “$1”.",
        "lockmanager-fail-deletelock": "Không thể xóa tập tin khóa cho “$1”.",
        "lockmanager-fail-acquirelock": "Không thể lấy khóa cho “$1”.",
-       "lockmanager-fail-openlock": "Không thể mở tập tin khóa cho “$1”.",
+       "lockmanager-fail-openlock": "Không thể mở tập tin khóa cho “$1”. Hãy chắc chắn rằng thư mục tải lên được cấu hình đàng hoàng và máy chủ Web được phép ghi vào thư mục đó. Xem thêm chi tiết tại https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:$wgUploadDirectory.",
        "lockmanager-fail-releaselock": "Không thể thả khóa cho “$1”.",
        "lockmanager-fail-db-bucket": "Không thể liên lạc với đủ cơ sở dữ liệu khóa trong nhóm $1.",
        "lockmanager-fail-db-release": "Không thể thả các chìa khóa trên cơ sở dữ liệu $1.",
        "uploadstash-bad-path-invalid": "Đường dẫn không hợp lệ.",
        "uploadstash-bad-path-unknown-type": "Loại không xác định \"$1\".",
        "uploadstash-bad-path-unrecognized-thumb-name": "Tên hình thu nhỏ không nhận dạng được.",
+       "uploadstash-bad-path-bad-format": "Chìa khóa “$1” không tuân theo định dạng.",
        "uploadstash-file-not-found-no-thumb": "Không thể tải hình thu nhỏ.",
        "uploadstash-file-not-found-no-object": "Không tạo được đối tượng tập tin cục bộ cho hình thu nhỏ.",
        "uploadstash-file-not-found-no-remote-thumb": "Nạp hình thu nhỏ thất bại: $1\nURL = $2",
+       "uploadstash-file-not-found-missing-content-type": "Thiếu đầu đề kiểu-nội-dung (content-type).",
        "uploadstash-not-logged-in": "Người dùng chưa đăng nhập, các tập tin phải do người dùng đã đăng nhập tải lên.",
        "uploadstash-no-such-key": "Khoá không tồn tại ($1), không thể xoá.",
        "uploadstash-zero-length": "Tập tin có dung lượng bằng không.",
        "doubleredirects": "Đổi hướng kép",
        "doubleredirectstext": "Trang này liệt kê các trang đổi hướng đến một trang đổi hướng khác.\nMỗi hàng có chứa các liên kết đến trang đổi hướng thứ nhất và thứ hai, cũng như mục tiêu của trang đổi hướng thứ hai, thường là trang đích “thực sự”, là nơi mà trang đổi hướng đầu tiên nên trỏ đến.\nCác mục <del>bị gạch bỏ</del> là các trang đã được sửa.",
        "double-redirect-fixed-move": "[[$1]] đã được đổi tên.\nNó được cập nhật tự động và giờ là trang đổi hướng đến [[$2]].",
-       "double-redirect-fixed-maintenance": "Tự động giải quyết đổi hướng kép từ [[$1]] đến [[$2]] trong một công việc bảo trì.",
+       "double-redirect-fixed-maintenance": "Tự động giải quyết đổi hướng kép từ [[$1]] đến [[$2]] trong một công việc bảo trì",
        "double-redirect-fixer": "Người sửa trang đổi hướng",
        "brokenredirects": "Đổi hướng sai",
        "brokenredirectstext": "Các trang đổi hướng sau đây liên kết đến trang không tồn tại:",
        "deadendpages": "Trang đường cùng",
        "deadendpagestext": "Các trang này không có liên kết đến trang khác trong {{SITENAME}}.",
        "protectedpages": "Trang bị khóa",
+       "protectedpages-filters": "Bộ lọc:",
        "protectedpages-indef": "Chỉ hiển thị khóa vô hạn",
        "protectedpages-summary": "Danh sách này liệt kê các trang hiện đang bị khóa. Xem danh sách các tên trang bị khóa không được tạo ra tại [[{{#special:ProtectedTitles}}|{{int:protectedtitles}}]].",
        "protectedpages-cascade": "Chỉ hiển thị khóa theo tầng",
        "protectedtitles-submit": "Xem các tên trang",
        "listusers": "Danh sách thành viên",
        "listusers-editsonly": "Chỉ hiện thành viên có tham gia sửa đổi",
+       "listusers-temporarygroupsonly": "Chỉ xem những người dùng trong nhóm người dùng tạm",
        "listusers-creationsort": "Xếp theo ngày khởi tạo",
        "listusers-desc": "Sắp xếp thứ tự giảm dần",
        "usereditcount": "$1 sửa đổi",
        "apisandbox-dynamic-parameters-add-label": "Thêm tham số:",
        "apisandbox-dynamic-parameters-add-placeholder": "Tên tham số",
        "apisandbox-dynamic-error-exists": "Một tham số có tên \"$1\" đã tồn tại.",
+       "apisandbox-templated-parameter-reason": "[[Special:ApiHelp/main#main/templatedparams|Tham số mẫu]] này được cung cấp theo {{PLURAL:$1|giá trị|các giá trị}} của $2.",
        "apisandbox-deprecated-parameters": "Tham số bị phản đối",
        "apisandbox-fetch-token": "Tự động điền token này",
+       "apisandbox-add-multi": "Thêm",
        "apisandbox-submit-invalid-fields-title": "Một số field là không hợp lệ",
        "apisandbox-submit-invalid-fields-message": "Xin vui lòng sửa các miền được đánh dấu và thử lại.",
        "apisandbox-results": "Kết quả",
        "rollback-success": "Đã hủy sửa đổi của {{GENDER:$3}}$1;\nquay về phiên bản cuối của {{GENDER:$4}}$2.",
        "rollback-success-notify": "Đã hủy sửa đổi của $1;\nquay về phiên bản cuối của $2. [$3 Xem thay đổi]",
        "sessionfailure-title": "Phiên thất bại",
-       "sessionfailure": "Dường như có trục trặc với phiên đăng nhập của bạn; thao tác này đã bị hủy để tránh việc cướp quyền đăng nhập. Xin hãy nhấn nút “Back”, tải lại trang đó, rồi thử lại.",
+       "sessionfailure": "Dường như có trục trặc với phiên đăng nhập của bạn; thao tác này đã bị hủy để tránh việc cướp quyền đăng nhập. Xin hãy gửi lại biểu mẫu.",
        "changecontentmodel": "Thay đổi kiểu nội dung của một trang",
        "changecontentmodel-legend": "Thay đổi kiểu nội dung",
        "changecontentmodel-title-label": "Tên trang",
        "fix-double-redirects": "Cập nhật tất cả các trang đổi hướng chỉ đến tựa đề cũ",
        "move-leave-redirect": "Để lại trang đổi hướng",
        "protectedpagemovewarning": "'''Cảnh báo:''' Trang này đã bị khóa nên chỉ có các thành viên có quyền quản lý mới có thể di chuyển được.\nThông tin mới nhất trong nhật trình được ghi dưới đây để tiện theo dõi:",
-       "semiprotectedpagemovewarning": "'''Lưu ý:''' Trang này đã bị khóa nên chỉ có các thành viên có tài khoản mới có thể di chuyển được.\nThông tin mới nhất trong nhật trình được ghi dưới đây để tiện theo dõi:",
+       "semiprotectedpagemovewarning": "<strong>Lưu ý:</strong> Trang này đã bị khóa nên chỉ có các thành viên tự xác nhận có thể di chuyển được.\nThông tin mới nhất trong nhật trình được ghi dưới đây để tiện theo dõi:",
        "move-over-sharedrepo": "[[:$1]] đã tồn tại trong kho dùng chung. Nếu đổi tên tập tin thành tên này thì sẽ ghi đè lên tập tin dùng chung.",
        "file-exists-sharedrepo": "Bạn đã chọn tên tập tin trùng với tập tin nằm trong kho dùng chung.\nXin hãy chọn tên khác.",
        "export": "Xuất các trang",
        "group-bot.css": "/* Mã CSS tại đây sẽ chỉ ảnh hưởng đến các bot */",
        "group-sysop.css": "/* Mã CSS tại đây sẽ chỉ ảnh hưởng đến các bảo quản viên */",
        "group-bureaucrat.css": "/* Mã CSS tại đây sẽ chỉ ảnh hưởng đến các hành chính viên */",
+       "common.json": "/* Bất kỳ mã JSON ở đây sẽ được tải cho tất cả các thành viên khi tải một trang nào đó lên. */",
        "common.js": "/* Bất kỳ mã JavaScript ở đây sẽ được tải cho tất cả các thành viên khi tải một trang nào đó lên. */",
        "group-autoconfirmed.js": "/* Mã JavaScript tại đây sẽ chỉ được tải cho các thành viên tự động xác nhận */",
        "group-user.js": "/* Mã JavaScript tại đây sẽ chỉ được tải cho các thành viên có tài khoản */",
        "autosumm-replace": "Đã thay thế cả nội dung bằng “$1”",
        "autoredircomment": "Đổi hướng đến [[$1]]",
        "autosumm-removed-redirect": "Xoá đổi hướng đến trang [[$1]]",
-       "autosumm-changed-redirect-target": "Thay đổi trang đích của đổi hướng từ [[$1]] sang [[S2]]",
+       "autosumm-changed-redirect-target": "Thay đổi trang đích của đổi hướng từ [[$1]] sang [[$2]]",
        "autosumm-new": "Tạo trang mới với nội dung “$1”",
        "autosumm-newblank": "Đã tạo trang trống",
        "size-bytes": "$1 byte",
        "version-specialpages": "Trang đặc biệt",
        "version-parserhooks": "Hook trong bộ xử lý",
        "version-variables": "Biến",
+       "version-editors": "Trình soạn",
        "version-antispam": "Chống spam",
        "version-other": "Phần mở rộng khác",
        "version-mediahandlers": "Bộ xử lý phương tiện",
        "version-poweredby-others": "những người khác",
        "version-poweredby-translators": "các biên dịch viên translatewiki.net",
        "version-credits-summary": "Chúng tôi muốn công nhận những người sau đã đóng góp vào [[Special:Version|MediaWiki]].",
-       "version-license-info": "MediaWiki là phần mềm tự do; bạn được phép tái phân phối và/hoặc sửa đổi nó theo những điều khoản của Giấy phép Công cộng GNU do Quỹ Phần mềm Tự do xuất bản; phiên bản 2 hay bất kỳ phiên bản nào mới hơn nào của Giấy phép.\n\nMediaWiki được phân phối với hy vọng rằng nó sẽ hữu ích, nhưng '''không có bất kỳ một bảo đảm nào cả''', ngay cả những bảo đảm ngụ ý cho '''các mục đích thương mại''' hoặc cho '''một mục đích đặc biệt nào đó'''. Xem Giấy phép Công cộng GNU để biết thêm chi tiết.\n\nCó lẽ bạn đã nhận [{{SERVER}}{{SCRIPTPATH}}/COPYING bản sao Giấy phép Công cộng GNU] đi kèm với tác phẩm này; nếu không, hãy viết thư đến:\n Free Software Foundation, Inc.\n 51 Franklin St., Fifth Floor\n Boston, MA 02110-1301\n USA\nhoặc [//www.gnu.org/licenses/old-licenses/gpl-2.0.html đọc nó trực tuyến].",
+       "version-license-info": "MediaWiki là phần mềm tự do; bạn được phép tái phân phối và/hoặc sửa đổi nó theo những điều khoản của Giấy phép Công cộng GNU do Quỹ Phần mềm Tự do xuất bản; phiên bản 2 hay bất kỳ phiên bản nào mới hơn nào của Giấy phép.\n\nMediaWiki được phân phối với hy vọng rằng nó sẽ hữu ích, nhưng <em>KHÔNG CÓ BẤT KỲ MỘT BAO ĐẢM NÀO CẢ</em>, ngay cả những bảo đảm ngụ ý cho <strong>CÁC MỤC ĐÍCH THƯƠNG MẠI</strong> hoặc cho <strong>MỘT MỤC ĐÍCH ĐẶC BIỆT NÀO ĐÓ</strong>. Xem Giấy phép Công cộng GNU để biết thêm chi tiết.\n\nCó lẽ bạn đã nhận [{{SERVER}}{{SCRIPTPATH}}/COPYING bản sao Giấy phép Công cộng GNU] đi kèm với tác phẩm này; nếu không, hãy viết thư đến:\n Free Software Foundation, Inc.\n 51 Franklin St., Fifth Floor\n Boston, MA 02110-1301\n USA\nhoặc [//www.gnu.org/licenses/old-licenses/gpl-2.0.html đọc nó trực tuyến].",
        "version-software": "Phần mềm được cài đặt",
        "version-software-product": "Phần mềm",
        "version-software-version": "Phiên bản",
        "limitreport-templateargumentsize-value": "$1/$2 byte",
        "limitreport-expansiondepth": "Độ sâu bung cao nhất",
        "limitreport-expensivefunctioncount": "Số lời gọi hàm cú pháp cần mức độ xử lý cao",
+       "limitreport-unstrip-size-value": "$1/$2 byte",
        "expandtemplates": "Bung bản mẫu",
-       "expand_templates_intro": "Trang đặc biệt này sẽ nhận vào văn bản và bung tất cả các bản mẫu trong nó ra một cách đệ quy cho đến hết. Nó cũng bung cả những hàm cú pháp như <code><nowiki>{{</nowiki>#language:…}}</code>, và những biến số như <code><nowiki>{{</nowiki>CURRENTDAY}}</code>. Thực ra nó bung các dữ liệu bình thường đặt trong ngoặc móc.",
+       "expand_templates_intro": "Trang đặc biệt này sẽ nhận vào mã wiki và bung tất cả các bản mẫu trong nó ra một cách đệ quy cho đến hết. Nó cũng bung cả những hàm cú pháp như <code><nowiki>{{</nowiki>#language:…}}</code>, và những biến số như <code><nowiki>{{</nowiki>CURRENTDAY}}</code>. Thực ra nó bung các dữ liệu bình thường đặt trong ngoặc móc.",
        "expand_templates_title": "Tên của trang văn cảnh (để phân tích {{FULLPAGENAME}} v.v.):",
-       "expand_templates_input": "Mã nguồn để bung:",
+       "expand_templates_input": "Mã wiki để bung:",
        "expand_templates_output": "Kết quả",
        "expand_templates_xml_output": "Xuất XML",
        "expand_templates_html_output": "Mã nguồn HTML thô",
        "expand_templates_preview": "Xem trước",
        "expand_templates_preview_fail_html": "<em>{{SITENAME}} cho phép mã nguồn HTML thô và dữ liệu phiên bị mất, nên bản xem trước bị ẩn để tránh tấn công JavaScript.</em>\n\n<strong>Nếu bạn thực sự muốn xem trước mã nguồn này, xin hãy thử lại nữa.</strong>\nNếu vẫn không được, hãy thử [[Special:UserLogout|đăng xuất]] rồi đăng nhập lại, và kiểm tra rằng trình duyệt của bạn cho phép các cookie của trang Web này.",
        "expand_templates_preview_fail_html_anon": "<em>{{SITENAME}} cho phép mã nguồn HTML thô và dữ liệu phiên bị mất, nên bản xem trước bị ẩn để tránh tấn công JavaScript.</em>\n\n<strong>Nếu bạn thực sự muốn xem trước mã nguồn này, xin hãy thử lại nữa.</strong>\nNếu vẫn không được, hãy [[Special:UserLogin|đăng nhập]] và thử lại lần nữa.",
-       "expand_templates_input_missing": "Bạn phải cung cấp văn bản nhập.",
+       "expand_templates_input_missing": "Bạn phải cung cấp mã wiki đầu vào.",
        "pagelanguage": "Thay đổi ngôn ngữ của trang",
        "pagelang-name": "Trang",
        "pagelang-language": "Ngôn ngữ",
        "unlinkaccounts-success": "Đã gỡ liên kết tài khoản.",
        "authenticationdatachange-ignored": "Tác vụ thay đổi dữ liệu xác thực không được xử lý. Có lẽ nhà cung cấp chưa được cấu hình?",
        "userjsispublic": "Xin lưu ý: Các trang con JavaScript không nên chứa dữ liệu bí mật, vì những người dùng khác có thể xem các trang này.",
+       "userjsonispublic": "Xin lưu ý: Các trang con JSON không nên chứa tin mật vì mọi người có thể xem trang.",
        "usercssispublic": "Xin lưu ý: Các trang con CSS không nên chứa dữ liệu bí mật, vì những người dùng khác có thể xem các trang này.",
        "restrictionsfield-badip": "Địa chỉ hoặc dải IP không hợp lệ: $1.",
        "restrictionsfield-label": "Các dải IP được cho phép:",
        "pagedata-title": "Dữ liệu về trang",
        "pagedata-text": "Trang này cung cấp giao diện dữ liệu cho các trang. Xin hãy cung cấp tên trang trong URL dùng cú pháp trang con.\n* Chế độ đàm phán nội dung được áp dụng tùy theo đầu đề Accept (chấp nhận) của trình khách của bạn. Điều này có nghĩa rằng dữ liệu trang được cung cấp dưới định dạng thích hợp nhất đối với trình khác của bạn.",
        "pagedata-not-acceptable": "Không tìm thấy định dạng phù hợp. Các kiểu MIME được hỗ trợ: $1",
-       "pagedata-bad-title": "Tiêu đề không hợp lệ: $1."
+       "pagedata-bad-title": "Tiêu đề không hợp lệ: $1.",
+       "unregistered-user-config": "Vì lý do bảo mật, các trang con JavaScript, CSS, và JSON của trang cá nhân không được tải cho những người dùng chưa đăng nhập.",
+       "passwordpolicies": "Quy định mật khẩu",
+       "passwordpolicies-summary": "Bảng này cho biết các quy định mật khẩu được áp dùng vào các nhóm người dùng được cấu hình tại wiki này.",
+       "passwordpolicies-group": "Nhóm",
+       "passwordpolicies-policies": "Quy định",
+       "passwordpolicies-policy-minimalpasswordlength": "Mật khẩu phải có ít nhất $1 ký tự",
+       "passwordpolicies-policy-minimumpasswordlengthtologin": "Mật khẩu phải có ít nhất $1 ký tự để cho bạn đăng nhập",
+       "passwordpolicies-policy-passwordcannotmatchusername": "Mật khẩu không thể khớp với tên người dùng",
+       "passwordpolicies-policy-passwordcannotmatchblacklist": "Mật khẩu không thể khớp với các mật khẩu trong danh sách đen",
+       "passwordpolicies-policy-maximalpasswordlength": "Mật khẩu không thể vượt quá $1 ký tự",
+       "passwordpolicies-policy-passwordcannotbepopular": "Mật khẩu không thể {{PLURAL:$1|là mật khẩu phổ biến nhất|xuất hiện trong danh sách $1 mật khẩu phổ biến nhất}}"
 }
index 200fc66..bbd22ed 100644 (file)
        "whatlinkshere": "װאָס פֿאַרבינדט אַהער",
        "whatlinkshere-title": "בלעטער וואס פֿארבינדן צו $1",
        "whatlinkshere-page": "בלאַט:",
-       "linkshere-2": "די פאלגנדע בלעטער פארבינדן צום בלאט '''$1''':",
-       "nolinkshere-2": "קיין שום בלאט פארבינדט נישט צו '''$1'''.",
-       "nolinkshere-ns-2": "קיין בלעטער פֿאַרבינדן נישט צו '''$1''' אינעם אויסגעקליבענעם נאמענטייל.",
+       "linkshere-2": "די פאָלגנדיקע בלעטער פאַרבינדן צום בלאַט '''$1''':",
+       "nolinkshere-2": "קיין שום בלאַט פאַרבינדט נישט צו '''$1'''.",
+       "nolinkshere-ns-2": "קיין בלעטער פאַרבינדן נישט צו '''$1''' אינעם אויסגעקליבענעם נאָמענטייל.",
        "isredirect": "ווײַטערפירן בלאט",
        "istemplate": "אײַנשליסן",
        "isimage": "!טעקע לינק",
index ff98909..243da62 100644 (file)
@@ -34,7 +34,8 @@
                        "Deryck Chan",
                        "Hello903hello",
                        "Fitoschido",
-                       "Kanashimi"
+                       "Kanashimi",
+                       "Roy17"
                ]
        },
        "tog-underline": "連結加底線:",
        "cascadeprotected": "呢一版已經保護咗唔能夠編輯,因為佢係響以下嘅{{PLURAL:$1|一|幾}}頁度包含咗,當中啟用咗\"連串\"保護選項來保護嗰一版: $2",
        "namespaceprotected": "你無權編輯響'''$1'''空間名裏面嘅呢一版。",
        "customcssprotected": "你無權改呢版CSS,因為佢包含其他用戶嘅個人設定。",
+       "customjsonprotected": "你無權改呢版JSON,因為佢包含其他用戶嘅個人設定。",
        "customjsprotected": "你無權改呢版JavaScript,因為佢包含其他用戶嘅個人設定。",
        "mycustomcssprotected": "你無權改呢版CSS。",
+       "mycustomjsonprotected": "你無權改呢版JSON。",
        "mycustomjsprotected": "你無權改呢版JavaScript。",
        "myprivateinfoprotected": "你無權改呢版你嘅私人資料。",
        "mypreferencesprotected": "你無權改呢版你嘅個人設定。",
        "botpasswords-deleted-body": "{{GENDER:$2|用戶}}「$2」嘅機械人「$1」嘅密碼已經剷走咗。",
        "botpasswords-restriction-failed": "機械人密碼限制令到呢次簽到失敗。",
        "botpasswords-invalid-name": "呢個用戶名無機械人密碼分隔字(「$1」)",
+       "botpasswords-not-exist": "用戶「$1」無叫做「$2」嘅機械人密碼。",
+       "botpasswords-needs-reset": "{{GENDER:$1|用戶}}「$1」嘅機械人「$2」嘅密碼一定要重新改。",
        "resetpass_forbidden": "唔可以更改密碼",
        "resetpass_forbidden-reason": "改唔到密碼:$1",
        "resetpass-no-info": "你一定要登入咗去直接入來呢一版。",
        "subject-preview": "主題預覽:",
        "previewerrortext": "預覽你嘅修改嗰陣出錯。",
        "blockedtitle": "用戶已經封鎖",
-       "blockedtext": "你嘅用戶名或者 IP 位址已經被 $1 封咗。\n\n呢次封鎖係由$1所封嘅。當中嘅原因係''$2''。\n\n* 呢次封鎖嘅開始時間係:$8\n* 呢次封鎖嘅到期時間係:$6\n* 對於被封鎖者:$7\n\n你可以聯絡 $1 或者其他嘅[[{{MediaWiki:Grouppage-sysop}}|管理員]],討論呢次封鎖。\n除非你已經響你嘅[[Special:Preferences|戶口喜好設定]]入面設定咗有效嘅電郵地址,否則你係唔可以用「電郵呢個用戶」嘅功能。當設定咗一個有效嘅電郵地址之後,呢個功能係唔會封鎖嘅。\n\n你現時嘅 IP 位址係 $3 ,而個封鎖 ID 係 #$5。 請你喺你嘅查詢都註明以上封鎖嘅資料。",
+       "blockedtext": "<strong>你嘅用戶名或者IP地址已經俾人封咗。</strong>\n\n呢次封鎖係由$1所封嘅。\n俾咗嘅原因係<em>$2</em>。\n\n* 呢次封鎖嘅開始時間係:$8\n* 呢次封鎖嘅到期時間係:$6\n* 被封鎖者:$7\n\n你可以聯絡 $1 或者其他嘅[[{{MediaWiki:Grouppage-sysop}}|管理員]]討論呢次封鎖。\n除非你已經響你嘅[[Special:Preferences|戶口喜好設定]]入面設定咗有效嘅電郵地址,否則你係唔可以用「{{int:emailuser}}」嘅功能。當設定咗一個有效嘅電郵地址之後,呢個功能係唔會被封鎖嘅。\n你現時嘅IP地址係 $3 ,而個封鎖ID係 #$5。\n請喺你嘅查詢都註明以上封鎖嘅資料。",
        "autoblockedtext": "你嘅IP地址已經被自動封鎖,由於之前嘅另一位用戶係畀$1封咗。\n而封鎖嘅原因係:\n\n:''$2''\n\n* 呢次封鎖嘅開始時間係:$8\n* 呢次封鎖嘅到期時間係:$6\n* 對於被封鎖者:$7\n\n你可以聯絡 $1 或者其他嘅[[{{MediaWiki:Grouppage-sysop}}|管理員]],討論呢次封鎖。\n\n除非你已經響你嘅[[Special:Preferences|戶口喜好設定]]入面設定咗有效嘅電郵地址,否則你係唔可以用「電郵呢個用戶」嘅功能。當設定咗一個有效嘅電郵地址之後,呢個功能係唔會封鎖嘅。\n\n你現時用緊嘅 IP 地址係 $3,個封鎖 ID 係 #$5。 請喺你嘅查詢都註明呢個封鎖上面嘅資料。",
        "systemblockedtext": "你嘅用戶名或者IP地址已經俾MediaWiki自動封鎖。\n封鎖原因係:\n\n:<em>$2</em>\n\n* 開始時間:$8\n* 到期時間:$6\n* 目標用戶:$7\n\n你而家嘅IP地址係$3。\n當你作出任何查詢嘅時候,請包含以上所有資料。",
        "blockednoreason": "無原因畀低",
        "post-expand-template-argument-warning": "警告: 呢一版有最少一個模參數有太大嘅擴展大細。\n呢啲參數會被略過。",
        "post-expand-template-argument-category": "包含住略過模參數嘅版",
        "parser-template-loop-warning": "已偵測迴模: [[$1]]",
+       "template-loop-category": "有循環模嘅頁",
        "parser-template-recursion-depth-warning": "迴模深度限制超過咗 ($1)",
        "language-converter-depth-warning": "字體變換器深度限制超過咗 ($1)",
        "node-count-exceeded-category": "有頁面超出咗指定數",
        "prefs-dateformat": "日期格式",
        "prefs-timeoffset": "時間偏移",
        "prefs-advancedediting": "普通選項",
+       "prefs-developertools": "開發者工具",
        "prefs-editor": "編輯",
        "prefs-preview": "預覽",
        "prefs-advancedrc": "進階選項",
        "right-editcontentmodel": "改版面嘅內容模型",
        "right-editinterface": "編輯用戶界面",
        "right-editusercss": "編輯其他用戶嘅CSS檔",
+       "right-edituserjson": "編輯其他用戶嘅JSON檔",
        "right-edituserjs": "編輯其他用戶嘅JavaScript檔",
-       "right-editmyusercss": "編輯戶口嘅CSS文件",
-       "right-editmyuserjs": "編輯戶口嘅JavaScript文件",
+       "right-editmyusercss": "編輯你自己嘅用戶CSS檔",
+       "right-editmyuserjson": "編輯你自己嘅用戶JSON檔",
+       "right-editmyuserjs": "編輯你自己嘅用戶JavaScript檔",
        "right-viewmywatchlist": "睇你自己嘅監視一覽",
        "right-viewmyprivateinfo": "睇下個人信息(例如電郵或真名)",
        "right-editmyprivateinfo": "修改個人信息(例如電郵或真名)",
        "right-sendemail": "寄電郵畀其他用戶",
        "right-managechangetags": "開同(取消)啟用[[Special:Tags|標籤]]",
        "right-applychangetags": "套用[[Special:Tags|標籤]]到某個人嘅改動",
+       "right-deletechangetags": "由資料庫刪[[Special:Tags|標籤]]",
+       "grant-generic": "「$1」權限組合",
        "grant-group-page-interaction": "同版面互動",
        "grant-group-file-interaction": "同傳媒互動",
        "grant-group-watchlist-interaction": "同監視清單互動",
        "grant-group-email": "送電郵",
+       "grant-group-high-volume": "執行大量活動",
        "grant-group-customization": "自訂同設定",
        "grant-group-administration": "做管理行動",
        "grant-group-private-information": "存取你嘅私隱資料",
        "grant-editmywatchlist": "改你嘅監視清單",
        "grant-editpage": "改已經有嘅版",
        "grant-editprotected": "改保護咗嘅版",
+       "grant-highvolume": "大量編輯",
+       "grant-oversight": "收埋用戶同禁止顯示修訂",
+       "grant-sendemail": "寄電郵畀其他用戶",
        "grant-uploadfile": "上載新檔案",
        "grant-basic": "基本權利",
+       "grant-viewdeleted": "睇刪咗嘅檔同頁",
        "grant-viewmywatchlist": "睇你嘅監視清單",
        "newuserlogpage": "使用者開戶記錄",
        "newuserlogpagetext": "呢個係一個使用者開戶嘅日誌",
        "action-editcontentmodel": "改頁面內容模型",
        "action-managechangetags": "從數據庫開或刪走啲符",
        "action-applychangetags": "套用標籤到你嘅改動",
+       "action-purge": "清呢版個快取版本",
        "nchanges": "$1次更改",
        "enhancedrc-since-last-visit": "{{PLURAL:$1|你上次嚟之後}}有 $1 個",
        "enhancedrc-history": "歷史",
        "exif-ycbcrpositioning-1": "置中",
        "exif-dc-contributor": "貢獻者",
        "exif-dc-date": "日子",
-       "exif-dc-publisher": "發者",
+       "exif-dc-publisher": "發者",
        "exif-dc-rights": "權",
        "exif-rating-rejected": "拒絕咗",
        "exif-isospeedratings-overflow": "超出咗65535嘅限制",
        "watchlistedit-normal-legend": "響監視清單度拎走",
        "watchlistedit-normal-explain": "響你張監視清單度嘅標題響下面度顯示。要拎走一個標題,響佢前面剔一剔,跟住要撳『{{int:Watchlistedit-normal-submit}}』。你亦都可以[[Special:EditWatchlist/raw|編輯原始清單]]。",
        "watchlistedit-normal-submit": "拎走標題",
-       "watchlistedit-normal-done": "$1個標題已經響你嘅監視清單度拎走咗:",
+       "watchlistedit-normal-done": "響你嘅監視清單,拎走咗$1個標題:",
        "watchlistedit-raw-title": "編輯原始監視清單",
        "watchlistedit-raw-legend": "編輯原始監視清單",
        "watchlistedit-raw-explain": "你張監視清單嘅標題響下面度顯示,同時亦都可以透過編輯呢個表去加入同埋拎走標題;一行一個標題。當完成咗之後,撳{{int:Watchlistedit-raw-submit}}。你亦都可以去用[[Special:EditWatchlist|標準編輯器]]。",
        "authmanager-email-help": "電郵地址",
        "authmanager-realname-label": "真名",
        "authmanager-realname-help": "用戶嘅真名",
-       "authprovider-resetpass-skip-label": "跳過"
+       "authprovider-resetpass-skip-label": "跳過",
+       "passwordpolicies": "密碼政策",
+       "passwordpolicies-summary": "爾度係對爾個wiki定義咗嘅用戶組來講有效嘅密碼政策一覽。",
+       "passwordpolicies-group": "組",
+       "passwordpolicies-policies": "政策",
+       "passwordpolicies-policy-minimalpasswordlength": "密碼一定要有至少$1個{{PLURAL:$1|字元}}長",
+       "passwordpolicies-policy-minimumpasswordlengthtologin": "密碼一定要有至少$1個{{PLURAL:$1|字元}}長先可以簽到",
+       "passwordpolicies-policy-passwordcannotmatchusername": "密碼唔可以同用戶名一樣",
+       "passwordpolicies-policy-passwordcannotmatchblacklist": "密碼唔可以同列入咗黑名單嘅密碼一樣",
+       "passwordpolicies-policy-maximalpasswordlength": "密碼一定要短過$1個{{PLURAL:$1|字元}}長",
+       "passwordpolicies-policy-passwordcannotbepopular": "密碼唔可以{{PLURAL:$1|係最常見嘅密碼|喺最常見嘅$1個密碼一覽度}}"
 }
index ea0ce8e..5faa030 100644 (file)
@@ -98,7 +98,8 @@
                        "Sanmosa",
                        "Dongzn",
                        "Shangkuanlc",
-                       "Kanashimi"
+                       "Kanashimi",
+                       "Hello903hello"
                ]
        },
        "tog-underline": "底線標示連結:",
        "watchthis": "監視此頁面",
        "savearticle": "儲存頁面",
        "savechanges": "儲存變更",
-       "publishpage": "發頁面",
-       "publishchanges": "發變更",
+       "publishpage": "發頁面",
+       "publishchanges": "發變更",
        "savearticle-start": "儲存頁面…",
        "savechanges-start": "儲存變更…",
-       "publishpage-start": "發頁面…",
-       "publishchanges-start": "發變更…",
+       "publishpage-start": "發頁面…",
+       "publishchanges-start": "發變更…",
        "preview": "預覽",
        "showpreview": "顯示預覽",
        "showdiff": "顯示變更",
        "ipboptions": "2 小時:2 hours,1 天:1 day,3 天:3 days,1 週:1 week,2 週:2 weeks,1 個月:1 month,3 個月:3 months,6 個月:6 months,1 年:1 year,無限期:infinite",
        "ipbhidename": "在編輯及清單中隱藏使用者名稱",
        "ipbwatchuser": "監視這位使用者的使用者頁面及其對話頁面",
-       "ipb-disableusertalk": "阻止此使用者在封鎖期間編輯自己的對話頁面",
+       "ipb-disableusertalk": "禁止使用者在封鎖期間編輯自己的對話頁面",
        "ipb-change-block": "使用現有設定重新封鎖使用者",
        "ipb-confirm": "確認封鎖",
        "badipaddress": "無效的 IP 位址",
        "exif-iimcategory": "分類",
        "exif-iimsupplementalcategory": "補充分類",
        "exif-datetimeexpires": "於此日期後請勿使用",
-       "exif-datetimereleased": "發於",
+       "exif-datetimereleased": "發於",
        "exif-originaltransmissionref": "原始傳輸位置代碼",
        "exif-identifier": "識別碼",
        "exif-lens": "使用鏡頭",
index 5b441f9..234e1b1 100644 (file)
@@ -38,6 +38,7 @@ class TitleCleanup extends TableCleanup {
        public function __construct() {
                parent::__construct();
                $this->addDescription( 'Script to clean up broken, unparseable titles' );
+               $this->batchSize = 1000;
        }
 
        /**
index b8b2b8e..af47d65 100644 (file)
@@ -35,7 +35,7 @@ class GenerateNormalizerDataAr extends Maintenance {
                parent::__construct();
                $this->addDescription( 'Generate the normalizer data file for Arabic' );
                $this->addOption( 'unicode-data-file', 'The local location of the data file ' .
-                       'from https://unicode.org/Public/UNIDATA/UnicodeData.txt', false, true );
+                       'from https://unicode.org/Public/6.0.0/ucd/UnicodeData.txt', false, true );
        }
 
        public function getDbType() {
@@ -122,7 +122,11 @@ class GenerateNormalizerDataAr extends Maintenance {
                }
 
                global $IP;
-               file_put_contents( "$IP/serialized/normalize-ar.ser", serialize( $pairs ) );
+               file_put_contents( "$IP/languages/data/normalize-ar.php", wfMakeStaticArrayFile(
+                       $pairs,
+                       'File created by generateNormalizerDataAr.php'
+               ) );
+
                echo "ar: " . count( $pairs ) . " pairs written.\n";
        }
 }
index 0bb491f..5b75d8b 100644 (file)
@@ -61,7 +61,11 @@ class GenerateNormalizerDataMl extends Maintenance {
                }
 
                global $IP;
-               file_put_contents( "$IP/serialized/normalize-ml.ser", serialize( $pairs ) );
+               file_put_contents( "$IP/languages/data/normalize-ml.php", wfMakeStaticArrayFile(
+                       $pairs,
+                       'File created by generateNormalizerDataMl.php'
+               ) );
+
                echo "ml: " . count( $pairs ) . " pairs written.\n";
        }
 }
index 4e0a452..b32bbcd 100644 (file)
@@ -115,6 +115,10 @@ return [
        'jquery.makeCollapsible.styles' => [
                'targets' => [ 'desktop', 'mobile' ],
                'class' => ResourceLoaderLessVarFileModule::class,
+               'lessMessages' => [
+                       'collapsible-collapse',
+                       'collapsible-expand',
+               ],
                'styles' => [
                        'resources/src/jquery/jquery.makeCollapsible.styles.less',
                ],
@@ -852,6 +856,7 @@ return [
                        'resources/src/mediawiki/mediawiki.js',
                        'resources/src/mediawiki/mediawiki.requestIdleCallback.js',
                        'resources/src/mediawiki/mediawiki.errorLogger.js',
+                       'resources/src/mediawiki/mediawiki.base.js',
                ],
                'debugScripts' => 'resources/src/mediawiki/mediawiki.log.js',
                'targets' => [ 'desktop', 'mobile' ],
index 2738d1a..186ad17 100644 (file)
                        // we can trim the previous one).
                        // See https://www.w3.org/TR/DOM-Level-3-Events/#events-keyboard-event-order for
                        // the order and characteristics of the key events.
-                       $el.on( eventKeys, function () {
+
+                       function enforceLimit() {
                                var res = trimFn(
                                        prevSafeVal,
                                        this.value,
                                // trimFn to compare the new value to an empty string instead of the
                                // old value, resulting in trimming always from the end (T42850).
                                prevSafeVal = res.newVal;
+                       }
+
+                       $el.on( eventKeys, function ( e ) {
+                               if ( e.type === 'cut' || e.type === 'paste' ) {
+                                       // For 'cut'/'paste', the input value is only updated after the event handlers resolve.
+                                       setTimeout( enforceLimit.bind( this ) );
+                               } else {
+                                       enforceLimit.call( this );
+                               }
                        } );
                } );
        }
index 7f12835..7467d50 100644 (file)
@@ -50,8 +50,6 @@
  * @class mw.Uri
  */
 
-/* eslint-disable no-use-before-define */
-
 ( function ( mw, $ ) {
        var parser, properties;
 
                                        return uri;
                                }
                                href = hrefCur;
+                               // eslint-disable-next-line no-use-before-define
                                uri = new Uri( href );
                                return uri;
                        };
index 5ae91e8..1be0052 100644 (file)
@@ -1,7 +1,7 @@
 /*!
  * Scripts for pre-emptive edit preparing on action=edit
  */
-/* eslint-disable no-use-before-define */
+
 ( function ( mw, $ ) {
        if ( !mw.config.get( 'wgAjaxEditStash' ) ) {
                return;
                        return;
                }
 
+               // Whether the body text content changed since the last stashEdit()
+               function isTextChanged() {
+                       return lastText !== $text.textSelection( 'getContents' );
+               }
+
+               // Whether the edit summary has changed since the last stashEdit()
+               function isSummaryChanged() {
+                       return lastSummary !== $summary.textSelection( 'getContents' );
+               }
+
                // Send a request to stash the edit to the API.
                // If a request is in progress, abort it since its payload is stale and the API
                // may limit concurrent stash parses.
@@ -43,6 +53,7 @@
                        if ( stashReq ) {
                                if ( lastPriority > priority ) {
                                        // Stash request for summary change should wait on pending text change stash
+                                       // eslint-disable-next-line no-use-before-define
                                        stashReq.then( checkStash );
                                        return;
                                }
                        } );
                }
 
-               // Whether the body text content changed since the last stashEdit()
-               function isTextChanged() {
-                       return lastText !== $text.textSelection( 'getContents' );
-               }
-
-               // Whether the edit summary has changed since the last stashEdit()
-               function isSummaryChanged() {
-                       return lastSummary !== $summary.textSelection( 'getContents' );
-               }
-
                // Check whether text or summary have changed and call stashEdit()
                function checkStash() {
                        if ( !isTextChanged() && !isSummaryChanged() ) {
index db81ff2..1367426 100644 (file)
@@ -60,7 +60,6 @@
 
        // Use buttonElement to include ButtonInputWidget and ButtonWidget
        .editButtons .oo-ui-buttonElement,
-       .cancelLink,
        .editHelp {
                margin-top: 0.5em;
        }
index 61a1c9c..0b56df1 100644 (file)
@@ -6,6 +6,8 @@
 
 @ooui-spacing-medium: 12 / @ooui-font-size-browser / @ooui-font-size-base; // equals `0.8571429em`≈`12px`
 @ooui-spacing-large: 16 / @ooui-font-size-browser / @ooui-font-size-base; // equals `1.1428571em`≈`16px`
+@ooui-padding-horizontal: 12 / @ooui-font-size-browser / @ooui-font-size-base;
+@ooui-padding-vertical: 4 / @ooui-font-size-browser / @ooui-font-size-base; // equals `0.285714em`≈`4px`
 
 .mw-htmlform-ooui-wrapper.oo-ui-panelLayout-padded {
        padding: @ooui-spacing-medium @ooui-spacing-large @ooui-spacing-large;
        }
 
        .mw-htmlform-matrix {
-               border-spacing: 0;
+               border-spacing: 0 2px;
 
                td {
-                       padding: 0.35em 0.7em;
+                       padding: @ooui-padding-vertical @ooui-padding-horizontal;
+                       text-align: center;
                        .transition( background-color 250ms );
+
+                       &:first-child {
+                               text-align: left;
+                       }
                }
 
                tbody tr:nth-child( even ) td {
@@ -40,6 +47,7 @@
 
                tbody tr:first-child td {
                        background-color: #fff;
+                       padding-bottom: 0;
                }
 
                td.first {
index 53dccc2..55be237 100644 (file)
@@ -1,6 +1,6 @@
 // Common Less mixin library for MediaWiki
 //
-// By default the folder containing this file is included in $wgResourceLoaderLESSImportPaths,
+// By default the folder containing this file is included in the LESS import paths,
 // which makes this file importable by all less files via `@import 'mediawiki.mixins';`.
 //
 // The mixins included below are considered a public interface for MediaWiki extensions.
index 06c34a5..1823ef0 100644 (file)
@@ -2,8 +2,6 @@
  * Implement AJAX navigation for multi-page images so the user may browse without a full page reload.
  */
 
-/* eslint-disable no-use-before-define */
-
 ( function ( mw, $ ) {
        var jqXhr, $multipageimage, $spinner,
                cache = {},
@@ -86,6 +84,7 @@
                        // Replace table contents
                        $multipageimage.empty().append( $contents.clone() );
 
+                       // eslint-disable-next-line no-use-before-define
                        bindPageNavigation( $multipageimage );
 
                        // Fire hook because the page's content has changed
diff --git a/resources/src/mediawiki/mediawiki.base.js b/resources/src/mediawiki/mediawiki.base.js
new file mode 100644 (file)
index 0000000..b68d779
--- /dev/null
@@ -0,0 +1,34 @@
+/*!
+ * This file is currently loaded as part of the 'mediawiki' module and therefore
+ * concatenated to mediawiki.js and executed at the same time. This file exists
+ * to help prepare for splitting up the 'mediawiki' module.
+ * This effort is tracked at https://phabricator.wikimedia.org/T192623
+ *
+ * In short:
+ *
+ * - mediawiki.js will be reduced to the minimum needed to define mw.loader and
+ *   mw.config, and then moved to its own private "mediawiki.loader" module that
+ *   can be embedded within the StartupModule response.
+ *
+ * - mediawiki.base.js and other files in this directory will remain part of the
+ *   "mediawiki" module, and will remain a default/implicit dependency for all
+ *   regular modules, just like jquery and wikibits already are.
+ */
+/* globals mw */
+( function () {
+       /**
+        * @class mw
+        * @singleton
+        */
+
+       /**
+        * @inheritdoc mw.inspect#runReports
+        * @method
+        */
+       mw.inspect = function () {
+               var args = arguments;
+               mw.loader.using( 'mediawiki.inspect', function () {
+                       mw.inspect.runReports.apply( mw.inspect, args );
+               } );
+       };
+}() );
index 702c18d..a2af443 100644 (file)
@@ -9,7 +9,6 @@
  */
 
 /* global mwNow */
-/* eslint-disable no-use-before-define */
 
 ( function ( $ ) {
        'use strict';
                }() );
        }
 
+       /**
+        * Alias property to the global object.
+        *
+        * @private
+        * @static
+        * @member mw.Map
+        * @param {mw.Map} map
+        * @param {string} key
+        * @param {Mixed} value
+        */
+       function setGlobalMapValue( map, key, value ) {
+               map.values[ key ] = value;
+               log.deprecate(
+                       window,
+                       key,
+                       value,
+                       // Deprecation notice for mw.config globals (T58550, T72470)
+                       map === mw.config && 'Use mw.config instead.'
+               );
+       }
+
        /**
         * Create an object that can be read from or written to via methods that allow
         * interaction both with single and multiple properties at once.
                }
        }
 
-       /**
-        * Alias property to the global object.
-        *
-        * @private
-        * @static
-        * @param {mw.Map} map
-        * @param {string} key
-        * @param {Mixed} value
-        */
-       function setGlobalMapValue( map, key, value ) {
-               map.values[ key ] = value;
-               log.deprecate(
-                       window,
-                       key,
-                       value,
-                       // Deprecation notice for mw.config globals (T58550, T72470)
-                       map === mw.config && 'Use mw.config instead.'
-               );
-       }
-
        Map.prototype = {
                constructor: Map,
 
                                        mw.loader.store.set( module, registry[ module ] );
                                        for ( m in registry ) {
                                                if ( registry[ m ].state === 'loaded' && allReady( registry[ m ].dependencies ) ) {
+                                                       // eslint-disable-next-line no-use-before-define
                                                        execute( m );
                                                }
                                        }
                                }
                        }
 
+                       /**
+                        * @private
+                        * @param {Object} params Map of parameter names to values
+                        * @return {string}
+                        */
+                       function makeQueryString( params ) {
+                               return Object.keys( params ).map( function ( key ) {
+                                       return encodeURIComponent( key ) + '=' + encodeURIComponent( params[ key ] );
+                               } ).join( '&' );
+                       }
+
                        /**
                         * Create network requests for a batch of modules.
                         *
                                        // combining versions from the module query string in-order. (T188076)
                                        query.version = getCombinedVersion( packed.list );
                                        query = sortQuery( query );
-                                       addScript( sourceLoadScript + '?' + $.param( query ) );
+                                       addScript( sourceLoadScript + '?' + makeQueryString( query ) );
                                }
 
                                if ( !batch.length ) {
                                                // > '&modules='.length === 9
                                                // > '&version=1234567'.length === 16
                                                // > 9 + 16 = 25
-                                               currReqBaseLength = $.param( currReqBase ).length + 25;
+                                               currReqBaseLength = makeQueryString( currReqBase ).length + 25;
 
                                                // We may need to split up the request to honor the query string length limit,
                                                // so build it piece by piece.
                                        return registry[ moduleName ].module.exports;
                                },
 
-                               /**
-                                * @inheritdoc mw.inspect#runReports
-                                * @method
-                                */
-                               inspect: function () {
-                                       var args = slice.call( arguments );
-                                       mw.loader.using( 'mediawiki.inspect', function () {
-                                               mw.inspect.runReports.apply( mw.inspect, args );
-                                       } );
-                               },
-
                                /**
                                 * On browsers that implement the localStorage API, the module store serves as a
                                 * smart complement to the browser cache. Unlike the browser cache, the module store
index d9d58dd..33b9f02 100644 (file)
@@ -1,4 +1,3 @@
-/UnicodeData.txt
 /allkeys.txt
 /ucd.all.grouped.xml
 /ucd.all.grouped.zip
index 0a04d85..09369ef 100644 (file)
@@ -1,4 +1,4 @@
-SPECIAL_TARGETS=normalize-ar.ser normalize-ml.ser first-letters-root.ser
+SPECIAL_TARGETS=first-letters-root.ser
 ALL_TARGETS=$(SPECIAL_TARGETS)
 DIST_TARGETS=$(SPECIAL_TARGETS)
 UNICODE_VERSION=6.0.0
@@ -13,18 +13,9 @@ dist: $(DIST_TARGETS)
 clean:
        rm -f $(ALL_TARGETS)
 
-normalize-ar.ser: UnicodeData.txt
-       php ../maintenance/language/generateNormalizerDataAr.php
-
-normalize-ml.ser:
-       php ../maintenance/language/generateNormalizerDataMl.php
-
 first-letters-root.ser: allkeys.txt ucd.all.grouped.xml
        php ../maintenance/language/generateCollationData.php
 
-UnicodeData.txt:
-       wget https://www.unicode.org/Public/$(UNICODE_VERSION)/ucd/UnicodeData.txt
-
 allkeys.txt:
        wget https://www.unicode.org/Public/UCA/$(UNICODE_VERSION)/allkeys.txt
 
diff --git a/serialized/normalize-ar.ser b/serialized/normalize-ar.ser
deleted file mode 100644 (file)
index 2a7f122..0000000
+++ /dev/null
@@ -1 +0,0 @@
-a:731:{s:3:"ﭐ";s:2:"ٱ";s:3:"ﭑ";s:2:"ٱ";s:3:"ﭒ";s:2:"ٻ";s:3:"ﭓ";s:2:"ٻ";s:3:"ﭔ";s:2:"ٻ";s:3:"ﭕ";s:2:"ٻ";s:3:"ﭖ";s:2:"پ";s:3:"ﭗ";s:2:"پ";s:3:"ﭘ";s:2:"پ";s:3:"ﭙ";s:2:"پ";s:3:"ﭚ";s:2:"ڀ";s:3:"ﭛ";s:2:"ڀ";s:3:"ﭜ";s:2:"ڀ";s:3:"ﭝ";s:2:"ڀ";s:3:"ﭞ";s:2:"ٺ";s:3:"ﭟ";s:2:"ٺ";s:3:"ﭠ";s:2:"ٺ";s:3:"ﭡ";s:2:"ٺ";s:3:"ﭢ";s:2:"ٿ";s:3:"ﭣ";s:2:"ٿ";s:3:"ﭤ";s:2:"ٿ";s:3:"ﭥ";s:2:"ٿ";s:3:"ﭦ";s:2:"ٹ";s:3:"ﭧ";s:2:"ٹ";s:3:"ﭨ";s:2:"ٹ";s:3:"ﭩ";s:2:"ٹ";s:3:"ﭪ";s:2:"ڤ";s:3:"ﭫ";s:2:"ڤ";s:3:"ﭬ";s:2:"ڤ";s:3:"ﭭ";s:2:"ڤ";s:3:"ﭮ";s:2:"ڦ";s:3:"ﭯ";s:2:"ڦ";s:3:"ﭰ";s:2:"ڦ";s:3:"ﭱ";s:2:"ڦ";s:3:"ﭲ";s:2:"ڄ";s:3:"ﭳ";s:2:"ڄ";s:3:"ﭴ";s:2:"ڄ";s:3:"ﭵ";s:2:"ڄ";s:3:"ﭶ";s:2:"ڃ";s:3:"ﭷ";s:2:"ڃ";s:3:"ﭸ";s:2:"ڃ";s:3:"ﭹ";s:2:"ڃ";s:3:"ﭺ";s:2:"چ";s:3:"ﭻ";s:2:"چ";s:3:"ﭼ";s:2:"چ";s:3:"ﭽ";s:2:"چ";s:3:"ﭾ";s:2:"ڇ";s:3:"ﭿ";s:2:"ڇ";s:3:"ﮀ";s:2:"ڇ";s:3:"ﮁ";s:2:"ڇ";s:3:"ﮂ";s:2:"ڍ";s:3:"ﮃ";s:2:"ڍ";s:3:"ﮄ";s:2:"ڌ";s:3:"ﮅ";s:2:"ڌ";s:3:"ﮆ";s:2:"ڎ";s:3:"ﮇ";s:2:"ڎ";s:3:"ﮈ";s:2:"ڈ";s:3:"ﮉ";s:2:"ڈ";s:3:"ﮊ";s:2:"ژ";s:3:"ﮋ";s:2:"ژ";s:3:"ﮌ";s:2:"ڑ";s:3:"ﮍ";s:2:"ڑ";s:3:"ﮎ";s:2:"ک";s:3:"ﮏ";s:2:"ک";s:3:"ﮐ";s:2:"ک";s:3:"ﮑ";s:2:"ک";s:3:"ﮒ";s:2:"گ";s:3:"ﮓ";s:2:"گ";s:3:"ﮔ";s:2:"گ";s:3:"ﮕ";s:2:"گ";s:3:"ﮖ";s:2:"ڳ";s:3:"ﮗ";s:2:"ڳ";s:3:"ﮘ";s:2:"ڳ";s:3:"ﮙ";s:2:"ڳ";s:3:"ﮚ";s:2:"ڱ";s:3:"ﮛ";s:2:"ڱ";s:3:"ﮜ";s:2:"ڱ";s:3:"ﮝ";s:2:"ڱ";s:3:"ﮞ";s:2:"ں";s:3:"ﮟ";s:2:"ں";s:3:"ﮠ";s:2:"ڻ";s:3:"ﮡ";s:2:"ڻ";s:3:"ﮢ";s:2:"ڻ";s:3:"ﮣ";s:2:"ڻ";s:3:"ﮤ";s:2:"ۀ";s:3:"ﮥ";s:2:"ۀ";s:3:"ﮦ";s:2:"ہ";s:3:"ﮧ";s:2:"ہ";s:3:"ﮨ";s:2:"ہ";s:3:"ﮩ";s:2:"ہ";s:3:"ﮪ";s:2:"ھ";s:3:"ﮫ";s:2:"ھ";s:3:"ﮬ";s:2:"ھ";s:3:"ﮭ";s:2:"ھ";s:3:"ﮮ";s:2:"ے";s:3:"ﮯ";s:2:"ے";s:3:"ﮰ";s:2:"ۓ";s:3:"ﮱ";s:2:"ۓ";s:3:"ﯓ";s:2:"ڭ";s:3:"ﯔ";s:2:"ڭ";s:3:"ﯕ";s:2:"ڭ";s:3:"ﯖ";s:2:"ڭ";s:3:"ﯗ";s:2:"ۇ";s:3:"ﯘ";s:2:"ۇ";s:3:"ﯙ";s:2:"ۆ";s:3:"ﯚ";s:2:"ۆ";s:3:"ﯛ";s:2:"ۈ";s:3:"ﯜ";s:2:"ۈ";s:3:"ﯝ";s:2:"ٷ";s:3:"ﯞ";s:2:"ۋ";s:3:"ﯟ";s:2:"ۋ";s:3:"ﯠ";s:2:"ۅ";s:3:"ﯡ";s:2:"ۅ";s:3:"ﯢ";s:2:"ۉ";s:3:"ﯣ";s:2:"ۉ";s:3:"ﯤ";s:2:"ې";s:3:"ﯥ";s:2:"ې";s:3:"ﯦ";s:2:"ې";s:3:"ﯧ";s:2:"ې";s:3:"ﯨ";s:2:"ى";s:3:"ﯩ";s:2:"ى";s:3:"ﯪ";s:4:"ئا";s:3:"ﯫ";s:4:"ئا";s:3:"ﯬ";s:4:"ئە";s:3:"ﯭ";s:4:"ئە";s:3:"ﯮ";s:4:"ئو";s:3:"ﯯ";s:4:"ئو";s:3:"ﯰ";s:4:"ئۇ";s:3:"ﯱ";s:4:"ئۇ";s:3:"ﯲ";s:4:"ئۆ";s:3:"ﯳ";s:4:"ئۆ";s:3:"ﯴ";s:4:"ئۈ";s:3:"ﯵ";s:4:"ئۈ";s:3:"ﯶ";s:4:"ئې";s:3:"ﯷ";s:4:"ئې";s:3:"ﯸ";s:4:"ئې";s:3:"ﯹ";s:4:"ئى";s:3:"ﯺ";s:4:"ئى";s:3:"ﯻ";s:4:"ئى";s:3:"ﯼ";s:2:"ی";s:3:"ﯽ";s:2:"ی";s:3:"ﯾ";s:2:"ی";s:3:"ﯿ";s:2:"ی";s:3:"ﰀ";s:4:"ئج";s:3:"ﰁ";s:4:"ئح";s:3:"ﰂ";s:4:"ئم";s:3:"ﰃ";s:4:"ئى";s:3:"ﰄ";s:4:"ئي";s:3:"ﰅ";s:4:"بج";s:3:"ﰆ";s:4:"بح";s:3:"ﰇ";s:4:"بخ";s:3:"ﰈ";s:4:"بم";s:3:"ﰉ";s:4:"بى";s:3:"ﰊ";s:4:"بي";s:3:"ﰋ";s:4:"تج";s:3:"ﰌ";s:4:"تح";s:3:"ﰍ";s:4:"تخ";s:3:"ﰎ";s:4:"تم";s:3:"ﰏ";s:4:"تى";s:3:"ﰐ";s:4:"تي";s:3:"ﰑ";s:4:"ثج";s:3:"ﰒ";s:4:"ثم";s:3:"ﰓ";s:4:"ثى";s:3:"ﰔ";s:4:"ثي";s:3:"ﰕ";s:4:"جح";s:3:"ﰖ";s:4:"جم";s:3:"ﰗ";s:4:"حج";s:3:"ﰘ";s:4:"حم";s:3:"ﰙ";s:4:"خج";s:3:"ﰚ";s:4:"خح";s:3:"ﰛ";s:4:"خم";s:3:"ﰜ";s:4:"سج";s:3:"ﰝ";s:4:"سح";s:3:"ﰞ";s:4:"سخ";s:3:"ﰟ";s:4:"سم";s:3:"ﰠ";s:4:"صح";s:3:"ﰡ";s:4:"صم";s:3:"ﰢ";s:4:"ضج";s:3:"ﰣ";s:4:"ضح";s:3:"ﰤ";s:4:"ضخ";s:3:"ﰥ";s:4:"ضم";s:3:"ﰦ";s:4:"طح";s:3:"ﰧ";s:4:"طم";s:3:"ﰨ";s:4:"ظم";s:3:"ﰩ";s:4:"عج";s:3:"ﰪ";s:4:"عم";s:3:"ﰫ";s:4:"غج";s:3:"ﰬ";s:4:"غم";s:3:"ﰭ";s:4:"فج";s:3:"ﰮ";s:4:"فح";s:3:"ﰯ";s:4:"فخ";s:3:"ﰰ";s:4:"فم";s:3:"ﰱ";s:4:"فى";s:3:"ﰲ";s:4:"في";s:3:"ﰳ";s:4:"قح";s:3:"ﰴ";s:4:"قم";s:3:"ﰵ";s:4:"قى";s:3:"ﰶ";s:4:"قي";s:3:"ﰷ";s:4:"كا";s:3:"ﰸ";s:4:"كج";s:3:"ﰹ";s:4:"كح";s:3:"ﰺ";s:4:"كخ";s:3:"ﰻ";s:4:"كل";s:3:"ﰼ";s:4:"كم";s:3:"ﰽ";s:4:"كى";s:3:"ﰾ";s:4:"كي";s:3:"ﰿ";s:4:"لج";s:3:"ﱀ";s:4:"لح";s:3:"ﱁ";s:4:"لخ";s:3:"ﱂ";s:4:"لم";s:3:"ﱃ";s:4:"لى";s:3:"ﱄ";s:4:"لي";s:3:"ﱅ";s:4:"مج";s:3:"ﱆ";s:4:"مح";s:3:"ﱇ";s:4:"مخ";s:3:"ﱈ";s:4:"مم";s:3:"ﱉ";s:4:"مى";s:3:"ﱊ";s:4:"مي";s:3:"ﱋ";s:4:"نج";s:3:"ﱌ";s:4:"نح";s:3:"ﱍ";s:4:"نخ";s:3:"ﱎ";s:4:"نم";s:3:"ﱏ";s:4:"نى";s:3:"ﱐ";s:4:"ني";s:3:"ﱑ";s:4:"هج";s:3:"ﱒ";s:4:"هم";s:3:"ﱓ";s:4:"هى";s:3:"ﱔ";s:4:"هي";s:3:"ﱕ";s:4:"يج";s:3:"ﱖ";s:4:"يح";s:3:"ﱗ";s:4:"يخ";s:3:"ﱘ";s:4:"يم";s:3:"ﱙ";s:4:"يى";s:3:"ﱚ";s:4:"يي";s:3:"ﱛ";s:4:"ذٰ";s:3:"ﱜ";s:4:"رٰ";s:3:"ﱝ";s:4:"ىٰ";s:3:"ﱞ";s:5:" ٌّ";s:3:"ﱟ";s:5:" ٍّ";s:3:"ﱠ";s:5:" َّ";s:3:"ﱡ";s:5:" ُّ";s:3:"ﱢ";s:5:" ِّ";s:3:"ﱣ";s:5:" ّٰ";s:3:"ﱤ";s:4:"ئر";s:3:"ﱥ";s:4:"ئز";s:3:"ﱦ";s:4:"ئم";s:3:"ﱧ";s:4:"ئن";s:3:"ﱨ";s:4:"ئى";s:3:"ﱩ";s:4:"ئي";s:3:"ﱪ";s:4:"بر";s:3:"ﱫ";s:4:"بز";s:3:"ﱬ";s:4:"بم";s:3:"ﱭ";s:4:"بن";s:3:"ﱮ";s:4:"بى";s:3:"ﱯ";s:4:"بي";s:3:"ﱰ";s:4:"تر";s:3:"ﱱ";s:4:"تز";s:3:"ﱲ";s:4:"تم";s:3:"ﱳ";s:4:"تن";s:3:"ﱴ";s:4:"تى";s:3:"ﱵ";s:4:"تي";s:3:"ﱶ";s:4:"ثر";s:3:"ﱷ";s:4:"ثز";s:3:"ﱸ";s:4:"ثم";s:3:"ﱹ";s:4:"ثن";s:3:"ﱺ";s:4:"ثى";s:3:"ﱻ";s:4:"ثي";s:3:"ﱼ";s:4:"فى";s:3:"ﱽ";s:4:"في";s:3:"ﱾ";s:4:"قى";s:3:"ﱿ";s:4:"قي";s:3:"ﲀ";s:4:"كا";s:3:"ﲁ";s:4:"كل";s:3:"ﲂ";s:4:"كم";s:3:"ﲃ";s:4:"كى";s:3:"ﲄ";s:4:"كي";s:3:"ﲅ";s:4:"لم";s:3:"ﲆ";s:4:"لى";s:3:"ﲇ";s:4:"لي";s:3:"ﲈ";s:4:"ما";s:3:"ﲉ";s:4:"مم";s:3:"ﲊ";s:4:"نر";s:3:"ﲋ";s:4:"نز";s:3:"ﲌ";s:4:"نم";s:3:"ﲍ";s:4:"نن";s:3:"ﲎ";s:4:"نى";s:3:"ﲏ";s:4:"ني";s:3:"ﲐ";s:4:"ىٰ";s:3:"ﲑ";s:4:"ير";s:3:"ﲒ";s:4:"يز";s:3:"ﲓ";s:4:"يم";s:3:"ﲔ";s:4:"ين";s:3:"ﲕ";s:4:"يى";s:3:"ﲖ";s:4:"يي";s:3:"ﲗ";s:4:"ئج";s:3:"ﲘ";s:4:"ئح";s:3:"ﲙ";s:4:"ئخ";s:3:"ﲚ";s:4:"ئم";s:3:"ﲛ";s:4:"ئه";s:3:"ﲜ";s:4:"بج";s:3:"ﲝ";s:4:"بح";s:3:"ﲞ";s:4:"بخ";s:3:"ﲟ";s:4:"بم";s:3:"ﲠ";s:4:"به";s:3:"ﲡ";s:4:"تج";s:3:"ﲢ";s:4:"تح";s:3:"ﲣ";s:4:"تخ";s:3:"ﲤ";s:4:"تم";s:3:"ﲥ";s:4:"ته";s:3:"ﲦ";s:4:"ثم";s:3:"ﲧ";s:4:"جح";s:3:"ﲨ";s:4:"جم";s:3:"ﲩ";s:4:"حج";s:3:"ﲪ";s:4:"حم";s:3:"ﲫ";s:4:"خج";s:3:"ﲬ";s:4:"خم";s:3:"ﲭ";s:4:"سج";s:3:"ﲮ";s:4:"سح";s:3:"ﲯ";s:4:"سخ";s:3:"ﲰ";s:4:"سم";s:3:"ﲱ";s:4:"صح";s:3:"ﲲ";s:4:"صخ";s:3:"ﲳ";s:4:"صم";s:3:"ﲴ";s:4:"ضج";s:3:"ﲵ";s:4:"ضح";s:3:"ﲶ";s:4:"ضخ";s:3:"ﲷ";s:4:"ضم";s:3:"ﲸ";s:4:"طح";s:3:"ﲹ";s:4:"ظم";s:3:"ﲺ";s:4:"عج";s:3:"ﲻ";s:4:"عم";s:3:"ﲼ";s:4:"غج";s:3:"ﲽ";s:4:"غم";s:3:"ﲾ";s:4:"فج";s:3:"ﲿ";s:4:"فح";s:3:"ﳀ";s:4:"فخ";s:3:"ﳁ";s:4:"فم";s:3:"ﳂ";s:4:"قح";s:3:"ﳃ";s:4:"قم";s:3:"ﳄ";s:4:"كج";s:3:"ﳅ";s:4:"كح";s:3:"ﳆ";s:4:"كخ";s:3:"ﳇ";s:4:"كل";s:3:"ﳈ";s:4:"كم";s:3:"ﳉ";s:4:"لج";s:3:"ﳊ";s:4:"لح";s:3:"ﳋ";s:4:"لخ";s:3:"ﳌ";s:4:"لم";s:3:"ﳍ";s:4:"له";s:3:"ﳎ";s:4:"مج";s:3:"ﳏ";s:4:"مح";s:3:"ﳐ";s:4:"مخ";s:3:"ﳑ";s:4:"مم";s:3:"ﳒ";s:4:"نج";s:3:"ﳓ";s:4:"نح";s:3:"ﳔ";s:4:"نخ";s:3:"ﳕ";s:4:"نم";s:3:"ﳖ";s:4:"نه";s:3:"ﳗ";s:4:"هج";s:3:"ﳘ";s:4:"هم";s:3:"ﳙ";s:4:"هٰ";s:3:"ﳚ";s:4:"يج";s:3:"ﳛ";s:4:"يح";s:3:"ﳜ";s:4:"يخ";s:3:"ﳝ";s:4:"يم";s:3:"ﳞ";s:4:"يه";s:3:"ﳟ";s:4:"ئم";s:3:"ﳠ";s:4:"ئه";s:3:"ﳡ";s:4:"بم";s:3:"ﳢ";s:4:"به";s:3:"ﳣ";s:4:"تم";s:3:"ﳤ";s:4:"ته";s:3:"ﳥ";s:4:"ثم";s:3:"ﳦ";s:4:"ثه";s:3:"ﳧ";s:4:"سم";s:3:"ﳨ";s:4:"سه";s:3:"ﳩ";s:4:"شم";s:3:"ﳪ";s:4:"شه";s:3:"ﳫ";s:4:"كل";s:3:"ﳬ";s:4:"كم";s:3:"ﳭ";s:4:"لم";s:3:"ﳮ";s:4:"نم";s:3:"ﳯ";s:4:"نه";s:3:"ﳰ";s:4:"يم";s:3:"ﳱ";s:4:"يه";s:3:"ﳲ";s:6:"ـَّ";s:3:"ﳳ";s:6:"ـُّ";s:3:"ﳴ";s:6:"ـِّ";s:3:"ﳵ";s:4:"طى";s:3:"ﳶ";s:4:"طي";s:3:"ﳷ";s:4:"عى";s:3:"ﳸ";s:4:"عي";s:3:"ﳹ";s:4:"غى";s:3:"ﳺ";s:4:"غي";s:3:"ﳻ";s:4:"سى";s:3:"ﳼ";s:4:"سي";s:3:"ﳽ";s:4:"شى";s:3:"ﳾ";s:4:"شي";s:3:"ﳿ";s:4:"حى";s:3:"ﴀ";s:4:"حي";s:3:"ﴁ";s:4:"جى";s:3:"ﴂ";s:4:"جي";s:3:"ﴃ";s:4:"خى";s:3:"ﴄ";s:4:"خي";s:3:"ﴅ";s:4:"صى";s:3:"ﴆ";s:4:"صي";s:3:"ﴇ";s:4:"ضى";s:3:"ﴈ";s:4:"ضي";s:3:"ﴉ";s:4:"شج";s:3:"ﴊ";s:4:"شح";s:3:"ﴋ";s:4:"شخ";s:3:"ﴌ";s:4:"شم";s:3:"ﴍ";s:4:"شر";s:3:"ﴎ";s:4:"سر";s:3:"ﴏ";s:4:"صر";s:3:"ﴐ";s:4:"ضر";s:3:"ﴑ";s:4:"طى";s:3:"ﴒ";s:4:"طي";s:3:"ﴓ";s:4:"عى";s:3:"ﴔ";s:4:"عي";s:3:"ﴕ";s:4:"غى";s:3:"ﴖ";s:4:"غي";s:3:"ﴗ";s:4:"سى";s:3:"ﴘ";s:4:"سي";s:3:"ﴙ";s:4:"شى";s:3:"ﴚ";s:4:"شي";s:3:"ﴛ";s:4:"حى";s:3:"ﴜ";s:4:"حي";s:3:"ﴝ";s:4:"جى";s:3:"ﴞ";s:4:"جي";s:3:"ﴟ";s:4:"خى";s:3:"ﴠ";s:4:"خي";s:3:"ﴡ";s:4:"صى";s:3:"ﴢ";s:4:"صي";s:3:"ﴣ";s:4:"ضى";s:3:"ﴤ";s:4:"ضي";s:3:"ﴥ";s:4:"شج";s:3:"ﴦ";s:4:"شح";s:3:"ﴧ";s:4:"شخ";s:3:"ﴨ";s:4:"شم";s:3:"ﴩ";s:4:"شر";s:3:"ﴪ";s:4:"سر";s:3:"ﴫ";s:4:"صر";s:3:"ﴬ";s:4:"ضر";s:3:"ﴭ";s:4:"شج";s:3:"ﴮ";s:4:"شح";s:3:"ﴯ";s:4:"شخ";s:3:"ﴰ";s:4:"شم";s:3:"ﴱ";s:4:"سه";s:3:"ﴲ";s:4:"شه";s:3:"ﴳ";s:4:"طم";s:3:"ﴴ";s:4:"سج";s:3:"ﴵ";s:4:"سح";s:3:"ﴶ";s:4:"سخ";s:3:"ﴷ";s:4:"شج";s:3:"ﴸ";s:4:"شح";s:3:"ﴹ";s:4:"شخ";s:3:"ﴺ";s:4:"طم";s:3:"ﴻ";s:4:"ظم";s:3:"ﴼ";s:4:"اً";s:3:"ﴽ";s:4:"اً";s:3:"ﵐ";s:6:"تجم";s:3:"ﵑ";s:6:"تحج";s:3:"ﵒ";s:6:"تحج";s:3:"ﵓ";s:6:"تحم";s:3:"ﵔ";s:6:"تخم";s:3:"ﵕ";s:6:"تمج";s:3:"ﵖ";s:6:"تمح";s:3:"ﵗ";s:6:"تمخ";s:3:"ﵘ";s:6:"جمح";s:3:"ﵙ";s:6:"جمح";s:3:"ﵚ";s:6:"حمي";s:3:"ﵛ";s:6:"حمى";s:3:"ﵜ";s:6:"سحج";s:3:"ﵝ";s:6:"سجح";s:3:"ﵞ";s:6:"سجى";s:3:"ﵟ";s:6:"سمح";s:3:"ﵠ";s:6:"سمح";s:3:"ﵡ";s:6:"سمج";s:3:"ﵢ";s:6:"سمم";s:3:"ﵣ";s:6:"سمم";s:3:"ﵤ";s:6:"صحح";s:3:"ﵥ";s:6:"صحح";s:3:"ﵦ";s:6:"صمم";s:3:"ﵧ";s:6:"شحم";s:3:"ﵨ";s:6:"شحم";s:3:"ﵩ";s:6:"شجي";s:3:"ﵪ";s:6:"شمخ";s:3:"ﵫ";s:6:"شمخ";s:3:"ﵬ";s:6:"شمم";s:3:"ﵭ";s:6:"شمم";s:3:"ﵮ";s:6:"ضحى";s:3:"ﵯ";s:6:"ضخم";s:3:"ﵰ";s:6:"ضخم";s:3:"ﵱ";s:6:"طمح";s:3:"ﵲ";s:6:"طمح";s:3:"ﵳ";s:6:"طمم";s:3:"ﵴ";s:6:"طمي";s:3:"ﵵ";s:6:"عجم";s:3:"ﵶ";s:6:"عمم";s:3:"ﵷ";s:6:"عمم";s:3:"ﵸ";s:6:"عمى";s:3:"ﵹ";s:6:"غمم";s:3:"ﵺ";s:6:"غمي";s:3:"ﵻ";s:6:"غمى";s:3:"ﵼ";s:6:"فخم";s:3:"ﵽ";s:6:"فخم";s:3:"ﵾ";s:6:"قمح";s:3:"ﵿ";s:6:"قمم";s:3:"ﶀ";s:6:"لحم";s:3:"ﶁ";s:6:"لحي";s:3:"ﶂ";s:6:"لحى";s:3:"ﶃ";s:6:"لجج";s:3:"ﶄ";s:6:"لجج";s:3:"ﶅ";s:6:"لخم";s:3:"ﶆ";s:6:"لخم";s:3:"ﶇ";s:6:"لمح";s:3:"ﶈ";s:6:"لمح";s:3:"ﶉ";s:6:"محج";s:3:"ﶊ";s:6:"محم";s:3:"ﶋ";s:6:"محي";s:3:"ﶌ";s:6:"مجح";s:3:"ﶍ";s:6:"مجم";s:3:"ﶎ";s:6:"مخج";s:3:"ﶏ";s:6:"مخم";s:3:"ﶒ";s:6:"مجخ";s:3:"ﶓ";s:6:"همج";s:3:"ﶔ";s:6:"همم";s:3:"ﶕ";s:6:"نحم";s:3:"ﶖ";s:6:"نحى";s:3:"ﶗ";s:6:"نجم";s:3:"ﶘ";s:6:"نجم";s:3:"ﶙ";s:6:"نجى";s:3:"ﶚ";s:6:"نمي";s:3:"ﶛ";s:6:"نمى";s:3:"ﶜ";s:6:"يمم";s:3:"ﶝ";s:6:"يمم";s:3:"ﶞ";s:6:"بخي";s:3:"ﶟ";s:6:"تجي";s:3:"ﶠ";s:6:"تجى";s:3:"ﶡ";s:6:"تخي";s:3:"ﶢ";s:6:"تخى";s:3:"ﶣ";s:6:"تمي";s:3:"ﶤ";s:6:"تمى";s:3:"ﶥ";s:6:"جمي";s:3:"ﶦ";s:6:"جحى";s:3:"ﶧ";s:6:"جمى";s:3:"ﶨ";s:6:"سخى";s:3:"ﶩ";s:6:"صحي";s:3:"ﶪ";s:6:"شحي";s:3:"ﶫ";s:6:"ضحي";s:3:"ﶬ";s:6:"لجي";s:3:"ﶭ";s:6:"لمي";s:3:"ﶮ";s:6:"يحي";s:3:"ﶯ";s:6:"يجي";s:3:"ﶰ";s:6:"يمي";s:3:"ﶱ";s:6:"ممي";s:3:"ﶲ";s:6:"قمي";s:3:"ﶳ";s:6:"نحي";s:3:"ﶴ";s:6:"قمح";s:3:"ﶵ";s:6:"لحم";s:3:"ﶶ";s:6:"عمي";s:3:"ﶷ";s:6:"كمي";s:3:"ﶸ";s:6:"نجح";s:3:"ﶹ";s:6:"مخي";s:3:"ﶺ";s:6:"لجم";s:3:"ﶻ";s:6:"كمم";s:3:"ﶼ";s:6:"لجم";s:3:"ﶽ";s:6:"نجح";s:3:"ﶾ";s:6:"جحي";s:3:"ﶿ";s:6:"حجي";s:3:"ﷀ";s:6:"مجي";s:3:"ﷁ";s:6:"فمي";s:3:"ﷂ";s:6:"بحي";s:3:"ﷃ";s:6:"كمم";s:3:"ﷄ";s:6:"عجم";s:3:"ﷅ";s:6:"صمم";s:3:"ﷆ";s:6:"سخي";s:3:"ﷇ";s:6:"نجي";s:3:"ﷰ";s:6:"صلے";s:3:"ﷱ";s:6:"قلے";s:3:"ﷲ";s:8:"الله";s:3:"ﷳ";s:8:"اكبر";s:3:"ﷴ";s:8:"محمد";s:3:"ﷵ";s:8:"صلعم";s:3:"ﷶ";s:8:"رسول";s:3:"ﷷ";s:8:"عليه";s:3:"ﷸ";s:8:"وسلم";s:3:"ﷹ";s:6:"صلى";s:3:"ﷺ";s:33:"صلى الله عليه وسلم";s:3:"ﷻ";s:15:"جل جلاله";s:3:"﷼";s:8:"ریال";s:3:"ﹰ";s:3:" ً";s:3:"ﹱ";s:4:"ـً";s:3:"ﹲ";s:3:" ٌ";s:3:"ﹴ";s:3:" ٍ";s:3:"ﹶ";s:3:" َ";s:3:"ﹷ";s:4:"ـَ";s:3:"ﹸ";s:3:" ُ";s:3:"ﹹ";s:4:"ـُ";s:3:"ﹺ";s:3:" ِ";s:3:"ﹻ";s:4:"ـِ";s:3:"ﹼ";s:3:" ّ";s:3:"ﹽ";s:4:"ـّ";s:3:"ﹾ";s:3:" ْ";s:3:"ﹿ";s:4:"ـْ";s:3:"ﺀ";s:2:"ء";s:3:"ﺁ";s:2:"آ";s:3:"ﺂ";s:2:"آ";s:3:"ﺃ";s:2:"أ";s:3:"ﺄ";s:2:"أ";s:3:"ﺅ";s:2:"ؤ";s:3:"ﺆ";s:2:"ؤ";s:3:"ﺇ";s:2:"إ";s:3:"ﺈ";s:2:"إ";s:3:"ﺉ";s:2:"ئ";s:3:"ﺊ";s:2:"ئ";s:3:"ﺋ";s:2:"ئ";s:3:"ﺌ";s:2:"ئ";s:3:"ﺍ";s:2:"ا";s:3:"ﺎ";s:2:"ا";s:3:"ﺏ";s:2:"ب";s:3:"ﺐ";s:2:"ب";s:3:"ﺑ";s:2:"ب";s:3:"ﺒ";s:2:"ب";s:3:"ﺓ";s:2:"ة";s:3:"ﺔ";s:2:"ة";s:3:"ﺕ";s:2:"ت";s:3:"ﺖ";s:2:"ت";s:3:"ﺗ";s:2:"ت";s:3:"ﺘ";s:2:"ت";s:3:"ﺙ";s:2:"ث";s:3:"ﺚ";s:2:"ث";s:3:"ﺛ";s:2:"ث";s:3:"ﺜ";s:2:"ث";s:3:"ﺝ";s:2:"ج";s:3:"ﺞ";s:2:"ج";s:3:"ﺟ";s:2:"ج";s:3:"ﺠ";s:2:"ج";s:3:"ﺡ";s:2:"ح";s:3:"ﺢ";s:2:"ح";s:3:"ﺣ";s:2:"ح";s:3:"ﺤ";s:2:"ح";s:3:"ﺥ";s:2:"خ";s:3:"ﺦ";s:2:"خ";s:3:"ﺧ";s:2:"خ";s:3:"ﺨ";s:2:"خ";s:3:"ﺩ";s:2:"د";s:3:"ﺪ";s:2:"د";s:3:"ﺫ";s:2:"ذ";s:3:"ﺬ";s:2:"ذ";s:3:"ﺭ";s:2:"ر";s:3:"ﺮ";s:2:"ر";s:3:"ﺯ";s:2:"ز";s:3:"ﺰ";s:2:"ز";s:3:"ﺱ";s:2:"س";s:3:"ﺲ";s:2:"س";s:3:"ﺳ";s:2:"س";s:3:"ﺴ";s:2:"س";s:3:"ﺵ";s:2:"ش";s:3:"ﺶ";s:2:"ش";s:3:"ﺷ";s:2:"ش";s:3:"ﺸ";s:2:"ش";s:3:"ﺹ";s:2:"ص";s:3:"ﺺ";s:2:"ص";s:3:"ﺻ";s:2:"ص";s:3:"ﺼ";s:2:"ص";s:3:"ﺽ";s:2:"ض";s:3:"ﺾ";s:2:"ض";s:3:"ﺿ";s:2:"ض";s:3:"ﻀ";s:2:"ض";s:3:"ﻁ";s:2:"ط";s:3:"ﻂ";s:2:"ط";s:3:"ﻃ";s:2:"ط";s:3:"ﻄ";s:2:"ط";s:3:"ﻅ";s:2:"ظ";s:3:"ﻆ";s:2:"ظ";s:3:"ﻇ";s:2:"ظ";s:3:"ﻈ";s:2:"ظ";s:3:"ﻉ";s:2:"ع";s:3:"ﻊ";s:2:"ع";s:3:"ﻋ";s:2:"ع";s:3:"ﻌ";s:2:"ع";s:3:"ﻍ";s:2:"غ";s:3:"ﻎ";s:2:"غ";s:3:"ﻏ";s:2:"غ";s:3:"ﻐ";s:2:"غ";s:3:"ﻑ";s:2:"ف";s:3:"ﻒ";s:2:"ف";s:3:"ﻓ";s:2:"ف";s:3:"ﻔ";s:2:"ف";s:3:"ﻕ";s:2:"ق";s:3:"ﻖ";s:2:"ق";s:3:"ﻗ";s:2:"ق";s:3:"ﻘ";s:2:"ق";s:3:"ﻙ";s:2:"ك";s:3:"ﻚ";s:2:"ك";s:3:"ﻛ";s:2:"ك";s:3:"ﻜ";s:2:"ك";s:3:"ﻝ";s:2:"ل";s:3:"ﻞ";s:2:"ل";s:3:"ﻟ";s:2:"ل";s:3:"ﻠ";s:2:"ل";s:3:"ﻡ";s:2:"م";s:3:"ﻢ";s:2:"م";s:3:"ﻣ";s:2:"م";s:3:"ﻤ";s:2:"م";s:3:"ﻥ";s:2:"ن";s:3:"ﻦ";s:2:"ن";s:3:"ﻧ";s:2:"ن";s:3:"ﻨ";s:2:"ن";s:3:"ﻩ";s:2:"ه";s:3:"ﻪ";s:2:"ه";s:3:"ﻫ";s:2:"ه";s:3:"ﻬ";s:2:"ه";s:3:"ﻭ";s:2:"و";s:3:"ﻮ";s:2:"و";s:3:"ﻯ";s:2:"ى";s:3:"ﻰ";s:2:"ى";s:3:"ﻱ";s:2:"ي";s:3:"ﻲ";s:2:"ي";s:3:"ﻳ";s:2:"ي";s:3:"ﻴ";s:2:"ي";s:3:"ﻵ";s:4:"لآ";s:3:"ﻶ";s:4:"لآ";s:3:"ﻷ";s:4:"لأ";s:3:"ﻸ";s:4:"لأ";s:3:"ﻹ";s:4:"لإ";s:3:"ﻺ";s:4:"لإ";s:3:"ﻻ";s:4:"لا";s:3:"ﻼ";s:4:"لا";}
\ No newline at end of file
diff --git a/serialized/normalize-ml.ser b/serialized/normalize-ml.ser
deleted file mode 100644 (file)
index b27a217..0000000
+++ /dev/null
@@ -1 +0,0 @@
-a:6:{s:9:"ണ്‍";s:3:"ൺ";s:9:"ന്‍";s:3:"ൻ";s:9:"ര്‍";s:3:"ർ";s:9:"ല്‍";s:3:"ൽ";s:9:"ള്‍";s:3:"ൾ";s:9:"ക്‍";s:3:"ൿ";}
\ No newline at end of file
index 08ec9f6..ce1dae6 100644 (file)
@@ -829,6 +829,13 @@ class ParserTestRunner {
                        $titleText = 'Parser test';
                }
 
+               if ( isset( $opts['maxincludesize'] ) ) {
+                       $options->setMaxIncludeSize( $opts['maxincludesize'] );
+               }
+               if ( isset( $opts['maxtemplatedepth'] ) ) {
+                       $options->setMaxTemplateDepth( $opts['maxtemplatedepth'] );
+               }
+
                $local = isset( $opts['local'] );
                $preprocessor = isset( $opts['preprocessor'] ) ? $opts['preprocessor'] : null;
                $parser = $this->getParser( $preprocessor );
@@ -1083,6 +1090,11 @@ class ParserTestRunner {
                        'wgFragmentMode' => [ 'legacy' ],
                ];
 
+               $nonIncludable = self::getOptionValue( 'wgNonincludableNamespaces', $opts, false );
+               if ( $nonIncludable !== false ) {
+                       $setup['wgNonincludableNamespaces'] = [ $nonIncludable ];
+               }
+
                if ( $config ) {
                        $configLines = explode( "\n", $config );
 
index d17fbbe..216d7e5 100644 (file)
@@ -62,6 +62,12 @@ Template:Foo
 FOO
 !!endarticle
 
+!! article
+Template:redirect to foo
+!! text
+#REDIRECT [[Template:Foo]]
+!! endarticle
+
 !! article
 Template:Blank
 !! text
@@ -109,6 +115,14 @@ Template:echo
 {{{1}}}
 !! endarticle
 
+!! article
+Template:echo3
+!! text
+{{{1}}}
+{{{1}}}
+{{{1}}}
+!! endarticle
+
 // For Serbian; localize Template namespace
 !! article
 Шаблон:Echo
@@ -128,6 +142,12 @@ Template:echo_with_div
 <div>{{{1}}}</div>
 !! endarticle
 
+!! article
+Template:echo with depth
+!! text
+{{echo|{{{1}}}}}
+!! endarticle
+
 !! article
 Template:blank_param
 !! text
@@ -1825,6 +1845,39 @@ b
 </p>
 !! end
 
+!! test
+post-expand include size being exceeded
+!! options
+maxincludesize=20
+!! wikitext
+{{echo3|1234567890}}
+!! html
+<p><a href="/wiki/Template:Echo3" title="Template:Echo3">Template:Echo3</a><!-- WARNING: template omitted, post-expand include size too large -->
+</p>
+!! end
+
+!! test
+max template depth being reached
+!! options
+maxtemplatedepth=1
+!! wikitext
+{{echo with depth|too deep!}}
+!! html
+<p><span class="error">Template recursion depth limit exceeded (1)</span>
+</p>
+!! end
+
+!! test
+multiple templates that are redirects
+!! wikitext
+{{redirect to foo}}
+{{redirect to foo}}
+!! html
+<p>FOO
+FOO
+</p>
+!! end
+
 !! test
 Multiple comments should still parse as SOL-transparent
 !! options
@@ -11504,6 +11557,17 @@ Template from main namespace
 </p>
 !! end
 
+!! test
+Template from non-includable namespace
+!! options
+wgNonincludableNamespaces=10
+!! wikitext
+{{echo|uh oh!}}
+!! html
+<p><a href="/wiki/Template:Echo" title="Template:Echo">Template:Echo</a>
+</p>
+!! end
+
 !! article
 Template:table
 !! text
diff --git a/tests/phpunit/data/autoloader/psr4/TestFooBar.php b/tests/phpunit/data/autoloader/psr4/TestFooBar.php
new file mode 100644 (file)
index 0000000..4a2e11f
--- /dev/null
@@ -0,0 +1,6 @@
+<?php
+
+namespace Test\MediaWiki\AutoLoader;
+
+class TestFooBar {
+}
index ad16c5e..cfad069 100644 (file)
@@ -1,4 +1,12 @@
 {
        "name": "FooBar",
-       "manifest_version": 1
+       "attributes": {
+               "FooBar": {
+                       "Attr": [ "test" ]
+               },
+               "NotLoaded": {
+                       "Attr": [ "test2" ]
+               }
+       },
+       "manifest_version": 2
 }
diff --git a/tests/phpunit/includes/AutoLoaderTest.php b/tests/phpunit/includes/AutoLoaderTest.php
new file mode 100644 (file)
index 0000000..af6911d
--- /dev/null
@@ -0,0 +1,64 @@
+<?php
+
+/**
+ * @covers AutoLoader
+ */
+class AutoLoaderTest extends MediaWikiTestCase {
+
+       private $oldPsr4;
+
+       protected function setUp() {
+               parent::setUp();
+
+               // Fancy dance to trigger a rebuild of AutoLoader::$autoloadLocalClassesLower
+               $this->mergeMwGlobalArrayValue( 'wgAutoloadLocalClasses', [
+                       'TestAutoloadedLocalClass' =>
+                               __DIR__ . '/../data/autoloader/TestAutoloadedLocalClass.php',
+                       'TestAutoloadedCamlClass' =>
+                               __DIR__ . '/../data/autoloader/TestAutoloadedCamlClass.php',
+                       'TestAutoloadedSerializedClass' =>
+                               __DIR__ . '/../data/autoloader/TestAutoloadedSerializedClass.php',
+               ] );
+               AutoLoader::resetAutoloadLocalClassesLower();
+
+               $this->mergeMwGlobalArrayValue( 'wgAutoloadClasses', [
+                       'TestAutoloadedClass' => __DIR__ . '/../data/autoloader/TestAutoloadedClass.php',
+               ] );
+
+               $this->oldPsr4 = AutoLoader::$psr4Namespaces;
+               AutoLoader::$psr4Namespaces['Test\\MediaWiki\\AutoLoader\\'] =
+                       __DIR__ . '/../data/autoloader/psr4';
+       }
+
+       protected function tearDown() {
+               AutoLoader::$psr4Namespaces = $this->oldPsr4;
+               parent::tearDown();
+       }
+
+       public function testCoreClass() {
+               $this->assertTrue( class_exists( 'TestAutoloadedLocalClass' ) );
+       }
+
+       public function testExtensionClass() {
+               $this->assertTrue( class_exists( 'TestAutoloadedClass' ) );
+       }
+
+       public function testWrongCaseClass() {
+               $this->setMwGlobals( 'wgAutoloadAttemptLowercase', true );
+
+               $this->assertTrue( class_exists( 'testautoLoadedcamlCLASS' ) );
+       }
+
+       public function testWrongCaseSerializedClass() {
+               $this->setMwGlobals( 'wgAutoloadAttemptLowercase', true );
+
+               $dummyCereal = 'O:29:"testautoloadedserializedclass":0:{}';
+               $uncerealized = unserialize( $dummyCereal );
+               $this->assertFalse( $uncerealized instanceof __PHP_Incomplete_Class,
+                       "unserialize() can load classes case-insensitively." );
+       }
+
+       public function testPsr4() {
+               $this->assertTrue( class_exists( 'Test\\MediaWiki\\AutoLoader\\TestFooBar' ) );
+       }
+}
index efe92ec..c1efc7f 100644 (file)
@@ -33,6 +33,12 @@ class HooksTest extends MediaWikiTestCase {
                                'changed-static',
                                'original'
                        ],
+                       [
+                               'Class::method static call as array',
+                               [ [ 'NothingClass::someStatic' ] ],
+                               'changed-static',
+                               'original'
+                       ],
                        [ 'Global function', [ 'NothingFunction' ], 'changed-func', 'original' ],
                        [ 'Global function with data', [ 'NothingFunctionData', 'data' ], 'data', 'original' ],
                        [ 'Closure', [ function ( &$foo, $bar ) {
@@ -81,10 +87,50 @@ class HooksTest extends MediaWikiTestCase {
                $this->assertSame( $expectedBar, $bar, $msg );
        }
 
+       /**
+        * @covers Hooks::getHandlers
+        */
+       public function testGetHandlers() {
+               global $wgHooks;
+
+               $this->assertSame(
+                       [],
+                       Hooks::getHandlers( 'MediaWikiHooksTest001' ),
+                       'No hooks registered'
+               );
+
+               $a = new NothingClass();
+               $b = new NothingClass();
+
+               $wgHooks['MediaWikiHooksTest001'][] = $a;
+
+               $this->assertSame(
+                       [ $a ],
+                       Hooks::getHandlers( 'MediaWikiHooksTest001' ),
+                       'Hook registered by $wgHooks'
+               );
+
+               Hooks::register( 'MediaWikiHooksTest001', $b );
+               $this->assertSame(
+                       [ $b, $a ],
+                       Hooks::getHandlers( 'MediaWikiHooksTest001' ),
+                       'Hooks::getHandlers() should return hooks registered via wgHooks as well as Hooks::register'
+               );
+
+               Hooks::clear( 'MediaWikiHooksTest001' );
+               unset( $wgHooks['MediaWikiHooksTest001'] );
+
+               Hooks::register( 'MediaWikiHooksTest001', $b );
+               $this->assertSame(
+                       [ $b ],
+                       Hooks::getHandlers( 'MediaWikiHooksTest001' ),
+                       'Hook registered by Hook::register'
+               );
+       }
+
        /**
         * @covers Hooks::isRegistered
         * @covers Hooks::register
-        * @covers Hooks::getHandlers
         * @covers Hooks::run
         * @covers Hooks::callHook
         */
@@ -151,6 +197,56 @@ class HooksTest extends MediaWikiTestCase {
                $this->assertSame( 'original', $foo, 'Hooks abort after a false return.' );
        }
 
+       /**
+        * @covers Hooks::run
+        */
+       public function testNullReturn() {
+               Hooks::register( 'MediaWikiHooksTest001', function ( &$foo ) {
+                       return;
+               } );
+               Hooks::register( 'MediaWikiHooksTest001', function ( &$foo ) {
+                       $foo = 'test';
+
+                       return true;
+               } );
+               $foo = 'original';
+               Hooks::run( 'MediaWikiHooksTest001', [ &$foo ] );
+               $this->assertSame( 'test', $foo, 'Hooks continue after a null return.' );
+       }
+
+       /**
+        * @covers Hooks::callHook
+        */
+       public function testCallHook_FalseHook() {
+               Hooks::register( 'MediaWikiHooksTest001', false );
+               Hooks::register( 'MediaWikiHooksTest001', function ( &$foo ) {
+                       $foo = 'test';
+
+                       return true;
+               } );
+               $foo = 'original';
+               Hooks::run( 'MediaWikiHooksTest001', [ &$foo ] );
+               $this->assertSame( 'test', $foo, 'Hooks that are falsey are skipped.' );
+       }
+
+       /**
+        * @covers Hooks::callHook
+        * @expectedException MWException
+        */
+       public function testCallHook_UnknownDatatype() {
+               Hooks::register( 'MediaWikiHooksTest001', 12345 );
+               Hooks::run( 'MediaWikiHooksTest001' );
+       }
+
+       /**
+        * @covers Hooks::callHook
+        * @expectedException PHPUnit_Framework_Error_Deprecated
+        */
+       public function testCallHook_Deprecated() {
+               Hooks::register( 'MediaWikiHooksTest001', 'NothingClass::someStatic' );
+               Hooks::run( 'MediaWikiHooksTest001', [], '1.31' );
+       }
+
        /**
         * @covers Hooks::runWithoutAbort
         * @covers Hooks::callHook
index e46fc67..4556473 100644 (file)
@@ -97,8 +97,8 @@ class XmlTest extends MediaWikiTestCase {
         */
        public function testElementEscaping() {
                $this->assertEquals(
-                       '<element>hello &lt;there&gt; you &amp; you</element>',
-                       Xml::element( 'element', null, 'hello <there> you & you' ),
+                       '<element>"hello &lt;there&gt; your\'s &amp; you"</element>',
+                       Xml::element( 'element', null, '"hello <there> your\'s & you"' ),
                        'Element with no attributes and content that needs escaping'
                );
        }
index 4e3e3fc..cce99ce 100644 (file)
@@ -212,6 +212,44 @@ class ApiBaseTest extends ApiTestCase {
                $mock->getTitleFromTitleOrPageId( [ 'pageid' => 298401643 ] );
        }
 
+       public function testGetParameter() {
+               $mock = $this->getMockBuilder( MockApi::class )
+                       ->setMethods( [ 'getAllowedParams' ] )
+                       ->getMock();
+               $mock->method( 'getAllowedParams' )->willReturn( [
+                       'foo' => [
+                               ApiBase::PARAM_TYPE => [ 'value' ],
+                       ],
+                       'bar' => [
+                               ApiBase::PARAM_TYPE => [ 'value' ],
+                       ],
+               ] );
+               $wrapper = TestingAccessWrapper::newFromObject( $mock );
+
+               $context = new DerivativeContext( $mock );
+               $context->setRequest( new FauxRequest( [ 'foo' => 'bad', 'bar' => 'value' ] ) );
+               $wrapper->mMainModule = new ApiMain( $context );
+
+               // Even though 'foo' is bad, getParameter( 'bar' ) must not fail
+               $this->assertSame( 'value', $wrapper->getParameter( 'bar' ) );
+
+               // But getParameter( 'foo' ) must throw.
+               try {
+                       $wrapper->getParameter( 'foo' );
+                       $this->fail( 'Expected exception not thrown' );
+               } catch ( ApiUsageException $ex ) {
+                       $this->assertTrue( $this->apiExceptionHasCode( $ex, 'unknown_foo' ) );
+               }
+
+               // And extractRequestParams() must throw too.
+               try {
+                       $mock->extractRequestParams();
+                       $this->fail( 'Expected exception not thrown' );
+               } catch ( ApiUsageException $ex ) {
+                       $this->assertTrue( $this->apiExceptionHasCode( $ex, 'unknown_foo' ) );
+               }
+       }
+
        /**
         * @dataProvider provideGetParameterFromSettings
         * @param string|null $input
index c196338..3909b30 100644 (file)
@@ -733,7 +733,7 @@ class ApiEditPageTest extends ApiTestCase {
                $dbw = wfGetDB( DB_MASTER );
                $dbw->update(
                        'revision',
-                       [ 'rev_timestamp' => wfTimestamp( TS_MW, time() - 86400 ) ],
+                       [ 'rev_timestamp' => $dbw->timestamp( time() - 86400 ) ],
                        [ 'rev_id' => $revId1 ],
                        __METHOD__
                );
index 915fb5c..4438332 100644 (file)
@@ -109,7 +109,7 @@ class ApiFormatXmlTest extends ApiFormatTestBase {
                                [ 'xslt' => 'DoesNotExist' ] ],
                        [ [], '<?xml version="1.0"?><api><warnings><xml xml:space="preserve">Stylesheet should be in the MediaWiki namespace.</xml></warnings></api>',
                                [ 'xslt' => 'ApiFormatXmlTest' ] ],
-                       [ [], '<?xml version="1.0"?><api><warnings><xml xml:space="preserve">Stylesheet should have &quot;.xsl&quot; extension.</xml></warnings></api>',
+                       [ [], '<?xml version="1.0"?><api><warnings><xml xml:space="preserve">Stylesheet should have ".xsl" extension.</xml></warnings></api>',
                                [ 'xslt' => 'MediaWiki:ApiFormatXmlTest' ] ],
                        [ [],
                                '<?xml version="1.0"?><?xml-stylesheet href="' .
diff --git a/tests/phpunit/includes/api/query/ApiQueryUserContribsTest.php b/tests/phpunit/includes/api/query/ApiQueryUserContribsTest.php
new file mode 100644 (file)
index 0000000..1d0b471
--- /dev/null
@@ -0,0 +1,194 @@
+<?php
+
+/**
+ * @group API
+ * @group Database
+ * @group medium
+ * @covers ApiQueryUserContribs
+ */
+class ApiQueryUserContribsTest extends ApiTestCase {
+       public function addDBDataOnce() {
+               global $wgActorTableSchemaMigrationStage;
+
+               $reset = new \Wikimedia\ScopedCallback( function ( $v ) {
+                       global $wgActorTableSchemaMigrationStage;
+                       $wgActorTableSchemaMigrationStage = $v;
+                       $this->overrideMwServices();
+               }, [ $wgActorTableSchemaMigrationStage ] );
+               $wgActorTableSchemaMigrationStage = MIGRATION_WRITE_BOTH;
+               $this->overrideMwServices();
+
+               $users = [
+                       User::newFromName( '192.168.2.2', false ),
+                       User::newFromName( '192.168.2.1', false ),
+                       User::newFromName( '192.168.2.3', false ),
+                       User::createNew( __CLASS__ . ' B' ),
+                       User::createNew( __CLASS__ . ' A' ),
+                       User::createNew( __CLASS__ . ' C' ),
+                       User::newFromName( 'IW>' . __CLASS__, false ),
+               ];
+
+               $title = Title::newFromText( __CLASS__ );
+               $page = WikiPage::factory( $title );
+               for ( $i = 0; $i < 3; $i++ ) {
+                       foreach ( array_reverse( $users ) as $user ) {
+                               $status = $page->doEditContent(
+                                       ContentHandler::makeContent( "Test revision $user #$i", $title ), 'Test edit', 0, false, $user
+                               );
+                               if ( !$status->isOK() ) {
+                                       $this->fail( "Failed to edit $title: " . $status->getWikiText( false, false, 'en' ) );
+                               }
+                       }
+               }
+       }
+
+       /**
+        * @dataProvider provideSorting
+        * @param int $stage One of the MIGRATION_* constants for $wgActorTableSchemaMigrationStage
+        * @param array $params Extra parameters for the query
+        * @param bool $reverse Reverse order?
+        * @param int $revs Number of revisions to expect
+        */
+       public function testSorting( $stage, $params, $reverse, $revs ) {
+               if ( isset( $params['ucuserprefix'] ) &&
+                       ( $stage === MIGRATION_WRITE_BOTH || $stage === MIGRATION_WRITE_NEW ) &&
+                       $this->db->getType() === 'mysql' && $this->usesTemporaryTables()
+               ) {
+                       // https://bugs.mysql.com/bug.php?id=10327
+                       $this->markTestSkipped( 'MySQL bug 10327 - can\'t reopen temporary tables' );
+               }
+
+               $this->setMwGlobals( 'wgActorTableSchemaMigrationStage', $stage );
+               $this->overrideMwServices();
+
+               if ( isset( $params['ucuserids'] ) ) {
+                       $params['ucuserids'] = implode( '|', array_map( 'User::idFromName', $params['ucuserids'] ) );
+               }
+               if ( isset( $params['ucuser'] ) ) {
+                       $params['ucuser'] = implode( '|', $params['ucuser'] );
+               }
+
+               $sort = 'rsort';
+               if ( $reverse ) {
+                       $params['ucdir'] = 'newer';
+                       $sort = 'sort';
+               }
+
+               $params += [
+                       'action' => 'query',
+                       'list' => 'usercontribs',
+                       'ucprop' => 'ids',
+               ];
+
+               $apiResult = $this->doApiRequest( $params + [ 'uclimit' => 500 ] );
+               $this->assertArrayNotHasKey( 'continue', $apiResult[0] );
+               $this->assertArrayHasKey( 'query', $apiResult[0] );
+               $this->assertArrayHasKey( 'usercontribs', $apiResult[0]['query'] );
+
+               $count = 0;
+               $ids = [];
+               foreach ( $apiResult[0]['query']['usercontribs'] as $page ) {
+                       $count++;
+                       $ids[$page['user']][] = $page['revid'];
+               }
+               $this->assertSame( $revs, $count, 'Expected number of revisions' );
+               foreach ( $ids as $user => $revids ) {
+                       $sorted = $revids;
+                       call_user_func_array( $sort, [ &$sorted ] );
+                       $this->assertSame( $sorted, $revids, "IDs for $user are sorted" );
+               }
+
+               for ( $limit = 1; $limit < $revs; $limit++ ) {
+                       $continue = [];
+                       $count = 0;
+                       $batchedIds = [];
+                       while ( $continue !== null ) {
+                               $apiResult = $this->doApiRequest( $params + [ 'uclimit' => $limit ] + $continue );
+                               $this->assertArrayHasKey( 'query', $apiResult[0], "Batching with limit $limit" );
+                               $this->assertArrayHasKey( 'usercontribs', $apiResult[0]['query'],
+                                       "Batching with limit $limit" );
+                               $continue = isset( $apiResult[0]['continue'] ) ? $apiResult[0]['continue'] : null;
+                               foreach ( $apiResult[0]['query']['usercontribs'] as $page ) {
+                                       $count++;
+                                       $batchedIds[$page['user']][] = $page['revid'];
+                               }
+                               $this->assertLessThanOrEqual( $revs, $count, "Batching with limit $limit" );
+                       }
+                       $this->assertSame( $ids, $batchedIds, "Result set is the same when batching with limit $limit" );
+               }
+       }
+
+       public static function provideSorting() {
+               $users = [ __CLASS__ . ' A', __CLASS__ . ' B', __CLASS__ . ' C' ];
+               $users2 = [ __CLASS__ . ' A', __CLASS__ . ' B', __CLASS__ . ' D' ];
+               $ips = [ '192.168.2.1', '192.168.2.2', '192.168.2.3', '192.168.2.4' ];
+
+               foreach (
+                       [
+                               'old' => MIGRATION_OLD,
+                               'write both' => MIGRATION_WRITE_BOTH,
+                               'write new' => MIGRATION_WRITE_NEW,
+                               'new' => MIGRATION_NEW,
+                       ] as $stageName => $stage
+               ) {
+                       foreach ( [ false, true ] as $reverse ) {
+                               $name = $stageName . ( $reverse ? ', reverse' : '' );
+                               yield "Named users, $name" => [ $stage, [ 'ucuser' => $users ], $reverse, 9 ];
+                               yield "Named users including a no-edit user, $name" => [
+                                       $stage, [ 'ucuser' => $users2 ], $reverse, 6
+                               ];
+                               yield "IP users, $name" => [ $stage, [ 'ucuser' => $ips ], $reverse, 9 ];
+                               yield "All users, $name" => [
+                                       $stage, [ 'ucuser' => array_merge( $users, $ips ) ], $reverse, 18
+                               ];
+                               yield "User IDs, $name" => [ $stage, [ 'ucuserids' => $users ], $reverse, 9 ];
+                               yield "Users by prefix, $name" => [ $stage, [ 'ucuserprefix' => __CLASS__ ], $reverse, 9 ];
+                               yield "IPs by prefix, $name" => [ $stage, [ 'ucuserprefix' => '192.168.2.' ], $reverse, 9 ];
+                       }
+               }
+       }
+
+       /**
+        * @dataProvider provideInterwikiUser
+        * @param int $stage One of the MIGRATION_* constants for $wgActorTableSchemaMigrationStage
+        */
+       public function testInterwikiUser( $stage ) {
+               $this->setMwGlobals( 'wgActorTableSchemaMigrationStage', $stage );
+               $this->overrideMwServices();
+
+               $params = [
+                       'action' => 'query',
+                       'list' => 'usercontribs',
+                       'ucuser' => 'IW>' . __CLASS__,
+                       'ucprop' => 'ids',
+                       'uclimit' => 'max',
+               ];
+
+               $apiResult = $this->doApiRequest( $params );
+               $this->assertArrayNotHasKey( 'continue', $apiResult[0] );
+               $this->assertArrayHasKey( 'query', $apiResult[0] );
+               $this->assertArrayHasKey( 'usercontribs', $apiResult[0]['query'] );
+
+               $count = 0;
+               $ids = [];
+               foreach ( $apiResult[0]['query']['usercontribs'] as $page ) {
+                       $count++;
+                       $this->assertSame( 'IW>' . __CLASS__, $page['user'], 'Correct user returned' );
+                       $ids[] = $page['revid'];
+               }
+               $this->assertSame( 3, $count, 'Expected number of revisions' );
+               $sorted = $ids;
+               rsort( $sorted );
+               $this->assertSame( $sorted, $ids, "IDs are sorted" );
+       }
+
+       public static function provideInterwikiUser() {
+               return [
+                       'old' => [ MIGRATION_OLD ],
+                       'write both' => [ MIGRATION_WRITE_BOTH ],
+                       'write new' => [ MIGRATION_WRITE_NEW ],
+                       'new' => [ MIGRATION_NEW ],
+               ];
+       }
+
+}
diff --git a/tests/phpunit/includes/api/query/ApiQueryUserContributionsTest.php b/tests/phpunit/includes/api/query/ApiQueryUserContributionsTest.php
deleted file mode 100644 (file)
index ca6a929..0000000
+++ /dev/null
@@ -1,194 +0,0 @@
-<?php
-
-/**
- * @group API
- * @group Database
- * @group medium
- * @covers ApiQueryContributions
- */
-class ApiQueryContributionsTest extends ApiTestCase {
-       public function addDBDataOnce() {
-               global $wgActorTableSchemaMigrationStage;
-
-               $reset = new \Wikimedia\ScopedCallback( function ( $v ) {
-                       global $wgActorTableSchemaMigrationStage;
-                       $wgActorTableSchemaMigrationStage = $v;
-                       $this->overrideMwServices();
-               }, [ $wgActorTableSchemaMigrationStage ] );
-               $wgActorTableSchemaMigrationStage = MIGRATION_WRITE_BOTH;
-               $this->overrideMwServices();
-
-               $users = [
-                       User::newFromName( '192.168.2.2', false ),
-                       User::newFromName( '192.168.2.1', false ),
-                       User::newFromName( '192.168.2.3', false ),
-                       User::createNew( __CLASS__ . ' B' ),
-                       User::createNew( __CLASS__ . ' A' ),
-                       User::createNew( __CLASS__ . ' C' ),
-                       User::newFromName( 'IW>' . __CLASS__, false ),
-               ];
-
-               $title = Title::newFromText( __CLASS__ );
-               $page = WikiPage::factory( $title );
-               for ( $i = 0; $i < 3; $i++ ) {
-                       foreach ( array_reverse( $users ) as $user ) {
-                               $status = $page->doEditContent(
-                                       ContentHandler::makeContent( "Test revision $user #$i", $title ), 'Test edit', 0, false, $user
-                               );
-                               if ( !$status->isOK() ) {
-                                       $this->fail( "Failed to edit $title: " . $status->getWikiText( false, false, 'en' ) );
-                               }
-                       }
-               }
-       }
-
-       /**
-        * @dataProvider provideSorting
-        * @param int $stage One of the MIGRATION_* constants for $wgActorTableSchemaMigrationStage
-        * @param array $params Extra parameters for the query
-        * @param bool $reverse Reverse order?
-        * @param int $revs Number of revisions to expect
-        */
-       public function testSorting( $stage, $params, $reverse, $revs ) {
-               if ( isset( $params['ucuserprefix'] ) &&
-                       ( $stage === MIGRATION_WRITE_BOTH || $stage === MIGRATION_WRITE_NEW ) &&
-                       $this->db->getType() === 'mysql' && $this->usesTemporaryTables()
-               ) {
-                       // https://bugs.mysql.com/bug.php?id=10327
-                       $this->markTestSkipped( 'MySQL bug 10327 - can\'t reopen temporary tables' );
-               }
-
-               $this->setMwGlobals( 'wgActorTableSchemaMigrationStage', $stage );
-               $this->overrideMwServices();
-
-               if ( isset( $params['ucuserids'] ) ) {
-                       $params['ucuserids'] = implode( '|', array_map( 'User::idFromName', $params['ucuserids'] ) );
-               }
-               if ( isset( $params['ucuser'] ) ) {
-                       $params['ucuser'] = implode( '|', $params['ucuser'] );
-               }
-
-               $sort = 'rsort';
-               if ( $reverse ) {
-                       $params['ucdir'] = 'newer';
-                       $sort = 'sort';
-               }
-
-               $params += [
-                       'action' => 'query',
-                       'list' => 'usercontribs',
-                       'ucprop' => 'ids',
-               ];
-
-               $apiResult = $this->doApiRequest( $params + [ 'uclimit' => 500 ] );
-               $this->assertArrayNotHasKey( 'continue', $apiResult[0] );
-               $this->assertArrayHasKey( 'query', $apiResult[0] );
-               $this->assertArrayHasKey( 'usercontribs', $apiResult[0]['query'] );
-
-               $count = 0;
-               $ids = [];
-               foreach ( $apiResult[0]['query']['usercontribs'] as $page ) {
-                       $count++;
-                       $ids[$page['user']][] = $page['revid'];
-               }
-               $this->assertSame( $revs, $count, 'Expected number of revisions' );
-               foreach ( $ids as $user => $revids ) {
-                       $sorted = $revids;
-                       call_user_func_array( $sort, [ &$sorted ] );
-                       $this->assertSame( $sorted, $revids, "IDs for $user are sorted" );
-               }
-
-               for ( $limit = 1; $limit < $revs; $limit++ ) {
-                       $continue = [];
-                       $count = 0;
-                       $batchedIds = [];
-                       while ( $continue !== null ) {
-                               $apiResult = $this->doApiRequest( $params + [ 'uclimit' => $limit ] + $continue );
-                               $this->assertArrayHasKey( 'query', $apiResult[0], "Batching with limit $limit" );
-                               $this->assertArrayHasKey( 'usercontribs', $apiResult[0]['query'],
-                                       "Batching with limit $limit" );
-                               $continue = isset( $apiResult[0]['continue'] ) ? $apiResult[0]['continue'] : null;
-                               foreach ( $apiResult[0]['query']['usercontribs'] as $page ) {
-                                       $count++;
-                                       $batchedIds[$page['user']][] = $page['revid'];
-                               }
-                               $this->assertLessThanOrEqual( $revs, $count, "Batching with limit $limit" );
-                       }
-                       $this->assertSame( $ids, $batchedIds, "Result set is the same when batching with limit $limit" );
-               }
-       }
-
-       public static function provideSorting() {
-               $users = [ __CLASS__ . ' A', __CLASS__ . ' B', __CLASS__ . ' C' ];
-               $users2 = [ __CLASS__ . ' A', __CLASS__ . ' B', __CLASS__ . ' D' ];
-               $ips = [ '192.168.2.1', '192.168.2.2', '192.168.2.3', '192.168.2.4' ];
-
-               foreach (
-                       [
-                               'old' => MIGRATION_OLD,
-                               'write both' => MIGRATION_WRITE_BOTH,
-                               'write new' => MIGRATION_WRITE_NEW,
-                               'new' => MIGRATION_NEW,
-                       ] as $stageName => $stage
-               ) {
-                       foreach ( [ false, true ] as $reverse ) {
-                               $name = $stageName . ( $reverse ? ', reverse' : '' );
-                               yield "Named users, $name" => [ $stage, [ 'ucuser' => $users ], $reverse, 9 ];
-                               yield "Named users including a no-edit user, $name" => [
-                                       $stage, [ 'ucuser' => $users2 ], $reverse, 6
-                               ];
-                               yield "IP users, $name" => [ $stage, [ 'ucuser' => $ips ], $reverse, 9 ];
-                               yield "All users, $name" => [
-                                       $stage, [ 'ucuser' => array_merge( $users, $ips ) ], $reverse, 18
-                               ];
-                               yield "User IDs, $name" => [ $stage, [ 'ucuserids' => $users ], $reverse, 9 ];
-                               yield "Users by prefix, $name" => [ $stage, [ 'ucuserprefix' => __CLASS__ ], $reverse, 9 ];
-                               yield "IPs by prefix, $name" => [ $stage, [ 'ucuserprefix' => '192.168.2.' ], $reverse, 9 ];
-                       }
-               }
-       }
-
-       /**
-        * @dataProvider provideInterwikiUser
-        * @param int $stage One of the MIGRATION_* constants for $wgActorTableSchemaMigrationStage
-        */
-       public function testInterwikiUser( $stage ) {
-               $this->setMwGlobals( 'wgActorTableSchemaMigrationStage', $stage );
-               $this->overrideMwServices();
-
-               $params = [
-                       'action' => 'query',
-                       'list' => 'usercontribs',
-                       'ucuser' => 'IW>' . __CLASS__,
-                       'ucprop' => 'ids',
-                       'uclimit' => 'max',
-               ];
-
-               $apiResult = $this->doApiRequest( $params );
-               $this->assertArrayNotHasKey( 'continue', $apiResult[0] );
-               $this->assertArrayHasKey( 'query', $apiResult[0] );
-               $this->assertArrayHasKey( 'usercontribs', $apiResult[0]['query'] );
-
-               $count = 0;
-               $ids = [];
-               foreach ( $apiResult[0]['query']['usercontribs'] as $page ) {
-                       $count++;
-                       $this->assertSame( 'IW>' . __CLASS__, $page['user'], 'Correct user returned' );
-                       $ids[] = $page['revid'];
-               }
-               $this->assertSame( 3, $count, 'Expected number of revisions' );
-               $sorted = $ids;
-               rsort( $sorted );
-               $this->assertSame( $sorted, $ids, "IDs are sorted" );
-       }
-
-       public static function provideInterwikiUser() {
-               return [
-                       'old' => [ MIGRATION_OLD ],
-                       'write both' => [ MIGRATION_WRITE_BOTH ],
-                       'write new' => [ MIGRATION_WRITE_NEW ],
-                       'new' => [ MIGRATION_NEW ],
-               ];
-       }
-
-}
index f963ad9..12e8a49 100644 (file)
@@ -199,7 +199,7 @@ class ThrottlerTest extends \MediaWikiTestCase {
                $logger->expects( $this->once() )->method( 'log' )->with( $this->anything(), $this->anything(), [
                        'throttle' => 'custom',
                        'index' => 0,
-                       'ip' => '1.2.3.4',
+                       'ipKey' => '1.2.3.4',
                        'username' => 'SomeUser',
                        'count' => 1,
                        'expiry' => 10,
index b434396..84c0c1c 100644 (file)
@@ -1893,15 +1893,31 @@ class DatabaseSQLTest extends PHPUnit\Framework\TestCase {
 
                $this->database->setFlag( Database::DBO_TRX );
 
-               // Implicit transaction gets silently rolled back
+               // Implicit transaction does not get silently rolled back
                $this->database->begin( __METHOD__, Database::TRANSACTION_INTERNAL );
                call_user_func( $doError );
-               $this->database->delete( 'x', [ 'field' => 1 ], __METHOD__ );
-               $this->database->commit( __METHOD__, Database::FLUSHING_INTERNAL );
-               // phpcs:ignore
-               $this->assertLastSql( 'BEGIN; DELETE FROM error WHERE 1; ROLLBACK; BEGIN; DELETE FROM x WHERE field = \'1\'; COMMIT' );
+               try {
+                       $this->database->delete( 'x', [ 'field' => 1 ], __METHOD__ );
+                       $this->fail( 'Expected exception not thrown' );
+               } catch ( DBTransactionError $e ) {
+                       $this->assertEquals(
+                               'Cannot execute query from ' . __METHOD__ . ' while transaction status is ERROR.',
+                               $e->getMessage()
+                       );
+               }
+               try {
+                       $this->database->commit( __METHOD__, Database::FLUSHING_INTERNAL );
+                       $this->fail( 'Expected exception not thrown' );
+               } catch ( DBTransactionError $e ) {
+                       $this->assertEquals(
+                               'Cannot execute query from ' . __METHOD__ . ' while transaction status is ERROR.',
+                               $e->getMessage()
+                       );
+               }
+               $this->database->rollback( __METHOD__, Database::FLUSHING_INTERNAL );
+               $this->assertLastSql( 'BEGIN; DELETE FROM error WHERE 1; ROLLBACK' );
 
-               // ... unless there were prior writes
+               // Likewise if there were prior writes
                $this->database->begin( __METHOD__, Database::TRANSACTION_INTERNAL );
                $this->database->delete( 'x', [ 'field' => 1 ], __METHOD__ );
                call_user_func( $doError );
index 62ab44c..9a8608f 100644 (file)
@@ -66,7 +66,7 @@ class DefaultPreferencesFactoryTest extends MediaWikiTestCase {
        public function testGetForm() {
                $testUser = $this->getTestUser();
                $form = $this->getPreferencesFactory()->getForm( $testUser->getUser(), $this->context );
-               $this->assertInstanceOf( PreferencesForm::class, $form );
+               $this->assertInstanceOf( PreferencesFormLegacy::class, $form );
                $this->assertCount( 5, $form->getPreferenceSections() );
        }
 
index 67bc088..a372c8c 100644 (file)
@@ -51,6 +51,26 @@ class ExtensionRegistryTest extends MediaWikiTestCase {
                $registry->loadFromQueue();
        }
 
+       public function testLoadFromQueue() {
+               $registry = new ExtensionRegistry();
+               $registry->queue( "{$this->dataDir}/good.json" );
+               $registry->loadFromQueue();
+               $this->assertArrayHasKey( 'FooBar', $registry->getAllThings() );
+               $this->assertTrue( $registry->isLoaded( 'FooBar' ) );
+               $this->assertSame( [ 'test' ], $registry->getAttribute( 'FooBarAttr' ) );
+               $this->assertSame( [], $registry->getAttribute( 'NotLoadedAttr' ) );
+       }
+
+       /**
+        * @expectedException PHPUnit_Framework_Error
+        */
+       public function testReadFromQueue_nonexistent() {
+               $registry = new ExtensionRegistry();
+               $registry->readFromQueue( [
+                       __DIR__ . '/doesnotexist.json' => 1
+               ] );
+       }
+
        /**
         * @dataProvider provideExportExtractedDataGlobals
         */
index 95006aa..c15eb2c 100644 (file)
@@ -8,7 +8,6 @@ class ResourceLoaderTest extends ResourceLoaderTestCase {
                parent::setUp();
 
                $this->setMwGlobals( [
-                       'wgResourceLoaderLESSImportPaths' => [],
                        'wgResourceLoaderLESSVars' => [
                                'foo'  => '2px',
                                'Foo' => '#eeeeee',
@@ -267,7 +266,7 @@ class ResourceLoaderTest extends ResourceLoaderTestCase {
         */
        public function testLessImportDirs() {
                $rl = new EmptyResourceLoader();
-               $lc = $rl->getLessCompiler();
+               $lc = $rl->getLessCompiler( $rl->getLessVars() );
                $basePath = dirname( dirname( __DIR__ ) ) . '/data/less';
                $lc->SetImportDirs( [
                         "$basePath/common" => '',
@@ -596,11 +595,11 @@ mw.example();
                }
        }
 
-       protected function getFailFerryMock() {
+       protected function getFailFerryMock( $getter = 'getScript' ) {
                $mock = $this->getMockBuilder( ResourceLoaderTestModule::class )
-                       ->setMethods( [ 'getScript' ] )
+                       ->setMethods( [ $getter ] )
                        ->getMock();
-               $mock->method( 'getScript' )->will( $this->throwException(
+               $mock->method( $getter )->will( $this->throwException(
                        new Exception( 'Ferry not found' )
                ) );
                return $mock;
@@ -614,6 +613,14 @@ mw.example();
                return $mock;
        }
 
+       protected function getSimpleStyleModuleMock( $styles = '' ) {
+               $mock = $this->getMockBuilder( ResourceLoaderTestModule::class )
+                       ->setMethods( [ 'getStyles' ] )
+                       ->getMock();
+               $mock->method( 'getStyles' )->willReturn( [ '' => $styles ] );
+               return $mock;
+       }
+
        /**
         * @covers ResourceLoader::getCombinedVersion
         */
@@ -729,6 +736,21 @@ mw.example();
                $this->assertEquals( $expected, $response, $message ?: 'Response' );
        }
 
+       /**
+        * @covers ResourceLoader::makeModuleResponse
+        */
+       public function testMakeModuleResponseEmpty() {
+               $rl = new EmptyResourceLoader();
+               $context = $this->getResourceLoaderContext(
+                       [ 'modules' => '', 'only' => 'scripts' ],
+                       $rl
+               );
+
+               $response = $rl->makeModuleResponse( $context, [] );
+               $this->assertSame( [], $rl->getErrors(), 'Errors' );
+               $this->assertRegExp( '/^\/\*.+no modules were requested.+\*\/$/ms', $response );
+       }
+
        /**
         * Verify that when building module content in a load.php response,
         * an exception from one module will not break script output from
@@ -770,6 +792,43 @@ mw.example();
                );
        }
 
+       /**
+        * Verify that exceptions in PHP for one module will not break others
+        * (stylesheet response).
+        *
+        * @covers ResourceLoader::makeModuleResponse
+        */
+       public function testMakeModuleResponseErrorCSS() {
+               $modules = [
+                       'foo' => self::getSimpleStyleModuleMock( '.foo{}' ),
+                       'ferry' => self::getFailFerryMock( 'getStyles' ),
+                       'bar' => self::getSimpleStyleModuleMock( '.bar{}' ),
+               ];
+               $rl = new EmptyResourceLoader();
+               $rl->register( $modules );
+               $context = $this->getResourceLoaderContext(
+                       [
+                               'modules' => 'foo|ferry|bar',
+                               'only' => 'styles',
+                               'debug' => 'false',
+                       ],
+                       $rl
+               );
+
+               // Disable log from makeModuleResponse via outputErrorAndLog
+               $this->setLogger( 'exception', new Psr\Log\NullLogger() );
+
+               $response = $rl->makeModuleResponse( $context, $modules );
+               $errors = $rl->getErrors();
+
+               $this->assertCount( 2, $errors );
+               $this->assertRegExp( '/Ferry not found/', $errors[0] );
+               $this->assertRegExp( '/Problem.+"ferry":\s*"error"/ms', $errors[1] );
+               $this->assertEquals(
+                       '.foo{}.bar{}',
+                       $response
+               );
+       }
        /**
         * Verify that when building the startup module response,
         * an exception from one module class will not break the entire
@@ -903,7 +962,7 @@ mw.example();
        /**
         * @covers ResourceLoader::respond
         */
-       public function testRespond() {
+       public function testRespondEmpty() {
                $rl = $this->getMockBuilder( EmptyResourceLoader::class )
                        ->setMethods( [
                                'tryRespondNotModified',
@@ -919,6 +978,66 @@ mw.example();
                $rl->respond( $context );
        }
 
+       /**
+        * @covers ResourceLoader::respond
+        */
+       public function testRespondSimple() {
+               $module = new ResourceLoaderTestModule( [ 'script' => 'foo();' ] );
+               $rl = $this->getMockBuilder( EmptyResourceLoader::class )
+                       ->setMethods( [
+                               'measureResponseTime',
+                               'tryRespondNotModified',
+                               'sendResponseHeaders',
+                               'makeModuleResponse',
+                       ] )
+                       ->getMock();
+               $rl->register( 'test', $module );
+               $context = $this->getResourceLoaderContext(
+                       [ 'modules' => 'test', 'only' => null ],
+                       $rl
+               );
+
+               $rl->expects( $this->once() )->method( 'makeModuleResponse' )
+                       ->with( $context, [ 'test' => $module ] )
+                       ->willReturn( 'implement_foo;' );
+               $this->expectOutputRegex( '/^implement_foo;/' );
+
+               $rl->respond( $context );
+       }
+
+       /**
+        * @covers ResourceLoader::respond
+        */
+       public function testRespondInternalFailures() {
+               $module = new ResourceLoaderTestModule( [ 'script' => 'foo();' ] );
+               $rl = $this->getMockBuilder( EmptyResourceLoader::class )
+                       ->setMethods( [
+                               'measureResponseTime',
+                               'preloadModuleInfo',
+                               'getCombinedVersion',
+                               'tryRespondNotModified',
+                               'makeModuleResponse',
+                               'sendResponseHeaders',
+                       ] )
+                       ->getMock();
+               $rl->register( 'test', $module );
+               $context = $this->getResourceLoaderContext( [ 'modules' => 'test' ], $rl );
+               // Disable logging from outputErrorAndLog
+               $this->setLogger( 'exception', new Psr\Log\NullLogger() );
+
+               $rl->expects( $this->once() )->method( 'preloadModuleInfo' )
+                       ->willThrowException( new Exception( 'Preload error' ) );
+               $rl->expects( $this->once() )->method( 'getCombinedVersion' )
+                       ->willThrowException( new Exception( 'Version error' ) );
+               $rl->expects( $this->once() )->method( 'makeModuleResponse' )
+                       ->with( $context, [ 'test' => $module ] )
+                       ->willReturn( 'foo;' );
+               // Internal errors should be caught and logged without affecting module output
+               $this->expectOutputRegex( '/^\/\*.+Preload error.+Version error.+\*\/.*foo;/ms' );
+
+               $rl->respond( $context );
+       }
+
        /**
         * @covers ResourceLoader::measureResponseTime
         */
index e819d35..3eb6abd 100644 (file)
@@ -1199,4 +1199,113 @@ class UserTest extends MediaWikiTestCase {
                $this->assertFalse( $user->isBlockedFrom( $ut ) );
        }
 
+       /**
+        * Block cookie should be set for IP Blocks if
+        * wgCookieSetOnIpBlock is set to true
+        */
+       public function testIpBlockCookieSet() {
+               $this->setMwGlobals( [
+                       'wgCookieSetOnIpBlock' => true,
+                       'wgCookiePrefix' => 'wiki',
+                       'wgSecretKey' => MWCryptRand::generateHex( 64, true ),
+               ] );
+
+               // setup block
+               $block = new Block( [
+                       'expiry' => wfTimestamp( TS_MW, wfTimestamp() + ( 5 * 60 * 60 ) ),
+               ] );
+               $block->setTarget( '1.2.3.4' );
+               $block->setBlocker( $this->getTestSysop()->getUser() );
+               $block->insert();
+
+               // setup request
+               $request = new FauxRequest();
+               $request->setIP( '1.2.3.4' );
+
+               // get user
+               $user = User::newFromSession( $request );
+               $user->trackBlockWithCookie();
+
+               // test cookie was set
+               $cookies = $request->response()->getCookies();
+               $this->assertArrayHasKey( 'wikiBlockID', $cookies );
+
+               // clean up
+               $block->delete();
+       }
+
+       /**
+        * Block cookie should NOT be set when wgCookieSetOnIpBlock
+        * is disabled
+        */
+       public function testIpBlockCookieNotSet() {
+               $this->setMwGlobals( [
+                       'wgCookieSetOnIpBlock' => false,
+                       'wgCookiePrefix' => 'wiki',
+                       'wgSecretKey' => MWCryptRand::generateHex( 64, true ),
+               ] );
+
+               // setup block
+               $block = new Block( [
+                       'expiry' => wfTimestamp( TS_MW, wfTimestamp() + ( 5 * 60 * 60 ) ),
+               ] );
+               $block->setTarget( '1.2.3.4' );
+               $block->setBlocker( $this->getTestSysop()->getUser() );
+               $block->insert();
+
+               // setup request
+               $request = new FauxRequest();
+               $request->setIP( '1.2.3.4' );
+
+               // get user
+               $user = User::newFromSession( $request );
+               $user->trackBlockWithCookie();
+
+               // test cookie was not set
+               $cookies = $request->response()->getCookies();
+               $this->assertArrayNotHasKey( 'wikiBlockID', $cookies );
+
+               // clean up
+               $block->delete();
+       }
+
+       /**
+        * When an ip user is blocked and then they log in, cookie block
+        * should be invalid and the cookie removed.
+        */
+       public function testIpBlockCookieIgnoredWhenUserLoggedIn() {
+               $this->setMwGlobals( [
+                       'wgAutoblockExpiry' => 8000,
+                       'wgCookieSetOnIpBlock' => true,
+                       'wgCookiePrefix' => 'wiki',
+                       'wgSecretKey' => MWCryptRand::generateHex( 64, true ),
+               ] );
+
+               // setup block
+               $block = new Block( [
+                       'expiry' => wfTimestamp( TS_MW, wfTimestamp() + ( 40 * 60 * 60 ) ),
+               ] );
+               $block->setTarget( '1.2.3.4' );
+               $block->setBlocker( $this->getTestSysop()->getUser() );
+               $block->insert();
+
+               // setup request
+               $request = new FauxRequest();
+               $request->setIP( '1.2.3.4' );
+               $request->getSession()->setUser( $this->getTestUser()->getUser() );
+               $request->setCookie( 'BlockID', $block->getCookieValue() );
+
+               // setup user
+               $user = User::newFromSession( $request );
+
+               // logged in users should be inmune to cookie block of type ip/range
+               $this->assertFalse( $user->isBlocked() );
+
+               // cookie is being cleared
+               $cookies = $request->response()->getCookies();
+               $this->assertEquals( '', $cookies['wikiBlockID']['value'] );
+
+               // clean up
+               $block->delete();
+       }
 }
index cd68fa5..19e93de 100644 (file)
@@ -27,6 +27,7 @@ class DeleteAutoPatrolLogsTest extends MaintenanceBaseTestCase {
        }
 
        private function insertLoggingData() {
+               $dbw = wfGetDB( DB_MASTER );
                $logs = [];
 
                // Manual patrolling
@@ -35,7 +36,9 @@ class DeleteAutoPatrolLogsTest extends MaintenanceBaseTestCase {
                        'log_action' => 'patrol',
                        'log_user' => 7251,
                        'log_params' => '',
-                       'log_timestamp' => 20041223210426
+                       'log_timestamp' => $dbw->timestamp( '20041223210426' ),
+                       'log_namespace' => NS_MAIN,
+                       'log_title' => 'DeleteAutoPatrolLogs',
                ];
 
                // Autopatrol #1
@@ -44,7 +47,9 @@ class DeleteAutoPatrolLogsTest extends MaintenanceBaseTestCase {
                        'log_action' => 'autopatrol',
                        'log_user' => 7252,
                        'log_params' => '',
-                       'log_timestamp' => 20051223210426
+                       'log_timestamp' => $dbw->timestamp( '20051223210426' ),
+                       'log_namespace' => NS_MAIN,
+                       'log_title' => 'DeleteAutoPatrolLogs',
                ];
 
                // Block
@@ -53,7 +58,9 @@ class DeleteAutoPatrolLogsTest extends MaintenanceBaseTestCase {
                        'log_action' => 'block',
                        'log_user' => 7253,
                        'log_params' => '',
-                       'log_timestamp' => 20061223210426
+                       'log_timestamp' => $dbw->timestamp( '20061223210426' ),
+                       'log_namespace' => NS_MAIN,
+                       'log_title' => 'DeleteAutoPatrolLogs',
                ];
 
                // Very old/ invalid patrol
@@ -62,7 +69,9 @@ class DeleteAutoPatrolLogsTest extends MaintenanceBaseTestCase {
                        'log_action' => 'patrol',
                        'log_user' => 7253,
                        'log_params' => 'nanana',
-                       'log_timestamp' => 20061223210426
+                       'log_timestamp' => $dbw->timestamp( '20061223210426' ),
+                       'log_namespace' => NS_MAIN,
+                       'log_title' => 'DeleteAutoPatrolLogs',
                ];
 
                // Autopatrol #2
@@ -71,7 +80,9 @@ class DeleteAutoPatrolLogsTest extends MaintenanceBaseTestCase {
                        'log_action' => 'autopatrol',
                        'log_user' => 7254,
                        'log_params' => '',
-                       'log_timestamp' => 20071223210426
+                       'log_timestamp' => $dbw->timestamp( '20071223210426' ),
+                       'log_namespace' => NS_MAIN,
+                       'log_title' => 'DeleteAutoPatrolLogs',
                ];
 
                // Autopatrol #3 old way
@@ -80,7 +91,9 @@ class DeleteAutoPatrolLogsTest extends MaintenanceBaseTestCase {
                        'log_action' => 'patrol',
                        'log_user' => 7255,
                        'log_params' => serialize( [ '6::auto' => true ] ),
-                       'log_timestamp' => 20081223210426
+                       'log_timestamp' => $dbw->timestamp( '20081223210426' ),
+                       'log_namespace' => NS_MAIN,
+                       'log_title' => 'DeleteAutoPatrolLogs',
                ];
 
                // Manual patrol #2 old way
@@ -89,7 +102,9 @@ class DeleteAutoPatrolLogsTest extends MaintenanceBaseTestCase {
                        'log_action' => 'patrol',
                        'log_user' => 7256,
                        'log_params' => serialize( [ '6::auto' => false ] ),
-                       'log_timestamp' => 20091223210426
+                       'log_timestamp' => $dbw->timestamp( '20091223210426' ),
+                       'log_namespace' => NS_MAIN,
+                       'log_title' => 'DeleteAutoPatrolLogs',
                ];
 
                // Autopatrol #4 very old way
@@ -98,7 +113,9 @@ class DeleteAutoPatrolLogsTest extends MaintenanceBaseTestCase {
                        'log_action' => 'patrol',
                        'log_user' => 7257,
                        'log_params' => "9227851\n0\n1",
-                       'log_timestamp' => 20081223210426
+                       'log_timestamp' => $dbw->timestamp( '20081223210426' ),
+                       'log_namespace' => NS_MAIN,
+                       'log_title' => 'DeleteAutoPatrolLogs',
                ];
 
                // Manual patrol #3 very old way
@@ -107,10 +124,12 @@ class DeleteAutoPatrolLogsTest extends MaintenanceBaseTestCase {
                        'log_action' => 'patrol',
                        'log_user' => 7258,
                        'log_params' => "9227851\n0\n0",
-                       'log_timestamp' => 20091223210426
+                       'log_timestamp' => $dbw->timestamp( '20091223210426' ),
+                       'log_namespace' => NS_MAIN,
+                       'log_title' => 'DeleteAutoPatrolLogs',
                ];
 
-               wfGetDB( DB_MASTER )->insert( 'logging', $logs );
+               $dbw->insert( 'logging', $logs );
        }
 
        public function runProvider() {
diff --git a/tests/phpunit/structure/AutoLoaderStructureTest.php b/tests/phpunit/structure/AutoLoaderStructureTest.php
new file mode 100644 (file)
index 0000000..2800d02
--- /dev/null
@@ -0,0 +1,193 @@
+<?php
+
+/**
+ * @coversNothing
+ */
+class AutoLoaderStructureTest extends MediaWikiTestCase {
+       /**
+        * Assert that there were no classes loaded that are not registered with the AutoLoader.
+        *
+        * For example foo.php having class Foo and class Bar but only registering Foo.
+        * This is important because we should not be relying on Foo being used before Bar.
+        */
+       public function testAutoLoadConfig() {
+               $results = self::checkAutoLoadConf();
+
+               $this->assertEquals(
+                       $results['expected'],
+                       $results['actual']
+               );
+       }
+
+       public function providePSR4Completeness() {
+               foreach ( AutoLoader::$psr4Namespaces as $prefix => $dir ) {
+                       foreach ( $this->recurseFiles( $dir ) as $file ) {
+                               yield [ $prefix, $dir, $file ];
+                       }
+               }
+       }
+
+       private function recurseFiles( $dir ) {
+               return ( new File_Iterator_Facade() )->getFilesAsArray( $dir, [ '.php' ] );
+       }
+
+       /**
+        * @dataProvider providePSR4Completeness
+        */
+       public function testPSR4Completeness( $prefix, $dir, $file ) {
+               global $wgAutoloadLocalClasses, $wgAutoloadClasses;
+               $contents = file_get_contents( $file );
+               list( $classesInFile, $aliasesInFile ) = self::parseFile( $contents );
+               $classes = array_keys( $classesInFile );
+               if ( $classes ) {
+                       $this->assertCount( 1, $classes,
+                               "Only one class per file in PSR-4 autoloaded classes ($file)" );
+
+                       // Check that the expected class name (based on the filename) is the
+                       // same as the one we found.
+                       // Strip directory prefix from front of filename, and .php extension
+                       $abbrFileName = substr( substr( $file, strlen( $dir ) ), 0, -4 );
+                       $expectedClassName = $prefix . str_replace( '/', '\\', $abbrFileName );
+
+                       $this->assertSame(
+                               $expectedClassName,
+                               $classes[0],
+                               "Class not autoloaded properly"
+                       );
+
+               } else {
+                       // Dummy assertion so this test isn't marked in risky
+                       // if the file has no classes nor aliases in it
+                       $this->assertCount( 0, $classes );
+               }
+
+               if ( $aliasesInFile ) {
+                       $otherClasses = $wgAutoloadLocalClasses + $wgAutoloadClasses;
+                       foreach ( $aliasesInFile as $alias => $class ) {
+                               $this->assertArrayHasKey( $alias, $otherClasses,
+                                       'Alias must be in the classmap autoloader'
+                               );
+                       }
+               }
+       }
+
+       private static function parseFile( $contents ) {
+               // We could use token_get_all() here, but this is faster
+               // Note: Keep in sync with ClassCollector
+               $matches = [];
+               preg_match_all( '/
+                               ^ [\t ]* (?:
+                                       (?:final\s+)? (?:abstract\s+)? (?:class|interface|trait) \s+
+                                       (?P<class> [a-zA-Z0-9_]+)
+                               |
+                                       class_alias \s* \( \s*
+                                               ([\'"]) (?P<original> [^\'"]+) \g{-2} \s* , \s*
+                                               ([\'"]) (?P<alias> [^\'"]+ ) \g{-2} \s*
+                                       \) \s* ;
+                               |
+                                       class_alias \s* \( \s*
+                                               (?P<originalStatic> [a-zA-Z0-9_]+)::class \s* , \s*
+                                               ([\'"]) (?P<aliasString> [^\'"]+ ) \g{-2} \s*
+                                       \) \s* ;
+                               )
+                       /imx', $contents, $matches, PREG_SET_ORDER );
+
+               $namespaceMatch = [];
+               preg_match( '/
+                               ^ [\t ]*
+                                       namespace \s+
+                                               ([a-zA-Z0-9_]+(\\\\[a-zA-Z0-9_]+)*)
+                                       \s* ;
+                       /imx', $contents, $namespaceMatch );
+               $fileNamespace = $namespaceMatch ? $namespaceMatch[1] . '\\' : '';
+
+               $classesInFile = [];
+               $aliasesInFile = [];
+
+               foreach ( $matches as $match ) {
+                       if ( !empty( $match['class'] ) ) {
+                               // 'class Foo {}'
+                               $class = $fileNamespace . $match['class'];
+                               $classesInFile[$class] = true;
+                       } else {
+                               if ( !empty( $match['original'] ) ) {
+                                       // 'class_alias( "Foo", "Bar" );'
+                                       $aliasesInFile[$match['alias']] = $match['original'];
+                               } else {
+                                       // 'class_alias( Foo::class, "Bar" );'
+                                       $aliasesInFile[$match['aliasString']] = $fileNamespace . $match['originalStatic'];
+                               }
+                       }
+               }
+
+               return [ $classesInFile, $aliasesInFile ];
+       }
+
+       protected static function checkAutoLoadConf() {
+               global $wgAutoloadLocalClasses, $wgAutoloadClasses, $IP;
+
+               // wgAutoloadLocalClasses has precedence, just like in includes/AutoLoader.php
+               $expected = $wgAutoloadLocalClasses + $wgAutoloadClasses;
+               $actual = [];
+
+               $files = array_unique( $expected );
+
+               foreach ( $files as $class => $file ) {
+                       // Only prefix $IP if it doesn't have it already.
+                       // Generally local classes don't have it, and those from extensions and test suites do.
+                       if ( substr( $file, 0, 1 ) != '/' && substr( $file, 1, 1 ) != ':' ) {
+                               $filePath = "$IP/$file";
+                       } else {
+                               $filePath = $file;
+                       }
+
+                       if ( !file_exists( $filePath ) ) {
+                               $actual[$class] = "[file '$filePath' does not exist]";
+                               continue;
+                       }
+
+                       Wikimedia\suppressWarnings();
+                       $contents = file_get_contents( $filePath );
+                       Wikimedia\restoreWarnings();
+
+                       if ( $contents === false ) {
+                               $actual[$class] = "[couldn't read file '$filePath']";
+                               continue;
+                       }
+
+                       list( $classesInFile, $aliasesInFile ) = self::parseFile( $contents );
+
+                       foreach ( $classesInFile as $className => $ignore ) {
+                               $actual[$className] = $file;
+                       }
+
+                       // Only accept aliases for classes in the same file, because for correct
+                       // behavior, all aliases for a class must be set up when the class is loaded
+                       // (see <https://bugs.php.net/bug.php?id=61422>).
+                       foreach ( $aliasesInFile as $alias => $class ) {
+                               if ( isset( $classesInFile[$class] ) ) {
+                                       $actual[$alias] = $file;
+                               } else {
+                                       $actual[$alias] = "[original class not in $file]";
+                               }
+                       }
+               }
+
+               return [
+                       'expected' => $expected,
+                       'actual' => $actual,
+               ];
+       }
+
+       public function testAutoloadOrder() {
+               $path = realpath( __DIR__ . '/../../..' );
+               $oldAutoload = file_get_contents( $path . '/autoload.php' );
+               $generator = new AutoloadGenerator( $path, 'local' );
+               $generator->setExcludePaths( array_values( AutoLoader::getAutoloadNamespaces() ) );
+               $generator->initMediaWikiDefault();
+               $newAutoload = $generator->getAutoload( 'maintenance/generateLocalAutoload.php' );
+
+               $this->assertEquals( $oldAutoload, $newAutoload, 'autoload.php does not match' .
+                       ' output of generateLocalAutoload.php script.' );
+       }
+}
diff --git a/tests/phpunit/structure/AutoLoaderTest.php b/tests/phpunit/structure/AutoLoaderTest.php
deleted file mode 100644 (file)
index 217232e..0000000
+++ /dev/null
@@ -1,171 +0,0 @@
-<?php
-
-class AutoLoaderTest extends MediaWikiTestCase {
-       protected function setUp() {
-               parent::setUp();
-
-               // Fancy dance to trigger a rebuild of AutoLoader::$autoloadLocalClassesLower
-               $this->mergeMwGlobalArrayValue( 'wgAutoloadLocalClasses', [
-                       'TestAutoloadedLocalClass' =>
-                               __DIR__ . '/../data/autoloader/TestAutoloadedLocalClass.php',
-                       'TestAutoloadedCamlClass' =>
-                               __DIR__ . '/../data/autoloader/TestAutoloadedCamlClass.php',
-                       'TestAutoloadedSerializedClass' =>
-                               __DIR__ . '/../data/autoloader/TestAutoloadedSerializedClass.php',
-               ] );
-               AutoLoader::resetAutoloadLocalClassesLower();
-
-               $this->mergeMwGlobalArrayValue( 'wgAutoloadClasses', [
-                       'TestAutoloadedClass' => __DIR__ . '/../data/autoloader/TestAutoloadedClass.php',
-               ] );
-       }
-
-       /**
-        * Assert that there were no classes loaded that are not registered with the AutoLoader.
-        *
-        * For example foo.php having class Foo and class Bar but only registering Foo.
-        * This is important because we should not be relying on Foo being used before Bar.
-        */
-       public function testAutoLoadConfig() {
-               $results = self::checkAutoLoadConf();
-
-               $this->assertEquals(
-                       $results['expected'],
-                       $results['actual']
-               );
-       }
-
-       protected static function checkAutoLoadConf() {
-               global $wgAutoloadLocalClasses, $wgAutoloadClasses, $IP;
-
-               // wgAutoloadLocalClasses has precedence, just like in includes/AutoLoader.php
-               $expected = $wgAutoloadLocalClasses + $wgAutoloadClasses;
-               $actual = [];
-
-               $files = array_unique( $expected );
-
-               foreach ( $files as $class => $file ) {
-                       // Only prefix $IP if it doesn't have it already.
-                       // Generally local classes don't have it, and those from extensions and test suites do.
-                       if ( substr( $file, 0, 1 ) != '/' && substr( $file, 1, 1 ) != ':' ) {
-                               $filePath = "$IP/$file";
-                       } else {
-                               $filePath = $file;
-                       }
-
-                       if ( !file_exists( $filePath ) ) {
-                               $actual[$class] = "[file '$filePath' does not exist]";
-                               continue;
-                       }
-
-                       Wikimedia\suppressWarnings();
-                       $contents = file_get_contents( $filePath );
-                       Wikimedia\restoreWarnings();
-
-                       if ( $contents === false ) {
-                               $actual[$class] = "[couldn't read file '$filePath']";
-                               continue;
-                       }
-
-                       // We could use token_get_all() here, but this is faster
-                       // Note: Keep in sync with ClassCollector
-                       $matches = [];
-                       preg_match_all( '/
-                               ^ [\t ]* (?:
-                                       (?:final\s+)? (?:abstract\s+)? (?:class|interface|trait) \s+
-                                       (?P<class> [a-zA-Z0-9_]+)
-                               |
-                                       class_alias \s* \( \s*
-                                               ([\'"]) (?P<original> [^\'"]+) \g{-2} \s* , \s*
-                                               ([\'"]) (?P<alias> [^\'"]+ ) \g{-2} \s*
-                                       \) \s* ;
-                               |
-                                       class_alias \s* \( \s*
-                                               (?P<originalStatic> [a-zA-Z0-9_]+)::class \s* , \s*
-                                               ([\'"]) (?P<aliasString> [^\'"]+ ) \g{-2} \s*
-                                       \) \s* ;
-                               )
-                       /imx', $contents, $matches, PREG_SET_ORDER );
-
-                       $namespaceMatch = [];
-                       preg_match( '/
-                               ^ [\t ]*
-                                       namespace \s+
-                                               ([a-zA-Z0-9_]+(\\\\[a-zA-Z0-9_]+)*)
-                                       \s* ;
-                       /imx', $contents, $namespaceMatch );
-                       $fileNamespace = $namespaceMatch ? $namespaceMatch[1] . '\\' : '';
-
-                       $classesInFile = [];
-                       $aliasesInFile = [];
-
-                       foreach ( $matches as $match ) {
-                               if ( !empty( $match['class'] ) ) {
-                                       // 'class Foo {}'
-                                       $class = $fileNamespace . $match['class'];
-                                       $actual[$class] = $file;
-                                       $classesInFile[$class] = true;
-                               } else {
-                                       if ( !empty( $match['original'] ) ) {
-                                               // 'class_alias( "Foo", "Bar" );'
-                                               $aliasesInFile[$match['alias']] = $match['original'];
-                                       } else {
-                                               // 'class_alias( Foo::class, "Bar" );'
-                                               $aliasesInFile[$match['aliasString']] = $fileNamespace . $match['originalStatic'];
-                                       }
-                               }
-                       }
-
-                       // Only accept aliases for classes in the same file, because for correct
-                       // behavior, all aliases for a class must be set up when the class is loaded
-                       // (see <https://bugs.php.net/bug.php?id=61422>).
-                       foreach ( $aliasesInFile as $alias => $class ) {
-                               if ( isset( $classesInFile[$class] ) ) {
-                                       $actual[$alias] = $file;
-                               } else {
-                                       $actual[$alias] = "[original class not in $file]";
-                               }
-                       }
-               }
-
-               return [
-                       'expected' => $expected,
-                       'actual' => $actual,
-               ];
-       }
-
-       function testCoreClass() {
-               $this->assertTrue( class_exists( 'TestAutoloadedLocalClass' ) );
-       }
-
-       function testExtensionClass() {
-               $this->assertTrue( class_exists( 'TestAutoloadedClass' ) );
-       }
-
-       function testWrongCaseClass() {
-               $this->setMwGlobals( 'wgAutoloadAttemptLowercase', true );
-
-               $this->assertTrue( class_exists( 'testautoLoadedcamlCLASS' ) );
-       }
-
-       function testWrongCaseSerializedClass() {
-               $this->setMwGlobals( 'wgAutoloadAttemptLowercase', true );
-
-               $dummyCereal = 'O:29:"testautoloadedserializedclass":0:{}';
-               $uncerealized = unserialize( $dummyCereal );
-               $this->assertFalse( $uncerealized instanceof __PHP_Incomplete_Class,
-                       "unserialize() can load classes case-insensitively." );
-       }
-
-       function testAutoloadOrder() {
-               $path = realpath( __DIR__ . '/../../..' );
-               $oldAutoload = file_get_contents( $path . '/autoload.php' );
-               $generator = new AutoloadGenerator( $path, 'local' );
-               $generator->setExcludePaths( array_values( AutoLoader::getAutoloadNamespaces() ) );
-               $generator->initMediaWikiDefault();
-               $newAutoload = $generator->getAutoload( 'maintenance/generateLocalAutoload.php' );
-
-               $this->assertEquals( $oldAutoload, $newAutoload, 'autoload.php does not match' .
-                       ' output of generateLocalAutoload.php script.' );
-       }
-}
index 1922de5..1ec6f72 100644 (file)
@@ -95,6 +95,8 @@ return [
                        'tests/qunit/suites/resources/mediawiki.rcfilters/dm.SavedQueryItemModel.test.js',
                        'tests/qunit/suites/resources/mediawiki.rcfilters/dm.SavedQueriesModel.test.js',
                        'tests/qunit/suites/resources/mediawiki.rcfilters/UriProcessor.test.js',
+                       'tests/qunit/suites/resources/mediawiki.widgets/' .
+                               'MediaSearch/mediawiki.widgets.APIResultsQueue.test.js',
                        'tests/qunit/suites/resources/mediawiki/mediawiki.language.test.js',
                        'tests/qunit/suites/resources/mediawiki/mediawiki.cldr.test.js',
                        'tests/qunit/suites/resources/mediawiki/mediawiki.cookie.test.js',
@@ -137,6 +139,7 @@ return [
                        'mediawiki.experiments',
                        'mediawiki.inspect',
                        'mediawiki.visibleTimeout',
+                       'mediawiki.widgets.MediaSearch',
                        'test.mediawiki.qunit.testrunner',
                ],
        ]
diff --git a/tests/qunit/suites/resources/mediawiki.widgets/MediaSearch/mediawiki.widgets.APIResultsQueue.test.js b/tests/qunit/suites/resources/mediawiki.widgets/MediaSearch/mediawiki.widgets.APIResultsQueue.test.js
new file mode 100644 (file)
index 0000000..92970bb
--- /dev/null
@@ -0,0 +1,197 @@
+/*!
+ * VisualEditor DataModel ResourceQueue tests.
+ *
+ * @copyright 2011-2018 VisualEditor Team and others; see http://ve.mit-license.org
+ */
+
+QUnit.module( 'mediawiki.widgets.APIResultsQueue' );
+
+( function ( $, mw ) {
+       var itemCounter, FullResourceProvider, EmptyResourceProvider, SingleResultResourceProvider;
+
+       itemCounter = 0;
+       FullResourceProvider = function ( config ) {
+               this.timer = null;
+               this.responseDelay = 1;
+               // Inheritance
+               FullResourceProvider.super.call( this, '', config );
+       };
+       EmptyResourceProvider = function ( config ) {
+               this.timer = null;
+               this.responseDelay = 1;
+               // Inheritance
+               EmptyResourceProvider.super.call( this, '', config );
+       };
+       SingleResultResourceProvider = function ( config ) {
+               this.timer = null;
+               this.responseDelay = 1;
+               // Inheritance
+               SingleResultResourceProvider.super.call( this, '', config );
+       };
+
+       OO.inheritClass( FullResourceProvider, mw.widgets.APIResultsProvider );
+       OO.inheritClass( EmptyResourceProvider, mw.widgets.APIResultsProvider );
+       OO.inheritClass( SingleResultResourceProvider, mw.widgets.APIResultsProvider );
+
+       FullResourceProvider.prototype.getResults = function ( howMany ) {
+               var i, timer,
+                       result = [],
+                       deferred = $.Deferred();
+
+               for ( i = itemCounter; i < itemCounter + howMany; i++ ) {
+                       result.push( 'result ' + ( i + 1 ) );
+               }
+               itemCounter = i;
+
+               timer = setTimeout(
+                       function () {
+                               // Always resolve with some values
+                               deferred.resolve( result );
+                       },
+                       this.responseDelay );
+
+               return deferred.promise( { abort: function () { clearTimeout( timer ); } } );
+       };
+
+       EmptyResourceProvider.prototype.getResults = function () {
+               var provider = this,
+                       deferred = $.Deferred(),
+                       timer = setTimeout(
+                               function () {
+                                       provider.toggleDepleted( true );
+                                       // Always resolve with empty value
+                                       deferred.resolve( [] );
+                               },
+                               this.responseDelay );
+
+               return deferred.promise( { abort: function () { clearTimeout( timer ); } } );
+       };
+
+       SingleResultResourceProvider.prototype.getResults = function ( howMany ) {
+               var timer,
+                       provider = this,
+                       deferred = $.Deferred();
+
+               timer = setTimeout(
+                       function () {
+                               provider.toggleDepleted( howMany > 1 );
+                               // Always resolve with one value
+                               deferred.resolve( [ 'one result (' + ( itemCounter++ + 1 ) + ')' ] );
+                       },
+                       this.responseDelay );
+
+               return deferred.promise( { abort: function () { clearTimeout( timer ); } } );
+       };
+
+       /* Tests */
+
+       QUnit.test( 'Query providers', function ( assert ) {
+               var done = assert.async(),
+                       providers = [
+                               new FullResourceProvider(),
+                               new EmptyResourceProvider(),
+                               new SingleResultResourceProvider()
+                       ],
+                       queue = new mw.widgets.APIResultsQueue( {
+                               threshold: 2
+                       } );
+
+               assert.expect( 15 );
+
+               // Add providers to queue
+               queue.setProviders( providers );
+
+               // Set parameters and fetch
+               queue.setParams( { foo: 'bar' } );
+
+               queue.get( 10 )
+                       .then( function ( data ) {
+                               // Check that we received all requested results
+                               assert.equal( data.length, 10, 'Query 1: Results received.' );
+                               // We've asked for 10 items + 2 threshold from all providers.
+                               // Provider 1 returned 12 results
+                               // Provider 2 returned 0 results
+                               // Provider 3 returned 1 results
+                               // Overall 13 results. 10 were retrieved. 3 left in queue.
+                               assert.equal( queue.getQueueSize(), 3, 'Query 1: Remaining queue size.' );
+
+                               // Check if sources are depleted
+                               assert.ok( !providers[ 0 ].isDepleted(), 'Query 1: Full provider not depleted.' );
+                               assert.ok( providers[ 1 ].isDepleted(), 'Query 1: Empty provider is depleted.' );
+                               assert.ok( providers[ 2 ].isDepleted(), 'Query 1: Single result provider is depleted.' );
+
+                               // Ask for more results
+                               return queue.get( 10 );
+                       } )
+                       .then( function ( data1 ) {
+                               // This time, only provider 1 was queried, because the other
+                               // two were marked as depleted.
+                               // * We asked for 10 items
+                               // * There are currently 3 items in the queue
+                               // * The queue queried provider #1 for 12 items
+                               // * The queue returned 10 results as requested
+                               // * 5 results are now left in the queue.
+                               assert.equal( data1.length, 10, 'Query 1: Second set of results received.' );
+                               assert.equal( queue.getQueueSize(), 5, 'Query 1: Remaining queue size.' );
+
+                               // Change the query
+                               queue.setParams( { foo: 'baz' } );
+                               // Check if sources are depleted
+                               assert.ok( !providers[ 0 ].isDepleted(), 'Query 2: Full provider not depleted.' );
+                               assert.ok( !providers[ 1 ].isDepleted(), 'Query 2: Empty provider not depleted.' );
+                               assert.ok( !providers[ 2 ].isDepleted(), 'Query 2: Single result provider not depleted.' );
+
+                               return queue.get( 10 );
+                       } )
+                       .then( function ( data2 ) {
+                               // This should be the same as the very first result
+                               assert.equal( data2.length, 10, 'Query 2: Results received.' );
+                               assert.equal( queue.getQueueSize(), 3, 'Query 2: Remaining queue size.' );
+                               // Check if sources are depleted
+                               assert.ok( !providers[ 0 ].isDepleted(), 'Query 2: Full provider not depleted.' );
+                               assert.ok( providers[ 1 ].isDepleted(), 'Query 2: Empty provider is not depleted.' );
+                               assert.ok( providers[ 2 ].isDepleted(), 'Query 2: Single result provider is not depleted.' );
+                       } )
+                       // Finish the async test
+                       .then( done );
+       } );
+
+       QUnit.test( 'Abort providers', function ( assert ) {
+               var done = assert.async(),
+                       completed = false,
+                       biggerQueue = new mw.widgets.APIResultsQueue( {
+                               threshold: 5
+                       } ),
+                       providers = [
+                               new FullResourceProvider(),
+                               new EmptyResourceProvider(),
+                               new SingleResultResourceProvider()
+                       ];
+
+               assert.expect( 1 );
+
+               // Make the delay higher
+               providers.forEach( function ( provider ) { provider.responseDelay = 3; } );
+
+               // Add providers to queue
+               biggerQueue.setProviders( providers );
+
+               biggerQueue.setParams( { foo: 'bar' } );
+               biggerQueue.get( 100 )
+                       .always( function () {
+                               // This should only run if the promise wasn't aborted
+                               completed = true;
+                       } );
+
+               // Make the delay higher
+               providers.forEach( function ( provider ) { provider.responseDelay = 5; } );
+
+               biggerQueue.setParams( { foo: 'baz' } );
+               biggerQueue.get( 10 )
+                       .then( function () {
+                               assert.ok( !completed, 'Provider promises aborted.' );
+                       } )
+                       // Finish the async test
+                       .then( done );
+       } );
+}( jQuery, mediaWiki ) );