Merge "Remove skin mode of Special:JavaScriptTest"
authorjenkins-bot <jenkins-bot@gerrit.wikimedia.org>
Mon, 4 Apr 2016 15:24:12 +0000 (15:24 +0000)
committerGerrit Code Review <gerrit@wikimedia.org>
Mon, 4 Apr 2016 15:24:12 +0000 (15:24 +0000)
226 files changed:
RELEASE-NOTES-1.27
autoload.php
composer.json
docs/contenthandler.txt
docs/hooks.txt
docs/injection.txt [new file with mode: 0644]
includes/Collation.php [deleted file]
includes/DefaultSettings.php
includes/EditPage.php
includes/MediaWikiServices.php [new file with mode: 0644]
includes/Revision.php
includes/ServiceWiring.php [new file with mode: 0644]
includes/Services/ServiceContainer.php [new file with mode: 0644]
includes/Setup.php
includes/SiteStats.php
includes/StubObject.php
includes/Title.php
includes/WatchedItemStore.php
includes/WikiMap.php
includes/api/ApiMain.php
includes/api/ApiPageSet.php
includes/api/i18n/en.json
includes/api/i18n/gl.json
includes/api/i18n/he.json
includes/api/i18n/qqq.json
includes/api/i18n/ru.json
includes/cache/localisation/LCStoreCDB.php
includes/changes/EnhancedChangesList.php
includes/collation/Collation.php [new file with mode: 0644]
includes/collation/CollationCkb.php [new file with mode: 0644]
includes/collation/CollationEt.php [new file with mode: 0644]
includes/collation/IcuCollation.php [new file with mode: 0644]
includes/collation/IdentityCollation.php [new file with mode: 0644]
includes/collation/UppercaseCollation.php [new file with mode: 0644]
includes/config/ConfigFactory.php
includes/db/DatabaseMysqlBase.php
includes/db/loadbalancer/LoadBalancer.php
includes/diff/DifferenceEngine.php
includes/htmlform/HTMLAutoCompleteSelectField.php
includes/htmlform/HTMLButtonField.php
includes/htmlform/HTMLEditTools.php
includes/htmlform/HTMLForm.php
includes/htmlform/HTMLFormField.php
includes/htmlform/HTMLFormFieldCloner.php
includes/htmlform/HTMLSelectAndOtherField.php
includes/htmlform/HTMLTextAreaField.php
includes/htmlform/HTMLTextField.php
includes/installer/i18n/pl.json
includes/libs/BufferingStatsdDataFactory.php [deleted file]
includes/libs/Cookie.php
includes/libs/CookieJar.php [new file with mode: 0644]
includes/libs/StatusValue.php
includes/libs/eventrelayer/EventRelayer.php
includes/libs/eventrelayer/EventRelayerNull.php [new file with mode: 0644]
includes/libs/stats/BufferingStatsdDataFactory.php [new file with mode: 0644]
includes/libs/stats/NullStatsdDataFactory.php [new file with mode: 0644]
includes/libs/stats/StatsdAwareInterface.php [new file with mode: 0644]
includes/mail/UserMailer.php
includes/media/Bitmap.php
includes/media/WebP.php
includes/page/Article.php
includes/page/Page.php [new file with mode: 0644]
includes/page/WikiPage.php
includes/resourceloader/ResourceLoaderImage.php
includes/resourceloader/ResourceLoaderStartUpModule.php
includes/resourceloader/ResourceLoaderWikiModule.php
includes/search/SearchExactMatchRescorer.php
includes/session/Session.php
includes/site/DBSiteStore.php
includes/site/MediaWikiSite.php
includes/site/SiteSQLStore.php
includes/skins/Skin.php
includes/specialpage/SpecialPage.php
includes/specialpage/SpecialPageFactory.php
includes/specials/SpecialBotPasswords.php
includes/specials/SpecialFileDuplicateSearch.php
includes/specials/SpecialRedirect.php
includes/specials/SpecialStatistics.php
includes/specials/SpecialUserrights.php
includes/specials/pagers/BlockListPager.php
includes/upload/UploadBase.php
includes/user/User.php
includes/utils/AutoloadGenerator.php
includes/utils/ClassCollector.php [new file with mode: 0644]
languages/i18n/ba.json
languages/i18n/be-tarask.json
languages/i18n/be.json
languages/i18n/bn.json
languages/i18n/ca.json
languages/i18n/ckb.json
languages/i18n/cs.json
languages/i18n/de.json
languages/i18n/en.json
languages/i18n/es.json
languages/i18n/fi.json
languages/i18n/fr.json
languages/i18n/gl.json
languages/i18n/he.json
languages/i18n/hi.json
languages/i18n/hy.json
languages/i18n/inh.json
languages/i18n/it.json
languages/i18n/ja.json
languages/i18n/kk-cyrl.json
languages/i18n/la.json
languages/i18n/lb.json
languages/i18n/mai.json
languages/i18n/min.json
languages/i18n/nan.json
languages/i18n/pl.json
languages/i18n/qqq.json
languages/i18n/ro.json
languages/i18n/ru.json
languages/i18n/sl.json
languages/i18n/sr-ec.json
languages/i18n/ta.json
languages/i18n/tr.json
languages/i18n/uk.json
languages/i18n/vep.json
languages/i18n/war.json
languages/i18n/zh-hans.json
languages/messages/MessagesAf.php
languages/messages/MessagesAn.php
languages/messages/MessagesAr.php
languages/messages/MessagesArc.php
languages/messages/MessagesArz.php
languages/messages/MessagesAzb.php
languages/messages/MessagesBcl.php
languages/messages/MessagesBe.php
languages/messages/MessagesBg.php
languages/messages/MessagesBs.php
languages/messages/MessagesCe.php
languages/messages/MessagesCkb.php
languages/messages/MessagesCs.php
languages/messages/MessagesCy.php
languages/messages/MessagesDe.php
languages/messages/MessagesDiq.php
languages/messages/MessagesEl.php
languages/messages/MessagesEn.php
languages/messages/MessagesEo.php
languages/messages/MessagesEs.php
languages/messages/MessagesEt.php
languages/messages/MessagesFa.php
languages/messages/MessagesFi.php
languages/messages/MessagesFr.php
languages/messages/MessagesFrp.php
languages/messages/MessagesGa.php
languages/messages/MessagesGl.php
languages/messages/MessagesHe.php
languages/messages/MessagesHi.php
languages/messages/MessagesHr.php
languages/messages/MessagesHu.php
languages/messages/MessagesHy.php
languages/messages/MessagesId.php
languages/messages/MessagesIt.php
languages/messages/MessagesJa.php
languages/messages/MessagesKa.php
languages/messages/MessagesKm.php
languages/messages/MessagesKo.php
languages/messages/MessagesKsh.php
languages/messages/MessagesKw.php
languages/messages/MessagesLb.php
languages/messages/MessagesLt.php
languages/messages/MessagesMg.php
languages/messages/MessagesMhr.php
languages/messages/MessagesMk.php
languages/messages/MessagesMl.php
languages/messages/MessagesMr.php
languages/messages/MessagesMt.php
languages/messages/MessagesMyv.php
languages/messages/MessagesNds.php
languages/messages/MessagesNl.php
languages/messages/MessagesNn.php
languages/messages/MessagesOc.php
languages/messages/MessagesOr.php
languages/messages/MessagesOs.php
languages/messages/MessagesPl.php
languages/messages/MessagesPs.php
languages/messages/MessagesPt.php
languages/messages/MessagesQu.php
languages/messages/MessagesRm.php
languages/messages/MessagesRo.php
languages/messages/MessagesRu.php
languages/messages/MessagesSa.php
languages/messages/MessagesSe.php
languages/messages/MessagesSh.php
languages/messages/MessagesSk.php
languages/messages/MessagesSl.php
languages/messages/MessagesSq.php
languages/messages/MessagesSv.php
languages/messages/MessagesTr.php
languages/messages/MessagesUk.php
languages/messages/MessagesUr.php
languages/messages/MessagesVi.php
languages/messages/MessagesYi.php
maintenance/createAndPromote.php
maintenance/exportSites.php
maintenance/importSites.php
maintenance/mctest.php
maintenance/rebuildSitesCache.php
resources/Resources.php
resources/lib/jquery.ui/i18n/jquery.ui.datepicker-de-AT.js [new file with mode: 0644]
resources/lib/jquery.ui/i18n/jquery.ui.datepicker-de-CH.js [new file with mode: 0644]
resources/src/mediawiki/mediawiki.user.js
resources/src/mediawiki/mediawiki.util.js
tests/phpunit/includes/MediaWikiServicesTest.php [new file with mode: 0644]
tests/phpunit/includes/RevisionStorageTest.php
tests/phpunit/includes/RevisionTest.php
tests/phpunit/includes/Services/ServiceContainerTest.php [new file with mode: 0644]
tests/phpunit/includes/Services/TestWiring1.php [new file with mode: 0644]
tests/phpunit/includes/Services/TestWiring2.php [new file with mode: 0644]
tests/phpunit/includes/WatchedItemStoreUnitTest.php
tests/phpunit/includes/config/ConfigFactoryTest.php
tests/phpunit/includes/content/JavaScriptContentTest.php
tests/phpunit/includes/content/TextContentTest.php
tests/phpunit/includes/db/DatabaseMysqlBaseTest.php
tests/phpunit/includes/debug/logger/monolog/AvroFormatterTest.php
tests/phpunit/includes/page/WikiPageTest.php
tests/phpunit/includes/site/DBSiteStoreTest.php
tests/phpunit/includes/site/SiteSQLStoreTest.php [deleted file]
tests/phpunit/includes/site/TestSites.php
tests/phpunit/includes/specialpage/SpecialPageFactoryTest.php
tests/phpunit/includes/utils/UIDGeneratorTest.php
tests/qunit/suites/resources/mediawiki/mediawiki.Title.test.js
tests/qunit/suites/resources/mediawiki/mediawiki.user.test.js
tests/qunit/suites/resources/mediawiki/mediawiki.util.test.js

index 915b93b..b5dca93 100644 (file)
@@ -107,6 +107,8 @@ HHVM 3.1.
 * $wgIncludeLegacyJavaScript, deprecated in MediaWiki 1.26, now defaults false.
   Extensions, skins, gadgets and scripts that need the mediawiki.legacy.wikibits
   module should express a dependency on it.
+* Removed configuration option $wgCopyrightIcon (deprecated since 1.18). Use
+  $wgFooterIcons['copyright']['copyright'] instead.
 
 === New features in 1.27 ===
 * $wgDataCenterUpdateStickTTL was also added. This decides how long a user
@@ -249,16 +251,11 @@ HHVM 3.1.
 * ApiQuery::setGeneratorContinue() was removed (deprecated since 1.24).
 * ApiMain::getModules() was removed (deprecated since 1.21).
 * ApiBase::getVersion() was removed (deprecated since 1.21).
-* Language::getLangObj() was removed (deprecated since 1.24).
-* Language::getLanguageName() was removed (deprecated since 1.20).
-* Language::getLanguageNames() was removed (deprecated since 1.20).
-* Language::getTranslatedLanguageNames() was removed (deprecated since 1.20).
-* Language::specialPage() was removed (deprecated since 1.24).
-* MediaWikiTestCase::assertException() was removed (deprecated since 1.22).
-* OutputPage::getHeadItems() was removed (deprecated since 1.24).
-* OutputPage::getScript() was removed (deprecated since 1.24).
-* OutputPage::out() was removed (deprecated since 1.22).
-* OutputPage::setAllowedModules() was removed (deprecated since 1.24).
+* ApiMain::getShowVersions() was removed (deprecated in 1.21).
+* ApiMain::addModule() was removed (deprecated in 1.21).
+* ApiMain::addFormat() was removed (deprecated in 1.21).
+* ApiMain::getFormats() was removed (deprecated in 1.21).
+* ApiPageSet::finishPageSetGeneration() was removed (deprecated in 1.21).
 
 === Languages updated in 1.27 ===
 
@@ -267,8 +264,12 @@ regularly. Below only new and removed languages are listed, as well as
 changes to languages because of Phabricator reports.
 
 * (T113688) Change default numerals from Gurmukhi to Arabic for Punjabi locale.
+* (T116020) Aliases of magic words in MessagesXx.php are sorted by usage.
 
 === Other changes in 1.27 ===
+* Added dependency injection (DI) infrastructure, see docs/injection.txt for details.
+  It is planned to incrementally move MediaWiki code towards using DI, using the
+  service locator (SL) pattern as a stepping stone.
 * ProfilerOutputUdp was removed. Note that there is a ProfilerOutputStats class.
 * WikiPage::doDeleteArticleReal() and WikiPage::doDeleteArticle() now
   ignore the 2nd and 3rd arguments (formerly $id and $commit).
@@ -378,6 +379,34 @@ changes to languages because of Phabricator reports.
 * Unit tests don't work with external PHPUnit anymore, Composer is now the only supported
   way. Run `composer install` to install it and other dev dependencies to run unit tests.
 * wl_id field added to the watchlist table.
+* Revision::getRawText() was removed (deprecated since 1.21).
+* WikiPage::replaceSection() was removed (deprecated since 1.21).
+* Article::replaceSection() was removed (deprecated since 1.21).
+* Language::getLangObj() was removed (deprecated since 1.24).
+* Language::getLanguageName() was removed (deprecated since 1.20).
+* Language::getLanguageNames() was removed (deprecated since 1.20).
+* Language::getTranslatedLanguageNames() was removed (deprecated since 1.20).
+* Language::specialPage() was removed (deprecated since 1.24).
+* MediaWikiTestCase::assertException() was removed (deprecated since 1.22).
+* OutputPage::getHeadItems() was removed (deprecated since 1.24).
+* OutputPage::getScript() was removed (deprecated since 1.24).
+* OutputPage::out() was removed (deprecated since 1.22).
+* OutputPage::setAllowedModules() was removed (deprecated since 1.24).
+* UserrightsPage::makeGroupNameListForLog() was removed (deprecated since 1.21).
+* MediaWikiSite::newFromGlobalId() was removed (deprecated since 1.21).
+* Title::newFromRedirect() was removed (deprecated since 1.21).
+* Skin::commonPrintStylesheet() was removed (deprecated since 1.22).
+* Skin::getCommonStylePath() was removed (deprecated since 1.24).
+* Skin::newFromKey() was removed (deprecated since 1.24).
+* Skin::getUsableSkins() was removed (deprecated since 1.23).
+* LoadBalancer::pickRandom() was removed (deprecated in 1.21).
+* Article::getUndoText() and WikiPage::getUndoText were removed (deprecated since
+  1.21).
+* DifferenceEngine::setText() was removed (deprecated in 1.21).
+* Title::newFromRedirectArray() was removed (deprecated in 1.21).
+* UserMailer::send() no longer accepts $replyto as the 5th argument and $contentType
+  as the 6th. These must be passed in the options array now.
+* Title::newFromRedirectRecurse() was removed (deprecated in 1.21).
 
 == Compatibility ==
 
index a4c09e0..388dd0d 100644 (file)
@@ -185,7 +185,7 @@ $wgAutoloadLocalClasses = [
        'BmpHandler' => __DIR__ . '/includes/media/BMP.php',
        'BotPassword' => __DIR__ . '/includes/user/BotPassword.php',
        'BrokenRedirectsPage' => __DIR__ . '/includes/specials/SpecialBrokenRedirects.php',
-       'BufferingStatsdDataFactory' => __DIR__ . '/includes/libs/BufferingStatsdDataFactory.php',
+       'BufferingStatsdDataFactory' => __DIR__ . '/includes/libs/stats/BufferingStatsdDataFactory.php',
        'CLIParser' => __DIR__ . '/maintenance/parse.php',
        'CSSMin' => __DIR__ . '/includes/libs/CSSMin.php',
        'CacheDependency' => __DIR__ . '/includes/cache/CacheDependency.php',
@@ -230,7 +230,7 @@ $wgAutoloadLocalClasses = [
        'CheckSyntax' => __DIR__ . '/maintenance/checkSyntax.php',
        'CheckUsernames' => __DIR__ . '/maintenance/checkUsernames.php',
        'ChronologyProtector' => __DIR__ . '/includes/db/ChronologyProtector.php',
-       'ClassCollector' => __DIR__ . '/includes/utils/AutoloadGenerator.php',
+       'ClassCollector' => __DIR__ . '/includes/utils/ClassCollector.php',
        'CleanupAncientTables' => __DIR__ . '/maintenance/cleanupAncientTables.php',
        'CleanupBlocks' => __DIR__ . '/maintenance/cleanupBlocks.php',
        'CleanupPreferences' => __DIR__ . '/maintenance/cleanupPreferences.php',
@@ -240,9 +240,9 @@ $wgAutoloadLocalClasses = [
        'CliInstaller' => __DIR__ . '/includes/installer/CliInstaller.php',
        'CloneDatabase' => __DIR__ . '/includes/db/CloneDatabase.php',
        'CodeContentHandler' => __DIR__ . '/includes/content/CodeContentHandler.php',
-       'Collation' => __DIR__ . '/includes/Collation.php',
-       'CollationCkb' => __DIR__ . '/includes/Collation.php',
-       'CollationEt' => __DIR__ . '/includes/Collation.php',
+       'Collation' => __DIR__ . '/includes/collation/Collation.php',
+       'CollationCkb' => __DIR__ . '/includes/collation/CollationCkb.php',
+       'CollationEt' => __DIR__ . '/includes/collation/CollationEt.php',
        'CommandLineInc' => __DIR__ . '/maintenance/commandLine.inc',
        'CommandLineInstaller' => __DIR__ . '/maintenance/install.php',
        'CompareParserCache' => __DIR__ . '/maintenance/compareParserCache.php',
@@ -269,7 +269,7 @@ $wgAutoloadLocalClasses = [
        'ConvertUserOptions' => __DIR__ . '/maintenance/convertUserOptions.php',
        'ConverterRule' => __DIR__ . '/languages/ConverterRule.php',
        'Cookie' => __DIR__ . '/includes/libs/Cookie.php',
-       'CookieJar' => __DIR__ . '/includes/libs/Cookie.php',
+       'CookieJar' => __DIR__ . '/includes/libs/CookieJar.php',
        'CopyFileBackend' => __DIR__ . '/maintenance/copyFileBackend.php',
        'CopyFileOp' => __DIR__ . '/includes/filebackend/FileOp.php',
        'CopyJobQueue' => __DIR__ . '/maintenance/copyJobQueue.php',
@@ -398,7 +398,7 @@ $wgAutoloadLocalClasses = [
        'EventRelayer' => __DIR__ . '/includes/libs/eventrelayer/EventRelayer.php',
        'EventRelayerGroup' => __DIR__ . '/includes/EventRelayerGroup.php',
        'EventRelayerMCRD' => __DIR__ . '/includes/libs/eventrelayer/EventRelayerMCRD.php',
-       'EventRelayerNull' => __DIR__ . '/includes/libs/eventrelayer/EventRelayer.php',
+       'EventRelayerNull' => __DIR__ . '/includes/libs/eventrelayer/EventRelayerNull.php',
        'Exif' => __DIR__ . '/includes/media/Exif.php',
        'ExifBitmapHandler' => __DIR__ . '/includes/media/ExifBitmap.php',
        'ExplodeIterator' => __DIR__ . '/includes/libs/ExplodeIterator.php',
@@ -564,8 +564,8 @@ $wgAutoloadLocalClasses = [
        'IPSet' => __DIR__ . '/includes/compat/IPSetCompat.php',
        'IPTC' => __DIR__ . '/includes/media/IPTC.php',
        'IRCColourfulRCFeedFormatter' => __DIR__ . '/includes/rcfeed/IRCColourfulRCFeedFormatter.php',
-       'IcuCollation' => __DIR__ . '/includes/Collation.php',
-       'IdentityCollation' => __DIR__ . '/includes/Collation.php',
+       'IcuCollation' => __DIR__ . '/includes/collation/IcuCollation.php',
+       'IdentityCollation' => __DIR__ . '/includes/collation/IdentityCollation.php',
        'ImageBuilder' => __DIR__ . '/maintenance/rebuildImages.php',
        'ImageCleanup' => __DIR__ . '/maintenance/cleanupImages.php',
        'ImageGallery' => __DIR__ . '/includes/gallery/TraditionalImageGallery.php',
@@ -780,6 +780,7 @@ $wgAutoloadLocalClasses = [
        'MediaWikiSite' => __DIR__ . '/includes/site/MediaWikiSite.php',
        'MediaWikiTitleCodec' => __DIR__ . '/includes/title/MediaWikiTitleCodec.php',
        'MediaWikiVersionFetcher' => __DIR__ . '/includes/MediaWikiVersionFetcher.php',
+       'MediaWiki\\MediaWikiServices' => __DIR__ . '/includes/MediaWikiServices.php',
        'MediaWiki\\Languages\\Data\\Names' => __DIR__ . '/languages/data/Names.php',
        'MediaWiki\\Languages\\Data\\ZhConversion' => __DIR__ . '/languages/data/ZhConversion.php',
        'MediaWiki\\Logger\\LegacyLogger' => __DIR__ . '/includes/debug/logger/LegacyLogger.php',
@@ -796,6 +797,7 @@ $wgAutoloadLocalClasses = [
        'MediaWiki\\Logger\\Monolog\\WikiProcessor' => __DIR__ . '/includes/debug/logger/monolog/WikiProcessor.php',
        'MediaWiki\\Logger\\NullSpi' => __DIR__ . '/includes/debug/logger/NullSpi.php',
        'MediaWiki\\Logger\\Spi' => __DIR__ . '/includes/debug/logger/Spi.php',
+       'MediaWiki\\Services\\ServiceContainer' => __DIR__ . '/includes/Services/ServiceContainer.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',
@@ -893,6 +895,7 @@ $wgAutoloadLocalClasses = [
        'NullJob' => __DIR__ . '/includes/jobqueue/jobs/NullJob.php',
        'NullLockManager' => __DIR__ . '/includes/filebackend/lockmanager/LockManager.php',
        'NullRepo' => __DIR__ . '/includes/filerepo/NullRepo.php',
+       'NullStatsdDataFactory' => __DIR__ . '/includes/libs/stats/NullStatsdDataFactory.php',
        'OOUIHTMLForm' => __DIR__ . '/includes/htmlform/OOUIHTMLForm.php',
        'ORAField' => __DIR__ . '/includes/db/DatabaseOracle.php',
        'ORAResult' => __DIR__ . '/includes/db/DatabaseOracle.php',
@@ -934,7 +937,7 @@ $wgAutoloadLocalClasses = [
        'PackedHoverImageGallery' => __DIR__ . '/includes/gallery/PackedOverlayImageGallery.php',
        'PackedImageGallery' => __DIR__ . '/includes/gallery/PackedImageGallery.php',
        'PackedOverlayImageGallery' => __DIR__ . '/includes/gallery/PackedOverlayImageGallery.php',
-       'Page' => __DIR__ . '/includes/page/WikiPage.php',
+       'Page' => __DIR__ . '/includes/page/Page.php',
        'PageArchive' => __DIR__ . '/includes/specials/SpecialUndelete.php',
        'PageExists' => __DIR__ . '/maintenance/pageExists.php',
        'PageLangLogFormatter' => __DIR__ . '/includes/logging/PageLangLogFormatter.php',
@@ -1266,6 +1269,7 @@ $wgAutoloadLocalClasses = [
        'SquidPurgeClientPool' => __DIR__ . '/includes/clientpool/SquidPurgeClientPool.php',
        'SquidUpdate' => __DIR__ . '/includes/deferred/CdnCacheUpdate.php',
        'SrConverter' => __DIR__ . '/languages/classes/LanguageSr.php',
+       'StatsdAwareInterface' => __DIR__ . '/includes/libs/stats/StatsdAwareInterface.php',
        'StatsOutput' => __DIR__ . '/maintenance/language/StatOutputs.php',
        'Status' => __DIR__ . '/includes/Status.php',
        'StatusValue' => __DIR__ . '/includes/libs/StatusValue.php',
@@ -1371,7 +1375,7 @@ $wgAutoloadLocalClasses = [
        'UploadStashNotLoggedInException' => __DIR__ . '/includes/upload/UploadStash.php',
        'UploadStashWrongOwnerException' => __DIR__ . '/includes/upload/UploadStash.php',
        'UploadStashZeroLengthFileException' => __DIR__ . '/includes/upload/UploadStash.php',
-       'UppercaseCollation' => __DIR__ . '/includes/Collation.php',
+       'UppercaseCollation' => __DIR__ . '/includes/collation/UppercaseCollation.php',
        'UsageException' => __DIR__ . '/includes/api/ApiMain.php',
        'User' => __DIR__ . '/includes/user/User.php',
        'UserArray' => __DIR__ . '/includes/user/UserArray.php',
index e0667e2..56b27f8 100644 (file)
@@ -16,7 +16,7 @@
                "wiki": "https://www.mediawiki.org/"
        },
        "require": {
-               "composer/semver": "1.2.0",
+               "composer/semver": "1.4.0",
                "cssjanus/cssjanus": "1.1.2",
                "ext-iconv": "*",
                "liuggio/statsd-php-client": "1.0.18",
index f1f478e..6209b14 100644 (file)
@@ -96,7 +96,7 @@ used.
 
 Most importantly, the following functions have been deprecated:
 
-* Revisions::getText() and Revisions::getRawText() is deprecated in favor Revisions::getContent()
+* Revisions::getText() is deprecated in favor Revisions::getContent()
 * WikiPage::getText() is deprecated in favor WikiPage::getContent()
 
 Also, the old Article::getContent() (which returns text) is superceded by Article::getContentObject(). However, both
index 9478f48..31e9d92 100644 (file)
@@ -1997,6 +1997,11 @@ $user: $wgUser
 $request: $wgRequest
 $mediaWiki: The $mediawiki object
 
+'MediaWikiServices': Override services in the default MediaWikiServices instance.
+Extensions may use this to define, replace, or wrap existing services.
+However, the preferred way to define a new service is the $wgServiceWiringFiles array.
+$services: MediaWikiServices
+
 'MessageCache::get': When fetching a message. Can be used to override the key
 for customisations. Given and returned message key must be in special format:
 1) first letter must be in lower case according to the content language.
@@ -2855,6 +2860,7 @@ $special: the SpecialPage object
 $subPage: the subpage string or null if no subpage was specified
 
 'SpecialPageBeforeExecute': Called before SpecialPage::execute.
+Return false to prevent execution.
 $special: the SpecialPage object
 $subPage: the subpage string or null if no subpage was specified
 
diff --git a/docs/injection.txt b/docs/injection.txt
new file mode 100644 (file)
index 0000000..e0466c4
--- /dev/null
@@ -0,0 +1,248 @@
+injection.txt
+
+This is an overview of how MediaWiki makes use of dependency injection.
+The design described here grew from the discussion of RFC T384.
+
+
+The term "dependency injection" (DI) refers to a pattern on object oriented
+programming that tries to improve modularity by reducing strong coupling
+between classes. In practical terms, this means that anything an object needs
+to operate should be injected from the outside, the object itself should only
+know narrow interfaces, no concrete implementation of the logic it relies on.
+
+The requirement to inject everything typically results in an architecture that
+based on two main types of objects: simple value objects with no business logic
+(and often immutable), and essentially stateless service objects that use
+other service objects to operate on the value objects.
+
+As of the beginning of 2016 (MW version 1.27), MediaWiki is only starting to
+use the DI approach. Much of the code still relies on global state or direct
+instantiation, resulting in a highly cyclical dependency graph.
+
+
+== Overview ==
+The heart of the DI in MediaWiki is the central service locator,
+MediaWikiServices, which acts as the top level factory for services in
+MediaWiki. MediaWikiServices::getInstance() returns the default service
+locator instance, which can be used to gain access to default instances of
+various services. MediaWikiServices however also allows new services to be
+defined and default services to be redefined. Services are defined or
+redefined by providing a callback function, the "instantiator" function,
+that will return a new instance of the service.
+
+When MediaWikiServices::getInstance() is first called, it will create an
+instance of MediaWikiServices and populate it with the services defined
+in the files listed by $wgServiceWiringFiles, thereby "bootstrapping" the
+DI framework. Per default, $wgServiceWiringFiles lists
+includes/ServiceWiring.php, which defines all default service
+implementations, and specifies how they depend on each other ("wiring").
+
+When a new service is added to MediaWiki core, an instantiator function
+that will create the appropriate default instance for that service must
+be added to ServiceWiring.php. This makes the service available through
+the generic getService() method on the service locator returned by
+MediaWikiServices::getInstance().
+
+Extensions can add their own wiring files to $wgServiceWiringFiles, in order
+to define their own service. Extensions may also use the 'MediaWikiServices'
+hook to define or redefined services by calling methods on the default
+MediaWikiServices instance.
+
+
+It should be noted that the term "service locator" is often used to refer to a
+top level factory that is accessed directly, throughout the code, to avoid
+explicit dependency injection. In contrast, the term "DI container" is often
+used to describe a top level factory that is only accessed when services
+are created. We use the term "service locator" for the top level factory
+because it is more descriptive than "DI container", even though application
+logic is strongly discouraged from accessing MediaWikiServices directly.
+MediaWikiServices::getInstance() should ideally be accessed only in "static
+entry points" such as hook handler functions. See "Migration" below.
+
+
+== Configuration ==
+
+When the default MediaWikiServices instance is created, a Config object is
+provided to the constructor. This Config object represents the "bootstrap"
+configuration which will become available as the 'BootstrapConfig' service.
+As of MW 1.27, the bootstrap config is a GlobalVarConfig object providing
+access to the $wgXxx configuration variables.
+
+The bootstrap config is then used to construct a 'ConfigFactory' service,
+which in turn is used to construct the 'MainConfig' service. Application
+logic should use the 'MainConfig' service (or a more specific configuration
+object). 'BootstrapConfig' should only be used for bootstrapping basic
+services that are needed to load the 'MainConfig'.
+
+
+Note: Several well known services in MediaWiki core act as factories
+themselves, e.g. ApiModuleManager, ObjectCache, SpecialPageFactory, etc.
+The registries these factories are based on are currently managed as part of
+the configuration. This may however change in the future.
+
+
+== Migration ==
+
+This section provides some recipes for improving code modularity by reducing
+strong coupling. The dependency injection mechanism described above is an
+essential tool in this effort.
+
+Migrate access to global service instances and config variables:
+Assume Foo is a class that uses the $wgScriptPath global and calls
+wfGetDB() to get a database connection, in non-static methods.
+* Add $scriptPath as a constructor parameter and use $this->scriptPath
+  instead of $wgScriptPath.
+* Add LoadBalancer $dbLoadBalancer as a constructor parameter. Use
+  $this->dbLoadBalancer->getConnection() instead of wfGetDB().
+* Any code that calls Foo's constructor would now need to provide the
+  $scriptPath and $dbLoadBalancer. To avoid this, avoid direct instantiation
+  of services all together - see below.
+
+Migrate class-level singleton getters:
+Assume class Foo has mostly non-static methods, and provides a static
+getInstance() method that returns a singleton (or default instance).
+* Add an instantiator function for Foo into ServiceWiring.php. The instantiator
+  would do exactly what Foo::getInstance() did. However, it should
+  replace any access to global state with calls to $services->getXxx() to get a
+  service, or $services->getMainConfig()->get() to get a configuration setting.
+* Add a getFoo() method to MediaWikiServices. Don't forget to add the
+  appropriate test cases in MediaWikiServicesTest.
+* Turn Foo::getInstance() into a deprecated alias for
+  MediaWikiServices::getInstance()->getFoo(). Change all calls to
+  Foo::getInstance() to use injection (see above).
+
+Migrate direct service instantiation:
+Assume class Bar calls new Foo().
+* Add an instantiator function for Foo into ServiceWiring.php and add a getFoo()
+  method to MediaWikiServices. Don't forget to add the appropriate test cases
+  in MediaWikiServicesTest.
+* In the instantiator, replace any access to global state with calls
+  to $services->getXxx() to get a service, or $services->getMainConfig()->get()
+  to get a configuration setting.
+* The code in Bar that calls Foo's constructor should be changed to have a Foo
+  instance injected; Eventually, the only code that instantiates Foo is the
+  instantiator in ServiceWiring.php.
+* As an intermediate step, Bar's constructor could initialize the $foo member
+  variable by calling MediaWikiServices::getInstance()->getFoo(). This is
+  acceptable as a stepping stone, but should be replaced by proper injection
+  via a constructor argument. Do not however inject the MediaWikiServices
+  object!
+
+Migrate parameterized helper instantiation:
+Assume class Bar creates some helper object by calling new Foo( $x ),
+and Foo uses a global singleton of the Xyzzy service.
+* Define a FooFactory class (or a FooFactory interface along with a MyFooFactory
+  implementation). FooFactory defines the method newFoo( $x ) or getFoo( $x ),
+  depending on the desired semantics (newFoo would guarantee a fresh instance).
+  When Foo gets refactored to have Xyzzy injected, FooFactory will need a
+  Xyzzy instance, so newFoo() can pass it to new Foo().
+* Add an instantiator function for FooFactory into ServiceWiring.php and add a
+  getFooFactory() method to MediaWikiServices. Don't forget to add the
+  appropriate test cases in MediaWikiServicesTest.
+* The code in Bar that calls Foo's constructor should be changed to have a
+  FooFactory instance injected; Eventually, the only code that instantiates
+  Foo are implementations of FooFactory, and the only code that instantiates
+  FooFactory is the instantiator in ServiceWiring.php.
+* As an intermediate step, Bar's constructor could initialize the $fooFactory
+  member variable by calling MediaWikiServices::getInstance()->getFooFactory().
+  This is acceptable as a stepping stone, but should be replaced by proper
+  injection via a constructor argument. Do not however inject the
+  MediaWikiServices object!
+
+Migrate a handler registry:
+Assume class Bar calls FooRegistry::getFoo( $x ) to get a specialized Foo
+instance for handling $x.
+* Turn getFoo into a non-static method.
+* Add an instantiator function for FooRegistry into ServiceWiring.php and add
+  a getFooRegistry() method to MediaWikiServices. Don't forget to add the
+  appropriate test cases in MediaWikiServicesTest.
+* Change all code that calls FooRegistry::getFoo() statically to call this
+  method on a FooRegistry instance. That is, Bar would have a $fooRegistry
+  member, initialized from a constructor parameter.
+* As an intermediate step, Bar's constructor could initialize the $fooRegistry
+  member variable by calling MediaWikiServices::getInstance()->
+  getFooRegistry(). This is acceptable as a stepping stone, but should be
+  replaced by proper injection via a constructor argument. Do not however
+  inject the MediaWikiServices object!
+
+Migrate deferred service instantiation:
+Assume class Bar calls new Foo(), but only when needed, to avoid the cost of
+instantiating Foo().
+* Define a FooFactory interface and a MyFooFactory implementation of that
+  interface. FooFactory defines the method getFoo() with no parameters.
+* Precede as for the "parameterized helper instantiation" case described above.
+
+Migrate a class with only static methods:
+Assume Foo is a class with only static methods, such as frob(), which
+interacts with global state or system resources.
+* Introduce a FooService interface and a DefaultFoo implementation of that
+  interface. FooService contains the public methods defined by Foo.
+* Add an instantiator function for FooService into ServiceWiring.php and
+  add a getFooService() method to MediaWikiServices. Don't forget to
+  add the appropriate test cases in MediaWikiServicesTest.
+* Add a private static getFooService() method to Foo. That method just
+  calls MediaWikiServices::getInstance()->getFooService().
+* Make all methods in Foo delegate to the FooService returned by
+  getFooService(). That is, Foo::frob() would do self::getFooService()->frob().
+* Deprecate Foo. Inject a FooService into all code that calls methods
+  on Foo, and change any calls to static methods in foo to the methods
+  provided by the FooService interface.
+
+Migrate static hook handler functions (to allow unit testing):
+Assume MyExtHooks::onFoo is a static hook handler function that is called with
+the parameter $x; Further assume MyExt::onFoo needs service Bar, which is
+already known to MediaWikiServices (if not, see above).
+* Create a non-static doFoo( $x ) method in MyExtHooks that has the same
+  signature as onFoo( $x ). Move the code from onFoo() into doFoo(), replacing
+  any access to global or static variables with access to instance member
+  variables.
+* Add a constructor to MyExtHooks that takes a Bar service as a parameter.
+* Add a static method called newFromGlobalState() with no parameters. It should
+  just return new MyExtHooks( MediaWikiServices::getBar() ).
+* The original static handler method onFoo( $x ) is then implemented as
+  self::newFromGlobalState()->doFoo( $x ).
+
+Migrate a "smart record":
+Assume Thingy is a "smart record" that "knows" how to load and store itself.
+For this purpose, Thingy uses wfGetDB().
+* Create a "dumb" value class ThingyRecord that contains all the information
+  that Thingy represents (e.g. the information from a database row). The value
+  object should not know about any service.
+* Create a DAO-style service for loading and storing ThingyRecords, called
+  ThingyStore. It may be useful to split the interfaces for reading and
+  writing, with a single class implementing both interfaces, so we in the
+  end have the ThingyLookup and ThingyStore interfaces, and a SqlThingyStore
+  implementation.
+* Add instantiator functions for ThingyLookup and ThingyStore in
+  ServiceWiring.php. Since we want to use the same instance for both service
+  interfaces, the instantiator for ThingyLookup would return
+  $services->getThingyStore().
+* Add getThingyLookup() and getThingyStore methods to MediaWikiServices.
+  Don't forget to add the appropriate test cases in MediaWikiServicesTest.
+* In the old Thingy class, replace all member variables that represent the
+  record's data with a single ThingyRecord object.
+* In the old Thingy class, replace all calls to static methods or functions,
+  such as wfGetDB(), with calls to the appropriate services, such as
+  LoadBalancer::getConnection().
+* In Thingy's constructor, pull in any services needed, such as the
+  LoadBalancer, by using MediaWikiServices::getInstance(). These services
+  cannot be injected without changing the constructor signature, which
+  is often impractical for "smart records" that get instantiated directly
+  in many places in the code base.
+* Deprecate the old Thingy class. Replace all usages of it with one of the
+  three new classes: loading needs a ThingyLookup, storing needs a ThingyStore,
+  and reading data needs a ThingyRecord.
+
+Migrate lazy loading:
+Assume Thingy is a "smart record" as described above, but requires lazy loading
+of some or all the data it represents.
+* Instead of a plain object, define ThingyRecord to be an interface. Provide a
+  "simple" and "lazy" implementations, called SimpleThingyRecord and
+  LazyThingyRecord. LazyThingyRecord knows about some lower level storage
+  interface, like a LoadBalancer, and uses it to load information on demand.
+* Any direct instantiation of a ThingyRecord would use the SimpleThingyRecord
+  implementation.
+* SqlThingyStore however creates instances of LazyThingyRecord, and injects
+  whatever storage layer service LazyThingyRecord needs to perform lazy loading.
+
+
diff --git a/includes/Collation.php b/includes/Collation.php
deleted file mode 100644 (file)
index 7a3623d..0000000
+++ /dev/null
@@ -1,648 +0,0 @@
-<?php
-/**
- * Database row sorting.
- *
- * 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
- */
-
-abstract class Collation {
-       private static $instance;
-
-       /**
-        * @return Collation
-        */
-       static function singleton() {
-               if ( !self::$instance ) {
-                       global $wgCategoryCollation;
-                       self::$instance = self::factory( $wgCategoryCollation );
-               }
-               return self::$instance;
-       }
-
-       /**
-        * @throws MWException
-        * @param string $collationName
-        * @return Collation
-        */
-       static function factory( $collationName ) {
-               switch ( $collationName ) {
-                       case 'uppercase':
-                               return new UppercaseCollation;
-                       case 'identity':
-                               return new IdentityCollation;
-                       case 'uca-default':
-                               return new IcuCollation( 'root' );
-                       case 'xx-uca-ckb':
-                               return new CollationCkb;
-                       case 'xx-uca-et':
-                               return new CollationEt;
-                       default:
-                               $match = [];
-                               if ( preg_match( '/^uca-([a-z@=-]+)$/', $collationName, $match ) ) {
-                                       return new IcuCollation( $match[1] );
-                               }
-
-                               # Provide a mechanism for extensions to hook in.
-                               $collationObject = null;
-                               Hooks::run( 'Collation::factory', [ $collationName, &$collationObject ] );
-
-                               if ( $collationObject instanceof Collation ) {
-                                       return $collationObject;
-                               }
-
-                               // If all else fails...
-                               throw new MWException( __METHOD__ . ": unknown collation type \"$collationName\"" );
-               }
-       }
-
-       /**
-        * Given a string, convert it to a (hopefully short) key that can be used
-        * for efficient sorting.  A binary sort according to the sortkeys
-        * corresponds to a logical sort of the corresponding strings.  Current
-        * code expects that a line feed character should sort before all others, but
-        * has no other particular expectations (and that one can be changed if
-        * necessary).
-        *
-        * @param string $string UTF-8 string
-        * @return string Binary sortkey
-        */
-       abstract function getSortKey( $string );
-
-       /**
-        * Given a string, return the logical "first letter" to be used for
-        * grouping on category pages and so on.  This has to be coordinated
-        * carefully with convertToSortkey(), or else the sorted list might jump
-        * back and forth between the same "initial letters" or other pathological
-        * behavior.  For instance, if you just return the first character, but "a"
-        * sorts the same as "A" based on getSortKey(), then you might get a
-        * list like
-        *
-        * == A ==
-        * * [[Aardvark]]
-        *
-        * == a ==
-        * * [[antelope]]
-        *
-        * == A ==
-        * * [[Ape]]
-        *
-        * etc., assuming for the sake of argument that $wgCapitalLinks is false.
-        *
-        * @param string $string UTF-8 string
-        * @return string UTF-8 string corresponding to the first letter of input
-        */
-       abstract function getFirstLetter( $string );
-}
-
-class UppercaseCollation extends Collation {
-       private $lang;
-
-       function __construct() {
-               // Get a language object so that we can use the generic UTF-8 uppercase
-               // function there
-               $this->lang = Language::factory( 'en' );
-       }
-
-       function getSortKey( $string ) {
-               return $this->lang->uc( $string );
-       }
-
-       function getFirstLetter( $string ) {
-               if ( $string[0] == "\0" ) {
-                       $string = substr( $string, 1 );
-               }
-               return $this->lang->ucfirst( $this->lang->firstChar( $string ) );
-       }
-}
-
-/**
- * Collation class that's essentially a no-op.
- *
- * Does sorting based on binary value of the string.
- * Like how things were pre 1.17.
- */
-class IdentityCollation extends Collation {
-
-       function getSortKey( $string ) {
-               return $string;
-       }
-
-       function getFirstLetter( $string ) {
-               global $wgContLang;
-               // Copied from UppercaseCollation.
-               // I'm kind of unclear on when this could happen...
-               if ( $string[0] == "\0" ) {
-                       $string = substr( $string, 1 );
-               }
-               return $wgContLang->firstChar( $string );
-       }
-}
-
-class IcuCollation extends Collation {
-       const FIRST_LETTER_VERSION = 2;
-
-       /** @var Collator */
-       private $primaryCollator;
-
-       /** @var Collator */
-       private $mainCollator;
-
-       /** @var string */
-       private $locale;
-
-       /** @var Language */
-       protected $digitTransformLanguage;
-
-       /** @var array */
-       private $firstLetterData;
-
-       /**
-        * Unified CJK blocks.
-        *
-        * The same definition of a CJK block must be used for both Collation and
-        * generateCollationData.php. These blocks are omitted from the first
-        * letter data, as an optimisation measure and because the default UCA table
-        * is pretty useless for sorting Chinese text anyway. Japanese and Korean
-        * blocks are not included here, because they are smaller and more useful.
-        */
-       private static $cjkBlocks = [
-               [ 0x2E80, 0x2EFF ], // CJK Radicals Supplement
-               [ 0x2F00, 0x2FDF ], // Kangxi Radicals
-               [ 0x2FF0, 0x2FFF ], // Ideographic Description Characters
-               [ 0x3000, 0x303F ], // CJK Symbols and Punctuation
-               [ 0x31C0, 0x31EF ], // CJK Strokes
-               [ 0x3200, 0x32FF ], // Enclosed CJK Letters and Months
-               [ 0x3300, 0x33FF ], // CJK Compatibility
-               [ 0x3400, 0x4DBF ], // CJK Unified Ideographs Extension A
-               [ 0x4E00, 0x9FFF ], // CJK Unified Ideographs
-               [ 0xF900, 0xFAFF ], // CJK Compatibility Ideographs
-               [ 0xFE30, 0xFE4F ], // CJK Compatibility Forms
-               [ 0x20000, 0x2A6DF ], // CJK Unified Ideographs Extension B
-               [ 0x2A700, 0x2B73F ], // CJK Unified Ideographs Extension C
-               [ 0x2B740, 0x2B81F ], // CJK Unified Ideographs Extension D
-               [ 0x2F800, 0x2FA1F ], // CJK Compatibility Ideographs Supplement
-       ];
-
-       /**
-        * Additional characters (or character groups) to be considered separate
-        * letters for given languages, or to be removed from the list of such
-        * letters (denoted by keys starting with '-').
-        *
-        * These are additions to (or subtractions from) the data stored in the
-        * first-letters-root.ser file (which among others includes full basic latin,
-        * cyrillic and greek alphabets).
-        *
-        * "Separate letter" is a letter that would have a separate heading/section
-        * for it in a dictionary or a phone book in this language. This data isn't
-        * used for sorting (the ICU library handles that), only for deciding which
-        * characters (or character groups) to use as headings.
-        *
-        * Initially generated based on the primary level of Unicode collation
-        * tailorings available at http://developer.mimer.com/charts/tailorings.htm ,
-        * later modified.
-        *
-        * Empty arrays are intended; this signifies that the data for the language is
-        * available and that there are, in fact, no additional letters to consider.
-        */
-       private static $tailoringFirstLetters = [
-               // Verified by native speakers
-               'be' => [ "Ё" ],
-               'be-tarask' => [ "Ё" ],
-               'cy' => [ "Ch", "Dd", "Ff", "Ng", "Ll", "Ph", "Rh", "Th" ],
-               'en' => [],
-               'fa' => [ "آ", "ء", "ه" ],
-               'fi' => [ "Å", "Ä", "Ö" ],
-               'fr' => [],
-               'hu' => [ "Cs", "Dz", "Dzs", "Gy", "Ly", "Ny", "Ö", "Sz", "Ty", "Ü", "Zs" ],
-               'is' => [ "Á", "Ð", "É", "Í", "Ó", "Ú", "Ý", "Þ", "Æ", "Ö", "Å" ],
-               'it' => [],
-               'lv' => [ "Č", "Ģ", "Ķ", "Ļ", "Ņ", "Š", "Ž" ],
-               'pl' => [ "Ą", "Ć", "Ę", "Ł", "Ń", "Ó", "Ś", "Ź", "Ż" ],
-               'pt' => [],
-               'ru' => [],
-               'sv' => [ "Å", "Ä", "Ö" ],
-               'sv@collation=standard' => [ "Å", "Ä", "Ö" ],
-               'uk' => [ "Ґ", "Ь" ],
-               'vi' => [ "Ă", "Â", "Đ", "Ê", "Ô", "Ơ", "Ư" ],
-               // Not verified, but likely correct
-               'af' => [],
-               'ast' => [ "Ch", "Ll", "Ñ" ],
-               'az' => [ "Ç", "Ə", "Ğ", "İ", "Ö", "Ş", "Ü" ],
-               'bg' => [],
-               'br' => [ "Ch", "C'h" ],
-               'bs' => [ "Č", "Ć", "Dž", "Đ", "Lj", "Nj", "Š", "Ž" ],
-               'ca' => [],
-               'co' => [],
-               'cs' => [ "Č", "Ch", "Ř", "Š", "Ž" ],
-               'da' => [ "Æ", "Ø", "Å" ],
-               'de' => [],
-               'dsb' => [ "Č", "Ć", "Dź", "Ě", "Ch", "Ł", "Ń", "Ŕ", "Š", "Ś", "Ž", "Ź" ],
-               'el' => [],
-               'eo' => [ "Ĉ", "Ĝ", "Ĥ", "Ĵ", "Ŝ", "Ŭ" ],
-               'es' => [ "Ñ" ],
-               'et' => [ "Š", "Ž", "Õ", "Ä", "Ö", "Ü", "W" ], // added W for CollationEt (xx-uca-et)
-               'eu' => [ "Ñ" ],
-               'fo' => [ "Á", "Ð", "Í", "Ó", "Ú", "Ý", "Æ", "Ø", "Å" ],
-               'fur' => [ "À", "Á", "Â", "È", "Ì", "Ò", "Ù" ],
-               'fy' => [],
-               'ga' => [],
-               'gd' => [],
-               'gl' => [ "Ch", "Ll", "Ñ" ],
-               'hr' => [ "Č", "Ć", "Dž", "Đ", "Lj", "Nj", "Š", "Ž" ],
-               'hsb' => [ "Č", "Dź", "Ě", "Ch", "Ł", "Ń", "Ř", "Š", "Ć", "Ž" ],
-               'kk' => [ "Ү", "І" ],
-               'kl' => [ "Æ", "Ø", "Å" ],
-               'ku' => [ "Ç", "Ê", "Î", "Ş", "Û" ],
-               'ky' => [ "Ё" ],
-               'la' => [],
-               'lb' => [],
-               'lt' => [ "Č", "Š", "Ž" ],
-               'mk' => [],
-               'mo' => [ "Ă", "Â", "Î", "Ş", "Ţ" ],
-               'mt' => [ "Ċ", "Ġ", "Għ", "Ħ", "Ż" ],
-               'nl' => [],
-               'no' => [ "Æ", "Ø", "Å" ],
-               'oc' => [],
-               'rm' => [],
-               'ro' => [ "Ă", "Â", "Î", "Ş", "Ţ" ],
-               'rup' => [ "Ă", "Â", "Î", "Ľ", "Ń", "Ş", "Ţ" ],
-               'sco' => [],
-               'sk' => [ "Ä", "Č", "Ch", "Ô", "Š", "Ž" ],
-               'sl' => [ "Č", "Š", "Ž" ],
-               'smn' => [ "Á", "Č", "Đ", "Ŋ", "Š", "Ŧ", "Ž", "Æ", "Ø", "Å", "Ä", "Ö" ],
-               'sq' => [ "Ç", "Dh", "Ë", "Gj", "Ll", "Nj", "Rr", "Sh", "Th", "Xh", "Zh" ],
-               'sr' => [],
-               'tk' => [ "Ç", "Ä", "Ž", "Ň", "Ö", "Ş", "Ü", "Ý" ],
-               'tl' => [ "Ñ", "Ng" ],
-               'tr' => [ "Ç", "Ğ", "İ", "Ö", "Ş", "Ü" ],
-               'tt' => [ "Ә", "Ө", "Ү", "Җ", "Ң", "Һ" ],
-               'uz' => [ "Ch", "G'", "Ng", "O'", "Sh" ],
-       ];
-
-       const RECORD_LENGTH = 14;
-
-       function __construct( $locale ) {
-               if ( !extension_loaded( 'intl' ) ) {
-                       throw new MWException( 'An ICU collation was requested, ' .
-                               'but the intl extension is not available.' );
-               }
-
-               $this->locale = $locale;
-               // Drop everything after the '@' in locale's name
-               $localeParts = explode( '@', $locale );
-               $this->digitTransformLanguage = Language::factory( $locale === 'root' ? 'en' : $localeParts[0] );
-
-               $this->mainCollator = Collator::create( $locale );
-               if ( !$this->mainCollator ) {
-                       throw new MWException( "Invalid ICU locale specified for collation: $locale" );
-               }
-
-               $this->primaryCollator = Collator::create( $locale );
-               $this->primaryCollator->setStrength( Collator::PRIMARY );
-       }
-
-       function getSortKey( $string ) {
-               // intl extension produces non null-terminated
-               // strings. Appending '' fixes it so that it doesn't generate
-               // a warning on each access in debug php.
-               MediaWiki\suppressWarnings();
-               $key = $this->mainCollator->getSortKey( $string ) . '';
-               MediaWiki\restoreWarnings();
-               return $key;
-       }
-
-       function getPrimarySortKey( $string ) {
-               MediaWiki\suppressWarnings();
-               $key = $this->primaryCollator->getSortKey( $string ) . '';
-               MediaWiki\restoreWarnings();
-               return $key;
-       }
-
-       function getFirstLetter( $string ) {
-               $string = strval( $string );
-               if ( $string === '' ) {
-                       return '';
-               }
-
-               // Check for CJK
-               $firstChar = mb_substr( $string, 0, 1, 'UTF-8' );
-               if ( ord( $firstChar ) > 0x7f && self::isCjk( UtfNormal\Utils::utf8ToCodepoint( $firstChar ) ) ) {
-                       return $firstChar;
-               }
-
-               $sortKey = $this->getPrimarySortKey( $string );
-
-               // Do a binary search to find the correct letter to sort under
-               $min = ArrayUtils::findLowerBound(
-                       [ $this, 'getSortKeyByLetterIndex' ],
-                       $this->getFirstLetterCount(),
-                       'strcmp',
-                       $sortKey );
-
-               if ( $min === false ) {
-                       // Before the first letter
-                       return '';
-               }
-               return $this->getLetterByIndex( $min );
-       }
-
-       function getFirstLetterData() {
-               if ( $this->firstLetterData !== null ) {
-                       return $this->firstLetterData;
-               }
-
-               $cache = wfGetCache( CACHE_ANYTHING );
-               $cacheKey = wfMemcKey(
-                       'first-letters',
-                       $this->locale,
-                       $this->digitTransformLanguage->getCode(),
-                       self::getICUVersion()
-               );
-               $cacheEntry = $cache->get( $cacheKey );
-
-               if ( $cacheEntry && isset( $cacheEntry['version'] )
-                       && $cacheEntry['version'] == self::FIRST_LETTER_VERSION
-               ) {
-                       $this->firstLetterData = $cacheEntry;
-                       return $this->firstLetterData;
-               }
-
-               // Generate data from serialized data file
-
-               if ( isset( self::$tailoringFirstLetters[$this->locale] ) ) {
-                       $letters = wfGetPrecompiledData( "first-letters-root.ser" );
-                       // Append additional characters
-                       $letters = array_merge( $letters, self::$tailoringFirstLetters[$this->locale] );
-                       // Remove unnecessary ones, if any
-                       if ( isset( self::$tailoringFirstLetters['-' . $this->locale] ) ) {
-                               $letters = array_diff( $letters, self::$tailoringFirstLetters['-' . $this->locale] );
-                       }
-                       // Apply digit transforms
-                       $digits = [ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' ];
-                       $letters = array_diff( $letters, $digits );
-                       foreach ( $digits as $digit ) {
-                               $letters[] = $this->digitTransformLanguage->formatNum( $digit, true );
-                       }
-               } else {
-                       $letters = wfGetPrecompiledData( "first-letters-{$this->locale}.ser" );
-                       if ( $letters === false ) {
-                               throw new MWException( "MediaWiki does not support ICU locale " .
-                                       "\"{$this->locale}\"" );
-                       }
-               }
-
-               /* Sort the letters.
-                *
-                * It's impossible to have the precompiled data file properly sorted,
-                * because the sort order changes depending on ICU version. If the
-                * array is not properly sorted, the binary search will return random
-                * results.
-                *
-                * We also take this opportunity to remove primary collisions.
-                */
-               $letterMap = [];
-               foreach ( $letters as $letter ) {
-                       $key = $this->getPrimarySortKey( $letter );
-                       if ( isset( $letterMap[$key] ) ) {
-                               // Primary collision
-                               // Keep whichever one sorts first in the main collator
-                               if ( $this->mainCollator->compare( $letter, $letterMap[$key] ) < 0 ) {
-                                       $letterMap[$key] = $letter;
-                               }
-                       } else {
-                               $letterMap[$key] = $letter;
-                       }
-               }
-               ksort( $letterMap, SORT_STRING );
-
-               /* Remove duplicate prefixes. Basically if something has a sortkey
-                * which is a prefix of some other sortkey, then it is an
-                * expansion and probably should not be considered a section
-                * header.
-                *
-                * For example 'þ' is sometimes sorted as if it is the letters
-                * 'th'. Other times it is its own primary element. Another
-                * example is '₨'. Sometimes its a currency symbol. Sometimes it
-                * is an 'R' followed by an 's'.
-                *
-                * Additionally an expanded element should always sort directly
-                * after its first element due to they way sortkeys work.
-                *
-                * UCA sortkey elements are of variable length but no collation
-                * element should be a prefix of some other element, so I think
-                * this is safe. See:
-                * - https://ssl.icu-project.org/repos/icu/icuhtml/trunk/design/collation/ICU_collation_design.htm
-                * - http://site.icu-project.org/design/collation/uca-weight-allocation
-                *
-                * Additionally, there is something called primary compression to
-                * worry about. Basically, if you have two primary elements that
-                * are more than one byte and both start with the same byte then
-                * the first byte is dropped on the second primary. Additionally
-                * either \x03 or \xFF may be added to mean that the next primary
-                * does not start with the first byte of the first primary.
-                *
-                * This shouldn't matter much, as the first primary is not
-                * changed, and that is what we are comparing against.
-                *
-                * tl;dr: This makes some assumptions about how icu implements
-                * collations. It seems incredibly unlikely these assumptions
-                * will change, but nonetheless they are assumptions.
-                */
-
-               $prev = false;
-               $duplicatePrefixes = [];
-               foreach ( $letterMap as $key => $value ) {
-                       // Remove terminator byte. Otherwise the prefix
-                       // comparison will get hung up on that.
-                       $trimmedKey = rtrim( $key, "\0" );
-                       if ( $prev === false || $prev === '' ) {
-                               $prev = $trimmedKey;
-                               // We don't yet have a collation element
-                               // to compare against, so continue.
-                               continue;
-                       }
-
-                       // Due to the fact the array is sorted, we only have
-                       // to compare with the element directly previous
-                       // to the current element (skipping expansions).
-                       // An element "X" will always sort directly
-                       // before "XZ" (Unless we have "XY", but we
-                       // do not update $prev in that case).
-                       if ( substr( $trimmedKey, 0, strlen( $prev ) ) === $prev ) {
-                               $duplicatePrefixes[] = $key;
-                               // If this is an expansion, we don't want to
-                               // compare the next element to this element,
-                               // but to what is currently $prev
-                               continue;
-                       }
-                       $prev = $trimmedKey;
-               }
-               foreach ( $duplicatePrefixes as $badKey ) {
-                       wfDebug( "Removing '{$letterMap[$badKey]}' from first letters.\n" );
-                       unset( $letterMap[$badKey] );
-                       // This code assumes that unsetting does not change sort order.
-               }
-               $data = [
-                       'chars' => array_values( $letterMap ),
-                       'keys' => array_keys( $letterMap ),
-                       'version' => self::FIRST_LETTER_VERSION,
-               ];
-
-               // Reduce memory usage before caching
-               unset( $letterMap );
-
-               // Save to cache
-               $this->firstLetterData = $data;
-               $cache->set( $cacheKey, $data, $cache::TTL_WEEK );
-               return $data;
-       }
-
-       function getLetterByIndex( $index ) {
-               if ( $this->firstLetterData === null ) {
-                       $this->getFirstLetterData();
-               }
-               return $this->firstLetterData['chars'][$index];
-       }
-
-       function getSortKeyByLetterIndex( $index ) {
-               if ( $this->firstLetterData === null ) {
-                       $this->getFirstLetterData();
-               }
-               return $this->firstLetterData['keys'][$index];
-       }
-
-       function getFirstLetterCount() {
-               if ( $this->firstLetterData === null ) {
-                       $this->getFirstLetterData();
-               }
-               return count( $this->firstLetterData['chars'] );
-       }
-
-       static function isCjk( $codepoint ) {
-               foreach ( self::$cjkBlocks as $block ) {
-                       if ( $codepoint >= $block[0] && $codepoint <= $block[1] ) {
-                               return true;
-                       }
-               }
-               return false;
-       }
-
-       /**
-        * Return the version of ICU library used by PHP's intl extension,
-        * or false when the extension is not installed of the version
-        * can't be determined.
-        *
-        * The constant INTL_ICU_VERSION this function refers to isn't really
-        * documented. It is available since PHP 5.3.7 (see PHP bug 54561).
-        * This function will return false on older PHPs.
-        *
-        * @since 1.21
-        * @return string|bool
-        */
-       static function getICUVersion() {
-               return defined( 'INTL_ICU_VERSION' ) ? INTL_ICU_VERSION : false;
-       }
-
-       /**
-        * Return the version of Unicode appropriate for the version of ICU library
-        * currently in use, or false when it can't be determined.
-        *
-        * @since 1.21
-        * @return string|bool
-        */
-       static function getUnicodeVersionForICU() {
-               $icuVersion = IcuCollation::getICUVersion();
-               if ( !$icuVersion ) {
-                       return false;
-               }
-
-               $versionPrefix = substr( $icuVersion, 0, 3 );
-               // Source: http://site.icu-project.org/download
-               $map = [
-                       '50.' => '6.2',
-                       '49.' => '6.1',
-                       '4.8' => '6.0',
-                       '4.6' => '6.0',
-                       '4.4' => '5.2',
-                       '4.2' => '5.1',
-                       '4.0' => '5.1',
-                       '3.8' => '5.0',
-                       '3.6' => '5.0',
-                       '3.4' => '4.1',
-               ];
-
-               if ( isset( $map[$versionPrefix] ) ) {
-                       return $map[$versionPrefix];
-               } else {
-                       return false;
-               }
-       }
-}
-
-/**
- * Workaround for the lack of support of Sorani Kurdish / Central Kurdish language ('ckb') in ICU.
- *
- * Uses the same collation rules as Persian / Farsi ('fa'), but different characters for digits.
- */
-class CollationCkb extends IcuCollation {
-       function __construct() {
-               // This will set $locale and collators, which affect the actual sorting order
-               parent::__construct( 'fa' );
-               // Override the 'fa' language set by parent constructor, which affects #getFirstLetterData()
-               $this->digitTransformLanguage = Language::factory( 'ckb' );
-       }
-}
-
-/**
- * Workaround for incorrect collation of Estonian language ('et') in ICU (bug 54168).
- *
- * 'W' and 'V' should not be considered the same letter for the purposes of collation in modern
- * Estonian. We work around this by replacing 'W' and 'w' with 'ᴡ' U+1D21 'LATIN LETTER SMALL
- * CAPITAL W' for sortkey generation, which is collated like 'W' and is not tailored to have the
- * same primary weight as 'V' in Estonian.
- */
-class CollationEt extends IcuCollation {
-       function __construct() {
-               parent::__construct( 'et' );
-       }
-
-       private static function mangle( $string ) {
-               return str_replace(
-                       [ 'w', 'W' ],
-                       'ᴡ', // U+1D21 'LATIN LETTER SMALL CAPITAL W'
-                       $string
-               );
-       }
-
-       private static function unmangle( $string ) {
-               // Casing data is lost…
-               return str_replace(
-                       'ᴡ', // U+1D21 'LATIN LETTER SMALL CAPITAL W'
-                       'W',
-                       $string
-               );
-       }
-
-       function getSortKey( $string ) {
-               return parent::getSortKey( self::mangle( $string ) );
-       }
-
-       function getFirstLetter( $string ) {
-               return self::unmangle( parent::getFirstLetter( self::mangle( $string ) ) );
-       }
-}
index 4950359..65032ad 100644 (file)
@@ -6480,6 +6480,10 @@ $wgUnwatchedPageThreshold = false;
  *   'legend' => 'legend-msg',
  *   // optional (defaults to 'flag'), CSS class to put on changes lists rows
  *   'class' => 'css-class',
+ *   // optional (defaults to 'any'), how top-level flag is determined.  'any'
+ *   // will set the top-level flag if any line contains the flag, 'all' will
+ *   // only be set if all lines contain the flag.
+ *   'grouping' => 'any',
  * );
  * @endcode
  *
@@ -6490,23 +6494,27 @@ $wgRecentChangesFlags = [
                'letter' => 'newpageletter',
                'title' => 'recentchanges-label-newpage',
                'legend' => 'recentchanges-legend-newpage',
+               'grouping' => 'any',
        ],
        'minor' => [
                'letter' => 'minoreditletter',
                'title' => 'recentchanges-label-minor',
                'legend' => 'recentchanges-legend-minor',
                'class' => 'minoredit',
+               'grouping' => 'all',
        ],
        'bot' => [
                'letter' => 'boteditletter',
                'title' => 'recentchanges-label-bot',
                'legend' => 'recentchanges-legend-bot',
                'class' => 'botedit',
+               'grouping' => 'all',
        ],
        'unpatrolled' => [
                'letter' => 'unpatrolledletter',
                'title' => 'recentchanges-label-unpatrolled',
                'legend' => 'recentchanges-legend-unpatrolled',
+               'grouping' => 'any',
        ],
 ];
 
@@ -6546,12 +6554,6 @@ $wgRightsText = null;
  */
 $wgRightsIcon = null;
 
-/**
- * Set this to some HTML to override the rights icon with an arbitrary logo
- * @deprecated since 1.18 Use $wgFooterIcons['copyright']['copyright']
- */
-$wgCopyrightIcon = null;
-
 /**
  * Set this to true if you want detailed copyright information forms on Upload.
  */
@@ -6884,6 +6886,21 @@ $wgAuth = null;
  */
 $wgHooks = [];
 
+/**
+ * List of service wiring files to be loaded by the default instance of MediaWikiServices.
+ * Each file listed here is expected to return an associative array mapping service names
+ * to instantiator functions. Extensions may add wiring files to define their own services.
+ * However, this cannot be used to replace existing services - use the MediaWikiServices
+ * hook for that.
+ *
+ * @see MediaWikiServices
+ * @see ServiceContainer::loadWiringFiles() for details on loading service instantiator functions.
+ * @see docs/injection.txt for an overview of dependency injection in MediaWiki.
+ */
+$wgServiceWiringFiles = [
+       __DIR__ . '/ServiceWiring.php'
+];
+
 /**
  * Maps jobs to their handling classes; extensions
  * can add to this to provide custom jobs
index b3bb07a..3522531 100644 (file)
@@ -1175,7 +1175,7 @@ class EditPage {
         * Get the content of the wanted revision, without section extraction.
         *
         * The result of this function can be used to compare user's input with
-        * section replaced in its context (using WikiPage::replaceSection())
+        * section replaced in its context (using WikiPage::replaceSectionAtRev())
         * to the original text of the edit.
         *
         * This differs from Article::getContent() that when a missing revision is
@@ -1982,7 +1982,7 @@ class EditPage {
                        } elseif ( $this->section != '' ) {
                                # Try to get a section anchor from the section source, redirect
                                # to edited section if header found.
-                               # XXX: Might be better to integrate this into Article::replaceSection
+                               # XXX: Might be better to integrate this into Article::replaceSectionAtRev
                                # for duplicate heading checking and maybe parsing.
                                $hasmatch = preg_match( "/^ *([=]{1,6})(.*?)(\\1) *\\n/i", $this->textbox1, $matches );
                                # We can't deal with anchors, includes, html etc in the header for now,
diff --git a/includes/MediaWikiServices.php b/includes/MediaWikiServices.php
new file mode 100644 (file)
index 0000000..7b1def9
--- /dev/null
@@ -0,0 +1,153 @@
+<?php
+namespace MediaWiki;
+
+use ConfigFactory;
+use GlobalVarConfig;
+use Config;
+use Hooks;
+use LBFactory;
+use LoadBalancer;
+use MediaWiki\Services\ServiceContainer;
+use SiteLookup;
+use SiteStore;
+
+/**
+ * Service locator for MediaWiki core services.
+ *
+ * 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
+ *
+ * @since 1.27
+ */
+
+/**
+ * MediaWikiServices is the service locator for the application scope of MediaWiki.
+ * Its implemented as a simple configurable DI container.
+ * MediaWikiServices acts as a top level factory/registry for top level services, and builds
+ * the network of service objects that defines MediaWiki's application logic.
+ * It acts as an entry point to MediaWiki's dependency injection mechanism.
+ *
+ * Services are defined in the "wiring" array passed to the constructor,
+ * or by calling defineService().
+ *
+ * @see docs/injection.txt for an overview of using dependency injection in the
+ *      MediaWiki code base.
+ */
+class MediaWikiServices extends ServiceContainer {
+
+       /**
+        * Returns the global default instance of the top level service locator.
+        *
+        * The default instance is initialized using the service instantiator functions
+        * defined in ServiceWiring.php.
+        *
+        * @note This should only be called by static functions! The instance returned here
+        * should not be passed around! Objects that need access to a service should have
+        * that service injected into the constructor, never a service locator!
+        *
+        * @return MediaWikiServices
+        */
+       public static function getInstance() {
+               static $instance = null;
+
+               if ( $instance === null ) {
+                       // NOTE: constructing GlobalVarConfig here is not particularly pretty,
+                       // but some information from the global scope has to be injected here,
+                       // even if it's just a file name or database credentials to load
+                       // configuration from.
+                       $config = new GlobalVarConfig();
+                       $instance = new self( $config );
+
+                       // Load the default wiring from the specified files.
+                       $wiringFiles = $config->get( 'ServiceWiringFiles' );
+                       $instance->loadWiringFiles( $wiringFiles );
+
+                       // Provide a traditional hook point to allow extensions to configure services.
+                       Hooks::run( 'MediaWikiServices', [ $instance ] );
+               }
+
+               return $instance;
+       }
+
+       /**
+        * @param Config $config The Config object to be registered as the 'BootstrapConfig' service.
+        *        This has to contain at least the information needed to set up the 'ConfigFactory'
+        *        service.
+        */
+       public function __construct( Config $config ) {
+               parent::__construct();
+
+               // register the given Config object as the bootstrap config service.
+               $this->defineService( 'BootstrapConfig', function() use ( $config ) {
+                       return $config;
+               } );
+       }
+
+       /**
+        * Returns the Config object containing the bootstrap configuration.
+        * Bootstrap configuration would typically include database credentials
+        * and other information that may be needed before the ConfigFactory
+        * service can be instantiated.
+        *
+        * @note This should only be used during bootstrapping, in particular
+        * when creating the MainConfig service. Application logic should
+        * use getMainConfig() to get a Config instances.
+        *
+        * @return Config
+        */
+       public function getBootstrapConfig() {
+               return $this->getService( 'BootstrapConfig' );
+       }
+
+       /**
+        * @return ConfigFactory
+        */
+       public function getConfigFactory() {
+               return $this->getService( 'ConfigFactory' );
+       }
+
+       /**
+        * Returns the Config object that provides configuration for MediaWiki core.
+        * This may or may not be the same object that is returned by getBootstrapConfig().
+        *
+        * @return Config
+        */
+       public function getMainConfig() {
+               return $this->getService( 'MainConfig' );
+       }
+
+       /**
+        * @return SiteLookup
+        */
+       public function getSiteLookup() {
+               return $this->getService( 'SiteLookup' );
+       }
+
+       /**
+        * @return SiteStore
+        */
+       public function getSiteStore() {
+               return $this->getService( 'SiteStore' );
+       }
+
+       ///////////////////////////////////////////////////////////////////////////
+       // NOTE: When adding a service getter here, don't forget to add a test
+       // case for it in MediaWikiServicesTest::provideGetters() and in
+       // MediaWikiServicesTest::provideGetService()!
+       ///////////////////////////////////////////////////////////////////////////
+
+}
index b7bb346..79cab79 100644 (file)
@@ -1035,19 +1035,6 @@ class Revision implements IDBAccessObject {
                }
        }
 
-       /**
-        * Fetch revision text without regard for view restrictions
-        *
-        * @return string
-        *
-        * @deprecated since 1.21. Instead, use Revision::getContent( Revision::RAW )
-        *                         or Revision::getSerializedData() as appropriate.
-        */
-       public function getRawText() {
-               ContentHandler::deprecated( __METHOD__, "1.21" );
-               return $this->getText( self::RAW );
-       }
-
        /**
         * Fetch original serialized data without regard for view restrictions
         *
diff --git a/includes/ServiceWiring.php b/includes/ServiceWiring.php
new file mode 100644 (file)
index 0000000..d8709b9
--- /dev/null
@@ -0,0 +1,81 @@
+<?php
+/**
+ * Default wiring for MediaWiki services.
+ *
+ * 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 file is loaded by MediaWiki\MediaWikiServices::getInstance() during the
+ * bootstrapping of the dependency injection framework.
+ *
+ * This file returns an array that associates service name with instantiator functions
+ * that create the default instances for the services used by MediaWiki core.
+ * For every service that MediaWiki core requires, an instantiator must be defined in
+ * this file.
+ *
+ * @note As of version 1.27, MediaWiki is only beginning to use dependency injection.
+ * The services defined here do not yet fully represent all services used by core,
+ * much of the code still relies on global state for this accessing services.
+ *
+ * @since 1.27
+ *
+ * @see docs/injection.txt for an overview of using dependency injection in the
+ *      MediaWiki code base.
+ */
+
+use MediaWiki\MediaWikiServices;
+
+return [
+       'SiteStore' => function( MediaWikiServices $services ) {
+               $loadBalancer = wfGetLB(); // TODO: use LB from MediaWikiServices
+               $rawSiteStore = new DBSiteStore( $loadBalancer );
+
+               // TODO: replace wfGetCache with a CacheFactory service.
+               // TODO: replace wfIsHHVM with a capabilities service.
+               $cache = wfGetCache( wfIsHHVM() ? CACHE_ACCEL : CACHE_ANYTHING );
+
+               return new CachingSiteStore( $rawSiteStore, $cache );
+       },
+
+       'SiteLookup' => function( MediaWikiServices $services ) {
+               // Use the default SiteStore as the SiteLookup implementation for now
+               return $services->getSiteStore();
+       },
+
+       'ConfigFactory' => function( MediaWikiServices $services ) {
+               // Use the bootstrap config to initialize the ConfigFactory.
+               $registry = $services->getBootstrapConfig()->get( 'ConfigRegistry' );
+               $factory = new ConfigFactory();
+
+               foreach ( $registry as $name => $callback ) {
+                       $factory->register( $name, $callback );
+               }
+               return $factory;
+       },
+
+       'MainConfig' => function( MediaWikiServices $services ) {
+               // Use the 'main' config from the ConfigFactory service.
+               return $services->getConfigFactory()->makeConfig( 'main' );
+       },
+
+       ///////////////////////////////////////////////////////////////////////////
+       // NOTE: When adding a service here, don't forget to add a getter function
+       // in the MediaWikiServices class. The convenience getter should just call
+       // $this->getService( 'FooBarService' ).
+       ///////////////////////////////////////////////////////////////////////////
+
+];
diff --git a/includes/Services/ServiceContainer.php b/includes/Services/ServiceContainer.php
new file mode 100644 (file)
index 0000000..e3cda2e
--- /dev/null
@@ -0,0 +1,222 @@
+<?php
+namespace MediaWiki\Services;
+
+use InvalidArgumentException;
+use RuntimeException;
+use Wikimedia\Assert\Assert;
+
+/**
+ * Generic service container.
+ *
+ * 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
+ *
+ * @since 1.27
+ */
+
+/**
+ * ServiceContainer provides a generic service to manage named services using
+ * lazy instantiation based on instantiator callback functions.
+ *
+ * Services managed by an instance of ServiceContainer may or may not implement
+ * a common interface.
+ *
+ * @note When using ServiceContainer to manage a set of services, consider
+ * creating a wrapper or a subclass that provides access to the services via
+ * getter methods with more meaningful names and more specific return type
+ * declarations.
+ *
+ * @see docs/injection.txt for an overview of using dependency injection in the
+ *      MediaWiki code base.
+ */
+class ServiceContainer {
+
+       /**
+        * @var object[]
+        */
+       private $services = [];
+
+       /**
+        * @var callable[]
+        */
+       private $serviceInstantiators = [];
+
+       /**
+        * @var array
+        */
+       private $extraInstantiationParams;
+
+       /**
+        * @param array $extraInstantiationParams Any additional parameters to be passed to the
+        * instantiator function when creating a service. This is typically used to provide
+        * access to additional ServiceContainers or Config objects.
+        */
+       public function __construct( array $extraInstantiationParams = [] ) {
+               $this->extraInstantiationParams = $extraInstantiationParams;
+       }
+
+       /**
+        * @param array $wiringFiles A list of PHP files to load wiring information from.
+        * Each file is loaded using PHP's include mechanism. Each file is expected to
+        * return an associative array that maps service names to instantiator functions.
+        */
+       public function loadWiringFiles( array $wiringFiles ) {
+               foreach ( $wiringFiles as $file ) {
+                       // the wiring file is required to return an array of instantiators.
+                       $wiring = require $file;
+
+                       Assert::postcondition(
+                               is_array( $wiring ),
+                               "Wiring file $file is expected to return an array!"
+                       );
+
+                       $this->applyWiring( $wiring );
+               }
+       }
+
+       /**
+        * Registers multiple services (aka a "wiring").
+        *
+        * @param array $serviceInstantiators An associative array mapping service names to
+        *        instantiator functions.
+        */
+       public function applyWiring( array $serviceInstantiators ) {
+               Assert::parameterElementType( 'callable', $serviceInstantiators, '$serviceInstantiators' );
+
+               foreach ( $serviceInstantiators as $name => $instantiator ) {
+                       $this->defineService( $name, $instantiator );
+               }
+       }
+
+       /**
+        * Returns true if a service is defined for $name, that is, if a call to getService( $name )
+        * would return a service instance.
+        *
+        * @param string $name
+        *
+        * @return bool
+        */
+       public function hasService( $name ) {
+               return isset( $this->serviceInstantiators[$name] );
+       }
+
+       /**
+        * @return string[]
+        */
+       public function getServiceNames() {
+               return array_keys( $this->serviceInstantiators );
+       }
+
+       /**
+        * Define a new service. The service must not be known already.
+        *
+        * @see getService().
+        * @see replaceService().
+        *
+        * @param string $name The name of the service to register, for use with getService().
+        * @param callable $instantiator Callback that returns a service instance.
+        *        Will be called with this MediaWikiServices instance as the only parameter.
+        *        Any extra instantiation parameters provided to the constructor will be
+        *        passed as subsequent parameters when invoking the instantiator.
+        *
+        * @throws RuntimeException if there is already a service registered as $name.
+        */
+       public function defineService( $name, callable $instantiator ) {
+               Assert::parameterType( 'string', $name, '$name' );
+
+               if ( $this->hasService( $name ) ) {
+                       throw new RuntimeException( 'Service already defined: ' . $name );
+               }
+
+               $this->serviceInstantiators[$name] = $instantiator;
+       }
+
+       /**
+        * Replace an already defined service.
+        *
+        * @see defineService().
+        *
+        * @note This causes any previously instantiated instance of the service to be discarded.
+        *
+        * @param string $name The name of the service to register.
+        * @param callable $instantiator Callback function that returns a service instance.
+        *        Will be called with this MediaWikiServices instance as the only parameter.
+        *        The instantiator must return a service compatible with the originally defined service.
+        *        Any extra instantiation parameters provided to the constructor will be
+        *        passed as subsequent parameters when invoking the instantiator.
+        *
+        * @throws RuntimeException if $name is not a known service.
+        */
+       public function redefineService( $name, callable $instantiator ) {
+               Assert::parameterType( 'string', $name, '$name' );
+
+               if ( !$this->hasService( $name ) ) {
+                       throw new RuntimeException( 'Service not defined: ' . $name );
+               }
+
+               if ( isset( $this->services[$name] ) ) {
+                       throw new RuntimeException( 'Cannot redefine a service that is already in use: ' . $name );
+               }
+
+               $this->serviceInstantiators[$name] = $instantiator;
+       }
+
+       /**
+        * Returns a service object of the kind associated with $name.
+        * Services instances are instantiated lazily, on demand.
+        * This method may or may not return the same service instance
+        * when called multiple times with the same $name.
+        *
+        * @note Rather than calling this method directly, it is recommended to provide
+        * getters with more meaningful names and more specific return types, using
+        * a subclass or wrapper.
+        *
+        * @see redefineService().
+        *
+        * @param string $name The service name
+        *
+        * @throws InvalidArgumentException if $name is not a known service.
+        * @return object The service instance
+        */
+       public function getService( $name ) {
+               if ( !isset( $this->services[$name] ) ) {
+                       $this->services[$name] = $this->createService( $name );
+               }
+
+               return $this->services[$name];
+       }
+
+       /**
+        * @param string $name
+        *
+        * @throws InvalidArgumentException if $name is not a known service.
+        * @return object
+        */
+       private function createService( $name ) {
+               if ( isset( $this->serviceInstantiators[$name] ) ) {
+                       $service = call_user_func_array(
+                               $this->serviceInstantiators[$name],
+                               array_merge( [ $this ], $this->extraInstantiationParams )
+                       );
+               } else {
+                       throw new InvalidArgumentException( 'Unknown service: ' . $name );
+               }
+
+               return $service;
+       }
+
+}
index f7d8d08..c60311f 100644 (file)
@@ -119,20 +119,15 @@ if ( $wgRightsIcon ) {
        );
 }
 
-if ( isset( $wgFooterIcons['copyright'] )
-       && isset( $wgFooterIcons['copyright']['copyright'] )
+if ( isset( $wgFooterIcons['copyright']['copyright'] )
        && $wgFooterIcons['copyright']['copyright'] === []
 ) {
-       if ( $wgCopyrightIcon ) {
-               $wgFooterIcons['copyright']['copyright'] = $wgCopyrightIcon;
-       } elseif ( $wgRightsIcon || $wgRightsText ) {
+       if ( $wgRightsIcon || $wgRightsText ) {
                $wgFooterIcons['copyright']['copyright'] = [
                        'url' => $wgRightsUrl,
                        'src' => $wgRightsIcon,
                        'alt' => $wgRightsText,
                ];
-       } else {
-               unset( $wgFooterIcons['copyright']['copyright'] );
        }
 }
 
index 580f7cc..acd5262 100644 (file)
@@ -36,9 +36,6 @@ class SiteStats {
        /** @var int[] */
        private static $pageCount = [];
 
-       /** @var int[] */
-       private static $groupMemberCounts = [];
-
        static function recache() {
                self::load( true );
        }
@@ -289,8 +286,10 @@ class SiteStatsInit {
        public function __construct( $database = false ) {
                if ( $database instanceof IDatabase ) {
                        $this->db = $database;
+               } elseif ( $database ) {
+                       $this->db = wfGetDB( DB_MASTER );
                } else {
-                       $this->db = wfGetDB( $database ? DB_MASTER : DB_SLAVE );
+                       $this->db = wfGetDB( DB_SLAVE, 'vslow' );
                }
        }
 
index 211afda..0b4d048 100644 (file)
@@ -149,7 +149,6 @@ class StubObject {
                }
 
                if ( get_class( $GLOBALS[$this->global] ) != $this->class ) {
-                       $fname = __METHOD__ . '-' . $this->global;
                        $caller = wfGetCaller( $level );
                        if ( ++$recursionLevel > 2 ) {
                                throw new MWException( "Unstub loop detected on call of "
index 8bafe26..f4a6894 100644 (file)
@@ -572,57 +572,6 @@ class Title implements LinkTarget {
                return $title;
        }
 
-       /**
-        * Extract a redirect destination from a string and return the
-        * Title, or null if the text doesn't contain a valid redirect
-        * This will only return the very next target, useful for
-        * the redirect table and other checks that don't need full recursion
-        *
-        * @param string $text Text with possible redirect
-        * @return Title The corresponding Title
-        * @deprecated since 1.21, use Content::getRedirectTarget instead.
-        */
-       public static function newFromRedirect( $text ) {
-               ContentHandler::deprecated( __METHOD__, '1.21' );
-
-               $content = ContentHandler::makeContent( $text, null, CONTENT_MODEL_WIKITEXT );
-               return $content->getRedirectTarget();
-       }
-
-       /**
-        * Extract a redirect destination from a string and return the
-        * Title, or null if the text doesn't contain a valid redirect
-        * This will recurse down $wgMaxRedirects times or until a non-redirect target is hit
-        * in order to provide (hopefully) the Title of the final destination instead of another redirect
-        *
-        * @param string $text Text with possible redirect
-        * @return Title
-        * @deprecated since 1.21, use Content::getUltimateRedirectTarget instead.
-        */
-       public static function newFromRedirectRecurse( $text ) {
-               ContentHandler::deprecated( __METHOD__, '1.21' );
-
-               $content = ContentHandler::makeContent( $text, null, CONTENT_MODEL_WIKITEXT );
-               return $content->getUltimateRedirectTarget();
-       }
-
-       /**
-        * Extract a redirect destination from a string and return an
-        * array of Titles, or null if the text doesn't contain a valid redirect
-        * The last element in the array is the final destination after all redirects
-        * have been resolved (up to $wgMaxRedirects times)
-        *
-        * @param string $text Text with possible redirect
-        * @return Title[] Array of Titles, with the destination last
-        * @deprecated since 1.21, use Content::getRedirectChain instead.
-        */
-       public static function newFromRedirectArray( $text ) {
-               ContentHandler::deprecated( __METHOD__, '1.21' );
-
-               $content = ContentHandler::makeContent( $text, null, CONTENT_MODEL_WIKITEXT );
-               return $content->getRedirectChain();
-       }
-
        /**
         * Get the prefixed DB key associated with an ID
         *
index c4340ad..8ae7932 100644 (file)
@@ -1,5 +1,6 @@
 <?php
 
+use Liuggio\StatsdClient\Factory\StatsdDataFactoryInterface;
 use Wikimedia\Assert\Assert;
 
 /**
@@ -10,7 +11,7 @@ use Wikimedia\Assert\Assert;
  *
  * @since 1.27
  */
-class WatchedItemStore {
+class WatchedItemStore implements StatsdAwareInterface {
 
        const SORT_DESC = 'DESC';
        const SORT_ASC = 'ASC';
@@ -43,6 +44,11 @@ class WatchedItemStore {
         */
        private $revisionGetTimestampFromIdCallback;
 
+       /**
+        * @var StatsdDataFactoryInterface
+        */
+       private $stats;
+
        /**
         * @var self|null
         */
@@ -58,10 +64,15 @@ class WatchedItemStore {
        ) {
                $this->loadBalancer = $loadBalancer;
                $this->cache = $cache;
+               $this->stats = new NullStatsdDataFactory();
                $this->deferredUpdatesAddCallableUpdateCallback = [ 'DeferredUpdates', 'addCallableUpdate' ];
                $this->revisionGetTimestampFromIdCallback = [ 'Revision', 'getTimestampFromId' ];
        }
 
+       public function setStatsdDataFactory( StatsdDataFactoryInterface $stats ) {
+               $this->stats = $stats;
+       }
+
        /**
         * Overrides the DeferredUpdates::addCallableUpdate callback
         * This is intended for use while testing and will fail if MW_PHPUNIT_TEST is not defined.
@@ -148,6 +159,7 @@ class WatchedItemStore {
                                wfGetLB(),
                                new HashBagOStuff( [ 'maxKeys' => 100 ] )
                        );
+                       self::$instance->setStatsdDataFactory( RequestContext::getMain()->getStats() );
                }
                return self::$instance;
        }
@@ -166,18 +178,22 @@ class WatchedItemStore {
                $key = $this->getCacheKey( $user, $target );
                $this->cache->set( $key, $item );
                $this->cacheIndex[$target->getNamespace()][$target->getDBkey()][$user->getId()] = $key;
+               $this->stats->increment( 'WatchedItemStore.cache' );
        }
 
        private function uncache( User $user, LinkTarget $target ) {
                $this->cache->delete( $this->getCacheKey( $user, $target ) );
                unset( $this->cacheIndex[$target->getNamespace()][$target->getDBkey()][$user->getId()] );
+               $this->stats->increment( 'WatchedItemStore.uncache' );
        }
 
        private function uncacheLinkTarget( LinkTarget $target ) {
                if ( !isset( $this->cacheIndex[$target->getNamespace()][$target->getDBkey()] ) ) {
                        return;
                }
+               $this->stats->increment( 'WatchedItemStore.uncacheLinkTarget' );
                foreach ( $this->cacheIndex[$target->getNamespace()][$target->getDBkey()] as $key ) {
+                       $this->stats->increment( 'WatchedItemStore.uncacheLinkTarget.items' );
                        $this->cache->delete( $key );
                }
        }
@@ -451,8 +467,10 @@ class WatchedItemStore {
 
                $cached = $this->getCached( $user, $target );
                if ( $cached ) {
+                       $this->stats->increment( 'WatchedItemStore.getWatchedItem.cached' );
                        return $cached;
                }
+               $this->stats->increment( 'WatchedItemStore.getWatchedItem.load' );
                return $this->loadWatchedItem( $user, $target );
        }
 
index 4534414..cf97984 100644 (file)
@@ -73,13 +73,8 @@ class WikiMap {
         * @return WikiReference|null WikiReference object or null if the wiki was not found
         */
        private static function getWikiWikiReferenceFromSites( $wikiID ) {
-               static $siteStore = null;
-               if ( !$siteStore ) {
-                       // Replace once T114471 got fixed and don't do the caching here.
-                       $siteStore = SiteSQLStore::newInstance();
-               }
-
-               $site = $siteStore->getSite( $wikiID );
+               $siteLookup = \MediaWiki\MediaWikiServices::getInstance()->getSiteLookup();
+               $site = $siteLookup->getSite( $wikiID );
 
                if ( !$site instanceof MediaWikiSite ) {
                        // Abort if not a MediaWikiSite, as this is about Wikis
index e372511..07642c4 100644 (file)
@@ -1816,53 +1816,6 @@ class ApiMain extends ApiBase {
                return "* $paramName={$module->getModuleName()} $modulePrefix*";
        }
 
-       /**
-        * Check whether the user wants us to show version information in the API help
-        * @return bool
-        * @deprecated since 1.21, always returns false
-        */
-       public function getShowVersions() {
-               wfDeprecated( __METHOD__, '1.21' );
-
-               return false;
-       }
-
-       /**
-        * Add or overwrite a module in this ApiMain instance. Intended for use by extending
-        * classes who wish to add their own modules to their lexicon or override the
-        * behavior of inherent ones.
-        *
-        * @deprecated since 1.21, Use getModuleManager()->addModule() instead.
-        * @param string $name The identifier for this module.
-        * @param ApiBase $class The class where this module is implemented.
-        */
-       protected function addModule( $name, $class ) {
-               $this->getModuleManager()->addModule( $name, 'action', $class );
-       }
-
-       /**
-        * Add or overwrite an output format for this ApiMain. Intended for use by extending
-        * classes who wish to add to or modify current formatters.
-        *
-        * @deprecated since 1.21, Use getModuleManager()->addModule() instead.
-        * @param string $name The identifier for this format.
-        * @param ApiFormatBase $class The class implementing this format.
-        */
-       protected function addFormat( $name, $class ) {
-               $this->getModuleManager()->addModule( $name, 'format', $class );
-       }
-
-       /**
-        * Returns the list of supported formats in form ( 'format' => 'ClassName' )
-        *
-        * @since 1.18
-        * @deprecated since 1.21, Use getModuleManager()'s methods instead.
-        * @return array
-        */
-       public function getFormats() {
-               return $this->getModuleManager()->getNamesWithClasses( 'format' );
-       }
-
        /**@}*/
 
 }
index 6bab762..f278989 100644 (file)
@@ -747,14 +747,6 @@ class ApiPageSet extends ApiBase {
                }
        }
 
-       /**
-        * Do not use, does nothing, will be removed
-        * @deprecated since 1.21
-        */
-       public function finishPageSetGeneration() {
-               wfDeprecated( __METHOD__, '1.21' );
-       }
-
        /**
         * This method populates internal variables with page information
         * based on the given array of title strings.
index 2d1542e..2b23da0 100644 (file)
@@ -20,7 +20,7 @@
        "apihelp-main-param-uselang": "Language to use for message translations. <kbd>[[Special:ApiHelp/query+siteinfo|action=query&meta=siteinfo]]</kbd> with <kbd>siprop=languages</kbd> returns a list of language codes, or specify <kbd>user</kbd> to use the current user's language preference, or specify <kbd>content</kbd> to use this wiki's content language.",
 
        "apihelp-block-description": "Block a user.",
-       "apihelp-block-param-user": "Username, IP address, or IP range to block.",
+       "apihelp-block-param-user": "Username, IP address, or IP address range to block.",
        "apihelp-block-param-expiry": "Expiry time. May be relative (e.g. <kbd>5 months</kbd> or <kbd>2 weeks</kbd>) or absolute (e.g. <kbd>2014-09-18T12:34:56Z</kbd>). If set to <kbd>infinite</kbd>, <kbd>indefinite</kbd>, or <kbd>never</kbd>, the block will never expire.",
        "apihelp-block-param-reason": "Reason for block.",
        "apihelp-block-param-anononly": "Block anonymous users only (i.e. disable anonymous edits for this IP address).",
        "apihelp-imagerotate-example-generator": "Rotate all images in <kbd>Category:Flip</kbd> by <kbd>180</kbd> degrees.",
 
        "apihelp-import-description": "Import a page from another wiki, or from an XML file.\n\nNote that the HTTP POST must be done as a file upload (i.e. using multipart/form-data) when sending a file for the <var>xml</var> parameter.",
-       "apihelp-import-param-summary": "Import summary.",
+       "apihelp-import-param-summary": "Log entry import summary.",
        "apihelp-import-param-xml": "Uploaded XML file.",
        "apihelp-import-param-interwikisource": "For interwiki imports: wiki to import from.",
        "apihelp-import-param-interwikipage": "For interwiki imports: page to import.",
        "apihelp-query+blocks-param-end": "The timestamp to stop enumerating at.",
        "apihelp-query+blocks-param-ids": "List of block IDs to list (optional).",
        "apihelp-query+blocks-param-users": "List of users to search for (optional).",
-       "apihelp-query+blocks-param-ip": "Get all blocks applying to this IP or CIDR range, including range blocks.\nCannot be used together with <var>$3users</var>. CIDR ranges broader than IPv4/$1 or IPv6/$2 are not accepted.",
+       "apihelp-query+blocks-param-ip": "Get all blocks applying to this IP address or CIDR range, including range blocks.\nCannot be used together with <var>$3users</var>. CIDR ranges broader than IPv4/$1 or IPv6/$2 are not accepted.",
        "apihelp-query+blocks-param-limit": "The maximum number of blocks to list.",
        "apihelp-query+blocks-param-prop": "Which properties to get:",
        "apihelp-query+blocks-paramvalue-prop-id": "Adds the ID of the block.",
 
        "apihelp-unblock-description": "Unblock a user.",
        "apihelp-unblock-param-id": "ID of the block to unblock (obtained through <kbd>list=blocks</kbd>). Cannot be used together with <var>$1user</var>.",
-       "apihelp-unblock-param-user": "Username, IP address or IP range to unblock. Cannot be used together with <var>$1id</var>.",
+       "apihelp-unblock-param-user": "Username, IP address or IP address range to unblock. Cannot be used together with <var>$1id</var>.",
        "apihelp-unblock-param-reason": "Reason for unblock.",
        "apihelp-unblock-param-tags": "Change tags to apply to the entry in the block log.",
        "apihelp-unblock-example-id": "Unblock block ID #<kbd>105</kbd>.",
index 6841ab7..c0c405a 100644 (file)
        "apihelp-watch-example-unwatch": "Deixar de vixiar a páxina <kbd>Páxina Principal</kbd>.",
        "apihelp-watch-example-generator": "Vixiar as primeiras páxinas no espazo de nomes principal",
        "apihelp-format-example-generic": "Devolver o resultado da consulta no formato $1.",
+       "apihelp-format-param-wrappedhtml": "Devolver o HTML formatado e os módulos ResourceLoader asociados como un obxecto JSON.",
        "apihelp-json-description": "Datos de saída en formato JSON.",
        "apihelp-json-param-callback": "Se está especificado, inclúe a saída na chamada da función indicada. Para maior seguridade, todos os datos específicos do usuario serán restrinxidos.",
        "apihelp-json-param-utf8": "Se está especificado, codifica a maioría (pero non todos) dos caracteres ASCII como UTF-8 no canto de reemprazalos con secuencias de escape hexadecimais. Por defecto cando <var>formatversion</var> non é <kbd>1</kbd>.",
index 618fbc7..a1058b8 100644 (file)
@@ -39,7 +39,7 @@
        "apihelp-block-param-reblock": "אם המשתמש כבר חסום, לדרוס את החסימה הנוכחית.",
        "apihelp-block-param-watchuser": "לעקוב אחרי דף המשתמש ודף השיחה של המשתמש או של כתובת ה־IP.",
        "apihelp-block-example-ip-simple": "חסימת כתובת ה־IP‏ <kbd>192.0.2.5</kbd> לשלושה ימים עם הסיבה <kbd>First strike</kbd>.",
-       "apihelp-block-example-user-complex": "×\97ס×\99×\9eת ×\94×\9eשת×\9eש <kbd>Vandal</kbd> ×\9c×\9c×\90 ×\94×\92×\91×\9cת ×\96×\9e×\9f ×¢×\9d ×\94ס×\99×\91×\94 <kbd>Vandalism</kbd>, ×\95×\9e× ×\99עת ×\99צ×\99רת ×\97ש×\91×\95×\91ות חדשים ושליחת דוא\"ל.",
+       "apihelp-block-example-user-complex": "×\97ס×\99×\9eת ×\94×\9eשת×\9eש <kbd>Vandal</kbd> ×\9c×\9c×\90 ×\94×\92×\91×\9cת ×\96×\9e×\9f ×¢×\9d ×\94ס×\99×\91×\94 <kbd>Vandalism</kbd>, ×\95×\9e× ×\99עת ×\99צ×\99רת ×\97ש×\91×\95× ות חדשים ושליחת דוא\"ל.",
        "apihelp-checktoken-description": "בדיקת התקינות של האסימון מ־<kbd>[[Special:ApiHelp/query+tokens|action=query&meta=tokens]]</kbd>.",
        "apihelp-checktoken-param-type": "סוג האסימון שבבדיקה.",
        "apihelp-checktoken-param-token": "איזה אסימון לבדוק.",
        "apihelp-query+allusers-paramvalue-prop-groups": "הוספת קבוצות שמשתמש חבר בהן. זה משתמש ביותר משאבי דפדפן ויכול להחזיר פחות תוצאות מהמגבלה.",
        "apihelp-query+allusers-paramvalue-prop-implicitgroups": "לרשום את כל הקבוצות שהמשתמש חבר בהן אוטומטית.",
        "apihelp-query+allusers-paramvalue-prop-rights": "רשימת הההרשאות שיש למשתמש.",
-       "apihelp-query+allusers-paramvalue-prop-editcount": "×\94×\95ספת ×\9e× ×\99×\99×\9f ×\94ער×\99×\9b×\95ת ×©×\9c ×\94×\9eשת×\9eש .",
+       "apihelp-query+allusers-paramvalue-prop-editcount": "×\94×\95ספת ×\9e×\95× ×\94 ×\94ער×\99×\9b×\95ת ×©×\9c ×\94×\9eשת×\9eש.",
        "apihelp-query+allusers-paramvalue-prop-registration": "הוספת חותם־הזמן של זמן הרישום של המשתמש (יכול להיות ריק).",
        "apihelp-query+allusers-paramvalue-prop-centralids": "הוספת המזהה המרכזי ומצב השיוך למשתמש.",
        "apihelp-query+allusers-param-limit": "כמה שמות משתמש בסך הכול לשנות.",
index cde4cf1..4ded4aa 100644 (file)
@@ -18,7 +18,7 @@
        "apihelp-main-description": "{{doc-apihelp-description|main}}",
        "apihelp-main-param-action": "{{doc-apihelp-param|main|action}}",
        "apihelp-main-param-format": "{{doc-apihelp-param|main|format}}",
-       "apihelp-main-param-maxlag": "{{doc-apihelp-param|main|maxlag}}\n\n\"$host\" and \"$lag\" are not variables and appear as is.\n----\n\"Database replication\" is a configuration where you have multiple databases that communicate with each other so they all contain the same data. A \"database replicated cluster\" is a cluster (meaning \"a group of computers that work together\") of databases configured in this manner.\n\n\"Lag\" refers to the situation where one or more of the databases in the cluster are not completely up to date. For example, if the \"master\" database has data up to 2016-01-21T01:23:45Z while one of the \"slave\" is only up to 2016-01-21T01:23:30Z, that's a lag of 15 seconds.\n\nIn this case, \"$lag\" and \"$host\" are syntactic variables rather than computer code variables, so <var> would not be appropriate. They are there to represent that the actual output text will be something like \"Waiting for db1045: 53 seconds lagged.\"",
+       "apihelp-main-param-maxlag": "{{doc-apihelp-param|main|maxlag}}",
        "apihelp-main-param-smaxage": "{{doc-apihelp-param|main|smaxage}}",
        "apihelp-main-param-maxage": "{{doc-apihelp-param|main|maxage}}",
        "apihelp-main-param-assert": "{{doc-apihelp-param|main|assert}}",
index fd7dd77..dd537f6 100644 (file)
@@ -15,7 +15,8 @@
                        "Краснорядцева Елена",
                        "Iniquity",
                        "Лилиә",
-                       "Айсар"
+                       "Айсар",
+                       "Гизатуллина"
                ]
        },
        "apihelp-main-description": "<div class=\"hlist plainlinks api-main-links\">\n* [[mw:API:Main_page|Документация]]\n* [[mw:API:FAQ|ЧаВО]]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api Почтовая рассылка]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api-announce Новости API]\n* [https://phabricator.wikimedia.org/maniphest/query/GebfyV4uCaLd/#R Ошибки и запросы]\n</div>\n<strong>Статус:</strong> Все отображаемые на этой странице функции должны работать, однако API находится в статусе активной разработки и может измениться в любой момент. Подпишитесь на [https://lists.wikimedia.org/pipermail/mediawiki-api-announce/ почтовую рассылку mediawiki-api-announce], чтобы быть в курсе обновлений.\n\n<strong>Ошибочные запросы:</strong> Если API получает запрос с ошибкой, вернётся заголовок HTTP с ключом «MediaWiki-API-Error», после чего значение заголовка и код ошибки будут отправлены обратно и установлены в то же значение. Более подробную информацию см. [[mw:API:Errors_and_warnings|API: Ошибки и предупреждения]].\n\n<strong>Тестирование:</strong> для удобства тестирования API-запросов, см. [[Special:ApiSandbox]].",
        "apihelp-query+categorymembers-param-sort": "Свойство для сортировки.",
        "apihelp-query+categorymembers-param-startsortkey": "Использовать $1starthexsortkey вместо.",
        "apihelp-query+categorymembers-param-endsortkey": "Использовать $1endhexsortkey вместо.",
+       "apihelp-query+deletedrevs-param-limit": "Исемлектәге яҙмаларҙың иң күбе.",
+       "apihelp-query+deletedrevs-example-mode1": "Юҡ ителгән һуңғы биттәрҙең исемлеге, баш биттең<kbd>-һы </kbd> һәм<kbd>әйтергә:баш биттең /kbd>-һы,континент менән(режим 1).",
+       "apihelp-query+deletedrevs-example-mode3-talk": "Юҡ ителгән тәүге 50 биттең исемлеге {{НС:фекер алышыу}} исемдәр арауығы(режим 3).",
        "apihelp-query+duplicatefiles-example-generated": "Поиск дубликатов всех файлов.",
        "apihelp-query+logevents-description": "Получать события из журналов.",
        "apihelp-query+logevents-example-simple": "Список последних зарегистрированных событий.",
index 386ef8c..2c3f58f 100644 (file)
@@ -17,6 +17,9 @@
  *
  * @file
  */
+use Cdb\Exception;
+use Cdb\Reader;
+use Cdb\Writer;
 
 /**
  * LCStore implementation which stores data as a collection of CDB files in the
  */
 class LCStoreCDB implements LCStore {
 
-       /** @var CdbReader[] */
+       /** @var Reader[] */
        private $readers;
 
-       /** @var CdbWriter */
+       /** @var Writer */
        private $writer;
 
        /** @var string Current language code */
@@ -61,8 +64,8 @@ class LCStoreCDB implements LCStore {
                        $this->readers[$code] = false;
                        if ( file_exists( $fileName ) ) {
                                try {
-                                       $this->readers[$code] = CdbReader::open( $fileName );
-                               } catch ( CdbException $e ) {
+                                       $this->readers[$code] = Reader::open( $fileName );
+                               } catch ( Exception $e ) {
                                        wfDebug( __METHOD__ . ": unable to open cdb file for reading\n" );
                                }
                        }
@@ -74,8 +77,8 @@ class LCStoreCDB implements LCStore {
                        $value = false;
                        try {
                                $value = $this->readers[$code]->get( $key );
-                       } catch ( CdbException $e ) {
-                               wfDebug( __METHOD__ . ": CdbException caught, error message was "
+                       } catch ( Exception $e ) {
+                               wfDebug( __METHOD__ . ": \Cdb\Exception caught, error message was "
                                        . $e->getMessage() . "\n" );
                        }
                        if ( $value === false ) {
@@ -100,8 +103,8 @@ class LCStoreCDB implements LCStore {
                }
 
                try {
-                       $this->writer = CdbWriter::open( $this->getFileName( $code ) );
-               } catch ( CdbException $e ) {
+                       $this->writer = Writer::open( $this->getFileName( $code ) );
+               } catch ( Exception $e ) {
                        throw new MWException( $e->getMessage() );
                }
                $this->currentLang = $code;
@@ -111,7 +114,7 @@ class LCStoreCDB implements LCStore {
                // Close the writer
                try {
                        $this->writer->close();
-               } catch ( CdbException $e ) {
+               } catch ( Exception $e ) {
                        throw new MWException( $e->getMessage() );
                }
                $this->writer = null;
@@ -125,7 +128,7 @@ class LCStoreCDB implements LCStore {
                }
                try {
                        $this->writer->set( $key, serialize( $value ) );
-               } catch ( CdbException $e ) {
+               } catch ( Exception $e ) {
                        throw new MWException( $e->getMessage() );
                }
        }
index 946c6d1..d79f316 100644 (file)
@@ -157,8 +157,10 @@ class EnhancedChangesList extends ChangesList {
         * Enhanced RC group
         * @param RCCacheEntry[] $block
         * @return string
+        * @throws DomainException
         */
        protected function recentChangesBlockGroup( $block ) {
+               $recentChangesFlags = $this->getConfig()->get( 'RecentChangesFlags' );
 
                # Add the namespace and title of the block as part of the class
                $tableClasses = [ 'mw-collapsible', 'mw-collapsed', 'mw-enhanced-rc' ];
@@ -186,20 +188,24 @@ class EnhancedChangesList extends ChangesList {
                $namehidden = true;
                $allLogs = true;
                $RCShowChangedSize = $this->getConfig()->get( 'RCShowChangedSize' );
-               $collectedRcFlags = [
-                       // All are by bots?
-                       'bot' => true,
-                       // Includes a new page?
-                       'newpage' => false,
-                       // All are minor edits?
-                       'minor' => true,
-                       // Contains an unpatrolled edit?
-                       'unpatrolled' => false,
-               ];
-               foreach ( $block as $rcObj ) {
-                       if ( $rcObj->mAttribs['rc_type'] == RC_NEW ) {
-                               $collectedRcFlags['newpage'] = true;
+
+               # Default values for RC flags
+               $collectedRcFlags = [];
+               foreach ( $recentChangesFlags as $key => $value ) {
+                       $flagGrouping = ( isset( $recentChangesFlags[$key]['grouping'] ) ?
+                                       $recentChangesFlags[$key]['grouping'] : 'any' );
+                       switch ( $flagGrouping ) {
+                               case 'all':
+                                       $collectedRcFlags[$key] = true;
+                                       break;
+                               case 'any':
+                                       $collectedRcFlags[$key] = false;
+                                       break;
+                               default:
+                                       throw new DomainException( "Unknown grouping type \"{$flagGrouping}\"" );
                        }
+               }
+               foreach ( $block as $rcObj ) {
                        // If all log actions to this page were hidden, then don't
                        // give the name of the affected page for this block!
                        if ( !$this->isDeleted( $rcObj, LogPage::DELETED_ACTION ) ) {
@@ -209,9 +215,6 @@ class EnhancedChangesList extends ChangesList {
                        if ( !isset( $userlinks[$u] ) ) {
                                $userlinks[$u] = 0;
                        }
-                       if ( $rcObj->unpatrolled ) {
-                               $collectedRcFlags['unpatrolled'] = true;
-                       }
                        if ( $rcObj->mAttribs['rc_type'] != RC_LOG ) {
                                $allLogs = false;
                        }
@@ -221,13 +224,6 @@ class EnhancedChangesList extends ChangesList {
                                $curId = $rcObj->mAttribs['rc_cur_id'];
                        }
 
-                       if ( !$rcObj->mAttribs['rc_bot'] ) {
-                               $collectedRcFlags['bot'] = false;
-                       }
-                       if ( !$rcObj->mAttribs['rc_minor'] ) {
-                               $collectedRcFlags['minor'] = false;
-                       }
-
                        $userlinks[$u]++;
                }
 
@@ -267,6 +263,27 @@ class EnhancedChangesList extends ChangesList {
                                // completely ignore this RC entry if we don't want to render it
                                unset( $block[$i] );
                        }
+
+                       // Roll up flags
+                       foreach ( $line['recentChangesFlagsRaw'] as $key => $value ) {
+                               $flagGrouping = ( isset( $recentChangesFlags[$key]['grouping'] ) ?
+                                       $recentChangesFlags[$key]['grouping'] : 'any' );
+                               switch ( $flagGrouping ) {
+                                       case 'all':
+                                               if ( !$value ) {
+                                                       $collectedRcFlags[$key] = false;
+                                               }
+                                               break;
+                                       case 'any':
+                                               if ( $value ) {
+                                                       $collectedRcFlags[$key] = true;
+                                               }
+                                               break;
+                                       default:
+                                               throw new DomainException( "Unknown grouping type \"{$flagGrouping}\"" );
+                               }
+                       }
+
                        $lines[] = $line;
                }
                // Further down are some assumptions that $block is a 0-indexed array
@@ -436,8 +453,11 @@ class EnhancedChangesList extends ChangesList {
                        return [];
                }
 
+               $lineParams['recentChangesFlagsRaw'] = [];
                if ( isset( $data['recentChangesFlags'] ) ) {
                        $lineParams['recentChangesFlags'] = $this->recentChangesFlags( $data['recentChangesFlags'] );
+                       # FIXME: This is used by logic, don't return it in the template params.
+                       $lineParams['recentChangesFlagsRaw'] = $data['recentChangesFlags'];
                        unset( $data['recentChangesFlags'] );
                }
 
diff --git a/includes/collation/Collation.php b/includes/collation/Collation.php
new file mode 100644 (file)
index 0000000..9fb0660
--- /dev/null
@@ -0,0 +1,121 @@
+<?php
+/**
+ * Database row sorting.
+ *
+ * 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
+ */
+
+/**
+ * @since 1.16.3
+ * @author Tim Starling
+ */
+abstract class Collation {
+       private static $instance;
+
+       /**
+        * @since 1.16.3
+        * @return Collation
+        */
+       public static function singleton() {
+               if ( !self::$instance ) {
+                       global $wgCategoryCollation;
+                       self::$instance = self::factory( $wgCategoryCollation );
+               }
+               return self::$instance;
+       }
+
+       /**
+        * @since 1.16.3
+        * @throws MWException
+        * @param string $collationName
+        * @return Collation
+        */
+       public static function factory( $collationName ) {
+               switch ( $collationName ) {
+                       case 'uppercase':
+                               return new UppercaseCollation;
+                       case 'identity':
+                               return new IdentityCollation;
+                       case 'uca-default':
+                               return new IcuCollation( 'root' );
+                       case 'xx-uca-ckb':
+                               return new CollationCkb;
+                       case 'xx-uca-et':
+                               return new CollationEt;
+                       default:
+                               $match = [];
+                               if ( preg_match( '/^uca-([a-z@=-]+)$/', $collationName, $match ) ) {
+                                       return new IcuCollation( $match[1] );
+                               }
+
+                               # Provide a mechanism for extensions to hook in.
+                               $collationObject = null;
+                               Hooks::run( 'Collation::factory', [ $collationName, &$collationObject ] );
+
+                               if ( $collationObject instanceof Collation ) {
+                                       return $collationObject;
+                               }
+
+                               // If all else fails...
+                               throw new MWException( __METHOD__ . ": unknown collation type \"$collationName\"" );
+               }
+       }
+
+       /**
+        * Given a string, convert it to a (hopefully short) key that can be used
+        * for efficient sorting.  A binary sort according to the sortkeys
+        * corresponds to a logical sort of the corresponding strings.  Current
+        * code expects that a line feed character should sort before all others, but
+        * has no other particular expectations (and that one can be changed if
+        * necessary).
+        *
+        * @since 1.16.3
+        *
+        * @param string $string UTF-8 string
+        * @return string Binary sortkey
+        */
+       abstract function getSortKey( $string );
+
+       /**
+        * Given a string, return the logical "first letter" to be used for
+        * grouping on category pages and so on.  This has to be coordinated
+        * carefully with convertToSortkey(), or else the sorted list might jump
+        * back and forth between the same "initial letters" or other pathological
+        * behavior.  For instance, if you just return the first character, but "a"
+        * sorts the same as "A" based on getSortKey(), then you might get a
+        * list like
+        *
+        * == A ==
+        * * [[Aardvark]]
+        *
+        * == a ==
+        * * [[antelope]]
+        *
+        * == A ==
+        * * [[Ape]]
+        *
+        * etc., assuming for the sake of argument that $wgCapitalLinks is false.
+        *
+        * @since 1.16.3
+        *
+        * @param string $string UTF-8 string
+        * @return string UTF-8 string corresponding to the first letter of input
+        */
+       abstract function getFirstLetter( $string );
+
+}
diff --git a/includes/collation/CollationCkb.php b/includes/collation/CollationCkb.php
new file mode 100644 (file)
index 0000000..01a4f7f
--- /dev/null
@@ -0,0 +1,35 @@
+<?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
+ */
+
+/**
+ * Workaround for the lack of support of Sorani Kurdish / Central Kurdish language ('ckb') in ICU.
+ *
+ * Uses the same collation rules as Persian / Farsi ('fa'), but different characters for digits.
+ *
+ * @since 1.23
+ */
+class CollationCkb extends IcuCollation {
+       public function __construct() {
+               // This will set $locale and collators, which affect the actual sorting order
+               parent::__construct( 'fa' );
+               // Override the 'fa' language set by parent constructor, which affects #getFirstLetterData()
+               $this->digitTransformLanguage = Language::factory( 'ckb' );
+       }
+}
diff --git a/includes/collation/CollationEt.php b/includes/collation/CollationEt.php
new file mode 100644 (file)
index 0000000..5dc9fa2
--- /dev/null
@@ -0,0 +1,60 @@
+<?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
+ */
+
+/**
+ * Workaround for incorrect collation of Estonian language ('et') in ICU (bug 54168).
+ *
+ * 'W' and 'V' should not be considered the same letter for the purposes of collation in modern
+ * Estonian. We work around this by replacing 'W' and 'w' with 'ᴡ' U+1D21 'LATIN LETTER SMALL
+ * CAPITAL W' for sortkey generation, which is collated like 'W' and is not tailored to have the
+ * same primary weight as 'V' in Estonian.
+ *
+ * @since 1.24
+ */
+class CollationEt extends IcuCollation {
+       public function __construct() {
+               parent::__construct( 'et' );
+       }
+
+       private static function mangle( $string ) {
+               return str_replace(
+                       [ 'w', 'W' ],
+                       'ᴡ', // U+1D21 'LATIN LETTER SMALL CAPITAL W'
+                       $string
+               );
+       }
+
+       private static function unmangle( $string ) {
+               // Casing data is lost…
+               return str_replace(
+                       'ᴡ', // U+1D21 'LATIN LETTER SMALL CAPITAL W'
+                       'W',
+                       $string
+               );
+       }
+
+       public function getSortKey( $string ) {
+               return parent::getSortKey( self::mangle( $string ) );
+       }
+
+       public function getFirstLetter( $string ) {
+               return self::unmangle( parent::getFirstLetter( self::mangle( $string ) ) );
+       }
+}
diff --git a/includes/collation/IcuCollation.php b/includes/collation/IcuCollation.php
new file mode 100644 (file)
index 0000000..0aa1406
--- /dev/null
@@ -0,0 +1,481 @@
+<?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
+ */
+
+/**
+ * @since 1.16.3
+ */
+class IcuCollation extends Collation {
+       const FIRST_LETTER_VERSION = 2;
+
+       /** @var Collator */
+       private $primaryCollator;
+
+       /** @var Collator */
+       private $mainCollator;
+
+       /** @var string */
+       private $locale;
+
+       /** @var Language */
+       protected $digitTransformLanguage;
+
+       /** @var array */
+       private $firstLetterData;
+
+       /**
+        * Unified CJK blocks.
+        *
+        * The same definition of a CJK block must be used for both Collation and
+        * generateCollationData.php. These blocks are omitted from the first
+        * letter data, as an optimisation measure and because the default UCA table
+        * is pretty useless for sorting Chinese text anyway. Japanese and Korean
+        * blocks are not included here, because they are smaller and more useful.
+        */
+       private static $cjkBlocks = [
+               [ 0x2E80, 0x2EFF ], // CJK Radicals Supplement
+               [ 0x2F00, 0x2FDF ], // Kangxi Radicals
+               [ 0x2FF0, 0x2FFF ], // Ideographic Description Characters
+               [ 0x3000, 0x303F ], // CJK Symbols and Punctuation
+               [ 0x31C0, 0x31EF ], // CJK Strokes
+               [ 0x3200, 0x32FF ], // Enclosed CJK Letters and Months
+               [ 0x3300, 0x33FF ], // CJK Compatibility
+               [ 0x3400, 0x4DBF ], // CJK Unified Ideographs Extension A
+               [ 0x4E00, 0x9FFF ], // CJK Unified Ideographs
+               [ 0xF900, 0xFAFF ], // CJK Compatibility Ideographs
+               [ 0xFE30, 0xFE4F ], // CJK Compatibility Forms
+               [ 0x20000, 0x2A6DF ], // CJK Unified Ideographs Extension B
+               [ 0x2A700, 0x2B73F ], // CJK Unified Ideographs Extension C
+               [ 0x2B740, 0x2B81F ], // CJK Unified Ideographs Extension D
+               [ 0x2F800, 0x2FA1F ], // CJK Compatibility Ideographs Supplement
+       ];
+
+       /**
+        * Additional characters (or character groups) to be considered separate
+        * letters for given languages, or to be removed from the list of such
+        * letters (denoted by keys starting with '-').
+        *
+        * These are additions to (or subtractions from) the data stored in the
+        * first-letters-root.ser file (which among others includes full basic latin,
+        * cyrillic and greek alphabets).
+        *
+        * "Separate letter" is a letter that would have a separate heading/section
+        * for it in a dictionary or a phone book in this language. This data isn't
+        * used for sorting (the ICU library handles that), only for deciding which
+        * characters (or character groups) to use as headings.
+        *
+        * Initially generated based on the primary level of Unicode collation
+        * tailorings available at http://developer.mimer.com/charts/tailorings.htm ,
+        * later modified.
+        *
+        * Empty arrays are intended; this signifies that the data for the language is
+        * available and that there are, in fact, no additional letters to consider.
+        */
+       private static $tailoringFirstLetters = [
+               // Verified by native speakers
+               'be' => [ "Ё" ],
+               'be-tarask' => [ "Ё" ],
+               'cy' => [ "Ch", "Dd", "Ff", "Ng", "Ll", "Ph", "Rh", "Th" ],
+               'en' => [],
+               'fa' => [ "آ", "ء", "ه" ],
+               'fi' => [ "Å", "Ä", "Ö" ],
+               'fr' => [],
+               'hu' => [ "Cs", "Dz", "Dzs", "Gy", "Ly", "Ny", "Ö", "Sz", "Ty", "Ü", "Zs" ],
+               'is' => [ "Á", "Ð", "É", "Í", "Ó", "Ú", "Ý", "Þ", "Æ", "Ö", "Å" ],
+               'it' => [],
+               'lv' => [ "Č", "Ģ", "Ķ", "Ļ", "Ņ", "Š", "Ž" ],
+               'pl' => [ "Ą", "Ć", "Ę", "Ł", "Ń", "Ó", "Ś", "Ź", "Ż" ],
+               'pt' => [],
+               'ru' => [],
+               'sv' => [ "Å", "Ä", "Ö" ],
+               'sv@collation=standard' => [ "Å", "Ä", "Ö" ],
+               'uk' => [ "Ґ", "Ь" ],
+               'vi' => [ "Ă", "Â", "Đ", "Ê", "Ô", "Ơ", "Ư" ],
+               // Not verified, but likely correct
+               'af' => [],
+               'ast' => [ "Ch", "Ll", "Ñ" ],
+               'az' => [ "Ç", "Ə", "Ğ", "İ", "Ö", "Ş", "Ü" ],
+               'bg' => [],
+               'br' => [ "Ch", "C'h" ],
+               'bs' => [ "Č", "Ć", "Dž", "Đ", "Lj", "Nj", "Š", "Ž" ],
+               'ca' => [],
+               'co' => [],
+               'cs' => [ "Č", "Ch", "Ř", "Š", "Ž" ],
+               'da' => [ "Æ", "Ø", "Å" ],
+               'de' => [],
+               'dsb' => [ "Č", "Ć", "Dź", "Ě", "Ch", "Ł", "Ń", "Ŕ", "Š", "Ś", "Ž", "Ź" ],
+               'el' => [],
+               'eo' => [ "Ĉ", "Ĝ", "Ĥ", "Ĵ", "Ŝ", "Ŭ" ],
+               'es' => [ "Ñ" ],
+               'et' => [ "Š", "Ž", "Õ", "Ä", "Ö", "Ü", "W" ], // added W for CollationEt (xx-uca-et)
+               'eu' => [ "Ñ" ],
+               'fo' => [ "Á", "Ð", "Í", "Ó", "Ú", "Ý", "Æ", "Ø", "Å" ],
+               'fur' => [ "À", "Á", "Â", "È", "Ì", "Ò", "Ù" ],
+               'fy' => [],
+               'ga' => [],
+               'gd' => [],
+               'gl' => [ "Ch", "Ll", "Ñ" ],
+               'hr' => [ "Č", "Ć", "Dž", "Đ", "Lj", "Nj", "Š", "Ž" ],
+               'hsb' => [ "Č", "Dź", "Ě", "Ch", "Ł", "Ń", "Ř", "Š", "Ć", "Ž" ],
+               'kk' => [ "Ү", "І" ],
+               'kl' => [ "Æ", "Ø", "Å" ],
+               'ku' => [ "Ç", "Ê", "Î", "Ş", "Û" ],
+               'ky' => [ "Ё" ],
+               'la' => [],
+               'lb' => [],
+               'lt' => [ "Č", "Š", "Ž" ],
+               'mk' => [],
+               'mo' => [ "Ă", "Â", "Î", "Ş", "Ţ" ],
+               'mt' => [ "Ċ", "Ġ", "Għ", "Ħ", "Ż" ],
+               'nl' => [],
+               'no' => [ "Æ", "Ø", "Å" ],
+               'oc' => [],
+               'rm' => [],
+               'ro' => [ "Ă", "Â", "Î", "Ş", "Ţ" ],
+               'rup' => [ "Ă", "Â", "Î", "Ľ", "Ń", "Ş", "Ţ" ],
+               'sco' => [],
+               'sk' => [ "Ä", "Č", "Ch", "Ô", "Š", "Ž" ],
+               'sl' => [ "Č", "Š", "Ž" ],
+               'smn' => [ "Á", "Č", "Đ", "Ŋ", "Š", "Ŧ", "Ž", "Æ", "Ø", "Å", "Ä", "Ö" ],
+               'sq' => [ "Ç", "Dh", "Ë", "Gj", "Ll", "Nj", "Rr", "Sh", "Th", "Xh", "Zh" ],
+               'sr' => [],
+               'tk' => [ "Ç", "Ä", "Ž", "Ň", "Ö", "Ş", "Ü", "Ý" ],
+               'tl' => [ "Ñ", "Ng" ],
+               'tr' => [ "Ç", "Ğ", "İ", "Ö", "Ş", "Ü" ],
+               'tt' => [ "Ә", "Ө", "Ү", "Җ", "Ң", "Һ" ],
+               'uz' => [ "Ch", "G'", "Ng", "O'", "Sh" ],
+       ];
+
+       /**
+        * @since 1.16.3
+        */
+       const RECORD_LENGTH = 14;
+
+       public function __construct( $locale ) {
+               if ( !extension_loaded( 'intl' ) ) {
+                       throw new MWException( 'An ICU collation was requested, ' .
+                               'but the intl extension is not available.' );
+               }
+
+               $this->locale = $locale;
+               // Drop everything after the '@' in locale's name
+               $localeParts = explode( '@', $locale );
+               $this->digitTransformLanguage = Language::factory( $locale === 'root' ? 'en' : $localeParts[0] );
+
+               $this->mainCollator = Collator::create( $locale );
+               if ( !$this->mainCollator ) {
+                       throw new MWException( "Invalid ICU locale specified for collation: $locale" );
+               }
+
+               $this->primaryCollator = Collator::create( $locale );
+               $this->primaryCollator->setStrength( Collator::PRIMARY );
+       }
+
+       public function getSortKey( $string ) {
+               // intl extension produces non null-terminated
+               // strings. Appending '' fixes it so that it doesn't generate
+               // a warning on each access in debug php.
+               MediaWiki\suppressWarnings();
+               $key = $this->mainCollator->getSortKey( $string ) . '';
+               MediaWiki\restoreWarnings();
+               return $key;
+       }
+
+       public function getPrimarySortKey( $string ) {
+               MediaWiki\suppressWarnings();
+               $key = $this->primaryCollator->getSortKey( $string ) . '';
+               MediaWiki\restoreWarnings();
+               return $key;
+       }
+
+       public function getFirstLetter( $string ) {
+               $string = strval( $string );
+               if ( $string === '' ) {
+                       return '';
+               }
+
+               // Check for CJK
+               $firstChar = mb_substr( $string, 0, 1, 'UTF-8' );
+               if ( ord( $firstChar ) > 0x7f && self::isCjk( UtfNormal\Utils::utf8ToCodepoint( $firstChar ) ) ) {
+                       return $firstChar;
+               }
+
+               $sortKey = $this->getPrimarySortKey( $string );
+
+               // Do a binary search to find the correct letter to sort under
+               $min = ArrayUtils::findLowerBound(
+                       [ $this, 'getSortKeyByLetterIndex' ],
+                       $this->getFirstLetterCount(),
+                       'strcmp',
+                       $sortKey );
+
+               if ( $min === false ) {
+                       // Before the first letter
+                       return '';
+               }
+               return $this->getLetterByIndex( $min );
+       }
+
+       /**
+        * @since 1.16.3
+        */
+       public function getFirstLetterData() {
+               if ( $this->firstLetterData !== null ) {
+                       return $this->firstLetterData;
+               }
+
+               $cache = wfGetCache( CACHE_ANYTHING );
+               $cacheKey = wfMemcKey(
+                       'first-letters',
+                       $this->locale,
+                       $this->digitTransformLanguage->getCode(),
+                       self::getICUVersion()
+               );
+               $cacheEntry = $cache->get( $cacheKey );
+
+               if ( $cacheEntry && isset( $cacheEntry['version'] )
+                       && $cacheEntry['version'] == self::FIRST_LETTER_VERSION
+               ) {
+                       $this->firstLetterData = $cacheEntry;
+                       return $this->firstLetterData;
+               }
+
+               // Generate data from serialized data file
+
+               if ( isset( self::$tailoringFirstLetters[$this->locale] ) ) {
+                       $letters = wfGetPrecompiledData( "first-letters-root.ser" );
+                       // Append additional characters
+                       $letters = array_merge( $letters, self::$tailoringFirstLetters[$this->locale] );
+                       // Remove unnecessary ones, if any
+                       if ( isset( self::$tailoringFirstLetters['-' . $this->locale] ) ) {
+                               $letters = array_diff( $letters, self::$tailoringFirstLetters['-' . $this->locale] );
+                       }
+                       // Apply digit transforms
+                       $digits = [ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' ];
+                       $letters = array_diff( $letters, $digits );
+                       foreach ( $digits as $digit ) {
+                               $letters[] = $this->digitTransformLanguage->formatNum( $digit, true );
+                       }
+               } else {
+                       $letters = wfGetPrecompiledData( "first-letters-{$this->locale}.ser" );
+                       if ( $letters === false ) {
+                               throw new MWException( "MediaWiki does not support ICU locale " .
+                                       "\"{$this->locale}\"" );
+                       }
+               }
+
+               /* Sort the letters.
+                *
+                * It's impossible to have the precompiled data file properly sorted,
+                * because the sort order changes depending on ICU version. If the
+                * array is not properly sorted, the binary search will return random
+                * results.
+                *
+                * We also take this opportunity to remove primary collisions.
+                */
+               $letterMap = [];
+               foreach ( $letters as $letter ) {
+                       $key = $this->getPrimarySortKey( $letter );
+                       if ( isset( $letterMap[$key] ) ) {
+                               // Primary collision
+                               // Keep whichever one sorts first in the main collator
+                               if ( $this->mainCollator->compare( $letter, $letterMap[$key] ) < 0 ) {
+                                       $letterMap[$key] = $letter;
+                               }
+                       } else {
+                               $letterMap[$key] = $letter;
+                       }
+               }
+               ksort( $letterMap, SORT_STRING );
+
+               /* Remove duplicate prefixes. Basically if something has a sortkey
+                * which is a prefix of some other sortkey, then it is an
+                * expansion and probably should not be considered a section
+                * header.
+                *
+                * For example 'þ' is sometimes sorted as if it is the letters
+                * 'th'. Other times it is its own primary element. Another
+                * example is '₨'. Sometimes its a currency symbol. Sometimes it
+                * is an 'R' followed by an 's'.
+                *
+                * Additionally an expanded element should always sort directly
+                * after its first element due to they way sortkeys work.
+                *
+                * UCA sortkey elements are of variable length but no collation
+                * element should be a prefix of some other element, so I think
+                * this is safe. See:
+                * - https://ssl.icu-project.org/repos/icu/icuhtml/trunk/design/collation/ICU_collation_design.htm
+                * - http://site.icu-project.org/design/collation/uca-weight-allocation
+                *
+                * Additionally, there is something called primary compression to
+                * worry about. Basically, if you have two primary elements that
+                * are more than one byte and both start with the same byte then
+                * the first byte is dropped on the second primary. Additionally
+                * either \x03 or \xFF may be added to mean that the next primary
+                * does not start with the first byte of the first primary.
+                *
+                * This shouldn't matter much, as the first primary is not
+                * changed, and that is what we are comparing against.
+                *
+                * tl;dr: This makes some assumptions about how icu implements
+                * collations. It seems incredibly unlikely these assumptions
+                * will change, but nonetheless they are assumptions.
+                */
+
+               $prev = false;
+               $duplicatePrefixes = [];
+               foreach ( $letterMap as $key => $value ) {
+                       // Remove terminator byte. Otherwise the prefix
+                       // comparison will get hung up on that.
+                       $trimmedKey = rtrim( $key, "\0" );
+                       if ( $prev === false || $prev === '' ) {
+                               $prev = $trimmedKey;
+                               // We don't yet have a collation element
+                               // to compare against, so continue.
+                               continue;
+                       }
+
+                       // Due to the fact the array is sorted, we only have
+                       // to compare with the element directly previous
+                       // to the current element (skipping expansions).
+                       // An element "X" will always sort directly
+                       // before "XZ" (Unless we have "XY", but we
+                       // do not update $prev in that case).
+                       if ( substr( $trimmedKey, 0, strlen( $prev ) ) === $prev ) {
+                               $duplicatePrefixes[] = $key;
+                               // If this is an expansion, we don't want to
+                               // compare the next element to this element,
+                               // but to what is currently $prev
+                               continue;
+                       }
+                       $prev = $trimmedKey;
+               }
+               foreach ( $duplicatePrefixes as $badKey ) {
+                       wfDebug( "Removing '{$letterMap[$badKey]}' from first letters.\n" );
+                       unset( $letterMap[$badKey] );
+                       // This code assumes that unsetting does not change sort order.
+               }
+               $data = [
+                       'chars' => array_values( $letterMap ),
+                       'keys' => array_keys( $letterMap ),
+                       'version' => self::FIRST_LETTER_VERSION,
+               ];
+
+               // Reduce memory usage before caching
+               unset( $letterMap );
+
+               // Save to cache
+               $this->firstLetterData = $data;
+               $cache->set( $cacheKey, $data, $cache::TTL_WEEK );
+               return $data;
+       }
+
+       /**
+        * @since 1.16.3
+        */
+       public function getLetterByIndex( $index ) {
+               if ( $this->firstLetterData === null ) {
+                       $this->getFirstLetterData();
+               }
+               return $this->firstLetterData['chars'][$index];
+       }
+
+       /**
+        * @since 1.16.3
+        */
+       public function getSortKeyByLetterIndex( $index ) {
+               if ( $this->firstLetterData === null ) {
+                       $this->getFirstLetterData();
+               }
+               return $this->firstLetterData['keys'][$index];
+       }
+
+       /**
+        * @since 1.16.3
+        */
+       public function getFirstLetterCount() {
+               if ( $this->firstLetterData === null ) {
+                       $this->getFirstLetterData();
+               }
+               return count( $this->firstLetterData['chars'] );
+       }
+
+       /**
+        * @since 1.16.3
+        */
+       public static function isCjk( $codepoint ) {
+               foreach ( self::$cjkBlocks as $block ) {
+                       if ( $codepoint >= $block[0] && $codepoint <= $block[1] ) {
+                               return true;
+                       }
+               }
+               return false;
+       }
+
+       /**
+        * Return the version of ICU library used by PHP's intl extension,
+        * or false when the extension is not installed of the version
+        * can't be determined.
+        *
+        * The constant INTL_ICU_VERSION this function refers to isn't really
+        * documented. It is available since PHP 5.3.7 (see PHP bug 54561).
+        * This function will return false on older PHPs.
+        *
+        * @since 1.21
+        * @return string|bool
+        */
+       static function getICUVersion() {
+               return defined( 'INTL_ICU_VERSION' ) ? INTL_ICU_VERSION : false;
+       }
+
+       /**
+        * Return the version of Unicode appropriate for the version of ICU library
+        * currently in use, or false when it can't be determined.
+        *
+        * @since 1.21
+        * @return string|bool
+        */
+       static function getUnicodeVersionForICU() {
+               $icuVersion = IcuCollation::getICUVersion();
+               if ( !$icuVersion ) {
+                       return false;
+               }
+
+               $versionPrefix = substr( $icuVersion, 0, 3 );
+               // Source: http://site.icu-project.org/download
+               $map = [
+                       '50.' => '6.2',
+                       '49.' => '6.1',
+                       '4.8' => '6.0',
+                       '4.6' => '6.0',
+                       '4.4' => '5.2',
+                       '4.2' => '5.1',
+                       '4.0' => '5.1',
+                       '3.8' => '5.0',
+                       '3.6' => '5.0',
+                       '3.4' => '4.1',
+               ];
+
+               if ( isset( $map[$versionPrefix] ) ) {
+                       return $map[$versionPrefix];
+               } else {
+                       return false;
+               }
+       }
+}
diff --git a/includes/collation/IdentityCollation.php b/includes/collation/IdentityCollation.php
new file mode 100644 (file)
index 0000000..46e7f38
--- /dev/null
@@ -0,0 +1,44 @@
+<?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
+ */
+
+/**
+ * Collation class that's essentially a no-op.
+ *
+ * Does sorting based on binary value of the string.
+ * Like how things were pre 1.17.
+ *
+ * @since 1.18
+ */
+class IdentityCollation extends Collation {
+
+       public function getSortKey( $string ) {
+               return $string;
+       }
+
+       public function getFirstLetter( $string ) {
+               global $wgContLang;
+               // Copied from UppercaseCollation.
+               // I'm kind of unclear on when this could happen...
+               if ( $string[0] == "\0" ) {
+                       $string = substr( $string, 1 );
+               }
+               return $wgContLang->firstChar( $string );
+       }
+}
diff --git a/includes/collation/UppercaseCollation.php b/includes/collation/UppercaseCollation.php
new file mode 100644 (file)
index 0000000..92a4c3b
--- /dev/null
@@ -0,0 +1,44 @@
+<?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
+ *
+ * @since 1.16.3
+ *
+ * @file
+ */
+
+class UppercaseCollation extends Collation {
+
+       private $lang;
+
+       public function __construct() {
+               // Get a language object so that we can use the generic UTF-8 uppercase
+               // function there
+               $this->lang = Language::factory( 'en' );
+       }
+
+       public function getSortKey( $string ) {
+               return $this->lang->uc( $string );
+       }
+
+       public function getFirstLetter( $string ) {
+               if ( $string[0] == "\0" ) {
+                       $string = substr( $string, 1 );
+               }
+               return $this->lang->ucfirst( $this->lang->firstChar( $string ) );
+       }
+
+}
index d52103c..4b803d8 100644 (file)
@@ -42,36 +42,12 @@ class ConfigFactory {
        protected $configs = [];
 
        /**
-        * @var ConfigFactory
-        */
-       private static $self;
-
-       /**
+        * @deprecated since 1.27, use MediaWikiServices::getConfigFactory() instead.
+        *
         * @return ConfigFactory
         */
        public static function getDefaultInstance() {
-               if ( !self::$self ) {
-                       self::$self = new self;
-                       global $wgConfigRegistry;
-                       foreach ( $wgConfigRegistry as $name => $callback ) {
-                               self::$self->register( $name, $callback );
-                       }
-               }
-               return self::$self;
-       }
-
-       /**
-        * Destroy the default instance
-        * Should only be called inside unit tests
-        * @throws MWException
-        * @codeCoverageIgnore
-        */
-       public static function destroyDefaultInstance() {
-               if ( !defined( 'MW_PHPUNIT_TEST' ) ) {
-                       throw new MWException( __METHOD__ . ' was called outside of unit tests' );
-               }
-
-               self::$self = null;
+               return \MediaWiki\MediaWikiServices::getInstance()->getConfigFactory();
        }
 
        /**
index 1e27205..13be911 100644 (file)
@@ -34,6 +34,8 @@ abstract class DatabaseMysqlBase extends Database {
        protected $lastKnownSlavePos;
        /** @var string Method to detect slave lag */
        protected $lagDetectionMethod;
+       /** @var array Method to detect slave lag */
+       protected $lagDetectionOptions = [];
 
        /** @var string|null */
        private $serverVersion = null;
@@ -44,6 +46,10 @@ abstract class DatabaseMysqlBase extends Database {
         *                          pt-heartbeat assumes the table is at heartbeat.heartbeat
         *                          and uses UTC timestamps in the heartbeat.ts column.
         *                          (https://www.percona.com/doc/percona-toolkit/2.2/pt-heartbeat.html)
+        *   - lagDetectionOptions : if using pt-heartbeat, this can be set to an array map to change
+        *                           the default behavior. Normally, the heartbeat row with the server
+        *                           ID of this server's master will be used. Set the "conds" field to
+        *                           override the query conditions, e.g. ['shard' => 's1'].
         * @param array $params
         */
        function __construct( array $params ) {
@@ -52,6 +58,9 @@ abstract class DatabaseMysqlBase extends Database {
                $this->lagDetectionMethod = isset( $params['lagDetectionMethod'] )
                        ? $params['lagDetectionMethod']
                        : 'Seconds_Behind_Master';
+               $this->lagDetectionOptions = isset( $params['lagDetectionOptions'] )
+                       ? $params['lagDetectionOptions']
+                       : [];
        }
 
        /**
@@ -652,19 +661,30 @@ abstract class DatabaseMysqlBase extends Database {
         * @return bool|float
         */
        protected function getLagFromPtHeartbeat() {
-               $masterInfo = $this->getMasterServerInfo();
-               if ( !$masterInfo ) {
-                       wfLogDBError(
-                               "Unable to query master of {db_server} for server ID",
-                               $this->getLogContext( [
-                                       'method' => __METHOD__
-                               ] )
-                       );
+               $options = $this->lagDetectionOptions;
+
+               if ( isset( $options['conds'] ) ) {
+                       // Best method for multi-DC setups: use logical channel names
+                       $data = $this->getHeartbeatData( $options['conds'] );
+               } else {
+                       // Standard method: use master server ID (works with stock pt-heartbeat)
+                       $masterInfo = $this->getMasterServerInfo();
+                       if ( !$masterInfo ) {
+                               wfLogDBError(
+                                       "Unable to query master of {db_server} for server ID",
+                                       $this->getLogContext( [
+                                               'method' => __METHOD__
+                                       ] )
+                               );
+
+                               return false; // could not get master server ID
+                       }
 
-                       return false; // could not get master server ID
+                       $conds = [ 'server_id' => intval( $masterInfo['serverId'] ) ];
+                       $data = $this->getHeartbeatData( $conds );
                }
 
-               list( $time, $nowUnix ) = $this->getHeartbeatData( $masterInfo['serverId'] );
+               list( $time, $nowUnix ) = $data;
                if ( $time !== null ) {
                        // @time is in ISO format like "2015-09-25T16:48:10.000510"
                        $dateTime = new DateTime( $time, new DateTimeZone( 'UTC' ) );
@@ -722,17 +742,17 @@ abstract class DatabaseMysqlBase extends Database {
        }
 
        /**
-        * @param string $masterId Server ID
-        * @return array (heartbeat `ts` column value or null, UNIX timestamp)
+        * @param array $conds WHERE clause conditions to find a row
+        * @return array (heartbeat `ts` column value or null, UNIX timestamp) for the newest beat
         * @see https://www.percona.com/doc/percona-toolkit/2.1/pt-heartbeat.html
         */
-       protected function getHeartbeatData( $masterId ) {
-               // Get the status row for this master; use the oldest for sanity in case the master
-               // has entries listed under different server IDs (which should really not happen).
-               // Note: this would use "MAX(TIMESTAMPDIFF(MICROSECOND,ts,UTC_TIMESTAMP(6)))" but the
+       protected function getHeartbeatData( array $conds ) {
+               $whereSQL = $this->makeList( $conds, LIST_AND );
+               // Use ORDER BY for channel based queries since that field might not be UNIQUE.
+               // Note: this would use "TIMESTAMPDIFF(MICROSECOND,ts,UTC_TIMESTAMP(6))" but the
                // percision field is not supported in MySQL <= 5.5.
                $res = $this->query(
-                       "SELECT ts FROM heartbeat.heartbeat WHERE server_id=" . intval( $masterId )
+                       "SELECT ts FROM heartbeat.heartbeat WHERE $whereSQL ORDER BY ts DESC LIMIT 1"
                );
                $row = $res ? $res->fetchObject() : false;
 
index 997efa6..741999c 100644 (file)
@@ -161,19 +161,6 @@ class LoadBalancer {
                return wfSetVar( $this->mParentInfo, $x );
        }
 
-       /**
-        * Given an array of non-normalised probabilities, this function will select
-        * an element and return the appropriate key
-        *
-        * @deprecated since 1.21, use ArrayUtils::pickRandom()
-        *
-        * @param array $weights
-        * @return bool|int|string
-        */
-       public function pickRandom( array $weights ) {
-               return ArrayUtils::pickRandom( $weights );
-       }
-
        /**
         * @param array $loads
         * @param bool|string $wiki Wiki to get non-lagged for
index 4fdacc5..1508cf1 100644 (file)
@@ -1152,19 +1152,6 @@ class DifferenceEngine extends ContextSource {
                return $header . $diff . "</table>";
        }
 
-       /**
-        * Use specified text instead of loading from the database
-        * @deprecated since 1.21, use setContent() instead.
-        */
-       public function setText( $oldText, $newText ) {
-               ContentHandler::deprecated( __METHOD__, "1.21" );
-
-               $oldContent = ContentHandler::makeContent( $oldText, $this->getTitle() );
-               $newContent = ContentHandler::makeContent( $newText, $this->getTitle() );
-
-               $this->setContent( $oldContent, $newContent );
-       }
-
        /**
         * Use specified text instead of loading from the database
         * @param Content $oldContent
index 6606ca3..76a88d5 100644 (file)
@@ -53,7 +53,7 @@ class HTMLAutoCompleteSelectField extends HTMLTextField {
                $this->getOptions();
                if ( $this->mOptions && !in_array( 'other', $this->mOptions, true ) ) {
                        if ( isset( $params['other-message'] ) ) {
-                               $msg = wfMessage( $params['other-message'] )->text();
+                               $msg = $this->getMessage( $params['other-message'] )->text();
                        } elseif ( isset( $params['other'] ) ) {
                                $msg = $params['other'];
                        } else {
index 16417fc..70bbf6c 100644 (file)
@@ -35,16 +35,7 @@ class HTMLButtonField extends HTMLFormField {
 
                # Generate the label from a message, if possible
                if ( isset( $info['buttonlabel-message'] ) ) {
-                       $msgInfo = $info['buttonlabel-message'];
-
-                       if ( is_array( $msgInfo ) ) {
-                               $msg = array_shift( $msgInfo );
-                       } else {
-                               $msg = $msgInfo;
-                               $msgInfo = [];
-                       }
-
-                       $this->buttonLabel = $this->msg( $msg, $msgInfo )->parse();
+                       $this->buttonLabel = $this->getMessage( $info['buttonlabel-message'] )->parse();
                } elseif ( isset( $info['buttonlabel'] ) ) {
                        if ( $info['buttonlabel'] === '&#160;' ) {
                                // Apparently some things set &nbsp directly and in an odd format
@@ -79,13 +70,14 @@ class HTMLButtonField extends HTMLFormField {
                        'id' => $this->mID,
                        'type' => $this->buttonType,
                        'name' => $this->mName,
-                       'value' => $value,
+                       'value' => $this->getDefault(),
                ] + $this->getAttributes( [ 'disabled', 'tabindex' ] );
 
                if ( $this->isBadIE() ) {
                        return Html::element( 'input', $attr );
                } else {
-                       return Html::rawElement( 'button', $attr, $this->buttonLabel ?: htmlspecialchars( $value ) );
+                       return Html::rawElement( 'button', $attr,
+                               $this->buttonLabel ?: htmlspecialchars( $this->getDefault() ) );
                }
        }
 
@@ -97,10 +89,10 @@ class HTMLButtonField extends HTMLFormField {
        public function getInputOOUI( $value ) {
                return new OOUI\ButtonInputWidget( [
                        'name' => $this->mName,
-                       'value' => $value,
+                       'value' => $this->getDefault(),
                        'label' => !$this->isBadIE() && $this->buttonLabel
                                ? new OOUI\HtmlSnippet( $this->buttonLabel )
-                               : $value,
+                               : $this->getDefault(),
                        'type' => $this->buttonType,
                        'classes' => [ 'mw-htmlform-submit', $this->mClass ],
                        'id' => $this->mID,
index 77924ef..1b5d1fb 100644 (file)
@@ -39,7 +39,7 @@ class HTMLEditTools extends HTMLFormField {
                if ( empty( $this->mParams['message'] ) ) {
                        $msg = $this->msg( 'edittools' );
                } else {
-                       $msg = $this->msg( $this->mParams['message'] );
+                       $msg = $this->getMessage( $this->mParams['message'] );
                        if ( $msg->isDisabled() ) {
                                $msg = $this->msg( 'edittools' );
                        }
index bf46e55..d50fac0 100644 (file)
  *                             Some field types support multi-level arrays.
  *    'options-messages'    -- associative array mapping message keys to values.
  *                             Some field types support multi-level arrays.
- *    'options-message'     -- message key to be parsed to extract the list of
+ *    'options-message'     -- message key or object to be parsed to extract the list of
  *                             options (like 'ipbreason-dropdown').
- *    'label-message'       -- message key for a message to use as the label.
+ *    'label-message'       -- message key or object for a message to use as the label.
  *                             can be an array of msg key and then parameters to
  *                             the message.
  *    'label'               -- alternatively, a raw text message. Overridden by
  *                             label-message
  *    'help'                -- message text for a message to use as a help text.
- *    'help-message'        -- message key for a message to use as a help text.
+ *    'help-message'        -- message key or object for a message to use as a help text.
  *                             can be an array of msg key and then parameters to
  *                             the message.
  *                             Overwrites 'help-messages' and 'help'.
- *    'help-messages'       -- array of message key. As above, each item can
+ *    'help-messages'       -- array of message keys/objects. As above, each item can
  *                             be an array of msg key and then parameters.
  *                             Overwrites 'help'.
  *    'required'            -- passed through to the object, indicating that it
@@ -180,6 +180,7 @@ class HTMLForm extends ContextSource {
        protected $mSectionFooters = [];
        protected $mPost = '';
        protected $mId;
+       protected $mName;
        protected $mTableId = '';
 
        protected $mSubmitID;
@@ -1006,6 +1007,9 @@ class HTMLForm extends ContextSource {
                if ( !empty( $this->mAutocomplete ) ) {
                        $attribs['autocomplete'] = $this->mAutocomplete;
                }
+               if ( !empty ( $this->mName ) ) {
+                       $attribs['name'] = $this->mName;
+               }
                return $attribs;
        }
 
@@ -1347,6 +1351,16 @@ class HTMLForm extends ContextSource {
                return $this;
        }
 
+       /**
+        * @param string $name 'name' attribute for the form
+        * @return HTMLForm $this for chaining calls
+        */
+       public function setName( $name ) {
+               $this->mName = $name;
+
+               return $this;
+       }
+
        /**
         * Prompt the whole form to be wrapped in a "<fieldset>", with
         * this text as its "<legend>" element.
index a9c7632..e86d4c4 100644 (file)
@@ -179,7 +179,7 @@ abstract class HTMLFormField {
                                        return true;
 
                                case 'OR':
-                                       foreach ( $params as $p ) {
+                                       foreach ( $params as $i => $p ) {
                                                if ( !is_array( $p ) ) {
                                                        throw new MWException(
                                                                "Expected array, found " . gettype( $p ) . " at index $i"
@@ -205,7 +205,7 @@ abstract class HTMLFormField {
                                        return false;
 
                                case 'NOR':
-                                       foreach ( $params as $p ) {
+                                       foreach ( $params as $i => $p ) {
                                                if ( !is_array( $p ) ) {
                                                        throw new MWException(
                                                                "Expected array, found " . gettype( $p ) . " at index $i"
@@ -381,16 +381,7 @@ abstract class HTMLFormField {
 
                # Generate the label from a message, if possible
                if ( isset( $params['label-message'] ) ) {
-                       $msgInfo = $params['label-message'];
-
-                       if ( is_array( $msgInfo ) ) {
-                               $msg = array_shift( $msgInfo );
-                       } else {
-                               $msg = $msgInfo;
-                               $msgInfo = [];
-                       }
-
-                       $this->mLabel = $this->msg( $msg, $msgInfo )->parse();
+                       $this->mLabel = $this->getMessage( $params['label-message'] )->parse();
                } elseif ( isset( $params['label'] ) ) {
                        if ( $params['label'] === '&#160;' ) {
                                // Apparently some things set &nbsp directly and in an odd format
@@ -783,9 +774,8 @@ abstract class HTMLFormField {
                }
 
                if ( isset( $this->mParams['help-messages'] ) ) {
-                       foreach ( $this->mParams['help-messages'] as $name ) {
-                               $helpMessage = (array)$name;
-                               $msg = $this->msg( array_shift( $helpMessage ), $helpMessage );
+                       foreach ( $this->mParams['help-messages'] as $msg ) {
+                               $msg = $this->getMessage( $msg );
 
                                if ( $msg->exists() ) {
                                        if ( is_null( $helptext ) ) {
@@ -988,7 +978,7 @@ abstract class HTMLFormField {
                                $this->mOptions = self::forceToStringRecursive( $this->mParams['options'] );
                        } elseif ( array_key_exists( 'options-message', $this->mParams ) ) {
                                /** @todo This is copied from Xml::listDropDown(), deprecate/avoid duplication? */
-                               $message = $this->msg( $this->mParams['options-message'] )->inContentLanguage()->plain();
+                               $message = $this->getMessage( $this->mParams['options-message'] )->inContentLanguage()->plain();
 
                                $optgroup = false;
                                $this->mOptions = [];
@@ -1097,4 +1087,23 @@ abstract class HTMLFormField {
                        return Html::rawElement( 'span', [ 'class' => 'error' ], $errors );
                }
        }
+
+       /**
+        * Turns a *-message parameter (which could be a MessageSpecifier, or a message name, or a
+        * name + parameters array) into a Message.
+        * @param mixed $value
+        * @return Message
+        */
+       protected function getMessage( $value ) {
+               if ( $value instanceof Message ) {
+                       return $value;
+               } elseif ( $value instanceof MessageSpecifier ) {
+                       return Message::newFromKey( $value );
+               } elseif ( is_array( $value ) ) {
+                       $msg = array_shift( $value );
+                       return $this->msg( $msg, $value );
+               } else {
+                       return $this->msg( $value, [] );
+               }
+       }
 }
index 6553b56..4f2460f 100644 (file)
@@ -14,9 +14,9 @@
  *     'table', 'div', or 'raw'.
  *   row-legend - If non-empty, each group of subfields will be enclosed in a
  *     fieldset. The value is the name of a message key to use as the legend.
- *   create-button-message - Message key to use as the text of the button to
+ *   create-button-message - Message to use as the text of the button to
  *     add an additional group of fields.
- *   delete-button-message - Message key to use as the text of automatically-
+ *   delete-button-message - Message to use as the text of automatically-
  *     generated 'delete' button. Ignored if 'delete' is included in 'fields'.
  *
  * In the generated HTML, the subfields will be named along the lines of
@@ -299,7 +299,7 @@ class HTMLFormFieldCloner extends HTMLFormField {
                                'name' => $name,
                                'id' => Sanitizer::escapeId( "{$this->mID}--$key--delete" ),
                                'cssclass' => 'mw-htmlform-cloner-delete-button',
-                               'default' => $this->msg( $label )->text(),
+                               'default' => $this->getMessage( $label )->text(),
                        ], $this->mParent );
                        $v = $field->getDefault();
 
@@ -371,7 +371,7 @@ class HTMLFormFieldCloner extends HTMLFormField {
                        'name' => $name,
                        'id' => Sanitizer::escapeId( "{$this->mID}--create" ),
                        'cssclass' => 'mw-htmlform-cloner-create-button',
-                       'default' => $this->msg( $label )->text(),
+                       'default' => $this->getMessage( $label )->text(),
                ], $this->mParent );
                $html .= $field->getInputHTML( $field->getDefault() );
 
index e44ffa3..e75c2b2 100644 (file)
@@ -15,9 +15,9 @@ class HTMLSelectAndOtherField extends HTMLSelectField {
                if ( array_key_exists( 'other', $params ) ) {
                        // Do nothing
                } elseif ( array_key_exists( 'other-message', $params ) ) {
-                       $params['other'] = wfMessage( $params['other-message'] )->plain();
+                       $params['other'] = $this->getMessage( $params['other-message'] )->plain();
                } else {
-                       $params['other'] = wfMessage( 'htmlform-selectorother-other' )->plain();
+                       $params['other'] = $this->msg( 'htmlform-selectorother-other' )->plain();
                }
 
                parent::__construct( $params );
index 973f1cb..8ffff43 100644 (file)
@@ -4,6 +4,24 @@ class HTMLTextAreaField extends HTMLFormField {
        const DEFAULT_COLS = 80;
        const DEFAULT_ROWS = 25;
 
+       protected $mPlaceholder = '';
+
+       /**
+        * @param array $params
+        *   - cols, rows: textarea size
+        *   - placeholder/placeholder-message: set HTML placeholder attribute
+        *   - spellcheck: set HTML spellcheck attribute
+        */
+       public function __construct( $params ) {
+               parent::__construct( $params );
+
+               if ( isset( $params['placeholder-message'] ) ) {
+                       $this->mPlaceholder = $this->getMessage( $params['placeholder-message'] )->parse();
+               } elseif ( isset( $params['placeholder'] ) ) {
+                       $this->mPlaceholder = $params['placeholder'];
+               }
+       }
+
        function getCols() {
                return isset( $this->mParams['cols'] ) ? $this->mParams['cols'] : static::DEFAULT_COLS;
        }
@@ -32,9 +50,11 @@ class HTMLTextAreaField extends HTMLFormField {
                if ( $this->mClass !== '' ) {
                        $attribs['class'] = $this->mClass;
                }
+               if ( $this->mPlaceholder !== '' ) {
+                       $attribs['placeholder'] = $this->mPlaceholder;
+               }
 
                $allowedParams = [
-                       'placeholder',
                        'tabindex',
                        'disabled',
                        'readonly',
@@ -56,9 +76,11 @@ class HTMLTextAreaField extends HTMLFormField {
                if ( $this->mClass !== '' ) {
                        $attribs['classes'] = [ $this->mClass ];
                }
+               if ( $this->mPlaceholder !== '' ) {
+                       $attribs['placeholder'] = $this->mPlaceholder;
+               }
 
                $allowedParams = [
-                       'placeholder',
                        'tabindex',
                        'disabled',
                        'readonly',
index 4d5bcab..3ab7176 100644 (file)
@@ -1,6 +1,27 @@
 <?php
 
 class HTMLTextField extends HTMLFormField {
+       protected $mPlaceholder = '';
+
+       /**
+        * @param array $params
+        *   - type: HTML textfield type
+        *   - size: field size in characters (defaults to 45)
+        *   - placeholder/placeholder-message: set HTML placeholder attribute
+        *   - spellcheck: set HTML spellcheck attribute
+        *   - persistent: upon unsuccessful requests, retain the value (defaults to true, except
+        *     for password fields)
+        */
+       public function __construct( $params ) {
+               parent::__construct( $params );
+
+               if ( isset( $params['placeholder-message'] ) ) {
+                       $this->mPlaceholder = $this->getMessage( $params['placeholder-message'] )->parse();
+               } elseif ( isset( $params['placeholder'] ) ) {
+                       $this->mPlaceholder = $params['placeholder'];
+               }
+       }
+
        function getSize() {
                return isset( $this->mParams['size'] ) ? $this->mParams['size'] : 45;
        }
@@ -14,7 +35,19 @@ class HTMLTextField extends HTMLFormField {
                return null;
        }
 
+       public function isPersistent() {
+               if ( isset( $this->mParams['persistent'] ) ) {
+                       return $this->mParams['persistent'];
+               }
+               // don't put passwords into the HTML body, they could get cached or otherwise leaked
+               return !( isset( $this->mParams['type'] ) && $this->mParams['type'] === 'password' );
+       }
+
        function getInputHTML( $value ) {
+               if ( !$this->isPersistent() ) {
+                       $value = '';
+               }
+
                $attribs = [
                                'id' => $this->mID,
                                'name' => $this->mName,
@@ -27,6 +60,9 @@ class HTMLTextField extends HTMLFormField {
                if ( $this->mClass !== '' ) {
                        $attribs['class'] = $this->mClass;
                }
+               if ( $this->mPlaceholder !== '' ) {
+                       $attribs['placeholder'] = $this->mPlaceholder;
+               }
 
                # @todo Enforce pattern, step, required, readonly on the server side as
                # well
@@ -37,7 +73,6 @@ class HTMLTextField extends HTMLFormField {
                        'pattern',
                        'title',
                        'step',
-                       'placeholder',
                        'list',
                        'maxlength',
                        'tabindex',
@@ -85,11 +120,18 @@ class HTMLTextField extends HTMLFormField {
        }
 
        function getInputOOUI( $value ) {
+               if ( !$this->isPersistent() ) {
+                       $value = '';
+               }
+
                $attribs = $this->getTooltipAndAccessKey();
 
                if ( $this->mClass !== '' ) {
                        $attribs['classes'] = [ $this->mClass ];
                }
+               if ( $this->mPlaceholder !== '' ) {
+                       $attribs['placeholder'] = $this->mPlaceholder;
+               }
 
                # @todo Enforce pattern, step, required, readonly on the server side as
                # well
@@ -100,7 +142,6 @@ class HTMLTextField extends HTMLFormField {
                        'flags',
                        'indicator',
                        'maxlength',
-                       'placeholder',
                        'readonly',
                        'required',
                        'tabindex',
index 0f7748d..1d5d779 100644 (file)
@@ -31,9 +31,9 @@
        "config-localsettings-cli-upgrade": "Wykryto obecność pliku <code>LocalSettings.php</code>.\nAktualizację należy wykonać poprzez uruchomienie <code>update.php</code>",
        "config-localsettings-key": "Klucz aktualizacji:",
        "config-localsettings-badkey": "Podany klucz aktualizacji jest nieprawidłowy.",
-       "config-upgrade-key-missing": "Wykryto zainstalowane wcześniej MediaWiki.\nJeśli chcesz je zaktualizować dodaj na koniec pliku <code>LocalSettings.php</code> poniższą linię tekstu.\n\n$1",
+       "config-upgrade-key-missing": "Wykryto zainstalowane wcześniej MediaWiki.\nJeśli chcesz je zaktualizować, dodaj na koniec pliku <code>LocalSettings.php</code> poniższą linię tekstu:\n\n$1",
        "config-localsettings-incomplete": "Istniejący plik <code>LocalSettings.php</code> wygląda na niekompletny.\nBrak wartości zmiennej $1.\nZmień plik <code>LocalSettings.php</code>, tak by zawierał deklarację wartości tej zmiennej, a następnie kliknij „{{int:Config-continue}}”.",
-       "config-localsettings-connection-error": "Wystąpił błąd podczas łączenia z bazą danych używając ustawień podanych w <code>LocalSettings.php</code>\nNapraw te ustawienia i spróbuj ponownie.\n\n$1",
+       "config-localsettings-connection-error": "Wystąpił błąd podczas łączenia z bazą danych używając ustawień podanych w <code>LocalSettings.php</code>.\nNapraw te ustawienia i spróbuj ponownie.\n\n$1",
        "config-session-error": "Błąd uruchomienia sesji – $1",
        "config-session-expired": "Wygląda na to, że Twoja sesja wygasła.\nCzas życia sesji został skonfigurowany na $1.\nMożesz go wydłużyć zmieniając <code>session.gc_maxlifetime</code> w pliku php.ini.\nUruchom ponownie proces instalacji.",
        "config-no-session": "Dane sesji zostały utracone.\nSprawdź plik php.ini i upewnij się, że <code>session.save_path</code> wskazuje na odpowiedni katalog.",
@@ -85,6 +85,7 @@
        "config-xcache": "[Http://trac.lighttpd.net/xcache/ XCache] jest zainstalowany",
        "config-apc": "[Http://www.php.net/apc APC] jest zainstalowany",
        "config-wincache": "[http://www.iis.net/download/WinCacheForPhp WinCache] jest zainstalowany",
+       "config-no-cache-apcu": "<strong>Ostrzeżenie:</strong> Nie można znaleźć [http://www.php.net/apcu APCu], [http://xcache.lighttpd.net/ XCache] lub [http://www.iis.net/download/WinCacheForPhp WinCache].\nPamięć podręczna obiektów nie zostanie włączona.",
        "config-mod-security": "''' Ostrzeżenie ''': Serwer sieci web ma włączone [http://modsecurity.org/ mod_security]. Jeśli jest niepoprawnie skonfigurowane, może być przyczyną problemów MediaWiki lub innego oprogramowania, które pozwala użytkownikom na wysyłanie dowolnej zawartości.\nSprawdź w [http://modsecurity.org/documentation/ dokumentacji mod_security] lub skontaktuj się z obsługa hosta, jeśli wystąpią losowe błędy.",
        "config-diff3-bad": "Nie znaleziono GNU diff3.",
        "config-git": "Znaleziono oprogramowanie kontroli wersji Git: <code>$1</code>.",
diff --git a/includes/libs/BufferingStatsdDataFactory.php b/includes/libs/BufferingStatsdDataFactory.php
deleted file mode 100644 (file)
index 9c18b10..0000000
+++ /dev/null
@@ -1,87 +0,0 @@
-<?php
-/**
- * Copyright 2015
- *
- * 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
- */
-
-use Liuggio\StatsdClient\Entity\StatsdData;
-use Liuggio\StatsdClient\Entity\StatsdDataInterface;
-use Liuggio\StatsdClient\Factory\StatsdDataFactory;
-
-/**
- * A factory for application metric data.
- *
- * This class prepends a context-specific prefix to each metric key and keeps
- * a reference to each constructed metric in an internal array buffer.
- *
- * @since 1.25
- */
-class BufferingStatsdDataFactory extends StatsdDataFactory {
-       protected $buffer = [];
-
-       public function __construct( $prefix ) {
-               parent::__construct();
-               $this->prefix = $prefix;
-       }
-
-       /**
-        * Normalize a metric key for StatsD
-        *
-        * Replace occurences of '::' with dots and any other non-alphanumeric
-        * characters with underscores. Combine runs of dots or underscores.
-        * Then trim leading or trailing dots or underscores.
-        *
-        * @param string $key
-        * @since 1.26
-        */
-       private static function normalizeMetricKey( $key ) {
-               $key = preg_replace( '/[:.]+/', '.', $key );
-               $key = preg_replace( '/[^a-z0-9.]+/i', '_', $key );
-               $key = trim( $key, '_.' );
-               return str_replace( [ '._', '_.' ], '.', $key );
-       }
-
-       public function produceStatsdData(
-               $key, $value = 1, $metric = StatsdDataInterface::STATSD_METRIC_COUNT
-       ) {
-               $entity = $this->produceStatsdDataEntity();
-               if ( $key !== null ) {
-                       $key = self::normalizeMetricKey( "{$this->prefix}.{$key}" );
-                       $entity->setKey( $key );
-               }
-               if ( $value !== null ) {
-                       $entity->setValue( $value );
-               }
-               if ( $metric !== null ) {
-                       $entity->setMetric( $metric );
-               }
-               // Don't bother buffering a counter update with a delta of zero.
-               if ( !( $metric === StatsdDataInterface::STATSD_METRIC_COUNT && !$value ) ) {
-                       $this->buffer[] = $entity;
-               }
-               return $entity;
-       }
-
-       /**
-        * @return StatsdData[]
-        */
-       public function getBuffer() {
-               return $this->buffer;
-       }
-}
index cc236e2..a67b919 100644 (file)
@@ -206,86 +206,3 @@ class Cookie {
                return $this->isSessionKey || $this->expires > time();
        }
 }
-
-class CookieJar {
-       private $cookie = [];
-
-       /**
-        * Set a cookie in the cookie jar. Make sure only one cookie per-name exists.
-        * @see Cookie::set()
-        * @param string $name
-        * @param string $value
-        * @param array $attr
-        */
-       public function setCookie( $name, $value, $attr ) {
-               /* cookies: case insensitive, so this should work.
-                * We'll still send the cookies back in the same case we got them, though.
-                */
-               $index = strtoupper( $name );
-
-               if ( isset( $this->cookie[$index] ) ) {
-                       $this->cookie[$index]->set( $value, $attr );
-               } else {
-                       $this->cookie[$index] = new Cookie( $name, $value, $attr );
-               }
-       }
-
-       /**
-        * @see Cookie::serializeToHttpRequest
-        * @param string $path
-        * @param string $domain
-        * @return string
-        */
-       public function serializeToHttpRequest( $path, $domain ) {
-               $cookies = [];
-
-               foreach ( $this->cookie as $c ) {
-                       $serialized = $c->serializeToHttpRequest( $path, $domain );
-
-                       if ( $serialized ) {
-                               $cookies[] = $serialized;
-                       }
-               }
-
-               return implode( '; ', $cookies );
-       }
-
-       /**
-        * Parse the content of an Set-Cookie HTTP Response header.
-        *
-        * @param string $cookie
-        * @param string $domain Cookie's domain
-        * @return null
-        */
-       public function parseCookieResponseHeader( $cookie, $domain ) {
-               $len = strlen( 'Set-Cookie:' );
-
-               if ( substr_compare( 'Set-Cookie:', $cookie, 0, $len, true ) === 0 ) {
-                       $cookie = substr( $cookie, $len );
-               }
-
-               $bit = array_map( 'trim', explode( ';', $cookie ) );
-
-               if ( count( $bit ) >= 1 ) {
-                       list( $name, $value ) = explode( '=', array_shift( $bit ), 2 );
-                       $attr = [];
-
-                       foreach ( $bit as $piece ) {
-                               $parts = explode( '=', $piece );
-                               if ( count( $parts ) > 1 ) {
-                                       $attr[strtolower( $parts[0] )] = $parts[1];
-                               } else {
-                                       $attr[strtolower( $parts[0] )] = true;
-                               }
-                       }
-
-                       if ( !isset( $attr['domain'] ) ) {
-                               $attr['domain'] = $domain;
-                       } elseif ( !Cookie::validateCookieDomain( $attr['domain'], $domain ) ) {
-                               return null;
-                       }
-
-                       $this->setCookie( $name, $value, $attr );
-               }
-       }
-}
diff --git a/includes/libs/CookieJar.php b/includes/libs/CookieJar.php
new file mode 100644 (file)
index 0000000..910a7ca
--- /dev/null
@@ -0,0 +1,103 @@
+<?php
+/**
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ * @ingroup HTTP
+ */
+
+class CookieJar {
+       private $cookie = [];
+
+       /**
+        * Set a cookie in the cookie jar. Make sure only one cookie per-name exists.
+        * @see Cookie::set()
+        * @param string $name
+        * @param string $value
+        * @param array $attr
+        */
+       public function setCookie( $name, $value, $attr ) {
+               /* cookies: case insensitive, so this should work.
+                * We'll still send the cookies back in the same case we got them, though.
+                */
+               $index = strtoupper( $name );
+
+               if ( isset( $this->cookie[$index] ) ) {
+                       $this->cookie[$index]->set( $value, $attr );
+               } else {
+                       $this->cookie[$index] = new Cookie( $name, $value, $attr );
+               }
+       }
+
+       /**
+        * @see Cookie::serializeToHttpRequest
+        * @param string $path
+        * @param string $domain
+        * @return string
+        */
+       public function serializeToHttpRequest( $path, $domain ) {
+               $cookies = [];
+
+               foreach ( $this->cookie as $c ) {
+                       $serialized = $c->serializeToHttpRequest( $path, $domain );
+
+                       if ( $serialized ) {
+                               $cookies[] = $serialized;
+                       }
+               }
+
+               return implode( '; ', $cookies );
+       }
+
+       /**
+        * Parse the content of an Set-Cookie HTTP Response header.
+        *
+        * @param string $cookie
+        * @param string $domain Cookie's domain
+        * @return null
+        */
+       public function parseCookieResponseHeader( $cookie, $domain ) {
+               $len = strlen( 'Set-Cookie:' );
+
+               if ( substr_compare( 'Set-Cookie:', $cookie, 0, $len, true ) === 0 ) {
+                       $cookie = substr( $cookie, $len );
+               }
+
+               $bit = array_map( 'trim', explode( ';', $cookie ) );
+
+               if ( count( $bit ) >= 1 ) {
+                       list( $name, $value ) = explode( '=', array_shift( $bit ), 2 );
+                       $attr = [];
+
+                       foreach ( $bit as $piece ) {
+                               $parts = explode( '=', $piece );
+                               if ( count( $parts ) > 1 ) {
+                                       $attr[strtolower( $parts[0] )] = $parts[1];
+                               } else {
+                                       $attr[strtolower( $parts[0] )] = true;
+                               }
+                       }
+
+                       if ( !isset( $attr['domain'] ) ) {
+                               $attr['domain'] = $domain;
+                       } elseif ( !Cookie::validateCookieDomain( $attr['domain'], $domain ) ) {
+                               return null;
+                       }
+
+                       $this->setCookie( $name, $value, $attr );
+               }
+       }
+}
index b4206a2..10d4c71 100644 (file)
@@ -58,7 +58,7 @@ class StatusValue {
         * Factory function for fatal errors
         *
         * @param string|MessageSpecifier $message Message key or object
-        * @return Status
+        * @return StatusValue
         */
        public static function newFatal( $message /*, parameters...*/ ) {
                $params = func_get_args();
@@ -71,7 +71,7 @@ class StatusValue {
         * Factory function for good results
         *
         * @param mixed $value
-        * @return Status
+        * @return StatusValue
         */
        public static function newGood( $value = null ) {
                $result = new static();
index c385c38..b61cae7 100644 (file)
@@ -55,11 +55,3 @@ abstract class EventRelayer {
        abstract protected function doNotify( $channel, array $events );
 }
 
-/**
- * No-op class for publishing messages into a PubSub system
- */
-class EventRelayerNull extends EventRelayer {
-       public function doNotify( $channel, array $events ) {
-               return true;
-       }
-}
diff --git a/includes/libs/eventrelayer/EventRelayerNull.php b/includes/libs/eventrelayer/EventRelayerNull.php
new file mode 100644 (file)
index 0000000..b8ec55f
--- /dev/null
@@ -0,0 +1,29 @@
+<?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
+ * @author Aaron Schulz
+ */
+
+/**
+ * No-op class for publishing messages into a PubSub system
+ */
+class EventRelayerNull extends EventRelayer {
+       public function doNotify( $channel, array $events ) {
+               return true;
+       }
+}
diff --git a/includes/libs/stats/BufferingStatsdDataFactory.php b/includes/libs/stats/BufferingStatsdDataFactory.php
new file mode 100644 (file)
index 0000000..9c18b10
--- /dev/null
@@ -0,0 +1,87 @@
+<?php
+/**
+ * Copyright 2015
+ *
+ * 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
+ */
+
+use Liuggio\StatsdClient\Entity\StatsdData;
+use Liuggio\StatsdClient\Entity\StatsdDataInterface;
+use Liuggio\StatsdClient\Factory\StatsdDataFactory;
+
+/**
+ * A factory for application metric data.
+ *
+ * This class prepends a context-specific prefix to each metric key and keeps
+ * a reference to each constructed metric in an internal array buffer.
+ *
+ * @since 1.25
+ */
+class BufferingStatsdDataFactory extends StatsdDataFactory {
+       protected $buffer = [];
+
+       public function __construct( $prefix ) {
+               parent::__construct();
+               $this->prefix = $prefix;
+       }
+
+       /**
+        * Normalize a metric key for StatsD
+        *
+        * Replace occurences of '::' with dots and any other non-alphanumeric
+        * characters with underscores. Combine runs of dots or underscores.
+        * Then trim leading or trailing dots or underscores.
+        *
+        * @param string $key
+        * @since 1.26
+        */
+       private static function normalizeMetricKey( $key ) {
+               $key = preg_replace( '/[:.]+/', '.', $key );
+               $key = preg_replace( '/[^a-z0-9.]+/i', '_', $key );
+               $key = trim( $key, '_.' );
+               return str_replace( [ '._', '_.' ], '.', $key );
+       }
+
+       public function produceStatsdData(
+               $key, $value = 1, $metric = StatsdDataInterface::STATSD_METRIC_COUNT
+       ) {
+               $entity = $this->produceStatsdDataEntity();
+               if ( $key !== null ) {
+                       $key = self::normalizeMetricKey( "{$this->prefix}.{$key}" );
+                       $entity->setKey( $key );
+               }
+               if ( $value !== null ) {
+                       $entity->setValue( $value );
+               }
+               if ( $metric !== null ) {
+                       $entity->setMetric( $metric );
+               }
+               // Don't bother buffering a counter update with a delta of zero.
+               if ( !( $metric === StatsdDataInterface::STATSD_METRIC_COUNT && !$value ) ) {
+                       $this->buffer[] = $entity;
+               }
+               return $entity;
+       }
+
+       /**
+        * @return StatsdData[]
+        */
+       public function getBuffer() {
+               return $this->buffer;
+       }
+}
diff --git a/includes/libs/stats/NullStatsdDataFactory.php b/includes/libs/stats/NullStatsdDataFactory.php
new file mode 100644 (file)
index 0000000..3b272e2
--- /dev/null
@@ -0,0 +1,111 @@
+<?php
+
+use Liuggio\StatsdClient\Entity\StatsdData;
+use Liuggio\StatsdClient\Entity\StatsdDataInterface;
+use Liuggio\StatsdClient\Factory\StatsdDataFactoryInterface;
+
+/**
+ * @author Addshore
+ * @since 1.27
+ */
+class NullStatsdDataFactory implements StatsdDataFactoryInterface {
+
+       /**
+        * This function creates a 'timing' StatsdData.
+        *
+        * @param string|array $key The metric(s) to set.
+        * @param float $time The elapsed time (ms) to log
+        **/
+       public function timing( $key, $time ) {
+       }
+
+       /**
+        * This function creates a 'gauge' StatsdData.
+        *
+        * @param string|array $key The metric(s) to set.
+        * @param float $value The value for the stats.
+        **/
+       public function gauge( $key, $value ) {
+       }
+
+       /**
+        * This function creates a 'set' StatsdData object
+        * A "Set" is a count of unique events.
+        * This data type acts like a counter, but supports counting
+        * of unique occurrences of values between flushes. The backend
+        * receives the number of unique events that happened since
+        * the last flush.
+        *
+        * The reference use case involved tracking the number of active
+        * and logged in users by sending the current userId of a user
+        * with each request with a key of "uniques" (or similar).
+        *
+        * @param  string|array $key The metric(s) to set.
+        * @param  float $value The value for the stats.
+        *
+        * @return array
+        **/
+       public function set( $key, $value ) {
+               return [];
+       }
+
+       /**
+        * This function creates a 'increment' StatsdData object.
+        *
+        * @param string|array $key The metric(s) to increment.
+        * @param float|1      $sampleRate The rate (0-1) for sampling.
+        *
+        * @return array
+        **/
+       public function increment( $key ) {
+               return [];
+       }
+
+       /**
+        * This function creates a 'decrement' StatsdData object.
+        *
+        *
+        * @param string|array $key The metric(s) to decrement.
+        * @param float|1      $sampleRate The rate (0-1) for sampling.
+        *
+        * @return mixed
+        **/
+       public function decrement( $key ) {
+               return [];
+       }
+
+       /**
+        * This function creates a 'updateCount' StatsdData object.
+        *
+        * @param string|array $key The metric(s) to decrement.
+        * @param integer $delta The delta to add to the each metric
+        *
+        * @return mixed
+        **/
+       public function updateCount( $key, $delta ) {
+               return [];
+       }
+
+       /**
+        * Produce a StatsdDataInterface Object.
+        *
+        * @param string $key The key of the metric
+        * @param int $value The amount to increment/decrement each metric by.
+        * @param string $metric The metric type
+        *                      ("c" for count, "ms" for timing, "g" for gauge, "s" for set)
+        *
+        * @return StatsdDataInterface
+        **/
+       public function produceStatsdData(
+               $key,
+               $value = 1,
+               $metric = StatsdDataInterface::STATSD_METRIC_COUNT
+       ) {
+               $data = new StatsdData();
+               $data->setKey( $key );
+               $data->setValue( $value );
+               $data->setMetric( $metric );
+               return $data;
+       }
+
+}
diff --git a/includes/libs/stats/StatsdAwareInterface.php b/includes/libs/stats/StatsdAwareInterface.php
new file mode 100644 (file)
index 0000000..5151b26
--- /dev/null
@@ -0,0 +1,21 @@
+<?php
+
+use Liuggio\StatsdClient\Factory\StatsdDataFactoryInterface;
+
+/**
+ * Describes a Statsd aware interface
+ *
+ * @since 1.27
+ * @author Addshore
+ */
+interface StatsdAwareInterface {
+
+       /**
+        * Sets a logger instance on the object
+        *
+        * @param StatsdDataFactoryInterface $statsFactory
+        * @return null
+        */
+       public function setStatsdDataFactory( StatsdDataFactoryInterface $statsFactory );
+
+}
index 1c7fb98..1059d7b 100644 (file)
@@ -107,9 +107,6 @@ class UserMailer {
         *              'contentType' string default 'text/plain; charset=UTF-8'
         *              'headers' array Extra headers to set
         *
-        * Previous versions of this function had $replyto as the 5th argument and $contentType
-        * as the 6th. These are still supported for backwards compatability, but deprecated.
-        *
         * @throws MWException
         * @throws Exception
         * @return Status
@@ -117,14 +114,6 @@ class UserMailer {
        public static function send( $to, $from, $subject, $body, $options = [] ) {
                global $wgAllowHTMLEmail;
 
-               if ( !is_array( $options ) ) {
-                       // Old calling style
-                       wfDeprecated( __METHOD__ . ' with $replyto as 5th parameter', '1.26' );
-                       $options = [ 'replyTo' => $options ];
-                       if ( func_num_args() === 6 ) {
-                               $options['contentType'] = func_get_arg( 5 );
-                       }
-               }
                if ( !isset( $options['contentType'] ) ) {
                        $options['contentType'] = 'text/plain; charset=UTF-8';
                }
index b055d16..4da41c8 100644 (file)
@@ -115,7 +115,7 @@ class BitmapHandler extends TransformationalImageHandler {
        protected function transformImageMagick( $image, $params ) {
                # use ImageMagick
                global $wgSharpenReductionThreshold, $wgSharpenParameter, $wgMaxAnimatedGifArea,
-                       $wgImageMagickTempDir, $wgImageMagickConvertCommand, $wgMaxInterlacingAreas;
+                       $wgImageMagickTempDir, $wgImageMagickConvertCommand;
 
                $quality = [];
                $sharpen = [];
index 6a01e87..35e885f 100644 (file)
@@ -63,9 +63,9 @@ class WebPHandler extends BitmapHandler {
                                return self::METADATA_GOOD;
                }
 
-               wfSuppressWarnings();
+               MediaWiki\suppressWarnings();
                $data = unserialize( $metadata );
-               wfRestoreWarnings();
+               MediaWiki\restoreWarnings();
 
                if ( !$data || !is_array( $data ) ) {
                                wfDebug( __METHOD__ . " invalid WebP metadata\n" );
@@ -234,9 +234,9 @@ class WebPHandler extends BitmapHandler {
                        $metadata = $file->getMetadata();
                }
 
-               wfSuppressWarnings();
+               MediaWiki\suppressWarnings();
                $metadata = unserialize( $metadata );
-               wfRestoreWarnings();
+               MediaWiki\restoreWarnings();
 
                if ( $metadata == false ) {
                        return false;
index 7592017..6c42e34 100644 (file)
@@ -1572,8 +1572,7 @@ class Article implements Page {
                                $title,
                                htmlspecialchars( $title->getFullText() ),
                                [],
-                               // Automatically append redirect=no to each link, since most of them are
-                               // redirect pages themselves.
+                               // Make sure wiki page redirects are not followed
                                $title->isRedirect() ? [ 'redirect' => 'no' ] : [],
                                ( $forceKnown ? [ 'known', 'noclasses' ] : [] )
                        ) . '</li>';
@@ -2380,15 +2379,6 @@ class Article implements Page {
                return $this->mPage->getUndoContent( $undo, $undoafter );
        }
 
-       /**
-        * Call to WikiPage function for backwards compatibility.
-        * @see WikiPage::getUndoText
-        */
-       public function getUndoText( Revision $undo, Revision $undoafter = null ) {
-               ContentHandler::deprecated( __METHOD__, '1.21' );
-               return $this->mPage->getUndoText( $undo, $undoafter );
-       }
-
        /**
         * Call to WikiPage function for backwards compatibility.
         * @see WikiPage::getUser
@@ -2551,19 +2541,6 @@ class Article implements Page {
                return $this->mPage->protectDescriptionLog( $limit, $expiry );
        }
 
-       /**
-        * Call to WikiPage function for backwards compatibility.
-        * @see WikiPage::replaceSection
-        */
-       public function replaceSection( $sectionId, $text, $sectionTitle = '',
-               $edittime = null
-       ) {
-               ContentHandler::deprecated( __METHOD__, '1.21' );
-               return $this->mPage->replaceSection( $sectionId, $text, $sectionTitle,
-                       $edittime
-               );
-       }
-
        /**
         * Call to WikiPage function for backwards compatibility.
         * @see WikiPage::replaceSectionAtRev
diff --git a/includes/page/Page.php b/includes/page/Page.php
new file mode 100644 (file)
index 0000000..2cb1fc0
--- /dev/null
@@ -0,0 +1,25 @@
+<?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 type hinting (accepts WikiPage, Article, ImagePage, CategoryPage)
+ */
+interface Page {
+}
index 0e3512b..5e5532f 100644 (file)
  * @file
  */
 
-/**
- * Interface for type hinting (accepts WikiPage, Article, ImagePage, CategoryPage)
- */
-interface Page {
-}
-
 /**
  * Class representing a MediaWiki article and history.
  *
@@ -1351,76 +1345,6 @@ class WikiPage implements Page, IDBAccessObject {
                return $handler->getUndoContent( $this->getRevision(), $undo, $undoafter );
        }
 
-       /**
-        * Get the text that needs to be saved in order to undo all revisions
-        * between $undo and $undoafter. Revisions must belong to the same page,
-        * must exist and must not be deleted
-        * @param Revision $undo
-        * @param Revision $undoafter Must be an earlier revision than $undo
-        * @return string|bool String on success, false on failure
-        * @deprecated since 1.21: use ContentHandler::getUndoContent() instead.
-        */
-       public function getUndoText( Revision $undo, Revision $undoafter = null ) {
-               ContentHandler::deprecated( __METHOD__, '1.21' );
-
-               $this->loadLastEdit();
-
-               if ( $this->mLastRevision ) {
-                       if ( is_null( $undoafter ) ) {
-                               $undoafter = $undo->getPrevious();
-                       }
-
-                       $handler = $this->getContentHandler();
-                       $undone = $handler->getUndoContent( $this->mLastRevision, $undo, $undoafter );
-
-                       if ( !$undone ) {
-                               return false;
-                       } else {
-                               return ContentHandler::getContentText( $undone );
-                       }
-               }
-
-               return false;
-       }
-
-       /**
-        * @param string|number|null|bool $sectionId Section identifier as a number or string
-        * (e.g. 0, 1 or 'T-1'), null/false or an empty string for the whole page
-        * or 'new' for a new section.
-        * @param string $text New text of the section.
-        * @param string $sectionTitle New section's subject, only if $section is "new".
-        * @param string $edittime Revision timestamp or null to use the current revision.
-        *
-        * @throws MWException
-        * @return string|null New complete article text, or null if error.
-        *
-        * @deprecated since 1.21, use replaceSectionAtRev() instead
-        */
-       public function replaceSection( $sectionId, $text, $sectionTitle = '',
-               $edittime = null
-       ) {
-               ContentHandler::deprecated( __METHOD__, '1.21' );
-
-               // NOTE: keep condition in sync with condition in replaceSectionContent!
-               if ( strval( $sectionId ) === '' ) {
-                       // Whole-page edit; let the whole text through
-                       return $text;
-               }
-
-               if ( !$this->supportsSections() ) {
-                       throw new MWException( "sections not supported for content model " .
-                               $this->getContentHandler()->getModelID() );
-               }
-
-               // could even make section title, but that's not required.
-               $sectionContent = ContentHandler::makeContent( $text, $this->getTitle() );
-
-               $newContent = $this->replaceSectionContent( $sectionId, $sectionContent, $sectionTitle,
-                       $edittime );
-
-               return ContentHandler::getContentText( $newContent );
-       }
-
        /**
         * Returns true if this page's content model supports sections.
         *
index f784d03..87e5fd7 100644 (file)
@@ -179,7 +179,7 @@ class ResourceLoaderImage {
                        'version' => $context->getVersion(),
                ];
 
-               return wfExpandUrl( wfAppendQuery( $script, $query ), PROTO_RELATIVE );
+               return wfAppendQuery( $script, $query );
        }
 
        /**
index d765137..34866f3 100644 (file)
@@ -40,8 +40,17 @@ class ResourceLoaderStartUpModule extends ResourceLoaderModule {
                }
 
                global $wgContLang;
+               $conf = $this->getConfig();
 
-               $mainPage = Title::newMainPage();
+               // We can't use Title::newMainPage() if 'mainpage' is in
+               // $wgForceUIMsgAsContentMsg because that will try to use the session
+               // user's language and we have no session user. This does the
+               // equivalent but falling back to our ResourceLoaderContext language
+               // instead.
+               $mainPage = Title::newFromText( $context->msg( 'mainpage' )->inContentLanguage()->text() );
+               if ( !$mainPage ) {
+                       $mainPage = Title::newFromText( 'Main Page' );
+               }
 
                /**
                 * Namespace related preparation
@@ -57,7 +66,6 @@ class ResourceLoaderStartUpModule extends ResourceLoaderModule {
                        }
                }
 
-               $conf = $this->getConfig();
                // Build list of variables
                $vars = [
                        'wgLoadScript' => wfScript( 'load' ),
index 7b0d93a..796dc20 100644 (file)
@@ -298,7 +298,8 @@ class ResourceLoaderWikiModule extends ResourceLoaderModule {
 
                        if ( !$batch->isEmpty() ) {
                                $res = $dbr->select( [ 'page', 'revision' ],
-                                       [ 'page_namespace', 'page_title', 'rev_len', 'rev_sha1' ],
+                                       // Include page_touched to allow purging if cache is poisoned (T117587, T113916)
+                                       [ 'page_namespace', 'page_title', 'page_touched', 'rev_len', 'rev_sha1' ],
                                        $batch->constructSet( 'page', $dbr ),
                                        __METHOD__,
                                        [],
@@ -311,6 +312,7 @@ class ResourceLoaderWikiModule extends ResourceLoaderModule {
                                        $this->titleInfo[$key][$title->getPrefixedText()] = [
                                                'rev_len' => $row->rev_len,
                                                'rev_sha1' => $row->rev_sha1,
+                                               'page_touched' => $row->page_touched,
                                        ];
                                }
                        }
index d3b9d5c..40cfe39 100644 (file)
@@ -41,7 +41,7 @@ class SearchExactMatchRescorer {
         */
        public function rescore( $search, $namespaces, $srchres, $limit ) {
                // Pick namespace (based on PrefixSearch::defaultSearchBackend)
-               $ns = in_array( NS_MAIN, $namespaces ) ? NS_MAIN : $namespaces[0];
+               $ns = in_array( NS_MAIN, $namespaces ) ? NS_MAIN : reset( $namespaces );
                $t = Title::newFromText( $search, $ns );
                if ( !$t || !$t->exists() ) {
                        // No exact match so just return the search results
index 0fd8fa8..b410e03 100644 (file)
@@ -335,7 +335,7 @@ final class Session implements \Countable, \Iterator, \ArrayAccess {
         *
         * @param string|string[] $salt Token salt
         * @param string $key Token key
-        * @return MediaWiki\\Session\\SessionToken
+        * @return MediaWiki\\Session\\Token
         */
        public function getToken( $salt = '', $key = 'default' ) {
                $new = false;
index 756bb51..974789f 100644 (file)
@@ -26,6 +26,7 @@
  *
  * @license GNU GPL v2+
  * @author Jeroen De Dauw < jeroendedauw@gmail.com >
+ * @author Daniel Kinzler
  */
 class DBSiteStore implements SiteStore {
 
@@ -35,15 +36,20 @@ class DBSiteStore implements SiteStore {
        protected $sites = null;
 
        /**
-        * @since 1.25
-        * @param null $sitesTable Unused since 1.27
+        * @var LoadBalancer
         */
-       public function __construct( $sitesTable = null ) {
-               if ( $sitesTable !== null ) {
-                       throw new InvalidArgumentException(
-                               __METHOD__ . ': $sitesTable parameter must be null'
-                       );
-               }
+       private $dbLoadBalancer;
+
+       /**
+        * @since 1.27
+        *
+        * @todo: inject some kind of connection manager that is aware of the target wiki,
+        * instead of injecting a LoadBalancer.
+        *
+        * @param LoadBalancer $dbLoadBalancer
+        */
+       public function __construct( LoadBalancer $dbLoadBalancer ) {
+               $this->dbLoadBalancer = $dbLoadBalancer;
        }
 
        /**
@@ -67,7 +73,7 @@ class DBSiteStore implements SiteStore {
        protected function loadSites() {
                $this->sites = new SiteList();
 
-               $dbr = wfGetDB( DB_SLAVE );
+               $dbr = $this->dbLoadBalancer->getConnection( DB_SLAVE );
 
                $res = $dbr->select(
                        'sites',
@@ -124,6 +130,8 @@ class DBSiteStore implements SiteStore {
                                $this->sites->setSite( $site );
                        }
                }
+
+               $this->dbLoadBalancer->reuseConnection( $dbr );
        }
 
        /**
@@ -170,7 +178,7 @@ class DBSiteStore implements SiteStore {
                        return true;
                }
 
-               $dbw = wfGetDB( DB_MASTER );
+               $dbw = $this->dbLoadBalancer->getConnection( DB_MASTER );
 
                $dbw->startAtomic( __METHOD__ );
 
@@ -241,6 +249,8 @@ class DBSiteStore implements SiteStore {
 
                $dbw->endAtomic( __METHOD__ );
 
+               $this->dbLoadBalancer->reuseConnection( $dbw );
+
                $this->reset();
 
                return $success;
@@ -263,13 +273,15 @@ class DBSiteStore implements SiteStore {
         * @return bool Success
         */
        public function clear() {
-               $dbw = wfGetDB( DB_MASTER );
+               $dbw = $this->dbLoadBalancer->getConnection( DB_MASTER );
 
                $dbw->startAtomic( __METHOD__ );
                $ok = $dbw->delete( 'sites', '*', __METHOD__ );
                $ok = $dbw->delete( 'site_identifiers', '*', __METHOD__ ) && $ok;
                $dbw->endAtomic( __METHOD__ );
 
+               $this->dbLoadBalancer->reuseConnection( $dbw );
+
                $this->reset();
 
                return $ok;
index 0f7e5d7..6734d5f 100644 (file)
@@ -39,20 +39,6 @@ class MediaWikiSite extends Site {
        const PATH_FILE = 'file_path';
        const PATH_PAGE = 'page_path';
 
-       /**
-        * @since 1.21
-        * @deprecated since 1.21 Just use the constructor or the factory Site::newForType
-        *
-        * @param int $globalId
-        *
-        * @return MediaWikiSite
-        */
-       public static function newFromGlobalId( $globalId ) {
-               $site = new static();
-               $site->setGlobalId( $globalId );
-               return $site;
-       }
-
        /**
         * Constructor.
         *
index e61179b..a4116ae 100644 (file)
@@ -1,9 +1,7 @@
 <?php
 
 /**
- * Represents the site configuration of a wiki.
- * Holds a list of sites (ie SiteList) and takes care
- * of retrieving and caching site information when appropriate.
+ * Dummy class for accessing the global SiteStore instance.
  *
  * 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
  * @ingroup Site
  *
  * @license GNU GPL v2+
- * @author Jeroen De Dauw < jeroendedauw@gmail.com >
+ * @author Daniel Kinzler
  */
-class SiteSQLStore extends CachingSiteStore {
+class SiteSQLStore {
 
        /**
+        * Returns the global SiteStore instance. This is a relict of the first implementation
+        * of SiteStore, and is kept around for compatibility.
+        *
+        * @note This does not return an instance of SiteSQLStore!
+        *
         * @since 1.21
-        * @deprecated 1.25 Construct a SiteStore instance directly instead.
+        * @deprecated 1.27 use MediaWikiServices::getSiteStore() or MediaWikiServices::getSiteLookup()
+        *             instead.
         *
-        * @param null $sitesTable Unused
-        * @param BagOStuff|null $cache
+        * @param null $sitesTable IGNORED
+        * @param null $cache IGNORED
         *
         * @return SiteStore
         */
@@ -46,13 +50,11 @@ class SiteSQLStore extends CachingSiteStore {
                        );
                }
 
-               if ( $cache === null ) {
-                       $cache = wfGetCache( wfIsHHVM() ? CACHE_ACCEL : CACHE_ANYTHING );
-               }
-
-               $siteStore = new DBSiteStore();
+               // NOTE: we silently ignore $cache for now, since some existing callers
+               // specify it. If we break compatibility with them, we could just as
+               // well just remove this class.
 
-               return new static( $siteStore, $cache );
+               return \MediaWiki\MediaWikiServices::getInstance()->getSiteStore();
        }
 
 }
index 3cc1d8f..e5b9cb9 100644 (file)
@@ -81,15 +81,6 @@ abstract class Skin extends ContextSource {
                return $allowedSkins;
        }
 
-       /**
-        * @deprecated since 1.23, use getAllowedSkins
-        * @return string[]
-        */
-       public static function getUsableSkins() {
-               wfDeprecated( __METHOD__, '1.23' );
-               return self::getAllowedSkins();
-       }
-
        /**
         * Normalize a skin preference value to a form that can be loaded.
         *
@@ -140,23 +131,6 @@ abstract class Skin extends ContextSource {
                }
        }
 
-       /**
-        * Factory method for loading a skin of a given type
-        * @param string $key 'monobook', 'vector', etc.
-        * @return Skin
-        * @deprecated since 1.24; Use SkinFactory instead
-        */
-       static function &newFromKey( $key ) {
-               wfDeprecated( __METHOD__, '1.24' );
-
-               $key = Skin::normalizeKey( $key );
-               $factory = SkinFactory::getDefaultInstance();
-
-               // normalizeKey() guarantees that a skin with this key will exist.
-               $skin = $factory->makeSkin( $key );
-               return $skin;
-       }
-
        /**
         * @return string Skin name
         */
@@ -801,12 +775,12 @@ abstract class Skin extends ContextSource {
         * @return null|string
         */
        function getCopyrightIcon() {
-               global $wgRightsUrl, $wgRightsText, $wgRightsIcon, $wgCopyrightIcon;
+               global $wgRightsUrl, $wgRightsText, $wgRightsIcon, $wgFooterIcons;
 
                $out = '';
 
-               if ( $wgCopyrightIcon ) {
-                       $out = $wgCopyrightIcon;
+               if ( $wgFooterIcons['copyright']['copyright'] ) {
+                       $out = $wgFooterIcons['copyright']['copyright'];
                } elseif ( $wgRightsIcon ) {
                        $icon = htmlspecialchars( $wgRightsIcon );
 
@@ -1024,21 +998,6 @@ abstract class Skin extends ContextSource {
                        $targetUser->canReceiveEmail();
        }
 
-       /**
-        * This function previously returned a fully resolved style path URL to images or styles stored in
-        * the legacy skins/common/ directory.
-        *
-        * That directory has been removed in 1.24 and the function always returns an empty string.
-        *
-        * @deprecated since 1.24
-        * @param string $name The name or path of a skin resource file
-        * @return string Empty string
-        */
-       function getCommonStylePath( $name ) {
-               wfDeprecated( __METHOD__, '1.24' );
-               return '';
-       }
-
        /**
         * Return a fully resolved style path url to images or styles stored in the current skins's folder.
         * This method returns a url resolved using the configured skin style path
@@ -1359,22 +1318,6 @@ abstract class Skin extends ContextSource {
                return $bar;
        }
 
-       /**
-        * This function previously controlled whether the 'mediawiki.legacy.wikiprintable' module
-        * should be loaded by OutputPage. That module no longer exists and the return value of this
-        * method is ignored.
-        *
-        * If your skin doesn't provide its own print styles, the 'mediawiki.legacy.commonPrint' module
-        * can be used instead (SkinTemplate-based skins do it automatically).
-        *
-        * @deprecated since 1.22
-        * @return bool
-        */
-       public function commonPrintStylesheet() {
-               wfDeprecated( __METHOD__, '1.22' );
-               return false;
-       }
-
        /**
         * Gets new talk page messages for the current user and returns an
         * appropriate alert message (or an empty string if there are no messages)
index 6a04c6a..fb153fc 100644 (file)
@@ -342,10 +342,10 @@ class SpecialPage {
                        return [];
                }
 
-               $search = SearchEngine::create();
-               $search->setLimitOffset( $limit, $offset );
-               $search->setNamespaces( [] );
-               $result = $search->defaultPrefixSearch( $search );
+               $searchEngine = SearchEngine::create();
+               $searchEngine->setLimitOffset( $limit, $offset );
+               $searchEngine->setNamespaces( [] );
+               $result = $searchEngine->defaultPrefixSearch( $search );
                return array_map( function( Title $t ) {
                        return $t->getPrefixedText();
                }, $result );
@@ -395,15 +395,20 @@ class SpecialPage {
        final public function run( $subPage ) {
                /**
                 * Gets called before @see SpecialPage::execute.
+                * Return false to prevent calling execute() (since 1.27+).
                 *
                 * @since 1.20
                 *
                 * @param SpecialPage $this
                 * @param string|null $subPage
                 */
-               Hooks::run( 'SpecialPageBeforeExecute', [ $this, $subPage ] );
+               if ( !Hooks::run( 'SpecialPageBeforeExecute', [ $this, $subPage ] ) ) {
+                       return;
+               }
 
-               $this->beforeExecute( $subPage );
+               if ( $this->beforeExecute( $subPage ) === false ) {
+                       return;
+               }
                $this->execute( $subPage );
                $this->afterExecute( $subPage );
 
@@ -420,10 +425,12 @@ class SpecialPage {
 
        /**
         * Gets called before @see SpecialPage::execute.
+        * Return false to prevent calling execute() (since 1.27+).
         *
         * @since 1.20
         *
         * @param string|null $subPage
+        * @return bool|void
         */
        protected function beforeExecute( $subPage ) {
                // No-op
index 8ce480e..725c4fc 100644 (file)
@@ -182,6 +182,7 @@ class SpecialPageFactory {
 
        private static $list;
        private static $aliases;
+       private static $pageObjectCache = [];
 
        /**
         * Reset the internal list of special pages. Useful when changing $wgSpecialPages after
@@ -190,6 +191,7 @@ class SpecialPageFactory {
        public static function resetList() {
                self::$list = null;
                self::$aliases = null;
+               self::$pageObjectCache = [];
        }
 
        /**
@@ -373,6 +375,10 @@ class SpecialPageFactory {
        public static function getPage( $name ) {
                list( $realName, /*...*/ ) = self::resolveAlias( $name );
 
+               if ( isset( self::$pageObjectCache[$realName] ) ) {
+                       return self::$pageObjectCache[$realName];
+               }
+
                $specialPageList = self::getPageList();
 
                if ( isset( $specialPageList[$realName] ) ) {
@@ -400,6 +406,7 @@ class SpecialPageFactory {
                                $page = null;
                        }
 
+                       self::$pageObjectCache[$realName] = $page;
                        if ( $page instanceof SpecialPage ) {
                                return $page;
                        } else {
index bcba190..1027f1f 100644 (file)
@@ -84,9 +84,6 @@ class SpecialBotPasswords extends FormSpecialPage {
        }
 
        protected function getFormFields() {
-               $user = $this->getUser();
-               $request = $this->getRequest();
-
                $fields = [];
 
                if ( $this->par !== null ) {
index 68960d3..20c0762 100644 (file)
@@ -246,11 +246,11 @@ class FileDuplicateSearchPage extends QueryPage {
                        // No prefix suggestion outside of file namespace
                        return [];
                }
-               $search = SearchEngine::create();
-               $search->setLimitOffset( $limit, $offset );
+               $searchEngine = SearchEngine::create();
+               $searchEngine->setLimitOffset( $limit, $offset );
                // Autocomplete subpage the same as a normal search, but just for files
-               $search->setNamespaces( [ NS_FILE ] );
-               $result = $search->defaultPrefixSearch( $search );
+               $searchEngine->setNamespaces( [ NS_FILE ] );
+               $result = $searchEngine->defaultPrefixSearch( $search );
 
                return array_map( function ( Title $t ) {
                        // Remove namespace in search suggestion
index 12959a3..80dc797 100644 (file)
@@ -352,6 +352,10 @@ class SpecialRedirect extends FormSpecialPage {
                $form->setMethod( 'get' );
        }
 
+       protected function getDisplayFormat() {
+               return 'ooui';
+       }
+
        /**
         * Return an array of subpages that this special page will accept.
         *
index c352927..86f1e20 100644 (file)
@@ -36,8 +36,6 @@ class SpecialStatistics extends SpecialPage {
        }
 
        public function execute( $par ) {
-               $miserMode = $this->getConfig()->get( 'MiserMode' );
-
                $this->setHeaders();
                $this->getOutput()->addModuleStyles( 'mediawiki.special' );
 
index 740f2f7..be110aa 100644 (file)
@@ -417,28 +417,18 @@ class UserrightsPage extends SpecialPage {
                return Status::newGood( $user );
        }
 
-       function makeGroupNameList( $ids ) {
-               if ( empty( $ids ) ) {
-                       return $this->msg( 'rightsnone' )->inContentLanguage()->text();
-               } else {
-                       return implode( ', ', $ids );
-               }
-       }
-
        /**
-        * Make a list of group names to be stored as parameter for log entries
+        * @since 1.15
         *
-        * @deprecated since 1.21; use LogFormatter instead.
         * @param array $ids
+        *
         * @return string
         */
-       function makeGroupNameListForLog( $ids ) {
-               wfDeprecated( __METHOD__, '1.21' );
-
+       public function makeGroupNameList( $ids ) {
                if ( empty( $ids ) ) {
-                       return '';
+                       return $this->msg( 'rightsnone' )->inContentLanguage()->text();
                } else {
-                       return $this->makeGroupNameList( $ids );
+                       return implode( ', ', $ids );
                }
        }
 
index 8857907..cfaf5c5 100644 (file)
@@ -140,6 +140,22 @@ class BlockListPager extends TablePager {
                                                                $language->pipeList( $links ) )->escaped()
                                                );
                                }
+                               if ( $value !== 'infinity' ) {
+                                       $timestamp = new MWTimestamp( $value );
+                                       $formatted .= '<br />' . $this->msg(
+                                               'ipb-blocklist-duration-left',
+                                               $language->formatDuration(
+                                                       $timestamp->getTimestamp() - time(),
+                                                       // reasonable output
+                                                       [
+                                                               'minutes',
+                                                               'hours',
+                                                               'days',
+                                                               'years',
+                                                       ]
+                                               )
+                                       )->escaped();
+                               }
                                break;
 
                        case 'ipb_by':
index 9d7b294..1185c4d 100644 (file)
@@ -645,9 +645,6 @@ abstract class UploadBase {
 
                if ( $this->mDesiredDestName != $filename && $comparableName != $filename ) {
                        $warnings['badfilename'] = $filename;
-                       // Debugging for bug 62241
-                       wfDebugLog( 'upload', "Filename: '$filename', mDesiredDestName: "
-                               . "'$this->mDesiredDestName', comparableName: '$comparableName'" );
                }
 
                // Check whether the file extension is on the unwanted list
@@ -666,7 +663,7 @@ abstract class UploadBase {
                }
 
                if ( $this->mFileSize == 0 ) {
-                       $warnings['emptyfile'] = true;
+                       $warnings['empty-file'] = true;
                }
 
                $exists = self::getExistsWarning( $localFile );
index a272b37..bd1a642 100644 (file)
  */
 
 use MediaWiki\Session\SessionManager;
+use MediaWiki\Session\Token;
 
 /**
  * String Some punctuation to prevent editing from broken text-mangling proxies.
  * @deprecated since 1.27, use \\MediaWiki\\Session\\Token::SUFFIX
  * @ingroup Constants
  */
-define( 'EDIT_TOKEN_SUFFIX', MediaWiki\Session\Token::SUFFIX );
+define( 'EDIT_TOKEN_SUFFIX', Token::SUFFIX );
 
 /**
  * The User object encapsulates all of the user-specific settings (user_id,
@@ -4265,7 +4266,7 @@ class User implements IDBAccessObject {
         * @return bool Whether the token matches
         */
        public function matchEditTokenNoSuffix( $val, $salt = '', $request = null, $maxage = null ) {
-               $val = substr( $val, 0, strspn( $val, '0123456789abcdef' ) ) . self::EDIT_TOKEN_SUFFIX;
+               $val = substr( $val, 0, strspn( $val, '0123456789abcdef' ) ) . Token::SUFFIX;
                return $this->matchEditToken( $val, $salt, $request, $maxage );
        }
 
index 916e2f8..4101879 100644 (file)
@@ -250,117 +250,3 @@ EOD
                return str_replace( '\\', '/', $path );
        }
 }
-
-/**
- * Reads PHP code and returns the FQCN of every class defined within it.
- */
-class ClassCollector {
-
-       /**
-        * @var string Current namespace
-        */
-       protected $namespace = '';
-
-       /**
-        * @var array List of FQCN detected in this pass
-        */
-       protected $classes;
-
-       /**
-        * @var array Token from token_get_all() that started an expect sequence
-        */
-       protected $startToken;
-
-       /**
-        * @var array List of tokens that are members of the current expect sequence
-        */
-       protected $tokens;
-
-       /**
-        * @var string $code PHP code (including <?php) to detect class names from
-        * @return array List of FQCN detected within the tokens
-        */
-       public function getClasses( $code ) {
-               $this->namespace = '';
-               $this->classes = [];
-               $this->startToken = null;
-               $this->tokens = [];
-
-               foreach ( token_get_all( $code ) as $token ) {
-                       if ( $this->startToken === null ) {
-                               $this->tryBeginExpect( $token );
-                       } else {
-                               $this->tryEndExpect( $token );
-                       }
-               }
-
-               return $this->classes;
-       }
-
-       /**
-        * Determine if $token begins the next expect sequence.
-        *
-        * @param array $token
-        */
-       protected function tryBeginExpect( $token ) {
-               if ( is_string( $token ) ) {
-                       return;
-               }
-               switch ( $token[0] ) {
-               case T_NAMESPACE:
-               case T_CLASS:
-               case T_INTERFACE:
-               case T_TRAIT:
-               case T_DOUBLE_COLON:
-                       $this->startToken = $token;
-               }
-       }
-
-       /**
-        * Accepts the next token in an expect sequence
-        *
-        * @param array
-        */
-       protected function tryEndExpect( $token ) {
-               switch ( $this->startToken[0] ) {
-               case T_DOUBLE_COLON:
-                       // Skip over T_CLASS after T_DOUBLE_COLON because this is something like
-                       // "self::static" which accesses the class name. It doens't define a new class.
-                       $this->startToken = null;
-                       break;
-               case T_NAMESPACE:
-                       if ( $token === ';' || $token === '{' ) {
-                               $this->namespace = $this->implodeTokens() . '\\';
-                       } else {
-                               $this->tokens[] = $token;
-                       }
-                       break;
-
-               case T_CLASS:
-               case T_INTERFACE:
-               case T_TRAIT:
-                       $this->tokens[] = $token;
-                       if ( is_array( $token ) && $token[0] === T_STRING ) {
-                               $this->classes[] = $this->namespace . $this->implodeTokens();
-                       }
-               }
-       }
-
-       /**
-        * Returns the string representation of the tokens within the
-        * current expect sequence and resets the sequence.
-        *
-        * @return string
-        */
-       protected function implodeTokens() {
-               $content = [];
-               foreach ( $this->tokens as $token ) {
-                       $content[] = is_string( $token ) ? $token : $token[1];
-               }
-
-               $this->tokens = [];
-               $this->startToken = null;
-
-               return trim( implode( '', $content ), " \n\t" );
-       }
-}
diff --git a/includes/utils/ClassCollector.php b/includes/utils/ClassCollector.php
new file mode 100644 (file)
index 0000000..25231df
--- /dev/null
@@ -0,0 +1,115 @@
+<?php
+
+/**
+ * Reads PHP code and returns the FQCN of every class defined within it.
+ */
+class ClassCollector {
+
+       /**
+        * @var string Current namespace
+        */
+       protected $namespace = '';
+
+       /**
+        * @var array List of FQCN detected in this pass
+        */
+       protected $classes;
+
+       /**
+        * @var array Token from token_get_all() that started an expect sequence
+        */
+       protected $startToken;
+
+       /**
+        * @var array List of tokens that are members of the current expect sequence
+        */
+       protected $tokens;
+
+       /**
+        * @var string $code PHP code (including <?php) to detect class names from
+        * @return array List of FQCN detected within the tokens
+        */
+       public function getClasses( $code ) {
+               $this->namespace = '';
+               $this->classes = [];
+               $this->startToken = null;
+               $this->tokens = [];
+
+               foreach ( token_get_all( $code ) as $token ) {
+                       if ( $this->startToken === null ) {
+                               $this->tryBeginExpect( $token );
+                       } else {
+                               $this->tryEndExpect( $token );
+                       }
+               }
+
+               return $this->classes;
+       }
+
+       /**
+        * Determine if $token begins the next expect sequence.
+        *
+        * @param array $token
+        */
+       protected function tryBeginExpect( $token ) {
+               if ( is_string( $token ) ) {
+                       return;
+               }
+               switch ( $token[0] ) {
+                       case T_NAMESPACE:
+                       case T_CLASS:
+                       case T_INTERFACE:
+                       case T_TRAIT:
+                       case T_DOUBLE_COLON:
+                               $this->startToken = $token;
+               }
+       }
+
+       /**
+        * Accepts the next token in an expect sequence
+        *
+        * @param array
+        */
+       protected function tryEndExpect( $token ) {
+               switch ( $this->startToken[0] ) {
+                       case T_DOUBLE_COLON:
+                               // Skip over T_CLASS after T_DOUBLE_COLON because this is something like
+                               // "self::static" which accesses the class name. It doens't define a new class.
+                               $this->startToken = null;
+                               break;
+                       case T_NAMESPACE:
+                               if ( $token === ';' || $token === '{' ) {
+                                       $this->namespace = $this->implodeTokens() . '\\';
+                               } else {
+                                       $this->tokens[] = $token;
+                               }
+                               break;
+
+                       case T_CLASS:
+                       case T_INTERFACE:
+                       case T_TRAIT:
+                               $this->tokens[] = $token;
+                               if ( is_array( $token ) && $token[0] === T_STRING ) {
+                                       $this->classes[] = $this->namespace . $this->implodeTokens();
+                               }
+               }
+       }
+
+       /**
+        * Returns the string representation of the tokens within the
+        * current expect sequence and resets the sequence.
+        *
+        * @return string
+        */
+       protected function implodeTokens() {
+               $content = [];
+               foreach ( $this->tokens as $token ) {
+                       $content[] = is_string( $token ) ? $token : $token[1];
+               }
+
+               $this->tokens = [];
+               $this->startToken = null;
+
+               return trim( implode( '', $content ), " \n\t" );
+       }
+}
index 579de23..bb8a083 100644 (file)
@@ -24,7 +24,8 @@
                        "Янмурза Баки",
                        "Айсар",
                        "Lizalizaufa",
-                       "Кутлубаева Кунсулу Закиевна"
+                       "Кутлубаева Кунсулу Закиевна",
+                       "Вильданова Гюзель"
                ]
        },
        "tog-underline": "Һылтанмалар аҫтына һыҙыу:",
        "special-characters-group-ipa": "ХАФӘ (IPA)",
        "special-characters-group-symbols": "Тамғалар",
        "special-characters-group-greek": "Грек",
+       "special-characters-group-greekextended": "Грек телендә киңәйтелгән",
        "special-characters-group-cyrillic": "Кириллик",
        "special-characters-group-arabic": "Ғәрәп",
        "special-characters-group-arabicextended": "Ғәрәп (киңәйтелгән)",
index 4f3fb62..9cd84cc 100644 (file)
        "apisandbox-fullscreen": "Разгарнуць панэль",
        "apisandbox-fullscreen-tooltip": "Разгарнуць панэль пясочніцы, каб запоўніць акно браўзэра.",
        "apisandbox-unfullscreen": "Паказаць старонку",
+       "apisandbox-unfullscreen-tooltip": "Паменшыць панэль пясочніцы, каб былі даступныя навігацыйныя спасылкі MediaWiki.",
        "apisandbox-submit": "Зрабіць запыт",
        "apisandbox-reset": "Ачысьціць",
+       "apisandbox-retry": "Паўтарыць",
        "apisandbox-examples": "Прыклады",
        "apisandbox-results": "Вынікі",
        "apisandbox-request-url-label": "URL-адрас запыту:",
index 2f3dfd1..ce74f96 100644 (file)
        "foreign-structured-upload-form-label-own-work": "Гэта мая ўласная праца",
        "foreign-structured-upload-form-label-infoform-categories": "Катэгорыі",
        "foreign-structured-upload-form-label-infoform-date": "Дата",
+       "foreign-structured-upload-form-label-own-work-message-local": "Я пацвярджаю, што ўкладваю гэты файл згодна з правіламі і ліцэнзійнай палітыкай {{GRAMMAR:родны|{{SITENAME}}}}.",
        "backend-fail-stream": "Не атрымалася трансляваць файл $1.",
        "backend-fail-backup": "Немагчыма зрабіць рэзервную копію $1.",
        "backend-fail-notexists": "Файл $1 не існуе.",
        "changecontentmodel-reason-label": "Прычына:",
        "changecontentmodel-submit": "Змяніць",
        "logentry-contentmodel-change-revertlink": "адкаціць",
+       "logentry-contentmodel-change-revert": "адкат",
        "protectlogpage": "Журнал аховы",
        "protectlogtext": "Ніжэй прыведзены журнал змен абароны старонкі.\nВы можаце таксама прагледзець [[Special:ProtectedPages|пералік старонак пад аховай]].",
        "protectedarticle": "пад аховай «[[$1]]»",
        "protect-othertime": "Іншы час:",
        "protect-othertime-op": "іншы час",
        "protect-existing-expiry": "Вызначаны час сканчэння: $3, $2",
+       "protect-existing-expiry-infinity": "Наяўны тэрмін дзеяння: бясконца",
        "protect-otherreason": "Іншая ці дадатковая прычына:",
        "protect-otherreason-op": "Іншая прычына",
        "protect-dropdown": "*Звычайныя прычыны пастаноўкі аховы\n** Празмерны ўзровень вандалізму\n** Празмерны ўзровень спаму\n** Шкодная вайна правак\n** Старонка з высокай наведвальнасцю",
        "block-log-flags-hiddenname": "схаванае імя ўдзельніка",
        "range_block_disabled": "Не дазволена адміністратарская магчымасць ставіць блокі на адрасныя дыяпазоны.",
        "ipb_expiry_invalid": "Некарэктны час сканчэння.",
+       "ipb_expiry_old": "Час сканчэння — у мінулым.",
        "ipb_expiry_temp": "Скрытыя блокі на імёны ўдзельнікаў мусяць быць сталымі.",
        "ipb_hide_invalid": "Немагчыма заглушыць гэты рахунак; для яго маецца больш за {{PLURAL:$1|адну праўку|$1 праўкі|$1 правак}}.",
        "ipb_already_blocked": "\"$1\" ужо знаходзіцца пад блокам",
        "import-interwiki-history": "Капіраваць усе гістарычныя версіі гэтай старонкі",
        "import-interwiki-templates": "Разам з усімі шаблонамі",
        "import-interwiki-submit": "Імпартаваць",
+       "import-mapping-namespace": "Імпартаваць у прастору назваў:",
+       "import-mapping-subpage": "Імпартаваць як падстаронкі наступнай старонкі:",
        "import-upload-filename": "Назва файла:",
        "import-comment": "Каментарый:",
        "importtext": "Калі ласка, экспартуйце файл з крынічнай вікі з дапамогай [[Special:Export|прылады экспарту]].\nЗахавайце яго на свой камп'ютар, а потым загрузіце сюды.",
        "javascripttest": "JavaScript-тэсты",
        "javascripttest-pagetext-noframework": "Гэта старонка зарэзервавана для запуску тэстаў JavaScript",
        "javascripttest-pagetext-unknownframework": "Невядомая бібліятэка тэставання «$1».",
+       "javascripttest-pagetext-unknownaction": "Невядомае дзеянне \"$1\".",
        "javascripttest-pagetext-frameworks": "Калі ласка, выберыце адну з прапанаваных бібліятэк тэставання: $1",
        "javascripttest-pagetext-skins": "Выберыце афармленне для тэставання:",
        "javascripttest-qunit-intro": "Глядзіце [$1 дакументацыю па тэставанні] на mediawiki.org.",
        "pageinfo-protect-cascading-yes": "Да",
        "pageinfo-protect-cascading-from": "Каскадная ахова ад",
        "pageinfo-category-info": "Звесткі аб катэгорыі",
+       "pageinfo-category-total": "Агульная колькасць членаў",
        "pageinfo-category-pages": "Колькасць старонак",
        "pageinfo-category-subcats": "Колькасць падкатэгорый",
        "pageinfo-category-files": "Колькасць файлаў",
        "redirect-page": "Ідэнтыфікатар старонкі",
        "redirect-revision": "Версія старонкі",
        "redirect-file": "Назва файла",
+       "redirect-logid": "ID журнала",
        "redirect-not-exists": "Значэнне не знойдзена",
        "fileduplicatesearch": "Пошук дублікатных файлаў",
        "fileduplicatesearch-summary": "Пошук дублікатных файлах на падставе іх хэшаў.",
        "specialpages-group-wiki": "Вікізвесткі і прылады",
        "specialpages-group-redirects": "Адмысловыя старонкі-перасылкі",
        "specialpages-group-spam": "Прылады супраць спама",
+       "specialpages-group-developer": "Інструменты распрацоўшчыка",
        "blankpage": "Пустая старонка",
        "intentionallyblankpage": "Старонка наўмысна пакінута пустой, і ўжываецца для вымярэння хуткасці і падобнага.",
        "external_image_whitelist": " #Гэты радок пакіньце ў такім самым выглядзе<pre>\n#Упішыце часткі рэгулярных выразаў (тое, што пішуць паміж знакамі //) ніжэй\n#Гэта будзе параўноўвацца з адрасамі URL вонкавых выяваў, на якія ёсць спасылкі\n#Тыя з іх, дзе атрымаецца адпаведнасць, будуць паказаныя як выявы, а іначай толькі як спасылкі\n#Радкі, якія пачынаюцца з знака #, лічацца каментарамі\n#Малыя і вялікія літары не адрозніваюцца\n\n#Усе часткі рэгулярных выразаў павінны быць над гэтым радком. Сам радок пакіньце ў такім самым выглядзе</pre>",
index 69f663d..e2d3b2d 100644 (file)
        "apisandbox-dynamic-parameters-add-label": "প্যারামিটার যোগ করুন:",
        "apisandbox-dynamic-parameters-add-placeholder": "প্যারামিটারের নাম",
        "apisandbox-results": "ফলাফল",
+       "apisandbox-sending-request": "API অনুরোধ পাঠানো হচ্ছে...",
+       "apisandbox-loading-results": "API ফলাফল গ্রহণ করা হচ্ছে...",
        "apisandbox-request-url-label": "অনুরোধের URL:",
        "apisandbox-request-time": "অনুরোধের সময়: {{PLURAL:$1|$1 মি.সে.}}",
        "booksources": "বইয়ের উৎস",
        "special-characters-group-ipa": "আইপিএ",
        "special-characters-group-symbols": "চিহ্নসমূহ",
        "special-characters-group-greek": "গ্রিক",
+       "special-characters-group-greekextended": "সম্প্রসারিত গ্রিক",
        "special-characters-group-cyrillic": "সিরিলিক",
        "special-characters-group-arabic": "আরবি",
        "special-characters-group-arabicextended": "সম্প্রসারিত আরবি",
        "sessionprovider-generic": "$1টি সেশন",
        "sessionprovider-mediawiki-session-cookiesessionprovider": "কুকি-ভিত্তিক সেশন",
        "sessionprovider-nocookies": "কুকি নিষ্ক্রিয় করা। নিশ্চিত করুন যে আপনার কুকি সক্রিয় আছে এবং আবার শুরু করুন।",
-       "randomrootpage": "অজানা মূল পাতা"
+       "randomrootpage": "অজানা মূল পাতা",
+       "log-action-filter-block": "বাধাদানের ধরন:",
+       "log-action-filter-delete": "অপসারণের ধরন:",
+       "log-action-filter-patrol": "টহলের ধরন:",
+       "log-action-filter-protect": "সুরক্ষার ধরন:",
+       "log-action-filter-upload": "আপলোডের ধরন:",
+       "log-action-filter-all": "সব",
+       "log-action-filter-block-block": "বাধাদান",
+       "log-action-filter-block-reblock": "বাধাদান পরিবর্তন",
+       "log-action-filter-block-unblock": "বাধা অপসারণ",
+       "log-action-filter-delete-delete": "পাতা অপসারণ",
+       "log-action-filter-delete-restore": "পাতা পুনঃরুদ্ধার",
+       "log-action-filter-delete-event": "লগ অপসারণ",
+       "log-action-filter-delete-revision": "সংশোধন অপসারণ",
+       "log-action-filter-patrol-patrol": "ম্যানুয়াল টহল",
+       "log-action-filter-patrol-autopatrol": "স্বয়ংক্রিয় টহল",
+       "log-action-filter-protect-protect": "সুরক্ষা",
+       "log-action-filter-protect-modify": "সুরক্ষা পরিমার্জন",
+       "log-action-filter-protect-unprotect": "অসুরক্ষা",
+       "log-action-filter-upload-upload": "নতুন আপলোড",
+       "log-action-filter-upload-overwrite": "পুনঃআপলোড"
 }
index 2689ce5..3516175 100644 (file)
        "botpasswords-label-grants": "Permisos aplicables:",
        "botpasswords-label-restrictions": "Restriccions d'ús:",
        "botpasswords-label-grants-column": "Concedit",
-       "botpasswords-bad-appid": "",
+       "botpasswords-bad-appid": "El nom del bot «$1» no és vàlid.",
+       "botpasswords-insert-failed": "No s'ha pogut afegir el nom del bot «$1». Ja hi estava afegit?",
+       "botpasswords-update-failed": "No s'ha pogut actualitzar el nom del bot «$1». Hi estava suprimit?",
+       "botpasswords-created-title": "S'ha creat la contrasenya del bot",
        "resetpass_forbidden": "No poden canviar-se les contrasenyes",
        "resetpass-no-info": "Heu d'estar registrats en un compte per a poder accedir directament a aquesta pàgina.",
        "resetpass-submit-loggedin": "Canvia la contrasenya",
        "apisandbox-dynamic-parameters": "Paràmetres adicionals",
        "apisandbox-dynamic-parameters-add-label": "Afegeix un paràmetre:",
        "apisandbox-dynamic-parameters-add-placeholder": "Nom del paràmetre",
+       "apisandbox-deprecated-parameters": "Paràmetres obsolets",
+       "apisandbox-submit-invalid-fields-title": "Alguns camps no són vàlids",
        "apisandbox-results": "Resultats",
        "apisandbox-request-url-label": "Sol·licita URL:",
        "apisandbox-request-time": "Temps de sol·licitud: $1",
        "wlshowlast": "Mostra les darreres $1 hores, els darrers $2 dies",
        "watchlist-hide": "Amaga",
        "watchlist-submit": "Mostra",
+       "wlshowtime": "Període de temps per mostrar:",
        "wlshowhideminor": "edicions menors",
        "wlshowhidebots": "bots",
        "wlshowhideliu": "usuaris registrats",
        "changecontentmodel-title-label": "Títol de la pàgina",
        "changecontentmodel-model-label": "Nou model de contingut",
        "changecontentmodel-reason-label": "Motiu:",
+       "changecontentmodel-submit": "Canvia",
        "changecontentmodel-success-title": "S'ha canviat el model de contingut",
        "changecontentmodel-success-text": "S'ha canviat el tipus de contingut de [[:$1]].",
        "changecontentmodel-cannot-convert": "El contingut a [[:$1]] no es pot convertir a un tipus de $2.",
        "newimages-legend": "Nom del fitxer",
        "newimages-label": "Nom de fitxer (o part d'ell):",
        "newimages-showbots": "Mostra les càrregues dels bots",
+       "newimages-hidepatrolled": "Amaga les càrregues patrullades",
        "noimages": "Res per veure.",
        "ilsubmit": "Cerca",
        "bydate": "per data",
        "special-characters-group-ipa": "AFI",
        "special-characters-group-symbols": "Símbols",
        "special-characters-group-greek": "Grec",
+       "special-characters-group-greekextended": "Grec estès",
        "special-characters-group-cyrillic": "Ciríl·lic",
        "special-characters-group-arabic": "Aràbic",
        "special-characters-group-arabicextended": "Aràbic estès",
        "mw-widgets-titleinput-description-new-page": "la pàgina no existeix encara",
        "mw-widgets-titleinput-description-redirect": "redirigeix a $1",
        "api-error-blacklisted": "Trieu un títol diferent, més descriptiu.",
+       "sessionmanager-tie": "No es poden combinar diferents tipus de sol·licituds d'autenticació: $1.",
        "sessionprovider-generic": "$1 sessions",
        "sessionprovider-mediawiki-session-cookiesessionprovider": "sessions basades en galetes",
-       "sessionprovider-nocookies": "Pot ser que les galetes estiguin inhabilitades. Assegureu-vos que teniu les galetes habilitades i inicieu de nou."
+       "sessionprovider-nocookies": "Pot ser que les galetes estiguin inhabilitades. Assegureu-vos que teniu les galetes habilitades i inicieu de nou.",
+       "randomrootpage": "Pàgina arrel aleatòria",
+       "log-action-filter-block": "Tipus de blocatge:",
+       "log-action-filter-delete": "Tipus de supressió:",
+       "log-action-filter-patrol": "Tipus de patrullatge:",
+       "log-action-filter-protect": "Tipus de protecció:",
+       "log-action-filter-upload": "Tipus de càrrega:",
+       "log-action-filter-protect-protect": "Protecció",
+       "log-action-filter-protect-modify": "Modificació de la protecció",
+       "log-action-filter-protect-unprotect": "Desprotecció",
+       "log-action-filter-upload-upload": "Nova càrrega",
+       "log-action-filter-upload-overwrite": "Torna a carregar"
 }
index 80d65d6..413b196 100644 (file)
        "october-date": "$1ی تشرینی یەکەم",
        "november-date": "$1ی تشرینی دووەم",
        "december-date": "$1ی کانوونی یەکەم",
+       "period-am": "پێش نیوەڕۆ",
+       "period-pm": "پاش نیوەڕۆ",
        "pagecategories": "{{PLURAL:$1|پۆل|پۆلەکان}}",
        "category_header": "پەڕەکانی پۆلی «$1»",
        "subcategories": "ژێرپۆلەکان",
        "retypenew": "تێپەڕوشەی نوێ دوبارە بنووسەوە:",
        "resetpass_submit": "تێپەڕوشە رێکخە و بچۆ ژوورەوە",
        "changepassword-success": "تێپەروشەکەت بە سەرکەوتوویی گۆڕدرا!",
+       "botpasswords-label-create": "دروستکردن",
+       "botpasswords-label-update": "نوێکردنەوە",
+       "botpasswords-label-cancel": "ھەڵوەشاندنەوە",
+       "botpasswords-label-delete": "سڕینەوە",
+       "botpasswords-label-resetpassword": "ڕێکخستنەوەی تێپەڕوشە",
        "resetpass_forbidden": "تێپەڕوشەکە ناگۆڕدرێت",
        "resetpass-no-info": "بۆ گەیشتنی راستەوخۆ بەم پەڕە ئەشێ بچیتە ژوورەوە.",
        "resetpass-submit-loggedin": "تێپەڕوشە بگۆڕە",
index 5847af6..0d64af2 100644 (file)
        "nosuchuser": "Neexistuje uživatel se jménem „$1“. U uživatelských jmen se rozlišují malá/velká písmena. Zkontrolujte zápis, nebo si [[Special:UserLogin/signup|vytvořte nový účet]].",
        "nosuchusershort": "Neexistuje uživatel se jménem „$1“. Zkontrolujte zápis.",
        "nouserspecified": "Musíte zadat uživatelské jméno.",
-       "login-userblocked": "Tento uživatel je zablokován. Přihlášení není dovoleno.",
+       "login-userblocked": "{{GENDER:$1|Tento uživatel je zablokován|Tato uživatelka je zablokována}}. Přihlášení není dovoleno.",
        "wrongpassword": "Bylo zadáno nesprávné heslo.\nZkuste to znovu.",
        "wrongpasswordempty": "Bylo zadáno prázdné heslo. Zkuste to znovu.",
        "passwordtooshort": "Heslo musí být dlouhé nejméně $1 {{PLURAL:$1|znak|znaky|znaků}}.",
        "missing-revision": "Revize #$1 stránky s názvem „{{FULLPAGENAME}}“ neexistuje.\n\nToto je obvykle způsobeno tím, že jste následovali zastaralý odkaz na historickou verzi stránky, jež byla smazána.\nPodrobnosti mohou být uvedeny v [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} knize smazaných stránek].",
        "userpage-userdoesnotexist": "Uživatelský účet „$1“ není zaregistrován.\nZkontrolujte, zda skutečně chcete tuto stránku vytvořit či editovat.",
        "userpage-userdoesnotexist-view": "Uživatelský účet „$1“ není zaregistrován.",
-       "blocked-notice-logextract": "Tento uživatel je momentálně zablokován.\nZde je pro přehled zobrazen nejnovější záznam z knihy zablokování:",
+       "blocked-notice-logextract": "{{GENDER:$1|Tento uživatel|Tato uživatelka}} je momentálně {{GENDER:$1|zablokován|zablokována}}.\nZde je pro přehled zobrazen nejnovější záznam z knihy zablokování:",
        "clearyourcache": "<strong>Poznámka:</strong> Po uložení musíte smazat cache vašeho prohlížeče, jinak změny neuvidíte.\n* <strong>Firefox / Safari:</strong> Při kliknutí na <em>Aktualizovat</em> držte <em>Shift</em> nebo stiskněte <em>Ctrl-F5</em> nebo <em>Ctrl-R</em> (na Macu <em>⌘-R</em>)\n* <strong>Google Chrome:</strong> Stiskněte <em>Ctrl-Shift-R</em> (na Macu <em>⌘-Shift-R</em>)\n* <strong>Internet Explorer:</strong> Při kliknutí na <em>Aktualizovat</em> držte <em>Ctrl</em> nebo stiskněte <em>Ctrl-F5</em>\n* <strong>Opera:</strong> Smažte obsah cache v menu <em>Nástroje → Nastavení</em>",
        "usercssyoucanpreview": "<strong>Tip:</strong> Použijte tlačítko „{{int:showpreview}}“ k testování vašeho nového CSS před uložením.",
        "userjsyoucanpreview": "<strong>Tip:</strong> Použijte tlačítko „{{int:showpreview}}“ k testování vašeho nového JavaScriptu před uložením.",
        "undo-summary": "Zrušena verze $1 od uživatele [[Special:Contributions/$2|$2]] ([[User talk:$2|diskuse]])",
        "undo-summary-username-hidden": "Zrušena verze $1 od skrytého uživatele",
        "cantcreateaccounttitle": "Nelze vytvořit uživatelský účet",
-       "cantcreateaccount-text": "Zakládání nových účtů z této IP adresy ('''$1''') bylo zablokováno uživatelem [[User:$3|$3]].\n\n$3 uvádí toto zdůvodnění: ''$2''",
+       "cantcreateaccount-text": "Zakládání nových účtů z této IP adresy (<strong>$1</strong>) bylo zablokováno {{GENDER:$3|uživatelem|uživatelkou}} [[User:$3|$3]].\n\n$3 uvádí toto zdůvodnění: <em>$2</em>",
        "cantcreateaccount-range-text": "Zakládání nových účtů z IP adres v rozsahu <strong>$1</strong>, který obsahuje i vaši IP adresu (<strong>$4</strong>), bylo zablokováno {{GENDER:$3|uživatelem|uživatelkou}} [[User:$3|$3]].\n\n$3 uvádí toto zdůvodnění: <em>$2</em>",
        "viewpagelogs": "Zobrazit protokolovací záznamy k této stránce",
        "nohistory": "O této stránce neexistuje historie editací.",
        "autoblocker": "Automatické zablokování kvůli tomu, že vaši IP adresu nedávno {{GENDER:$1|používal uživatel|používala uživatelka}} „[[User:$1|$1]]“.\nDůvod zablokování {{GENDER:$1|uživatele $1|uživatelky $1}}: „$2“",
        "blocklogpage": "Kniha zablokování",
        "blocklog-showlog": "{{GENDER:$1|Tento uživatel byl dříve blokován.|Tato uživatelka byla dříve blokována.|Tento uživatel byl dříve blokován.}}\nZde je pro přehled zobrazen výpis z knihy zablokování:",
-       "blocklog-showsuppresslog": "Tento uživatel byl zablokován a skryt. Zde je pro přehled zobrazen výpis záznamu utajení:",
+       "blocklog-showsuppresslog": "{{GENDER:$1|Tento uživatel byl zablokován a skryt|Tato uživatelka byla zablokována a skryta}}. Zde je pro přehled zobrazen výpis záznamu utajení:",
        "blocklogentry": "blokuje „[[$1]]“ s časem vypršení $2 $3",
        "reblock-logentry": "mění nastavení bloku „[[$1]]“ s časem vypršení $2 $3",
        "blocklogtext": "Toto je kniha úkonů blokování a odblokování uživatelů.\nAutomaticky blokované IP adresy nejsou vypsány.\nVizte též [[Special:BlockList|seznam všech probíhajících bloků]].",
        "ipb_expiry_temp": "Blokování skrytých uživatelských jmen by měla být trvalá.",
        "ipb_hide_invalid": "Tento účet nelze utajit; má více než $1 {{PLURAL:$1|editaci|editace|editací}}.",
        "ipb_already_blocked": "„$1“ již je zablokován.",
-       "ipb-needreblock": "$1 je již {{GENDER:zablokován|zablokována}}. Chcete změnit nastavení bloku?",
+       "ipb-needreblock": "$1 je již {{GENDER:$1|zablokován|zablokována|zablokován(a)}}. Chcete změnit nastavení bloku?",
        "ipb-otherblocks-header": "{{PLURAL:$1|Jiné zablokování|Jiná zablokování}}",
        "unblock-hideuser": "Tohoto uživatele nemůžete odblokovat, protože jeho uživatelské jméno bylo skryto.",
        "ipb_cant_unblock": "Chyba: Blokování s ID $1 nebylo nalezeno. Uživatel již možná byl odblokován.",
index 408ebed..9a553dd 100644 (file)
        "special-characters-group-ipa": "Internationales Phonetisches Alphabet (IPA)",
        "special-characters-group-symbols": "Symbole",
        "special-characters-group-greek": "Griechisch",
+       "special-characters-group-greekextended": "Erweitertes Griechisch",
        "special-characters-group-cyrillic": "Kyrillisch",
        "special-characters-group-arabic": "Arabisch",
        "special-characters-group-arabicextended": "Arabisch, erweitert",
index 579e9b8..fe307d4 100644 (file)
        "noemail": "There is no email address recorded for user \"$1\".",
        "noemailcreate": "You need to provide a valid email address.",
        "passwordsent": "A new password has been sent to the email address registered for \"$1\".\nPlease log in again after you receive it.",
-       "blocked-mailpassword": "Your IP address is blocked from editing, and so is not allowed to use the password recovery function to prevent abuse.",
+       "blocked-mailpassword": "Your IP address is blocked from editing. To prevent abuse, it is not allowed to use password recovery from this IP address.",
        "eauthentsent": "A confirmation email has been sent to the specified email address.\nBefore any other email is sent to the account, you will have to follow the instructions in the email, to confirm that the account is actually yours.",
        "throttled-mailpassword": "A password reset email has already been sent, within the last {{PLURAL:$1|hour|$1 hours}}.\nTo prevent abuse, only one password reset email will be sent per {{PLURAL:$1|hour|$1 hours}}.",
        "signupstart": "",
        "uploadstash-summary": "This page provides access to files that are uploaded or in the process of uploading, but are not yet published to the wiki. These files are not visible to anyone but the user who uploaded them.",
        "uploadstash-clear": "Clear stashed files",
        "uploadstash-nofiles": "You have no stashed files.",
-       "uploadstash-badtoken": "Performing that action failed. Perhaps because your editing credentials expired. Please try again.",
+       "uploadstash-badtoken": "Performing that action failed, perhaps because your editing credentials expired. Please try again.",
        "uploadstash-errclear": "Clearing the files failed.",
        "uploadstash-refresh": "Refresh the list of files",
        "uploadstash-thumbnail": "view thumbnail",
        "unblock-summary": "",
        "blockip": "Block {{GENDER:$1|user}}",
        "blockip-legend": "Block user",
-       "blockiptext": "Use the form below to block write access from a specific IP address or username.\nThis should be done only to prevent vandalism, and in accordance with [[{{MediaWiki:Policy-url}}|policy]].\nFill in a specific reason below (for example, citing particular pages that were vandalized).\nYou can block IP ranges using the [https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing CIDR] syntax; the largest allowed range is /$1 for IPv4 and /$2 for IPv6.",
+       "blockiptext": "Use the form below to block write access from a specific IP address or username.\nThis should be done only to prevent vandalism, and in accordance with [[{{MediaWiki:Policy-url}}|policy]].\nFill in a specific reason below (for example, citing particular pages that were vandalized).\nYou can block IP address ranges using the [https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing CIDR] syntax; the largest allowed range is /$1 for IPv4 and /$2 for IPv6.",
        "ipaddressorusername": "IP address or username:",
        "ipbexpiry": "Expiration:",
        "ipbreason": "Reason:",
        "ipb-unblock": "Unblock a username or IP address",
        "ipb-blocklist": "View existing blocks",
        "ipb-blocklist-contribs": "Contributions for {{GENDER:$1|$1}}",
+       "ipb-blocklist-duration-left": "$1 left",
        "unblockip": "Unblock user",
        "unblockiptext": "Use the form below to restore write access to a previously blocked IP address or username.",
        "ipusubmit": "Remove this block",
        "unblock-hideuser": "You cannot unblock this user, as their username has been hidden.",
        "ipb_cant_unblock": "Error: Block ID $1 not found. It may have been unblocked already.",
        "ipb_blocked_as_range": "Error: The IP address $1 is not blocked directly and cannot be unblocked.\nIt is, however, blocked as part of the range $2, which can be unblocked.",
-       "ip_range_invalid": "Invalid IP range.",
+       "ip_range_invalid": "Invalid IP address range.",
        "ip_range_toolarge": "Range blocks larger than /$1 are not allowed.",
        "proxyblocker": "Proxy blocker",
        "proxyblockreason": "Your IP address has been blocked because it is an open proxy.\nPlease contact your Internet service provider or technical support of your organization and inform them of this serious security problem.",
        "version-libraries-description": "Description",
        "version-libraries-authors": "Authors",
        "redirect": "Redirect by file, user, page, revision, or log ID",
-       "redirect-legend": "Redirect to a file or page",
        "redirect-text": "",
        "redirect-summary": "This special page redirects to a file (given the filename), a page (given a revision ID or page ID), a user page (given a numeric user ID), or a log entry (given the log ID). Usage: [[{{#Special:Redirect}}/file/Example.jpg]], [[{{#Special:Redirect}}/page/64308]], [[{{#Special:Redirect}}/revision/328429]], [[{{#Special:Redirect}}/user/101]], or [[{{#Special:Redirect}}/logid/186]].",
        "redirect-submit": "Go",
        "logentry-protect-protect-cascade": "$1 {{GENDER:$2|protected}} $3 $4 [cascading]",
        "logentry-protect-modify": "$1 {{GENDER:$2|changed}} protection level for $3 $4",
        "logentry-protect-modify-cascade": "$1 {{GENDER:$2|changed}} protection level for $3 $4 [cascading]",
-       "logentry-rights-rights": "$1 {{GENDER:$2|changed}} group membership for $3 from $4 to $5",
+       "logentry-rights-rights": "$1 {{GENDER:$2|changed}} group membership for {{GENDER:$3|$3}} from $4 to $5",
        "logentry-rights-rights-legacy": "$1 {{GENDER:$2|changed}} group membership for $3",
        "logentry-rights-autopromote": "$1 was automatically {{GENDER:$2|promoted}} from $4 to $5",
        "logentry-upload-upload": "$1 {{GENDER:$2|uploaded}} $3",
index e9ccda5..2fd51b3 100644 (file)
        "special-characters-group-ipa": "AFI",
        "special-characters-group-symbols": "Símbolos",
        "special-characters-group-greek": "Griego",
+       "special-characters-group-greekextended": "Griego extendido",
        "special-characters-group-cyrillic": "Cirílico",
        "special-characters-group-arabic": "Árabe",
        "special-characters-group-arabicextended": "Arábico extendido",
index 7e301a8..7b0a322 100644 (file)
        "revdelete-unsuppress": "Poista rajoitukset palautetuilta versioilta",
        "revdelete-log": "Syy:",
        "revdelete-submit": "Toteuta {{PLURAL:$1|valittuun versioon|valittuihin versioihin}}",
-       "revdelete-success": "'''Version näkyvyys päivitetty.'''",
+       "revdelete-success": "Version näkyvyys päivitetty.",
        "revdelete-failure": "'''Version näkyvyyden muuttaminen ei onnistunut:'''\n$1",
-       "logdelete-success": "'''Lokitapahtuman näkyvyyttä on muutettu.'''",
+       "logdelete-success": "Lokitapahtuman näkyvyyttä on muutettu.",
        "logdelete-failure": "'''Lokin näkyvyyttä ei voitu asettaa:'''\n$1",
        "revdel-restore": "muuta näkyvyyttä",
        "pagehist": "Sivun muutoshistoria",
        "userrights-changeable-col": "Ryhmät, joita voit muuttaa",
        "userrights-unchangeable-col": "Ryhmät, joita et voi muuttaa",
        "userrights-conflict": "Päällekkäinen käyttöoikeuksien muutos! Tarkista tekemäsi muutokset ja vahvista ne.",
-       "userrights-removed-self": "Poistit onnistuneesti omat oikeutesi. Tämän jälkeen et enää pääse tälle sivulle.",
+       "userrights-removed-self": "Poistit omat oikeutesi. Tämän vuoksi sinulla ei enää ole oikeutta päästä tälle sivulle.",
        "group": "Ryhmä",
        "group-user": "käyttäjät",
        "group-autoconfirmed": "automaattisesti hyväksytyt käyttäjät",
        "uploadstash-summary": "Tämä sivu tarjoaa pääsyn tiedostoihin, jotka on tallennettu tai joiden tallennus on käynnissä, mutta joita ei ole vielä julkaistu tässä wikissä. Vain tiedostot tallentanut käyttäjä voi tarkastella näitä tiedostoja.",
        "uploadstash-clear": "Poista muistissa olevat tiedostot",
        "uploadstash-nofiles": "Sinulla ei ole muistissa olevia tiedostoja.",
-       "uploadstash-badtoken": "Toiminnon suoritus epäonnistui. Tähän voi olla syynä muokkausvaltuuksien vanhentuminen. Yritä uudelleen.",
-       "uploadstash-errclear": "Muistin tyhjennys epäonnistui.",
+       "uploadstash-badtoken": "Toiminnon suorittaminen epäonnistui. Tähän saattaa olla syynä muokkausvaltuuksiesi vanhentuminen. Yritä uudelleen.",
+       "uploadstash-errclear": "Tiedostojen tyhjentäminen epäonnistui.",
        "uploadstash-refresh": "Päivitä tiedostoluettelo",
        "uploadstash-thumbnail": "näytä pienoiskuva",
        "invalid-chunk-offset": "Kelpaamaton siirtymä lohkoissa",
        "special-characters-group-ipa": "Kansainvälinen foneettinen kirjaimisto (IPA)",
        "special-characters-group-symbols": "Symbolit",
        "special-characters-group-greek": "Kreikka",
+       "special-characters-group-greekextended": "Laajennettu kreikka",
        "special-characters-group-cyrillic": "Kyrillinen",
        "special-characters-group-arabic": "Arabia",
        "special-characters-group-arabicextended": "Laajennettu arabia",
        "sessionprovider-generic": "$1 istuntoa",
        "sessionprovider-mediawiki-session-cookiesessionprovider": "istuntoja, joissa on evästeet käytössä",
        "sessionprovider-nocookies": "Evästeet on voitu poistaa käytöstä. Varmista, että sinulla on evästeet käytössä ja yritä sitten uudelleen.",
-       "randomrootpage": "Satunnainen juurisivu"
+       "randomrootpage": "Satunnainen juurisivu",
+       "log-action-filter-block": "Eston tyyppi:",
+       "log-action-filter-delete": "Poiston tyyppi:",
+       "log-action-filter-patrol": "Tarkastuksen tyyppi:",
+       "log-action-filter-protect": "Suojauksen tyyppi:",
+       "log-action-filter-upload": "Tallennuksen tyyppi:",
+       "log-action-filter-all": "Kaikki",
+       "log-action-filter-block-block": "Eston asettaminen",
+       "log-action-filter-block-reblock": "Estoasetusten muuttaminen",
+       "log-action-filter-block-unblock": "Eston poistaminen",
+       "log-action-filter-delete-delete": "Sivun poistaminen",
+       "log-action-filter-delete-restore": "Sivun palauttaminen",
+       "log-action-filter-delete-event": "Lokimerkinnän poistaminen",
+       "log-action-filter-delete-revision": "Version piilottaminen",
+       "log-action-filter-protect-protect": "Suojauksen asettaminen",
+       "log-action-filter-protect-modify": "Suojausasetusten muuttaminen",
+       "log-action-filter-protect-unprotect": "Suojauksen poistaminen",
+       "log-action-filter-upload-upload": "Uusi tallennus",
+       "log-action-filter-upload-overwrite": "Päälletallennus"
 }
index 9859a05..d879df4 100644 (file)
        "special-characters-group-ipa": "API",
        "special-characters-group-symbols": "symboles",
        "special-characters-group-greek": "grec",
+       "special-characters-group-greekextended": "Grec étendu",
        "special-characters-group-cyrillic": "cyrillique",
        "special-characters-group-arabic": "arabe",
        "special-characters-group-arabicextended": "arabe étendu",
index 8312954..da26a3e 100644 (file)
        "special-characters-group-ipa": "IPA",
        "special-characters-group-symbols": "Símbolos",
        "special-characters-group-greek": "Grego",
+       "special-characters-group-greekextended": "Grego estendido",
        "special-characters-group-cyrillic": "Cirílico",
        "special-characters-group-arabic": "Árabe",
        "special-characters-group-arabicextended": "Árabe estendido",
index 3ab0e75..d6962b2 100644 (file)
        "noemail": "לא רשומה כתובת דואר אלקטרוני עבור ה{{GENDER:$1|משתמש|משתמשת}} \"$1\".",
        "noemailcreate": "יש לספק כתובת דואר אלקטרוני תקינה.",
        "passwordsent": "סיסמה חדשה נשלחה לכתובת הדואר האלקטרוני הרשומה עבור \"$1\".\nאנא היכנסו חזרה לאתר אחרי שתקבלו אותה.",
-       "blocked-mailpassword": "כתובת ה־IP שלך נחסמה מעריכה, ולפיכך אינך מורשה להשתמש באפשרות שחזור הסיסמה, וזאת כדי למנוע ניצול לרעה של התכונה.",
+       "blocked-mailpassword": "כתובת ה־IP שלך נחסמה מעריכה. אינך מורשה להשתמש באפשרות שחזור הסיסמה, וזאת כדי למנוע ניצול לרעה של התכונה.",
        "eauthentsent": "דוא\"ל אימות נשלח לכתובת הדוא\"ל שצוינה.\nלפני שדברי דוא\"ל אחרים יישלחו לחשבון הזה, יהיה עליכם לפעול לפי ההוראות בדוא\"ל, כדי לאשר שהחשבון אכן שייך לכם.",
        "throttled-mailpassword": "כבר נשלח דוא\"ל לאיפוס הסיסמה ב{{PLURAL:$1|שעה האחרונה|שעתיים האחרונות|־$1 השעות האחרונות}}.\nכדי למנוע ניצול לרעה, יכול להישלח רק דוא\"ל אחד כזה בכל {{PLURAL:$1|שעה|שעתיים|$1 שעות}}.",
        "mailerror": "שגיאה בשליחת דואר: $1",
        "parser-unstrip-loop-warning": "נמצאה לולאה בפריסה",
        "parser-unstrip-recursion-limit": "עומק הרקורסיה של הפריסה עבר את המגבלה ($1)",
        "converter-manual-rule-error": "התגלתה שגיאה בכלל המרת שפה ידני",
-       "undo-success": "× ×\99ת×\9f ×\9c×\91×\98×\9c ×\90ת ×\94ער×\99×\9b×\94.\n×\90× ×\90 ×\91Ö´Ö¼×\93ק×\95 ×\90ת ×\94ש×\95×\95×\90ת ×\94×\92רס×\90×\95ת ×\9c×\9e×\98×\94 ×\9b×\93×\99 ×\9c×\95×\95×\93×\90 ×©×\96×\94 ×\90×\9b×\9f ×\9e×\94 ×©×\90ת×\9d ×¨×\95צ×\99×\9d ×\9cעש×\95ת, ×\95×\90×\96 ×©Ö´×\81×\9eר×\95 ×\90ת ×\94ש×\99× ×\95×\99×\99×\9d ×\9c×\9e×\98×\94 ×\9b×\93×\99 ×\9c×\91צע את ביטול העריכה.",
+       "undo-success": "× ×\99ת×\9f ×\9c×\91×\98×\9c ×\90ת ×\94ער×\99×\9b×\94.\n×\90× ×\90 ×\91Ö´Ö¼×\93ק×\95 ×\90ת ×\94ש×\95×\95×\90ת ×\94×\92רס×\90×\95ת ×\9c×\9e×\98×\94 ×\9b×\93×\99 ×\9c×\95×\95×\93×\90 ×©×\96×\94 ×\90×\9b×\9f ×\9e×\94 ×©×\90ת×\9d ×¨×\95צ×\99×\9d ×\9cעש×\95ת, ×\95×\90×\96 ×©Ö´×\81×\9eר×\95 ×\90ת ×\94ש×\99× ×\95×\99×\99×\9d ×\9c×\9e×\98×\94 ×\9b×\93×\99 ×\9cס×\99×\99×\9d את ביטול העריכה.",
        "undo-failure": "לא ניתן היה לבטל את העריכה עקב התנגשות עם עריכות מאוחרות יותר.",
        "undo-norev": "לא ניתן היה לבטל את העריכה כי היא אינה קיימת או כי היא נמחקה.",
        "undo-nochange": "נראה שהעריכה כבר בוטלה.",
        "mergelogpagetext": "זוהי רשימה של המיזוגים האחרונים של גרסאות מדף אחד לתוך דף שני.",
        "history-title": "היסטוריית גרסאות של הדף \"$1\"",
        "difference-title": "הבדלים בין גרסאות בדף \"$1\"",
-       "difference-title-multipage": "×\94×\91×\93×\9c×\99×\9d ×\91×\99×\9f ×\94×\93×£ \"$1\" ×\9c×\91×\99×\9f ×\94×\93×£ \"$2\"",
+       "difference-title-multipage": "הבדלים בין הדף \"$1\" לדף \"$2\"",
        "difference-multipage": "(הבדלים בין דפים)",
        "lineno": "שורה $1:",
        "compareselectedversions": "השוואת הגרסאות שנבחרו",
        "largefileserver": "גודל הקובץ חורג ממגבלת השרת.",
        "emptyfile": "נראה שהקובץ שהעלית ריק.\nייתכן שהסיבה לכך היא שגיאת הקלדה בשם הקובץ.\nיש לוודא שזה הקובץ שברצונך להעלות.",
        "windows-nonascii-filename": "אתר ויקי זה אינו תומך בשמות קבצים עם תווים מיוחדים או תווים שאינם באנגלית.",
-       "fileexists": "קובץ בשם הזה כבר קיים, אנא בדקו את <strong>[[:$1]]</strong> אם אינכם בטוחים שברצונכם להחליף אותו.\n[[$1|thumb]]",
+       "fileexists": "קובץ בשם הזה כבר קיים, אנא בִּדקו את <strong>[[:$1]]</strong> אם אינכם בטוחים שברצונכם להחליף אותו.\n[[$1|thumb]]",
        "filepageexists": "דף תיאור הקובץ עבור קובץ זה כבר נוצר ב<strong>[[:$1]]</strong>, אך לא קיים קובץ בשם זה.\nתיאור הקובץ שתכתבו לא יופיע בדף תיאור הקובץ.\nכדי לגרום לו להופיע שם, יהיה עליכם לערוך אותו ידנית. [[$1|thumb]]",
        "fileexists-extension": "קובץ עם שם דומה כבר קיים: [[$2|thumb]]\n* שם הקובץ המועלה: <strong>[[:$1]]</strong>\n* שם הקובץ הקיים: <strong>[[:$2]]</strong>\nאולי כדאי לתת לקובץ שם ספציפי יותר?",
        "fileexists-thumbnail-yes": "נראה שהקובץ הוא תמונה מוקטנת (ממוזערת).\n[[$1|thumb]]\nיש לבדוק את הקובץ <strong>[[:$1]]</strong>.\nאם הקובץ שבדקת הוא אותה התמונה בגודל מקורי, אין זה הכרחי להעלות גם תמונה ממוזערת.",
        "upload-description": "תיאור הקובץ",
        "upload-options": "אפשרויות העלאה",
        "watchthisupload": "מעקב אחרי קובץ זה",
-       "filewasdeleted": "קובץ בשם זה כבר הועלה בעבר, ולאחר מכן נמחק. אנא בדקו את הדף $1 לפני שתמשיכו להעלותו שנית.",
+       "filewasdeleted": "קובץ בשם זה כבר הועלה בעבר, ולאחר מכן נמחק.\nאנא בִּדקו את $1 לפני שתמשיכו להעלות את הקובץ שנית.",
        "filename-thumb-name": "נראה שכותרת הקובץ היא כותרת של תמונה מוקטנת (ממוזערת). יש להימנע מהעלאת תמונות ממוזערות בחזרה לאותו אתר ויקי. אם זו אינה תמונה ממוזערת, יש לתקן את שם הקובץ כך שיהיה משמעותי יותר ושלא יכלול את הקידומת של תמונה ממוזערת.",
        "filename-bad-prefix": "שם הקובץ שאתם מעלים מתחיל ב־<strong>\"$1\"</strong>, שהוא שם שאינו מתאר את הקובץ ובדרך כלל מוקצה אוטומטית על־ידי מצלמות דיגיטליות.\nיש לבחור שם מתאים יותר לקובץ, שיתאר את תכניו.",
        "filename-prefix-blacklist": " #<!-- נא להשאיר שורה זו בדיוק כפי שהיא --> <pre>\n# התחביר הוא כדלקמן:\n#   * כל דבר מתו \"#\" לסוף השורה הוא הערה\n#   * כל שורה לא ריקה היא קידומת לשמות קבצים טיפוסיים שמצלמות דיגיטליות נותנות אוטומטית\nCIMG # Casio\nDSC_ # Nikon\nDSCF # Fuji\nDSCN # Nikon\nDUW # מספר טלפונים סלולריים\nIMG # כללי\nJD # Jenoptik\nMGP # Pentax\nPICT # שונות\n #</pre> <!-- נא להשאיר שורה זו בדיוק כפי שהיא -->",
        "log-edit-tags": "עריכת התגיות של רשומות היומן שנבחרו",
        "checkbox-select": "בחירה: $1",
        "checkbox-all": "הכול",
-       "checkbox-none": "כלום",
-       "checkbox-invert": "×\94פ×\99×\9bת ×\94×\91×\97×\99ר×\94",
+       "checkbox-none": "×\9c×\90 ×\9b×\9c×\95×\9d",
+       "checkbox-invert": "הפיכה",
        "allpages": "כל הדפים",
        "nextpage": "הדף הבא ($1)",
        "prevpage": "הדף הקודם ($1)",
        "allpagesfrom": "הצגת דפים החל מ:",
        "allpagesto": "הצגת דפים עד:",
        "allarticles": "כל הדפים",
-       "allinnamespace": "כל הדפים (מרחב שם $1)",
+       "allinnamespace": "×\9b×\9c ×\94×\93פ×\99×\9d (×\9eר×\97×\91 ×\94ש×\9d $1)",
        "allpagessubmit": "הצגה",
        "allpagesprefix": "הדפים ששמם מתחיל ב־:",
        "allpagesbadtitle": "כותרת הדף שניתנה הייתה בלתי־תקינה או שהייתה בה קידומת של קישור לשפה אחרת או לוויקי אחר.\nייתכן שהיא מכילה תו אחד או יותר האסורים לשימוש בכותרות.",
        "movepage-moved-redirect": "נוצרה הפניה.",
        "movepage-moved-noredirect": "יצירת ההפניה בוטלה.",
        "articleexists": "קיים כבר דף באותו שם, או שהשם שבחרת אינו תקין.\nנא לבחור שם אחר.",
-       "cantmove-titleprotected": "×\90×\99× ×\9a ×\9e×\95רש×\94 ×\9c×\94×¢×\91×\99ר ×\90ת ×\94×\93×£ ×\9cש×\9d ×\96×\94 ×\9b×\99×\95×\95×\9f ×©×\94ש×\9d ×\94×\97×\93ש ×\9e×\95×\92×\9f ×\9eפנ×\99 ×\99צ×\99ר×\94",
+       "cantmove-titleprotected": "×\90×\99×\9f ×\9c×\9a ×\94רש×\90×\94 ×\9c×\94×¢×\91×\99ר ×\90ת ×\94×\93×£ ×\9c×\9b×\90×\9f, ×\9b×\99 ×\94ש×\9d ×\94×\97×\93ש ×\9e×\95×\92×\9f ×\9eפנ×\99 ×\99צ×\99ר×\94.",
        "movetalk": "העברה גם של דף השיחה",
        "move-subpages": "העברת כל דפי המשנה (עד $1)",
        "move-talk-subpages": "העברת כל דפי המשנה של דף השיחה (עד $1)",
        "log-name-managetags": "יומן ניהול תגיות",
        "log-description-managetags": "דף זה כולל רשימה של פעולות ניהול הקשורות ל[[Special:Tags|תגיות]]. היומן כולל רק פעולות שבוצעו ידנית על־ידי מפעיל מערכת; ייתכן שתגיות ייווצרו או יימחקו על־ידי תוכנת הוויקי ללא הוספת ערך ליומן זה.",
        "logentry-managetags-create": "$1 {{GENDER:$2|יצר|יצרה}} את התגית \"$4\"",
-       "logentry-managetags-delete": "$1 {{GENDER:$2|מחק|מחקה}} את התגית \"4$\" (שהוסרה {{PLURAL:$5|מגרסה אחת/פריט יומן אחד|מ־$5 גרסאות ו/או פריטי יומן}})",
+       "logentry-managetags-delete": "$1 {{GENDER:$2|מחק|מחקה}} את התגית \"$4\" (שהוסרה {{PLURAL:$5|מגרסה אחת/פריט יומן אחד|מ־$5 גרסאות ו/או פריטי יומן}})",
        "logentry-managetags-activate": "$1 {{GENDER:$2|הפעיל|הפעילה}} את התגית \"$4\" לשימוש על־ידי משתמשים ובוטים",
        "logentry-managetags-deactivate": "$1 {{GENDER:$2|ביטל|ביטלה}} את הפעלת התגית \"$4\" לשימוש על־ידי משתמשים ובוטים",
        "log-name-tag": "יומן תגיות",
        "special-characters-group-ipa": "אלפבית פונטי בינלאומי (IPA)",
        "special-characters-group-symbols": "סימנים",
        "special-characters-group-greek": "יווני",
+       "special-characters-group-greekextended": "יוונית מורחבת",
        "special-characters-group-cyrillic": "קירילי",
        "special-characters-group-arabic": "ערבי",
        "special-characters-group-arabicextended": "ערבי מורחב",
index 3dfd4bb..2e63884 100644 (file)
        "special-characters-group-ipa": "आइपीए",
        "special-characters-group-symbols": "प्रतीक",
        "special-characters-group-greek": "ग्रीक",
+       "special-characters-group-greekextended": "ग्रीक विस्तृत",
        "special-characters-group-cyrillic": "सिरिलिक",
        "special-characters-group-arabic": "अरबी",
        "special-characters-group-arabicextended": "अरबी विस्तारित",
        "sessionprovider-generic": "$1 सत्र",
        "sessionprovider-mediawiki-session-cookiesessionprovider": "कुकी-आधारित सत्र",
        "sessionprovider-nocookies": "हो सकता है कि कुकी निष्क्रिय है। कृपया देखें कि और सक्रिय करें।",
-       "randomrootpage": "अविशिष्ट मूल पृष्ठ"
+       "randomrootpage": "अविशिष्ट मूल पृष्ठ",
+       "log-action-filter-block": "प्रतिबंध के प्रकार:",
+       "log-action-filter-delete": "हटाने के प्रकार:",
+       "log-action-filter-patrol": "परीक्षण के प्रकार:",
+       "log-action-filter-protect": "सुरक्षा के प्रकार:",
+       "log-action-filter-upload": "अपलोड के प्रकार:",
+       "log-action-filter-all": "सभी",
+       "log-action-filter-block-block": "अवरोध",
+       "log-action-filter-block-reblock": "अवरोध परिवर्तन",
+       "log-action-filter-block-unblock": "अवरोधरहित",
+       "log-action-filter-delete-delete": "पृष्ठ हटाना",
+       "log-action-filter-delete-restore": "पृष्ठ न हटाना",
+       "log-action-filter-delete-event": "पृष्ठ हटाने का लॉग",
+       "log-action-filter-delete-revision": "अवतरण हटाना",
+       "log-action-filter-patrol-patrol": "अपने से परीक्षण",
+       "log-action-filter-patrol-autopatrol": "स्वतः पुनरीक्षण",
+       "log-action-filter-protect-protect": "सुरक्षा",
+       "log-action-filter-protect-modify": "सुरक्षा परिवर्तन",
+       "log-action-filter-protect-unprotect": "असुरक्षा",
+       "log-action-filter-upload-upload": "नया अपलोड",
+       "log-action-filter-upload-overwrite": "फिर से अपलोड"
 }
index 7b0dd88..39436f8 100644 (file)
        "preview": "Նախադիտում",
        "showpreview": "Նախադիտել",
        "showdiff": "Կատարված փոփոխությունները",
-       "blankarticle": "<strong>Զգուշացում:</strong> Էջը, որը Դուք ստեղծում եք, դատարկ է:\nԵթե նորից սեղմեք «\"{{int:savearticle}}\"» կոճակը, էջը կստեղծվի առանց որևէ բովանդակության:",
+       "blankarticle": "<strong>Զգուշացում:</strong> Էջը, որը Դուք ստեղծում եք, դատարկ է:\nԵթե նորից սեղմեք «{{int:savearticle}}» կոճակը, էջը կստեղծվի առանց որևէ բովանդակության:",
        "anoneditwarning": "<strong>Ուշադրություն,</strong> Դուք չեք մտել համակարգ։ Ցանկացած խմբագրման դեպքում Ձեր IP հասցեն կդառնա բոլորին տեսանելի։ Եթե Դուք <strong>[$1 մուտք գործեք]</strong> կամ <strong>[$2 ստեղծեք մասնակցային հաշիվ]</strong>, Ձեր կատարած խմբագրումները կկապվեն Ձեր մասնակցային անվան հետ, ինչպես նաև կունենաք այլ առավելություններ։",
        "anonpreviewwarning": "<em>Դուք չեք մտել համակարգ։\nՀիշելով Ձեր կատարած խմբագրումը, այն կպահանվի Ձեր IP հասցեի հետ միասին այս էջի խմբագրումների պատմության մեջ։</em>",
        "missingsummary": "'''Հիշեցում.''' Դուք չեք տվել խմբագրման ամփոփում։ «Հիշել» կոճակի կրկնակի մատնահարման դեպքում փոփոխությունները կհիշվեն առանց ամփոփման։",
index 6e0cd11..ce2ebdd 100644 (file)
        "search": "Лахаp",
        "searchbutton": "Лахар",
        "go": "Дехьа г|о",
-       "searcharticle": "Дехьа г|о",
+       "searcharticle": "Дехьавала",
        "history": "Истори",
        "history_short": "Истори",
        "updatedmarker": "Со ханача денца хувцамаш хиннaд",
        "printableversion": "Кепатохара нийсхьал",
-       "permalink": "Даиман латташ йола хьожадерг",
+       "permalink": "Даиман латташ йола хьожаярг",
        "print": "Кепатохар",
        "view": "Б|аргтассам",
        "view-foreign": "Мазаоаг|он чу $1 хьажа",
-       "edit": "Ð¥Ñ\83вÑ\86а",
+       "edit": "Ð\9dийÑ\81де",
        "edit-local": "Хувца локальни йоазонца сурт оттадар",
        "create": "Хьаде",
        "create-local": "ТIатоха локальни йоазонца сурт оттадар",
        "specialpage": "Г|улакхадара оаг|ув",
        "personaltools": "Са г|ирсаш",
        "articlepage": "Йоазон т|а б|аргтасса",
-       "talk": "Дувцам",
+       "talk": "Дувца оттадар",
        "views": "БӀаргтассамаш",
        "toolbox": "ГӀирсаш",
        "userpage": "Доакъошхочун оаг|он т|а б|аргтасса",
        "imagepage": "Лурдара оаг|oн т|а б|аргтасса",
        "mediawikipage": "Xоаман оаг|ув хьахьокха",
        "templatepage": "Ч|абала оаг|oн т|а б|аргтасса",
-       "viewhelppage": "ГӀо деха",
+       "viewhelppage": "ГӀо хьаэцар",
        "categorypage": "Катага оаг|oн т|а б|аргтасса",
        "viewtalkpage": "Дувцамага б|аргтасса",
        "otherlanguages": "Кхыча меттаех",
        "redirectedfrom": "($1 т|aра хьадейта да)",
        "redirectpagesub": "Д|а-хьа дайта оаг|ув",
        "redirectto": "Д|ахьожаде укх т|а:",
-       "lastmodifiedat": "Укх оаг|oн т|ехьара  хувцам: $2, $1.",
+       "lastmodifiedat": "Укх оагIoн тIехьара хувцам: $2, $1.",
        "viewcount": "Укх оаг|oн т|а б|аргтассаб {{PLURAL:$1|цхьааца\n|$1 times}}. {{PLURAL:$1|1=цхьазза|$1за}}.",
        "protectedpage": "Лорама оаг|ув",
        "jumpto": "Укхаза дехьаг|о:",
        "mainpage": "Кертера оагӀув",
        "mainpage-description": "Кертера оагӀув",
        "policy-url": "Project:Бокъонаш",
-       "portal": "Ð\93Ñ\83лламков",
-       "portal-url": "Project:Ð\93Ñ\83лламков",
+       "portal": "ЮкÑ\8aаÑ\80а ков",
+       "portal-url": "Project:ЮкÑ\8aаÑ\80а ков",
        "privacy": "Паьлбокъо",
        "privacypage": "Project:Паьлбокъо",
        "badaccess": "Чуваларa гӀалат",
        "nstab-media": "Медифаг",
        "nstab-special": "ГӀулакха оагӀув",
        "nstab-project": "Хьахоадайтамах лаьца",
-       "nstab-image": "Ð\9fаÑ\8cл",
+       "nstab-image": "Файл",
        "nstab-mediawiki": "Хоам",
        "nstab-template": "ЧIабал",
        "nstab-help": "ГӀо",
        "emailconfirmlink": "Доаржален хоамни хьожадорг дIачIоагIаде",
        "loginlanguagelabel": "Мотт: $1",
        "pt-login": "Чувала/яла",
-       "pt-createaccount": "Ð\94акÑ\8aалаÑ\8cÑ\86аÑ\80Ñ\85о кхолла",
+       "pt-createaccount": "УÑ\87Ñ\91Ñ\82а Ñ\8fздаÑ\80 кхолла",
        "changepassword": "КъайладIоaгIа дIахувцар",
        "oldpassword": "Къаьна къайладIоагӀа:",
        "newpassword": "Керда къайладIоагӀа:",
        "italic_sample": "Кулга яздам",
        "italic_tip": "Кулга яздам",
        "link_sample": "Ӏинка кортале",
-       "link_tip": "ЧураӀинк",
+       "link_tip": "Чура хьожадарг",
        "extlink_sample": "Ӏинка кортале http://www.example.com",
        "extlink_tip": "Арен Ӏинка (http:// тамагӀах дийца ма ле)",
        "headline_sample": "Кортален яздам",
        "nowiki_sample": "Укхаза кийчаде дезаш доаца яздам оттаде",
        "nowiki_tip": "Масса-бустамлорг теркамза дита",
        "image_tip": "Чуяьккха паьла",
-       "media_tip": "Ð\9fаÑ\8cла Ó\80инк",
+       "media_tip": "Файлан Ñ\82IаÑ\85Ñ\8cожаваÑ\80",
        "sig_tip": "Шун кулгаяздар а, хӀанзара ха а",
        "hr_tip": "Мухала мугӀ (могаш тайпара к|еззига хайраде)",
        "summary": "Хувцамий белгалдер",
        "nextn": "{{PLURAL:$1|тlехьайоагlар $1|тlехьайоагlараш $1|тlехьайоагlараш $1}}",
        "prevn-title": "{{PLURAL:$1|1=$1 хьалхара йоазув|$1 хьалхара йоазувнаш}}",
        "nextn-title": "{{PLURAL:$1|1=$1 тIехьара йоазув|$1 тIехьара йоазувнаш}}",
-       "shown-title": "Хьóкха $1 {{PLURAL:$1|даь йоазо|даь йоазош}} укх оáгIувна тIа",
+       "shown-title": "Хьóкха $1 {{PLURAL:$1|даь йоазо|даь йоазонаш}} укх оáгIувна тIа",
        "viewprevnext": "($1 {{int:pipe-separator}} $2) ($3) хьажа",
        "searchmenu-exists": "'''Укх масса-хьахьоадайтамач ер оаг|ув \"[[:$1]]\" я'''",
        "searchmenu-new": "'''Укх \"[[:$1]]\" масса-хьахоадайтамач оагIув хьае!'''",
        "action-read": "Укх оагIуви дешам",
        "action-edit": "Ер оагIув хувца",
        "nchanges": "$1 {{PLURAL:$1|1=хувцам|хувцамаш}}",
-       "enhancedrc-history": "Ð\98стори",
+       "enhancedrc-history": "истори",
        "recentchanges": "Керда хувцамаш",
        "recentchanges-legend": "Керда хувцамий оттамаш",
        "recentchanges-summary": "КIалхагIа лоарамий доаламе тIехьара оагIувний хувцамаш дIаязадаь да {{grammar:genitive|{{SITENAME}}}}.",
        "rcshowhideliu": "Чубаьнначара дакъалаьцархочий $1",
        "rcshowhideliu-hide": "Къайлдаккха",
        "rcshowhideanons": "$1 цIияьккханза дакъалаьцархой",
+       "rcshowhideanons-show": "Хьахьокха",
        "rcshowhideanons-hide": "Къайлдаккха",
        "rcshowhidepatr": "$1 теркам даь хувцамаш",
        "rcshowhidemine": "$1 сай хувцамаш",
        "recentchangeslinked-summary": "Ер, Iинк яь йола оагIув (е укх цатегачу чуйоагIараш), дукха ха йоацаш хьийца оагIувнашкий дагарле я.\n[[Special:Watchlist|Шун теркама дагарленашках]] чуйоагIа оагIувнаш '''белгалаяь я'''.",
        "recentchangeslinked-page": "ОагIува цIи",
        "recentchangeslinked-to": "ОагIувнаш тIа хувцамаш хьахьокха, хьахьекха йола оагIув тIа Iинкаш еш йола.",
-       "upload": "Ð\9fаÑ\8cл Ñ\87Ñ\83Ñ\8fÑ\8cккха",
+       "upload": "Файл Ñ\87Ñ\83даккха",
        "uploadbtn": "Паьл чуяьккха",
        "uploadlogpage": "Чуяьккхамий тептар",
        "filedesc": "Лоаца лоацам",
        "filehist-filesize": "Паьла юстарал",
        "filehist-comment": "ХIамоалар",
        "imagelinks": "Паьлий пайда эца",
-       "linkstoimage": "{{PLURAL:$1|1=ТIехьайоагIа $1 оагIув Iинк ду|ТIехьайоагIа $1 оагIувнаш Iинкаш ду}} укх паьла тIа:",
+       "linkstoimage": "{{PLURAL:$1|1=ТIехьайоагIача $1 оагIуво тIахьожаву|ТIехьайоагIача $1 оагIувнаша тIахьожаву}} укх файла тIа:",
        "nolinkstoimage": "Йола паьла тIа  Iинк ю оагIувнаш дац",
        "sharedupload": "Ер паьла $1чера я, кхыча хьахьоадайтамча хьахайраде йийшайолаш я.",
        "sharedupload-desc-here": "Ер паьл $1чара я, кхыдола хьахьоадайтамача хайрамбе йийш йолаш да.\nЦун [$2 лоацама оагIувца] лоаца маIандар кIалхагIа латта.",
        "filedelete-reason-otherlist": "Кхыдола бахьан",
        "download": "хьачуяьккха",
        "unwatchedpages": "Теркамза оагIувнаш",
-       "randompage": "Ð\94агадоаÑ\86а йоазув",
+       "randompage": "Ца Ñ\85овÑ\88 Ð½Ð¸Ð¹Ñ\81Ñ\8aенна йоазув",
        "statistics": "Дагара куц",
        "statistics-pages": "ОагIувнаш",
        "brokenredirects-edit": "хувца",
        "tooltip-pt-mycontris": "Шун хувцамаш",
        "tooltip-pt-login": "Укхаза хьай цIи аьле чувала/яла йиша я, амма чуцаваьлача/ялача хIама а дац",
        "tooltip-pt-logout": "Аравала/яла",
-       "tooltip-pt-createaccount": "Хьа бокъо я лоархIама яздар кхелла система чу вала, амма декхар долаш дац из.",
+       "tooltip-pt-createaccount": "Хьа бокъо я учёта яздар кхелла система чу вала, амма декхар долаш дац из.",
        "tooltip-ca-talk": "ОагIувна чулоацаме дувцам",
-       "tooltip-ca-edit": "Ð¥Ñ\83вÑ\86а ер оагIув",
+       "tooltip-ca-edit": "Ð\9dийÑ\81Ñ\8aе ер оагIув",
        "tooltip-ca-addsection": "Керда декъам хьаде",
        "tooltip-ca-viewsource": "Ер оагIув хувцамах лораяь я, амма шун цунна гIувамага хьажа бокъо я.",
-       "tooltip-ca-history": "УкÑ\85 Ð¾Ð°Ð³IÑ\83вни Ñ\85Ñ\83вÑ\86ама Ñ\82аптар",
+       "tooltip-ca-history": "УкÑ\85 Ð¾Ð°Ð³IÑ\83ван Ð´Ð°Ñ\8c Ñ\85Ñ\83вÑ\86амаÑ\88 Ñ\82Iа Ð´Ð¾Ð»Ð° Ñ\82ептар",
        "tooltip-ca-protect": "Eр оагIув лорае",
        "tooltip-ca-delete": "Ер оагIув дIаяькха",
        "tooltip-ca-move": "Укх оагIува цIи хувца",
        "tooltip-n-currentevents": "ХIанзара хоаман дагарле",
        "tooltip-n-recentchanges": "ТӀехьара хувцамий дагарче",
        "tooltip-n-randompage": "Бе йоаца оагӀув ела",
-       "tooltip-n-help": "Новкъостала моттиг",
-       "tooltip-t-whatlinkshere": "Ð\9cаÑ\81Ñ\81айола Ð¾Ð°Ð³IÑ\83вий Ð´Ð°Ð³Ð°Ñ\80ле, Ñ\83кÑ\85 Ð¾Ð°Ð³IÑ\83в Ñ\82Iа IинкаÑ\88 Ð»Ñ\83Ñ\88 Ð¹Ð¾Ð»Ð°",
+       "tooltip-n-help": "Новкъостал лаха мегаш йола моттиг",
+       "tooltip-t-whatlinkshere": "УкÑ\85аз Ñ\82Iа Ñ\85Ñ\8cожавеÑ\88 Ð¹Ð¾Ð»Ð° Ð¾Ð°Ð³IÑ\83вий Ñ\81пиÑ\81ок",
        "tooltip-t-recentchangeslinked": "ОагIувнаш тIа тIехьара хувцамаш, укх оагIувнера Iинк яь йола",
        "tooltip-feed-rss": "Укх оагIувна RSSчу гойтар",
        "tooltip-feed-atom": "Укх оаг|увна Atomчу гойтар",
        "tooltip-t-contributions": "{{GENDER:$1|Укх доакъашхочо хийца}} йола оагIувнаш",
        "tooltip-t-emailuser": "Укх дакъалаьцархочоа зIы яхьийта",
-       "tooltip-t-upload": "Ð\9fаÑ\8cлаÑ\88 Ñ\87Ñ\83Ñ\8fÑ\8cккха",
+       "tooltip-t-upload": "ФайлаÑ\88 Ñ\87Ñ\83даккха",
        "tooltip-t-specialpages": "ГIулакха оагIувний дагарчe",
        "tooltip-t-print": "Укх оаугIувна каьхатзарбане доржам",
        "tooltip-t-permalink": "Укх оагIув доржама даим латта Iинк",
        "tooltip-ca-nstab-main": "Йоазува чулоацам",
        "tooltip-ca-nstab-user": "Дакъалаьцархочунна ший оагIув",
-       "tooltip-ca-nstab-special": "Ер гIулакха оагIув я, из хувца хьо бокъо йолаш вац/яц.",
+       "tooltip-ca-nstab-special": "Ер гIулакха оагIув я, из хувца бокъо яц",
        "tooltip-ca-nstab-project": "Хьахьоадайтама оагIув",
        "tooltip-ca-nstab-image": "Паьла оагIув",
        "tooltip-ca-nstab-template": "ЧIабала оагIув",
-       "tooltip-ca-nstab-help": "ГӀона оагIув",
+       "tooltip-ca-nstab-help": "ГӀон оагIув",
        "tooltip-ca-nstab-category": "Цатега оагIув",
        "tooltip-minoredit": "Ер хувцар башха доаца санна белгалде",
        "tooltip-save": "Хувцамаш кходе",
        "version-software-version": "Доржам",
        "fileduplicatesearch-filename": "ПаьлацIи:",
        "fileduplicatesearch-submit": "Лаха",
-       "specialpages": "Ð\93\83лакÑ\85ий оагIувнаш",
+       "specialpages": "Ð\9bаÑ\8cÑ\80Ñ\85Ñ\85Iа Ð¹Ð¾Ð»Ð° оагIувнаш",
        "specialpages-group-users": "Дакъалаьцархой, цара бокъо",
        "specialpages-group-pages": "ОагIувний дагарченаш",
        "specialpages-group-pagetools": "ОагIувнаша гIирсаш",
        "htmlform-submit": "ДIадахьийта",
        "htmlform-reset": "Хувцамаш юхадаккха",
        "htmlform-selectorother-other": "Кхыдола",
+       "logentry-newusers-create": "{{GENDER:$2|Доакъашхочо кхеллай}} учёта яздар $1",
        "rightsnone": "(а)",
        "revdelete-summary": "хувцамий лоацам",
        "searchsuggest-search": "Лаха",
index 1b2b603..58f0050 100644 (file)
        "passwordreset-emailsentusername": "Se c'è un indirizzo di posta elettronica associato con questo nome utente, allora verrà inviata una email per reimpostare la password.",
        "passwordreset-emailsent-capture": "È stata inviata una email di reimpostazione della password, il contenuto è riportato di seguito.",
        "passwordreset-emailerror-capture": "È stata generata una email di reimpostazione della password, riportata di seguito. L'invio {{GENDER:$2|all'utente}} non è riuscito: $1",
-       "changeemail": "Modifica o rimuovi indirizzo email",
+       "changeemail": "Modifica o rimuovi indirizzo di posta elettronica",
        "changeemail-header": "Completa questo modulo per cambiare il tuo indirizzo email. Se vuoi rimuovere l'associazione di qualsiasi indirizzo email dalla tua utenza, lascia il nuovo indirizzo email vuoto quando invii il modulo.",
        "changeemail-passwordrequired": "Sarà necessario inserire la password per confermare la modifica.",
        "changeemail-no-info": "Devi aver effettuato l'accesso per accedere a questa pagina direttamente.",
        "prefs-watchlist-token": "Token osservati speciali:",
        "prefs-misc": "Varie",
        "prefs-resetpass": "Cambia password",
-       "prefs-changeemail": "Modifica o rimuovi indirizzo email",
-       "prefs-setemail": "Imposta un indirizzo email",
+       "prefs-changeemail": "Modifica o rimuovi indirizzo di posta elettronica",
+       "prefs-setemail": "Imposta un indirizzo di posta elettronica",
        "prefs-email": "Opzioni email",
        "prefs-rendering": "Aspetto",
        "saveprefs": "Salva",
        "prefs-custom-js": "JavaScript personalizzato",
        "prefs-common-css-js": "CSS/JavaScript condiviso per tutti i temi:",
        "prefs-reset-intro": "È possibile usare questa pagina per reimpostare le proprie preferenze a quelle predefinite del sito.\nL'operazione non può essere annullata.",
-       "prefs-emailconfirm-label": "Conferma dell'e-mail:",
+       "prefs-emailconfirm-label": "Conferma dell'email:",
        "youremail": "Indirizzo email:",
        "username": "{{GENDER:$1|Nome utente}}:",
        "prefs-memberingroups": "{{GENDER:$2|Membro}} {{PLURAL:$1|del gruppo|dei gruppi}}:",
        "special-characters-group-ipa": "IPA",
        "special-characters-group-symbols": "Simboli",
        "special-characters-group-greek": "Greco",
+       "special-characters-group-greekextended": "Greco esteso",
        "special-characters-group-cyrillic": "Cirillico",
        "special-characters-group-arabic": "Arabo",
        "special-characters-group-arabicextended": "Arabo esteso",
index 32a4205..3f62970 100644 (file)
        "mw-widgets-titleinput-description-redirect": "$1 へのリダイレクト",
        "api-error-blacklisted": "他の、説明的なタイトルをお選びください。",
        "sessionprovider-generic": "$1 セッション",
-       "randomrootpage": "おまかせルートページ"
+       "randomrootpage": "おまかせルートページ",
+       "log-action-filter-block": "ブロックの種類",
+       "log-action-filter-upload": "ブロックの種類",
+       "log-action-filter-all": "すべて",
+       "log-action-filter-block-block": "ブロック",
+       "log-action-filter-block-reblock": "ブロック変更",
+       "log-action-filter-block-unblock": "ブロック解除",
+       "log-action-filter-delete-delete": "ページの削除",
+       "log-action-filter-delete-restore": "ページの復帰"
 }
index bd1ee65..2017608 100644 (file)
        "whatlinkshere-submit": "Өту",
        "autoblockid": "#$1 өздікбұғаттауы",
        "block": "Қатысушыны бұғаттау",
-       "unblock": "Ò\9aаÑ\82Ñ\8bÑ\81Ñ\83Ñ\88Ñ\8bнÑ\8b Ð±Ò±Ò\93аÑ\82Ñ\82аÑ\83Ñ\8bнан Ð±Ð¾Ñ\81аÑ\82Ñ\83",
+       "unblock": "Қатысушыны бұғатынан босату",
        "blockip": "{{GENDER:$1|Қатысушыны}} бұғаттау",
        "blockip-legend": "Қатысушыны бұғаттау",
        "blockiptext": "Төмендегі форманы жазу рұқсатын белгілі IP мекенжайынан не қатысушы есімінен бұғаттау үшін қолданыңыз.\nБұны тек бұзақылықты болдырмау үшін және де [[{{MediaWiki:Policy-url}}|ережелер]] бойынша атқаруыңыз кажет.\nТөменге тиісті себебін көрсетіңіз (мысалы дәлелге бұзақылықпен өзгертілген беттерді келтіріңіз).",
        "ipb-confirmhideuser": "Сіз қатысушыны бұғаттауда «қатысушыны жасыру» параметрін қосқасыз. Бұл барлық тізімдерден және журнал жазбаларынан қатысушы есімін жасырады. Сіз шынымен бұлай жасауды қалайсыз ба?",
        "ipb-confirmaction": "Егер сіз шынымен оны істеуді қаласаңыз, төмендегі жолақтан «{{int:ipb-confirm}}» дегенді белгілеңіз.",
        "ipb-edit-dropdown": "Бұғаттау себептерін өңдеу",
-       "ipb-unblock-addr": "$1 Ð´ÐµÐ³ÐµÐ½Ð´Ñ\96 Ð±Ò±Ò\93аÑ\82Ñ\82аÑ\83Ñ\8bнан Ð±Ð¾Ñ\81аÑ\82Ñ\83",
+       "ipb-unblock-addr": "$1 дегенді бұғатынан босату",
        "ipb-unblock": "Қатысушы атын немесе IP мекенжайын бұғаттамау",
        "ipb-blocklist": "Бұғатталғандарды қарау",
        "ipb-blocklist-contribs": "{{GENDER:$1|$1}} есімді қатысушының үлесі",
-       "unblockip": "Ò\9aаÑ\82Ñ\8bÑ\81Ñ\83Ñ\88Ñ\8bнÑ\8b Ð±Ò±Ò\93аÑ\82Ñ\82аÑ\83Ñ\8bнан Ð±Ð¾Ñ\81аÑ\82Ñ\83",
+       "unblockip": "Қатысушыны бұғатынан босату",
        "unblockiptext": "Төмендегі форманы IP мекенжайымен не қатысушы есімімен алдын-ала бұғатталған қатысушыға жазу рұқсатын қалпына келтіріу үшін қолданыңыз.",
        "ipusubmit": "Осы бұғаттауды алып тастау",
        "unblocked": "[[User:$1|$1]] бұғаттауы өшірілді",
        "blocklog-showsuppresslog": "Бұл қатысушы ұдайы жасырылып және бұғатталып отырған.\nДерек үшін төменде жасыру журналы берілген:",
        "blocklogentry": "[[$1]] дегенді $2 мерзімге бұғаттады $3",
        "reblock-logentry": "[[$1]] дегеннің бұғатталу мерзімінің аяқталуын $2 $3 дегенге өзгертті.",
-       "blocklogtext": "Ð\91ұл Ò\9bаÑ\82Ñ\8bÑ\81Ñ\83Ñ\88Ñ\8bлаÑ\80дÑ\8b Ð±Ò±Ò\93аÑ\82Ñ\82аÑ\83 Ð¶Ó\99не Ð±Ò±Ò\93аÑ\82Ñ\82аÑ\83Ñ\8bнан Ð±Ð¾Ñ\81аÑ\82Ñ\83 Ó\99Ñ\80екеÑ\82Ñ\82еÑ\80Ñ\96нÑ\96Ò£ Ð¶Ñ\83Ñ\80налÑ\8b.\nӨздÑ\96кÑ\82Ñ\96к Ð±Ò±Ò\93аÑ\82Ñ\82алÒ\93ан IP Ð¼ÐµÐºÐµÐ½Ð¶Ð°Ð¹Ð»Ð°Ñ\80 Ñ\82Ñ\96зÑ\96мделмеген.\nÒ\9aазÑ\96Ñ\80гÑ\96 Ñ\83аÒ\9bÑ\8bÑ\82Ñ\82аÒ\93Ñ\8b Ð±ÐµÐ»Ñ\81ендÑ\96 Ñ\82иÑ\8bмдаÑ\80 Ð¼ÐµÐ½ Ð±Ò±Ò\93аÑ\82Ñ\82аÑ\83лаÑ\80дÑ\8b [[Special:BlockList|бұÒ\93аÑ\82Ñ\82аÑ\83 Ñ\82Ñ\96зÑ\96мÑ\96нен]] Ò\9bаÑ\80аңÑ\8bз.",
-       "unblocklogentry": "$1 ÐµÑ\81Ñ\96мдÑ\96 Ò\9bаÑ\82Ñ\8bÑ\81Ñ\83Ñ\88Ñ\8bнÑ\8b Ð±Ò±Ò\93аÑ\82Ñ\82аÑ\83Ñ\8bнан Ð±Ð¾Ñ\81аÑ\82Ñ\82Ñ\8b",
+       "blocklogtext": "Бұл қатысушыларды бұғаттау және бұғатынан босату әрекеттерінің журналы.\nӨздіктік бұғатталған IP мекенжайлар тізімделмеген.\nҚазіргі уақыттағы белсенді тиымдар мен бұғаттауларды [[Special:BlockList|бұғаттау тізімінен]] қараңыз.",
+       "unblocklogentry": "$1 есімді қатысушыны бұғатынан босатты",
        "block-log-flags-anononly": "тек аноним қатысушылар",
        "block-log-flags-nocreate": "тіркелуін өшірді",
        "block-log-flags-noautoblock": "автобұғаттау өшірілген",
index a9f3289..1589163 100644 (file)
        "historysize": "({{PLURAL:$1|1 octetus|$1 octeti}})",
        "historyempty": "(vacua)",
        "history-feed-title": "Historia",
-       "history-feed-description": "Historia recensionum huius paginae",
+       "history-feed-description": "Historia redactionum huius paginae",
        "history-feed-item-nocomment": "$1 ad $2",
        "rev-deleted-comment": "(summarium celatum)",
        "rev-deleted-user": "(nomen usoris celatum est)",
        "shared-repo-name-wikimediacommons": "Vicimedia Communia",
        "filerevert": "Revertere $1",
        "filerevert-legend": "Reverti fasciculum",
-       "filerevert-intro": "Reversurus es '''[[Media:$1|$1]]''' ad [redactionem $4, sicut $2, $3 facta erat].",
+       "filerevert-intro": "Reversurus es '''[[Media:$1|$1]]''' ad [$4 redactionem quae $2, $3 facta erat].",
        "filerevert-comment": "Causa:",
        "filerevert-defaultcomment": "Reverti ad redactionem die $1, hora $2 ($3) factam",
        "filerevert-submit": "Revertere",
-       "filerevert-success": "'''[[Media:$1|$1]]''' reversum est ad redactionem [$4, quae $2, $3 facta erat].",
+       "filerevert-success": "'''[[Media:$1|$1]]''' reversum est ad [$4 redactionem quae $2, $3 facta erat].",
        "filedelete": "Delere $1",
        "filedelete-legend": "Fasciculum delere",
        "filedelete-intro": "Deles fasciculum '''[[Media:$1|$1]]''' una cum tota eius historia.",
index d253742..186bb22 100644 (file)
        "special-characters-group-ipa": "IPA",
        "special-characters-group-symbols": "Symboler",
        "special-characters-group-greek": "Griichesch",
+       "special-characters-group-greekextended": "Griichesch erweidert",
        "special-characters-group-cyrillic": "Kyrillisch",
        "special-characters-group-arabic": "Arabesch",
        "special-characters-group-arabicextended": "Arabesch, erweidert",
        "log-action-filter-protect": "Typ vu Spär",
        "log-action-filter-all": "All",
        "log-action-filter-block-block": "Spären",
+       "log-action-filter-block-reblock": "Ännere vun enger Spär",
        "log-action-filter-block-unblock": "Spär ophiewen",
        "log-action-filter-delete-delete": "Säite läschen",
        "log-action-filter-patrol-patrol": "Manuell Kontroll",
        "log-action-filter-patrol-autopatrol": "Automatesch Kontroll",
        "log-action-filter-protect-protect": "Spär",
-       "log-action-filter-protect-modify": "Spär-pÄnnerung"
+       "log-action-filter-protect-modify": "Spär-pÄnnerung",
+       "log-action-filter-upload-upload": "Neien Upload",
+       "log-action-filter-upload-overwrite": "Nees eroplueden"
 }
index 7975cf9..cfadde3 100644 (file)
        "tog-watchmoves": "हमराद्वारा घस्काओल पृष्ठ हमर साकांक्ष सूचीमे राखी",
        "tog-watchdeletion": "हमराद्वारा मेटाओल पृष्ठ हमर साकांक्ष सूचीमे राखी",
        "tog-watchrollback": "हमराद्वारा रोलब्याक कएल पृष्ठ हमर सांकक्ष सूचीमे राखी",
-       "tog-minordefault": "हमर à¤¸à¤­ à¤¸à¤®à¥\8dपादन à¤ªà¥\82रà¥\8dवनà¥\8dयसà¥\8dत à¤°à¥\82पà¥\87à¤\81 à¤®à¤¾à¤®à¥\82लà¥\80 à¤\95हà¥\82",
+       "tog-minordefault": "हमर à¤¸à¤­ à¤¸à¤®à¥\8dपादन à¤ªà¥\82रà¥\8dवनà¥\8dयसà¥\8dत à¤°à¥\82पमà¥\87 à¤®à¤¾à¤®à¥\82लà¥\80 à¤\95हà¥\80",
        "tog-previewontop": "सम्पादन पेटीक ऊपर दृश्य देखाबी",
        "tog-previewonfirst": "पहिल सम्पादनक बाद पूर्वावलोकन देखाबी",
        "tog-enotifwatchlistpages": "जौं हमर ध्यानसूचीक कोनो पन्नामे परिवर्तन हुअए तँ हमरा इमेल पठाबी",
        "tog-enotifusertalkpages": "हमर वार्ता पृष्ठ परिवर्तित भेला पर हमरा इमेल करी",
        "tog-enotifminoredits": "छोट परिवर्तनक हेतु सेहो हमरा इमेल भेजी",
        "tog-enotifrevealaddr": "अधिसूचना इमेलमे हमर इमेल पता देखाबी",
-       "tog-shownumberswatching": "धà¥\8dयान à¤°à¤¾à¤\96à¥\88बला à¤ªà¥\8dरयà¥\8bà¤\97à¤\95रà¥\8dताà¤\95 à¤¸à¤\82ख्या",
+       "tog-shownumberswatching": "धà¥\8dयान à¤°à¤¾à¤\96à¥\88बला à¤ªà¥\8dरयà¥\8bà¤\97à¤\95रà¥\8dताà¤\95 à¤¸à¤\99à¥\8dख्या",
        "tog-oldsig": "अखुनका दस्खत:",
-       "tog-fancysig": "दसà¥\8dà¤\96तà¤\95 à¤µà¤¿à¤\95िà¤\9fà¥\87à¤\95à¥\8dसà¤\9fà¤\95 à¤¸à¤®à¤¾à¤¨ à¤®à¤¾à¤¨à¥\80 (सà¥\8dवà¤\9aालित à¤¶à¥\8dरà¥\83à¤\82खला हीन)",
+       "tog-fancysig": "दसà¥\8dà¤\96तà¤\95 à¤µà¤¿à¤\95िà¤\9fà¥\87à¤\95à¥\8dसà¤\9fà¤\95 à¤¸à¤®à¤¾à¤¨ à¤®à¤¾à¤¨à¥\80 (सà¥\8dवà¤\9aालित à¤¶à¥\8dरà¥\83à¤\99à¥\8dखला हीन)",
        "tog-uselivepreview": "पूर्वावलोकनके उपयोग करी",
        "tog-forceeditsummary": "यदि सम्पादन सारांश नै देल गेल होए तहन हमरा सूचित करी",
-       "tog-watchlisthideown": "हमर à¤¸à¤¾à¤\95ाà¤\82à¤\95à¥\8dष à¤¸à¥\82à¤\9aà¥\80सà¤\81 à¤¹à¤®à¤° à¤¸à¤®à¥\8dपादन à¤¨à¥\81à¤\95ाà¤\89",
-       "tog-watchlisthidebots": "हमर à¤¸à¤¾à¤\95ाà¤\82à¤\95à¥\8dष à¤¸à¥\82à¤\9aà¥\80सà¤\81 à¤¸à¥\8dवà¤\9aालित à¤¸à¤®à¥\8dपादन à¤¹à¤\9fाà¤\89",
-       "tog-watchlisthideminor": "हमर à¤¸à¤¾à¤\95ाà¤\82à¤\95à¥\8dष à¤¸à¥\82à¤\9aà¥\80सà¤\81 à¤®à¤¾à¤®à¥\82लà¥\80 à¤¸à¤®à¥\8dपादन à¤¨à¥\81à¤\95ाà¤\89",
-       "tog-watchlisthideliu": "साà¤\95ाà¤\82à¤\95à¥\8dषसà¥\82à¤\9aà¥\80सà¤\81 à¤¸à¤®à¥\8dपà¥\8dरवà¥\87शित à¤ªà¥\8dरयà¥\8bà¤\95à¥\8dताà¤\95 à¤¸à¤®à¥\8dपादन à¤¹à¤\9fाà¤\89",
-       "tog-watchlisthideanons": "साà¤\95ाà¤\82à¤\95à¥\8dषसà¥\82à¤\9aà¥\80सà¤\81 à¤\85नाम à¤ªà¥\8dरयà¥\8bà¤\95à¥\8dताà¤\95 à¤¸à¤®à¥\8dपादन à¤¹à¤\9fाà¤\89",
-       "tog-watchlisthidepatrolled": "साà¤\95ाà¤\82à¤\95à¥\8dष à¤¸à¥\82à¤\9aà¥\80सà¤\81 à¤¸à¤\82à¤\9aालित à¤¸à¤®à¥\8dपादन à¤¨à¥\81à¤\95ाà¤\89",
-       "tog-ccmeonemails": "हमरा à¤¦à¥\8dवारा à¤¦à¥\8bसर à¤ªà¥\8dरयà¥\8bà¤\95à¥\8dताà¤\95à¥\87à¤\81 à¤ªà¤ à¤¾à¤\93ल à¤\88-पतà¥\8dरà¤\95 à¤\95à¥\89पà¥\80 à¤ªà¤ à¤¾à¤\89",
-       "tog-diffonly": "फाà¤\87ल-à¤\85नà¥\8dतर à¤ªà¥\8dरणालà¥\80à¤\95 à¤¨à¥\80à¤\9aाà¤\81 à¤ªà¤¨à¥\8dनाà¤\95 à¤¸à¤¾à¤®à¤¿à¤\97à¥\8dरà¥\80 à¤¨à¥\88 à¤¦à¥\87à¤\96ाà¤\89",
-       "tog-showhiddencats": "नà¥\81à¤\95ाà¤\8fल à¤¸à¤\82वरà¥\8dà¤\97 à¤¦à¥\87à¤\96ाà¤\89",
-       "tog-norollbackdiff": "प्रत्यावर्तनक बाद फाइल-अन्तर प्रणालीकेँ बिसरू",
-       "tog-useeditwarning": "à¤\9cब à¤¹à¤® à¤\95à¥\8bनà¥\8b à¤¸à¤\82पादन à¤ªà¥\83षà¥\8dठà¤\95à¥\87 à¤¬à¤¿à¤¨à¤¾ à¤¸à¥\81रà¤\95à¥\8dषित à¤\95à¥\87नà¥\88 à¤¬à¤¦à¤²à¤¾à¤µ à¤¸à¤\82à¤\97 à¤\9bà¥\8bà¤\87ड à¤¦à¤¿ à¤¤ à¤¹à¤®à¤°à¤¾ à¤¸à¥\82à¤\9aित à¤\95रà¥\81 ।",
-       "tog-prefershttps": "समà¥\8dपà¥\8dरवà¥\87शित à¤\95रलाà¤\95 à¤¬à¤¾à¤¦ à¤¸à¤¦à¥\88व à¤¸à¥\81रà¤\95à¥\8dषित à¤\95नà¥\87à¤\95à¥\8dशनà¤\95à¥\87 à¤ªà¥\8dरयà¥\8bà¤\97 à¤\95रà¥\81",
+       "tog-watchlisthideown": "हमर à¤¸à¤¾à¤\95ाà¤\82à¤\95à¥\8dष à¤¸à¥\82à¤\9aà¥\80सà¤\81 à¤¹à¤®à¤° à¤¸à¤®à¥\8dपादन à¤¨à¥\81à¤\95ाबà¥\80",
+       "tog-watchlisthidebots": "हमर à¤¸à¤¾à¤\95ाà¤\82à¤\95à¥\8dष à¤¸à¥\82à¤\9aà¥\80सà¤\81 à¤¸à¥\8dवà¤\9aालित à¤¸à¤®à¥\8dपादन à¤¹à¤\9fाबà¥\80",
+       "tog-watchlisthideminor": "हमर à¤¸à¤¾à¤\95ाà¤\82à¤\95à¥\8dष à¤¸à¥\82à¤\9aà¥\80सà¤\81 à¤®à¤¾à¤®à¥\82लà¥\80 à¤¸à¤®à¥\8dपादन à¤¨à¥\81à¤\95ाबà¥\80",
+       "tog-watchlisthideliu": "साà¤\95ाà¤\82à¤\95à¥\8dषसà¥\82à¤\9aà¥\80सà¤\81 à¤¸à¤®à¥\8dपà¥\8dरवà¥\87शित à¤ªà¥\8dरयà¥\8bà¤\95à¥\8dताà¤\95 à¤¸à¤®à¥\8dपादन à¤¹à¤\9fाबà¥\80",
+       "tog-watchlisthideanons": "साà¤\95ाà¤\82à¤\95à¥\8dषसà¥\82à¤\9aà¥\80सà¤\81 à¤\85नाम à¤ªà¥\8dरयà¥\8bà¤\95à¥\8dताà¤\95 à¤¸à¤®à¥\8dपादन à¤¹à¤\9fाबà¥\80",
+       "tog-watchlisthidepatrolled": "साà¤\95ाà¤\82à¤\95à¥\8dष à¤¸à¥\82à¤\9aà¥\80सà¤\81 à¤¸à¤\82à¤\9aालित à¤¸à¤®à¥\8dपादन à¤¨à¥\81à¤\95ाबà¥\80",
+       "tog-ccmeonemails": "हमरदà¥\8dवारा à¤¦à¥\8bसर à¤ªà¥\8dरयà¥\8bà¤\95à¥\8dताà¤\95 à¤ªà¤ à¤¾à¤\93ल à¤\88-पतà¥\8dरà¤\95 à¤\95पà¥\80 à¤ªà¤ à¤¾à¤¬à¥\80",
+       "tog-diffonly": "फाà¤\87ल-à¤\85नà¥\8dतर à¤ªà¥\8dरणालà¥\80à¤\95 à¤¨à¥\80à¤\9aाà¤\81 à¤ªà¤¨à¥\8dनाà¤\95 à¤¸à¤¾à¤®à¤¿à¤\97à¥\8dरà¥\80 à¤¨à¥\88 à¤¦à¥\87à¤\96ाबà¥\80",
+       "tog-showhiddencats": "नà¥\81à¤\95ाà¤\8fल à¤¶à¥\8dरà¥\87णà¥\80 à¤¦à¥\87à¤\96ाबà¥\80",
+       "tog-norollbackdiff": "प्रत्यावर्तनक बाद फाइल-अन्तर प्रणालीक बिसरी",
+       "tog-useeditwarning": "à¤\9cब à¤¹à¤® à¤\95à¥\8bनà¥\8b à¤¸à¤®à¥\8dपादन à¤ªà¥\83षà¥\8dठà¤\95à¥\87 à¤¬à¤¿à¤¨à¤¾ à¤¸à¥\81रà¤\95à¥\8dषित à¤\95à¥\87नà¥\88 à¤¬à¤¦à¤²à¤¾à¤µ à¤¸à¤\82à¤\97 à¤\9bà¥\8bडि à¤¦à¤¿ à¤¤ à¤¹à¤®à¤°à¤¾ à¤¸à¥\82à¤\9aित à¤\95रà¥\80 ।",
+       "tog-prefershttps": "समà¥\8dपà¥\8dरवà¥\87शित à¤\95रलाà¤\95 à¤¬à¤¾à¤¦ à¤¸à¤¦à¥\88व à¤¸à¥\81रà¤\95à¥\8dषित à¤\95नà¥\87à¤\95à¥\8dशनà¤\95à¥\87 à¤ªà¥\8dरयà¥\8bà¤\97 à¤\95रà¥\80",
        "underline-always": "सदिखन",
        "underline-never": "कखनो नै",
        "underline-default": "पूर्वन्यस्त गवेषक",
        "march-gen": "मार्च",
        "april-gen": "अप्रैल",
        "may-gen": "मई",
-       "june-gen": "à¤\9cà¥\82न",
+       "june-gen": "à¤\9cà¥\81न",
        "july-gen": "जुलाई",
        "august-gen": "अगस्त",
-       "september-gen": "सितà¤\82बर",
-       "october-gen": "à¤\85à¤\95à¤\9fà¥\82बर",
-       "november-gen": "नवà¤\82बर",
-       "december-gen": "दिसà¤\82बर",
+       "september-gen": "सितमà¥\8dबर",
+       "october-gen": "à¤\85à¤\95à¤\9fà¥\81बर",
+       "november-gen": "नवमà¥\8dबर",
+       "december-gen": "दिसमà¥\8dबर",
        "jan": "जन.",
        "feb": "फर.",
        "mar": "मा.",
        "march-date": "मार्च $1",
        "april-date": "अप्रैल $1",
        "may-date": "मई $1",
-       "june-date": "à¤\9cà¥\82न $1",
+       "june-date": "à¤\9cà¥\81न $1",
        "july-date": "जुलाई $1",
        "august-date": "अगस्त $1",
        "september-date": "सितम्बर $1",
-       "october-date": "à¤\85à¤\95à¥\8dà¤\9fà¥\82बर $1",
+       "october-date": "à¤\85à¤\95à¥\8dà¤\9fà¥\81बर $1",
        "november-date": "नवम्बर $1",
        "december-date": "दिसम्बर $1",
+       "period-am": "पूर्वाह्न",
+       "period-pm": "अपराह्न",
        "pagecategories": "{{PLURAL:$1|श्रेणी|कएटा श्रेणी}}",
-       "category_header": "सà¤\82वरà¥\8dà¤\97 \"$1\" मे पन्ना सभ",
-       "subcategories": "à¤\89पसà¤\82वरà¥\8dà¤\97",
-       "category-media-header": "सà¤\82वरà¥\8dà¤\97 \"$1\" मे मीडिया",
-       "category-empty": "''ऐ संवर्गमे अखन कोनो पन्ना वा मीडिया नै अछि।''",
-       "hidden-categories": "{{PLURAL:$1|नà¥\81à¤\95ाà¤\8fल à¤µà¤°à¥\8dà¤\97|नà¥\81à¤\95ाà¤\8fल à¤µà¤°à¥\8dà¤\97सभ}}",
-       "hidden-category-category": "नà¥\81à¤\95ाà¤\8fल à¤¸à¤\82वरà¥\8dà¤\97 सभ",
-       "category-subcat-count": "{{PLURAL:$2| ऐ संवर्गक खाली ई सभ उप संवर्ग अछिइ।.|ऐ संवर्गमे ई सभ {{PLURAL:$1| उपसंवर्ग|$1 उपसंवर्ग सभ}}, ऐमे सँ $2 सभटा।}}",
-       "category-subcat-count-limited": "à¤\90 à¤¸à¤\82वरà¥\8dà¤\97मà¥\87 à¤\85à¤\9bि {{PLURAL:$1|à¤\89पसà¤\82वरà¥\8dà¤\97|$1à¤\89पसà¤\82वरà¥\8dà¤\97 à¤¸à¤­}}",
-       "category-article-count": "{{PLURAL:$2|à¤\90 à¤¸à¤\82वरà¥\8dà¤\97मà¥\87 à¤\96ालà¥\80 à¤\88 à¤ªà¤¨à¥\8dना à¤\85à¤\9bि।| à¤\88 {{PLURAL:$1|पनà¥\8dना à¤\85à¤\9bि|$1 à¤ªà¤¨à¥\8dना à¤¸à¤­ à¤\85à¤\9bि}} à¤\90 à¤¸à¤\82वरà¥\8dà¤\97मà¥\87, à¤\9cाà¤\87मà¥\87 à¤¸à¤\81 $2 à¤¸à¤­à¥¤}}",
-       "category-article-count-limited": "à¤\88 {{PLURAL:$1|पनà¥\8dना à¤\85à¤\9bि|$1 à¤ªà¤¨à¥\8dना à¤¸à¤­ à¤\85à¤\9bि}}",
-       "category-file-count": "{{PLURAL:$2| ऐ संवर्गमे मातर ई फाइल अछि।| ई {{PLURAL:$1|फाइल अछि|$1 फाइल सभ अछि}} ऐ संवर्गमे, कुल $2 सँ।}}",
-       "category-file-count-limited": "ई {{PLURAL:$1|पन्ना अछि|$1 पन्ना सभ अछि}} ऐ संवर्गमे।",
+       "category_header": "शà¥\8dरà¥\87णà¥\80 \"$1\" मे पन्ना सभ",
+       "subcategories": "à¤\89पशà¥\8dरà¥\87णà¥\80",
+       "category-media-header": "शà¥\8dरà¥\87णà¥\80 \"$1\" मे मीडिया",
+       "category-empty": "<em>ई श्रेणीमे ई समय कोनो पृष्ठ या मिडिया नै अछि।</em>",
+       "hidden-categories": "{{PLURAL:$1|नà¥\81à¤\95ाà¤\8fल à¤¶à¥\8dरà¥\87णà¥\80|नà¥\81à¤\95ाà¤\8fल à¤¶à¥\8dरà¥\87णà¥\80सभ}}",
+       "hidden-category-category": "नà¥\81à¤\95ाà¤\8fल à¤¶à¥\8dरà¥\87णà¥\80सभ",
+       "category-subcat-count": "{{PLURAL:$2|ई श्रेणीमे मात्र निम्नलिखित उपश्रेणी अछि।|ई श्रेणीक कुल $2 मेसँ {{PLURAL:$1|उपश्रेणी निम्नलिखित अछि।|$1 उपश्रेणीसभ निम्नलिखित अछि।}}}}",
+       "category-subcat-count-limited": "à¤\88 à¤¶à¥\8dरà¥\87णà¥\80मà¥\87 à¤¨à¤¿à¤®à¥\8dनलिà¤\96ित {{PLURAL:$1|à¤\89पशà¥\8dरà¥\87णà¥\80 à¤\85à¤\9bि|$1 à¤\89पशà¥\8dरà¥\87णà¥\80 à¤\85à¤\9bि}}।",
+       "category-article-count": "{{PLURAL:$2|à¤\88 à¤¶à¥\8dरà¥\87णà¥\80मà¥\87 à¤®à¤¾à¤¤à¥\8dर à¤¨à¤¿à¤®à¥\8dनलिà¤\96ित à¤ªà¥\83षà¥\8dठ à¤\85à¤\9bि।|à¤\88 à¤¶à¥\8dरà¥\87णà¥\80मà¥\87 à¤¨à¤¿à¤®à¥\8dनलिà¤\96ित {{PLURAL:$1|पà¥\83षà¥\8dठ à¤\85à¤\9bि|$1 à¤ªà¥\83षà¥\8dठ à¤\85à¤\9bि}}, à¤\95à¥\81ल à¤ªà¥\83षà¥\8dठ $2}}",
+       "category-article-count-limited": "निमà¥\8dनलिà¤\96ित {{PLURAL:$1|पà¥\83षà¥\8dठ|$1 à¤ªà¥\83षà¥\8dठ}} à¤\88 à¤¶à¥\8dरà¥\87णà¥\80मà¥\87 à¤\85à¤\9bि।",
+       "category-file-count": "{{PLURAL:$2|ई श्रेणीमे मात्र निम्नलिखित फाइल अछि।|ई श्रेणीमे निम्नलिखित {{PLURAL:$1|फाइल|$1 फाइलसभ}} अछि, कुल फाइलसभ $2}}",
+       "category-file-count-limited": "ई श्रेणीमे निम्नलिखित {{PLURAL:$1|फाइल अछि।|फाइलसभ अछि।}}",
        "listingcontinuesabbrev": "शेष आगाँ।",
        "index-category": "क्रम कएल पन्ना सभ",
-       "noindex-category": "क्रम नै कएल पन्ना सभ",
-       "broken-file-category": "पन्ना सभ जाइमे फाइल लिंक सभ टूटल हुअए",
-       "about": "विषयमे",
-       "article": "विषय à¤¸à¥\82à¤\9aà¥\80 à¤ªà¤¨à¥\8dना",
-       "newwindow": "(नव à¤\96िड़à¤\95à¥\80सà¤\81 à¤\96à¥\81à¤\9cà¥\88à¤\9b)",
+       "noindex-category": "क्रम नै कएल पन्नासभ",
+       "broken-file-category": "पन्नासभ जाइमे फाइल लिङ्कसभ टूटल हुअए",
+       "about": "à¤\95à¥\87 à¤µà¤¿à¤·à¤¯à¤®à¥\87",
+       "article": "सामà¤\97à¥\8dरà¥\80 à¤²à¥\87à¤\96",
+       "newwindow": "(नव खिडकीसँ खुजैछ)",
        "cancel": "समाप्त",
        "moredotdotdot": "आर...",
-       "morenotlisted": "à¤\88 à¤ªà¥\81रा à¤¸à¥\82à¤\9aà¥\80 à¤¨à¥\88 à¤\85à¤\9bà¥\80 ।",
+       "morenotlisted": "à¤\88 à¤ªà¥\81रा à¤¸à¥\82à¤\9aà¥\80 à¤¨à¥\88 à¤\9bà¥\80।",
        "mypage": "पन्ना",
-       "mytalk": "वारà¥\8dतà¥\8dता",
-       "anontalk": "à¤\90 à¤\85निà¤\95à¥\87त à¤ªà¤¤à¤¾ à¤²à¥\87ल à¤µà¤¿à¤®à¤°à¥\8dश",
+       "mytalk": "वार्ता",
+       "anontalk": "वारà¥\8dता",
        "navigation": "सञ्चार",
        "and": "&#32;आर",
        "qbfind": "ताकू",
        "qbbrowse": "गवेषण करू",
        "qbedit": "सम्पादन करू",
        "qbpageoptions": "ई पृष्ठ",
-       "qbmyoptions": "हमर पृष्ठ सभ",
+       "qbmyoptions": "हमर पृष्ठसभ",
        "faq": "त्वरित प्रश्नोत्तरी",
        "faqpage": "Project: त्वरित प्रश्नोत्तरी",
-       "actions": "क्रिया सभ",
+       "actions": "क्रियासभ",
        "namespaces": "चेन्हासी समूहसभ",
        "variants": "प्रकारसभ",
        "navigation-heading": "दिक्चालन सूची",
        "help": "मदति",
        "search": "ताकी",
        "searchbutton": "ताकी",
-       "go": "à¤\9cाà¤\8a",
-       "searcharticle": "à¤\9cाà¤\87",
+       "go": "à¤\9cाà¤\8f",
+       "searcharticle": "à¤\9cाà¤\8f",
        "history": "पन्नाक इतिहास",
        "history_short": "इतिहास",
        "updatedmarker": "हमर अन्तिम आगमनसँ पहिने अद्यतन कएल",
        "printableversion": "प्रिन्ट करबा योग्य",
        "permalink": "स्थायी लिङ्क",
-       "print": "à¤\9bापà¥\82",
+       "print": "à¤\9bापà¥\80",
        "view": "देखी",
-       "view-foreign": "$1 à¤ªà¤° à¤¦à¥\87à¤\96à¥\81",
+       "view-foreign": "$1 à¤ªà¤° à¤¦à¥\87à¤\96à¥\80",
        "edit": "सम्पादन",
-       "edit-local": "सà¥\8dथानà¥\80य à¤µà¤¿à¤µà¤°à¤£ à¤¸à¤\82पादन",
-       "create": "बनाà¤\89",
+       "edit-local": "सà¥\8dथानà¥\80य à¤µà¤¿à¤µà¤°à¤£ à¤¸à¤®à¥\8dपादन",
+       "create": "बनाबà¥\80",
        "create-local": "स्थानीय विवरण निर्माण",
-       "editthispage": "à¤\8fहि à¤ªà¥\83षà¥\8dठà¤\95 à¤¸à¤\82पादन",
-       "create-this-page": "à¤\88 à¤ªà¤¨à¥\8dना à¤¬à¤¨à¤¾à¤\89",
-       "delete": "मà¥\87à¤\9fाà¤\89",
-       "deletethispage": "à¤\88 à¤ªà¤¨à¥\8dना à¤®à¥\87à¤\9fाà¤\89",
-       "undeletethispage": "à¤\88 à¤ªà¤¨à¥\8dना à¤®à¥\87à¤\9fाà¤\89",
-       "undelete_short": "आपस आनू  {{PLURAL:$1|एक सम्पादनt|$1 सम्पादन सभ}}",
-       "viewdeleted_short": "दà¥\87à¤\96à¥\82 {{PLURAL:$1|एकटा मेटाएल सम्पादन|$1 मेटाएल सम्पादन सभ}}",
-       "protect": "बà¤\9aाà¤\89",
-       "protect_change": "बदलà¥\82",
-       "protectthispage": "à¤\90 à¤ªà¤¨à¥\8dनाà¤\95 à¤°à¤\95à¥\8dषा à¤\95रà¥\82",
-       "unprotect": "रà¤\95à¥\8dषा à¤\95वà¤\9a à¤¬à¤¦à¤²à¥\82",
-       "unprotectthispage": "à¤\90 à¤ªà¤¨à¥\8dनाà¤\95 à¤°à¤\95à¥\8dषा à¤\95वà¤\9a à¤¬à¤¦à¤²à¥\82",
+       "editthispage": "à¤\88 à¤ªà¥\83षà¥\8dठ à¤¸à¤®à¥\8dपादन à¤\95रà¥\80",
+       "create-this-page": "à¤\88 à¤ªà¤¨à¥\8dना à¤¬à¤¨à¤¾à¤¬à¥\80",
+       "delete": "मà¥\87à¤\9fाबà¥\80",
+       "deletethispage": "à¤\88 à¤ªà¤¨à¥\8dना à¤®à¥\87à¤\9fाबà¥\80",
+       "undeletethispage": "à¤\88 à¤ªà¥\83षà¥\8dठà¤\95à¥\87 à¤ªà¥\81नरà¥\8dसà¥\8dथापित à¤\95रà¥\80।",
+       "undelete_short": "{{PLURAL:$1|एक हटाएल गएल|$1 हटाएल गएल}} परिवर्तन आपस आनी",
+       "viewdeleted_short": "दà¥\87à¤\96à¥\80 {{PLURAL:$1|एकटा मेटाएल सम्पादन|$1 मेटाएल सम्पादन सभ}}",
+       "protect": "सà¥\81रà¤\95à¥\8dषित à¤\95रà¥\80",
+       "protect_change": "बदलà¥\80",
+       "protectthispage": "à¤\88 à¤ªà¤¨à¥\8dनाà¤\95 à¤¸à¥\81रà¤\95à¥\8dषित à¤\95रà¥\80",
+       "unprotect": "à¤\85सà¥\81रà¤\95à¥\8dषित",
+       "unprotectthispage": "à¤\88 à¤ªà¥\83षà¥\8dठà¤\95 à¤¸à¥\81रà¤\95à¥\8dषा à¤¸à¥\8dतर à¤¬à¤¦à¤²à¥\80",
        "newpage": "नवका पन्ना",
-       "talkpage": "à¤\8fहि à¤ªà¥\83षà¥\8dठ à¤ªà¤° à¤µà¤¾à¤°à¥\8dतà¥\8dतालाप",
+       "talkpage": "à¤\88 à¤ªà¥\83षà¥\8dठà¤\95 à¤¬à¤¾à¤°à¥\87मà¥\87 à¤\9aरà¥\8dà¤\9aा à¤\95रà¥\80",
        "talkpagelinktext": "वार्ता",
        "specialpage": "विशेष पन्ना",
        "personaltools": "व्यक्तिगत उपकरणसभ",
-       "articlepage": "विषय-सà¥\82à¤\9aà¥\80 à¤ªà¤¨à¥\8dना à¤¦à¥\87à¤\96à¥\82",
+       "articlepage": "विषय-सà¥\82à¤\9aà¥\80 à¤ªà¤¨à¥\8dना à¤¦à¥\87à¤\96à¥\80",
        "talk": "वार्तालाप",
-       "views": "दà¥\83षà¥\8dà¤\9fिसभ",
-       "toolbox": "उपकरणसभ",
-       "userpage": "पà¥\8dरयà¥\8bà¤\95à¥\8dता à¤ªà¤¨à¥\8dना à¤¦à¥\87à¤\96à¥\82",
-       "projectpage": "परियà¥\8bà¤\9cना à¤ªà¤¨à¥\8dना à¤¦à¥\87à¤\96à¥\82",
-       "imagepage": "पनà¥\8dनाà¤\95 à¤ªà¥\83षà¥\8dठ à¤¦à¥\87à¤\96à¥\82",
-       "mediawikipage": "सनà¥\8dदà¥\87श à¤ªà¤¨à¥\8dना à¤¦à¥\87à¤\96à¥\82",
-       "templatepage": "नमà¥\82ना à¤ªà¥\83षà¥\8dठ à¤¦à¥\87à¤\96à¥\82",
-       "viewhelppage": "सहायता à¤ªà¤¨à¥\8dना à¤¦à¥\87à¤\96à¥\82",
-       "categorypage": "सà¤\82वरà¥\8dà¤\97 à¤ªà¤¨à¥\8dना à¤¦à¥\87à¤\96à¥\82",
-       "viewtalkpage": "à¤\97पशप à¤¦à¥\87à¤\96à¥\82",
-       "otherlanguages": "दà¥\8bसर à¤­à¤¾à¤·à¤¾मे",
-       "redirectedfrom": "(एतयसँ बहटारल $1)",
-       "redirectpagesub": "पनà¥\8dनाà¤\95à¥\87à¤\81 à¤ªà¤ à¤¾à¤\89",
-       "redirectto": "मà¥\87 à¤ªà¥\81नरà¥\8dनिरà¥\8dदà¥\87श:",
-       "lastmodifiedat": "à¤\88 à¤ªà¤¨à¥\8dना à¤\85नà¥\8dतिम à¤¬à¥\87र à¤¸à¤\82वरà¥\8dधित à¤­à¥\87ल $1, à¤\95à¥\87à¤\81  $2 à¤¬à¤\9cà¥\87।",
-       "viewcount": "à¤\88 à¤ªà¤¨à¥\8dना à¤¦à¥\87à¤\96ल à¤\97à¥\87ल {{PLURAL:$1|à¤\8fà¤\95 à¤¬à¥\87र|$1 à¤\8fतà¥\87à¤\95 à¤¬à¥\87र}}",
-       "protectedpage": "सà¤\82रà¤\95à¥\8dषित à¤ªà¤¨à¥\8dना",
-       "jumpto": "à¤\9cाà¤\8a:",
-       "jumptonavigation": "हà¥\87लà¥\82",
-       "jumptosearch": "ताà¤\95à¥\80",
-       "view-pool-error": "दà¥\81à¤\96à¥\80 à¤\9bà¥\80, à¤µà¤¿à¤¤à¤°à¤\95 à¤¸à¤­ à¤\8fà¤\96न à¤µà¥\8dयसà¥\8dत à¤\85à¤\9bि।\nबडà¥\8dड à¤¬à¥\87शà¥\80 à¤²à¥\8bà¤\95 à¤\90 à¤ªà¤¨à¥\8dनाà¤\95à¥\87à¤\81 à¤¦à¥\87à¤\96बामà¥\87 à¤²à¤¾à¤\97ल à¤\9bथि।\nà¤\90 à¤ªà¤¨à¥\8dनाà¤\95à¥\87à¤\81 फेरसँ देखबा लेल कनी बिलमू। \n$1",
-       "generic-pool-error": "दà¥\81à¤\96à¥\80 à¤\9bà¥\80, à¤µà¤¿à¤¤à¤°à¤\95 à¤¸à¤­ à¤\8fà¤\96न à¤µà¥\8dयसà¥\8dत à¤\85à¤\9bि।\nबडà¥\8dड à¤¬à¥\87शà¥\80 à¤²à¥\8bà¤\95 à¤\90 à¤ªà¤¨à¥\8dनाà¤\95à¥\87à¤\81 à¤¦à¥\87à¤\96बामà¥\87 à¤²à¤¾à¤\97ल à¤\9bथि।\nà¤\90 à¤ªà¤¨à¥\8dनाà¤\95à¥\87à¤\81 à¤«à¥\87रसà¤\81 à¤¦à¥\87à¤\96बा à¤²à¥\87ल à¤\95नà¥\80 à¤¬à¤¿à¤²à¤®à¥\82। \n$1",
+       "views": "दरà¥\8dशाव",
+       "toolbox": "उपकरण",
+       "userpage": "पà¥\8dरयà¥\8bà¤\95à¥\8dता à¤ªà¤¨à¥\8dना à¤¦à¥\87à¤\96à¥\80",
+       "projectpage": "परियà¥\8bà¤\9cना à¤ªà¤¨à¥\8dना à¤¦à¥\87à¤\96à¥\80",
+       "imagepage": "फाà¤\87ल à¤ªà¥\83षà¥\8dठ à¤¦à¥\87à¤\96à¥\80",
+       "mediawikipage": "सनà¥\8dदà¥\87श à¤ªà¤¨à¥\8dना à¤¦à¥\87à¤\96à¥\80",
+       "templatepage": "नमà¥\82ना à¤ªà¥\83षà¥\8dठ à¤¦à¥\87à¤\96à¥\80",
+       "viewhelppage": "सहायता à¤ªà¤¨à¥\8dना à¤¦à¥\87à¤\96à¥\80",
+       "categorypage": "शà¥\8dरà¥\87णà¥\80 à¤ªà¤¨à¥\8dना à¤¦à¥\87à¤\96à¥\80",
+       "viewtalkpage": "à¤\97पशप à¤¦à¥\87à¤\96à¥\80",
+       "otherlanguages": "à¤\85नà¥\8dय à¤­à¤¾à¤·à¤¾à¤¸à¤­मे",
+       "redirectedfrom": "($1 सँ पुनर्निर्देशित)",
+       "redirectpagesub": "पà¥\83षà¥\8dठ à¤ªà¥\81नरà¥\8dनिरà¥\8dदà¥\87शित à¤\95रà¥\80",
+       "redirectto": "à¤\95 à¤\85नà¥\81पà¥\8dरà¥\87षित:",
+       "lastmodifiedat": "à¤\88 à¤ªà¥\83षà¥\8dठà¤\95 à¤ªà¤¹à¤¿à¤¨à¥\81à¤\95ा à¤¬à¤¦à¤²à¤¾à¤µ $1 à¤\95à¥\87 $2 à¤¬à¤\9cà¥\87 à¤­à¤\8fल à¤\9bल।",
+       "viewcount": "à¤\88 à¤ªà¥\83षà¥\8dठ {{PLURAL:$1|à¤\8fà¤\95|$1}} à¤¬à¥\87र à¤¦à¥\87à¤\96ल à¤\97à¥\87ल à¤\9bल।",
+       "protectedpage": "सà¥\81रà¤\95à¥\8dषित à¤ªà¥\83षà¥\8dठ",
+       "jumpto": "à¤\8fतय à¤\9cाà¤\8f:",
+       "jumptonavigation": "भà¥\8dरमण",
+       "jumptosearch": "à¤\96à¥\8bà¤\9c",
+       "view-pool-error": "à¤\95à¥\8dषमा à¤\95रà¥\80, à¤µà¤¿à¤¤à¤°à¤\95सभ à¤\8fà¤\96न à¤µà¥\8dयसà¥\8dत à¤\85à¤\9bि।\nबडà¥\8dड à¤¬à¥\87शà¥\80 à¤²à¥\8bà¤\95 à¤\88 à¤ªà¤¨à¥\8dनाà¤\95 à¤¦à¥\87à¤\96बामà¥\87 à¤²à¤¾à¤\97ल à¤\9bथि।\nà¤\88 à¤ªà¤¨à¥\8dनाà¤\95 फेरसँ देखबा लेल कनी बिलमू। \n$1",
+       "generic-pool-error": "à¤\95à¥\8dषमा à¤\95रà¥\80, à¤µà¤¿à¤¤à¤°à¤\95सभ à¤\8fà¤\96न à¤µà¥\8dयसà¥\8dत à¤\85à¤\9bि।\nबडà¥\8dड à¤¬à¥\87शà¥\80 à¤²à¥\8bà¤\95 à¤\88 à¤ªà¤¨à¥\8dनाà¤\95 à¤¦à¥\87à¤\96बामà¥\87 à¤²à¤¾à¤\97ल à¤\9bथि।\nà¤\88 à¤ªà¤¨à¥\8dनाà¤\95 à¤«à¥\87रसà¤\81 à¤¦à¥\87à¤\96बा à¤²à¥\87ल à¤\95नà¥\80 à¤¬à¤¿à¤²à¤®à¥\82।",
        "pool-timeout": "प्रतीक्षा निगृहीत कालावसान",
        "pool-queuefull": "प्रतीक्षा-पाँती पौती भरल",
        "pool-errorunknown": "अज्ञात भ्रम",
-       "pool-servererror": "पà¥\82ल à¤\95ाà¤\89à¤\82टर सेवा उपलब्ध नै अछि ($1)।",
+       "pool-servererror": "पà¥\81ल à¤\95ाà¤\89नà¥\8dटर सेवा उपलब्ध नै अछि ($1)।",
        "poolcounter-usage-error": "उपयोग त्रुटि: $1",
        "aboutsite": "विषयमे {{SITENAME}}",
        "aboutpage": "Project:विवरण",
-       "copyright": "$1à¤\95 à¤\85à¤\82तर्गत विषय सूची उपलब्ध अछि",
+       "copyright": "$1à¤\95 à¤\85नà¥\8dतर्गत विषय सूची उपलब्ध अछि",
        "copyrightpage": "{{ns:project}}:सर्वाधिकार",
        "currentevents": "आइ-काल्हिक घटनासभ",
        "currentevents-url": "Project:आइ-काल्हिक घटनासभ",
        "disclaimers": "अनाधिकार घोषणा",
        "disclaimerpage": "Project:अनाधिकार घोषणा",
-       "edithelp": "सà¤\82पादन सहयोग",
+       "edithelp": "समà¥\8dपादन सहयोग",
        "helppage-top-gethelp": "मदति",
        "mainpage": "सम्मुख पन्ना",
        "mainpage-description": "सम्मुख पृष्ठ",
        "privacy": "गोपनीयताक नियम",
        "privacypage": "Project:गोपनीयता नियम",
        "badaccess": "आज्ञा गल्ती",
-       "badaccess-group0": "अहाँकेँ आग्रह कएल क्रियाकेँ करबाक अनुमति नै अछि।",
-       "badaccess-groups": "à¤\9cà¤\87 à¤\95à¥\8dरियाà¤\95 à¤\85हाà¤\81 à¤\86à¤\97à¥\8dरह à¤\95à¥\87नà¥\87 à¤\9bà¥\80 à¤¸à¥\87 à¤®à¤¾à¤¤à¥\8dर à¤\95िà¤\9bà¥\81 à¤ªà¥\8dरयà¥\8bà¤\95à¥\8dता à¤²à¥\87ल à¤¸à¥\81रà¤\95à¥\8dषित à¤\85à¤\9bि {{PLURAL:$2|सà¤\82वरà¥\8dà¤\97|सà¤\82वरà¥\8dà¤\97 à¤¸à¤­à¤®à¥\87 à¤\8fà¤\95à¤\9fा}}: $1",
-       "versionrequired": "मिडियाविà¤\95à¥\80à¤\95ऽ संस्करण $1 चाही",
-       "versionrequiredtext": "à¤\90 à¤ªà¤¨à¥\8dनाà¤\95 à¤ªà¥\8dरयà¥\8bà¤\97 à¤²à¥\87ल à¤®à¤¿à¤¡à¤¿à¤¯à¤¾à¤µà¤¿à¤\95à¥\80à¤\95ऽ à¤¸à¤\82सà¥\8dà¤\95रण $1 à¤\9aाहà¥\80।\nदà¥\87à¤\96à¥\82 [[Special:Version|पà¥\83षà¥\8dठ à¤­à¤°à¥\8dसन]]",
+       "badaccess-group0": "अहाँक आग्रह कएल क्रियाक करबाक अनुमति नै अछि।",
+       "badaccess-groups": "à¤\85हाà¤\81 à¤\9cà¥\87 à¤\95à¥\8dरिया à¤\86à¤\9cमà¥\87नà¥\87 à¤\9bà¥\80 à¤\93 à¤®à¤¾à¤¤à¥\8dर {{PLURAL:$2|$1 à¤¸à¤®à¥\82ह|$1 à¤¸à¤®à¥\82हसभ}}à¤\95 à¤¸à¤¦à¤¸à¥\8dय à¤¹à¥\80 à¤\95रि à¤¸à¤\95à¤\8fत à¤\85à¤\9bि।",
+       "versionrequired": "मिडियाविà¤\95िà¤\95 संस्करण $1 चाही",
+       "versionrequiredtext": "à¤\88 à¤ªà¥\83षà¥\8dठ à¤ªà¥\8dरयà¥\8bà¤\97 à¤\95रà¥\88à¤\95 à¤²à¥\87ल à¤®à¤¿à¤¡à¤¿à¤¯à¤¾à¤µà¤¿à¤\95िà¤\95 $1 à¤\85वतरण à¤\9cरà¥\81रà¥\80 à¤\85à¤\9bि।\nदà¥\87à¤\96à¥\80 [[Special:Version|à¤\85वतरण à¤ªà¥\83षà¥\8dठ]]।",
        "ok": "ठीक अछि",
        "pagetitle-view-mainpage": "{{अन्तर्जाल}}",
        "backlinksubtitle": "← $1",
        "retrievedfrom": "प्राप्ति स्थल \"$1\"",
-       "youhavenewmessages": "अहाँ लग अछि $1 ($2).",
+       "youhavenewmessages": "{{PLURAL:$3|अहाँक लेल}} $1 ($2) अछि।",
        "youhavenewmessagesfromusers": "{{PLURAL:$4|अहाँके लेल}} $1 सँ {{PLURAL:$3|अन्य प्रयोक्ता|$3 प्रयोक्तासभ}} ($2)।",
        "youhavenewmessagesmanyusers": "अहाँके $1 सँ बहुत प्रयोक्ता सभ ($2)।",
        "newmessageslinkplural": "{{PLURAL:$1|एगो नयाँ पत्र|999=नयाँ पत्र}}",
        "newmessagesdifflinkplural": "अन्तिम {{PLURAL:$1|परिवर्त्तन|999=परिवर्त्तन सभ}}",
        "youhavenewmessagesmulti": "$1 पर अहाँ लेल नव पत्र अछि",
        "editsection": "सम्पादन करी",
-       "editold": "समà¥\8dपादित à¤\95रà¥\82",
-       "viewsourceold": "à¤\9cड़ि à¤¦à¥\87à¤\96à¥\82",
-       "editlink": "समà¥\8dपादन à¤\95रà¥\82",
-       "viewsourcelink": "à¤\9cडà¥\80 देखी",
+       "editold": "समà¥\8dपादित à¤\95रà¥\80",
+       "viewsourceold": "सà¥\8dरà¥\8bत à¤¦à¥\87à¤\96à¥\80",
+       "editlink": "समà¥\8dपादन à¤\95रà¥\80",
+       "viewsourcelink": "सà¥\8dरà¥\8bत देखी",
        "editsectionhint": "सम्पादन शाखा: $1",
        "toc": "विषय सूचीसभ",
-       "showtoc": "दà¥\87à¤\96ाà¤\8a",
-       "hidetoc": "नà¥\81à¤\95ाà¤\8a",
-       "collapsible-collapse": "भà¤\96ड़ाà¤\89",
-       "collapsible-expand": "बढ़ाà¤\89",
-       "confirmable-confirm": "कि {{GENDER:$1|अहाँ}} छी?",
+       "showtoc": "दà¥\87à¤\96ाबà¥\80",
+       "hidetoc": "नà¥\81à¤\95ाबà¥\80",
+       "collapsible-collapse": "भà¤\96डाबà¥\80",
+       "collapsible-expand": "विसà¥\8dतार à¤\95रà¥\80",
+       "confirmable-confirm": "à¤\95ि {{GENDER:$1|à¤\85हाà¤\81}} à¤¨à¤¿à¤¶à¥\8dà¤\9aित à¤\9bà¥\80?",
        "confirmable-yes": "हँ",
        "confirmable-no": "नै",
-       "thisisdeleted": "$1 à¤¦à¥\87à¤\96à¥\82 à¤µà¤¾ à¤«à¥\87र à¤¸à¤\81 à¤\86नà¥\81?",
-       "viewdeleted": "$1 à¤\95à¥\87 à¤¦à¥\87à¤\96ाà¤\8a?",
+       "thisisdeleted": "$1 à¤¦à¥\87à¤\96à¥\80 à¤µà¤¾ à¤«à¥\87रसà¤\81 à¤\86नà¥\80?",
+       "viewdeleted": "$1 à¤\95à¥\87 à¤¦à¥\87à¤\96ाबà¥\80?",
        "restorelink": "{{PLURAL:$1|एकटा मेटाएल सम्पादन|$1 मेटाएल सम्पादन सभ}}",
        "feedlinks": "सूचक:",
        "feed-invalid": "अमान्य सूचक प्रकार मासुल",
        "feed-atom": "अणु",
        "feed-rss": "आर.एस.एस.",
        "red-link-title": "$1 (पृष्ठ उपलब्ध नै अछि)",
-       "sort-descending": "à¤\98à¤\9fà¥\88त à¤\95à¥\8dरममà¥\87 à¤\9bाà¤\81à¤\9fà¥\82",
-       "sort-ascending": "बढ़à¥\88त à¤\95à¥\8dरममà¥\87 à¤\9bाà¤\81à¤\9fà¥\82",
+       "sort-descending": "à¤\98à¤\9fà¥\88त à¤\95à¥\8dरममà¥\87 à¤\9bाà¤\81à¤\9fà¥\80",
+       "sort-ascending": "बढà¥\88त à¤\95à¥\8dरममà¥\87 à¤\9bाà¤\81à¤\9fà¥\80",
        "nstab-main": "पन्ना",
        "nstab-user": "प्रयोक्ता पृष्ठ",
        "nstab-media": "मिडिया पृष्ठ",
        "nstab-mediawiki": "पत्र",
        "nstab-template": "आकृति",
        "nstab-help": "सहायता पृष्ठ",
-       "nstab-category": "सà¤\82वरà¥\8dà¤\97",
+       "nstab-category": "शà¥\8dरà¥\87णà¥\80",
        "mainpage-nstab": "सम्मुख पन्ना",
        "nosuchaction": "एहेन कोनो क्रिया नै अछि",
        "nosuchactiontext": "ऐ सार्वत्रिक विभव संकेत द्वारा निर्दिष्ट क्रिया अमान्य अछि।\nअहाँ सार्वत्रिक विभव संकेतक गलत टंकण केने हएब, वा कोनो गलत लिंकक पाछाँ गेल हएब।\nई {{अन्तर्जाल}} प्रयोक्ता द्वारा प्रयुक्त तंत्रांशमे स्थित कोनो दोषक संकेत सेहो कऽ सकैए।",
        "laggedslavemode": "'''चेतौनी:''' पन्नापर सम्भव जे अद्यतन परिवर्तन नै हुअए।",
        "readonly": "दत्तनिधि प्रतिबन्धित",
        "enterlockreason": "प्रतिबन्ध लेल कारण बताउ, संगमे एकटा अंदाज सेहो बताउ जे कखन ई प्रतिबन्ध हटाएल जाएत।",
-       "readonlytext": "à¤\85à¤\96न à¤¦à¤¤à¥\8dताà¤\82शनिधि à¤¨à¤µ à¤ªà¥\8dरविषà¥\8dà¤\9fि à¤\86 à¤\86न à¤¸à¤\82शà¥\8bधन à¤²à¥\87ल à¤ªà¥\8dरतिबनà¥\8dधित à¤\85à¤\9bि, à¤¸à¤®à¥\8dभवतà¤\83 à¤¸à¤¾à¤®à¤¾à¤¨à¥\8dत à¤¦à¤¤à¥\8dताà¤\82शनिधि à¤¦à¥\87à¤\96भाल à¤²à¥\87ल, à¤¤à¤\95र à¤¬à¤¾à¤¦ à¤\88 à¤¸à¤¾à¤®à¤¾à¤¨à¥\8dय à¤­à¤½ à¤\9cाà¤\8fत।\n\nसà¤\82चालक जे एकरा प्रतिबन्धित कएने छथि ई कारण दै छथि:$1",
+       "readonlytext": "à¤\85à¤\96न à¤¦à¤¤à¥\8dताà¤\82शनिधि à¤¨à¤µ à¤ªà¥\8dरविषà¥\8dà¤\9fि à¤\86 à¤\86न à¤¸à¤\82शà¥\8bधन à¤²à¥\87ल à¤ªà¥\8dरतिबनà¥\8dधित à¤\85à¤\9bि, à¤¸à¤®à¥\8dभवतà¤\83 à¤¸à¤¾à¤®à¤¾à¤¨à¥\8dत à¤¦à¤¤à¥\8dताà¤\82शनिधि à¤¦à¥\87à¤\96भाल à¤²à¥\87ल, à¤¤à¤\95र à¤¬à¤¾à¤¦ à¤\88 à¤¸à¤¾à¤®à¤¾à¤¨à¥\8dय à¤­à¤½ à¤\9cाà¤\8fत।\n\nसà¤\9eà¥\8dचालक जे एकरा प्रतिबन्धित कएने छथि ई कारण दै छथि:$1",
        "missing-article": "दत्तनिधि पृष्ठक वांछित पाठ्य नै ताकि सकल, माने \"$1\" $2\nएकर कारण कोनो पुरान फाइल चेन्हासी वा ऐतिहासिक लिंकक पाछाँ जाएब अछि, जे मेटा देल गेल छै।\nजौं ई तकर कारण नै अछि,  तखन अहाँकेँ तंत्रांशमे कोनो दोष भेटल अछि।\nएकर खबरि पहुँचाउ [[Special:ListUsers/sysop|administrator]], केँ, अपन सार्वत्रिक विभव संकेत सूचित करैत।",
        "missingarticle-rev": "(संशोधन#: $1)",
        "missingarticle-diff": "(फाइल-अन्तर प्रणाली: $1, $2)",
        "readonly_lag": "दत्तांशनिधि स्वचालित रूपेँ प्रतिबन्धित कएल गेल अछि जा परजीवी दतांशनिधि वितरक मूलक समक्ष नै आबि जाए।",
+       "nonwrite-api-promise-error": "'Promise-Non-Write-API-Action'क एचटिटिपी शीर्षकद्वारा भेजल गएल पर एपिआईमे लेखन मोड्युल अछि।",
        "internalerror": "आन्तरिक भ्रम",
        "internalerror_info": "आन्तरिक भ्रम: $1",
        "internalerror-fatal-exception": "प्रकारक गम्भीर अपवाद \"$1\"",
        "directorynotreadableerror": "निर्देशिका \"$1\" पठनीय नै अछि।",
        "filenotfound": "फाइल \"$1\" नै ताकि सकल।",
        "unexpected": "आसक विपरीत परिणाम: \"$1\"=\"$2\"",
-       "formerror": "फà¥\89रà¥\8dम à¤¨à¥\88 à¤ªà¤ ा सकल",
+       "formerror": "तà¥\8dरà¥\81à¤\9fि: à¤«à¤°à¥\8dम à¤\85नà¥\81रà¥\8bध à¤¨à¥\88 à¤\95à¤\8fल à¤\9cा सकल",
        "badarticleerror": "ई क्रिया ऐ पन्नापर नै कएल जा सकैए।",
        "cannotdelete": "पन्ना व संचिका \"$1\" मेटाएल नै जा सकल।",
        "cannotdelete-title": "पन्ना \"$1\" नै मेटा सकल",
        "perfcached": "ई दत्तांश उपस्मृतिक आधारपर अछि आ भऽ सकैए जे अद्यतन नै हुअए। अधिकतम {{PLURAL:$1|एकटा परिणाम|$1 परिणाम सभ}} क्याचेमे उपलब्ध अछि ।",
        "perfcachedts": "ई दत्तांश उपस्मृतिमे अछि, आ एकर अन्तिम परिवर्धन भेल अछि $1 केँ। A maximum of {{PLURAL:$4|one result is|$4 results are}} available in the cache.",
        "querypage-no-updates": "ऐ पन्नाक नवीनीकरण अखन बन्न अछि।\nएतुक्का दत्तांश अखन नवीकरण नै कएल जाएत।",
-       "viewsource": "à¤\9cड़ि à¤¦à¥\87à¤\96à¥\82",
-       "viewsource-title": "\"$1\" à¤²à¥\87ल à¤\9cड़ि à¤¦à¥\87à¤\96à¥\82",
-       "actionthrottled": "à¤\95à¥\8dरियाà¤\95à¥\87à¤\81 à¤®à¥\8bà¤\95ल à¤\97à¥\87ल",
-       "actionthrottledtext": "à¤\85नपà¥\87à¤\95à¥\8dषित à¤¸à¤\82दà¥\87श à¤°à¥\8bà¤\95ा à¤²à¥\87ल, à¤\85हाà¤\81à¤\95à¥\87à¤\81 à¤\90 à¤\95à¥\8dरियाà¤\95à¥\87à¤\81 à¤\95मà¥\8dमà¥\87 à¤\95ालमà¥\87 à¤¸à¥\80मासà¤\81 à¤¬à¥\87शà¥\80 à¤¬à¥\87र à¤\95रबासà¤\81 à¤°à¥\8bà¤\95ल à¤\97à¥\87ल à¤\85à¤\9bि, à¤\85हाà¤\81 à¤\93à¤\87 à¤¸à¥\80माà¤\95à¥\87à¤\81 à¤ªà¤¾à¤° à¤\95ऽ à¤\97à¥\87ल à¤\9bà¥\80।\nà¤\95à¥\83पया à¤\95िà¤\9bà¥\81 à¤\95ाल à¤¬à¤¾à¤¦ à¤«à¥\87रसà¤\81 à¤ªà¥\8dरयास à¤\95रà¥\82।",
+       "viewsource": "सà¥\8dरà¥\8bत à¤¦à¥\87à¤\96à¥\80",
+       "viewsource-title": "\"$1\" à¤²à¥\87ल à¤¸à¥\8dरà¥\8bत à¤¦à¥\87à¤\96à¥\80",
+       "actionthrottled": "à¤\95ारà¥\8dय à¤¸à¤®à¤¾à¤ªà¥\8dत à¤\95रि à¤¦à¥\87ल à¤\97à¤\8fल",
+       "actionthrottledtext": "à¤\85नपà¥\87à¤\95à¥\8dषित à¤¸à¤¨à¥\8dदà¥\87श à¤°à¥\8bà¤\95 à¤²à¥\87ल, à¤\85हाà¤\81à¤\95 à¤\88 à¤\95à¥\8dरियाà¤\95 à¤\95मà¥\8dमà¥\87 à¤\95ालमà¥\87 à¤¸à¥\80मासà¤\81 à¤¬à¥\87सà¥\80बà¥\87र à¤\95रबासà¤\81 à¤°à¥\8bà¤\95ल à¤\97à¥\87ल à¤\85à¤\9bि, à¤\85हाà¤\81 à¤\93 à¤¸à¥\80माà¤\95 à¤ªà¤¾à¤° à¤\95ऽ à¤\97à¥\87ल à¤\9bà¥\80।\nà¤\95à¥\83पया à¤\95िà¤\9b à¤\95ाल à¤¬à¤¾à¤¦ à¤«à¥\87रसà¤\81 à¤ªà¥\8dरयास à¤\95रà¥\80।",
        "protectedpagetext": "ई पन्ना सम्पादन रोकबा लेल संरक्षित अछि।",
-       "viewsourcetext": "à¤\85हाà¤\81 à¤\90 à¤ªà¤¨à¥\8dनाà¤\95 à¤\9cड़िà¤\95à¥\87à¤\81 देख आ अनुकृत कऽ सकै छी:",
-       "viewyourtext": "अहाँ '''अहाँक सम्पादन''' केँ देख आ एतए उतारि सकै छी:",
+       "viewsourcetext": "à¤\85हाà¤\81 à¤\87 à¤ªà¥\83षà¥\8dठà¤\95 à¤\9cडिà¤\95 देख आ अनुकृत कऽ सकै छी:",
+       "viewyourtext": "अहाँ ई पृष्ठमे '''अपन सम्पादन'''क देख आ एतए उतारि सकै छी:",
        "protectedinterface": "ई पन्ना तंत्रांश लेल मध्यस्थ पाठक व्यवस्था करैत अछि, आ अपशब्द रोकबाक ब्योंत करैत अछि।",
        "editinginterface": "'''चेतौनी''' अहाँ एकटा एहेन पन्नाक सम्पादन कऽ रहल छी जे तंत्रांशक मध्यस्थ पन्नाकेँ पाठ देबा लेल प्रयोग भऽ रहल अछि।\nऐ पन्नामे परिवर्तन दोसर प्रयोक्ता लेल प्रयोक्ता मध्यस्थक रूपमे परिवर्तन करत।\nअनुवाद लेल [//translatewiki.net/wiki/Main_Page?setlang=en translatewiki.net] जाउ, मीडियाविकी स्थानीयकरण परियोजना पर।",
        "translateinterface": "सभ विकिसब के लेल अनुवाद जोडइ या बदलई के लेल मीडियाविकि क्षेत्रीयकरण परियोजना [//translatewiki.net/ translatewiki.net] कें प्रयोग करु।",
-       "cascadeprotected": "à¤\90 à¤ªà¤¨à¥\8dनाà¤\95 à¤¸à¤®à¥\8dपादन à¤¸à¤®à¥\8dभव à¤¨à¥\88 à¤\85à¤\9bि, à¤\95ारण à¤\88 à¤\90 à¤®à¥\87 à¤¸à¤®à¥\8dमिलित à¤\85à¤\9bि, {{PLURAL:$1|पनà¥\8dना, à¤\9cà¥\87 à¤\85à¤\9bि|पनà¥\8dना, à¤¸à¥\87 à¤¸à¤­ à¤\85à¤\9bि}} à¤¸à¥\81रà¤\95à¥\8dषित à¤\85à¤\9bि \"तराà¤\89पड़ी\" विकल्प खोललाक बाद:\n$2",
+       "cascadeprotected": "à¤\88 à¤ªà¤¨à¥\8dनाà¤\95 à¤¸à¤®à¥\8dपादन à¤¸à¤®à¥\8dभव à¤¨à¥\88 à¤\85à¤\9bि, à¤\95ारण à¤\85हिमà¥\87 à¤¸à¤®à¥\8dमिलित à¤\85à¤\9bि, {{PLURAL:$1|पà¥\83षà¥\8dठ|पà¥\83षà¥\8dठसभ}} à¤¸à¥\81रà¤\95à¥\8dषित à¤\85à¤\9bि \"तराà¤\89पडी\" विकल्प खोललाक बाद:\n$2",
        "namespaceprotected": "अहाँकेँ '''$1''' नाम-पेटारमे सम्पादनक अनुमति नै अछि।",
        "customcssprotected": "अहांकें ऐ सी.एस.एस.पन्नाकें सम्पादित करबाक अधिकार नै अछि, कारण ऐमे दोसर प्रयोक्ताक व्यक्तिगत विकल्प छै।",
        "customjsprotected": "अहांकें ऐ जावास्क्रिप्ट पन्नाकें सम्पादित करबाक अधिकार नै अछि, कारण ऐमे दोसर प्रयोक्ताक व्यक्तिगत विकल्प छै।",
        "mypreferencesprotected": "अहाके अपन प्राथमिकता बदलैक अनुमति नै अछि।",
        "ns-specialprotected": "विशेष पन्ना सभकेँ सम्पादित नै कएल जा सकैए।",
        "titleprotected": "ऐ शीर्षकक निर्माण प्रतिबन्धित अछि [[User:$1|$1]] द्वारा।\nकारण एतऽ देल अछि <em>$2</em>।",
-       "filereadonlyerror": "\"$1\" फाइलके बदलैलेल अक्षम कियाक भण्डार \"$2\" इ समय 'मात्र पाठन के लेल' (रीड ओनली) अछि।\n\nजे प्रबंधक इ प्रबंध लगोनै अछि हुनका निम्न विवरण प्रदान कएल गेल अछि: \"$3\"।",
+       "filereadonlyerror": "\"$1\" फाइलके बदलैलेल अक्षम कियाक भण्डार \"$2\" इ समय 'मात्र पाठनक लेल' अछि।\n\nजे प्रबन्धक ई प्रबन्ध लगोनै अछि ओ निम्न विवरण प्रदान कएने अछि: \"$3\"।",
        "invalidtitle-knownnamespace": "\"$2\" नामस्थान आर \"$3\" नाम बला गलत शीर्षक",
        "invalidtitle-unknownnamespace": "अज्ञात नामस्थान संख्या $1 आर नाम \"$2\" वाला गलत शीर्षक",
        "exception-nologin": "सम्प्रवेशित नै",
        "virus-scanfailed": "बिम्ब विफल (विध्यादेश $1)",
        "virus-unknownscanner": "अज्ञात विषविधि निरोधक",
        "logouttext": "'''अहाँ निष्क्रमण कऽ गेल छी।'''\n\nअहाँ {{अन्तर्जाल}} प्रयोग अनाम भऽ कऽ सकै छी, वा अहाँ <span class='plainlinks'>[$1 log in again]</span> वएह आकि कोनो आन प्रयोक्ताक रूपमे सेहू प्रयोक कऽ सकै छी।\nई मोन राखू जे किछु पन्ना एना देखा पड़ि सकैए जेना अहाँ अखनो सम्प्रवेशित होइ, जावत अहाँ अपन गवेषकक उपस्मृति मेटा नै दै छी।",
+       "cannotlogoutnow-title": "अखन प्रस्थान नै भऽ रहल अछि",
+       "cannotlogoutnow-text": "$1 क उपयोग समय प्रस्थान नै कएल जा सकएत अछि।",
        "welcomeuser": "अहाके स्वागत अछि, $1!",
        "welcomecreation-msg": "अहाँक खाता बनाएल गेल अछि।\nअपन [[Special:Preferences|{{SITENAME}} पसन्द]] बदलै लेल नै बिसरब।",
        "yourname": "प्रयोक्ता:",
        "userlogin-yourname": "प्रयोक्ता:",
-       "userlogin-yourname-ph": "à¤\85पन à¤ªà¥\8dरयà¥\8bà¤\95à¥\8dतानाम à¤²à¤¿à¤\96à¥\81",
-       "createacct-another-username-ph": "à¤\8fà¤\95à¤\9fा à¤ªà¥\8dरयà¥\8bà¤\95à¥\8dतानाम à¤²à¤¿à¤\96à¥\82:",
+       "userlogin-yourname-ph": "à¤\85पन à¤ªà¥\8dरयà¥\8bà¤\97à¤\95रà¥\8dतानाम à¤²à¤¿à¤\96à¥\80",
+       "createacct-another-username-ph": "पà¥\8dरयà¥\8bà¤\97à¤\95रà¥\8dतानाम à¤ªà¥\8dरदान à¤\95रà¥\80",
        "yourpassword": "कूटशब्द:",
-       "userlogin-yourpassword": "कूटशब्द:",
-       "userlogin-yourpassword-ph": "अपन कूटशब्द लिखु",
-       "createacct-yourpassword-ph": "कूटशब्द ई ठाम राखु",
-       "yourpasswordagain": "कूटशब्द फेरसँ टाइप करू:",
-       "createacct-yourpasswordagain": "कूटशब्दके जाँच करु",
-       "createacct-yourpasswordagain-ph": "कूटशब्द पुनः लिखु",
-       "remembermypassword": "हमर सम्प्रवेश ऐ गवेषकपर मोन राखू (बेशीसँ बेशी $1 {{PLURAL:$1|दिन|दिन}})",
-       "userlogin-remembermypassword": "हमरा सम्प्रवेशित राखु",
-       "userlogin-signwithsecure": "सुरक्षित कनेक्शनके प्रयोग करु",
-       "yourdomainname": "अहाँक प्रभावक्षेत्र:",
-       "password-change-forbidden": "अहा इ विकिमे कूटशब्द नै बदल सकैत छि ।",
-       "externaldberror": "खाहे सत्यापन दतांश भ्रम छल वा अहाँ अपन बाह्य खाताकेँ अद्यतन करबामे असमर्थ छी।",
+       "userlogin-yourpassword": "कूटशब्द",
+       "userlogin-yourpassword-ph": "अपन कूटशब्द लिखी",
+       "createacct-yourpassword-ph": "कूटशब्द दर्ज करी",
+       "yourpasswordagain": "कूटशब्द फेरसँ टाइप करी:",
+       "createacct-yourpasswordagain": "कूटशब्दक जाँच करी",
+       "createacct-yourpasswordagain-ph": "कूटशब्द पुनः लिखी",
+       "remembermypassword": "ई ब्राउजर पर हमर सम्प्रवेश याद राखी (अधिकतम $1 {{PLURAL:$1|दिन|दिनधरि}}क लेल)",
+       "userlogin-remembermypassword": "हमरा सम्प्रवेशित राखी",
+       "userlogin-signwithsecure": "सुरक्षित कनेक्शनक प्रयोग करी",
+       "cannotloginnow-title": "अखन प्रवेश नै भऽ रहल अछि",
+       "cannotloginnow-text": "$1 क उपयोग समय प्रवेश नै कएल जा सकएत अछि।",
+       "yourdomainname": "अहाँक डोमेन (प्रभावक्षेत्र):",
+       "password-change-forbidden": "अहाँ ई विकिमे कूटशब्द नै बदल सकैत छी।",
+       "externaldberror": "या त प्रमाणिकरण डेटाबेसमे त्रुटि भएल अछि या फेर अहाँक अपन बाह्य खाता अपडेट करैक अनुमति नै अछि।",
        "login": "सम्प्रवेश",
-       "nav-login-createaccount": "सम्प्रवेश /खेसरा बनाऊ",
-       "userlogin": "समà¥\8dपà¥\8dरवà¥\87श/ à¤\96à¥\87सरा à¤¬à¤¨à¤¾à¤\8a",
+       "nav-login-createaccount": "सम्प्रवेश / खाता खोली",
+       "userlogin": "समà¥\8dपà¥\8dरवà¥\87श/ à¤\96ाता à¤¬à¤¨à¤¾à¤¬à¥\80",
        "userloginnocreate": "सम्प्रवेश",
        "logout": "निष्क्रमण",
        "userlogout": "फेर आयब",
        "notloggedin": "सम्प्रवेशित नै छी",
        "userlogin-noaccount": "खाता नै अछि?",
-       "userlogin-joinproject": "{{SITENAME}} से जोडु",
+       "userlogin-joinproject": "{{SITENAME}}सँ जुडी",
        "nologin": "खाता नै अछि? $1।",
-       "nologinlink": "नव à¤\96ाता à¤\96à¥\8bलà¥\82",
-       "createaccount": "à¤\96ाता à¤\96à¥\8bलà¥\82",
+       "nologinlink": "नव à¤\96ाता à¤\96à¥\8bलà¥\80",
+       "createaccount": "à¤\96ाता à¤\96à¥\8bलà¥\80",
        "gotaccount": "पहिनहियेसँ खाता अछि? $1",
        "gotaccountlink": "सम्प्रवेश",
-       "userlogin-resetlink": "à¤\85पन à¤¸à¤®à¥\8dपà¥\8dरवà¥\87श à¤µà¤¿à¤µà¤°à¤£ à¤¬à¤¿à¤¸à¤°à¤¿ à¤\97à¥\87लहà¥\81à¤\81?",
-       "userlogin-resetpassword-link": "अपन कूटशब्द बिसर गेलौ ?",
+       "userlogin-resetlink": "à¤\85पन à¤¸à¤®à¥\8dपà¥\8dरवà¥\87श à¤µà¤¿à¤µà¤°à¤£ à¤¬à¤¿à¤¸à¤°à¤¿ à¤\97à¥\87लà¥\8c?",
+       "userlogin-resetpassword-link": "अपन कूटशब्द बिसरि गेलौ?",
        "userlogin-helplink2": "सम्प्रवेशित करवाकलेल मदत",
-       "userlogin-loggedin": "अहा {{GENDER:$1|$1}} के रूपमे पहिले स सम्प्रवेशित छि।\nकोनो दोसर सदस्यके रुपमे सम्प्रवेशित करवाक लेल देल गेल फारमके प्रयोग करु।",
-       "userlogin-createanother": "दà¥\8bसर à¤\96ाता à¤¬à¤¨à¤¾à¤\89",
-       "createacct-emailrequired": "à¤\88-पतà¥\8dर à¤¸à¤\82à¤\95à¥\87त",
-       "createacct-emailoptional": "à¤\88-पतà¥\8dर à¤¸à¤\82à¤\95à¥\87त (वैकल्पिक)",
-       "createacct-email-ph": "à¤\85पन à¤\88-पतà¥\8dर à¤¸à¤\82à¤\95à¥\87त à¤¸à¤¤à¥\8dयापित à¤\95रà¥\82",
-       "createacct-another-email-ph": "ई-पत्र संकेत सत्यापित करू",
-       "createaccountmail": "à¤\88-पतà¥\8dर à¤¦à¥\8dवारा",
+       "userlogin-loggedin": "अहाँ {{GENDER:$1|$1}}क रूपमे पहिनेसँ सम्प्रवेशित छी।\nकोनो दोसर सदस्यक रुपमे सम्प्रवेशित करवाक लेल देल गेल फारमके प्रयोग करी।",
+       "userlogin-createanother": "दà¥\8bसर à¤\96ाता à¤¬à¤¨à¤¾à¤¬à¥\80",
+       "createacct-emailrequired": "à¤\88-मà¥\87ल à¤ªà¤¤à¤¾",
+       "createacct-emailoptional": "à¤\88-मà¥\87ल à¤ªà¤¤à¤¾ (वैकल्पिक)",
+       "createacct-email-ph": "à¤\85पन à¤\88-मà¥\87ल à¤ªà¤¤à¤¾ à¤²à¤¿à¤\96à¥\80",
+       "createacct-another-email-ph": "ईमेल पता प्रदान करी",
+       "createaccountmail": "à¤\8fà¤\95 à¤\85सà¥\8dथायà¥\80 à¤¯à¤¾à¤¦à¥\83à¤\9aà¥\8dà¤\9bिà¤\95 à¤\95à¥\82à¤\9fशबà¥\8dद à¤\9aà¥\81नà¥\80 à¤\86 à¤\93 à¤¨à¤¿à¤°à¥\8dदिषà¥\8dà¤\9f à¤\88-मà¥\87ल à¤ªà¤¤à¤¾ à¤ªà¤° à¤­à¥\87à¤\9cà¥\80",
        "createacct-realname": "असली नाम (वैकल्पिक)",
        "createaccountreason": "कारण:",
        "createacct-reason": "कारण:",
        "createacct-reason-ph": "अहा इगो आर दोसर खाता कियाक बनउने जा रहल छि",
        "createacct-submit": "अपन खाता बनाउ",
-       "createacct-another-submit": "दोसर खाता बनाउ",
-       "createacct-benefit-heading": "{{SITENAME}} अहि जोका लोकनिसभ द्वारा बनावल गेल अछि।",
-       "createacct-benefit-body1": "$1 {{PLURAL:$1|सम्पादन|सम्पादन सभ}}",
-       "createacct-benefit-body2": "{{PLURAL:$1|पन्ना}}",
-       "createacct-benefit-body3": "{{PLURAL:$1|योगदानकर्ता}}",
-       "badretype": "कूटशब्द जे अहाँ भरलहुँ से मेल नै खाइए।",
-       "userexists": "सम्प्रवेशित प्रयोक्तानाम पहिनहियेसँ प्रयोगमे अछि।\nकृपा कऽ कोनो दोसर नाम चुनू।",
-       "loginerror": "सम्प्रवेश भ्रम",
-       "createacct-error": "खाता निर्माण त्रुटि",
-       "createaccounterror": "खाता नै बना सकल: $1",
-       "nocookiesnew": "प्रयोक्ता खाता खुजि गेल, मुदा अहाँ सम्प्रवेशित नै छी।\n{{अन्तर्जाल}} सम्प्रवेशित प्रयोक्ताक लेल ज्ञापकक प्रयोग करैत अछि।\nअहाँ ज्ञापककेँ अशक्त केने छी।\nकृपा कऽ ओकरा सक्रिप करू, तखन अपन प्रयोक्तानाम आ कूटशब्दक संग सम्प्रवेश करू।",
-       "nocookieslogin": "{{अन्तर्जाल}} प्रयोक्ताकेँ सम्प्रवेशित करबा लेल ज्ञापकक प्रयोग करैत अछि।\nअहाँ ज्ञापककेँ अशक्त केने छी।\nकृपा कऽ ओकरा सक्रिय करू आ फेरसँ प्रयास करू।",
-       "nocookiesfornew": "प्रयोक्ता खाजा नै खुजल, कारण हम ओकर जड़ि पूर्ण रूपेँ नै ताकि सकलौं।\nई दृढ़ करू जे ज्ञापक सक्रिय अछि, ऐ पन्नाकेँ फेरसँ भारित करू आ फेरसँ प्रयास करू।",
+       "createacct-another-submit": "खाता बनाबी",
+       "createacct-benefit-heading": "{{SITENAME}} अहाँ जोका लोगसभद्वारा बनाएल गएल अछि।",
+       "createacct-benefit-body1": "$1 {{PLURAL:$1|सम्पादन|सम्पादनसभ}}",
+       "createacct-benefit-body2": "{{PLURAL:$1|पन्ना|पन्नासभ}}",
+       "createacct-benefit-body3": "सन्निकट {{PLURAL:$1|योगदानकर्ता|योगदानकर्तासभ}}",
+       "badretype": "कूटशब्द जे अहाँ देलौ से मेल नै खाइए।",
+       "usernameinprogress": "ई प्रयोक्ताक खाता निर्माण अखन चालू अछि।\nकृपया प्रतीक्षा करी।",
+       "userexists": "सम्प्रवेशित प्रयोक्तानाम पहिनहियेसँ प्रयोगमे अछि।\nकृपा कऽ कोनो दोसर नाम चुनी।",
+       "loginerror": "सम्प्रवेश त्रुटी",
+       "createacct-error": "खाता निर्माण त्रुटी",
+       "createaccounterror": "खाता नै बनि सकल: $1",
+       "nocookiesnew": "प्रयोक्ता खाता खुजि गेल, मुदा अहाँ सम्प्रवेशित नै छी।\n{{SITENAME}} सम्प्रवेशित प्रयोक्ताक लेल ज्ञापकक प्रयोग करैत अछि।\nअहाँ ज्ञापकक अशक्त केनए छी।\nकृपा कऽ ओकरा सक्रिय करी, तखन अपन प्रयोक्तानाम आ कूटशब्दक संग सम्प्रवेश करी।",
+       "nocookieslogin": "{{SITENAME}} प्रयोक्ताक सम्प्रवेशित करबा लेल ज्ञापकक प्रयोग करैत अछि।\nअहाँ ज्ञापकक अशक्त केने छी।\nकृपा कऽ ओकरा सक्रिय करी आ फेरसँ प्रयास करी।",
+       "nocookiesfornew": "प्रयोक्ता खाजा नै खुजल, कारण हम ओकर जडि पूर्ण रूपेँ नै ताकि सकलौ।\nई दृढ करी जे ज्ञापक सक्रिय अछि, ई पन्नाक फेरसँ भारित करी आ फेरसँ प्रयास करी।",
        "noname": "अहाँ वैध प्रयोक्तानाम नै देने छी।",
-       "loginsuccesstitle": "समà¥\8dपà¥\8dरवà¥\87श à¤¸à¤«ल",
+       "loginsuccesstitle": "समà¥\8dपà¥\8dरवà¥\87श à¤­à¤\8fल",
        "loginsuccess": "'''अहाँ सम्प्रवेश केलहुँ {{SITENAME}} \"$1\".'''क रूपमे।",
-       "nosuchuser": "\"$1\" à¤¨à¤¾à¤®à¤¸à¤\81 à¤\95à¥\8bनà¥\8b à¤ªà¥\8dरयà¥\8bà¤\95à¥\8dता à¤¨à¥\88 à¤\85à¤\9bि।\nपà¥\8dरयà¥\8bà¤\95à¥\8dतानाम à¤¬à¥\8dरहà¥\8dमà¤\95à¥\8dषर-लà¤\98à¥\8dवà¤\95à¥\8dषर à¤­à¥\87द à¤¯à¥\81à¤\95à¥\8dत à¤\85à¤\9bि।\nà¤\85पन à¤¹à¥\8dरिà¤\9cà¥\88 à¤\9cाà¤\81à¤\9aà¥\82, à¤µà¤¾ [[Special:UserLogin/signup|नव à¤\96ाता à¤¬à¤¨à¤¾à¤\89]] ।",
-       "nosuchusershort": "\"$1\" à¤¨à¤¾à¤®à¥\8dना à¤\95à¥\8bनà¥\8b à¤ªà¥\8dरयà¥\8bà¤\95à¥\8dता à¤¨à¥\88 à¤\85à¤\9bि।\nà¤\85पन à¤¹à¥\8dरिà¤\9cà¤\8f à¤¸à¥\81धारà¥\82।",
-       "nouserspecified": "अहाँकेँ एकटा प्रयोक्तानाम देबऽ पड़त।",
+       "nosuchuser": "\"$1\" à¤¨à¤¾à¤®à¤¸à¤\81 à¤\95à¥\8bनà¥\8b à¤ªà¥\8dरयà¥\8bà¤\95à¥\8dता à¤¨à¥\88 à¤\85à¤\9bि।\nपà¥\8dरयà¥\8bà¤\95à¥\8dतानाम à¤¬à¥\8dरहà¥\8dमà¤\95à¥\8dषर-लà¤\98à¥\8dवà¤\95à¥\8dषर à¤­à¥\87द à¤¯à¥\81à¤\95à¥\8dत à¤\85à¤\9bि।\nà¤\85पन à¤¹à¥\8dरिà¤\9cà¥\88 à¤\9cाà¤\81à¤\9aà¥\80, à¤µà¤¾ [[Special:UserLogin/signup|नव à¤\96ाता à¤¬à¤¨à¤¾à¤¬à¥\80]] ।",
+       "nosuchusershort": "\"$1\" à¤¨à¤¾à¤®à¥\8dना à¤\95à¥\8bनà¥\8b à¤ªà¥\8dरयà¥\8bà¤\95à¥\8dता à¤¨à¥\88 à¤\85à¤\9bि।\nà¤\85पन à¤¹à¤¿à¤\9cà¤\8f à¤¸à¥\81धारà¥\80।",
+       "nouserspecified": "अहाँक एकटा प्रयोक्तानाम देबऽ पडत।",
        "login-userblocked": "ई प्रयोक्ता प्रतिबन्धित अछि। सम्प्रवेशक अधिकार नै अछि।",
        "wrongpassword": "गलत कूटशब्द देल गेल।\nफेरसँ प्रयास करू।",
        "wrongpasswordempty": "रिक्त कूटशब्द देल गेल।\nफेरसँ प्रयास करू।",
        "passwordtooshort": "कूटशब्द कमसँ कम {{PLURAL:$1|1 वर्ण|$1 वर्णक}} हुअए।",
        "passwordtoolong": "कुटशब्द kuttsabda {{PLURAL:$1|1 वर्ण|$1 वर्णों}} से बेसी नम्हर भ्या सकएत अछि।",
+       "passwordtoopopular": "आम पासवर्ड अहाँ नै चुनि सकएत अछि। कृपया अनोखा पासवर्ड चुनी।",
        "password-name-match": "अहाँक कूटशब्द अहाँक प्रयोक्तानामसँ भिन्न हेबाक चाही।",
        "password-login-forbidden": "ऐ प्रयोक्तानाम आ कूटशब्दक प्रयोग प्रतिबन्धित अछि।",
        "mailmypassword": "नूतन कूटशब्द ई-पत्रसँ पठाउ",
        "emaildisabled": "ई अन्तर्जाल ई-पत्र नै पठाएत।",
        "accountcreated": "खाता खुजि गेल",
        "accountcreatedtext": "[[{{ns:User}}:$1|$1]] ([[{{ns:User talk}}:$1|वार्ता]]) के लेल खाता खोलल गेल अछि।",
-       "createaccount-title": "{{अन्तर्जाल}} लेल खाता निर्माण",
+       "createaccount-title": "{{SITENAME}}क लेल खाता बनाबी",
        "createaccount-text": "कियो अहाँक ई-पत्र संकेत लेल एकटा खाता {{अन्तर्जाल}} पर खोललन्हि ($4) नाम भेल \"$2\", कूटशब्द भेल \"$3\"।\nअहाँ सम्प्रवेश करू आ अपन कूटशब्द बदलू।\n\nअहाँ ऐ संदेशकेँ बिसरि सकै छी, जँ ई खाता भ्रमवश बनल हुअए।",
        "login-throttled": "अहाँ ढ़ेर रास सम्प्रवेश प्रयास केलहुँ।\nफेर प्रयास करबासँ पहिने कने काल थम्हू।",
-       "login-abort-generic": "à¤\85हाà¤\81à¤\95 à¤¸à¤®à¥\8dपà¥\8dरवà¥\87श à¤¸à¤«à¤² à¤¨à¥\88 à¤­à¥\87ल- à¤\96तम",
+       "login-abort-generic": "à¤\85हाà¤\81à¤\95 à¤¸à¤®à¥\8dपà¥\8dरवà¥\87श à¤¸à¤«à¤² à¤¨à¥\88 à¤­à¥\87ल- à¤°à¥\8bà¤\95ल à¤\97à¤\8fल",
        "login-migrated-generic": "अहाँके खाता माइग्रेट कएल गेल अछि, आर अहाँके प्रयोक्ता नाम आब ई विकिमे नै अछि।",
        "loginlanguagelabel": "भाषा : $1",
        "suspicious-userlogout": "अहाँक निष्क्रमणक अनुरोध नै मानल गेल कारण ई लागल जे ई पुरान गवेषकक लागि वा दोसराइत उपस्मृति द्वारा पठाओल गेल छल।",
        "newpassword": "नव कूटशब्द",
        "retypenew": "नव कूटशब्द फेरसँ टंकित करू",
        "resetpass_submit": "कूटशब्द बनाउ आ सम्प्रवेश करू",
-       "changepassword-success": "à¤\85हाà¤\81à¤\95 à¤\95à¥\82à¤\9fशबà¥\8dद सफलतासँ बदलि देल गेल!",
+       "changepassword-success": "à¤\85हाà¤\81à¤\95 à¤ªà¤¾à¤¸à¤µà¤°à¥\8dड सफलतासँ बदलि देल गेल!",
        "changepassword-throttled": "अहाँ ढ़ेर रास सम्प्रवेश प्रयास केलहुँ।\nफेर प्रयास $1 करबासँ पहिने कने काल थम्हू।",
+       "botpasswords": "बोट पासवर्ड",
+       "botpasswords-disabled": "बोट पासवर्ड अखन निष्क्रिय अछि।",
+       "botpasswords-no-central-id": "बोट पासवर्डक उपयोग करएक लेल अहाँक मुख्य खातासँ प्रवेश करै पडत।",
+       "botpasswords-existing": "वर्तमान बोट पासवर्ड",
+       "botpasswords-createnew": "बोटक लेल नव पासवर्ड बनाबी",
+       "botpasswords-editexisting": "बोटक वर्तमान पासवर्डके बदली",
+       "botpasswords-label-appid": "बोट नाम:",
+       "botpasswords-label-create": "बनाबी",
+       "botpasswords-label-update": "अद्यतन",
+       "botpasswords-label-cancel": "रद्द करी",
+       "botpasswords-label-delete": "मेटाबी",
+       "botpasswords-label-resetpassword": "पासवर्ड पुनः तय करी",
+       "botpasswords-label-grants": "अनुदान आवेदन:",
        "resetpass_forbidden": "कूटशब्द नै बदलल जा सकैए।",
        "resetpass-no-info": "अहाँकेँ ऐ पन्नाकेँ सोझे प्रयोग करबालेल सम्प्रवेशित हुअए पड़त।",
-       "resetpass-submit-loggedin": "à¤\95à¥\82à¤\9fशबà¥\8dद à¤¬à¤¦à¤²à¥\82",
-       "resetpass-submit-cancel": "à¤\96तम à¤\95रà¥\82",
+       "resetpass-submit-loggedin": "à¤\95à¥\82à¤\9fशबà¥\8dद à¤¬à¤¦à¤²à¥\80",
+       "resetpass-submit-cancel": "रदà¥\8dद à¤\95रà¥\80",
        "resetpass-wrong-oldpass": "अमान्य अस्थायी वा अखुनका कूटशब्द।\nअहाँ पहिनहिये सफलतासँ कूटशब्द बदलि लेने छी वा एकटा नव अस्थायी कूटशब्द लेल आग्रह केने छी।",
        "resetpass-recycled": "रीसेट करएके लेल नयाँ कूटशब्दमे कृपया अपन वर्तमान कूटशब्द नै द के नयाँ कूटशब्द देल जाउ।",
        "resetpass-temp-emailed": "अहाँ अखन एकटा अस्थायी ई-पत्र कोड सँ सम्प्रवेशित केनए छी। सम्प्रवेश पूर्ण करए के लेल अहाँ के एतए नयाँ कूटशब्द राखए पडत:",
        "changeemail-oldemail": "अखुनका ई-पत्र संकेत:",
        "changeemail-newemail": "नव ई-पत्र संकेत:",
        "changeemail-none": "(कोनो नै)",
-       "changeemail-password": "à¤\85हाà¤\95à¥\87 {{SITENAME}} कूटशब्द:",
-       "changeemail-submit": "à¤\88-पतà¥\8dर à¤¸à¤\82à¤\95à¥\87त à¤¬à¤¦à¤²à¥\82",
-       "changeemail-throttled": "à¤\85हाà¤\81 à¤¢à¤¼à¥\87र à¤°à¤¾à¤¸ à¤¸à¤®à¥\8dपà¥\8dरवà¥\87श à¤ªà¥\8dरयास à¤\95à¥\87लहà¥\81à¤\81।\nफà¥\87र à¤ªà¥\8dरयास à¤\95रबासà¤\81 à¤ªà¤¹à¤¿à¤¨à¥\87 à¤\95नà¥\87 काल थम्हू।",
+       "changeemail-password": "à¤\85हाà¤\81à¤\95 {{SITENAME}} कूटशब्द:",
+       "changeemail-submit": "à¤\88-मà¥\87ल à¤¬à¤¦à¤²à¥\80",
+       "changeemail-throttled": "à¤\85हाà¤\81 à¤¢à¥\87र à¤°à¤¾à¤¸ à¤¸à¤®à¥\8dपà¥\8dरवà¥\87श à¤ªà¥\8dरयास à¤\95à¥\87लहà¥\81à¤\81।\nफà¥\87र à¤ªà¥\8dरयास à¤\95रबासà¤\81 à¤ªà¤¹à¤¿à¤¨à¥\87 à¤\95नà¥\87 $1 काल थम्हू।",
        "resettokens": "टोकन रीसेट करी",
        "resettokens-text": "जे स्तोक अहाँके खाता सँ सम्बद्ध किछु विशिष्ट व्यक्तिगत जानकारी प्रदान करएत अछि, अहाँ वोकरा एतए सँ रिसेट कऽ सकएत छी।\n\nयदि अहाँ एकरा गलती सँ केकरो देखा देनए छी वा अहाँ के खाता ह्याक भ गेल अछि तहन अहाँके एकरा रिसेट कऽ देना चाही।",
        "resettokens-no-tokens": "रीसेट करवाक लेल कोनो टोकन नै अछि।",
        "token_suffix_mismatch": "'''अहाँक सम्पादन अस्वीकार कऽ देल गेल अछि कारण अहाँक ग्राहक प्रेष्यमान अंक विधानक विराम चेन्ह सभकेँ नष्ट कऽ देलन्हि।'''\nई सम्पादन पन्नाक पाठकेँ दूषित होएबासँ बचेबा लेल अमान्य कऽ देल गेल।\nई कखनो काल होइए जखन अहाँ जाल आधारित अनाम दोसरा लेल चल सेवा प्रयुक्त करै छी।",
        "edit_form_incomplete": "'''सम्पादन आवेदनक किछु भाग वितरक धरि नै पहुँचल; एक बेर फेर देखू जे अहाँक सम्पादन दुरुस्त अछि आ फेरसँ प्रयास करू।'''",
        "editing": "सम्पादन होइए $1",
-       "creating": "$1 à¤¬à¤¨à¤¾à¤\89",
+       "creating": "$1 à¤¬à¤¨à¤¾à¤¬à¥\80",
        "editingsection": "सम्पादन कऽ रहल छी $1 (खण्ड)",
        "editingcomment": "सम्पादन कऽ रहल छी $1 (नव खण्ड)",
        "editconflict": "सम्पादन अन्तर: $1",
        "storedversion": "पेटारमे राखल संशोधन",
        "nonunicodebrowser": "'''चेतौनी: अहाँक गवेषक सार्वत्रिकाक्षरकूट सहयोगी नै अछि।'''\nएकटा अस्थायी-परोक्ष तंत्रांश अहाँकेँ सुरक्षित रूपेँ पन्नाक सम्पादनमे मदति करत: गएर-अस्की अक्षर सभ षोडशमान पद्धतिमे सम्पादन बक्सामे आएत।",
        "editingold": "'''चेतौनी: अहाँ ऐ पन्नाक एकटा पुरान संशोधनक सम्पादन कऽ रहल छी।'''\nजँ अहाँ एकरा संरक्षित करै छी, कोनो संशोधन जे ऐ संशोधनक बाद भेल छै से खतम भऽ जाएत।",
-       "yourdiff": "फराà¤\95",
+       "yourdiff": "à¤\85नà¥\8dतर",
        "copyrightwarning": "कृपा कय बुझू जे सभटा योगदान {{SITENAME}} ई बुझि कय देल जा रहल अछि जे ई निम्नांकितक अंतर्गत अछि $2 (देखू $1 जनकारीक हेतु). जौँ अहाँ चाहैत छी जी अहाँक रचना बिना रोकटोकक संपादित नहि हो किंवा बाँटल नहि जाय, तँ एकर योगदान एतय नहि करू। <br />\nएतय अहाँ ईहो सप्पत खाइत छी जी ई अहाँक अपन रचना छी आकि अहाँ एकरा कोनो सार्वजनिक डोमेन किंवा ओह्ने कोनो मँगनीक संदर्भ-स्थलसँ कॉपी कएने छी।\n< दृढ़> सर्वाधिकार सुरक्षित कार्य एतय नहि दी।!</दृढ़>",
        "copyrightwarning2": "कृपा कऽ बुझू जे सभटा योगदान {{अन्तर्जाल}} योगदानकर्ता द्वारा सम्पादित, बदलल वा हटाएल जा सकैत अछि।. जौँ अहाँ चाहैत छी जी अहाँक रचना बिना रोकटोकक संपादित नहि हो किंवा बाँटल नहि जाय, तँ एकर योगदान एतय नहि करू। <br />\nएतय अहाँ ईहो सप्पत खाइत छी जी ई अहाँक अपन रचना छी आकि अहाँ एकरा कोनो सार्वजनिक डोमेन किंवा ओहने कोनो मँगनीक संदर्भ-स्थलसँ कॉपी कएने छी(देखू $1 वर्णन लेल)।\n''' सर्वाधिकार सुरक्षित कार्य एतय नहि दी।!'''",
        "longpageerror": "'''भ्रम: पाठ जे अहाँ देने छी से $1 किलोबाइट नमगर अछि,  जे अधिकतम आकार $2 किलोबाइट सँ बेशी नमगर अछि।'''\nई संरक्षित नै कएल जा सकत।",
        "edittools": "<!-- एतए देल गेल पाठ सम्पादन आर अपलोड फारम के निचा देखाओल जाएत। -->",
        "edittools-upload": "-",
        "nocreatetext": "{{अन्तर्जाल}} नव पन्ना निर्माणक क्षमताकेँ सीमित कऽ देने अछि।\nअहाँ आपस जा सकै छी आ कोनो पन्नाकेँ सम्पादित कऽ सकै छी, वा [[Special:UserLogin|log in or create an account]]",
-       "nocreate-loggedin": "अहाँकेँ नव पन्ना बनेबाक अधिकार नै अछि।",
-       "sectioneditnotsupported-title": "à¤\96à¤\82ड à¤¸à¤®à¥\8dपादन à¤¸à¤®à¤°à¥\8dथन à¤¨à¥\88",
-       "sectioneditnotsupported-text": "à¤\96à¤\82ड à¤¸à¤®à¥\8dपादनà¤\95 à¤\90 à¤ªà¤¨à¥\8dनापर  à¤¸à¤®à¤°à¥\8dथन à¤¨à¥\88",
+       "nocreate-loggedin": "अहाँक नव पन्ना बनेबाक अधिकार नै अछि।",
+       "sectioneditnotsupported-title": "à¤\85नà¥\81भाà¤\97 à¤¸à¤®à¥\8dपादन à¤¸à¤®à¤°à¥\8dथित à¤¨à¥\88 à¤\85à¤\9bि",
+       "sectioneditnotsupported-text": "à¤\88 à¤ªà¥\83षà¥\8dठ à¤ªà¤° à¤\85नà¥\81भाà¤\97 à¤¸à¤®à¥\8dपादन à¤¸à¤®à¤°à¥\8dथित à¤¨à¥\88 à¤\85à¤\9bि",
        "permissionserrors": "आज्ञा गल्ती",
        "permissionserrorstext": "अहाँके ऐ लेल अनुमति नै अछि, ऐ ले {{PLURAL:$1|कारण|कारण सभ}}:",
        "permissionserrorstext-withaction": "अहाँके अनुमति नै अछि $2 लेल, ऐ लेल {{PLURAL:$1|कारण|कारण सभ}}:",
        "columns": "स्तम्भ सभ",
        "searchresultshead": "ताकू",
        "stub-threshold": "सीमा <a href=\"#\" class=\"stub\">काटल लागि</a> सँचियाएल (अष्टक):",
+       "stub-threshold-sample-link": "उदाहरण",
        "stub-threshold-disabled": "अशक्त कएल",
        "recentchangesdays": "आइ-काल्हिक परिवर्तनमे कतेक दिन देखाएल गेल:",
        "recentchangesdays-max": "बेसीसँ बेसी $1 {{PLURAL:$1|दिन|दिन}}",
        "prefs-help-recentchangescount": "ऐ मे सम्मिलित अछि आइ-काल्हिक परिवर्तन, पन्नाक इतिहास आ वृत्तलेख",
        "prefs-help-watchlist-token2": "इ अहाँके कंक्षाकसूचीके वेब फिडके गोपनीय चाभी छी ।\nइ जे कोइ लंग अछि उ अपन कंक्षाकसूची पैढ सकैत अछि, ऐ लेल इ क्यों गोटा स नै बाटब ।\n[[Special:ResetTokens|एकरा रीसेट करवाक लेल यै ठाम क्लिक करु]]।",
        "savedprefs": "अहाँक पसिन्न सुरक्षित कएल गेल",
+       "savedrights": "प्रयोक्ता {{GENDER:$1|$1}}क सदस्य अधिकार सङ्ग्रह कएल गेल।",
        "timezonelegend": "समय क्षेत्र",
        "localtime": "स्थानीय समए:",
        "timezoneuseserverdefault": "पूर्वनिर्धारित वितरक प्रयुक्त करू ($1)",
        "prefs-reset-intro": "अहाँ ऐ पन्नाक प्रयोग अपन विकल्पकेँ पूर्वनिविष्ट रूपेँ जाल पुनर्निधारित करबा लेल कऽ सकै छी।\nई बदलल नै जा सकैए।",
        "prefs-emailconfirm-label": "ई-पत्र पुष्टि:",
        "youremail": "ई-पत्र:",
-       "username": "प्रयोक्तानाम:",
-       "prefs-memberingroups": "{{PLURAL:$1|संवर्ग|संवर्ग सभ}}:एकर सदस्य",
+       "username": "{{GENDER:$1|प्रयोगकर्तानाम}}:",
+       "prefs-memberingroups": "निम्नलिखित {{PLURAL:$1|समूह|समूहसभ}}क {{GENDER:$2|सदस्य}}:",
        "prefs-memberingroups-type": "$1",
        "prefs-registration": "पंजीकरणक समए:",
        "prefs-registration-date-time": "$1",
        "badsig": "अमान्य प्रारम्भिक पहिचान।\nएच.टी.एम.एल.चेन्ह जाँचू।",
        "badsiglength": "अहाँक हस्ताक्षर बड्ड पैघ अछि।\nई $1 सँ बेसी नै हेबाक चाही {{PLURAL:$1|वर्ण|वर्ण}} पैघ।",
        "yourgender": "पुरुख आकि स्त्री",
-       "gender-unknown": "à¤\85à¤\9cà¥\8dà¤\9eात",
+       "gender-unknown": "à¤\85हाà¤\81à¤\95 à¤µà¤°à¥\8dणन à¤\95रà¥\88त à¤¸à¤®à¤¯, à¤\9cतà¥\87à¤\95धरि à¤¸à¤®à¥\8dभव à¤¹à¥\8bà¤\8fत à¤¸à¤«à¥\8dà¤\9fवà¥\87यर à¤²à¤¿à¤\99à¥\8dà¤\97 à¤¤à¤\9fसà¥\8dथ à¤¶à¤¬à¥\8dदसभà¤\95 à¤ªà¥\8dरयà¥\8bà¤\97 à¤\95रत",
        "gender-male": "पुरुख",
        "gender-female": "स्त्री",
        "prefs-help-gender": "वैकल्पिक: तंत्रांश द्वारा लिंग निरपेक्ष सम्बोधन लेल प्रयुक्त।\nई सूचना सार्वजनिक हएत।",
        "userrights": "प्रयोक्ता अधिकारक प्रबन्धन",
        "userrights-lookup-user": "प्रयोक्ता संवर्ग सभक प्रबन्ध करू",
        "userrights-user-editname": "एकटा प्रयोक्तानाम लिखू:",
-       "editusergroup": "प्रयोक्ता संवर्ग सभक सम्पादन करू",
-       "editinguser": "पà¥\8dरयà¥\8bà¤\95à¥\8dताà¤\95 à¤ªà¥\8dरयà¥\8bà¤\95à¥\8dता à¤\85धिà¤\95ार à¤¬à¤¦à¤²à¤¬ '''[[User:$1|$1]]''' $2",
+       "editusergroup": "{{GENDER:$1|सदस्य}} समूहसभक सम्पादन करी",
+       "editinguser": "सदसà¥\8dय '''[[User:$1|$1]]''' $2 à¤\95 à¤\85धिà¤\95ार à¤¬à¤¦à¤²à¤¿\n{{GENDER:$1|सदसà¥\8dय}}à¤\95 à¤¸à¤¦à¤¸à¥\8dय à¤\85धिà¤\95ार à¤¬à¤¦à¤²à¤² à¤\9cा à¤°à¤¹à¤² à¤\85à¤\9bि <strong>[[User:$1|$1]]</strong> $2",
        "userrights-editusergroup": "प्रयोक्ता संवर्ग सभक सम्पादन करू",
-       "saveusergroups": "प्रयोक्ता संवर्ग सभकेँ सुरक्षित करू",
+       "saveusergroups": "{{GENDER:$1|सदस्य}} समूह सङ्ग्रह करी",
        "userrights-groupsmember": "क सदस्य:",
        "userrights-groupsmember-auto": "क जानल सदस्य:",
        "userrights-groups-help": "अहाँ ऐ प्रयोक्ताक वर्गकेँ बदलि सकै छी:\n* एकटा निशान लगाएल बक्सा माने प्रयोक्ता ओइ वर्गमे अछि।\n* एकटा बिन निशान लगाएल माने प्रयोक्ता ओइ वर्गमे नै अछि।\n* ई * देखबैए जे अहाँ वर्गकेँ एक बेर देलाक बाद हटा नै सकै छी, आ एकर उलट सेहो ठीक अछि।",
        "userrights-irreversible-marker": "$1*",
        "userrights-conflict": "प्रयोक्ता अधिकार बदलावक समयमे अंतर्विरोध! कृपया अपन बदलाव जाँच करु आ पुनः सुनिश्चित करु।",
        "userrights-removed-self": "अहाँ सफलतापूर्वक अपन अधिकार हटा देने छी। अतः अहाँ आब ई पृष्ठ नै देख सकैत छी।",
-       "group": "वरà¥\8dà¤\97:",
-       "group-user": "प्रयोक्ता सभ",
+       "group": "समà¥\82ह:",
+       "group-user": "प्रयोक्तासभ",
        "group-autoconfirmed": "स्वतःअनुमोदित प्रयोक्ता सभ",
        "group-bot": "स्वचालक",
-       "group-sysop": "माà¤\87नà¤\9cन",
+       "group-sysop": "पà¥\8dरबनà¥\8dधà¤\95",
        "group-bureaucrat": "अधिकारी",
-       "group-suppress": "नà¤\9cरिपर à¤¨à¥\88 à¤\86à¤\8fल",
+       "group-suppress": "नà¥\81à¤\95ाबà¤\8f à¤µà¤¾à¤²à¤¾",
        "group-all": "(सभ)",
        "group-user-member": "{{लिंग:$1|प्रयोक्ता}}",
        "group-autoconfirmed-member": "{{लिंग:$1|स्वतःअनुमोदित प्रयोक्ता}}",
        "group-bot-member": "{{लिंग:$1|स्वचालक}}",
        "group-sysop-member": "{{लिंग:$1|माइनजन}}",
        "group-bureaucrat-member": "{{लिंग:$1|अधिकारी}}",
-       "group-suppress-member": "{{लिंग:$1|नजरिपर नै आएल}}",
+       "group-suppress-member": "{{GENDER:$1|नुकाए वाला}}",
        "grouppage-user": "{{ns:project}}:प्रयोक्ता सभ",
        "grouppage-autoconfirmed": "{{ns:project}}:स्वतःअनुमोदित प्रयोक्ता सभ",
        "grouppage-bot": "{{ns:project}}:स्वचालक सभ",
        "grouppage-sysop": "{{ns:project}}:माइनजन सभ",
        "grouppage-bureaucrat": "{{ns:project}}:अधिकारी सभ",
-       "grouppage-suppress": "{{ns:project}}:नà¤\9cरिपर à¤¨à¥\88 à¤\86à¤\8fल",
+       "grouppage-suppress": "{{ns:project}}:नà¥\81à¤\95ाबà¥\80",
        "right-read": "पन्ना सभ पढ़ू",
        "right-edit": "पन्ना सभ सम्पादन करू",
        "right-createpage": "पन्ना सभ बनाउ (जे वार्ता पन्ना नै हुअए)",
        "right-createtalk": "वार्ता पन्ना सभ बनाउ",
        "right-createaccount": "नव प्रयोक्ता खाता सभ बनाउ",
+       "right-autocreateaccount": "बाहरी खातासँ स्वतः प्रवेश",
        "right-minoredit": "सम्पादन सभकेँ मामूली चिन्हित करू",
        "right-move": "पन्ना सभ घसकाउ",
        "right-move-subpages": "पन्ना सभकेँ उपपन्ना सभक संग घसकाउ",
        "right-managechangetags": "डेटाबेस से [[Special:Tags|नुकाबू]] बनाबु आर हटाबु",
        "right-applychangetags": "प्रयोग में लाबू [[Special:Tags|tags]] कक्रो बदलाव के साथ।",
        "right-changetags": "जमा करु आर हटाबु स्वतंत्र [[Special:Tags|टैग]] व्यक्तिगत अवतरण आर लॉग प्रविक्ति पे",
+       "grant-generic": "\"$1\" अधिकार सङ्ग्रह",
+       "grant-group-page-interaction": "पृष्ठसभसँ जोडी",
+       "grant-group-file-interaction": "मिडियासँ जोडी",
        "newuserlogpage": "प्रयोक्ता रचना वृत्तलेख",
        "newuserlogpagetext": "ई प्रयोक्ता निर्माणक वृत्तलेख अछि।",
        "rightslog": "प्रयोक्ता अधिकार वृत्तलेख",
        "upload-copy-upload-invalid-domain": "कपि अपलोड इ डोमेन स उपलब्ध नै अछि।",
        "upload-dialog-title": "फाइल अपलोड करी",
        "upload-dialog-button-cancel": "रद्द करी",
+       "upload-dialog-button-done": "पूर्ण भएल",
+       "upload-dialog-button-save": "सङ्ग्रह करी",
+       "upload-dialog-button-upload": "उपारोपण",
+       "upload-form-label-infoform-title": "विवरण",
+       "upload-form-label-infoform-name": "नाम",
+       "upload-form-label-infoform-description": "विवरण",
+       "upload-form-label-usage-title": "उपयोग",
+       "upload-form-label-usage-filename": "फाइलक नाम",
+       "foreign-structured-upload-form-label-own-work": "ई हमर काज छी",
+       "foreign-structured-upload-form-label-infoform-categories": "श्रेणीसभ",
+       "foreign-structured-upload-form-label-infoform-date": "दिनाङ्क",
        "backend-fail-stream": "\"$1\" केँ नै स्ट्रिम क सकल।",
        "backend-fail-backup": "\"$1\" केँ नै ब्याकअप क सकल।",
        "backend-fail-notexists": "फाइल $1 नै अछि।",
index e498c30..f55d378 100644 (file)
        "articlepage": "Lihek isi laman",
        "talk": "Rundiang",
        "views": "Caliak",
-       "toolbox": "Kotak pakakeh",
+       "toolbox": "Pakakeh",
        "userpage": "Lihek laman pangguno",
        "projectpage": "Caliak laman proyek",
        "imagepage": "Caliak laman berkas",
        "nstab-template": "Templat",
        "nstab-help": "Bantuan",
        "nstab-category": "Kategori",
+       "mainpage-nstab": "Palanta",
        "nosuchaction": "Indak ado tindakan tasabuik",
        "nosuchactiontext": "Tindakan nan diminta dek URL tasabuik indak valid. Sanak mungkin salah mangetikkan URL, atau mangikuik pautan nan salah. Iko mungkin manunjuakan adonyo suatu bug pado parangkaik lunak nan dipagunoan dek {{SITENAME}}.",
        "nosuchspecialpage": "Indak ado laman istimewa tasabuik",
        "login-abort-generic": "Proses masuak Sanak indak barasil - Dibatalan",
        "loginlanguagelabel": "Baso: $1",
        "suspicious-userlogout": "Pamintaan Sanak untuak kalua log ditulak karano tampaknyo dikirim oleh paramban nan rusak atau proksi panyinggah.",
+       "pt-login": "Masuak log",
+       "pt-createaccount": "Buek akun",
        "pt-userlogout": "Kalua log",
        "php-mail-error-unknown": "Kasalahan nan indak jaleh dalam fungsi mail() PHP",
        "user-mail-no-addy": "Mancubo mangirim surel tanpa alamaik surel.",
        "minoreditletter": "k",
        "newpageletter": "B",
        "boteditletter": "b",
+       "rc-change-size-new": "$1 {{PLURAL:$1|byte|bita}} satalah parubahan",
        "rc-enhanced-expand": "Tampilkan rincian (paralu JavaScript)",
        "rc-enhanced-hide": "Suruakkan rincian",
        "recentchangeslinked": "Parubahan takaik",
        "tooltip-pt-mycontris": "Daftar jariah Sanak",
        "tooltip-pt-login": "Sanak disaranan untuak masuak log; walaupun indak wajib",
        "tooltip-pt-logout": "Kalua log",
+       "tooltip-pt-createaccount": "Sanak dianjuaan mambuek akun dan masuak log; walaupun hal iko indak aruih",
        "tooltip-ca-talk": "Parudiangan tantang isi laman",
-       "tooltip-ca-edit": "Angku dapek manyuntiang laman ko. Silakan gunoan tombol pratonton sabalun manyimpan",
+       "tooltip-ca-edit": "Suntiang laman ko",
        "tooltip-ca-addsection": "Mulai bagian baru",
        "tooltip-ca-viewsource": "Laman ko dilinduangi.\nSanak hanyo buliah mancaliak sumbernyo sajo",
        "tooltip-ca-history": "Revisi sabalunnyo dari laman ko",
index 1fc9b49..8bcfce5 100644 (file)
        "changeemail": "Kái tiān-chú-phoe ê tē-chí",
        "changeemail-oldemail": "Chit-má ê E-mail tē-chí:",
        "changeemail-newemail": "Sin E-mail ê chū-chí:",
+       "changeemail-password": "Lí-ê {{SITENAME}} bi̍t-bé:",
+       "changeemail-submit": "Kái-piàn tiān-chu-phoe",
+       "changeemail-throttled": "Lí chi̍t-ê-á teng-ji̍p liáu siuⁿ chē kái.\nChiáⁿ tan-thāi $1 kòe-āu chài chhì chi̍t pái.",
+       "changeemail-nochange": "Chhiáⁿ su-ji̍p chi̍t-ê bô-kâng ê sin tiān-chú-phoe chū-chí.",
        "bold_sample": "Chho·-thé bûn-jī",
        "bold_tip": "Chho·-thé jī",
        "italic_sample": "Chhú-thé ê bûn-jī",
        "recreate-moveddeleted-warn": "'''Sè-jī: Lí taⁿ chún-pī beh khui ê ia̍h, chêng bat hō͘ lâng thâi tiāu koè.''' Lí tio̍h chim-chiok soà-chiap pian-chi̍p chit ia̍h ê pit-iàu-sèng. Chia ū chit ia̍h ê san-tû kì-lo̍k (deletion log) hō͘ lí chham-khó:",
        "edit-conflict": "Siu-kái sio-chhiong",
        "defaultmessagetext": "Siat piān ê bûn-jī",
+       "content-model-wikitext": "wikitext",
+       "content-model-text": "sûn bûn-pún",
        "content-model-javascript": "JavaScript",
+       "content-json-empty-object": "Khang bu̍t-kiāⁿ",
+       "content-json-empty-array": "Khang tīn-lia̍t",
        "post-expand-template-inclusion-warning": "'''Kéng-pò:'''Pau ji̍t lâi ê pán-bôo sioⁿ koè tsē ia̍h tuā.\nŪ chi̍t-koá-á ē bô pau ji̍t lâi.",
        "undo-success": "Pian-chi̍p í-keng chhú-siau. Chhiáⁿ khak-tēng, liáu-āu kā ē-kha ho̍k-goân ê kái-piàn pó-chûn--khí-lâi.",
        "undo-failure": "Pian-chi̍p bē-tàng chhú-siau, in-ūi chhiong tio̍h kî-kan chhah-ji̍p ê pian-chi̍p.",
index 0c158b2..009e871 100644 (file)
        "botpasswords-label-cancel": "Anuluj",
        "botpasswords-label-delete": "Usuń",
        "botpasswords-label-resetpassword": "Zresetuj hasło",
+       "botpasswords-label-grants": "Zastosowane uprawnienia:",
        "botpasswords-label-grants-column": "Przyznane",
        "botpasswords-bad-appid": "Nazwa bota \"$1\" nie jest prawidłowa.",
        "botpasswords-created-title": "Hasło bota stworzone",
        "autoredircomment": "Przekierowanie do [[$1]]",
        "autosumm-new": "Utworzono nową stronę \"$1\"",
        "autosumm-newblank": "Utworzono pustą stronę",
-       "size-bytes": "$1&nbsp;B",
+       "size-bytes": "$1 {{PLURAL:$1|bajt|bajty|bajtów}}",
        "size-kilobytes": "$1&nbsp;KB",
        "size-megabytes": "$1&nbsp;MB",
        "size-gigabytes": "$1&nbsp;GB",
index 28c02cb..2ee34bd 100644 (file)
        "undo-summary-username-hidden": "Edit summary for an undo action where the username of the old revision is hidden.\n\nParameters:\n* $1 - the revision ID being undone\nSee also:\n* {{msg-mw|Undo-summary}}",
        "cantcreateaccounttitle": "Used as title of the error message {{msg-mw|Cantcreateaccount-text}}.",
        "cantcreateaccount-text": "Used as error message, with the title {{msg-mw|Cantcreateaccounttitle}}.\n* $1 - target IP address\n* $2 - reason or {{msg-mw|Blockednoreason}}\n* $3 - username\nSee also:\n* {{msg-mw|Cantcreateaccount-range-text}}",
-       "cantcreateaccount-range-text": "Used as more detailed version of the {{msg-mw|Cantcreateaccount-text}} error message, with the title {{msg-mw|Cantcreateaccounttitle}}.\n* $1 - target IP range\n* $2 - reason or {{msg-mw|Blockednoreason}}\n* $3 - username\n* $4 - current user's IP address",
+       "cantcreateaccount-range-text": "Used as more detailed version of the {{msg-mw|Cantcreateaccount-text}} error message, with the title {{msg-mw|Cantcreateaccounttitle}}.\n* $1 - target IP address range\n* $2 - reason or {{msg-mw|Blockednoreason}}\n* $3 - username\n* $4 - current user's IP address",
        "createaccount-hook-aborted": "Placeholder message to return with API errors on account create; passes through the message from a hook {{notranslate}}",
        "viewpagelogs": "Link displayed in history of pages",
        "nohistory": "Message shown when there are no history to list. See [{{canonicalurl:x|action=history}} example history].\n----\nAlso used as title of error message when the feed is empty. See [{{canonicalurl:x|action=history&feed=atom}} example feed].\n\nSee the error message:\n* {{msg-mw|history-feed-empty}}",
        "ipb-unblock": "Used as page title in [[Special:Block]], if the target user is not specified.\n\nSee also:\n* {{msg-mw|Ipb-unblock-addr}}",
        "ipb-blocklist": "Used as link text in [[Special:Block]].\n\nThe link points to Specil:BlockList.",
        "ipb-blocklist-contribs": "Used in [[Special:Block]].\n* $1 - target username",
+       "ipb-blocklist-duration-left": "Used on [[Special:BlockList]] to show the remaining time (years, months, days, hours, minutes) until the block expires.\n$1 - The duration left",
        "unblockip": "Used as legend for the form in [[Special:Unblock]].",
        "unblockiptext": "Used in the {{msg-mw|Unblockip}} form on [[Special:Unblock]].",
        "ipusubmit": "Used as button text on [{{canonicalurl:Special:BlockList|action=unblock}} Special:BlockList?action=unblock]. To see the message:\n* Go to [[Special:BlockList]]\n* Click \"unblock\" for any block (but you can only see \"unblock\" if you have administrator rights)\n* It is now the button below the form",
        "ipb_expiry_temp": "Warning message displayed on [[Special:BlockIP]] if the option \"hide username\" is selected but the expiry time is not infinite.",
        "ipb_hide_invalid": "Used as error message in [[Special:Block]].\n* $1 - Number of edits (Value of [[mw:Manual:$wgHideUserContribLimit]])",
        "ipb_already_blocked": "{{Identical|$1 is already blocked}}",
-       "ipb-needreblock": "Used in [[Special:Block]].\n* $1 - target username",
+       "ipb-needreblock": "Used in [[Special:Block]].\n* $1 - target username, can be used for GENDER support",
        "ipb-otherblocks-header": "[[File:Special.Block with other blocks from GlobalBlocking and TorBlocks.png|thumb|Example]]\nUsed on [[Special:Block]] as header for other blocks, i.e. from GlobalBlocking or TorBlocks\n\nParameters:\n* $1 - number of blocks\nSee also:\n* {{msg-mw|Ipblocklist-otherblocks}}",
        "unblock-hideuser": "{{doc-singularthey}}",
        "ipb_cant_unblock": "Used as error message in [[Special:Unblock]]. Parameters:\n* $1 - block ID",
-       "ipb_blocked_as_range": "Used when unblock of a single IP fails. Parameters:\n* $1 - IP address\n* $2 - IP range",
+       "ipb_blocked_as_range": "Used when unblock of a single IP fails. Parameters:\n* $1 - IP address\n* $2 - IP address range",
        "ip_range_invalid": "Used as error message in [[Special:Block]].\n\nSee also:\n* {{msg-mw|Range block disabled}}\n* {{msg-mw|Ip range invalid}}\n* {{msg-mw|Ip range toolarge}}",
        "ip_range_toolarge": "Used as error message in [[Special:Block]]. Parameters:\n* $1 - a number from 0 to 32 for IPv4 (from 0 to 128 for IPv6); a part of CIDR (Classless Inter-Domain Routing) notation.\nSee also:\n* {{msg-mw|Range block disabled}}\n* {{msg-mw|Ip range invalid}}\n* {{msg-mw|Ip range toolarge}}",
        "proxyblocker": "Used in [[Special:BlockMe]].\n\nSee also:\n* {{msg-mw|proxyblocker-disabled}}\n* {{msg-mw|proxyblockreason}}\n* {{msg-mw|proxyblocksuccess}}",
        "version-libraries-description": "Column header for the library's description\n{{Identical|Description}}",
        "version-libraries-authors": "Column header for the library's authors\n{{Identical|Author}}",
        "redirect": "{{doc-special|Redirect}}\nThis means \"Redirect by file '''name''', user '''ID''', page '''ID''', revision '''ID''', or log '''ID'''\".",
-       "redirect-legend": "Legend of fieldset around input box in [[Special:Redirect]]",
        "redirect-text": "Inside fieldset for [[Special:Redirect]]",
        "redirect-summary": "Shown at top of [[Special:Redirect]]",
        "redirect-submit": "Button label in [[Special:Redirect]].\n{{Identical|Go}}",
        "logentry-protect-protect-cascade": "{{Logentry|[[Special:Log/protect]]}}\n\n* $4 - protect expiry (formatted with {{msg-mw|protect-summary-desc}}, multiple possible)\nFor word \"cascading\" see {{msg-mw|protect-summary-cascade}}",
        "logentry-protect-modify": "{{Logentry|[[Special:Log/protect]]}}\n\n* $4 - protect expiry (formatted with {{msg-mw|protect-summary-desc}}, multiple possible)",
        "logentry-protect-modify-cascade": "{{Logentry|[[Special:Log/protect]]}}\n\n* $4 - protect expiry (formatted with {{msg-mw|protect-summary-desc}}, multiple possible)\nFor word \"cascading\" see {{msg-mw|protect-summary-cascade}}",
-       "logentry-rights-rights": "* $1 - username\n* $2 - (see below)\n* $3 - username\n* $4 - list of user groups or {{msg-mw|Rightsnone}}\n* $5 - list of user groups or {{msg-mw|Rightsnone}}\n----\n{{Logentry|[[Special:Log/rights]]}}",
+       "logentry-rights-rights": "* $1 - username\n* $2 - (see below)\n* $3 - username, also used for GENDER support\n* $4 - list of user groups or {{msg-mw|Rightsnone}}\n* $5 - list of user groups or {{msg-mw|Rightsnone}}\n----\n{{Logentry|[[Special:Log/rights]]}}",
        "logentry-rights-rights-legacy": "* $1 - username\n* $2 - (see below)\n* $3 - username\n----\n{{Logentry|[[Special:Log/rights]]}}",
        "logentry-rights-autopromote": "* $1 - username\n* $2 - (see below)\n* $3 - (see below)\n* $4 - comma separated list of old user groups or {{msg-mw|Rightsnone}}\n* $5 - comma separated list of new user groups\n----\n{{Logentry|[[Special:Log/rights]]}}",
        "logentry-upload-upload": "{{Logentry|[[Special:Log/upload]]}}",
index 414123e..f97de72 100644 (file)
        "nocookieslogin": "{{SITENAME}} folosește module cookie pentru a autentifica utilizatorii. Browser-ul dvs. are cookie-urile dezactivate. Vă rugăm să le activați și să incercați din nou.",
        "nocookiesfornew": "Contul de utilizator nu a fost creat, deoarece nu am putut confirma sursa.\nAsigurați-vă că aveți cookie-urile activate, reîncărcați pagina și încercați din nou.",
        "noname": "Numele de utilizator pe care l-ați introdus nu este valid.",
-       "loginsuccesstitle": "Autentificare reușită",
+       "loginsuccesstitle": "Autentificat(ă)",
        "loginsuccess": "'''Ați fost autentificat la {{SITENAME}} ca „$1”.'''",
        "nosuchuser": "Nu există nici un utilizator cu numele „$1”.\nNumele de utilizatori sunt sensibile la majuscule.\nVerifică dacă ai scris corect sau [[Special:UserLogin/signup|creează un nou cont de utilizator]].",
        "nosuchusershort": "Nu există niciun utilizator cu numele „$1”.\nVerificați ortografierea.",
        "createaccount-title": "Creare de cont la {{SITENAME}}",
        "createaccount-text": "Cineva a creat un cont asociat adresei dumneavoastră de e-mail pe {{SITENAME}} ($4) numit „$2” și având parola „$3”.\nEste de dorit să vă autentificați și să schimbați parola cât mai repede.\n\nIgnorați acest mesaj dacă crearea contului s-a produs în urma unei greșeli.",
        "login-throttled": "Ați avut prea multe încercări recente de a vă autentifica.\nVă rugăm să așteptați $1 până să reîncercați.",
-       "login-abort-generic": "Procesul de autentificare a eșuat și a fost abandonat",
+       "login-abort-generic": "Procesul de autentificare a eșuat - Abandonat",
        "login-migrated-generic": "Contul dumneavoastră a fost migrat, iar numele de utilizator nu mai există pe acest wiki.",
        "loginlanguagelabel": "Limba: $1",
        "suspicious-userlogout": "Cererea dumneavoastră de a închide sesiunea a fost refuzată întrucât pare că a fost trimisă printr-o eroare a navigatorului sau de un proxy memorat în cache.",
        "newpassword": "Parola nouă:",
        "retypenew": "Reintroduceți noua parolă:",
        "resetpass_submit": "Setează parola și autentifică",
-       "changepassword-success": "Parola dumneavoastră a fost schimbată cu succes!",
+       "changepassword-success": "Parola dumneavoastră a fost schimbată!",
        "changepassword-throttled": "Ați avut prea multe încercări recente de a vă autentifica.\nVă rugăm să așteptați $1 până să reîncercați.",
        "botpasswords": "Parole roboți",
        "botpasswords-summary": "<em>Parolele de roboți</em> permit accesul la un cont de utilizator prin intermediul API-ului fără utilizarea identificatorilor de conectare principali ai contului. Este posibil ca drepturile de utilizator disponibile după conectarea cu parole de roboți să fie restricționate.\n\nDacă nu știți exact de ce ați recurge la această metodă, probabil ar trebui să nu o faceți. Nimeni nu ar trebui să vă ceară vreodată să generați acest tip de parolă și să le-o furnizați.",
index aa6dd44..d1bef27 100644 (file)
        "special-characters-group-ipa": "МФА (IPA)",
        "special-characters-group-symbols": "Символы",
        "special-characters-group-greek": "Греческие",
+       "special-characters-group-greekextended": "Расширенный греческий",
        "special-characters-group-cyrillic": "Кириллица",
        "special-characters-group-arabic": "Арабские",
        "special-characters-group-arabicextended": "Арабские расширенные",
index 63008eb..8bcc683 100644 (file)
        "special-characters-group-ipa": "Mednarodna fonetična abeceda (IPA)",
        "special-characters-group-symbols": "Simboli",
        "special-characters-group-greek": "Grški",
+       "special-characters-group-greekextended": "Grščina, razširjeno",
        "special-characters-group-cyrillic": "Cirilica",
        "special-characters-group-arabic": "Arabski",
        "special-characters-group-arabicextended": "Razširjena arabščina",
index 9c8254a..b94be84 100644 (file)
        "mw-widgets-titleinput-description-new-page": "страница још увек не постоји",
        "mw-widgets-titleinput-description-redirect": "преусмерава на $1",
        "api-error-blacklisted": "Изаберите другачији, описан назив.",
-       "randomrootpage": "Случајна коренска страница"
+       "randomrootpage": "Случајна коренска страница",
+       "log-action-filter-block": "Тип блокирања:",
+       "log-action-filter-delete": "Тип брисања:",
+       "log-action-filter-patrol": "Тип патролирања:",
+       "log-action-filter-protect": "Тип закључавања:",
+       "log-action-filter-upload": "Тип отпремања:",
+       "log-action-filter-all": "све",
+       "log-action-filter-block-block": "блокирање",
+       "log-action-filter-block-reblock": "измена блокирања",
+       "log-action-filter-block-unblock": "деблокирање",
+       "log-action-filter-delete-delete": "брисање странице",
+       "log-action-filter-delete-restore": "враћање странице",
+       "log-action-filter-delete-event": "брисање уноса у дневницима",
+       "log-action-filter-delete-revision": "брисање измене",
+       "log-action-filter-patrol-patrol": "ручно",
+       "log-action-filter-patrol-autopatrol": "аутоматско",
+       "log-action-filter-protect-protect": "закључавање",
+       "log-action-filter-protect-modify": "измена закључавања",
+       "log-action-filter-protect-unprotect": "уклањање закључавања",
+       "log-action-filter-upload-upload": "ново",
+       "log-action-filter-upload-overwrite": "промена постојећег"
 }
index a87091f..3d373dd 100644 (file)
        "perfcachedts": "பின்வரும் தரவுகள் இடைமாற்றைக் கொண்டுள்ளன, தரவுகள் கடைசியாக  $1 இல் புதுபிக்கப்பட்டுள்ளன.அதிகபட்சமாக {{PLURAL:$4|ஒரு முடிவு|$4 முடிவுகள்}} இடைமாற்றில் இருக்கலாம்.",
        "querypage-no-updates": "இப்பக்கத்துக்கான இற்றைப்படுத்தல்கள் செயலிழக்கச் செய்யப்பட்டுள்ளன. இங்கே உள்ளத் தரவுகள் தற்சமயம் இற்றைப்படுத்தப்படமாட்டாது.",
        "viewsource": "மூலத்தைப் பார்",
-       "viewsource-title": "$1க்கான மூலத்தைப்  பார்",
+       "viewsource-title": "$1 என்பதற்கான மூலத்தைப் பார்",
        "actionthrottled": "செயற்பாடு கட்டுப்படுத்தப்பட்டது",
        "actionthrottledtext": "எரிதக் காப்பு நடவடிக்கையாகப் பயனொருவர் குறித்த சிறு கால இடைவெளியில் இச்செயற்பாட்டை அதிகளவில் செய்வது தடுக்கப்பட்டுள்ளது. நீர் அவ்வெல்லையைத் தாண்டிவிட்டீர். அருள் கூர்ந்து சில நிமிடங்களில் முயலவும்.",
        "protectedpagetext": "இப்பக்கம் தொகுக்கப்படுவதையோ அல்லது பிற செயல்களைத் தவிர்ப்பதற்காகவோ பூட்டப்பட்டுள்ளது.",
        "sectioneditnotsupported-text": "இப்பக்கத்தில் உட்பிரிவை தொகுக்க தேவையான ஆதரவில்லை.",
        "permissionserrors": "அனுமதி தவறுகள்",
        "permissionserrorstext": "பின்வரும் {{PLURAL:$1|காரணத்துக்காக|காரணங்களுக்காக}} நீங்கள் அதைச் செய்ய முடியாது:",
-       "permissionserrorstext-withaction": "$2-்கு தங்களுக்கு அனுமதி இல்லை. அதற்கான {{PLURAL:$1|காரணம்|காரணங்கள்}}:",
+       "permissionserrorstext-withaction": "$2- இதற்கு தங்களுக்கு அனுமதி இல்லை. அதற்கான {{PLURAL:$1|காரணம்|காரணங்கள்}}:",
        "recreate-moveddeleted-warn": "'''எச்சரிக்கை: தாங்கள் ஏற்கனவே நீக்கப்பட்ட பக்கமொன்றை மீண்டும் தொடங்க விழைகிறீர்கள்.'''\n\nஇப்பக்கத்தைத் தொடர்ந்து தொகுப்பது சரியானதா என்று எண்ணிப்பார்க்கவும்.\n\nதங்களின் வசதிக்காக இப்பக்கத்தின் நீக்கல் மற்றும் நகர்த்தல் குறிப்புகள் கொடுக்கப்பட்டுள்ளது:",
        "moveddeleted-notice": "இது ஒரு நீக்கப்பட்ட பக்கமாகும்.\n\nதங்களின் வசதிக்காக இப்பக்கத்தின் நீக்கல் மற்றும் நகர்த்தல் குறிப்புகள் கொடுக்கப்பட்டுள்ளது.",
        "moveddeleted-notice-recent": "மன்னிக்கவும், இந்தப் பக்கம் அண்மையில் நீக்கப்பட்டுள்ளது (24 மணித்தியாலத்திற்குள்). இப்பக்கத்திற்கான நீக்கல் மற்றும் நகர்த்தல் பதிவு கீழே மேற்கோளுக்காக தரப்பட்டுள்ளது.",
        "postedit-confirmation-saved": "உங்களது தொகுப்பு சேமிக்கப்பட்டது.",
        "edit-already-exists": "புதிய பக்கமொன்றை உருவாக்க முடியாது.\nஇப்பக்கம் ஏற்கனவே உள்ளது.",
        "defaultmessagetext": "இயல்பிருப்பு தகவல் உரை",
-       "content-failed-to-parse": "à®\89ளà¯\8dளà®\9fà®\95à¯\8dà®\95à®®à¯\8d $2 à®µà®\95à¯\88 $1 à®\95்காக பாகுபடுத்தல் தோல்வி: $3",
+       "content-failed-to-parse": "à®\89ளà¯\8dளà®\9fà®\95à¯\8dà®\95à®®à¯\8d $2 à®µà®\95à¯\88 $1 à®\87à®±்காக பாகுபடுத்தல் தோல்வி: $3",
        "invalid-content-data": "செல்லாத உள்ளடக்கத் தரவு",
        "content-not-allowed-here": "\"$1\" உள்ளடக்கம் [[$2]] பக்கத்தில் அனுமதிக்கப்படவில்லை.",
        "editwarning-warning": "இந்த பக்கத்தை விட்டு செல்வது நீங்கள் ஏற்படுத்திய மாற்றங்களை இழக்க வழிவகுக்கும்.\nநீங்கள் புகுபதிந்திருந்தால், இந்த எச்சரிக்கையை உங்கள் விருப்பத்தேர்வில் உள்ள \"{{int:prefs-editing}}\" பகுதி மூலம் நீக்கலாம்.",
        "recentchanges-label-newpage": "இந்தத் தொகுப்பு ஒரு புதிய பக்கத்தை உருவாக்கியுள்ளது",
        "recentchanges-label-minor": "இது ஒரு சிறு தொகுப்பு",
        "recentchanges-label-bot": "இந்த தொகுப்பானது ஒரு தானியங்கியால் செய்யப்பட்டதாகும்",
-       "recentchanges-label-unpatrolled": "à®\87நà¯\8dத  à®¤à¯\8aà®\95à¯\81பà¯\8dபà¯\81  à®\87னà¯\8dனà¯\81à®®à¯\8d à®°à¯\8bநà¯\8dதிà®\9fபà¯\8dபà®\9fவில்லை",
+       "recentchanges-label-unpatrolled": "à®\87தà¯\8dதà¯\8aà®\95à¯\81பà¯\8dபà¯\81 à®\87னà¯\8dனà¯\81à®®à¯\8d à®\9aà¯\81à®±à¯\8dà®±à¯\81à®\95à¯\8dà®\95ாவலà¯\81à®\95à¯\8dà®\95à¯\81 à®\89ளà¯\8dளாà®\95வில்லை",
        "recentchanges-label-plusminus": "இத்தனை பைட்டுகளுக்கு பக்கத்தின் அளவு மாற்றப்பட்டுள்ளது",
        "recentchanges-legend-heading": "<strong>குறியீட்டு விளக்கம்:</strong>",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} ([[Special:NewPages|புதிய பக்கங்கள் பட்டியலையும்]] காணவும்)",
        "contributions-title": "$1 இற்கான பயனர் பங்களிப்புகள்",
        "mycontris": "பங்களிப்புக்கள்",
        "anoncontribs": "பங்களிப்புக்கள்",
-       "contribsub2": "{{GENDER:$3|$1}} à®\95்காக ($2)",
+       "contribsub2": "{{GENDER:$3|$1}} à®\87à®±்காக ($2)",
        "contributions-userdoesnotexist": "பயனர் கணக்கு \"$1\" ஆனது பதியப்படவில்லை.",
        "nocontribs": "இந்த நிபந்தனையுடன் ஒத்துப்போகும் வகையில் மாற்றங்களெதுவும் காணப்படவில்லை.",
        "uctop": "(தற்போதைய)",
        "pageinfo-category-subcats": "துணைபகுப்புகளின் எண்ணிக்கை",
        "pageinfo-category-files": "கோப்புகளின் எண்ணிக்கை",
        "markaspatrolleddiff": "ரோந்திட்டதாக குறி",
-       "markaspatrolledtext": "à®\87பà¯\8dபà®\95à¯\8dà®\95தà¯\8dதà¯\88 à®°à¯\8bநà¯\8dதிà®\9fà¯\8dà®\9fதாகக் குறி",
+       "markaspatrolledtext": "à®\87தனà¯\88 à®\9aà¯\81à®±à¯\8dà®±à¯\81à®\95à¯\8dà®\95ாவலà¯\8d à®\9aà¯\86யà¯\8dததாகக் குறி",
        "markaspatrolledtext-file": "இக்கோப்பு பதிப்பினை ரோந்திட்டதாக குறி",
        "markedaspatrolled": "ரோந்திட்டதாக குறிக்கப்பட்டது",
        "markedaspatrolledtext": "தெரிவு செய்யப்பட்டத் திருத்தம் [[:$1]]  பார்வையிட்டதாக குறிக்கப்பட்டுள்ளது.",
index db06b86..fc27968 100644 (file)
@@ -83,7 +83,8 @@
                        "Matma Rex",
                        "HakanIST",
                        "Imabadplayer",
-                       "İnternion"
+                       "İnternion",
+                       "Hbseren"
                ]
        },
        "tog-underline": "Bağlantıların altını çiz:",
        "special-characters-group-ipa": "UFA",
        "special-characters-group-symbols": "Simgeler",
        "special-characters-group-greek": "Yunan",
+       "special-characters-group-greekextended": "Genişletilmiş Yunanca",
        "special-characters-group-cyrillic": "Kiril",
        "special-characters-group-arabic": "Arap",
        "special-characters-group-arabicextended": "Genişletilmiş Arapça",
        "mw-widgets-titleinput-description-redirect": "$1'e yönlendirildi",
        "sessionprovider-mediawiki-session-cookiesessionprovider": "çerez tabanlı oturumlar",
        "sessionprovider-nocookies": "Çerezler devre dışı olabilir. Çerkezlerin aktif olduğuna emin olun ve yeniden başlatin.",
-       "randomrootpage": "Rastgele kök sayfası"
+       "randomrootpage": "Rastgele kök sayfası",
+       "log-action-filter-block": "Blok türü:",
+       "log-action-filter-delete": "Silme türü:",
+       "log-action-filter-patrol": "Devriye türü:",
+       "log-action-filter-protect": "Koruma tipi:",
+       "log-action-filter-upload": "Yükleme türü:",
+       "log-action-filter-all": "Tümü",
+       "log-action-filter-block-block": "Blok",
+       "log-action-filter-block-reblock": "Blok değiştirme",
+       "log-action-filter-block-unblock": "Engeli kaldır",
+       "log-action-filter-delete-delete": "Sayfa silme",
+       "log-action-filter-delete-restore": "Sayfa silmeyi geri al",
+       "log-action-filter-delete-event": "Günlük silme",
+       "log-action-filter-delete-revision": "Gözden geçirmenin silinmesi",
+       "log-action-filter-patrol-patrol": "Manuel devriye",
+       "log-action-filter-patrol-autopatrol": "Otomatik devriye",
+       "log-action-filter-protect-protect": "Koruma",
+       "log-action-filter-protect-modify": "Koruma değişikliği",
+       "log-action-filter-protect-unprotect": "Korunmayan",
+       "log-action-filter-upload-upload": "Yeni yükleme",
+       "log-action-filter-upload-overwrite": "Yeniden yükle"
 }
index de2a10d..4cb973b 100644 (file)
        "special-characters-group-ipa": "МФА (IPA)",
        "special-characters-group-symbols": "Символи",
        "special-characters-group-greek": "Грецькі",
+       "special-characters-group-greekextended": "Розширений грецький",
        "special-characters-group-cyrillic": "Кирилиця",
        "special-characters-group-arabic": "Арабські",
        "special-characters-group-arabicextended": "Арабська розширена",
index c840b1b..4ce72b4 100644 (file)
        "powersearch-togglelabel": "Kodvda:",
        "powersearch-toggleall": "Kaik",
        "powersearch-togglenone": "Ei ole nimidä",
+       "powersearch-remember": "Panda valičend muštho tulebiden ecmižiden täht",
        "search-external": "Irdecind",
        "searchdisabled": "{{SITENAME}} ecind om saubatud.\nTö voit nügüd' ectä Google'n turbiš.\nOtkat sil'mnägubale üks-se, miše {{SITENAME}}-saitan sädäimišt voib olda vanhtunuden.",
        "preferences": "Järgendused",
        "recentchanges-label-bot": "Necen redakcijan tegi bot",
        "recentchanges-label-unpatrolled": "Necidä redakcijad ei völ patruliruinugoi",
        "recentchanges-label-plusminus": "Suruden toižetamine baitoiš",
+       "recentchanges-legend-heading": "<strong>Legend:</strong>",
        "recentchanges-legend-newpage": "$1 - uz' lehtpol'",
        "rcnotefrom": "Alemba oma anttud toižetused '''$2'''-späi ( '''$1'''-hesai).",
        "rclistfrom": "Ozutada uded toižetused dataspäi $3 $2 augotaden",
index 6fb8443..9d244ba 100644 (file)
        "nocookieslogin": "{{SITENAME}} in nagkikinahanglan hin mga kuki para makapagpalog-in hin mga gumaramit.  An im mga kuki in diri nagana.\nAlayon paganaha hira ngan utro liwat.",
        "nocookiesfornew": "An imo akawnt han gumaramit in waray nahimo, kay tungod diri kami nakakakompirma han tinikangan.\nSiguradoha nga an mga cookies in nakaandar, igreload ini nga pakli ngan utroha.",
        "noname": "Waray ka nakahatag hin maupay nga agnay-hit-gumaramit.",
-       "loginsuccesstitle": "Malinamposon an pagsulod",
+       "loginsuccesstitle": "Nakalog-in",
        "loginsuccess": "'''Ikaw in nakalog-in ha {{SITENAME}} komo \"$1\".'''",
        "nosuchuser": "Waray gumaramit an may-ada ngaran nga \"$1\".\nIt mga agnay-hi-gumaramit in case sensitive.\nPanginano-a it imo pagbaybay, o [[Special:UserLogin/signup|paghimo hin bag-o nga akawnt]].",
        "nosuchusershort": "Waray nagamit it may ngaran nga \"$1\".\nKitaa kun amo it im pagbaybay.",
        "newarticle": "(Bag-o)",
        "newarticletext": "Ginsunod mo an pakli nga waray pa kahihimo.  Para ighimo an pakli, tikanga pagmakinilya ha kahon nga aada ha ubos (kitaa an [$1 nabulig nga pakli] para han kadugangan nga pananabutan).  Kun sayop an imo pagkanhi, igpidlit an imo kanan panngaykay (''browser'') '''balik''' (''back'') nga piridlitan.",
        "anontalkpagetext": "----\n''Ini in hiruhimangraw-nga-pakli para han waray magpakilala nga gumaramit, nga waray pa hinmimo hin akawnt.''\nMagamit la kami hin IP address para makilal-an hiya.\nSugad hini nga IP address, in puydi sinmaro hiton pipira nga mga gumaramit.\nKun ikaw in waray magpakilala nga gumaramit, ngan pag-abat mo in may mga diri naangay nga komento an ginpapadangat ha imo, alayon nala [[Special:UserLogin/signup|paghimo hin akawnt]] o [[Special:UserLogin|pag-log in]] para malikyan an sumurunod nga mga pagkalipat nga dapat para ha iba nga waray magpakilala nga mga gumaramit.",
-       "noarticletext": "Waray yana nahasurat hini nga pakli.\nPuyde hi ikaw [[Special:Search/{{PAGENAME}}|magbiling para han ngaran hini nga pakli]] ha iba nga mga pakli,\n<span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} binga an mga nanginginlabot nga mga log],\no [{{fullurl:{{FULLPAGENAME}}|action=edit}} igliwat ini nga pakli]</span>.",
+       "noarticletext": "Waray yana teksto ha sulod hinin nga pakli.\nPuyde ka [[Special:Search/{{PAGENAME}}|mamiling hin titulo hinin nga pakli]] ha iba pa nga mga pakli,\n<span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} pamilnga an may mga pagkahisumpay nga mga talaan],\no [{{fullurl:{{FULLPAGENAME}}|action=edit}} igliwat ini nga pakli]</span>.",
        "noarticletext-nopermission": "Waray yana nahasurat hini nga pakli\nPuyde hi ikaw [[Special:Search/{{PAGENAME}}|magbiling han ngaran hini nga pakli]] ha iba nga mga pakli,\no <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} mamiling han mga nanginginlabot nga mga talaan]</span>, kundi diri ka gintutugotan hin paghímò hini nga pakli.",
        "missing-revision": "Waray na an rebisyon #$1 han pakli nga ginngaranan nga  \"{{FULLPAGENAME}}\".\n\nIni in agsob tungod han pagsunod hin daan nga sumpay hin kaagi ha pakli nga ginpara.\nAn mga detalye in mabibilngan ha [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} deletion log].",
        "userpage-userdoesnotexist": "Diri nakarehistro an akawnt han gumaramit nga \"$1\".\nAlayon pagpamuruotbuot kun karuyag mo maghimo/mag-edit hini nga pakli.",
        "grant-createaccount": "Pahimo hin mga account",
        "grant-createeditmovepage": "Paghimo, pagliwat, ngan pagbalhin hin mga pakli",
        "grant-delete": "Pagpara hin mga pakli, mga rebisyon, ngan mga iginsulod ha log",
+       "grant-sendemail": "Igpadara hin email ngadto ha iba nga mga gumaramit",
+       "grant-uploadeditmovefile": "Pagkarga, pagsaliwan, ngan pagbalhin hin mga file",
+       "grant-uploadfile": "Pagkarga hin bag-o nga mga file",
+       "grant-basic": "Mga panguna nga katungod",
+       "grant-viewdeleted": "Kitaa an mga pinanmara nga file ngan pakli",
+       "grant-viewmywatchlist": "Kitaa an imo mga barantayon",
        "newuserlogpage": "Talaan han paghimo hin gumaramit",
        "newuserlogpagetext": "Ini an talaan han mga nagkahihimo nga mga gumaramit.",
        "rightslog": "Talaan hin mga katungod han gumaramit",
+       "rightslogtext": "Ini an talaan han mga pagbag-o han mga katungod hit gumaramit.",
        "action-read": "basaha ini nga pakli",
        "action-edit": "liwata ini nga pakli",
        "action-createpage": "pahimo hin mga pakli",
        "import-rootpage-nosubpage": "Ngaran-lat'ang nga \"$1\" han gamot-pakli in diri natugot hin mga bahin-pakli.",
        "importlogpage": "Talaan hin pan-aangbit",
        "javascripttest-pagetext-skins": "Pagpili hin panit para ha pag-paandar han:",
-       "tooltip-pt-userpage": "An imo pakli hin gumaramit",
-       "tooltip-pt-mytalk": "An imo pakli hin hiruhimangraw",
-       "tooltip-pt-preferences": "An imo mga karuyag",
+       "tooltip-pt-userpage": "{{GENDER:|An imo gumaramit}} nga pakli",
+       "tooltip-pt-mytalk": "{{GENDER:|An imo}} hiruhimangraw nga pakli",
+       "tooltip-pt-preferences": "{{GENDER:|An imo}} mga karuyag",
        "tooltip-pt-watchlist": "An talaan hin mga pakli nga imo ginsisinubay para hin mga kabag-ohan",
-       "tooltip-pt-mycontris": "Talaan han imo mga ámot",
+       "tooltip-pt-mycontris": "Listahan han {{GENDER:|imo}} mga gin-amot",
        "tooltip-pt-login": "Gin-aaghat ka nga mag log-in, pero diri ini ginpipirit.",
        "tooltip-pt-logout": "gawas",
        "tooltip-pt-createaccount": "Ginaag-hat ka nga maghimo hin account ngan maglog-in; pero diri ini mandatorya",
        "tooltip-t-recentchangeslinked": "Mga bag-o nga kabag-ohan ha mga pakli nga nahasumpay tikang hini nga pakli",
        "tooltip-feed-rss": "RSS nga pangarga para hini nga pakli",
        "tooltip-feed-atom": "Atom nga pangarga para hini nga pakli",
-       "tooltip-t-contributions": "Kitaa an talaan hin mga amot hini nga nágámit",
+       "tooltip-t-contributions": "Kitaa an listahan hin mga amot {{GENDER:$1|hinin nga gumaramit}}",
        "tooltip-t-emailuser": "Padad-i hin e-mail ini nga nágámit",
        "tooltip-t-upload": "Pagkarga hin mga paypay",
        "tooltip-t-specialpages": "Talaan hin mga pinaurog nga pakli",
index 7aa6dc8..de1040f 100644 (file)
        "revdelete-uname-unhid": "公开用户名",
        "revdelete-restricted": "应用对管理员的限制",
        "revdelete-unrestricted": "删除对管理员的限制",
-       "logentry-block-block": "$1{{GENDER:$2|å°\81ç¦\81äº\86}}{{GENDER:$4|$3}}ï¼\8cæ\8c\81ç»­æ\97¶é\97´$5 $6",
+       "logentry-block-block": "$1{{GENDER:$2|å°\81ç¦\81äº\86}}{{GENDER:$4|$3}}ï¼\8cæ\9c\9fé\99\90è\87³$5 $6",
        "logentry-block-unblock": "$1{{GENDER:$2|解封了}}{{GENDER:$4|$3}}",
        "logentry-block-reblock": "$1将{{GENDER:$4|$3}}的封禁设置{{GENDER:$2|更改为}}持续时间$5 $6",
        "logentry-suppress-block": "$1{{GENDER:$2|封禁了}}{{GENDER:$4|$3}},持续时间$5 $6",
        "special-characters-group-ipa": "国际音标",
        "special-characters-group-symbols": "符号",
        "special-characters-group-greek": "希腊字母",
+       "special-characters-group-greekextended": "希腊字母扩展",
        "special-characters-group-cyrillic": "西里尔字母",
        "special-characters-group-arabic": "阿拉伯字母",
        "special-characters-group-arabicextended": "扩展阿拉伯字母",
index 181032c..d6dab21 100644 (file)
@@ -59,12 +59,12 @@ $magicWords = [
        'namespace'                 => [ '1', 'NAAMSPASIE', 'NAMESPACE' ],
        'talkspace'                 => [ '1', 'BESPREKINGSBLADSY', 'TALKSPACE' ],
        'fullpagename'              => [ '1', 'VOLBLADSYNAAM', 'FULLPAGENAME' ],
-       'img_thumbnail'             => [ '1', 'duimnael', 'thumbnail', 'thumb' ],
+       'img_thumbnail'             => [ '1', 'duimnael', 'thumb', 'thumbnail' ],
        'img_right'                 => [ '1', 'regs', 'right' ],
        'img_left'                  => [ '1', 'links', 'left' ],
        'img_none'                  => [ '1', 'geen', 'none' ],
        'img_center'                => [ '1', 'senter', 'center', 'centre' ],
-       'img_framed'                => [ '1', 'omraam', 'framed', 'enframed', 'frame' ],
+       'img_framed'                => [ '1', 'omraam', 'frame', 'framed', 'enframed' ],
        'img_frameless'             => [ '1', 'raamloos', 'frameless' ],
        'img_border'                => [ '1', 'raam', 'border' ],
        'img_top'                   => [ '1', 'bo', 'top' ],
index 33b1107..038566b 100644 (file)
@@ -44,7 +44,7 @@ $magicWords = [
        'namespace'                 => [ '1', 'ESPACIODENOMBRES', 'ESPACIODENOMBRE', 'NAMESPACE' ],
        'namespacee'                => [ '1', 'ESPACIODENOMBRESE', 'ESPACIODENOMBREC', 'NAMESPACEE' ],
        'img_right'                 => [ '1', 'dreita', 'derecha', 'dcha', 'der', 'right' ],
-       'img_left'                  => [ '1', 'cucha', 'zurda', 'izquierda', 'izda', 'izq', 'left' ],
+       'img_left'                  => [ '1', 'cucha', 'izquierda', 'zurda', 'izda', 'izq', 'left' ],
        'ns'                        => [ '0', 'EN:', 'EDN:', 'NS:' ],
        'displaytitle'              => [ '1', 'TÍTOL', 'MOSTRARTÍTULO', 'MOSTRARTITULO', 'DISPLAYTITLE' ],
        'currentversion'            => [ '1', 'BERSIÓNAUTUAL', 'BERSIONAUTUAL', 'REVISIÓNACTUAL', 'VERSIONACTUAL', 'VERSIÓNACTUAL', 'CURRENTVERSION' ],
index e76e419..a83b717 100644 (file)
@@ -196,14 +196,14 @@ $magicWords = [
        'subst'                     => [ '0', 'نسخ:', 'SUBST:' ],
        'safesubst'                 => [ '0', 'نسخ_آمن:', 'SAFESUBST:' ],
        'msgnw'                     => [ '0', 'رسالة_بدون_تهيئة:', 'MSGNW:' ],
-       'img_thumbnail'             => [ '1', 'تصغير', 'thumbnail', 'thumb' ],
+       'img_thumbnail'             => [ '1', 'تصغير', 'thumb', 'thumbnail' ],
        'img_manualthumb'           => [ '1', 'تصغير=$1', 'مصغر=$1', 'thumbnail=$1', 'thumb=$1' ],
        'img_right'                 => [ '1', 'يمين', 'right' ],
        'img_left'                  => [ '1', 'يسار', 'left' ],
        'img_none'                  => [ '1', 'بدون', 'بلا', 'none' ],
        'img_width'                 => [ '1', '$1بك', '$1عن', '$1px' ],
        'img_center'                => [ '1', 'مركز', 'center', 'centre' ],
-       'img_framed'                => [ '1', 'إطار', 'بإطار', 'framed', 'enframed', 'frame' ],
+       'img_framed'                => [ '1', 'إطار', 'بإطار', 'frame', 'framed', 'enframed' ],
        'img_frameless'             => [ '1', 'لاإطار', 'frameless' ],
        'img_lang'                  => [ '1', 'لغة=$1', 'lang=$1' ],
        'img_page'                  => [ '1', 'صفحة=$1', 'صفحة_$1', 'page=$1', 'page $1' ],
index 91dc377..0c1b668 100644 (file)
@@ -108,7 +108,7 @@ $magicWords = [
        'pagenamee'                 => [ '1', 'ܟܘܢܝܐ_ܕܦܐܬܐ', 'PAGENAMEE' ],
        'namespace'                 => [ '1', 'ܚܩܠܐ', 'NAMESPACE' ],
        'msg'                       => [ '0', 'ܐܓܪܬܐ:', 'MSG:' ],
-       'img_thumbnail'             => [ '1', 'ܙܥܘܪܬܐ', 'thumbnail', 'thumb' ],
+       'img_thumbnail'             => [ '1', 'ܙܥܘܪܬܐ', 'thumb', 'thumbnail' ],
        'img_manualthumb'           => [ '1', 'ܙܥܘܪܬܐ=$1', 'thumbnail=$1', 'thumb=$1' ],
        'img_right'                 => [ '1', 'ܝܡܝܢܐ', 'right' ],
        'img_left'                  => [ '1', 'ܣܡܠܐ', 'left' ],
index f3377ae..2e69353 100644 (file)
@@ -208,15 +208,15 @@ $magicWords = [
        'subst'                     => [ '0', 'نسخ:', 'إحلال:', 'SUBST:' ],
        'safesubst'                 => [ '0', 'نسخ_آمن:', 'SAFESUBST:' ],
        'msgnw'                     => [ '0', 'رسالة_من_غير_تهيئه:', 'رسالة_بدون_تهيئة:', 'MSGNW:' ],
-       'img_thumbnail'             => [ '1', 'تصغير', 'مصغر', 'thumbnail', 'thumb' ],
+       'img_thumbnail'             => [ '1', 'تصغير', 'مصغر', 'thumb', 'thumbnail' ],
        'img_manualthumb'           => [ '1', 'تصغير=$1', 'مصغر=$1', 'thumbnail=$1', 'thumb=$1' ],
        'img_right'                 => [ '1', 'يمين', 'right' ],
        'img_left'                  => [ '1', 'يسار', 'left' ],
        'img_none'                  => [ '1', 'بدون', 'بلا', 'none' ],
        'img_width'                 => [ '1', '$1بك', '$1عن', '$1px' ],
        'img_center'                => [ '1', 'مركز', 'center', 'centre' ],
-       'img_framed'                => [ '1', 'إطار', 'بإطار', 'framed', 'enframed', 'frame' ],
-       'img_frameless'             => [ '1', 'Ù\85Ù\86_غÙ\8aر_اطار', 'Ù\84اإطار', 'frameless' ],
+       'img_framed'                => [ '1', 'إطار', 'بإطار', 'frame', 'framed', 'enframed' ],
+       'img_frameless'             => [ '1', 'Ù\84اإطار', 'Ù\85Ù\86_غÙ\8aر_اطار', 'frameless' ],
        'img_lang'                  => [ '1', 'لغه=$1', 'لغة=$1', 'lang=$1' ],
        'img_page'                  => [ '1', 'صفح=$1', 'صفحه_$1', 'صفحة=$1', 'صفحة_$1', 'page=$1', 'page $1' ],
        'img_upright'               => [ '1', 'معدول', 'معدول=$1', 'معدول_$1', 'upright', 'upright=$1', 'upright $1' ],
index 840d17b..92ca0f8 100644 (file)
@@ -81,6 +81,6 @@ $magicWords = [
        'img_right'                 => [ '1', 'ساغ', 'راست', 'right' ],
        'img_left'                  => [ '1', 'سول', 'چپ', 'left' ],
        'img_none'                  => [ '1', 'هئچ', 'هیچ', 'none' ],
-       'img_framed'                => [ '1', 'قابیق', 'قاب', 'framed', 'enframed', 'frame' ],
+       'img_framed'                => [ '1', 'قابیق', 'قاب', 'frame', 'framed', 'enframed' ],
 ];
 
index 475ba9b..0b0d42e 100644 (file)
@@ -67,7 +67,7 @@ $magicWords = [
        'img_left'                  => [ '1', 'wala', 'left' ],
        'img_none'                  => [ '1', 'mayò', 'none' ],
        'img_center'                => [ '1', 'sentro', 'tangâ', 'center', 'centre' ],
-       'img_framed'                => [ '1', 'nakakawadro', 'kwadro', 'framed', 'enframed', 'frame' ],
+       'img_framed'                => [ '1', 'nakakawadro', 'kwadro', 'frame', 'framed', 'enframed' ],
        'img_frameless'             => [ '1', 'daing kwadro', 'frameless' ],
        'img_page'                  => [ '1', 'pahina=$1', 'pahina $1', 'page=$1', 'page $1' ],
        'localurl'                  => [ '0', 'LOKALURL', 'LOCALURL:' ],
index c306ba4..9822436 100644 (file)
@@ -34,14 +34,14 @@ $namespaceAliases = [
 ];
 
 $magicWords = [
-       'img_thumbnail'             => [ '1', 'міні', 'мініяцюра', 'thumbnail', 'thumb' ],
+       'img_thumbnail'             => [ '1', 'міні', 'мініяцюра', 'thumb', 'thumbnail' ],
        'img_manualthumb'           => [ '1', 'міні=$1', 'мініяцюра=$1', 'thumbnail=$1', 'thumb=$1' ],
        'img_right'                 => [ '1', 'справа', 'right' ],
        'img_left'                  => [ '1', 'злева', 'left' ],
        'img_none'                  => [ '1', 'няма', 'none' ],
        'img_width'                 => [ '1', '$1пкс', '$1px' ],
        'img_center'                => [ '1', 'цэнтр', 'center', 'centre' ],
-       'img_framed'                => [ '1', 'безрамкі', 'framed', 'enframed', 'frame' ],
+       'img_framed'                => [ '1', 'безрамкі', 'frame', 'framed', 'enframed' ],
 ];
 
 $bookstoreList = [
index d775d25..74b7fe0 100644 (file)
@@ -162,14 +162,14 @@ $magicWords = [
        'msg'                       => [ '0', 'СЪОБЩ:', 'MSG:' ],
        'subst'                     => [ '0', 'ЗАМЕСТ:', 'SUBST:' ],
        'msgnw'                     => [ '0', 'СЪОБЩБУ:', 'MSGNW:' ],
-       'img_thumbnail'             => [ '1', 'мини', 'thumbnail', 'thumb' ],
+       'img_thumbnail'             => [ '1', 'мини', 'thumb', 'thumbnail' ],
        'img_manualthumb'           => [ '1', 'мини=$1', 'thumbnail=$1', 'thumb=$1' ],
-       'img_right'                 => [ '1', 'вдÑ\8fÑ\81но', 'дясно', 'д', 'right' ],
-       'img_left'                  => [ '1', 'влÑ\8fво', 'ляво', 'л', 'left' ],
+       'img_right'                 => [ '1', 'дÑ\8fÑ\81но', 'вдясно', 'д', 'right' ],
+       'img_left'                  => [ '1', 'лÑ\8fво', 'вляво', 'л', 'left' ],
        'img_none'                  => [ '1', 'н', 'none' ],
        'img_width'                 => [ '1', '$1пкс', '$1п', '$1px' ],
-       'img_center'                => [ '1', 'център', 'центр', 'ц', 'center', 'centre' ],
-       'img_framed'                => [ '1', 'рамка', 'врамка', 'framed', 'enframed', 'frame' ],
+       'img_center'                => [ '1', 'център', 'ц', 'центр', 'center', 'centre' ],
+       'img_framed'                => [ '1', 'рамка', 'врамка', 'frame', 'framed', 'enframed' ],
        'img_frameless'             => [ '1', 'безрамка', 'frameless' ],
        'img_border'                => [ '1', 'ръб', 'контур', 'border' ],
        'int'                       => [ '0', 'ВЪТР:', 'INT:' ],
index adeafda..6211da2 100644 (file)
@@ -187,14 +187,14 @@ $magicWords = [
        'msg'                       => [ '0', 'POR:', 'MSG:' ],
        'subst'                     => [ '0', 'ZAMJENI:', 'SUBST:' ],
        'msgnw'                     => [ '0', 'NVPOR:', 'MSGNW:' ],
-       'img_thumbnail'             => [ '1', 'mini', 'thumbnail', 'thumb' ],
+       'img_thumbnail'             => [ '1', 'mini', 'thumb', 'thumbnail' ],
        'img_manualthumb'           => [ '1', 'mini=$1', 'thumbnail=$1', 'thumb=$1' ],
        'img_right'                 => [ '1', 'desno', 'd', 'right' ],
        'img_left'                  => [ '1', 'lijevo', 'l', 'left' ],
        'img_none'                  => [ '1', 'n', 'bez', 'none' ],
        'img_width'                 => [ '1', '$1piksel', '$1p', '$1px' ],
        'img_center'                => [ '1', 'centar', 'c', 'center', 'centre' ],
-       'img_framed'                => [ '1', 'okvir', 'ram', 'framed', 'enframed', 'frame' ],
+       'img_framed'                => [ '1', 'okvir', 'ram', 'frame', 'framed', 'enframed' ],
        'img_frameless'             => [ '1', 'bez_okvira', 'frameless' ],
        'img_page'                  => [ '1', 'stranica=$1', 'stranica $1', 'page=$1', 'page $1' ],
        'img_upright'               => [ '1', 'na_gore', 'na_gore=$1', 'na_gore_$1', 'upright', 'upright=$1', 'upright $1' ],
index d83a364..d442f07 100644 (file)
@@ -221,20 +221,20 @@ $magicWords = [
        'msg'                       => [ '0', 'ХААМ:', 'СООБЩЕНИЕ:', 'СООБЩ:', 'MSG:' ],
        'subst'                     => [ '0', 'ХӀОТТОР:', 'ХӀОТТ:', 'ПОДСТАНОВКА:', 'ПОДСТ:', 'SUBST:' ],
        'msgnw'                     => [ '0', 'ВИКИ_ХААМ_БОЦАШ:', 'СООБЩ_БЕЗ_ВИКИ:', 'MSGNW:' ],
-       'img_thumbnail'             => [ '1', 'жима', 'жимо', 'мини', 'миниаÑ\82Ñ\8eÑ\80а', 'thumbnail', 'thumb' ],
+       'img_thumbnail'             => [ '1', 'мини', 'жима', 'жимо', 'миниаÑ\82Ñ\8eÑ\80а', 'thumb', 'thumbnail' ],
        'img_manualthumb'           => [ '1', 'жима=$1', 'жимо=$1', 'мини=$1', 'миниатюра=$1', 'thumbnail=$1', 'thumb=$1' ],
-       'img_right'                 => [ '1', 'бакъхьа', 'справа', 'right' ],
-       'img_left'                  => [ '1', 'Ñ\85аÑ\80Ñ\86Ñ\85Ñ\8cа', 'Ñ\81лева', 'left' ],
+       'img_right'                 => [ '1', 'справа', 'бакъхьа', 'right' ],
+       'img_left'                  => [ '1', 'Ñ\81лева', 'Ñ\85аÑ\80Ñ\86Ñ\85Ñ\8cа', 'left' ],
        'img_none'                  => [ '1', 'йоцуш', 'без', 'none' ],
        'img_width'                 => [ '1', '$1пкс', '$1px' ],
-       'img_center'                => [ '1', 'Ñ\8eккÑ\8a', 'Ñ\86енÑ\82Ñ\80', 'center', 'centre' ],
-       'img_framed'                => [ '1', 'гурабе', 'обрамить', 'framed', 'enframed', 'frame' ],
-       'img_frameless'             => [ '1', 'гÑ\83Ñ\80абоÑ\86аÑ\88', 'безÑ\80амки', 'frameless' ],
+       'img_center'                => [ '1', 'Ñ\86енÑ\82Ñ\80', 'Ñ\8eккÑ\8a', 'center', 'centre' ],
+       'img_framed'                => [ '1', 'гурабе', 'обрамить', 'frame', 'framed', 'enframed' ],
+       'img_frameless'             => [ '1', 'безÑ\80амки', 'гÑ\83Ñ\80абоÑ\86аÑ\88', 'frameless' ],
        'img_page'                  => [ '1', 'агlо=$1', 'агlо_$1', 'page_$1', 'страница=$1', 'страница_$1', 'страница $1', 'page=$1', 'page $1' ],
        'img_upright'               => [ '1', 'бакъхьалакхо', 'бакъхьалакхо=$1', 'бакъхьалакхо_$1', 'upright_$1', 'сверхусправа', 'сверхусправа=$1', 'сверхусправа_$1', 'сверхусправа $1', 'upright', 'upright=$1', 'upright $1' ],
        'img_border'                => [ '1', 'доза', 'граница', 'border' ],
        'img_baseline'              => [ '1', 'бух', 'основание', 'baseline' ],
-       'img_sub'                   => [ '1', 'бÑ\83Ñ\85а', 'под', 'sub' ],
+       'img_sub'                   => [ '1', 'под', 'бÑ\83Ñ\85а', 'sub' ],
        'img_super'                 => [ '1', 'тӀе', 'над', 'super', 'sup' ],
        'img_top'                   => [ '1', 'лакхахь', 'сверху', 'top' ],
        'img_text_top'              => [ '1', 'лакххьара-йоза', 'текст-сверху', 'text-top' ],
index a010c2c..ad45b66 100644 (file)
@@ -109,12 +109,12 @@ $specialPageAliases = [
 ];
 
 $magicWords = [
-       'img_thumbnail'             => [ '1', 'وێنۆک', 'thumbnail', 'thumb' ],
+       'img_thumbnail'             => [ '1', 'وێنۆک', 'thumb', 'thumbnail' ],
        'img_right'                 => [ '1', 'ڕاست', 'right' ],
        'img_left'                  => [ '1', 'چەپ', 'left' ],
        'img_width'                 => [ '1', '$1پیکسڵ', '$1px' ],
        'img_center'                => [ '1', 'ناوەڕاست', 'center', 'centre' ],
-       'img_framed'                => [ '1', 'چوارچێوە', 'framed', 'enframed', 'frame' ],
+       'img_framed'                => [ '1', 'چوارچێوە', 'frame', 'framed', 'enframed' ],
        'img_frameless'             => [ '1', 'بێچوارچێوە', 'frameless' ],
        'img_border'                => [ '1', 'سنوور', 'border' ],
 ];
index 3cd652b..548b78c 100644 (file)
@@ -72,12 +72,12 @@ $specialPageAliases = [
        'Filepath'                  => [ 'Cesta_k_souboru' ],
        'Import'                    => [ 'Importovat_stránky' ],
        'Invalidateemail'           => [ 'Zneplatnit_e-mail', 'Zrušit_potvrzení_e-mailu' ],
-       'BlockList'                 => [ 'Blokovaní_uživatelé', 'Blokovani_uzivatele' ],
+       'BlockList'                 => [ 'Blokovaní_uživatelé', 'Blokovani_uzivatele', 'Zablokovaní_uživatelé' ],
        'LinkSearch'                => [ 'Hledání_odkazů', 'Hledani_odkazu' ],
        'Listadmins'                => [ 'Seznam_správců', 'Seznam_spravcu' ],
        'Listbots'                  => [ 'Seznam_botů', 'Seznam_botu' ],
        'Listfiles'                 => [ 'Seznam_souborů', 'Seznam_souboru' ],
-       'Listgrouprights'           => [ 'Seznam_uživatelských_práv', 'Seznam_uzivatelskych_prav' ],
+       'Listgrouprights'           => [ 'Práva_uživatelských_skupin', 'Seznam_uživatelských_práv', 'Seznam_uzivatelskych_prav' ],
        'Listredirects'             => [ 'Seznam_přesměrování', 'Seznam_presmerovani' ],
        'Listusers'                 => [ 'Uživatelé', 'Uzivatele', 'Seznam_uživatelů', 'Seznam_uzivatelu' ],
        'Lockdb'                    => [ 'Zamknout_databázi', 'Zamknout_databazi' ],
@@ -92,7 +92,7 @@ $specialPageAliases = [
        'Mostlinkedcategories'      => [ 'Nejpoužívanější_kategorie', 'Nejpouzivanejsi_kategorie' ],
        'Mostlinkedtemplates'       => [ 'Nejpoužívanější_šablony', 'Nejpouzivanejsi_sablony' ],
        'Mostrevisions'             => [ 'Stránky_s_nejvíce_editacemi', 'Stranky_s_nejvice_editacemi', 'Stránky_s_nejvyšším_počtem_editací' ],
-       'Movepage'                  => [ 'Přesunout_stránku' ],
+       'Movepage'                  => [ 'Přesunout_stránku', 'Přejmenovat_stránku' ],
        'Mycontributions'           => [ 'Mé_příspěvky', 'Me_prispevky' ],
        'Mypage'                    => [ 'Moje_stránka', 'Moje_stranka' ],
        'Mytalk'                    => [ 'Moje_diskuse' ],
@@ -191,14 +191,14 @@ $magicWords = [
        'subjectpagenamee'          => [ '1', 'NÁZEVČLÁNKUE', 'SUBJECTPAGENAMEE', 'ARTICLEPAGENAMEE' ],
        'subst'                     => [ '0', 'VLOŽIT:', 'SUBST:' ],
        'msgnw'                     => [ '0', 'VLOŽITNW:', 'MSGNW:' ],
-       'img_thumbnail'             => [ '1', 'náhled', 'thumbnail', 'thumb' ],
+       'img_thumbnail'             => [ '1', 'náhled', 'thumb', 'thumbnail' ],
        'img_manualthumb'           => [ '1', 'náhled=$1', 'thumbnail=$1', 'thumb=$1' ],
        'img_right'                 => [ '1', 'vpravo', 'right' ],
        'img_left'                  => [ '1', 'vlevo', 'left' ],
        'img_none'                  => [ '1', 'žádné', 'none' ],
        'img_width'                 => [ '1', '$1pixelů', '$1px' ],
        'img_center'                => [ '1', 'střed', 'center', 'centre' ],
-       'img_framed'                => [ '1', 'rám', 'framed', 'enframed', 'frame' ],
+       'img_framed'                => [ '1', 'rám', 'frame', 'framed', 'enframed' ],
        'img_frameless'             => [ '1', 'bezrámu', 'frameless' ],
        'img_lang'                  => [ '1', 'jazyk=$1', 'lang=$1' ],
        'img_page'                  => [ '1', 'strana=$1', 'strana_$1', 'page=$1', 'page $1' ],
index 8306461..a569f16 100644 (file)
@@ -53,7 +53,7 @@ $magicWords = [
        'subpagenamee'              => [ '1', 'ENWISDUDALENE', 'SUBPAGENAMEE' ],
        'talkpagename'              => [ '1', 'ENWTUDALENSGWRS', 'TALKPAGENAME' ],
        'talkpagenamee'             => [ '1', 'ENWTUDALENSGWRSE', 'TALKPAGENAMEE' ],
-       'img_thumbnail'             => [ '1', 'ewin_bawd', 'bawd', 'mân-lun', 'thumbnail', 'thumb' ],
+       'img_thumbnail'             => [ '1', 'bawd', 'ewin_bawd', 'mân-lun', 'thumb', 'thumbnail' ],
        'img_manualthumb'           => [ '1', 'mân-lun=$1', 'bawd=$1', 'thumbnail=$1', 'thumb=$1' ],
        'img_right'                 => [ '1', 'de', 'right' ],
        'img_left'                  => [ '1', 'chwith', 'left' ],
index 0a53ff5..5fc359e 100644 (file)
@@ -208,21 +208,21 @@ $magicWords = [
        'subjectpagenamee'          => [ '1', 'HAUPTSEITENNAME_URL', 'VORDERSEITE_URL', 'HAUPTSEITE_URL', 'SUBJECTPAGENAMEE', 'ARTICLEPAGENAMEE' ],
        'subst'                     => [ '0', 'ERS:', 'SUBST:' ],
        'safesubst'                 => [ '0', 'SICHER_ERS:', 'SICHERERS:', 'SAFESUBST:' ],
-       'img_thumbnail'             => [ '1', 'mini', 'miniatur', 'thumbnail', 'thumb' ],
+       'img_thumbnail'             => [ '1', 'miniatur', 'mini', 'thumb', 'thumbnail' ],
        'img_manualthumb'           => [ '1', 'miniatur=$1', 'mini=$1', 'thumbnail=$1', 'thumb=$1' ],
        'img_right'                 => [ '1', 'rechts', 'right' ],
        'img_left'                  => [ '1', 'links', 'left' ],
        'img_none'                  => [ '1', 'ohne', 'none' ],
        'img_center'                => [ '1', 'zentriert', 'center', 'centre' ],
-       'img_framed'                => [ '1', 'gerahmt', 'framed', 'enframed', 'frame' ],
+       'img_framed'                => [ '1', 'gerahmt', 'frame', 'framed', 'enframed' ],
        'img_frameless'             => [ '1', 'rahmenlos', 'frameless' ],
        'img_lang'                  => [ '1', 'sprache=$1', 'lang=$1' ],
        'img_page'                  => [ '1', 'seite=$1', 'seite_$1', 'page=$1', 'page $1' ],
        'img_upright'               => [ '1', 'hochkant', 'hochkant=$1', 'hochkant_$1', 'upright', 'upright=$1', 'upright $1' ],
        'img_border'                => [ '1', 'rand', 'border' ],
        'img_baseline'              => [ '1', 'grundlinie', 'baseline' ],
-       'img_sub'                   => [ '1', 'tiefgestellt', 'tief', 'sub' ],
-       'img_super'                 => [ '1', 'hochgestellt', 'hoch', 'super', 'sup' ],
+       'img_sub'                   => [ '1', 'tief', 'tiefgestellt', 'sub' ],
+       'img_super'                 => [ '1', 'hoch', 'hochgestellt', 'super', 'sup' ],
        'img_top'                   => [ '1', 'oben', 'top' ],
        'img_text_top'              => [ '1', 'text-oben', 'text-top' ],
        'img_middle'                => [ '1', 'mitte', 'middle' ],
index 03cf459..c81fd34 100644 (file)
@@ -224,14 +224,14 @@ $magicWords = [
        'subst'                     => [ '0', 'KOPYAKE', 'ATEBERDE', 'SUBST:' ],
        'safesubst'                 => [ '0', 'EMELEYATEBERDE', 'SAFESUBST:' ],
        'msgnw'                     => [ '0', 'MSCNW:', 'MSGNW:' ],
-       'img_thumbnail'             => [ '1', 'resmoqıckek', 'qıckek', 'thumbnail', 'thumb' ],
+       'img_thumbnail'             => [ '1', 'resmoqıckek', 'qıckek', 'thumb', 'thumbnail' ],
        'img_manualthumb'           => [ '1', 'resmoqıckek=$1', 'qıckek=$1', 'thumbnail=$1', 'thumb=$1' ],
        'img_right'                 => [ '1', 'raşt', 'right' ],
        'img_left'                  => [ '1', 'çep', 'left' ],
        'img_none'                  => [ '1', 'çıniyo', 'none' ],
        'img_width'                 => [ '1', '$1pik', '$1piksel', '$1px' ],
        'img_center'                => [ '1', 'werte', 'miyan', 'center', 'centre' ],
-       'img_framed'                => [ '1', 'çerçeweyın', 'çerçewekerden', 'çerçewe', 'framed', 'enframed', 'frame' ],
+       'img_framed'                => [ '1', 'çerçeweyın', 'çerçewekerden', 'çerçewe', 'frame', 'framed', 'enframed' ],
        'img_frameless'             => [ '1', 'béçerçewe', 'frameless' ],
        'img_lang'                  => [ '1', 'zuwan=1$', 'lang=$1' ],
        'img_page'                  => [ '1', 'pera=$1', 'pera_$1', 'page=$1', 'page $1' ],
@@ -239,7 +239,7 @@ $magicWords = [
        'img_border'                => [ '1', 'sinor', 'border' ],
        'img_baseline'              => [ '1', 'Sinoréerdi', 'baseline' ],
        'img_sub'                   => [ '1', 'anvar', 'sub' ],
-       'img_super'                 => [ '1', 'corén', 'cor', 'super', 'sup' ],
+       'img_super'                 => [ '1', 'cor', 'corén', 'super', 'sup' ],
        'img_top'                   => [ '1', 'gedug', 'top' ],
        'img_text_top'              => [ '1', 'gedug-metin', 'text-top' ],
        'img_middle'                => [ '1', 'merkez', 'middle' ],
index 763f9fa..dd7cd68 100644 (file)
@@ -215,14 +215,14 @@ $magicWords = [
        'msg'                       => [ '0', 'ΚΕΙΜΕΝΟ:', 'MSG:' ],
        'subst'                     => [ '0', 'ΑΛΛΑΓΗ:', 'SUBST:' ],
        'msgnw'                     => [ '0', 'ΑΠΛΟΚΕΙΜΕΝΟ:', 'MSGNW:' ],
-       'img_thumbnail'             => [ '1', 'μικρογραφία', 'μινιατούρα', 'thumbnail', 'thumb' ],
+       'img_thumbnail'             => [ '1', 'μικρογραφία', 'μινιατούρα', 'thumb', 'thumbnail' ],
        'img_manualthumb'           => [ '1', 'μικρογραφία=$1', 'μινιατούρα=$1', 'thumbnail=$1', 'thumb=$1' ],
        'img_right'                 => [ '1', 'δεξιά', 'right' ],
        'img_left'                  => [ '1', 'αριστερά', 'left' ],
        'img_none'                  => [ '1', 'καθόλου', 'none' ],
        'img_width'                 => [ '1', '$1εσ', '$1px' ],
        'img_center'                => [ '1', 'κέντρο', 'center', 'centre' ],
-       'img_framed'                => [ '1', 'με-πλαίσιο', 'framed', 'enframed', 'frame' ],
+       'img_framed'                => [ '1', 'με-πλαίσιο', 'frame', 'framed', 'enframed' ],
        'img_frameless'             => [ '1', 'χωρίς-πλαίσιο', 'frameless' ],
        'img_page'                  => [ '1', 'σελίδα=$1', 'σελίδα_$1', 'page=$1', 'page $1' ],
        'img_upright'               => [ '1', 'κατακόρυφα', 'κατακόρυφα=$1', 'κατακόρυφα_$1', 'upright', 'upright=$1', 'upright $1' ],
index d6ed235..23f2bb0 100644 (file)
@@ -197,9 +197,11 @@ $bookstoreList = [
  * IDs must be valid identifiers, they cannot contain hyphens.
  * CASE is 0 to match all case variants, 1 for case-sensitive
  *
- * Note to translators:
- *   Please include the English words as synonyms.  This allows people
- *   from other wikis to contribute more easily.
+ * Note to localisers:
+ *   - Include the English magic words as synonyms. This allows people from other
+ *     that do no speak the language to contribute more easily.
+ *   - Order the aliases so that common aliases are occur before more rarely
+ *     used aliases. Tools are expected to use the first alias.
  *
  * This array can be modified at runtime with the LanguageGetMagic hook
  */
@@ -265,14 +267,14 @@ $magicWords = [
        'subst'                   => [ 0, 'SUBST:' ],
        'safesubst'               => [ 0, 'SAFESUBST:' ],
        'msgnw'                   => [ 0, 'MSGNW:' ],
-       'img_thumbnail'           => [ 1, 'thumbnail', 'thumb' ],
+       'img_thumbnail'           => [ 1, 'thumb', 'thumbnail' ],
        'img_manualthumb'         => [ 1, 'thumbnail=$1', 'thumb=$1' ],
        'img_right'               => [ 1, 'right' ],
        'img_left'                => [ 1, 'left' ],
        'img_none'                => [ 1, 'none' ],
        'img_width'               => [ 1, '$1px' ],
        'img_center'              => [ 1, 'center', 'centre' ],
-       'img_framed'              => [ 1, 'framed', 'enframed', 'frame' ],
+       'img_framed'              => [ 1, 'frame', 'framed', 'enframed' ],
        'img_frameless'           => [ 1, 'frameless' ],
        'img_lang'                => [ 1, 'lang=$1' ],
        'img_page'                => [ 1, 'page=$1', 'page $1' ],
index 45ea18b..9c6b7be 100644 (file)
@@ -202,14 +202,14 @@ $magicWords = [
        'subst'                     => [ '0', 'ANSTAT:', 'SUBST:' ],
        'safesubst'                 => [ '0', 'SEKURANSTAT:', 'SAFESUBST:' ],
        'msgnw'                     => [ '0', 'NVMSĜ:', 'NVMSGX:', 'MSGNW:' ],
-       'img_thumbnail'             => [ '1', 'eta', 'thumbnail', 'thumb' ],
+       'img_thumbnail'             => [ '1', 'eta', 'thumb', 'thumbnail' ],
        'img_manualthumb'           => [ '1', 'eta=$1', 'thumbnail=$1', 'thumb=$1' ],
        'img_right'                 => [ '1', 'dekstra', 'dekstre', 'right' ],
        'img_left'                  => [ '1', 'maldekstra', 'maldekstre', 'left' ],
-       'img_none'                  => [ '1', 'nenio', 'neniu', 'none' ],
+       'img_none'                  => [ '1', 'neniu', 'nenio', 'none' ],
        'img_width'                 => [ '1', '$1ra', '$1px' ],
        'img_center'                => [ '1', 'centra', 'meza', 'center', 'centre' ],
-       'img_framed'                => [ '1', 'kadro', 'enkadrita', 'enkadrite', 'framed', 'enframed', 'frame' ],
+       'img_framed'                => [ '1', 'kadro', 'enkadrita', 'enkadrite', 'frame', 'framed', 'enframed' ],
        'img_frameless'             => [ '1', 'senkadra', 'frameless' ],
        'img_page'                  => [ '1', 'paĝo=$1', 'paĝo $1', 'pagxo=$1', 'pagxo_$1', 'page=$1', 'page $1' ],
        'img_upright'               => [ '1', 'altdekstre', 'altdekstre=$1', 'altdekstre_$1', 'upright', 'upright=$1', 'upright $1' ],
index a9f1d08..3b7c4bc 100644 (file)
@@ -201,13 +201,13 @@ $magicWords = [
        'subjectpagenamee'          => [ '1', 'NOMBREDEPAGINADETEMAC', 'NOMBREDEPÁGINADETEMAC', 'NOMBREDEPÁGINADEASUNTOC', 'NOMBREDEPAGINADEASUNTOC', 'NOMBREDEPAGINADEARTICULOC', 'NOMBREDEPÁGINADEARTÍCULOC', 'SUBJECTPAGENAMEE', 'ARTICLEPAGENAMEE' ],
        'msg'                       => [ '0', 'MSJ:', 'MSG:' ],
        'subst'                     => [ '0', 'SUST:', 'FIJAR:', 'SUBST:' ],
-       'img_thumbnail'             => [ '1', 'miniaturadeimagen', 'miniatura', 'mini', 'thumbnail', 'thumb' ],
+       'img_thumbnail'             => [ '1', 'miniaturadeimagen', 'miniatura', 'mini', 'thumb', 'thumbnail' ],
        'img_manualthumb'           => [ '1', 'miniaturadeimagen=$1', 'miniatura=$1', 'thumbnail=$1', 'thumb=$1' ],
-       'img_right'                 => [ '1', 'derecha', 'dcha', 'der', 'right' ],
+       'img_right'                 => [ '1', 'derecha', 'der', 'dcha', 'right' ],
        'img_left'                  => [ '1', 'izquierda', 'izda', 'izq', 'left' ],
-       'img_none'                  => [ '1', 'ninguna', 'nada', 'no', 'ninguno', 'none' ],
+       'img_none'                  => [ '1', 'no', 'ninguna', 'ninguno', 'nada', 'none' ],
        'img_center'                => [ '1', 'centro', 'centrado', 'centrada', 'centrar', 'center', 'centre' ],
-       'img_framed'                => [ '1', 'marco', 'enmarcado', 'enmarcada', 'framed', 'enframed', 'frame' ],
+       'img_framed'                => [ '1', 'marco', 'enmarcado', 'enmarcada', 'frame', 'framed', 'enframed' ],
        'img_frameless'             => [ '1', 'sinmarco', 'sin_enmarcar', 'sinenmarcar', 'frameless' ],
        'img_lang'                  => [ '1', 'idioma=$1', 'lang=$1' ],
        'img_page'                  => [ '1', 'pagina=$1', 'página=$1', 'pagina_$1', 'página_$1', 'page=$1', 'page $1' ],
index 681d2ff..8a53d9e 100644 (file)
@@ -204,13 +204,13 @@ $magicWords = [
        'talkpagename'              => [ '1', 'ARUTELUNIMI', 'TALKPAGENAME' ],
        'talkpagenamee'             => [ '1', 'ARUTELUNIMI1', 'TALKPAGENAMEE' ],
        'subst'                     => [ '0', 'ASENDA:', 'SUBST:' ],
-       'img_thumbnail'             => [ '1', 'pisi', 'pisipilt', 'thumbnail', 'thumb' ],
+       'img_thumbnail'             => [ '1', 'pisi', 'pisipilt', 'thumb', 'thumbnail' ],
        'img_manualthumb'           => [ '1', 'pisi=$1', 'pisipilt=$1', 'thumbnail=$1', 'thumb=$1' ],
        'img_right'                 => [ '1', 'paremal', 'right' ],
        'img_left'                  => [ '1', 'vasakul', 'left' ],
        'img_none'                  => [ '1', 'tühi', 'none' ],
        'img_center'                => [ '1', 'keskel', 'center', 'centre' ],
-       'img_framed'                => [ '1', 'raam', 'framed', 'enframed', 'frame' ],
+       'img_framed'                => [ '1', 'raam', 'frame', 'framed', 'enframed' ],
        'img_frameless'             => [ '1', 'raamita', 'frameless' ],
        'img_lang'                  => [ '1', 'keel=$1', 'lang=$1' ],
        'img_page'                  => [ '1', 'lehekülg=$1', 'lehekülg_$1', 'page=$1', 'page $1' ],
index 564445b..eee9793 100644 (file)
@@ -211,14 +211,14 @@ $magicWords = [
        'subst'                     => [ '0', 'جایگزین:', 'جا:', 'SUBST:' ],
        'safesubst'                 => [ '0', 'جایگزین_امن:', 'جام:', 'SAFESUBST:' ],
        'msgnw'                     => [ '0', 'پیغام‌بی‌بسط:', 'MSGNW:' ],
-       'img_thumbnail'             => [ '1', 'بندانگشتی', 'انگشتدان', 'انگشتی', 'thumbnail', 'thumb' ],
+       'img_thumbnail'             => [ '1', 'بندانگشتی', 'انگشتی', 'انگشتدان', 'thumb', 'thumbnail' ],
        'img_manualthumb'           => [ '1', 'بندانگشتی=$1', 'انگشتدان=$1', 'انگشتی=$1', 'thumbnail=$1', 'thumb=$1' ],
        'img_right'                 => [ '1', 'راست', 'right' ],
        'img_left'                  => [ '1', 'چپ', 'left' ],
        'img_none'                  => [ '1', 'هیچ', 'none' ],
        'img_width'                 => [ '1', '$1پیکسل', '$1px' ],
        'img_center'                => [ '1', 'وسط', 'center', 'centre' ],
-       'img_framed'                => [ '1', 'قاب', 'framed', 'enframed', 'frame' ],
+       'img_framed'                => [ '1', 'قاب', 'frame', 'framed', 'enframed' ],
        'img_frameless'             => [ '1', 'بی‌قاب', 'بیقاب', 'بی_قاب', 'frameless' ],
        'img_lang'                  => [ '1', 'زبان=$1', 'lang=$1' ],
        'img_page'                  => [ '1', 'صفحه=$1', 'صفحه_$1', 'page=$1', 'page $1' ],
index 3013ea6..0d1abbd 100644 (file)
@@ -190,13 +190,13 @@ $magicWords = [
        'subjectpagename'           => [ '1', 'AIHESIVUNIMI', 'ARTIKKELISIVUNIMI', 'SUBJECTPAGENAME', 'ARTICLEPAGENAME' ],
        'subjectpagenamee'          => [ '1', 'AIHESIVUNIMIE', 'ARTIKKELISIVUNIMIE', 'SUBJECTPAGENAMEE', 'ARTICLEPAGENAMEE' ],
        'subst'                     => [ '0', 'VASTINE:', 'SUBST:' ],
-       'img_thumbnail'             => [ '1', 'pienoiskuva', 'pienois', 'thumbnail', 'thumb' ],
+       'img_thumbnail'             => [ '1', 'pienoiskuva', 'pienois', 'thumb', 'thumbnail' ],
        'img_manualthumb'           => [ '1', 'pienoiskuva=$1', 'pienois=$1', 'thumbnail=$1', 'thumb=$1' ],
        'img_right'                 => [ '1', 'oikea', 'right' ],
        'img_left'                  => [ '1', 'vasen', 'left' ],
        'img_none'                  => [ '1', 'tyhjä', 'none' ],
-       'img_center'                => [ '1', 'keskitetty', 'keski', 'center', 'centre' ],
-       'img_framed'                => [ '1', 'kehys', 'kehystetty', 'framed', 'enframed', 'frame' ],
+       'img_center'                => [ '1', 'keski', 'keskitetty', 'center', 'centre' ],
+       'img_framed'                => [ '1', 'kehys', 'kehystetty', 'frame', 'framed', 'enframed' ],
        'img_frameless'             => [ '1', 'kehyksetön', 'frameless' ],
        'img_page'                  => [ '1', 'sivu=$1', 'sivu_$1', 'page=$1', 'page $1' ],
        'img_upright'               => [ '1', 'yläoikea', 'yläoikea=$1', 'yläoikea_$1', 'upright', 'upright=$1', 'upright $1' ],
index d69149c..9bb02da 100644 (file)
@@ -196,18 +196,18 @@ $magicWords = [
        'talkpagenamee'             => [ '1', 'NOMPAGEDISCUSSIONX', 'TALKPAGENAMEE' ],
        'subjectpagename'           => [ '1', 'NOMPAGESUJET', 'NOMPAGEARTICLE', 'SUBJECTPAGENAME', 'ARTICLEPAGENAME' ],
        'subjectpagenamee'          => [ '1', 'NOMPAGESUJETX', 'NOMPAGEARTICLEX', 'SUBJECTPAGENAMEE', 'ARTICLEPAGENAMEE' ],
-       'img_thumbnail'             => [ '1', 'vignette', 'thumbnail', 'thumb' ],
+       'img_thumbnail'             => [ '1', 'vignette', 'thumb', 'thumbnail' ],
        'img_manualthumb'           => [ '1', 'vignette=$1', 'thumbnail=$1', 'thumb=$1' ],
        'img_right'                 => [ '1', 'droite', 'right' ],
        'img_left'                  => [ '1', 'gauche', 'left' ],
        'img_none'                  => [ '1', 'néant', 'neant', 'none' ],
        'img_center'                => [ '1', 'centré', 'center', 'centre' ],
-       'img_framed'                => [ '1', 'cadre', 'encadré', 'encadre', 'framed', 'enframed', 'frame' ],
+       'img_framed'                => [ '1', 'cadre', 'encadré', 'encadre', 'frame', 'framed', 'enframed' ],
        'img_frameless'             => [ '1', 'sans_cadre', 'non_encadré', 'non_encadre', 'frameless' ],
        'img_lang'                  => [ '1', 'langue=$1', 'lang=$1' ],
        'img_upright'               => [ '1', 'redresse', 'redresse=$1', 'redresse_$1', 'upright', 'upright=$1', 'upright $1' ],
        'img_border'                => [ '1', 'bordure', 'border' ],
-       'img_baseline'              => [ '1', 'ligne-de-base', 'base', 'baseline' ],
+       'img_baseline'              => [ '1', 'base', 'ligne-de-base', 'baseline' ],
        'img_sub'                   => [ '1', 'indice', 'ind', 'sub' ],
        'img_super'                 => [ '1', 'exposant', 'exp', 'super', 'sup' ],
        'img_top'                   => [ '1', 'haut', 'top' ],
index dd6d1c8..106ba5e 100644 (file)
@@ -196,13 +196,13 @@ $magicWords = [
        'subjectpagenamee'          => [ '1', 'NOM_DE_LA_PÂGE_DU_SUJÈT_URL', 'NOM_DE_LA_PÂGE_DE_L_ARTICLLO_URL', 'NOMPAGESUJETX', 'NOMPAGEARTICLEX', 'SUBJECTPAGENAMEE', 'ARTICLEPAGENAMEE' ],
        'msg'                       => [ '0', 'MSJ:', 'MSG:' ],
        'msgnw'                     => [ '0', 'MSJNV:', 'MSGNW:' ],
-       'img_thumbnail'             => [ '1', 'figura', 'vignette', 'thumbnail', 'thumb' ],
+       'img_thumbnail'             => [ '1', 'figura', 'vignette', 'thumb', 'thumbnail' ],
        'img_manualthumb'           => [ '1', 'figura=$1', 'vignette=$1', 'thumbnail=$1', 'thumb=$1' ],
        'img_right'                 => [ '1', 'drêta', 'droite', 'right' ],
        'img_left'                  => [ '1', 'gôche', 'gauche', 'left' ],
        'img_none'                  => [ '1', 'vouedo', 'néant', 'neant', 'none' ],
        'img_center'                => [ '1', 'centrâ', 'centré', 'center', 'centre' ],
-       'img_framed'                => [ '1', 'encâdrâ', 'câdro', 'cadre', 'encadré', 'encadre', 'framed', 'enframed', 'frame' ],
+       'img_framed'                => [ '1', 'encâdrâ', 'câdro', 'cadre', 'encadré', 'encadre', 'frame', 'framed', 'enframed' ],
        'img_frameless'             => [ '1', 'sen_câdro', 'pas_encâdrâ', 'sans_cadre', 'non_encadré', 'non_encadre', 'frameless' ],
        'img_page'                  => [ '1', 'pâge=$1', 'pâge $1', 'page=$1', 'page $1' ],
        'img_upright'               => [ '1', 'drêt', 'drêt=$1', 'drêt $1', 'redresse', 'redresse=$1', 'redresse $1', 'redresse_$1', 'upright', 'upright=$1', 'upright $1' ],
index 7c00dc7..a508790 100644 (file)
@@ -30,12 +30,12 @@ $magicWords = [
        'msg'                       => [ '0', 'TCHT:', 'MSG:' ],
        'subst'                     => [ '0', 'IONAD:', 'SUBST:' ],
        'msgnw'                     => [ '0', 'TCHTFS:', 'MSGNW:' ],
-       'img_thumbnail'             => [ '1', 'mionsamhail', 'mion', 'thumbnail', 'thumb' ],
+       'img_thumbnail'             => [ '1', 'mion', 'mionsamhail', 'thumb', 'thumbnail' ],
        'img_right'                 => [ '1', 'deas', 'right' ],
        'img_left'                  => [ '1', 'clé', 'left' ],
        'img_none'                  => [ '1', 'faic', 'none' ],
        'img_center'                => [ '1', 'lár', 'center', 'centre' ],
-       'img_framed'                => [ '1', 'fráma', 'frámaithe', 'framed', 'enframed', 'frame' ],
+       'img_framed'                => [ '1', 'fráma', 'frámaithe', 'frame', 'framed', 'enframed' ],
        'int'                       => [ '0', 'INMH:', 'INT:' ],
        'sitename'                  => [ '1', 'AINMANTSUÍMH', 'SITENAME' ],
        'ns'                        => [ '0', 'AS:', 'NS:' ],
index 092226c..8f1d4a7 100644 (file)
@@ -200,17 +200,17 @@ $magicWords = [
        'basepagename'              => [ '1', 'NOMEDAPÁXINABASE', 'NOMEDAPAGINABASE', 'NOMEDAPÁGINABASE', 'BASEPAGENAME' ],
        'talkpagename'              => [ '1', 'NOMEDAPÁXINADECONVERSA', 'NOMEDAPAGINADEDISCUSSAO', 'NOMEDAPÁGINADEDISCUSSÃO', 'TALKPAGENAME' ],
        'subjectpagename'           => [ '1', 'NOMEDAPÁXINADECONTIDO', 'NOMEDAPAGINADECONTEUDO', 'NOMEDAPÁGINADECONTEÚDO', 'SUBJECTPAGENAME', 'ARTICLEPAGENAME' ],
-       'img_thumbnail'             => [ '1', 'miniatura', 'miniaturadaimaxe', 'miniaturadaimagem', 'thumbnail', 'thumb' ],
+       'img_thumbnail'             => [ '1', 'miniatura', 'miniaturadaimagem', 'miniaturadaimaxe', 'thumb', 'thumbnail' ],
        'img_manualthumb'           => [ '1', 'miniatura=$1', 'miniaturadaimaxe=$1', 'miniaturadaimagem=$1', 'thumbnail=$1', 'thumb=$1' ],
        'img_right'                 => [ '1', 'dereita', 'direita', 'right' ],
        'img_left'                  => [ '1', 'esquerda', 'left' ],
        'img_none'                  => [ '1', 'ningún', 'nenhum', 'none' ],
        'img_center'                => [ '1', 'centro', 'center', 'centre' ],
-       'img_framed'                => [ '1', 'conmarco', 'conbordo', 'marco', 'commoldura', 'comborda', 'framed', 'enframed', 'frame' ],
+       'img_framed'                => [ '1', 'conmarco', 'marco', 'conbordo', 'commoldura', 'comborda', 'frame', 'framed', 'enframed' ],
        'img_frameless'             => [ '1', 'senmarco', 'senbordo', 'semmoldura', 'semborda', 'frameless' ],
        'img_page'                  => [ '1', 'páxina=$1', 'páxina_$1', 'página=$1', 'página_$1', 'página $1', 'page=$1', 'page $1' ],
        'img_upright'               => [ '1', 'arribaádereita', 'arribaádereita=$1', 'arribaádereita_$1', 'superiordireito', 'superiordireito=$1', 'superiordireito_$1', 'superiordireito $1', 'upright', 'upright=$1', 'upright $1' ],
-       'img_border'                => [ '1', 'bordo', 'borda', 'border' ],
+       'img_border'                => [ '1', 'borda', 'bordo', 'border' ],
        'img_baseline'              => [ '1', 'liñadebase', 'linhadebase', 'baseline' ],
        'img_top'                   => [ '1', 'arriba', 'acima', 'top' ],
        'img_text_top'              => [ '1', 'texto-arriba', 'text-top' ],
index 217e5cb..9e03942 100644 (file)
@@ -211,18 +211,18 @@ $magicWords = [
        'subst'                     => [ '0', 'ס:', 'SUBST:' ],
        'safesubst'                 => [ '0', 'ס בטוח:', 'SAFESUBST:' ],
        'msgnw'                     => [ '0', 'הכללת מקור', 'MSGNW:' ],
-       'img_thumbnail'             => [ '1', 'ממוזער', 'thumbnail', 'thumb' ],
+       'img_thumbnail'             => [ '1', 'ממוזער', 'thumb', 'thumbnail' ],
        'img_manualthumb'           => [ '1', 'ממוזער=$1', 'thumbnail=$1', 'thumb=$1' ],
        'img_right'                 => [ '1', 'ימין', 'right' ],
        'img_left'                  => [ '1', 'שמאל', 'left' ],
        'img_none'                  => [ '1', 'ללא', 'none' ],
        'img_width'                 => [ '1', '$1 פיקסלים', '$1px' ],
        'img_center'                => [ '1', 'מרכז', 'center', 'centre' ],
-       'img_framed'                => [ '1', '×\9e×\9e×\95ס×\92ר', '×\9eס×\92רת', 'framed', 'enframed', 'frame' ],
+       'img_framed'                => [ '1', '×\9eס×\92רת', '×\9e×\9e×\95ס×\92ר', 'frame', 'framed', 'enframed' ],
        'img_frameless'             => [ '1', 'לא ממוסגר', 'ללא מסגרת', 'frameless' ],
        'img_page'                  => [ '1', 'דף=$1', 'דף $1', 'page=$1', 'page $1' ],
        'img_upright'               => [ '1', 'ימין למעלה', 'ימין למעלה=$1', 'ימין למעלה $1', 'upright', 'upright=$1', 'upright $1' ],
-       'img_border'                => [ '1', 'גבולות', 'גבול', 'border' ],
+       'img_border'                => [ '1', 'גבול', 'גבולות', 'border' ],
        'img_baseline'              => [ '1', 'שורת הבסיס', 'baseline' ],
        'img_sub'                   => [ '1', 'תחתי', 'sub' ],
        'img_super'                 => [ '1', 'עילי', 'super', 'sup' ],
index 30902e3..3f3b007 100644 (file)
@@ -179,19 +179,19 @@ $magicWords = [
        'subst'                     => [ '0', 'प्रति:', 'SUBST:' ],
        'safesubst'                 => [ '0', 'सुरक्षित_प्रति:', 'SAFESUBST:' ],
        'msgnw'                     => [ '0', 'सन्देश_नोविकी:', 'संदेश_नोविकी:', 'MSGNW:' ],
-       'img_thumbnail'             => [ '1', 'अंगूठाकार', 'अंगूठा', 'thumbnail', 'thumb' ],
+       'img_thumbnail'             => [ '1', 'अंगूठाकार', 'अंगूठा', 'thumb', 'thumbnail' ],
        'img_manualthumb'           => [ '1', 'अंगूठाकार=$1', 'अंगूठा=$1', 'thumbnail=$1', 'thumb=$1' ],
        'img_right'                 => [ '1', 'दाएँ', 'दायें', 'दाएं', 'right' ],
-       'img_left'                  => [ '1', 'बाà¤\8fà¤\81', 'बायà¥\87à¤\82', 'बाà¤\8fं', 'left' ],
+       'img_left'                  => [ '1', 'बाà¤\8fà¤\81', 'बाà¤\8fà¤\82', 'बायà¥\87ं', 'left' ],
        'img_none'                  => [ '1', 'कोई_नहीं', 'none' ],
        'img_width'                 => [ '1', '$1पिक्सेल', '$1px' ],
-       'img_center'                => [ '1', 'à¤\95à¥\87नà¥\8dदà¥\8dर', 'à¤\95à¥\87à¤\82द्र', 'केन्द्रित', 'केंद्रित', 'center', 'centre' ],
-       'img_framed'                => [ '1', 'फ़à¥\8dरà¥\87म', 'फà¥\8dरà¥\87म', 'framed', 'enframed', 'frame' ],
+       'img_center'                => [ '1', 'à¤\95à¥\87à¤\82दà¥\8dर', 'à¤\95à¥\87नà¥\8dद्र', 'केन्द्रित', 'केंद्रित', 'center', 'centre' ],
+       'img_framed'                => [ '1', 'फà¥\8dरà¥\87म', 'फ़à¥\8dरà¥\87म', 'frame', 'framed', 'enframed' ],
        'img_frameless'             => [ '1', 'फ़्रेमहीन', 'फ्रेमहीन', 'frameless' ],
        'img_lang'                  => [ '1', 'भाषा=$1', 'lang=$1' ],
        'img_page'                  => [ '1', 'पृष्ठ=$1', 'पृष्ठ_$1', 'page=$1', 'page $1' ],
        'img_upright'               => [ '1', 'खड़ी', 'खड़ी=$1', 'खड़ी_$1', 'upright', 'upright=$1', 'upright $1' ],
-       'img_border'                => [ '1', 'à¤\95िनारा', 'बà¥\89रà¥\8dडर', 'border' ],
+       'img_border'                => [ '1', 'बà¥\89रà¥\8dडर', 'à¤\95िनारा', 'border' ],
        'img_baseline'              => [ '1', 'आधार_रेखा', 'baseline' ],
        'img_sub'                   => [ '1', 'पद', 'sub' ],
        'img_super'                 => [ '1', 'मूर्ध', 'super', 'sup' ],
index ee06560..97cac52 100644 (file)
@@ -181,20 +181,20 @@ $magicWords = [
        'subjectpagename'           => [ '1', 'IMEGLAVNESTRANICE', 'SUBJECTPAGENAME', 'ARTICLEPAGENAME' ],
        'subjectpagenamee'          => [ '1', 'IMEGLAVNESTRANICEE', 'SUBJECTPAGENAMEE', 'ARTICLEPAGENAMEE' ],
        'subst'                     => [ '0', 'ZAMJENA:', 'SUBST:' ],
-       'img_thumbnail'             => [ '1', 'minijatura', 'mini', 'thumbnail', 'thumb' ],
+       'img_thumbnail'             => [ '1', 'mini', 'minijatura', 'thumb', 'thumbnail' ],
        'img_manualthumb'           => [ '1', 'minijatura=$1', 'thumbnail=$1', 'thumb=$1' ],
        'img_right'                 => [ '1', 'desno', 'right' ],
        'img_left'                  => [ '1', 'lijevo', 'left' ],
        'img_none'                  => [ '1', 'ništa', 'none' ],
        'img_center'                => [ '1', 'središte', 'center', 'centre' ],
-       'img_framed'                => [ '1', 'okvir', 'framed', 'enframed', 'frame' ],
+       'img_framed'                => [ '1', 'okvir', 'frame', 'framed', 'enframed' ],
        'img_frameless'             => [ '1', 'bezokvira', 'frameless' ],
        'img_lang'                  => [ '1', 'jezik=$1', 'lang=$1' ],
        'img_page'                  => [ '1', 'stranica=$1', 'stranica $1', 'page=$1', 'page $1' ],
        'img_upright'               => [ '1', 'uspravno=$1', 'uspravno $1', 'upright', 'upright=$1', 'upright $1' ],
        'img_border'                => [ '1', 'obrub', 'border' ],
        'img_baseline'              => [ '1', 'osnovnacrta', 'baseline' ],
-       'img_sub'                   => [ '1', 'potpis', 'ind', 'sub' ],
+       'img_sub'                   => [ '1', 'ind', 'potpis', 'sub' ],
        'img_super'                 => [ '1', 'natpis', 'eks', 'super', 'sup' ],
        'img_top'                   => [ '1', 'vrh', 'top' ],
        'img_text_top'              => [ '1', 'tekst-vrh', 'text-top' ],
index 93a7f5a..6ba075a 100644 (file)
@@ -207,13 +207,13 @@ $magicWords = [
        'subjectpagenamee'          => [ '1', 'SZÓCIKKNEVEE', 'SUBJECTPAGENAMEE', 'ARTICLEPAGENAMEE' ],
        'msg'                       => [ '0', 'ÜZENET:', 'ÜZ:', 'MSG:' ],
        'subst'                     => [ '0', 'BEILLESZT:', 'BEMÁSOL:', 'SUBST:' ],
-       'img_thumbnail'             => [ '1', 'bélyegkép', 'bélyeg', 'miniatűr', 'thumbnail', 'thumb' ],
+       'img_thumbnail'             => [ '1', 'bélyegkép', 'bélyeg', 'miniatűr', 'thumb', 'thumbnail' ],
        'img_manualthumb'           => [ '1', 'bélyegkép=$1', 'bélyeg=$1', 'miniatűr=$1', 'thumbnail=$1', 'thumb=$1' ],
-       'img_right'                 => [ '1', 'jobb', 'jobbra', 'right' ],
-       'img_left'                  => [ '1', 'bal', 'balra', 'left' ],
+       'img_right'                 => [ '1', 'jobbra', 'jobb', 'right' ],
+       'img_left'                  => [ '1', 'balra', 'bal', 'left' ],
        'img_none'                  => [ '1', 'semmi', 'none' ],
-       'img_center'                => [ '1', 'közép', 'középre', 'center', 'centre' ],
-       'img_framed'                => [ '1', 'keretezett', 'keretes', 'keretben', 'kerettel', 'framed', 'enframed', 'frame' ],
+       'img_center'                => [ '1', 'középre', 'közép', 'center', 'centre' ],
+       'img_framed'                => [ '1', 'keretezett', 'keretben', 'keretes', 'kerettel', 'frame', 'framed', 'enframed' ],
        'img_frameless'             => [ '1', 'keretnélküli', 'frameless' ],
        'img_page'                  => [ '1', 'oldal=$1', 'oldal $1', 'page=$1', 'page $1' ],
        'img_upright'               => [ '1', 'fennjobbra', 'fennjobbra=$1', 'fennjobbra $1', 'upright', 'upright=$1', 'upright $1' ],
@@ -224,7 +224,7 @@ $magicWords = [
        'img_top'                   => [ '1', 'fenn', 'fent', 'top' ],
        'img_text_top'              => [ '1', 'szöveg-fenn', 'szöveg-fent', 'text-top' ],
        'img_middle'                => [ '1', 'vközépen', 'vközépre', 'middle' ],
-       'img_bottom'                => [ '1', 'lenn', 'lent', 'bottom' ],
+       'img_bottom'                => [ '1', 'lent', 'lenn', 'bottom' ],
        'img_text_bottom'           => [ '1', 'szöveg-lenn', 'szöveg-lent', 'text-bottom' ],
        'sitename'                  => [ '1', 'WIKINEVE', 'SITENAME' ],
        'ns'                        => [ '0', 'NÉVTÉR:', 'NS:' ],
index 28c3a4d..ab1d198 100644 (file)
@@ -130,14 +130,14 @@ $magicWords = [
        'subjectpagenamee'          => [ '1', 'ՀՈԴՎԱԾԻ_ԷՋԻ_ԱՆՎԱՆՈՒՄԸ_2', 'SUBJECTPAGENAMEE', 'ARTICLEPAGENAMEE' ],
        'msg'                       => [ '0', 'ՀՈՂՈՐԴ՝', 'MSG:' ],
        'msgnw'                     => [ '0', 'ՀՈՂՈՐԴ_ԱՌԱՆՑ_ՎԻՔԻԻ՝', 'MSGNW:' ],
-       'img_thumbnail'             => [ '1', 'մինի', 'thumbnail', 'thumb' ],
+       'img_thumbnail'             => [ '1', 'մինի', 'thumb', 'thumbnail' ],
        'img_manualthumb'           => [ '1', 'մինի=$1', 'thumbnail=$1', 'thumb=$1' ],
        'img_right'                 => [ '1', 'աջից', 'right' ],
        'img_left'                  => [ '1', 'ձախից', 'left' ],
        'img_none'                  => [ '1', 'առանց', 'none' ],
        'img_width'                 => [ '1', '$1փքս', '$1px' ],
        'img_center'                => [ '1', 'կենտրոն', 'center', 'centre' ],
-       'img_framed'                => [ '1', 'շրջափակել', 'framed', 'enframed', 'frame' ],
+       'img_framed'                => [ '1', 'շրջափակել', 'frame', 'framed', 'enframed' ],
        'img_page'                  => [ '1', 'էջը=$1', 'էջ $1', 'page=$1', 'page $1' ],
        'int'                       => [ '0', 'ՆԵՐՔ՝', 'INT:' ],
        'sitename'                  => [ '1', 'ԿԱՅՔԻ_ԱՆՈՒՆԸ', 'SITENAME' ],
index bf1d4d9..5fee306 100644 (file)
@@ -105,13 +105,13 @@ $magicWords = [
        'msg'                       => [ '0', 'PSN:', 'PESAN:', 'MSG:' ],
        'subst'                     => [ '0', 'GNT:', 'GANTI:', 'TUKAR:', 'SUBST:' ],
        'msgnw'                     => [ '0', 'TPL:', 'MSGNW:' ],
-       'img_thumbnail'             => [ '1', 'jmpl', 'jempol', 'mini', 'miniatur', 'thumbnail', 'thumb' ],
+       'img_thumbnail'             => [ '1', 'jmpl', 'jempol', 'mini', 'miniatur', 'thumb', 'thumbnail' ],
        'img_manualthumb'           => [ '1', 'jmpl=$1', 'jempol=$1', 'mini=$1', 'miniatur=$1', 'thumbnail=$1', 'thumb=$1' ],
        'img_right'                 => [ '1', 'ka', 'kanan', 'right' ],
-       'img_left'                  => [ '1', 'ki', 'kiri', 'left' ],
+       'img_left'                  => [ '1', 'kiri', 'ki', 'left' ],
        'img_none'                  => [ '1', 'nir', 'tanpa', 'none' ],
        'img_center'                => [ '1', 'pus', 'pusat', 'center', 'centre' ],
-       'img_framed'                => [ '1', 'bing', 'bingkai', 'framed', 'enframed', 'frame' ],
+       'img_framed'                => [ '1', 'bingkai', 'bing', 'frame', 'framed', 'enframed' ],
        'img_frameless'             => [ '1', 'nirbing', 'tanpabingkai', 'frameless' ],
        'img_lang'                  => [ '1', 'bhs=$1', 'lang=$1' ],
        'img_page'                  => [ '1', 'hal=$1', 'halaman=$1', 'hal_$1', 'halaman_$1', 'page=$1', 'page $1' ],
index 19cb171..8714c72 100644 (file)
@@ -188,13 +188,13 @@ $magicWords = [
        'subpagename'               => [ '1', 'NOMESOTTOPAGINA', 'SUBPAGENAME' ],
        'subpagenamee'              => [ '1', 'NOMESOTTOPAGINAE', 'SUBPAGENAMEE' ],
        'subst'                     => [ '0', 'SOST:', 'SUBST:' ],
-       'img_thumbnail'             => [ '1', 'miniatura', 'min', 'thumbnail', 'thumb' ],
+       'img_thumbnail'             => [ '1', 'miniatura', 'min', 'thumb', 'thumbnail' ],
        'img_manualthumb'           => [ '1', 'miniatura=$1', 'min=$1', 'thumbnail=$1', 'thumb=$1' ],
        'img_right'                 => [ '1', 'destra', 'right' ],
        'img_left'                  => [ '1', 'sinistra', 'left' ],
        'img_none'                  => [ '1', 'nessuno', 'none' ],
        'img_center'                => [ '1', 'centro', 'center', 'centre' ],
-       'img_framed'                => [ '1', 'riquadrato', 'incorniciato', 'originale', 'framed', 'enframed', 'frame' ],
+       'img_framed'                => [ '1', 'riquadrato', 'originale', 'incorniciato', 'frame', 'framed', 'enframed' ],
        'img_frameless'             => [ '1', 'senza_cornice', 'frameless' ],
        'img_page'                  => [ '1', 'pagina=$1', 'pagina_$1', 'page=$1', 'page $1' ],
        'img_upright'               => [ '1', 'verticale', 'verticale=$1', 'verticale_$1', 'upright', 'upright=$1', 'upright $1' ],
index ef20b15..b905345 100644 (file)
@@ -229,19 +229,19 @@ $magicWords = [
        'subst'                     => [ '0', '展開:', '展開:', 'SUBST:' ],
        'safesubst'                 => [ '0', '安全展開:', 'SAFESUBST:' ],
        'msgnw'                     => [ '0', 'ウィキ無効メッセージ:', 'MSGNW:' ],
-       'img_thumbnail'             => [ '1', 'サムネイル', 'thumbnail', 'thumb' ],
+       'img_thumbnail'             => [ '1', 'サムネイル', 'thumb', 'thumbnail' ],
        'img_manualthumb'           => [ '1', '代替画像=$1', 'サムネイル=$1', 'thumbnail=$1', 'thumb=$1' ],
        'img_right'                 => [ '1', '右', 'right' ],
        'img_left'                  => [ '1', '左', 'left' ],
        'img_none'                  => [ '1', 'なし', '無し', 'none' ],
        'img_width'                 => [ '1', '$1ピクセル', '$1px' ],
        'img_center'                => [ '1', '中央', 'center', 'centre' ],
-       'img_framed'                => [ '1', 'フレーム', 'framed', 'enframed', 'frame' ],
+       'img_framed'                => [ '1', 'フレーム', 'frame', 'framed', 'enframed' ],
        'img_frameless'             => [ '1', 'フレームなし', 'frameless' ],
        'img_page'                  => [ '1', 'ページ=$1', 'ページ $1', 'page=$1', 'page $1' ],
        'img_upright'               => [ '1', '右上', 'upright', 'upright=$1', 'upright $1' ],
        'img_border'                => [ '1', '境界', 'ボーダー', 'border' ],
-       'img_baseline'              => [ '1', '下線', 'ベースライン', 'baseline' ],
+       'img_baseline'              => [ '1', 'ベースライン', '下線', 'baseline' ],
        'img_sub'                   => [ '1', '下付き', 'sub' ],
        'img_super'                 => [ '1', '上付き', 'super', 'sup' ],
        'img_top'                   => [ '1', '上端', 'top' ],
index 00b98dc..7c55460 100644 (file)
@@ -126,7 +126,7 @@ $magicWords = [
        'namespace'                 => [ '1', 'სახელთა_სივრცე', 'NAMESPACE' ],
        'fullpagename'              => [ '1', 'გვერდის_სრული_სახელი', 'FULLPAGENAME' ],
        'subst'                     => [ '0', 'მიდგმ:', 'SUBST:' ],
-       'img_thumbnail'             => [ '1', 'მინიატიურა', 'მინი', 'მინიასლი', 'ცეროდენა', 'thumbnail', 'thumb' ],
+       'img_thumbnail'             => [ '1', 'მინი', 'მინიატიურა', 'მინიასლი', 'ცეროდენა', 'thumb', 'thumbnail' ],
        'img_manualthumb'           => [ '1', 'მინიატიურა=$1', 'მინი=$1', 'thumbnail=$1', 'thumb=$1' ],
        'img_right'                 => [ '1', 'მარჯვნივ', 'right' ],
        'img_left'                  => [ '1', 'მარცხნივ', 'left' ],
index 6ae2e88..e970b17 100644 (file)
@@ -215,14 +215,14 @@ $magicWords = [
        'talkpagename'              => [ '1', 'ឈ្មោះទំព័រពិភាក្សា', 'TALKPAGENAME' ],
        'msg'                       => [ '0', 'សារ:', 'MSG:' ],
        'msgnw'                     => [ '0', 'សារមិនមែនជាកូដវិគី:', 'MSGNW:' ],
-       'img_thumbnail'             => [ '1', 'រូបភាពតូច', 'រូបតូច', 'thumbnail', 'thumb' ],
+       'img_thumbnail'             => [ '1', 'រូបភាពតូច', 'រូបតូច', 'thumb', 'thumbnail' ],
        'img_manualthumb'           => [ '1', 'រូបភាពតូច=$1', 'រូបតូច=$1', 'thumbnail=$1', 'thumb=$1' ],
        'img_right'                 => [ '1', 'ស្តាំ', 'ខាងស្តាំ', 'right' ],
        'img_left'                  => [ '1', 'ធ្វេង', 'ខាងធ្វេង', 'left' ],
        'img_none'                  => [ '1', 'ទទេ', 'គ្មាន', 'none' ],
        'img_width'                 => [ '1', '$1ភីកសែល', '$1ភស', '$1px' ],
        'img_center'                => [ '1', 'កណ្តាល', 'center', 'centre' ],
-       'img_framed'                => [ '1', 'ស៊ុម', 'framed', 'enframed', 'frame' ],
+       'img_framed'                => [ '1', 'ស៊ុម', 'frame', 'framed', 'enframed' ],
        'img_frameless'             => [ '1', 'គ្មានស៊ុម', 'frameless' ],
        'img_page'                  => [ '1', 'ទំព័រ=$1', 'ទំព័រ$1', 'page=$1', 'page $1' ],
        'img_top'                   => [ '1', 'ផ្នែកលើ', 'ផ្នែកខាងលើ', 'top' ],
index 09acaad..4a3c15e 100644 (file)
@@ -245,14 +245,14 @@ $magicWords = [
        'subst'                     => [ '0', '풀기:', 'SUBST:' ],
        'safesubst'                 => [ '0', '안전풀기:', 'SAFESUBST:' ],
        'msgnw'                     => [ '0', '위키잘못메시지:', 'MSGNW:' ],
-       'img_thumbnail'             => [ '1', '섬네일', '썸네일', '축소판', 'thumbnail', 'thumb' ],
+       'img_thumbnail'             => [ '1', '섬네일', '썸네일', '축소판', 'thumb', 'thumbnail' ],
        'img_manualthumb'           => [ '1', '섬네일=$1', '썸네일=$1', '축소판=$1', 'thumbnail=$1', 'thumb=$1' ],
        'img_right'                 => [ '1', '오른쪽', 'right' ],
        'img_left'                  => [ '1', '왼쪽', 'left' ],
        'img_none'                  => [ '1', '없음', 'none' ],
        'img_width'                 => [ '1', '$1픽셀', '$1px' ],
        'img_center'                => [ '1', '가운데', 'center', 'centre' ],
-       'img_framed'                => [ '1', '프레임', 'framed', 'enframed', 'frame' ],
+       'img_framed'                => [ '1', '프레임', 'frame', 'framed', 'enframed' ],
        'img_frameless'             => [ '1', '프레임없음', 'frameless' ],
        'img_lang'                  => [ '1', '언어=$1', 'lang=$1' ],
        'img_page'                  => [ '1', '문서=$1', 'page=$1', 'page $1' ],
index f3aea35..b13578e 100644 (file)
@@ -202,7 +202,7 @@ $magicWords = [
        'nogallery'                 => [ '0', '__KEIN_JALLERIE__', '__KEINE_GALERIE__', '__KEINEGALERIE__', '__NOGALLERY__' ],
        'toc'                       => [ '0', '__ENHALLT__', '__INHALTSVERZEICHNIS__', '__TOC__' ],
        'img_right'                 => [ '1', 'rähß', 'räts', 'rechts', 'right' ],
-       'img_left'                  => [ '1', 'lengks', 'lenks', 'links', 'left' ],
+       'img_left'                  => [ '1', 'links', 'lengks', 'lenks', 'left' ],
        'language'                  => [ '0', '#SHPROOCH:', '#SPROCH:', '#SPRACHE:', '#LANGUAGE:' ],
        'hiddencat'                 => [ '1', '__VERSHTOCHE_SAACHJRUPP__', '__VERSTECKTE_KATEGORIE__', '__WARTUNGSKATEGORIE__', '__HIDDENCAT__' ],
 ];
index 45b9bb4..5a0a02b 100644 (file)
@@ -166,13 +166,13 @@ $magicWords = [
        'numberofedits'             => [ '1', 'NIVERAJANJYOW', 'NUMBEROFEDITS' ],
        'pagename'                  => [ '1', 'HANOWANFOLEN', 'PAGENAME' ],
        'fullpagename'              => [ '1', 'HANOWLEUNANFOLEN', 'FULLPAGENAME' ],
-       'img_thumbnail'             => [ '1', 'skeusennik', 'thumbnail', 'thumb' ],
+       'img_thumbnail'             => [ '1', 'skeusennik', 'thumb', 'thumbnail' ],
        'img_manualthumb'           => [ '1', 'skeusennik=$1', 'thumbnail=$1', 'thumb=$1' ],
        'img_right'                 => [ '1', 'dyhow', 'right' ],
        'img_left'                  => [ '1', 'kledh', 'left' ],
        'img_none'                  => [ '1', 'nagonan', 'none' ],
        'img_center'                => [ '1', 'kresel', 'center', 'centre' ],
-       'img_framed'                => [ '1', 'fremys', 'framed', 'enframed', 'frame' ],
+       'img_framed'                => [ '1', 'fremys', 'frame', 'framed', 'enframed' ],
        'img_frameless'             => [ '1', 'hebfram', 'frameless' ],
        'img_page'                  => [ '1', 'folen=$1', 'folen_$1', 'page=$1', 'page $1' ],
        'img_top'                   => [ '1', 'gwartha', 'top' ],
index 77a5b43..2f52faf 100644 (file)
@@ -169,15 +169,15 @@ $magicWords = [
        'namespace'                 => [ '1', 'Nummraum', 'NAMENSRAUM', 'NAMESPACE' ],
        'subjectspace'              => [ '1', 'Haaptnummraum', 'HAUPTNAMENSRAUM', 'SUBJECTSPACE', 'ARTICLESPACE' ],
        'subjectpagename'           => [ '1', 'Haaptsäit', 'HAUPTSEITE', 'HAUPTSEITENNAME', 'VORDERSEITE', 'SUBJECTPAGENAME', 'ARTICLEPAGENAME' ],
-       'img_thumbnail'             => [ '1', 'Miniatur', 'miniatur', 'mini', 'thumbnail', 'thumb' ],
+       'img_thumbnail'             => [ '1', 'miniatur', 'Miniatur', 'mini', 'thumb', 'thumbnail' ],
        'img_right'                 => [ '1', 'riets', 'rechts', 'right' ],
        'img_left'                  => [ '1', 'lénks', 'links', 'left' ],
-       'img_none'                  => [ '1', 'ouni', 'ohne', 'none' ],
+       'img_none'                  => [ '1', 'ohne', 'ouni', 'none' ],
        'img_center'                => [ '1', 'zentréiert', 'zentriert', 'center', 'centre' ],
-       'img_framed'                => [ '1', 'gerummt', 'gerahmt', 'framed', 'enframed', 'frame' ],
-       'img_frameless'             => [ '1', 'net_gerummt', 'rahmenlos', 'frameless' ],
+       'img_framed'                => [ '1', 'gerummt', 'gerahmt', 'frame', 'framed', 'enframed' ],
+       'img_frameless'             => [ '1', 'rahmenlos', 'net_gerummt', 'frameless' ],
        'img_page'                  => [ '1', 'Säit=$1', 'Säit_$1', 'seite=$1', 'seite $1', 'page=$1', 'page $1' ],
-       'img_border'                => [ '1', 'bord', 'rand', 'border' ],
+       'img_border'                => [ '1', 'rand', 'bord', 'border' ],
        'img_top'                   => [ '1', 'uewen', 'oben', 'top' ],
        'img_middle'                => [ '1', 'mëtt', 'mitte', 'middle' ],
        'img_bottom'                => [ '1', 'ënnen', 'unten', 'bottom' ],
index 289bd90..a8e6c77 100644 (file)
@@ -164,7 +164,7 @@ $magicWords = [
        'numberoffiles'             => [ '1', 'FAILŲSKAIČIUS', 'NUMBEROFFILES' ],
        'numberofusers'             => [ '1', 'NAUDOTOJŲSKAIČIUS', 'NUMBEROFUSERS' ],
        'numberofedits'             => [ '1', 'KEITIMŲSKAIČIUS', 'NUMBEROFEDITS' ],
-       'img_thumbnail'             => [ '1', 'miniatiūra', 'mini', 'thumbnail', 'thumb' ],
+       'img_thumbnail'             => [ '1', 'miniatiūra', 'mini', 'thumb', 'thumbnail' ],
        'img_manualthumb'           => [ '1', 'miniatiūra=$1', 'mini=$1', 'thumbnail=$1', 'thumb=$1' ],
        'img_right'                 => [ '1', 'dešinėje', 'right' ],
        'img_left'                  => [ '1', 'kairėje', 'left' ],
index 48720ad..653be83 100644 (file)
@@ -67,7 +67,7 @@ $magicWords = [
        'img_right'                 => [ '1', 'ankavanana', 'droite', 'right' ],
        'img_left'                  => [ '1', 'ankavia', 'gauche', 'left' ],
        'img_none'                  => [ '1', 'tsymisy', 'néant', 'neant', 'none' ],
-       'img_center'                => [ '1', 'ampivoany', 'anivony', 'centré', 'center', 'centre' ],
+       'img_center'                => [ '1', 'centré', 'ampivoany', 'anivony', 'center', 'centre' ],
        'img_page'                  => [ '1', 'pejy $1', 'page=$1', 'page $1' ],
        'img_border'                => [ '1', 'sisiny', 'bordure', 'border' ],
        'img_top'                   => [ '1', 'ambony', 'haut', 'top' ],
index 2d6e83a..99ab0e5 100644 (file)
@@ -81,7 +81,7 @@ $specialPageAliases = [
 ];
 
 $magicWords = [
-       'img_right'                 => [ '1', 'пурла', 'справа', 'right' ],
+       'img_right'                 => [ '1', 'справа', 'пурла', 'right' ],
        'img_left'                  => [ '1', 'шола', 'слева', 'left' ],
        'img_border'                => [ '1', 'чек', 'граница', 'border' ],
        'img_sub'                   => [ '1', 'йымалне', 'под', 'sub' ],
index cc76c61..c15b040 100644 (file)
@@ -252,14 +252,14 @@ $magicWords = [
        'subst'                     => [ '0', 'ЗАМЕНИ:', 'SUBST:' ],
        'safesubst'                 => [ '0', 'БЕЗБЗАМЕНИ', 'SAFESUBST:' ],
        'msgnw'                     => [ '0', 'ИЗВЕШТNW:', 'MSGNW:' ],
-       'img_thumbnail'             => [ '1', 'мини', 'мини-слика', 'thumbnail', 'thumb' ],
+       'img_thumbnail'             => [ '1', 'мини', 'мини-слика', 'thumb', 'thumbnail' ],
        'img_manualthumb'           => [ '1', 'мини-слика=$1', 'мини=$1', 'thumbnail=$1', 'thumb=$1' ],
        'img_right'                 => [ '1', 'десно', 'д', 'right' ],
        'img_left'                  => [ '1', 'лево', 'л', 'left' ],
        'img_none'                  => [ '1', 'н', 'нема', 'none' ],
        'img_width'                 => [ '1', '$1пкс', '$1п', '$1px' ],
        'img_center'                => [ '1', 'центар', 'ц', 'center', 'centre' ],
-       'img_framed'                => [ '1', 'рамка', 'ворамка', 'framed', 'enframed', 'frame' ],
+       'img_framed'                => [ '1', 'рамка', 'ворамка', 'frame', 'framed', 'enframed' ],
        'img_frameless'             => [ '1', 'безрамка', 'frameless' ],
        'img_lang'                  => [ '1', 'јаз=$1', 'lang=$1' ],
        'img_page'                  => [ '1', 'страница=$1', 'страница_$1', 'page=$1', 'page $1' ],
index 0f2c189..2c9542b 100644 (file)
@@ -253,14 +253,14 @@ $magicWords = [
        'subst'                     => [ '0', 'ബദൽ:', 'ഉൾപ്പെടുത്തൽ:', 'SUBST:' ],
        'safesubst'                 => [ '0', 'സംരക്ഷിതബദൽ:', 'സംരക്ഷിതയുൾപ്പെടുത്തൽ:', 'SAFESUBST:' ],
        'msgnw'                     => [ '0', 'മൂലരൂപം:', 'MSGNW:' ],
-       'img_thumbnail'             => [ '1', 'ലഘുചിത്രം', 'ലഘു', 'thumbnail', 'thumb' ],
+       'img_thumbnail'             => [ '1', 'ലഘുചിത്രം', 'ലഘു', 'thumb', 'thumbnail' ],
        'img_manualthumb'           => [ '1', 'ലഘുചിത്രം=$1', 'ലഘു=$1', 'thumbnail=$1', 'thumb=$1' ],
        'img_right'                 => [ '1', 'വലത്ത്‌', 'വലത്‌', 'right' ],
        'img_left'                  => [ '1', 'ഇടത്ത്‌', 'ഇടത്‌', 'left' ],
        'img_none'                  => [ '1', 'ശൂന്യം', 'none' ],
        'img_width'                 => [ '1', '$1ബിന്ദു', '$1px' ],
        'img_center'                => [ '1', 'നടുവിൽ', 'നടുക്ക്‌', 'center', 'centre' ],
-       'img_framed'                => [ '1', 'ചട്ടം', 'ചട്ടത്തിൽ', 'framed', 'enframed', 'frame' ],
+       'img_framed'                => [ '1', 'ചട്ടം', 'ചട്ടത്തിൽ', 'frame', 'framed', 'enframed' ],
        'img_frameless'             => [ '1', 'ചട്ടരഹിതം', 'frameless' ],
        'img_lang'                  => [ '1', 'ഭാഷ=$1', 'lang=$1' ],
        'img_page'                  => [ '1', 'താൾ=$1', 'താൾ_$1', 'page=$1', 'page $1' ],
index 0ea16f9..61fc613 100644 (file)
@@ -223,14 +223,14 @@ $magicWords = [
        'msg'                       => [ '0', 'संदेश:', 'निरोप:', 'MSG:' ],
        'subst'                     => [ '0', 'पर्याय:', 'समाविष्टी:', 'अबाह्य:', 'निरकंसबिंब:', 'कंसत्याग:', 'साचाहिन:', 'साचान्तर:', 'साचापरिस्फोट:', 'साचोद्घाटन:', 'SUBST:' ],
        'msgnw'                     => [ '0', 'संदेशनवा:', 'निरोपनवा:', 'MSGNW:' ],
-       'img_thumbnail'             => [ '1', 'इवलेसे', 'thumbnail', 'thumb' ],
+       'img_thumbnail'             => [ '1', 'इवलेसे', 'thumb', 'thumbnail' ],
        'img_manualthumb'           => [ '1', 'इवलेसे=$1', 'thumbnail=$1', 'thumb=$1' ],
        'img_right'                 => [ '1', 'उजवे', 'right' ],
        'img_left'                  => [ '1', 'डावे', 'left' ],
        'img_none'                  => [ '1', 'कोणतेचनाही', 'नन्ना', 'none' ],
        'img_width'                 => [ '1', '$1अंश', '$1कणी', '$1पक्ष', '$1px' ],
        'img_center'                => [ '1', 'मध्यवर्ती', 'center', 'centre' ],
-       'img_framed'                => [ '1', 'चौकट', 'फ़्रेम', 'framed', 'enframed', 'frame' ],
+       'img_framed'                => [ '1', 'चौकट', 'फ़्रेम', 'frame', 'framed', 'enframed' ],
        'img_frameless'             => [ '1', 'विनाचौकट', 'विनाफ़्रेम', 'frameless' ],
        'img_page'                  => [ '1', 'पान=$1', 'पान_$1', 'page=$1', 'page $1' ],
        'img_upright'               => [ '1', 'उभा', 'उभा=$1', 'उभा_$1', 'upright', 'upright=$1', 'upright $1' ],
index 50ea43b..aad38b7 100644 (file)
@@ -192,13 +192,13 @@ $magicWords = [
        'msg'                       => [ '0', 'MSĠ:', 'MSG:' ],
        'subst'                     => [ '0', 'BIDDEL:', 'SUBST:' ],
        'msgnw'                     => [ '0', 'MSĠEW:', 'MSGNW:' ],
-       'img_thumbnail'             => [ '1', 'daqsminuri', 'minuri', 'thumbnail', 'thumb' ],
+       'img_thumbnail'             => [ '1', 'daqsminuri', 'minuri', 'thumb', 'thumbnail' ],
        'img_manualthumb'           => [ '1', 'daqsminuri=$1', 'minuri=$1', 'thumbnail=$1', 'thumb=$1' ],
        'img_right'                 => [ '1', 'lemin', 'right' ],
        'img_left'                  => [ '1', 'xellug', 'left' ],
        'img_none'                  => [ '1', 'xejn', 'none' ],
        'img_center'                => [ '1', 'nofs', 'ċentrali', 'ċentru', 'center', 'centre' ],
-       'img_framed'                => [ '1', 'tilat', 'b\'tilar', 'tilar', 'framed', 'enframed', 'frame' ],
+       'img_framed'                => [ '1', 'tilat', 'b\'tilar', 'tilar', 'frame', 'framed', 'enframed' ],
        'img_frameless'             => [ '1', 'bla_tilar', 'frameless' ],
        'img_page'                  => [ '1', 'paġna=$1', 'paġna $1', 'page=$1', 'page $1' ],
        'img_upright'               => [ '1', 'wieqaf', 'wieqaf=$1', 'wieqaf $1', 'upright', 'upright=$1', 'upright $1' ],
index 53033c3..20057d5 100644 (file)
@@ -144,12 +144,12 @@ $magicWords = [
        'fullpagename'              => [ '1', 'ЛОПАЛЕМКУВАКАСТО', 'ПОЛНОЕ_НАЗВАНИЕ_СТРАНИЦЫ', 'FULLPAGENAME' ],
        'talkpagename'              => [ '1', 'КОРТАМОЛОПАЛЕМ', 'НАЗВАНИЕ_СТРАНИЦЫ_ОБСУЖДЕНИЯ', 'TALKPAGENAME' ],
        'msg'                       => [ '0', 'ПАЧТЯМНЭ:', 'СООБЩЕНИЕ:', 'СООБЩ:', 'MSG:' ],
-       'img_thumbnail'             => [ '1', 'кенжешка', 'мини', 'миниатюра', 'thumbnail', 'thumb' ],
+       'img_thumbnail'             => [ '1', 'кенжешка', 'мини', 'миниатюра', 'thumb', 'thumbnail' ],
        'img_right'                 => [ '1', 'вить_кедь', 'справа', 'right' ],
        'img_left'                  => [ '1', 'керш_кедь', 'слева', 'left' ],
        'img_none'                  => [ '1', 'вейкеяк_арась', 'без', 'none' ],
        'img_center'                => [ '1', 'куншкасо', 'центр', 'center', 'centre' ],
-       'img_framed'                => [ '1', 'кундсо', 'обрамить', 'framed', 'enframed', 'frame' ],
+       'img_framed'                => [ '1', 'кундсо', 'обрамить', 'frame', 'framed', 'enframed' ],
        'img_frameless'             => [ '1', 'кундовтомо', 'безрамки', 'frameless' ],
        'img_page'                  => [ '1', 'лопа=$1', 'лопа_$1', 'страница=$1', 'страница_$1', 'страница $1', 'page=$1', 'page $1' ],
        'img_top'                   => [ '1', 'верькс', 'сверху', 'top' ],
index 8a18f2f..b04066c 100644 (file)
@@ -72,12 +72,12 @@ $magicWords = [
        'pagename'                  => [ '1', 'SIETNAAM', 'SEITENNAME', 'PAGENAME' ],
        'pagenamee'                 => [ '1', 'SIETNAAME', 'SEITENNAME_URL', 'PAGENAMEE' ],
        'namespace'                 => [ '1', 'NAAMRUUM', 'NAMENSRAUM', 'NAMESPACE' ],
-       'img_thumbnail'             => [ '1', 'duum', 'miniatur', 'mini', 'thumbnail', 'thumb' ],
+       'img_thumbnail'             => [ '1', 'duum', 'miniatur', 'mini', 'thumb', 'thumbnail' ],
        'img_right'                 => [ '1', 'rechts', 'right' ],
        'img_left'                  => [ '1', 'links', 'left' ],
        'img_none'                  => [ '1', 'keen', 'ohne', 'none' ],
-       'img_center'                => [ '1', 'merrn', 'zentriert', 'center', 'centre' ],
-       'img_framed'                => [ '1', 'rahmt', 'gerahmt', 'framed', 'enframed', 'frame' ],
+       'img_center'                => [ '1', 'zentriert', 'merrn', 'center', 'centre' ],
+       'img_framed'                => [ '1', 'gerahmt', 'rahmt', 'frame', 'framed', 'enframed' ],
        'sitename'                  => [ '1', 'STEEDNAAM', 'PROJEKTNAME', 'SITENAME' ],
        'ns'                        => [ '0', 'NR:', 'NS:' ],
        'localurl'                  => [ '0', 'STEEDURL:', 'LOKALE_URL:', 'LOCALURL:' ],
index 9ebb79f..dde2e04 100644 (file)
@@ -171,13 +171,13 @@ $magicWords = [
        'subst'                     => [ '0', 'VERV:', 'SUBST:' ],
        'safesubst'                 => [ '0', 'VEILIGVERV:', 'SAFESUBST:' ],
        'msgnw'                     => [ '0', 'BERICHTNW', 'MSGNW:' ],
-       'img_thumbnail'             => [ '1', 'miniatuur', 'thumbnail', 'thumb' ],
+       'img_thumbnail'             => [ '1', 'miniatuur', 'thumb', 'thumbnail' ],
        'img_manualthumb'           => [ '1', 'miniatuur=$1', 'thumbnail=$1', 'thumb=$1' ],
        'img_right'                 => [ '1', 'rechts', 'right' ],
        'img_left'                  => [ '1', 'links', 'left' ],
        'img_none'                  => [ '1', 'geen', 'none' ],
        'img_center'                => [ '1', 'gecentreerd', 'center', 'centre' ],
-       'img_framed'                => [ '1', 'omkaderd', 'framed', 'enframed', 'frame' ],
+       'img_framed'                => [ '1', 'omkaderd', 'frame', 'framed', 'enframed' ],
        'img_frameless'             => [ '1', 'kaderloos', 'frameless' ],
        'img_lang'                  => [ '1', 'taal=$1', 'lang=$1' ],
        'img_page'                  => [ '1', 'pagina=$1', 'pagina_$1', 'page=$1', 'page $1' ],
index 49987ad..b8ae8d7 100644 (file)
@@ -132,14 +132,14 @@ $magicWords = [
        'subst'                     => [ '0', 'LIMINN:', 'SUBST:' ],
        'safesubst'                 => [ '0', 'TRYGGLIMINN:', 'SAFESUBST:' ],
        'msgnw'                     => [ '0', 'IKWIKMELD:', 'MSGNW:' ],
-       'img_thumbnail'             => [ '1', 'mini', 'miniatyr', 'thumbnail', 'thumb' ],
+       'img_thumbnail'             => [ '1', 'mini', 'miniatyr', 'thumb', 'thumbnail' ],
        'img_manualthumb'           => [ '1', 'mini=$1', 'miniatyr=$1', 'thumbnail=$1', 'thumb=$1' ],
        'img_right'                 => [ '1', 'høgre', 'høyre', 'right' ],
        'img_left'                  => [ '1', 'venstre', 'left' ],
        'img_none'                  => [ '1', 'ingen', 'none' ],
        'img_width'                 => [ '1', '$1pk', '$1px' ],
        'img_center'                => [ '1', 'sentrum', 'center', 'centre' ],
-       'img_framed'                => [ '1', 'ramme', 'ramma', 'framed', 'enframed', 'frame' ],
+       'img_framed'                => [ '1', 'ramme', 'ramma', 'frame', 'framed', 'enframed' ],
        'img_frameless'             => [ '1', 'rammelaus', 'frameless' ],
        'img_lang'                  => [ '1', 'språk=$1', 'lang=$1' ],
        'img_page'                  => [ '1', 'side=$1', 'side_$1', 'page=$1', 'page $1' ],
index 47f6b0a..6c7512b 100644 (file)
@@ -194,13 +194,13 @@ $magicWords = [
        'talkpagenamee'             => [ '1', 'NOMPAGINADISCUSSIONX', 'TALKPAGENAMEE' ],
        'subjectpagename'           => [ '1', 'NOMPAGINASUBJECTE', 'NOMPAGINASUBJÈCTE', 'NOMPAGINAARTICLE', 'SUBJECTPAGENAME', 'ARTICLEPAGENAME' ],
        'subjectpagenamee'          => [ '1', 'NOMPAGINASUBJECTEX', 'NOMPAGINASUBJÈCTEX', 'NOMPAGINAARTICLEX', 'SUBJECTPAGENAMEE', 'ARTICLEPAGENAMEE' ],
-       'img_thumbnail'             => [ '1', 'vinheta', 'thumbnail', 'thumb' ],
+       'img_thumbnail'             => [ '1', 'vinheta', 'thumb', 'thumbnail' ],
        'img_manualthumb'           => [ '1', 'vinheta=$1', 'thumbnail=$1', 'thumb=$1' ],
        'img_right'                 => [ '1', 'drecha', 'dreta', 'right' ],
        'img_left'                  => [ '1', 'esquèrra', 'senèstra', 'gaucha', 'left' ],
        'img_none'                  => [ '1', 'neant', 'nonrés', 'none' ],
        'img_center'                => [ '1', 'centrat', 'center', 'centre' ],
-       'img_framed'                => [ '1', 'quadre', 'enquagrat', 'framed', 'enframed', 'frame' ],
+       'img_framed'                => [ '1', 'quadre', 'enquagrat', 'frame', 'framed', 'enframed' ],
        'img_frameless'             => [ '1', 'sens_quadre', 'frameless' ],
        'img_upright'               => [ '1', 'redreça', 'redreça$1', 'redreça $1', 'upright', 'upright=$1', 'upright $1' ],
        'img_border'                => [ '1', 'bordadura', 'border' ],
index e84c4f6..4f500a7 100644 (file)
@@ -216,7 +216,7 @@ $magicWords = [
        'img_none'                  => [ '1', 'କିଛି_ନୁହେଁ', 'none' ],
        'img_width'                 => [ '1', '$1_ପିକସେଲ', '$1px' ],
        'img_center'                => [ '1', 'କେନ୍ଦ୍ର', 'center', 'centre' ],
-       'img_framed'                => [ '1', 'ଫ୍ରେମକରା', 'framed', 'enframed', 'frame' ],
+       'img_framed'                => [ '1', 'ଫ୍ରେମକରା', 'frame', 'framed', 'enframed' ],
        'img_frameless'             => [ '1', 'ଫ୍ରେମନଥିବା', 'frameless' ],
        'img_border'                => [ '1', 'ବର୍ଡର', 'border' ],
        'img_baseline'              => [ '1', 'ବେସଲାଇନ', 'baseline' ],
index 26b3832..5ba4ff5 100644 (file)
@@ -169,7 +169,7 @@ $magicWords = [
        'numberofpages'             => [ '1', 'ФÆРСТЫНЫМÆЦ', 'КОЛИЧЕСТВО_СТРАНИЦ', 'NUMBEROFPAGES' ],
        'numberofarticles'          => [ '1', 'УАЦТЫНЫМÆЦ', 'КОЛИЧЕСТВО_СТАТЕЙ', 'NUMBEROFARTICLES' ],
        'pagename'                  => [ '1', 'ФАРСЫНОМ', 'НАЗВАНИЕ_СТРАНИЦЫ', 'PAGENAME' ],
-       'img_thumbnail'             => [ '1', 'кÑ\8aаддæÑ\80гонд', 'кÑ\8aаддæÑ\80', 'мини', 'миниаÑ\82Ñ\8eÑ\80а', 'thumbnail', 'thumb' ],
+       'img_thumbnail'             => [ '1', 'мини', 'кÑ\8aаддæÑ\80гонд', 'кÑ\8aаддæÑ\80', 'миниаÑ\82Ñ\8eÑ\80а', 'thumb', 'thumbnail' ],
        'img_manualthumb'           => [ '1', 'къаддæргонд=$1', 'къаддæр=$1', 'мини=$1', 'миниатюра=$1', 'thumbnail=$1', 'thumb=$1' ],
        'img_right'                 => [ '1', 'рахиз', 'справа', 'right' ],
        'img_left'                  => [ '1', 'галиу', 'слева', 'left' ],
index 9c7264d..cfe0345 100644 (file)
@@ -266,13 +266,13 @@ $magicWords = [
        'basepagename'              => [ '1', 'BAZOWANAZWASTRONY', 'BASEPAGENAME' ],
        'talkpagename'              => [ '1', 'NAZWASTRONYDYSKUSJI', 'TALKPAGENAME' ],
        'subst'                     => [ '0', 'podst:', 'SUBST:' ],
-       'img_thumbnail'             => [ '1', 'mały', 'thumbnail', 'thumb' ],
+       'img_thumbnail'             => [ '1', 'mały', 'thumb', 'thumbnail' ],
        'img_manualthumb'           => [ '1', 'mały=$1', 'thumbnail=$1', 'thumb=$1' ],
        'img_right'                 => [ '1', 'prawo', 'right' ],
        'img_left'                  => [ '1', 'lewo', 'left' ],
        'img_none'                  => [ '1', 'brak', 'none' ],
        'img_center'                => [ '1', 'centruj', 'center', 'centre' ],
-       'img_framed'                => [ '1', 'ramka', 'framed', 'enframed', 'frame' ],
+       'img_framed'                => [ '1', 'ramka', 'frame', 'framed', 'enframed' ],
        'img_frameless'             => [ '1', 'bezramki', 'bez_ramki', 'frameless' ],
        'img_page'                  => [ '1', 'strona=$1', 'page=$1', 'page $1' ],
        'img_border'                => [ '1', 'tło', 'border' ],
index 4254b74..18c115b 100644 (file)
@@ -133,7 +133,7 @@ $magicWords = [
        'fullpagename'              => [ '1', 'دمخ_بشپړنوم', 'FULLPAGENAME' ],
        'fullpagenamee'             => [ '1', 'دمخ_بشپړنوم_نښه', 'FULLPAGENAMEE' ],
        'msg'                       => [ '0', 'پیغام:', 'پ:', 'MSG:' ],
-       'img_thumbnail'             => [ '1', 'بټنوک', 'thumbnail', 'thumb' ],
+       'img_thumbnail'             => [ '1', 'بټنوک', 'thumb', 'thumbnail' ],
        'img_right'                 => [ '1', 'ښي', 'right' ],
        'img_left'                  => [ '1', 'کيڼ', 'left' ],
        'img_none'                  => [ '1', 'هېڅ', 'none' ],
index dd6216e..5c3c191 100644 (file)
@@ -269,13 +269,13 @@ $magicWords = [
        'talkpagenamee'             => [ '1', 'NOMEDAPAGINADEDISCUSSAOC', 'NOMEDAPÁGINADEDISCUSSÃOC', 'TALKPAGENAMEE' ],
        'subjectpagename'           => [ '1', 'NOMEDAPAGINADECONTEUDO', 'NOMEDAPÁGINADECONTEÚDO', 'SUBJECTPAGENAME', 'ARTICLEPAGENAME' ],
        'subjectpagenamee'          => [ '1', 'NOMEDAPAGINADECONTEUDOC', 'NOMEDAPÁGINADECONTEÚDOC', 'SUBJECTPAGENAMEE', 'ARTICLEPAGENAMEE' ],
-       'img_thumbnail'             => [ '1', 'miniaturadaimagem', 'miniatura', 'thumbnail', 'thumb' ],
+       'img_thumbnail'             => [ '1', 'miniaturadaimagem', 'miniatura', 'thumb', 'thumbnail' ],
        'img_manualthumb'           => [ '1', 'miniaturadaimagem=$1', 'miniatura=$1', 'thumbnail=$1', 'thumb=$1' ],
        'img_right'                 => [ '1', 'direita', 'right' ],
        'img_left'                  => [ '1', 'esquerda', 'left' ],
        'img_none'                  => [ '1', 'nenhum', 'none' ],
        'img_center'                => [ '1', 'centro', 'center', 'centre' ],
-       'img_framed'                => [ '1', 'commoldura', 'comborda', 'framed', 'enframed', 'frame' ],
+       'img_framed'                => [ '1', 'commoldura', 'comborda', 'frame', 'framed', 'enframed' ],
        'img_frameless'             => [ '1', 'semmoldura', 'semborda', 'frameless' ],
        'img_page'                  => [ '1', 'página=$1', 'página_$1', 'página $1', 'page=$1', 'page $1' ],
        'img_upright'               => [ '1', 'superiordireito', 'superiordireito=$1', 'superiordireito_$1', 'superiordireito $1', 'upright', 'upright=$1', 'upright $1' ],
index 8339ad2..eb1c8d9 100644 (file)
@@ -197,13 +197,13 @@ $magicWords = [
        'msg'                       => [ '0', 'WILLA:', 'MSJ:', 'MSG:' ],
        'subst'                     => [ '0', 'WAKCHAY:', 'SUST:', 'FIJAR:', 'SUBST:' ],
        'msgnw'                     => [ '0', 'WILLAMUSUQ:', 'MSGNW:' ],
-       'img_thumbnail'             => [ '1', 'rikchacha', 'miniaturadeimagen', 'miniatura', 'mini', 'thumbnail', 'thumb' ],
+       'img_thumbnail'             => [ '1', 'rikchacha', 'miniaturadeimagen', 'mini', 'miniatura', 'thumb', 'thumbnail' ],
        'img_manualthumb'           => [ '1', 'rikchacha=$1', 'miniaturadeimagen=$1', 'miniatura=$1', 'thumbnail=$1', 'thumb=$1' ],
        'img_right'                 => [ '1', 'paña', 'alliq', 'derecha', 'dcha', 'der', 'right' ],
        'img_left'                  => [ '1', 'lluqi', 'ichuq', 'izquierda', 'izda', 'izq', 'left' ],
        'img_none'                  => [ '1', 'manaima', 'mana', 'ninguna', 'nada', 'no', 'ninguno', 'none' ],
        'img_center'                => [ '1', 'chawpi', 'centro', 'centrado', 'centrada', 'centrar', 'center', 'centre' ],
-       'img_framed'                => [ '1', 'inchuyuq', 'inchu', 'marco', 'enmarcado', 'enmarcada', 'framed', 'enframed', 'frame' ],
+       'img_framed'                => [ '1', 'inchuyuq', 'inchu', 'marco', 'enmarcado', 'enmarcada', 'frame', 'framed', 'enframed' ],
        'img_frameless'             => [ '1', 'inchunnaq', 'sinmarco', 'sin_embarcar', 'sinenmarcar', 'sin_enmarcar', 'frameless' ],
        'img_page'                  => [ '1', 'panqa=$1', 'pagina=$1', 'página=$1', 'pagina_$1', 'página_$1', 'page=$1', 'page $1' ],
        'img_upright'               => [ '1', 'sayaq', 'sayaq=$1', 'upright', 'upright=$1', 'upright $1' ],
index 8c04de8..7304dbf 100644 (file)
@@ -36,7 +36,7 @@ $namespaceNames = [
 
 $magicWords = [
        'redirect'                  => [ '0', '#RENVIAMENT', '#REDIRECT' ],
-       'img_thumbnail'             => [ '1', 'miniatura', 'thumbnail', 'thumb' ],
+       'img_thumbnail'             => [ '1', 'miniatura', 'thumb', 'thumbnail' ],
        'img_manualthumb'           => [ '1', 'miniatura=$1', 'thumbnail=$1', 'thumb=$1' ],
        'img_upright'               => [ '1', 'sidretg', 'sidretg=$1', 'sidretg_$1', 'upright', 'upright=$1', 'upright $1' ],
 ];
index b1860f9..8b92171 100644 (file)
@@ -86,13 +86,13 @@ $magicWords = [
        'subjectpagenamee'          => [ '1', 'NUMEEPAGINASUBIECT', 'NUMEEPAGINAARTICOL', 'SUBJECTPAGENAMEE', 'ARTICLEPAGENAMEE' ],
        'msg'                       => [ '0', 'MSJ:', 'MSG:' ],
        'msgnw'                     => [ '0', 'MSJNOU:', 'MSGNW:' ],
-       'img_thumbnail'             => [ '1', 'miniatura', 'mini', 'thumbnail', 'thumb' ],
+       'img_thumbnail'             => [ '1', 'miniatura', 'mini', 'thumb', 'thumbnail' ],
        'img_manualthumb'           => [ '1', 'miniatura=$1', 'mini=$1', 'thumbnail=$1', 'thumb=$1' ],
        'img_right'                 => [ '1', 'dreapta', 'right' ],
        'img_left'                  => [ '1', 'stanga', 'left' ],
        'img_none'                  => [ '1', 'nu', 'none' ],
        'img_center'                => [ '1', 'centru', 'center', 'centre' ],
-       'img_framed'                => [ '1', 'cadru', 'framed', 'enframed', 'frame' ],
+       'img_framed'                => [ '1', 'cadru', 'frame', 'framed', 'enframed' ],
        'img_frameless'             => [ '1', 'faracadru', 'frameless' ],
        'img_page'                  => [ '1', 'pagina=$1', 'pagina $1', 'page=$1', 'page $1' ],
        'img_upright'               => [ '1', 'dreaptasus', 'dreaptasus=$1', 'dreaptasus $1', 'upright', 'upright=$1', 'upright $1' ],
index c273654..e1af8f3 100644 (file)
@@ -291,14 +291,14 @@ $magicWords = [
        'subst'                     => [ '0', 'ПОДСТАНОВКА:', 'ПОДСТ:', 'SUBST:' ],
        'safesubst'                 => [ '0', 'ЗАЩПОДСТ:', 'SAFESUBST:' ],
        'msgnw'                     => [ '0', 'СООБЩ_БЕЗ_ВИКИ:', 'MSGNW:' ],
-       'img_thumbnail'             => [ '1', 'мини', 'миниатюра', 'thumbnail', 'thumb' ],
+       'img_thumbnail'             => [ '1', 'мини', 'миниатюра', 'thumb', 'thumbnail' ],
        'img_manualthumb'           => [ '1', 'мини=$1', 'миниатюра=$1', 'thumbnail=$1', 'thumb=$1' ],
        'img_right'                 => [ '1', 'справа', 'right' ],
        'img_left'                  => [ '1', 'слева', 'left' ],
        'img_none'                  => [ '1', 'без', 'none' ],
        'img_width'                 => [ '1', '$1пкс', '$1px' ],
        'img_center'                => [ '1', 'центр', 'center', 'centre' ],
-       'img_framed'                => [ '1', 'обрамить', 'framed', 'enframed', 'frame' ],
+       'img_framed'                => [ '1', 'обрамить', 'frame', 'framed', 'enframed' ],
        'img_frameless'             => [ '1', 'безрамки', 'frameless' ],
        'img_page'                  => [ '1', 'страница=$1', 'страница $1', 'page=$1', 'page $1' ],
        'img_upright'               => [ '1', 'сверхусправа', 'сверхусправа=$1', 'сверхусправа $1', 'upright', 'upright=$1', 'upright $1' ],
index 21b5e63..4a369bd 100644 (file)
@@ -223,14 +223,14 @@ $magicWords = [
        'subjectpagename'           => [ '1', 'विषयपृष्ठनाम', 'लेखपृष्ठनाम', 'SUBJECTPAGENAME', 'ARTICLEPAGENAME' ],
        'msg'                       => [ '0', 'सन्देश:', 'MSG:' ],
        'msgnw'                     => [ '0', 'नूतनसन्देश:', 'MSGNW:' ],
-       'img_thumbnail'             => [ '1', 'लà¤\98à¥\81तà¥\8dतम', 'सà¤\99à¥\8dà¤\95à¥\81à¤\9aितà¤\9aितà¥\8dर', 'à¤\85à¤\99à¥\8dà¤\97à¥\81षà¥\8dठ', 'thumbnail', 'thumb' ],
+       'img_thumbnail'             => [ '1', 'लà¤\98à¥\81तà¥\8dतम', 'à¤\85à¤\99à¥\8dà¤\97à¥\81षà¥\8dठ', 'सà¤\99à¥\8dà¤\95à¥\81à¤\9aितà¤\9aितà¥\8dर', 'thumb', 'thumbnail' ],
        'img_manualthumb'           => [ '1', 'सङ्कुचितचित्र=$1', 'अङ्गुष्ठ=$1', 'लघुत्तमचित्र=$1', 'thumbnail=$1', 'thumb=$1' ],
        'img_right'                 => [ '1', 'दक्षिणत', 'right' ],
        'img_left'                  => [ '1', 'वामतः', 'left' ],
        'img_none'                  => [ '1', 'नैव', 'none' ],
        'img_width'                 => [ '1', '$1पिट', '$1px' ],
        'img_center'                => [ '1', 'मध्य', 'center', 'centre' ],
-       'img_framed'                => [ '1', 'आबन्ध', 'framed', 'enframed', 'frame' ],
+       'img_framed'                => [ '1', 'आबन्ध', 'frame', 'framed', 'enframed' ],
        'img_frameless'             => [ '1', 'निराबन्ध', 'frameless' ],
        'img_page'                  => [ '1', 'पृष्ठ=$1', 'पृष्ठ $1', 'page=$1', 'page $1' ],
        'img_upright'               => [ '1', 'उन्नत', 'उन्नत=$1', 'उन्नत $1', 'upright', 'upright=$1', 'upright $1' ],
index 0208991..e04b004 100644 (file)
@@ -126,7 +126,7 @@ $magicWords = [
        'numberofactiveusers'       => [ '1', 'AKTIIVAGEAVAHEDDJIIDMEARRI', ' AKTIIVAGEAVAHEADDJIMEARRI', ' AKTIIVAGEAVAHEADDJEMEARRI', 'NUMBEROFACTIVEUSERS' ],
        'numberofedits'             => [ '1', 'RIEVDADUSAIDMEARRI', ' RIEVDADUSMEARRI', 'NUMBEROFEDITS' ],
        'subst'                     => [ '0', 'LIIBME:', 'SUBST:' ],
-       'img_thumbnail'             => [ '1', 'mini', 'thumbnail', 'thumb' ],
+       'img_thumbnail'             => [ '1', 'mini', 'thumb', 'thumbnail' ],
        'img_manualthumb'           => [ '1', 'mini=$1', 'thumbnail=$1', 'thumb=$1' ],
        'img_right'                 => [ '1', 'olgeš', 'right' ],
        'img_left'                  => [ '1', 'gurut', 'left' ],
index 3a821e2..fb79237 100644 (file)
@@ -158,14 +158,14 @@ $magicWords = [
        'msg'                       => [ '0', 'POR:', 'MSG:' ],
        'subst'                     => [ '0', 'ZAMJENI:', 'ZAMENI:', 'ZAMJENA:', 'SUBST:' ],
        'msgnw'                     => [ '0', 'NVPOR:', 'MSGNW:' ],
-       'img_thumbnail'             => [ '1', 'minijatura', 'mini', 'thumbnail', 'thumb' ],
+       'img_thumbnail'             => [ '1', 'mini', 'minijatura', 'thumb', 'thumbnail' ],
        'img_manualthumb'           => [ '1', 'minijatura=$1', 'mini=$1', 'thumbnail=$1', 'thumb=$1' ],
        'img_right'                 => [ '1', 'desno', 'right' ],
        'img_left'                  => [ '1', 'lijevo', 'levo', 'left' ],
-       'img_none'                  => [ '1', 'n', 'bez', 'ništa', 'none' ],
-       'img_center'                => [ '1', 'centar', 'središte', 'c', 'center', 'centre' ],
-       'img_framed'                => [ '1', 'okvir', 'ram', 'framed', 'enframed', 'frame' ],
-       'img_frameless'             => [ '1', 'bez_okvira', 'bezokvira', 'frameless' ],
+       'img_none'                  => [ '1', 'n', 'ništa', 'bez', 'none' ],
+       'img_center'                => [ '1', 'centar', 'c', 'središte', 'center', 'centre' ],
+       'img_framed'                => [ '1', 'okvir', 'ram', 'frame', 'framed', 'enframed' ],
+       'img_frameless'             => [ '1', 'bezokvira', 'bez_okvira', 'frameless' ],
        'img_page'                  => [ '1', 'stranica=$1', 'stranica_$1', 'strana=$1', 'strana_$1', 'page=$1', 'page $1' ],
        'img_upright'               => [ '1', 'na_gore', 'na_gore=$1', 'na_gore_$1', 'uspravno', 'uspravno=$1', 'uspravno_$1', 'upright', 'upright=$1', 'upright $1' ],
        'img_border'                => [ '1', 'granica', 'obrub', 'border' ],
index d1ac72f..299fd13 100644 (file)
@@ -220,13 +220,13 @@ $magicWords = [
        'subjectpagenamee'          => [ '1', 'NÁZOVČLÁNKUE', 'SUBJECTPAGENAMEE', 'ARTICLEPAGENAMEE' ],
        'msg'                       => [ '0', 'SPRÁVA:', 'MSG:' ],
        'subst'                     => [ '0', 'NAHR:', 'SUBST:' ],
-       'img_thumbnail'             => [ '1', 'náhľad', 'náhľadobrázka', 'thumbnail', 'thumb' ],
+       'img_thumbnail'             => [ '1', 'náhľad', 'náhľadobrázka', 'thumb', 'thumbnail' ],
        'img_right'                 => [ '1', 'vpravo', 'right' ],
        'img_left'                  => [ '1', 'vľavo', 'left' ],
        'img_none'                  => [ '1', 'žiadny', 'none' ],
        'img_width'                 => [ '1', '$1bod', '$1px' ],
        'img_center'                => [ '1', 'stred', 'center', 'centre' ],
-       'img_framed'                => [ '1', 'rám', 'framed', 'enframed', 'frame' ],
+       'img_framed'                => [ '1', 'rám', 'frame', 'framed', 'enframed' ],
        'img_border'                => [ '1', 'okraj', 'border' ],
        'sitename'                  => [ '1', 'NÁZOVLOKALITY', 'SITENAME' ],
        'ns'                        => [ '0', 'MP:', 'NS:' ],
index c434309..7599bc2 100644 (file)
@@ -119,14 +119,14 @@ $magicWords = [
        'forcetoc'                  => [ '0', '__VSILIKAZALOVSEBINE__', '__FORCETOC__' ],
        'toc'                       => [ '0', '__POGLAVJE__', '__TOC__' ],
        'noeditsection'             => [ '0', '__BREZUREJANJARAZDELKOV__', '__NOEDITSECTION__' ],
-       'img_thumbnail'             => [ '1', 'sličica', 'thumbnail', 'thumb' ],
+       'img_thumbnail'             => [ '1', 'sličica', 'thumb', 'thumbnail' ],
        'img_manualthumb'           => [ '1', 'sličica=$1', 'thumbnail=$1', 'thumb=$1' ],
        'img_right'                 => [ '1', 'desno', 'right' ],
        'img_left'                  => [ '1', 'levo', 'left' ],
        'img_none'                  => [ '1', 'brez', 'none' ],
        'img_width'                 => [ '1', '$1_pik', '$1px' ],
        'img_center'                => [ '1', 'sredina', 'sredinsko', 'center', 'centre' ],
-       'img_framed'                => [ '1', 'okvir', 'okvirjeno', 'framed', 'enframed', 'frame' ],
+       'img_framed'                => [ '1', 'okvir', 'okvirjeno', 'frame', 'framed', 'enframed' ],
        'img_frameless'             => [ '1', 'brezokvirja', 'frameless' ],
        'img_page'                  => [ '1', 'stran=$1', 'm_stran $1', 'page=$1', 'page $1' ],
        'img_upright'               => [ '1', 'zgorajdesno', 'zgorajdesno=$1', 'zgorajdesno $1', 'upright', 'upright=$1', 'upright $1' ],
index 20e3978..a0d88d4 100644 (file)
@@ -166,13 +166,13 @@ $magicWords = [
        'talkpagename'              => [ '1', 'EMRIIFAQESSËDISKUTIMIT', 'TALKPAGENAME' ],
        'talkpagenamee'             => [ '1', 'EMRIIFAQESSËDISKUTIMITE', 'TALKPAGENAMEE' ],
        'subst'                     => [ '0', 'ZËVN', 'SUBST:' ],
-       'img_thumbnail'             => [ '1', 'parapamje', 'pamje', 'thumbnail', 'thumb' ],
+       'img_thumbnail'             => [ '1', 'parapamje', 'pamje', 'thumb', 'thumbnail' ],
        'img_manualthumb'           => [ '1', 'parapamje=$1', 'pamje=$1', 'thumbnail=$1', 'thumb=$1' ],
        'img_right'                 => [ '1', 'djathtas', 'right' ],
        'img_left'                  => [ '1', 'majtas', 'left' ],
        'img_none'                  => [ '1', 's\'ka', 'none' ],
        'img_center'                => [ '1', 'qendër', 'qendrore', 'center', 'centre' ],
-       'img_framed'                => [ '1', 'i_kornizuar', 'pa_kornizë', 'kornizë', 'framed', 'enframed', 'frame' ],
+       'img_framed'                => [ '1', 'i_kornizuar', 'pa_kornizë', 'kornizë', 'frame', 'framed', 'enframed' ],
        'img_page'                  => [ '1', 'faqja=$1', 'faqja $1', 'page=$1', 'page $1' ],
        'img_upright'               => [ '1', 'lartdjathtas', 'lartdjathtas=$1', 'lartdjathtas $1', 'upright', 'upright=$1', 'upright $1' ],
        'img_border'                => [ '1', 'kufi', 'border' ],
index 0815c71..8819be6 100644 (file)
@@ -249,13 +249,13 @@ $magicWords = [
        'msg'                       => [ '0', 'MED:', 'MSG:' ],
        'subst'                     => [ '0', 'BYT:', 'SUBST:' ],
        'msgnw'                     => [ '0', 'MEDNW:', 'MSGNW:' ],
-       'img_thumbnail'             => [ '1', 'miniatyr', 'mini', 'thumbnail', 'thumb' ],
+       'img_thumbnail'             => [ '1', 'miniatyr', 'mini', 'thumb', 'thumbnail' ],
        'img_manualthumb'           => [ '1', 'miniatyr=$1', 'mini=$1', 'thumbnail=$1', 'thumb=$1' ],
        'img_right'                 => [ '1', 'höger', 'right' ],
        'img_left'                  => [ '1', 'vänster', 'left' ],
        'img_none'                  => [ '1', 'ingen', 'none' ],
        'img_center'                => [ '1', 'centrerad', 'center', 'centre' ],
-       'img_framed'                => [ '1', 'inramad', 'ram', 'framed', 'enframed', 'frame' ],
+       'img_framed'                => [ '1', 'ram', 'inramad', 'frame', 'framed', 'enframed' ],
        'img_frameless'             => [ '1', 'ramlös', 'frameless' ],
        'img_page'                  => [ '1', 'sida=$1', 'sida $1', 'page=$1', 'page $1' ],
        'img_upright'               => [ '1', 'stående', 'stående=$1', 'stående $1', 'upright', 'upright=$1', 'upright $1' ],
index 747f1e8..9e07263 100644 (file)
@@ -252,14 +252,14 @@ $magicWords = [
        'subst'                     => [ '0', 'YK:', 'YERİNEKOY:', 'KOPYALA:', 'AKTAR:', 'YAPIŞTIR:', 'SUBST:' ],
        'safesubst'                 => [ '0', 'GÜVENLİYERİNEKOY:', 'GÜVENLİKOPYALA:', 'GÜVENLİAKTAR:', 'GÜVENLİYAPIŞTIR:', 'SAFESUBST:' ],
        'msgnw'                     => [ '0', 'MSJYN:', 'İLTYN:', 'MSGNW:' ],
-       'img_thumbnail'             => [ '1', 'küçükresim', 'küçük', 'thumbnail', 'thumb' ],
+       'img_thumbnail'             => [ '1', 'küçükresim', 'küçük', 'thumb', 'thumbnail' ],
        'img_manualthumb'           => [ '1', 'küçükresim=$1', 'küçük=$1', 'thumbnail=$1', 'thumb=$1' ],
        'img_right'                 => [ '1', 'sağ', 'right' ],
        'img_left'                  => [ '1', 'sol', 'left' ],
        'img_none'                  => [ '1', 'yok', 'none' ],
        'img_width'                 => [ '1', '$1pik', '$1piksel', '$1px' ],
        'img_center'                => [ '1', 'orta', 'center', 'centre' ],
-       'img_framed'                => [ '1', 'çerçeveli', 'çerçeve', 'framed', 'enframed', 'frame' ],
+       'img_framed'                => [ '1', 'çerçeveli', 'çerçeve', 'frame', 'framed', 'enframed' ],
        'img_frameless'             => [ '1', 'çerçevesiz', 'frameless' ],
        'img_page'                  => [ '1', 'sayfa=$1', 'sayfa $1', 'page=$1', 'page $1' ],
        'img_upright'               => [ '1', 'dikey', 'dikey=$1', 'dikey $1', 'upright', 'upright=$1', 'upright $1' ],
@@ -267,7 +267,7 @@ $magicWords = [
        'img_baseline'              => [ '1', 'tabançizgisi', 'altçizgi', 'baseline' ],
        'img_sub'                   => [ '1', 'alt', 'sub' ],
        'img_super'                 => [ '1', 'üst', 'üs', 'super', 'sup' ],
-       'img_top'                   => [ '1', 'tavan', 'tepe', 'top' ],
+       'img_top'                   => [ '1', 'tepe', 'tavan', 'top' ],
        'img_text_top'              => [ '1', 'metin-tavan', 'metin-tepe', 'text-top' ],
        'img_middle'                => [ '1', 'merkez', 'middle' ],
        'img_bottom'                => [ '1', 'taban', 'bottom' ],
index d3bca66..369e0be 100644 (file)
@@ -274,14 +274,14 @@ $magicWords = [
        'subst'                     => [ '0', 'ПІДСТ:', 'ПІДСТАНОВКА:', 'ПОДСТАНОВКА:', 'ПОДСТ:', 'SUBST:' ],
        'safesubst'                 => [ '0', 'БЕЗПЕЧНА_ПІДСТАНОВКА:', 'ЗАЩПОДСТ:', 'SAFESUBST:' ],
        'msgnw'                     => [ '0', 'ПОВІД_БЕЗ_ВІКІ:', 'СООБЩ_БЕЗ_ВИКИ:', 'MSGNW:' ],
-       'img_thumbnail'             => [ '1', 'міні', 'мініатюра', 'мини', 'миниатюра', 'thumbnail', 'thumb' ],
+       'img_thumbnail'             => [ '1', 'міні', 'мини', 'мініатюра', 'миниатюра', 'thumb', 'thumbnail' ],
        'img_manualthumb'           => [ '1', 'міні=$1', 'мініатюра=$1', 'мини=$1', 'миниатюра=$1', 'thumbnail=$1', 'thumb=$1' ],
        'img_right'                 => [ '1', 'праворуч', 'справа', 'right' ],
        'img_left'                  => [ '1', 'ліворуч', 'слева', 'left' ],
        'img_none'                  => [ '1', 'без', 'none' ],
        'img_width'                 => [ '1', '$1пкс', '$1px' ],
        'img_center'                => [ '1', 'центр', 'center', 'centre' ],
-       'img_framed'                => [ '1', 'обрамити', 'рамка', 'обрамить', 'framed', 'enframed', 'frame' ],
+       'img_framed'                => [ '1', 'обрамити', 'рамка', 'обрамить', 'frame', 'framed', 'enframed' ],
        'img_frameless'             => [ '1', 'безрамки', 'frameless' ],
        'img_page'                  => [ '1', 'сторінка=$1', 'сторінка_$1', 'страница=$1', 'страница $1', 'page=$1', 'page $1' ],
        'img_upright'               => [ '1', 'зверхуправоруч', 'зверхуправоруч=$1', 'зверхуправоруч_$1', 'сверхусправа', 'сверхусправа=$1', 'сверхусправа $1', 'upright', 'upright=$1', 'upright $1' ],
index f70080b..f9da1ed 100644 (file)
@@ -152,7 +152,7 @@ $magicWords = [
        'msg'                       => [ '0', 'پیغام:', 'MSG:' ],
        'subst'                     => [ '0', 'جا:', 'نقل:', 'SUBST:' ],
        'safesubst'                 => [ '0', 'محفوظ_جا:', 'محفوظ_نقل:', 'SAFESUBST:' ],
-       'img_thumbnail'             => [ '1', 'تصغیر', 'thumbnail', 'thumb' ],
+       'img_thumbnail'             => [ '1', 'تصغیر', 'thumb', 'thumbnail' ],
        'img_right'                 => [ '1', 'دائیں', 'right' ],
        'img_left'                  => [ '1', 'بائیں', 'left' ],
        'img_center'                => [ '1', 'درمیان', 'center', 'centre' ],
index 593f61a..201a677 100644 (file)
@@ -220,13 +220,13 @@ $magicWords = [
        'subst'                     => [ '0', 'THẾ:', 'SUBST:' ],
        'safesubst'                 => [ '0', 'THẾ_AN_TOÀN:', 'SAFESUBST:' ],
        'msgnw'                     => [ '0', 'NHẮN_MỚI:', 'NHẮNMỚI:', 'MSGNW:' ],
-       'img_thumbnail'             => [ '1', 'nhỏ', 'thumbnail', 'thumb' ],
+       'img_thumbnail'             => [ '1', 'nhỏ', 'thumb', 'thumbnail' ],
        'img_manualthumb'           => [ '1', 'nhỏ=$1', 'thumbnail=$1', 'thumb=$1' ],
        'img_right'                 => [ '1', 'phải', 'right' ],
        'img_left'                  => [ '1', 'trái', 'left' ],
        'img_none'                  => [ '1', 'không', 'none' ],
        'img_center'                => [ '1', 'giữa', 'center', 'centre' ],
-       'img_framed'                => [ '1', 'khung', 'framed', 'enframed', 'frame' ],
+       'img_framed'                => [ '1', 'khung', 'frame', 'framed', 'enframed' ],
        'img_frameless'             => [ '1', 'không_khung', 'frameless' ],
        'img_lang'                  => [ '1', 'tiếng=$1', 'ngôn_ngữ=$1', 'lang=$1' ],
        'img_page'                  => [ '1', 'trang=$1', 'trang_$1', 'page=$1', 'page $1' ],
index 074bf54..edc860e 100644 (file)
@@ -169,7 +169,7 @@ $magicWords = [
        'subpagename'               => [ '1', 'אונטערבלאטנאמען', 'שם דף המשנה', 'SUBPAGENAME' ],
        'talkpagename'              => [ '1', 'רעדנבלאטנאמען', 'שם דף השיחה', 'TALKPAGENAME' ],
        'subst'                     => [ '0', 'ס:', 'SUBST:' ],
-       'img_thumbnail'             => [ '1', 'קליין', 'ממוזער', 'thumbnail', 'thumb' ],
+       'img_thumbnail'             => [ '1', 'קליין', 'ממוזער', 'thumb', 'thumbnail' ],
        'img_manualthumb'           => [ '1', 'קליין=$1', 'ממוזער=$1', 'thumbnail=$1', 'thumb=$1' ],
        'img_right'                 => [ '1', 'רעכטס', 'ימין', 'right' ],
        'img_left'                  => [ '1', 'לינקס', 'שמאל', 'left' ],
index 9abc297..848c2f7 100644 (file)
@@ -79,11 +79,16 @@ class CreateAndPromote extends Maintenance {
 
                $groups = array_filter( self::$permitRoles, [ $this, 'hasOption' ] );
                if ( $this->hasOption( 'custom-groups' ) ) {
+                       $allGroups = array_flip( User::getAllGroups() );
                        $customGroupsText = $this->getOption( 'custom-groups' );
                        if ( $customGroupsText !== '' ) {
                                $customGroups = explode( ',', $customGroupsText );
                                foreach ( $customGroups as $customGroup ) {
-                                       $groups[] = trim( $customGroup );
+                                       if ( isset( $allGroups[$customGroup] ) ) {
+                                               $groups[] = trim( $customGroup );
+                                       } else {
+                                               $this->output( "$customGroup is not a valid group, ignoring!\n" );
+                                       }
                                }
                        }
                }
index 157a323..b1e4fa9 100644 (file)
@@ -42,8 +42,8 @@ class ExportSites extends Maintenance {
 
                $exporter = new SiteExporter( $handle );
 
-               $sites = SiteSQLStore::newInstance()->getSites( 'recache' );
-               $exporter->exportSites( $sites );
+               $siteLookup = \MediaWiki\MediaWikiServices::getInstance()->getSiteLookup();
+               $exporter->exportSites( $siteLookup->getSites() );
 
                fclose( $handle );
 
index daec7b6..5722344 100644 (file)
@@ -30,7 +30,8 @@ class ImportSites extends Maintenance {
        public function execute() {
                $file = $this->getArg( 0 );
 
-               $importer = new SiteImporter( SiteSQLStore::newInstance() );
+               $siteStore = \MediaWiki\MediaWikiServices::getInstance()->getSiteStore();
+               $importer = new SiteImporter( $siteStore );
                $importer->setExceptionCallback( [ $this, 'reportException' ] );
 
                $importer->importFromFile( $file );
index c4dfd8f..60f94a5 100644 (file)
@@ -70,7 +70,7 @@ class McTest extends Maintenance {
                                $server # output channel
                        );
 
-                       $mcc = new MemCachedClientforWiki( [
+                       $mcc = new MemcachedClient( [
                                'persistant' => true,
                                'timeout' => $wgMemCachedTimeout
                        ] );
index 044bafd..230e86d 100644 (file)
@@ -38,7 +38,7 @@ class RebuildSitesCache extends Maintenance {
 
        public function execute() {
                $sitesCacheFileBuilder = new SitesCacheFileBuilder(
-                       new DBSiteStore(),
+                       \MediaWiki\MediaWikiServices::getInstance()->getSiteLookup(),
                        $this->getCacheFile()
                );
 
index 0f3d70b..6992de1 100644 (file)
@@ -436,6 +436,8 @@ return [
                        'ca' => 'resources/lib/jquery.ui/i18n/jquery.ui.datepicker-ca.js',
                        'cs' => 'resources/lib/jquery.ui/i18n/jquery.ui.datepicker-cs.js',
                        'da' => 'resources/lib/jquery.ui/i18n/jquery.ui.datepicker-da.js',
+                       'de-at' => 'resources/lib/jquery.ui/i18n/jquery.ui.datepicker-de-AT.js',
+                       'de-ch' => 'resources/lib/jquery.ui/i18n/jquery.ui.datepicker-de-CH.js',
                        'de' => 'resources/lib/jquery.ui/i18n/jquery.ui.datepicker-de.js',
                        'el' => 'resources/lib/jquery.ui/i18n/jquery.ui.datepicker-el.js',
                        'en-au' => 'resources/lib/jquery.ui/i18n/jquery.ui.datepicker-en-AU.js',
diff --git a/resources/lib/jquery.ui/i18n/jquery.ui.datepicker-de-AT.js b/resources/lib/jquery.ui/i18n/jquery.ui.datepicker-de-AT.js
new file mode 100644 (file)
index 0000000..456c3a0
--- /dev/null
@@ -0,0 +1,22 @@
+/* Austrian German initialisation for the jQuery UI date picker plugin. */
+jQuery(function($){
+       $.datepicker.regional['de-AT'] = {
+               closeText: 'schließen',
+               prevText: '&#x3C;zurück',
+               nextText: 'Vor&#x3E;',
+               currentText: 'heute',
+               monthNames: ['Jänner','Februar','März','April','Mai','Juni',
+               'Juli','August','September','Oktober','November','Dezember'],
+               monthNamesShort: ['Jän','Feb','Mär','Apr','Mai','Jun',
+               'Jul','Aug','Sep','Okt','Nov','Dez'],
+               dayNames: ['Sonntag','Montag','Dienstag','Mittwoch','Donnerstag','Freitag','Samstag'],
+               dayNamesShort: ['So','Mo','Di','Mi','Do','Fr','Sa'],
+               dayNamesMin: ['So','Mo','Di','Mi','Do','Fr','Sa'],
+               weekHeader: 'KW',
+               dateFormat: 'dd.mm.yy',
+               firstDay: 1,
+               isRTL: false,
+               showMonthAfterYear: false,
+               yearSuffix: ''};
+       $.datepicker.setDefaults($.datepicker.regional['de-AT']);
+});
diff --git a/resources/lib/jquery.ui/i18n/jquery.ui.datepicker-de-CH.js b/resources/lib/jquery.ui/i18n/jquery.ui.datepicker-de-CH.js
new file mode 100644 (file)
index 0000000..60cbc29
--- /dev/null
@@ -0,0 +1,22 @@
+/* Swiss Standard German initialisation for the jQuery UI date picker plugin. */
+jQuery(function($){
+       $.datepicker.regional['de-CH'] = {
+               closeText: 'schliessen',
+               prevText: '&#x3C;zurück',
+               nextText: 'Vor&#x3E;',
+               currentText: 'heute',
+               monthNames: ['Januar','Februar','März','April','Mai','Juni',
+               'Juli','August','September','Oktober','November','Dezember'],
+               monthNamesShort: ['Jan','Feb','Mär','Apr','Mai','Jun',
+               'Jul','Aug','Sep','Okt','Nov','Dez'],
+               dayNames: ['Sonntag','Montag','Dienstag','Mittwoch','Donnerstag','Freitag','Samstag'],
+               dayNamesShort: ['So','Mo','Di','Mi','Do','Fr','Sa'],
+               dayNamesMin: ['So','Mo','Di','Mi','Do','Fr','Sa'],
+               weekHeader: 'KW',
+               dateFormat: 'dd.mm.yy',
+               firstDay: 1,
+               isRTL: false,
+               showMonthAfterYear: false,
+               yearSuffix: ''};
+       $.datepicker.setDefaults($.datepicker.regional['de-CH']);
+});
index d2f2abd..0fdd9aa 100644 (file)
                 * @return {jQuery.Promise}
                 */
                getGroups: function ( callback ) {
-                       return getUserInfo().then(
-                               function ( userInfo ) { return userInfo.groups; },
-                               function () { return []; }
-                       ).done( callback );
+                       var userGroups = mw.config.get( 'wgUserGroups', [] );
+
+                       // Uses promise for backwards compatibility
+                       return $.Deferred().resolve( userGroups ).done( callback );
                },
 
                /**
index cc983e4..cccc468 100644 (file)
                /**
                 * Get the link to a page name (relative to `wgServer`),
                 *
-                * @param {string|null} [str=wgPageName] Page name
+                * @param {string|null} [pageName=wgPageName] Page name
                 * @param {Object} [params] A mapping of query parameter names to values,
                 *  e.g. `{ action: 'edit' }`
-                * @return {string} Url of the page with name of `str`
+                * @return {string} Url of the page with name of `pageName`
                 */
-               getUrl: function ( str, params ) {
-                       var titleFragmentStart,
-                               url,
+               getUrl: function ( pageName, params ) {
+                       var titleFragmentStart, url, query,
                                fragment = '',
-                               pageName = typeof str === 'string' ? str : mw.config.get( 'wgPageName' );
-
-                       // Find any fragment should one exist
-                       if ( typeof str === 'string' ) {
-                               titleFragmentStart = pageName.indexOf( '#' );
-                               if ( titleFragmentStart !== -1 ) {
-                                       fragment = pageName.slice( titleFragmentStart + 1 );
-                                       // Exclude the fragment from the page name
-                                       pageName = pageName.slice( 0, titleFragmentStart );
-                               }
+                               title = typeof pageName === 'string' ? pageName : mw.config.get( 'wgPageName' );
+
+                       // Find any fragment
+                       titleFragmentStart = title.indexOf( '#' );
+                       if ( titleFragmentStart !== -1 ) {
+                               fragment = title.slice( titleFragmentStart + 1 );
+                               // Exclude the fragment from the page name
+                               title = title.slice( 0, titleFragmentStart );
                        }
 
-                       url = mw.config.get( 'wgArticlePath' ).replace( '$1', util.wikiUrlencode( pageName ) );
-
-                       // Add query string if necessary
-                       if ( params && !$.isEmptyObject( params ) ) {
-                               url += ( url.indexOf( '?' ) !== -1 ? '&' : '?' ) + $.param( params );
+                       // Produce query string
+                       if ( params ) {
+                               query = $.param( params );
+                       }
+                       if ( query ) {
+                               url = title
+                                       ? util.wikiScript() + '?title=' + util.wikiUrlencode( title ) + '&' + query
+                                       : util.wikiScript() + '?' + query;
+                       } else {
+                               url = mw.config.get( 'wgArticlePath' ).replace( '$1', util.wikiUrlencode( title ) );
                        }
 
                        // Append the encoded fragment
-                       if ( fragment.length > 0 ) {
+                       if ( fragment.length ) {
                                url += '#' + util.escapeId( fragment );
                        }
 
diff --git a/tests/phpunit/includes/MediaWikiServicesTest.php b/tests/phpunit/includes/MediaWikiServicesTest.php
new file mode 100644 (file)
index 0000000..127f869
--- /dev/null
@@ -0,0 +1,77 @@
+<?php
+use MediaWiki\MediaWikiServices;
+
+/**
+ * @covers MediaWiki\MediaWikiServices
+ *
+ * @group MediaWiki
+ */
+class MediaWikiServicesTest extends PHPUnit_Framework_TestCase {
+
+       public function testGetInstance() {
+               $services = MediaWikiServices::getInstance();
+               $this->assertInstanceOf( 'MediaWiki\\MediaWikiServices', $services );
+       }
+
+       public function provideGetters() {
+               // NOTE: This should list all service getters defined in MediaWikiServices.
+               // NOTE: For every test case defined here there should be a corresponding
+               // test case defined in provideGetService().
+               return [
+                       'BootstrapConfig' => [ 'getBootstrapConfig', Config::class ],
+                       'ConfigFactory' => [ 'getConfigFactory', ConfigFactory::class ],
+                       'MainConfig' => [ 'getMainConfig', Config::class ],
+                       'SiteStore' => [ 'getSiteStore', SiteStore::class ],
+                       'SiteLookup' => [ 'getSiteLookup', SiteLookup::class ],
+               ];
+       }
+
+       /**
+        * @dataProvider provideGetters
+        */
+       public function testGetters( $getter, $type ) {
+               // Test against the default instance, since the dummy will not know the default services.
+               $services = MediaWikiServices::getInstance();
+               $service = $services->$getter();
+               $this->assertInstanceOf( $type, $service );
+       }
+
+       public function provideGetService() {
+               // NOTE: This should list all service getters defined in ServiceWiring.php.
+               // NOTE: For every test case defined here there should be a corresponding
+               // test case defined in provideGetters().
+               return [
+                       'BootstrapConfig' => [ 'BootstrapConfig', Config::class ],
+                       'ConfigFactory' => [ 'ConfigFactory', ConfigFactory::class ],
+                       'MainConfig' => [ 'MainConfig', Config::class ],
+                       'SiteStore' => [ 'SiteStore', SiteStore::class ],
+                       'SiteLookup' => [ 'SiteLookup', SiteLookup::class ],
+               ];
+       }
+
+       /**
+        * @dataProvider provideGetService
+        */
+       public function testGetService( $name, $type ) {
+               // Test against the default instance, since the dummy will not know the default services.
+               $services = MediaWikiServices::getInstance();
+
+               $service = $services->getService( $name );
+               $this->assertInstanceOf( $type, $service );
+       }
+
+       public function testDefaultServiceInstantiation() {
+               // Check all services in the default instance, not a dummy instance!
+               // Note that we instantiate all services here, including any that
+               // were registered by extensions.
+               $services = MediaWikiServices::getInstance();
+               $names = $services->getServiceNames();
+
+               foreach ( $names as $name ) {
+                       $this->assertTrue( $services->hasService( $name ) );
+                       $service = $services->getService( $name );
+                       $this->assertInternalType( 'object', $service );
+               }
+       }
+
+}
index 0ac9c3c..7d3007b 100644 (file)
@@ -314,18 +314,6 @@ class RevisionStorageTest extends MediaWikiTestCase {
                $this->assertEquals( 'hello hello.', $rev->getContent()->getNativeData() );
        }
 
-       /**
-        * @covers Revision::getRawText
-        */
-       public function testGetRawText() {
-               $this->hideDeprecated( 'Revision::getRawText' );
-
-               $orig = $this->makeRevision( [ 'text' => 'hello hello raw.' ] );
-               $rev = Revision::newFromId( $orig->getId() );
-
-               $this->assertEquals( 'hello hello raw.', $rev->getRawText() );
-       }
-
        /**
         * @covers Revision::getContentModel
         */
index d2eb6b8..767c963 100644 (file)
@@ -333,19 +333,6 @@ class RevisionTest extends MediaWikiTestCase {
                $this->assertEquals( $expectedText, $rev->getText( $audience ) );
        }
 
-       /**
-        * @group Database
-        * @dataProvider dataGetText
-        * @covers Revision::getRawText
-        */
-       public function testGetRawText( $text, $title, $model, $format, $audience, $expectedText ) {
-               $this->hideDeprecated( 'Revision::getRawText' );
-
-               $rev = $this->newTestRevision( $text, $title, $model, $format );
-
-               $this->assertEquals( $expectedText, $rev->getRawText( $audience ) );
-       }
-
        public function dataGetSize() {
                return [
                        [ "hello world.", CONTENT_MODEL_WIKITEXT, 12 ],
diff --git a/tests/phpunit/includes/Services/ServiceContainerTest.php b/tests/phpunit/includes/Services/ServiceContainerTest.php
new file mode 100644 (file)
index 0000000..942c45e
--- /dev/null
@@ -0,0 +1,214 @@
+<?php
+use MediaWiki\Services\ServiceContainer;
+
+/**
+ * @covers MediaWiki\Services\ServiceContainer
+ *
+ * @group MediaWiki
+ */
+class ServiceContainerTest extends PHPUnit_Framework_TestCase {
+
+       private function newServiceContainer( $extraArgs = [] ) {
+               return new ServiceContainer( $extraArgs );
+       }
+
+       public function testGetServiceNames() {
+               $services = $this->newServiceContainer();
+               $names = $services->getServiceNames();
+
+               $this->assertInternalType( 'array', $names );
+               $this->assertEmpty( $names );
+
+               $name = 'TestService92834576';
+               $services->defineService( $name, function() {
+                       return null;
+               } );
+
+               $names = $services->getServiceNames();
+               $this->assertContains( $name, $names );
+       }
+
+       public function testHasService() {
+               $services = $this->newServiceContainer();
+
+               $name = 'TestService92834576';
+               $this->assertFalse( $services->hasService( $name ) );
+
+               $services->defineService( $name, function() {
+                       return null;
+               } );
+
+               $this->assertTrue( $services->hasService( $name ) );
+       }
+
+       public function testGetService() {
+               $services = $this->newServiceContainer( [ 'Foo' ] );
+
+               $theService = new stdClass();
+               $name = 'TestService92834576';
+               $count = 0;
+
+               $services->defineService(
+                       $name,
+                       function( $actualLocator, $extra ) use ( $services, $theService, &$count ) {
+                               $count++;
+                               PHPUnit_Framework_Assert::assertSame( $services, $actualLocator );
+                               PHPUnit_Framework_Assert::assertSame( $extra, 'Foo' );
+                               return $theService;
+                       }
+               );
+
+               $this->assertSame( $theService, $services->getService( $name ) );
+
+               $services->getService( $name );
+               $this->assertSame( 1, $count, 'instantiator should be called exactly once!' );
+       }
+
+       public function testGetService_fail_unknown() {
+               $services = $this->newServiceContainer();
+
+               $name = 'TestService92834576';
+
+               $this->setExpectedException( 'InvalidArgumentException' );
+
+               $services->getService( $name );
+       }
+
+       public function testDefineService() {
+               $services = $this->newServiceContainer();
+
+               $theService = new stdClass();
+               $name = 'TestService92834576';
+
+               $services->defineService( $name, function( $actualLocator ) use ( $services, $theService ) {
+                       PHPUnit_Framework_Assert::assertSame( $services, $actualLocator );
+                       return $theService;
+               } );
+
+               $this->assertTrue( $services->hasService( $name ) );
+               $this->assertSame( $theService, $services->getService( $name ) );
+       }
+
+       public function testDefineService_fail_duplicate() {
+               $services = $this->newServiceContainer();
+
+               $theService = new stdClass();
+               $name = 'TestService92834576';
+
+               $services->defineService( $name, function() use ( $theService ) {
+                       return $theService;
+               } );
+
+               $this->setExpectedException( 'RuntimeException' );
+
+               $services->defineService( $name, function() use ( $theService ) {
+                       return $theService;
+               } );
+       }
+
+       public function testApplyWiring() {
+               $services = $this->newServiceContainer();
+
+               $wiring = [
+                       'Foo' => function() {
+                               return 'Foo!';
+                       },
+                       'Bar' => function() {
+                               return 'Bar!';
+                       },
+               ];
+
+               $services->applyWiring( $wiring );
+
+               $this->assertSame( 'Foo!', $services->getService( 'Foo' ) );
+               $this->assertSame( 'Bar!', $services->getService( 'Bar' ) );
+       }
+
+       public function testLoadWiringFiles() {
+               $services = $this->newServiceContainer();
+
+               $wiringFiles = [
+                       __DIR__ . '/TestWiring1.php',
+                       __DIR__ . '/TestWiring2.php',
+               ];
+
+               $services->loadWiringFiles( $wiringFiles );
+
+               $this->assertSame( 'Foo!', $services->getService( 'Foo' ) );
+               $this->assertSame( 'Bar!', $services->getService( 'Bar' ) );
+       }
+
+       public function testLoadWiringFiles_fail_duplicate() {
+               $services = $this->newServiceContainer();
+
+               $wiringFiles = [
+                       __DIR__ . '/TestWiring1.php',
+                       __DIR__ . '/./TestWiring1.php',
+               ];
+
+               // loading the same file twice should fail, because
+               $this->setExpectedException( 'RuntimeException' );
+
+               $services->loadWiringFiles( $wiringFiles );
+       }
+
+       public function testRedefineService() {
+               $services = $this->newServiceContainer( [ 'Foo' ] );
+
+               $theService1 = new stdClass();
+               $name = 'TestService92834576';
+
+               $services->defineService( $name, function() {
+                       PHPUnit_Framework_Assert::fail(
+                               'The original instantiator function should not get called'
+                       );
+               } );
+
+               // redefine before instantiation
+               $services->redefineService(
+                       $name,
+                       function( $actualLocator, $extra ) use ( $services, $theService1 ) {
+                               PHPUnit_Framework_Assert::assertSame( $services, $actualLocator );
+                               PHPUnit_Framework_Assert::assertSame( 'Foo', $extra );
+                               return $theService1;
+                       }
+               );
+
+               // force instantiation, check result
+               $this->assertSame( $theService1, $services->getService( $name ) );
+       }
+
+       public function testRedefineService_fail_undefined() {
+               $services = $this->newServiceContainer();
+
+               $theService = new stdClass();
+               $name = 'TestService92834576';
+
+               $this->setExpectedException( 'RuntimeException' );
+
+               $services->redefineService( $name, function() use ( $theService ) {
+                       return $theService;
+               } );
+       }
+
+       public function testRedefineService_fail_in_use() {
+               $services = $this->newServiceContainer( [ 'Foo' ] );
+
+               $theService = new stdClass();
+               $name = 'TestService92834576';
+
+               $services->defineService( $name, function() {
+                       return 'Foo';
+               } );
+
+               // create the service, so it can no longer be redefined
+               $services->getService( $name );
+
+               $this->setExpectedException( 'RuntimeException' );
+
+               $services->redefineService( $name, function() use ( $theService ) {
+                       return $theService;
+               } );
+       }
+
+}
diff --git a/tests/phpunit/includes/Services/TestWiring1.php b/tests/phpunit/includes/Services/TestWiring1.php
new file mode 100644 (file)
index 0000000..186021a
--- /dev/null
@@ -0,0 +1,10 @@
+<?php
+/**
+ * Test file for testing ServiceContainer::loadWiringFiles
+ */
+
+return [
+       'Foo' => function() {
+               return 'Foo!';
+       },
+];
diff --git a/tests/phpunit/includes/Services/TestWiring2.php b/tests/phpunit/includes/Services/TestWiring2.php
new file mode 100644 (file)
index 0000000..3b4fff0
--- /dev/null
@@ -0,0 +1,10 @@
+<?php
+/**
+ * Test file for testing ServiceContainer::loadWiringFiles
+ */
+
+return [
+       'Bar' => function() {
+               return 'Bar!';
+       },
+];
index 5f07dbf..9dd38df 100644 (file)
@@ -1,4 +1,5 @@
 <?php
+use Liuggio\StatsdClient\Factory\StatsdDataFactory;
 
 /**
  * @author Addshore
@@ -82,6 +83,13 @@ class WatchedItemStoreUnitTest extends PHPUnit_Framework_TestCase {
                return $fakeRow;
        }
 
+       private function newWatchedItemStore( LoadBalancer $loadBalancer, HashBagOStuff $cache ) {
+               return new WatchedItemStore(
+                       $loadBalancer,
+                       $cache
+               );
+       }
+
        public function testGetDefaultInstance() {
                $instanceOne = WatchedItemStore::getDefaultInstance();
                $instanceTwo = WatchedItemStore::getDefaultInstance();
@@ -120,7 +128,7 @@ class WatchedItemStoreUnitTest extends PHPUnit_Framework_TestCase {
                $mockCache->expects( $this->never() )->method( 'set' );
                $mockCache->expects( $this->never() )->method( 'delete' );
 
-               $store = new WatchedItemStore(
+               $store = $this->newWatchedItemStore(
                        $this->getMockLoadBalancer( $mockDb ),
                        $mockCache
                );
@@ -150,7 +158,7 @@ class WatchedItemStoreUnitTest extends PHPUnit_Framework_TestCase {
                $mockCache->expects( $this->never() )->method( 'set' );
                $mockCache->expects( $this->never() )->method( 'delete' );
 
-               $store = new WatchedItemStore(
+               $store = $this->newWatchedItemStore(
                        $this->getMockLoadBalancer( $mockDb ),
                        $mockCache
                );
@@ -201,7 +209,7 @@ class WatchedItemStoreUnitTest extends PHPUnit_Framework_TestCase {
                $mockCache->expects( $this->never() )->method( 'set' );
                $mockCache->expects( $this->never() )->method( 'delete' );
 
-               $store = new WatchedItemStore(
+               $store = $this->newWatchedItemStore(
                        $this->getMockLoadBalancer( $mockDb ),
                        $mockCache
                );
@@ -267,7 +275,7 @@ class WatchedItemStoreUnitTest extends PHPUnit_Framework_TestCase {
                $mockCache->expects( $this->never() )->method( 'set' );
                $mockCache->expects( $this->never() )->method( 'delete' );
 
-               $store = new WatchedItemStore(
+               $store = $this->newWatchedItemStore(
                        $this->getMockLoadBalancer( $mockDb ),
                        $mockCache
                );
@@ -315,7 +323,7 @@ class WatchedItemStoreUnitTest extends PHPUnit_Framework_TestCase {
                $mockCache->expects( $this->never() )->method( 'get' );
                $mockCache->expects( $this->never() )->method( 'delete' );
 
-               $store = new WatchedItemStore(
+               $store = $this->newWatchedItemStore(
                        $this->getMockLoadBalancer( $mockDb ),
                        $mockCache
                );
@@ -394,7 +402,7 @@ class WatchedItemStoreUnitTest extends PHPUnit_Framework_TestCase {
                $mockCache->expects( $this->never() )->method( 'set' );
                $mockCache->expects( $this->never() )->method( 'delete' );
 
-               $store = new WatchedItemStore(
+               $store = $this->newWatchedItemStore(
                        $this->getMockLoadBalancer( $mockDb ),
                        $mockCache
                );
@@ -496,7 +504,7 @@ class WatchedItemStoreUnitTest extends PHPUnit_Framework_TestCase {
                $mockCache->expects( $this->never() )->method( 'set' );
                $mockCache->expects( $this->never() )->method( 'delete' );
 
-               $store = new WatchedItemStore(
+               $store = $this->newWatchedItemStore(
                        $this->getMockLoadBalancer( $mockDb ),
                        $mockCache
                );
@@ -549,7 +557,7 @@ class WatchedItemStoreUnitTest extends PHPUnit_Framework_TestCase {
                $mockCache->expects( $this->never() )->method( 'set' );
                $mockCache->expects( $this->never() )->method( 'delete' );
 
-               $store = new WatchedItemStore(
+               $store = $this->newWatchedItemStore(
                        $this->getMockLoadBalancer( $mockDb ),
                        $mockCache
                );
@@ -586,7 +594,7 @@ class WatchedItemStoreUnitTest extends PHPUnit_Framework_TestCase {
                $mockCache->expects( $this->never() )->method( 'get' );
                $mockCache->expects( $this->never() )->method( 'delete' );
 
-               $store = new WatchedItemStore(
+               $store = $this->newWatchedItemStore(
                        $this->getMockLoadBalancer( $mockDb ),
                        $mockCache
                );
@@ -620,7 +628,7 @@ class WatchedItemStoreUnitTest extends PHPUnit_Framework_TestCase {
                $mockCache->expects( $this->never() )->method( 'get' );
                $mockCache->expects( $this->never() )->method( 'delete' );
 
-               $store = new WatchedItemStore(
+               $store = $this->newWatchedItemStore(
                        $this->getMockLoadBalancer( $mockDb ),
                        $mockCache
                );
@@ -657,7 +665,7 @@ class WatchedItemStoreUnitTest extends PHPUnit_Framework_TestCase {
                $mockCache->expects( $this->never() )->method( 'get' );
                $mockCache->expects( $this->never() )->method( 'delete' );
 
-               $store = new WatchedItemStore(
+               $store = $this->newWatchedItemStore(
                        $this->getMockLoadBalancer( $mockDb ),
                        $mockCache
                );
@@ -687,7 +695,7 @@ class WatchedItemStoreUnitTest extends PHPUnit_Framework_TestCase {
                        )
                        ->will( $this->returnValue( new FakeResultWrapper( [] ) ) );
 
-               $store = new WatchedItemStore(
+               $store = $this->newWatchedItemStore(
                        $this->getMockLoadBalancer( $mockDb ),
                        $this->getMockCache()
                );
@@ -745,7 +753,7 @@ class WatchedItemStoreUnitTest extends PHPUnit_Framework_TestCase {
                $mockCache->expects( $this->never() )->method( 'get' );
                $mockCache->expects( $this->never() )->method( 'delete' );
 
-               $store = new WatchedItemStore(
+               $store = $this->newWatchedItemStore(
                        $this->getMockLoadBalancer( $mockDb ),
                        $mockCache
                );
@@ -791,7 +799,7 @@ class WatchedItemStoreUnitTest extends PHPUnit_Framework_TestCase {
                $mockCache->expects( $this->never() )->method( 'get' );
                $mockCache->expects( $this->never() )->method( 'delete' );
 
-               $store = new WatchedItemStore(
+               $store = $this->newWatchedItemStore(
                        $this->getMockLoadBalancer( $mockDb ),
                        $mockCache
                );
@@ -871,7 +879,7 @@ class WatchedItemStoreUnitTest extends PHPUnit_Framework_TestCase {
                $mockCache->expects( $this->never() )->method( 'get' );
                $mockCache->expects( $this->never() )->method( 'delete' );
 
-               $store = new WatchedItemStore(
+               $store = $this->newWatchedItemStore(
                        $this->getMockLoadBalancer( $mockDb ),
                        $mockCache
                );
@@ -903,7 +911,7 @@ class WatchedItemStoreUnitTest extends PHPUnit_Framework_TestCase {
                        ->method( 'delete' )
                        ->with( '0:Some_Page:1' );
 
-               $store = new WatchedItemStore(
+               $store = $this->newWatchedItemStore(
                        $this->getMockLoadBalancer( $mockDb ),
                        $mockCache
                );
@@ -923,7 +931,7 @@ class WatchedItemStoreUnitTest extends PHPUnit_Framework_TestCase {
                $mockCache->expects( $this->never() )
                        ->method( 'delete' );
 
-               $store = new WatchedItemStore(
+               $store = $this->newWatchedItemStore(
                        $this->getMockLoadBalancer( $mockDb ),
                        $mockCache
                );
@@ -966,7 +974,7 @@ class WatchedItemStoreUnitTest extends PHPUnit_Framework_TestCase {
                        ->method( 'delete' )
                        ->with( '1:Some_Page:1' );
 
-               $store = new WatchedItemStore(
+               $store = $this->newWatchedItemStore(
                        $this->getMockLoadBalancer( $mockDb ),
                        $mockCache
                );
@@ -990,7 +998,7 @@ class WatchedItemStoreUnitTest extends PHPUnit_Framework_TestCase {
                $mockCache->expects( $this->never() )
                        ->method( 'delete' );
 
-               $store = new WatchedItemStore(
+               $store = $this->newWatchedItemStore(
                        $this->getMockLoadBalancer( $mockDb ),
                        $mockCache
                );
@@ -1013,7 +1021,7 @@ class WatchedItemStoreUnitTest extends PHPUnit_Framework_TestCase {
                $mockCache->expects( $this->never() )
                        ->method( 'delete' );
 
-               $store = new WatchedItemStore(
+               $store = $this->newWatchedItemStore(
                        $this->getMockLoadBalancer( $mockDb ),
                        $mockCache
                );
@@ -1047,7 +1055,7 @@ class WatchedItemStoreUnitTest extends PHPUnit_Framework_TestCase {
                                '0:SomeDbKey:1'
                        );
 
-               $store = new WatchedItemStore(
+               $store = $this->newWatchedItemStore(
                        $this->getMockLoadBalancer( $mockDb ),
                        $mockCache
                );
@@ -1081,7 +1089,7 @@ class WatchedItemStoreUnitTest extends PHPUnit_Framework_TestCase {
                $mockCache->expects( $this->never() )->method( 'get' );
                $mockCache->expects( $this->never() )->method( 'delete' );
 
-               $store = new WatchedItemStore(
+               $store = $this->newWatchedItemStore(
                        $this->getMockLoadBalancer( $mockDb ),
                        $mockCache
                );
@@ -1103,7 +1111,7 @@ class WatchedItemStoreUnitTest extends PHPUnit_Framework_TestCase {
                $mockCache->expects( $this->never() )->method( 'get' );
                $mockCache->expects( $this->never() )->method( 'delete' );
 
-               $store = new WatchedItemStore(
+               $store = $this->newWatchedItemStore(
                        $this->getMockLoadBalancer( $mockDb ),
                        $mockCache
                );
@@ -1138,7 +1146,7 @@ class WatchedItemStoreUnitTest extends PHPUnit_Framework_TestCase {
                        ->method( 'delete' )
                        ->with( '0:SomeDbKey:1' );
 
-               $store = new WatchedItemStore(
+               $store = $this->newWatchedItemStore(
                        $this->getMockLoadBalancer( $mockDb ),
                        $mockCache
                );
@@ -1173,7 +1181,7 @@ class WatchedItemStoreUnitTest extends PHPUnit_Framework_TestCase {
                        ->method( 'delete' )
                        ->with( '0:SomeDbKey:1' );
 
-               $store = new WatchedItemStore(
+               $store = $this->newWatchedItemStore(
                        $this->getMockLoadBalancer( $mockDb ),
                        $mockCache
                );
@@ -1196,7 +1204,7 @@ class WatchedItemStoreUnitTest extends PHPUnit_Framework_TestCase {
                $mockCache->expects( $this->never() )
                        ->method( 'delete' );
 
-               $store = new WatchedItemStore(
+               $store = $this->newWatchedItemStore(
                        $this->getMockLoadBalancer( $mockDb ),
                        $mockCache
                );
@@ -1240,7 +1248,7 @@ class WatchedItemStoreUnitTest extends PHPUnit_Framework_TestCase {
                                '0:SomeDbKey:1'
                        );
 
-               $store = new WatchedItemStore(
+               $store = $this->newWatchedItemStore(
                        $this->getMockLoadBalancer( $mockDb ),
                        $mockCache
                );
@@ -1274,7 +1282,7 @@ class WatchedItemStoreUnitTest extends PHPUnit_Framework_TestCase {
                        )
                        ->will( $this->returnValue( $cachedItem ) );
 
-               $store = new WatchedItemStore(
+               $store = $this->newWatchedItemStore(
                        $this->getMockLoadBalancer( $mockDb ),
                        $mockCache
                );
@@ -1311,7 +1319,7 @@ class WatchedItemStoreUnitTest extends PHPUnit_Framework_TestCase {
                        ->with( '0:SomeDbKey:1' )
                        ->will( $this->returnValue( false ) );
 
-               $store = new WatchedItemStore(
+               $store = $this->newWatchedItemStore(
                        $this->getMockLoadBalancer( $mockDb ),
                        $mockCache
                );
@@ -1334,7 +1342,7 @@ class WatchedItemStoreUnitTest extends PHPUnit_Framework_TestCase {
                $mockCache->expects( $this->never() )->method( 'get' );
                $mockCache->expects( $this->never() )->method( 'delete' );
 
-               $store = new WatchedItemStore(
+               $store = $this->newWatchedItemStore(
                        $this->getMockLoadBalancer( $mockDb ),
                        $mockCache
                );
@@ -1374,7 +1382,7 @@ class WatchedItemStoreUnitTest extends PHPUnit_Framework_TestCase {
                $mockCache->expects( $this->never() )->method( 'get' );
                $mockCache->expects( $this->never() )->method( 'set' );
 
-               $store = new WatchedItemStore(
+               $store = $this->newWatchedItemStore(
                        $this->getMockLoadBalancer( $mockDb ),
                        $mockCache
                );
@@ -1424,7 +1432,7 @@ class WatchedItemStoreUnitTest extends PHPUnit_Framework_TestCase {
                        )
                        ->will( $this->returnValue( [] ) );
 
-               $store = new WatchedItemStore(
+               $store = $this->newWatchedItemStore(
                        $mockLoadBalancer,
                        $mockCache
                );
@@ -1437,7 +1445,7 @@ class WatchedItemStoreUnitTest extends PHPUnit_Framework_TestCase {
        }
 
        public function testGetWatchedItemsForUser_badSortOptionThrowsException() {
-               $store = new WatchedItemStore(
+               $store = $this->newWatchedItemStore(
                        $this->getMockLoadBalancer( $this->getMockDb() ),
                        $this->getMockCache()
                );
@@ -1478,7 +1486,7 @@ class WatchedItemStoreUnitTest extends PHPUnit_Framework_TestCase {
                                '0:SomeDbKey:1'
                        );
 
-               $store = new WatchedItemStore(
+               $store = $this->newWatchedItemStore(
                        $this->getMockLoadBalancer( $mockDb ),
                        $mockCache
                );
@@ -1514,7 +1522,7 @@ class WatchedItemStoreUnitTest extends PHPUnit_Framework_TestCase {
                        ->with( '0:SomeDbKey:1' )
                        ->will( $this->returnValue( false ) );
 
-               $store = new WatchedItemStore(
+               $store = $this->newWatchedItemStore(
                        $this->getMockLoadBalancer( $mockDb ),
                        $mockCache
                );
@@ -1537,7 +1545,7 @@ class WatchedItemStoreUnitTest extends PHPUnit_Framework_TestCase {
                $mockCache->expects( $this->never() )->method( 'get' );
                $mockCache->expects( $this->never() )->method( 'delete' );
 
-               $store = new WatchedItemStore(
+               $store = $this->newWatchedItemStore(
                        $this->getMockLoadBalancer( $mockDb ),
                        $mockCache
                );
@@ -1604,7 +1612,7 @@ class WatchedItemStoreUnitTest extends PHPUnit_Framework_TestCase {
                $mockCache->expects( $this->never() )->method( 'set' );
                $mockCache->expects( $this->never() )->method( 'delete' );
 
-               $store = new WatchedItemStore(
+               $store = $this->newWatchedItemStore(
                        $this->getMockLoadBalancer( $mockDb ),
                        $mockCache
                );
@@ -1654,7 +1662,7 @@ class WatchedItemStoreUnitTest extends PHPUnit_Framework_TestCase {
                $mockCache->expects( $this->never() )->method( 'set' );
                $mockCache->expects( $this->never() )->method( 'delete' );
 
-               $store = new WatchedItemStore(
+               $store = $this->newWatchedItemStore(
                        $this->getMockLoadBalancer( $mockDb ),
                        $mockCache
                );
@@ -1715,7 +1723,7 @@ class WatchedItemStoreUnitTest extends PHPUnit_Framework_TestCase {
                $mockCache->expects( $this->never() )->method( 'set' );
                $mockCache->expects( $this->never() )->method( 'delete' );
 
-               $store = new WatchedItemStore(
+               $store = $this->newWatchedItemStore(
                        $this->getMockLoadBalancer( $mockDb ),
                        $mockCache
                );
@@ -1755,7 +1763,7 @@ class WatchedItemStoreUnitTest extends PHPUnit_Framework_TestCase {
                $mockCache->expects( $this->never() )->method( 'set' );
                $mockCache->expects( $this->never() )->method( 'delete' );
 
-               $store = new WatchedItemStore(
+               $store = $this->newWatchedItemStore(
                        $this->getMockLoadBalancer( $mockDb ),
                        $mockCache
                );
@@ -1781,7 +1789,7 @@ class WatchedItemStoreUnitTest extends PHPUnit_Framework_TestCase {
                $mockCache = $this->getMockCache();
                $mockCache->expects( $this->never() )->method( $this->anything() );
 
-               $store = new WatchedItemStore(
+               $store = $this->newWatchedItemStore(
                        $this->getMockLoadBalancer( $mockDb ),
                        $mockCache
                );
@@ -1805,7 +1813,7 @@ class WatchedItemStoreUnitTest extends PHPUnit_Framework_TestCase {
                $mockCache->expects( $this->never() )->method( 'set' );
                $mockCache->expects( $this->never() )->method( 'delete' );
 
-               $store = new WatchedItemStore(
+               $store = $this->newWatchedItemStore(
                        $this->getMockLoadBalancer( $mockDb ),
                        $mockCache
                );
@@ -1838,7 +1846,7 @@ class WatchedItemStoreUnitTest extends PHPUnit_Framework_TestCase {
                $mockCache->expects( $this->never() )->method( 'set' );
                $mockCache->expects( $this->never() )->method( 'delete' );
 
-               $store = new WatchedItemStore(
+               $store = $this->newWatchedItemStore(
                        $this->getMockLoadBalancer( $mockDb ),
                        $mockCache
                );
@@ -1883,7 +1891,7 @@ class WatchedItemStoreUnitTest extends PHPUnit_Framework_TestCase {
                        ->method( 'delete' )
                        ->with( '0:SomeDbKey:1' );
 
-               $store = new WatchedItemStore(
+               $store = $this->newWatchedItemStore(
                        $this->getMockLoadBalancer( $mockDb ),
                        $mockCache
                );
@@ -1923,7 +1931,7 @@ class WatchedItemStoreUnitTest extends PHPUnit_Framework_TestCase {
                $mockDb->expects( $this->never() )
                        ->method( 'delete' );
 
-               $store = new WatchedItemStore(
+               $store = $this->newWatchedItemStore(
                        $this->getMockLoadBalancer( $mockDb ),
                        $mockCache
                );
@@ -1989,7 +1997,7 @@ class WatchedItemStoreUnitTest extends PHPUnit_Framework_TestCase {
                $mockDb->expects( $this->never() )
                        ->method( 'delete' );
 
-               $store = new WatchedItemStore(
+               $store = $this->newWatchedItemStore(
                        $this->getMockLoadBalancer( $mockDb ),
                        $mockCache
                );
@@ -2049,7 +2057,7 @@ class WatchedItemStoreUnitTest extends PHPUnit_Framework_TestCase {
                $mockDb->expects( $this->never() )
                        ->method( 'delete' );
 
-               $store = new WatchedItemStore(
+               $store = $this->newWatchedItemStore(
                        $this->getMockLoadBalancer( $mockDb ),
                        $mockCache
                );
@@ -2130,7 +2138,7 @@ class WatchedItemStoreUnitTest extends PHPUnit_Framework_TestCase {
                $mockCache->expects( $this->never() )->method( 'get' );
                $mockCache->expects( $this->never() )->method( 'delete' );
 
-               $store = new WatchedItemStore(
+               $store = $this->newWatchedItemStore(
                        $this->getMockLoadBalancer( $mockDb ),
                        $mockCache
                );
@@ -2172,7 +2180,7 @@ class WatchedItemStoreUnitTest extends PHPUnit_Framework_TestCase {
                $mockCache->expects( $this->never() )->method( 'get' );
                $mockCache->expects( $this->never() )->method( 'delete' );
 
-               $store = new WatchedItemStore(
+               $store = $this->newWatchedItemStore(
                        $this->getMockLoadBalancer( $mockDb ),
                        $mockCache
                );
@@ -2224,7 +2232,7 @@ class WatchedItemStoreUnitTest extends PHPUnit_Framework_TestCase {
                        ->method( 'delete' )
                        ->with( '0:SomeDbKey:1' );
 
-               $store = new WatchedItemStore(
+               $store = $this->newWatchedItemStore(
                        $this->getMockLoadBalancer( $mockDb ),
                        $mockCache
                );
index c4829d2..2288507 100644 (file)
@@ -2,12 +2,6 @@
 
 class ConfigFactoryTest extends MediaWikiTestCase {
 
-       public function tearDown() {
-               // Reset this since we mess with it a bit
-               ConfigFactory::destroyDefaultInstance();
-               parent::tearDown();
-       }
-
        /**
         * @covers ConfigFactory::register
         */
@@ -54,17 +48,10 @@ class ConfigFactoryTest extends MediaWikiTestCase {
         * @covers ConfigFactory::getDefaultInstance
         */
        public function testGetDefaultInstance() {
-               // Set $wgConfigRegistry, and check the default
-               // instance read from it
-               $this->setMwGlobals( 'wgConfigRegistry', [
-                       'conf1' => 'GlobalVarConfig::newInstance',
-                       'conf2' => 'GlobalVarConfig::newInstance',
-               ] );
-               ConfigFactory::destroyDefaultInstance();
                $factory = ConfigFactory::getDefaultInstance();
-               $this->assertInstanceOf( 'Config', $factory->makeConfig( 'conf1' ) );
-               $this->assertInstanceOf( 'Config', $factory->makeConfig( 'conf2' ) );
+               $this->assertInstanceOf( 'Config', $factory->makeConfig( 'main' ) );
+
                $this->setExpectedException( 'ConfigException' );
-               $factory->makeConfig( 'conf3' );
+               $factory->makeConfig( 'xyzzy' );
        }
 }
index 8cbbfb8..1c746bc 100644 (file)
@@ -141,26 +141,6 @@ class JavaScriptContentTest extends TextContentTest {
                ];
        }
 
-       /**
-        * @todo Test needs database!
-        */
-       /*
-       public function getRedirectChain() {
-               $text = $this->getNativeData();
-               return Title::newFromRedirectArray( $text );
-       }
-       */
-
-       /**
-        * @todo Test needs database!
-        */
-       /*
-       public function getUltimateRedirectTarget() {
-               $text = $this->getNativeData();
-               return Title::newFromRedirectRecurse( $text );
-       }
-       */
-
        public static function dataIsCountable() {
                return [
                        [ '',
index 93bf716..ac83428 100644 (file)
@@ -180,26 +180,6 @@ class TextContentTest extends MediaWikiLangTestCase {
                $this->assertEquals( !is_null( $expected ), $content->isRedirect() );
        }
 
-       /**
-        * @todo Test needs database! Should be done by a test class in the Database group.
-        */
-       /*
-       public function getRedirectChain() {
-               $text = $this->getNativeData();
-               return Title::newFromRedirectArray( $text );
-       }
-       */
-
-       /**
-        * @todo Test needs database! Should be done by a test class in the Database group.
-        */
-       /*
-       public function getUltimateRedirectTarget() {
-               $text = $this->getNativeData();
-               return Title::newFromRedirectRecurse( $text );
-       }
-       */
-
        public static function dataIsCountable() {
                return [
                        [ '',
index 168b2c6..bb747c7 100644 (file)
@@ -339,7 +339,7 @@ class DatabaseMysqlBaseTest extends MediaWikiTestCase {
 
                $db->expects( $this->any() )
                        ->method( 'getHeartbeatData' )
-                       ->with( 172 )
+                       ->with( [ 'server_id' => 172 ] )
                        ->will( $this->returnValue( [ $ptTimeISO, $now ] ) );
 
                $db->setLBInfo( 'clusterMasterHost', 'db1052' );
index a9a1e7a..938397a 100644 (file)
@@ -47,9 +47,9 @@ class AvroFormatterTest extends MediaWikiTestCase {
                // disable conversion of notices
                PHPUnit_Framework_Error_Notice::$enabled = false;
                // have to keep the user notice from being output
-               wfSuppressWarnings();
+               \MediaWiki\suppressWarnings();
                $res = $formatter->format( [ 'channel' => 'marty' ] );
-               wfRestoreWarnings();
+               \MediaWiki\restoreWarnings();
                PHPUnit_Framework_Error_Notice::$enabled = $noticeEnabled;
                $this->assertNull( $res );
        }
index d488eee..10e0f59 100644 (file)
@@ -767,22 +767,6 @@ more stuff
                ];
        }
 
-       /**
-        * @dataProvider dataReplaceSection
-        * @covers WikiPage::replaceSection
-        */
-       public function testReplaceSection( $title, $model, $text, $section, $with,
-               $sectionTitle, $expected
-       ) {
-               $this->hideDeprecated( "WikiPage::replaceSection" );
-
-               $page = $this->createPage( $title, $text, $model );
-               $text = $page->replaceSection( $section, $with, $sectionTitle );
-               $text = trim( $text );
-
-               $this->assertEquals( $expected, $text );
-       }
-
        /**
         * @dataProvider dataReplaceSection
         * @covers WikiPage::replaceSectionContent
index 4f4275d..32dd7f2 100644 (file)
  */
 class DBSiteStoreTest extends MediaWikiTestCase {
 
+       /**
+        * @return DBSiteStore
+        */
+       private function newDBSiteStore() {
+               // NOTE: Use the real DB load balancer for now. Eventually, the test framework should
+               // provide a LoadBalancer that is safe to use in unit tests.
+               return new DBSiteStore( wfGetLB() );
+       }
+
        /**
         * @covers DBSiteStore::getSites
         */
@@ -38,7 +47,7 @@ class DBSiteStoreTest extends MediaWikiTestCase {
                $expectedSites = TestSites::getSites();
                TestSites::insertIntoDb();
 
-               $store = new DBSiteStore();
+               $store = $this->newDBSiteStore();
 
                $sites = $store->getSites();
 
@@ -62,7 +71,7 @@ class DBSiteStoreTest extends MediaWikiTestCase {
         * @covers DBSiteStore::saveSites
         */
        public function testSaveSites() {
-               $store = new DBSiteStore();
+               $store = $this->newDBSiteStore();
 
                $sites = [];
 
@@ -95,8 +104,8 @@ class DBSiteStoreTest extends MediaWikiTestCase {
         * @covers DBSiteStore::reset
         */
        public function testReset() {
-               $store1 = new DBSiteStore();
-               $store2 = new DBSiteStore();
+               $store1 = $this->newDBSiteStore();
+               $store2 = $this->newDBSiteStore();
 
                // initialize internal cache
                $this->assertGreaterThan( 0, $store1->getSites()->count() );
@@ -121,7 +130,7 @@ class DBSiteStoreTest extends MediaWikiTestCase {
         * @covers DBSiteStore::clear
         */
        public function testClear() {
-               $store = new DBSiteStore();
+               $store = $this->newDBSiteStore();
                $this->assertTrue( $store->clear() );
 
                $site = $store->getSite( 'enwiki' );
@@ -135,7 +144,7 @@ class DBSiteStoreTest extends MediaWikiTestCase {
         * @covers DBSiteStore::getSites
         */
        public function testGetSitesDefaultOrder() {
-               $store = new DBSiteStore();
+               $store = $this->newDBSiteStore();
                $siteB = new Site();
                $siteB->setGlobalId( 'B' );
                $siteA = new Site();
diff --git a/tests/phpunit/includes/site/SiteSQLStoreTest.php b/tests/phpunit/includes/site/SiteSQLStoreTest.php
deleted file mode 100644 (file)
index 6908800..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-<?php
-
-/**
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- * http://www.gnu.org/copyleft/gpl.html
- *
- * @file
- * @since 1.25
- *
- * @ingroup Site
- * @ingroup Test
- *
- * @group Site
- * @group Database
- *
- * @author Katie Filbert < aude.wiki@gmail.com >
- */
-class SiteSQLStoreTest extends MediaWikiTestCase {
-
-       /**
-        * @covers SiteSQLStore::newInstance
-        */
-       public function testNewInstance() {
-               $siteStore = SiteSQLStore::newInstance();
-               $this->assertInstanceOf( 'SiteSQLStore', $siteStore );
-       }
-
-}
index d7865d4..6597906 100644 (file)
@@ -107,7 +107,7 @@ class TestSites {
         * @since 0.1
         */
        public static function insertIntoDb() {
-               $sitesTable = new DBSiteStore();
+               $sitesTable = \MediaWiki\MediaWikiServices::getInstance()->getSiteStore();
                $sitesTable->clear();
                $sitesTable->saveSites( TestSites::getSites() );
        }
index 534cf9b..3d407fb 100644 (file)
@@ -55,19 +55,17 @@ class SpecialPageFactoryTest extends MediaWikiTestCase {
                $specialPageTestHelper = new SpecialPageTestHelper();
 
                return [
-                       'class name' => [ 'SpecialAllPages', false ],
+                       'class name' => [ 'SpecialAllPages' ],
                        'closure' => [ function () {
                                return new SpecialAllPages();
-                       }, false ],
-                       'function' => [ [ $this, 'newSpecialAllPages' ], false ],
-                       'callback string' => [ 'SpecialPageTestHelper::newSpecialAllPages', false ],
+                       } ],
+                       'function' => [ [ $this, 'newSpecialAllPages' ] ],
+                       'callback string' => [ 'SpecialPageTestHelper::newSpecialAllPages' ],
                        'callback with object' => [
-                               [ $specialPageTestHelper, 'newSpecialAllPages' ],
-                               false
+                               [ $specialPageTestHelper, 'newSpecialAllPages' ]
                        ],
                        'callback array' => [
-                               [ 'SpecialPageTestHelper', 'newSpecialAllPages' ],
-                               false
+                               [ 'SpecialPageTestHelper', 'newSpecialAllPages' ]
                        ]
                ];
        }
@@ -76,7 +74,7 @@ class SpecialPageFactoryTest extends MediaWikiTestCase {
         * @covers SpecialPageFactory::getPage
         * @dataProvider specialPageProvider
         */
-       public function testGetPage( $spec, $shouldReuseInstance ) {
+       public function testGetPage( $spec ) {
                $this->mergeMwGlobalArrayValue( 'wgSpecialPages', [ 'testdummy' => $spec ] );
                SpecialPageFactory::resetList();
 
@@ -84,7 +82,7 @@ class SpecialPageFactoryTest extends MediaWikiTestCase {
                $this->assertInstanceOf( 'SpecialPage', $page );
 
                $page2 = SpecialPageFactory::getPage( 'testdummy' );
-               $this->assertEquals( $shouldReuseInstance, $page2 === $page, "Should re-use instance:" );
+               $this->assertEquals( true, $page2 === $page, "Should re-use instance:" );
        }
 
        /**
index 6d7325d..d746ea1 100644 (file)
@@ -9,6 +9,9 @@ class UIDGeneratorTest extends PHPUnit_Framework_TestCase {
        }
 
        /**
+        * Flaky test (T131549).
+        *
+        * @group Broken
         * @dataProvider provider_testTimestampedUID
         * @covers UIDGenerator::newTimestampedUID128
         * @covers UIDGenerator::newTimestampedUID88
index 932ba7d..991725b 100644 (file)
 
        QUnit.test( 'getUrl', 4, function ( assert ) {
                var title;
-
-               // Config
-               mw.config.set( 'wgArticlePath', '/wiki/$1' );
+               mw.config.set( {
+                       wgScript: '/w/index.php',
+                       wgArticlePath: '/wiki/$1'
+               } );
 
                title = new mw.Title( 'Foobar' );
                assert.equal( title.getUrl(), '/wiki/Foobar', 'Basic functionality, getUrl uses mw.util.getUrl' );
-               assert.equal( title.getUrl( { action: 'edit' } ), '/wiki/Foobar?action=edit', 'Basic functionality, \'params\' parameter' );
+               assert.equal( title.getUrl( { action: 'edit' } ), '/w/index.php?title=Foobar&action=edit', 'Basic functionality, \'params\' parameter' );
 
                title = new mw.Title( 'John Doe', 3 );
                assert.equal( title.getUrl(), '/wiki/User_talk:John_Doe', 'Escaping in title and namespace for urls' );
 
                title = new mw.Title( 'John Cena#And_His_Name_Is', 3 );
-               assert.equal( title.getUrl( { meme: true } ), '/wiki/User_talk:John_Cena?meme=true#And_His_Name_Is', 'title with fragment and query parameter' );
+               assert.equal( title.getUrl( { meme: true } ), '/w/index.php?title=User_talk:John_Cena&meme=true#And_His_Name_Is', 'title with fragment and query parameter' );
        } );
 
        QUnit.test( 'newFromImg', 44, function ( assert ) {
index 04e002d..3332c08 100644 (file)
@@ -41,6 +41,8 @@
        } );
 
        QUnit.test( 'getUserInfos', 3, function ( assert ) {
+               mw.config.set( 'wgUserGroups', [ '*', 'user' ] );
+
                mw.user.getGroups( function ( groups ) {
                        assert.deepEqual( groups, [ '*', 'user' ], 'Result' );
                } );
@@ -55,7 +57,7 @@
 
                this.server.respondWith( /meta=userinfo/, function ( request ) {
                        request.respond( 200, { 'Content-Type': 'application/json' },
-                               '{ "query": { "userinfo": { "groups": [ "*", "user" ], "rights": [ "read", "edit", "createtalk" ] } } }'
+                               '{ "query": { "userinfo": { "groups": [ "unused" ], "rights": [ "read", "edit", "createtalk" ] } } }'
                        );
                } );
 
index 5d72179..d697507 100644 (file)
                } );
        } );
 
-       QUnit.test( 'getUrl', 12, function ( assert ) {
+       QUnit.test( 'getUrl', 13, function ( assert ) {
+               var href;
                mw.config.set( {
+                       wgScript: '/w/index.php',
                        wgArticlePath: '/wiki/$1',
                        wgPageName: 'Foobar'
                } );
 
-               var href = mw.util.getUrl( 'Sandbox' );
+               href = mw.util.getUrl( 'Sandbox' );
                assert.equal( href, '/wiki/Sandbox', 'simple title' );
 
                href = mw.util.getUrl( 'Foo:Sandbox? 5+5=10! (test)/sub ' );
-               assert.equal( href, '/wiki/Foo:Sandbox%3F_5%2B5%3D10!_(test)/sub_', 'advanced title' );
+               assert.equal( href, '/wiki/Foo:Sandbox%3F_5%2B5%3D10!_(test)/sub_', 'complex title' );
 
                href = mw.util.getUrl();
                assert.equal( href, '/wiki/Foobar', 'default title' );
 
                href = mw.util.getUrl( null, { action: 'edit' } );
-               assert.equal( href, '/wiki/Foobar?action=edit', 'default title with query string' );
+               assert.equal( href, '/w/index.php?title=Foobar&action=edit', 'default title with query string' );
 
                href = mw.util.getUrl( 'Sandbox', { action: 'edit' } );
-               assert.equal( href, '/wiki/Sandbox?action=edit', 'simple title with query string' );
+               assert.equal( href, '/w/index.php?title=Sandbox&action=edit', 'simple title with query string' );
 
                // Test fragments
                href = mw.util.getUrl( 'Foo:Sandbox#Fragment', { action: 'edit' } );
-               assert.equal( href, '/wiki/Foo:Sandbox?action=edit#Fragment', 'advanced title with query string and fragment' );
+               assert.equal( href, '/w/index.php?title=Foo:Sandbox&action=edit#Fragment', 'namespaced title with query string and fragment' );
 
-               href = mw.util.getUrl( 'Foo:Sandbox#', { action: 'edit' } );
-               assert.equal( href, '/wiki/Foo:Sandbox?action=edit', 'title with query string and empty fragment' );
+               href = mw.util.getUrl( 'Sandbox#', { action: 'edit' } );
+               assert.equal( href, '/w/index.php?title=Sandbox&action=edit', 'title with query string and empty fragment' );
+
+               href = mw.util.getUrl( 'Sandbox', {} );
+               assert.equal( href, '/wiki/Sandbox', 'title with empty query string' );
 
                href = mw.util.getUrl( '#Fragment' );
-               assert.equal( href, '/wiki/#Fragment', 'epmty title with fragment' );
+               assert.equal( href, '/wiki/#Fragment', 'empty title with fragment' );
 
                href = mw.util.getUrl( '#Fragment', { action: 'edit' } );
-               assert.equal( href, '/wiki/?action=edit#Fragment', 'epmty title with query string and fragment' );
+               assert.equal( href, '/w/index.php?action=edit#Fragment', 'epmty title with query string and fragment' );
 
                href = mw.util.getUrl( 'Foo:Sandbox \xC4#Fragment \xC4', { action: 'edit' } );
-               assert.equal( href, '/wiki/Foo:Sandbox_%C3%84?action=edit#Fragment_.C3.84', 'title with query string, fragment, and special characters' );
+               assert.equal( href, '/w/index.php?title=Foo:Sandbox_%C3%84&action=edit#Fragment_.C3.84', 'title with query string, fragment, and special characters' );
 
                href = mw.util.getUrl( 'Foo:%23#Fragment', { action: 'edit' } );
-               assert.equal( href, '/wiki/Foo:%2523?action=edit#Fragment', 'title containing %23 (#), fragment, and a query string' );
+               assert.equal( href, '/w/index.php?title=Foo:%2523&action=edit#Fragment', 'title containing %23 (#), fragment, and a query string' );
 
                href = mw.util.getUrl( '#+&=:;@$-_.!*/[]<>\'§', { action: 'edit' } );
-               assert.equal( href, '/wiki/?action=edit#.2B.26.3D:.3B.40.24-_..21.2A.2F.5B.5D.3C.3E.27.C2.A7', 'fragment with various characters' );
+               assert.equal( href, '/w/index.php?action=edit#.2B.26.3D:.3B.40.24-_..21.2A.2F.5B.5D.3C.3E.27.C2.A7', 'fragment with various characters' );
        } );
 
        QUnit.test( 'wikiScript', 4, function ( assert ) {