Merge "Fix RestbaseVirtualRESTService URL standardization"
authorjenkins-bot <jenkins-bot@gerrit.wikimedia.org>
Tue, 5 Sep 2017 08:56:06 +0000 (08:56 +0000)
committerGerrit Code Review <gerrit@wikimedia.org>
Tue, 5 Sep 2017 08:56:06 +0000 (08:56 +0000)
325 files changed:
HISTORY
RELEASE-NOTES-1.30
autoload.php
composer.json
docs/ontology.owl [new file with mode: 0644]
includes/Block.php
includes/CategoriesRdf.php [new file with mode: 0644]
includes/CommentStore.php [new file with mode: 0644]
includes/CommentStoreComment.php [new file with mode: 0644]
includes/DefaultSettings.php
includes/EditPage.php
includes/FeedUtils.php
includes/Linker.php
includes/MagicWordArray.php
includes/MediaWiki.php
includes/PageProps.php
includes/Revision.php
includes/Title.php
includes/WatchedItemQueryService.php
includes/WikiMap.php
includes/actions/CreditsAction.php
includes/actions/InfoAction.php
includes/api/ApiEditPage.php
includes/api/ApiMove.php
includes/api/ApiQuery.php
includes/api/ApiQueryAllUsers.php
includes/api/ApiQueryBacklinks.php
includes/api/ApiQueryBase.php
includes/api/ApiQueryBlocks.php
includes/api/ApiQueryCategoryInfo.php
includes/api/ApiQueryDeletedrevs.php
includes/api/ApiQueryDuplicateFiles.php
includes/api/ApiQueryFilearchive.php
includes/api/ApiQueryImageInfo.php
includes/api/ApiQueryInfo.php
includes/api/ApiQueryLinks.php
includes/api/ApiQueryLogEvents.php
includes/api/ApiQueryProtectedTitles.php
includes/api/ApiQueryQueryPage.php
includes/api/ApiQueryRecentChanges.php
includes/api/ApiQueryRevisions.php
includes/api/ApiQueryUserContributions.php
includes/api/ApiQueryUsers.php
includes/api/ApiQueryWatchlist.php
includes/api/ApiSetNotificationTimestamp.php
includes/api/ApiUpload.php
includes/api/i18n/de.json
includes/api/i18n/es.json
includes/api/i18n/eu.json
includes/api/i18n/fr.json
includes/api/i18n/gl.json
includes/api/i18n/he.json
includes/api/i18n/it.json
includes/api/i18n/ko.json
includes/api/i18n/lb.json
includes/api/i18n/pt-br.json
includes/api/i18n/pt.json
includes/api/i18n/zh-hans.json
includes/auth/AuthManager.php
includes/cache/LinkBatch.php
includes/changes/ChangesListBooleanFilter.php
includes/changes/EnhancedChangesList.php
includes/changes/RecentChange.php
includes/config/EtcdConfig.php
includes/config/EtcdConfigParseError.php [new file with mode: 0644]
includes/db/DatabaseOracle.php
includes/deferred/CdnCacheUpdate.php
includes/deferred/DeferredUpdates.php
includes/deferred/LinksUpdate.php
includes/export/WikiExporter.php
includes/export/XmlDumpWriter.php
includes/externalstore/ExternalStoreDB.php
includes/filerepo/LocalRepo.php
includes/filerepo/file/ArchivedFile.php
includes/filerepo/file/File.php
includes/filerepo/file/LocalFile.php
includes/filerepo/file/OldLocalFile.php
includes/import/WikiImporter.php
includes/import/WikiRevision.php
includes/installer/DatabaseUpdater.php
includes/installer/Installer.php
includes/installer/MssqlInstaller.php
includes/installer/MysqlInstaller.php
includes/installer/MysqlUpdater.php
includes/installer/OracleUpdater.php
includes/installer/PostgresInstaller.php
includes/installer/PostgresUpdater.php
includes/installer/SqliteUpdater.php
includes/installer/i18n/da.json
includes/installer/i18n/es.json
includes/installer/i18n/eu.json
includes/installer/i18n/fr.json
includes/installer/i18n/pt-br.json
includes/installer/i18n/uk.json
includes/installer/i18n/vi.json
includes/jobqueue/JobQueueDB.php
includes/jobqueue/jobs/HTMLCacheUpdateJob.php
includes/libs/IP.php
includes/libs/filebackend/SwiftFileBackend.php
includes/libs/rdbms/ChronologyProtector.php
includes/libs/rdbms/database/DatabaseMysqli.php
includes/libs/rdbms/database/DatabasePostgres.php
includes/libs/rdbms/database/IDatabase.php
includes/libs/rdbms/database/resultwrapper/FakeResultWrapper.php
includes/libs/rdbms/database/utils/NextSequenceValue.php [new file with mode: 0644]
includes/libs/rdbms/exception/DBConnectionError.php
includes/libs/rdbms/exception/DBError.php
includes/libs/rdbms/exception/DBExpectedError.php
includes/libs/rdbms/exception/DBQueryError.php
includes/libs/rdbms/exception/DBTransactionSizeError.php
includes/libs/rdbms/lbfactory/ILBFactory.php
includes/libs/rdbms/loadbalancer/LoadBalancer.php
includes/libs/stats/SamplingStatsdClient.php
includes/logging/LogEntry.php
includes/logging/LogPage.php
includes/media/TransformationalImageHandler.php
includes/page/PageArchive.php
includes/page/WikiPage.php
includes/parser/CoreParserFunctions.php
includes/parser/Parser.php
includes/rcfeed/FormattedRCFeed.php
includes/rcfeed/IRCColourfulRCFeedFormatter.php
includes/resourceloader/ResourceLoaderStartUpModule.php
includes/revisiondelete/RevDelArchivedFileItem.php
includes/revisiondelete/RevDelList.php
includes/revisiondelete/RevDelLogItem.php
includes/revisiondelete/RevDelLogList.php
includes/site/DBSiteStore.php
includes/skins/Skin.php
includes/specialpage/AuthManagerSpecialPage.php
includes/specialpage/ChangesListSpecialPage.php
includes/specials/SpecialNewimages.php
includes/specials/SpecialNewpages.php
includes/specials/SpecialRecentchanges.php
includes/specials/SpecialUpload.php
includes/specials/SpecialWatchlist.php
includes/specials/pagers/BlockListPager.php
includes/specials/pagers/DeletedContribsPager.php
includes/specials/pagers/ImageListPager.php
includes/specials/pagers/NewPagesPager.php
includes/specials/pagers/ProtectedPagesPager.php
includes/upload/UploadFromUrl.php
includes/upload/UploadStash.php
includes/user/User.php
languages/data/Names.php
languages/i18n/ais.json [new file with mode: 0644]
languages/i18n/ar.json
languages/i18n/as.json
languages/i18n/az.json
languages/i18n/be-tarask.json
languages/i18n/bg.json
languages/i18n/bn.json
languages/i18n/br.json
languages/i18n/ca.json
languages/i18n/cdo.json
languages/i18n/ce.json
languages/i18n/ckb.json
languages/i18n/cs.json
languages/i18n/da.json
languages/i18n/de-formal.json
languages/i18n/de.json
languages/i18n/el.json
languages/i18n/en.json
languages/i18n/es.json
languages/i18n/et.json
languages/i18n/eu.json
languages/i18n/fa.json
languages/i18n/fi.json
languages/i18n/fr.json
languages/i18n/gor.json
languages/i18n/gu.json
languages/i18n/hak.json
languages/i18n/he.json
languages/i18n/hi.json
languages/i18n/hr.json
languages/i18n/hsb.json
languages/i18n/hu.json
languages/i18n/hy.json
languages/i18n/ia.json
languages/i18n/id.json
languages/i18n/is.json
languages/i18n/it.json
languages/i18n/ja.json
languages/i18n/jv.json
languages/i18n/kab.json
languages/i18n/ko.json
languages/i18n/ku-latn.json
languages/i18n/lb.json
languages/i18n/lt.json
languages/i18n/lv.json
languages/i18n/lzh.json
languages/i18n/mk.json
languages/i18n/mwl.json
languages/i18n/my.json
languages/i18n/nan.json
languages/i18n/nb.json
languages/i18n/ne.json
languages/i18n/nl.json
languages/i18n/nn.json
languages/i18n/or.json
languages/i18n/pl.json
languages/i18n/pt-br.json
languages/i18n/pt.json
languages/i18n/qqq.json
languages/i18n/roa-tara.json
languages/i18n/ru.json
languages/i18n/sd.json
languages/i18n/shi.json
languages/i18n/skr-arab.json
languages/i18n/sl.json
languages/i18n/sr-ec.json
languages/i18n/sr-el.json
languages/i18n/su.json
languages/i18n/sv.json
languages/i18n/tay.json
languages/i18n/th.json
languages/i18n/uk.json
languages/i18n/ur.json
languages/i18n/vi.json
languages/i18n/yi.json
languages/i18n/zh-hans.json
languages/i18n/zh-hant.json
languages/messages/MessagesTay.php [new file with mode: 0644]
maintenance/archives/patch-categorylinks-fix-pk.sql [new file with mode: 0644]
maintenance/archives/patch-comment-table.sql [new file with mode: 0644]
maintenance/archives/patch-imagelinks-fix-pk.sql [new file with mode: 0644]
maintenance/archives/patch-iwlinks-fix-pk.sql [new file with mode: 0644]
maintenance/archives/patch-langlinks-fix-pk.sql [new file with mode: 0644]
maintenance/archives/patch-log_search-fix-pk.sql [new file with mode: 0644]
maintenance/archives/patch-log_search-rename-index.sql [deleted file]
maintenance/archives/patch-module_deps-fix-pk.sql [new file with mode: 0644]
maintenance/archives/patch-objectcache-fix-pk.sql [new file with mode: 0644]
maintenance/archives/patch-pagelinks-fix-pk.sql [new file with mode: 0644]
maintenance/archives/patch-querycache_info-fix-pk.sql [new file with mode: 0644]
maintenance/archives/patch-site_stats-fix-pk.sql [new file with mode: 0644]
maintenance/archives/patch-templatelinks-fix-pk.sql [new file with mode: 0644]
maintenance/archives/patch-text-fix-pk.sql [new file with mode: 0644]
maintenance/archives/patch-transcache-fix-pk.sql [new file with mode: 0644]
maintenance/archives/patch-user_former_groups-fix-pk.sql [new file with mode: 0644]
maintenance/archives/patch-user_properties-fix-pk.sql [new file with mode: 0644]
maintenance/dumpCategoriesAsRdf.php [new file with mode: 0644]
maintenance/fixExtLinksProtocolRelative.php
maintenance/importDump.php
maintenance/migrateComments.php [new file with mode: 0644]
maintenance/oracle/archives/patch-auto_increment_triggers.sql [new file with mode: 0644]
maintenance/oracle/tables.sql
maintenance/orphans.php
maintenance/postgres/archives/patch-comment-table.sql [new file with mode: 0644]
maintenance/postgres/tables.sql
maintenance/rebuildrecentchanges.php
maintenance/sqlite/archives/patch-categorylinks-fix-pk.sql [new file with mode: 0644]
maintenance/sqlite/archives/patch-comment-table.sql [new file with mode: 0644]
maintenance/sqlite/archives/patch-imagelinks-fix-pk.sql [new file with mode: 0644]
maintenance/sqlite/archives/patch-iwlinks-fix-pk.sql [new file with mode: 0644]
maintenance/sqlite/archives/patch-langlinks-fix-pk.sql [new file with mode: 0644]
maintenance/sqlite/archives/patch-log_search-fix-pk.sql [new file with mode: 0644]
maintenance/sqlite/archives/patch-log_search-rename-index.sql [deleted file]
maintenance/sqlite/archives/patch-module_deps-fix-pk.sql [new file with mode: 0644]
maintenance/sqlite/archives/patch-objectcache-fix-pk.sql [new file with mode: 0644]
maintenance/sqlite/archives/patch-pagelinks-fix-pk.sql [new file with mode: 0644]
maintenance/sqlite/archives/patch-querycache_info-fix-pk.sql [new file with mode: 0644]
maintenance/sqlite/archives/patch-site_stats-fix-pk.sql [new file with mode: 0644]
maintenance/sqlite/archives/patch-templatelinks-fix-pk.sql [new file with mode: 0644]
maintenance/sqlite/archives/patch-text-fix-pk.sql [new file with mode: 0644]
maintenance/sqlite/archives/patch-transcache-fix-pk.sql [new file with mode: 0644]
maintenance/sqlite/archives/patch-user_former_groups-fix-pk.sql [new file with mode: 0644]
maintenance/sqlite/archives/patch-user_properties-fix-pk.sql [new file with mode: 0644]
maintenance/tables.sql
resources/Resources.php
resources/src/jquery/jquery.tablesorter.js
resources/src/mediawiki.action/mediawiki.action.edit.styles.css [deleted file]
resources/src/mediawiki.action/mediawiki.action.edit.styles.less [new file with mode: 0644]
resources/src/mediawiki.action/mediawiki.action.view.postEdit.js
resources/src/mediawiki.action/mediawiki.action.view.postEdit.less
resources/src/mediawiki.rcfilters/dm/mw.rcfilters.dm.FiltersViewModel.js
resources/src/mediawiki.rcfilters/dm/mw.rcfilters.dm.SavedQueriesModel.js
resources/src/mediawiki.rcfilters/mw.rcfilters.Controller.js
resources/src/mediawiki.rcfilters/mw.rcfilters.UriProcessor.js
resources/src/mediawiki.rcfilters/mw.rcfilters.init.js
resources/src/mediawiki.rcfilters/styles/mw.rcfilters.less
resources/src/mediawiki.rcfilters/styles/mw.rcfilters.mixins.less
resources/src/mediawiki.rcfilters/styles/mw.rcfilters.ui.ChangesListWrapperWidget.highlightCircles.seenunseen.less [new file with mode: 0644]
resources/src/mediawiki.rcfilters/styles/mw.rcfilters.ui.ChangesListWrapperWidget.less
resources/src/mediawiki.rcfilters/styles/mw.rcfilters.ui.FilterWrapperWidget.less
resources/src/mediawiki.rcfilters/styles/mw.rcfilters.ui.RcTopSectionWidget.less [new file with mode: 0644]
resources/src/mediawiki.rcfilters/styles/mw.rcfilters.ui.SavedLinksListItemWidget.less
resources/src/mediawiki.rcfilters/styles/mw.rcfilters.ui.SavedLinksListWidget.less
resources/src/mediawiki.rcfilters/styles/mw.rcfilters.ui.WatchlistTopSectionWidget.less [new file with mode: 0644]
resources/src/mediawiki.rcfilters/styles/mw.rcfilters.ui.less
resources/src/mediawiki.rcfilters/styles/mw.rcfilters.variables.less
resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.ChangesListWrapperWidget.js
resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.FilterWrapperWidget.js
resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.FormWrapperWidget.js
resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.MarkSeenButtonWidget.js
resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.RcTopSectionWidget.js [new file with mode: 0644]
resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.WatchlistTopSectionWidget.js [new file with mode: 0644]
resources/src/mediawiki.special/mediawiki.special.changeslist.legend.js
resources/src/mediawiki.special/mediawiki.special.search.interwikiwidget.styles.less
resources/src/mediawiki.toolbar/images/ksh/LICENSE
resources/src/mediawiki.widgets/MediaSearch/mw.widgets.MediaResultWidget.css
resources/src/mediawiki.widgets/mw.widgets.StashedFileWidget.less
resources/src/mediawiki.widgets/mw.widgets.TitleWidget.less
tests/parser/ParserTestRunner.php
tests/parser/parserTests.txt
tests/phpunit/MediaWikiTestCase.php
tests/phpunit/data/categoriesrdf/categoriesRdf-out.nt [new file with mode: 0644]
tests/phpunit/includes/CommentStoreTest.php [new file with mode: 0644]
tests/phpunit/includes/RevisionStorageTest.php
tests/phpunit/includes/WatchedItemQueryServiceUnitTest.php
tests/phpunit/includes/WikiMapTest.php
tests/phpunit/includes/api/ApiQueryWatchlistIntegrationTest.php
tests/phpunit/includes/auth/AuthManagerTest.php
tests/phpunit/includes/changes/ChangesListStringOptionsFilterGroupTest.php
tests/phpunit/includes/changes/RecentChangeTest.php
tests/phpunit/includes/changes/TestRecentChangesHelper.php
tests/phpunit/includes/config/EtcdConfigTest.php
tests/phpunit/includes/deferred/LinksUpdateTest.php
tests/phpunit/includes/libs/IPTest.php
tests/phpunit/includes/logging/LogFormatterTestCase.php
tests/phpunit/includes/page/WikiPageTest.php
tests/phpunit/includes/specials/SpecialPageDataTest.php
tests/phpunit/maintenance/categoriesRdfTest.php [new file with mode: 0644]
tests/phpunit/suites/ParserTestTopLevelSuite.php
tests/qunit/suites/resources/jquery/jquery.tablesorter.parsers.test.js
tests/selenium/wdio.conf.js

diff --git a/HISTORY b/HISTORY
index 9259814..0a2869d 100644 (file)
--- a/HISTORY
+++ b/HISTORY
@@ -699,6 +699,17 @@ There's usually someone online in #mediawiki on irc.freenode.net.
 
 = MediaWiki 1.27 =
 
+== MediaWiki 1.27.3 ==
+Due to a packaging error, the wrong version of the SyntaxHighlight extension was
+included in the tarball version of MediaWiki 1.27.2. The version included had a
+serious security issue in it (T158689). There was also some minor code fixes in
+MediaWiki itself since 1.27.2, but none of them were security relevant.
+
+=== Changes since 1.27.2 ===
+* (T145664) Fix broken wincache merge() implementation
+* (T163434) Add wikimedia/testing-access-wrapper for forwards compatibility
+* (T153505) Fix php warnings on php 7.1 due to use of &$this
+
 == MediaWiki 1.27.2 ==
 This is a security and maintenance release of the MediaWiki 1.27 branch.
 
index 13a9f4e..fb69bfd 100644 (file)
@@ -61,11 +61,11 @@ section).
   just been unwatched.
 * Added $wgParserTestMediaHandlers, where mock media handlers can be passed to
   MediaHandlerFactory for parser tests.
-
-=== Languages updated in 1.30 ===
-
-* Support for kbp (Kabɩyɛ / Kabiyè) was added.
-* Support for skr (Saraiki, سرائیکی) was added.
+* Edit summaries, block reasons, and other "comments" are now stored in a
+  separate database table. Use the CommentFormatter class to access them.
+** This is currently gated by $wgCommentTableSchemaMigrationStage. Most wikis
+   can set this to MIGRATION_NEW and run maintenance/migrateComments.php as
+   soon as any necessary extensions are updated.
 
 === External library changes in 1.30 ===
 
@@ -111,7 +111,9 @@ MediaWiki supports over 350 languages. Many localisations are updated
 regularly. Below only new and removed languages are listed, as well as
 changes to languages because of Phabricator reports.
 
-* …
+* Added: kbp (Kabɩyɛ / Kabiyè)
+* Added: skr (Saraiki, سرائیکی)
+* Added: tay (Tayal / Atayal)
 
 ==== Pig Latin added ====
 * (T45547) Added Pig Latin, a made-up English variant (en-x-piglatin),
@@ -155,6 +157,7 @@ changes to languages because of Phabricator reports.
   WikiPage::makeParserOptions() to create the ParserOptions object and only
   change options that affect the parser cache key.
 * Article::viewRedirect() is deprecated.
+* IP::isValidBlock() was deprecated. Use the equivalent IP::isValidRange().
 * DeprecatedGlobal no longer supports passing in a direct value, it requires a
   callable factory function or a class name.
 * The $parserMemc global, wfGetParserCacheStorage(), and ParserCache::singleton()
@@ -186,10 +189,20 @@ changes to languages because of Phabricator reports.
 * MWMemcached and MemCachedClientforWiki classes (deprecated in 1.27) were removed.
   The MemcachedClient class should be used instead.
 * EditPage::isOouiEnabled() is deprecated and will always return true.
+* EditPage::getSummaryInput() and ::getSummaryInputOOUI() are deprecated. Please
+  use ::getSummaryInputWidget() instead.
+* EditPage::getCheckboxes() and ::getCheckboxesOOUI() are deprecated. Please
+  use ::getCheckboxesWidget() instead.
 * Parser::getRandomString() (deprecated in 1.26) was removed.
 * Parser::uniqPrefix() (deprecated in 1.26) was removed.
-* Parser::extractTagsAndParams() now only accepts three arguments.  The fourth,
+* Parser::extractTagsAndParams() now only accepts three arguments. The fourth,
   $uniq_prefix was deprecated in 1.26 and has now been removed.
+* (T172514) The following tables have had their UNIQUE indexes turned into proper
+  PRIMARY KEYs for increased maintainability: categorylinks, imagelinks, iwlinks,
+  langlinks, log_search, module_deps, objectcache, pagelinks, query_cache, site_stats,
+  templatelinks, text, transcache, user_former_groups, user_properties.
+* IDatabase::nextSequenceValue() is no longer needed by any database backends
+  (formerly it was needed by PostgreSQL and Oracle), and is now deprecated.
 
 == Compatibility ==
 MediaWiki 1.30 requires PHP 5.5.9 or later. There is experimental support for
index 47b78fc..eab8e45 100644 (file)
@@ -219,6 +219,7 @@ $wgAutoloadLocalClasses = [
        'CachedBagOStuff' => __DIR__ . '/includes/libs/objectcache/CachedBagOStuff.php',
        'CachingSiteStore' => __DIR__ . '/includes/site/CachingSiteStore.php',
        'CapsCleanup' => __DIR__ . '/maintenance/cleanupCaps.php',
+       'CategoriesRdf' => __DIR__ . '/includes/CategoriesRdf.php',
        'Category' => __DIR__ . '/includes/Category.php',
        'CategoryFinder' => __DIR__ . '/includes/CategoryFinder.php',
        'CategoryMembershipChange' => __DIR__ . '/includes/changes/CategoryMembershipChange.php',
@@ -275,6 +276,8 @@ $wgAutoloadLocalClasses = [
        'CollationFa' => __DIR__ . '/includes/collation/CollationFa.php',
        'CommandLineInc' => __DIR__ . '/maintenance/commandLine.inc',
        'CommandLineInstaller' => __DIR__ . '/maintenance/install.php',
+       'CommentStore' => __DIR__ . '/includes/CommentStore.php',
+       'CommentStoreComment' => __DIR__ . '/includes/CommentStoreComment.php',
        'CompareParserCache' => __DIR__ . '/maintenance/compareParserCache.php',
        'CompareParsers' => __DIR__ . '/maintenance/compareParsers.php',
        'ComposerHookHandler' => __DIR__ . '/includes/composer/ComposerHookHandler.php',
@@ -397,6 +400,7 @@ $wgAutoloadLocalClasses = [
        'Dump7ZipOutput' => __DIR__ . '/includes/export/Dump7ZipOutput.php',
        'DumpBZip2Output' => __DIR__ . '/includes/export/DumpBZip2Output.php',
        'DumpBackup' => __DIR__ . '/maintenance/dumpBackup.php',
+       'DumpCategoriesAsRdf' => __DIR__ . '/maintenance/dumpCategoriesAsRdf.php',
        'DumpDBZip2Output' => __DIR__ . '/includes/export/DumpDBZip2Output.php',
        'DumpFileOutput' => __DIR__ . '/includes/export/DumpFileOutput.php',
        'DumpFilter' => __DIR__ . '/includes/export/DumpFilter.php',
@@ -433,6 +437,7 @@ $wgAutoloadLocalClasses = [
        'EraseArchivedFile' => __DIR__ . '/maintenance/eraseArchivedFile.php',
        'ErrorPageError' => __DIR__ . '/includes/exception/ErrorPageError.php',
        'EtcdConfig' => __DIR__ . '/includes/config/EtcdConfig.php',
+       'EtcdConfigParseError' => __DIR__ . '/includes/config/EtcdConfigParseError.php',
        'EventRelayer' => __DIR__ . '/includes/libs/eventrelayer/EventRelayer.php',
        'EventRelayerGroup' => __DIR__ . '/includes/EventRelayerGroup.php',
        'EventRelayerKafka' => __DIR__ . '/includes/libs/eventrelayer/EventRelayerKafka.php',
@@ -980,6 +985,7 @@ $wgAutoloadLocalClasses = [
        'MessageContent' => __DIR__ . '/includes/content/MessageContent.php',
        'MessageLocalizer' => __DIR__ . '/languages/MessageLocalizer.php',
        'MessageSpecifier' => __DIR__ . '/includes/libs/MessageSpecifier.php',
+       'MigrateComments' => __DIR__ . '/maintenance/migrateComments.php',
        'MigrateFileRepoLayout' => __DIR__ . '/maintenance/migrateFileRepoLayout.php',
        'MigrateUserGroup' => __DIR__ . '/maintenance/migrateUserGroup.php',
        'MimeAnalyzer' => __DIR__ . '/includes/libs/mime/MimeAnalyzer.php',
@@ -1661,6 +1667,7 @@ $wgAutoloadLocalClasses = [
        'Wikimedia\\Rdbms\\MssqlResultWrapper' => __DIR__ . '/includes/libs/rdbms/database/resultwrapper/MssqlResultWrapper.php',
        'Wikimedia\\Rdbms\\MySQLField' => __DIR__ . '/includes/libs/rdbms/field/MySQLField.php',
        'Wikimedia\\Rdbms\\MySQLMasterPos' => __DIR__ . '/includes/libs/rdbms/database/position/MySQLMasterPos.php',
+       'Wikimedia\\Rdbms\\NextSequenceValue' => __DIR__ . '/includes/libs/rdbms/database/utils/NextSequenceValue.php',
        'Wikimedia\\Rdbms\\PostgresBlob' => __DIR__ . '/includes/libs/rdbms/encasing/PostgresBlob.php',
        'Wikimedia\\Rdbms\\PostgresField' => __DIR__ . '/includes/libs/rdbms/field/PostgresField.php',
        'Wikimedia\\Rdbms\\ResultWrapper' => __DIR__ . '/includes/libs/rdbms/database/resultwrapper/ResultWrapper.php',
index d6379e4..a7983a0 100644 (file)
@@ -37,6 +37,7 @@
                "wikimedia/html-formatter": "1.0.1",
                "wikimedia/ip-set": "1.1.0",
                "wikimedia/php-session-serializer": "1.0.4",
+               "wikimedia/purtle": "1.0.6",
                "wikimedia/relpath": "2.0.0",
                "wikimedia/remex-html": "1.0.1",
                "wikimedia/running-stat": "1.1.0",
diff --git a/docs/ontology.owl b/docs/ontology.owl
new file mode 100644 (file)
index 0000000..6b2e0b7
--- /dev/null
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!DOCTYPE rdf:RDF [
+  <!ENTITY xsd "http://www.w3.org/2001/XMLSchema#">
+  <!ENTITY rdf "http://www.w3.org/1999/02/22-rdf-syntax-ns#">
+  <!ENTITY rdfs "http://www.w3.org/2000/01/rdf-schema#">
+  <!ENTITY owl "http://www.w3.org/2002/07/owl#">
+  <!ENTITY mediawiki "https://www.mediawiki.org/ontology#">
+]>
+
+<rdf:RDF
+  xmlns:xsd="&xsd;"
+  xmlns:rdf="&rdf;"
+  xmlns:rdfs="&rdfs;"
+  xmlns:owl="&owl;"
+>
+
+  <owl:Ontology rdf:about="&mediawiki;">
+    <rdfs:label>MediaWiki ontology</rdfs:label>
+    <rdfs:comment>The ontology of MediaWiki</rdfs:comment>
+  </owl:Ontology>
+
+  <!--
+  ///////////////////////////////////////////////////////////////////////////////////////
+  //
+  // Classes
+  //
+  ///////////////////////////////////////////////////////////////////////////////////////
+  -->
+
+  <owl:Class rdf:about="&mediawiki;Dump">
+    <rdfs:label>Dump</rdfs:label>
+    <rdfs:comment>A dump of MediaWiki content.</rdfs:comment>
+  </owl:Class>
+
+  <owl:Class rdf:about="&mediawiki;Category">
+    <rdfs:label>Category</rdfs:label>
+    <rdfs:comment>MediaWiki category.</rdfs:comment>
+  </owl:Class>
+
+  <!--
+  ///////////////////////////////////////////////////////////////////////////////////////
+  //
+  // Properties
+  //
+  ///////////////////////////////////////////////////////////////////////////////////////
+  -->
+
+  <owl:ObjectProperty rdf:about="&mediawiki;isInCategory">
+      <rdfs:label>isInCategory</rdfs:label>
+      <rdfs:comment>One category is the parent of another.</rdfs:comment>
+      <rdfs:range rdf:resource="&mediawiki;Category"/>
+      <rdfs:domain rdf:resource="&mediawiki;Category"/>
+  </owl:ObjectProperty>
+
+</rdf:RDF>
index 5066038..40095f1 100644 (file)
@@ -199,6 +199,8 @@ class Block {
        /**
         * Return the list of ipblocks fields that should be selected to create
         * a new block.
+        * @todo Deprecate this in favor of a method that returns tables and joins
+        *  as well, and use CommentStore::getJoin().
         * @return array
         */
        public static function selectFields() {
@@ -207,7 +209,6 @@ class Block {
                        'ipb_address',
                        'ipb_by',
                        'ipb_by_text',
-                       'ipb_reason',
                        'ipb_timestamp',
                        'ipb_auto',
                        'ipb_anon_only',
@@ -218,7 +219,7 @@ class Block {
                        'ipb_block_email',
                        'ipb_allow_usertalk',
                        'ipb_parent_block_id',
-               ];
+               ] + CommentStore::newKey( 'ipb_reason' )->getFields();
        }
 
        /**
@@ -411,7 +412,6 @@ class Block {
                        $this->setBlocker( $row->ipb_by_text );
                }
 
-               $this->mReason = $row->ipb_reason;
                $this->mTimestamp = wfTimestamp( TS_MW, $row->ipb_timestamp );
                $this->mAuto = $row->ipb_auto;
                $this->mHideName = $row->ipb_deleted;
@@ -419,7 +419,11 @@ class Block {
                $this->mParentBlockId = $row->ipb_parent_block_id;
 
                // I wish I didn't have to do this
-               $this->mExpiry = wfGetDB( DB_REPLICA )->decodeExpiry( $row->ipb_expiry );
+               $db = wfGetDB( DB_REPLICA );
+               $this->mExpiry = $db->decodeExpiry( $row->ipb_expiry );
+               $this->mReason = CommentStore::newKey( 'ipb_reason' )
+                       // Legacy because $row probably came from self::selectFields()
+                       ->getCommentLegacy( $db, $row )->text;
 
                $this->isHardblock( !$row->ipb_anon_only );
                $this->isAutoblocking( $row->ipb_enable_autoblock );
@@ -488,8 +492,7 @@ class Block {
                        self::purgeExpired();
                }
 
-               $row = $this->getDatabaseArray();
-               $row['ipb_id'] = $dbw->nextSequenceValue( "ipblocks_ipb_id_seq" );
+               $row = $this->getDatabaseArray( $dbw );
 
                $dbw->insert( 'ipblocks', $row, __METHOD__, [ 'IGNORE' ] );
                $affected = $dbw->affectedRows();
@@ -558,7 +561,7 @@ class Block {
                        // update corresponding autoblock(s) (T50813)
                        $dbw->update(
                                'ipblocks',
-                               $this->getAutoblockUpdateArray(),
+                               $this->getAutoblockUpdateArray( $dbw ),
                                [ 'ipb_parent_block_id' => $this->getId() ],
                                __METHOD__
                        );
@@ -583,14 +586,11 @@ class Block {
 
        /**
         * Get an array suitable for passing to $dbw->insert() or $dbw->update()
-        * @param IDatabase $db
+        * @param IDatabase $dbw
         * @return array
         */
-       protected function getDatabaseArray( $db = null ) {
-               if ( !$db ) {
-                       $db = wfGetDB( DB_REPLICA );
-               }
-               $expiry = $db->encodeExpiry( $this->mExpiry );
+       protected function getDatabaseArray( IDatabase $dbw ) {
+               $expiry = $dbw->encodeExpiry( $this->mExpiry );
 
                if ( $this->forcedTargetID ) {
                        $uid = $this->forcedTargetID;
@@ -603,8 +603,7 @@ class Block {
                        'ipb_user'             => $uid,
                        'ipb_by'               => $this->getBy(),
                        'ipb_by_text'          => $this->getByName(),
-                       'ipb_reason'           => $this->mReason,
-                       'ipb_timestamp'        => $db->timestamp( $this->mTimestamp ),
+                       'ipb_timestamp'        => $dbw->timestamp( $this->mTimestamp ),
                        'ipb_auto'             => $this->mAuto,
                        'ipb_anon_only'        => !$this->isHardblock(),
                        'ipb_create_account'   => $this->prevents( 'createaccount' ),
@@ -616,23 +615,23 @@ class Block {
                        'ipb_block_email'      => $this->prevents( 'sendemail' ),
                        'ipb_allow_usertalk'   => !$this->prevents( 'editownusertalk' ),
                        'ipb_parent_block_id'  => $this->mParentBlockId
-               ];
+               ] + CommentStore::newKey( 'ipb_reason' )->insert( $dbw, $this->mReason );
 
                return $a;
        }
 
        /**
+        * @param IDatabase $dbw
         * @return array
         */
-       protected function getAutoblockUpdateArray() {
+       protected function getAutoblockUpdateArray( IDatabase $dbw ) {
                return [
                        'ipb_by'               => $this->getBy(),
                        'ipb_by_text'          => $this->getByName(),
-                       'ipb_reason'           => $this->mReason,
                        'ipb_create_account'   => $this->prevents( 'createaccount' ),
                        'ipb_deleted'          => (int)$this->mHideName, // typecast required for SQLite
                        'ipb_allow_usertalk'   => !$this->prevents( 'editownusertalk' ),
-               ];
+               ] + CommentStore::newKey( 'ipb_reason' )->insert( $dbw, $this->mReason );
        }
 
        /**
@@ -1354,7 +1353,7 @@ class Block {
                                self::TYPE_IP
                        ];
 
-               } elseif ( IP::isValidBlock( $target ) ) {
+               } elseif ( IP::isValidRange( $target ) ) {
                        # Can't create a User from an IP range
                        return [ IP::sanitizeRange( $target ), self::TYPE_RANGE ];
                }
diff --git a/includes/CategoriesRdf.php b/includes/CategoriesRdf.php
new file mode 100644 (file)
index 0000000..e19dc2a
--- /dev/null
@@ -0,0 +1,95 @@
+<?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
+ *
+ */
+use Wikimedia\Purtle\RdfWriter;
+
+/**
+ * Helper class to produce RDF representation of categories.
+ */
+class CategoriesRdf {
+       /**
+        * Prefix used for Mediawiki ontology in the dump.
+        */
+       const ONTOLOGY_PREFIX = 'mediawiki';
+       /**
+        * Base URL for Mediawiki ontology.
+        */
+       const ONTOLOGY_URL = 'https://www.mediawiki.org/ontology#';
+       /**
+        * OWL description of the ontology.
+        */
+       const OWL_URL = 'https://www.mediawiki.org/ontology/ontology.owl';
+       /**
+        * Current version of the dump format.
+        */
+       const FORMAT_VERSION = "1.0";
+       /**
+        * @var RdfWriter
+        */
+       private $rdfWriter;
+
+       public function __construct( RdfWriter $writer ) {
+               $this->rdfWriter = $writer;
+       }
+
+       /**
+        * Setup prefixes relevant for the dump
+        */
+       public function setupPrefixes() {
+               $this->rdfWriter->prefix( self::ONTOLOGY_PREFIX, self::ONTOLOGY_URL );
+               $this->rdfWriter->prefix( 'rdfs', 'http://www.w3.org/2000/01/rdf-schema#' );
+               $this->rdfWriter->prefix( 'owl', 'http://www.w3.org/2002/07/owl#' );
+               $this->rdfWriter->prefix( 'schema', 'http://schema.org/' );
+               $this->rdfWriter->prefix( 'cc', 'http://creativecommons.org/ns#' );
+       }
+
+       /**
+        * Write RDF data for link between categories.
+        * @param string $fromName Child category name
+        * @param string $toName Parent category name
+        */
+       public function writeCategoryLinkData( $fromName, $toName ) {
+               $titleFrom = Title::makeTitle( NS_CATEGORY, $fromName );
+               $titleTo = Title::makeTitle( NS_CATEGORY, $toName );
+               $this->rdfWriter->about( $this->titleToUrl( $titleFrom ) )
+                       ->say( self::ONTOLOGY_PREFIX, 'isInCategory' )
+                       ->is( $this->titleToUrl( $titleTo ) );
+       }
+
+       /**
+        * Write out the data for single category.
+        * @param string $categoryName Category name
+        */
+       public function writeCategoryData( $categoryName ) {
+               $title = Title::makeTitle( NS_CATEGORY, $categoryName );
+               $this->rdfWriter->about( $this->titleToUrl( $title ) )
+                       ->say( 'a' )
+                       ->is( self::ONTOLOGY_PREFIX, 'Category' );
+               $titletext = $title->getText();
+               $this->rdfWriter->say( 'rdfs', 'label' )->value( $titletext );
+       }
+
+       /**
+        * Convert Title to link to target page.
+        * @param Title $title
+        * @return string
+        */
+       private function titleToUrl( Title $title ) {
+               return $title->getFullURL( '', false, PROTO_CANONICAL );
+       }
+}
diff --git a/includes/CommentStore.php b/includes/CommentStore.php
new file mode 100644 (file)
index 0000000..fdfa6d9
--- /dev/null
@@ -0,0 +1,565 @@
+<?php
+/**
+ * Manage storage of comments in the database
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (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 Wikimedia\Rdbms\IDatabase;
+
+/**
+ * CommentStore handles storage of comments (edit summaries, log reasons, etc)
+ * in the database.
+ * @since 1.30
+ */
+class CommentStore {
+
+       /**
+        * Define fields that use temporary tables for transitional purposes
+        * @var array Keys are '$key', values are arrays with four fields:
+        *  - table: Temporary table name
+        *  - pk: Temporary table column referring to the main table's primary key
+        *  - field: Temporary table column referring comment.comment_id
+        *  - joinPK: Main table's primary key
+        */
+       protected static $tempTables = [
+               'rev_comment' => [
+                       'table' => 'revision_comment_temp',
+                       'pk' => 'revcomment_rev',
+                       'field' => 'revcomment_comment_id',
+                       'joinPK' => 'rev_id',
+               ],
+               'img_description' => [
+                       'table' => 'image_comment_temp',
+                       'pk' => 'imgcomment_name',
+                       'field' => 'imgcomment_description_id',
+                       'joinPK' => 'img_name',
+               ],
+       ];
+
+       /**
+        * Fields that formerly used $tempTables
+        * @var array Key is '$key', value is the MediaWiki version in which it was
+        *  removed from $tempTables.
+        */
+       protected static $formerTempTables = [];
+
+       /** @var string */
+       protected $key;
+
+       /** @var int One of the MIGRATION_* constants */
+       protected $stage;
+
+       /** @var array|null Cache for `self::getJoin()` */
+       protected $joinCache = null;
+
+       /**
+        * @param string $key A key such as "rev_comment" identifying the comment
+        *  field being fetched.
+        */
+       public function __construct( $key ) {
+               global $wgCommentTableSchemaMigrationStage;
+
+               $this->key = $key;
+               $this->stage = $wgCommentTableSchemaMigrationStage;
+       }
+
+       /**
+        * Static constructor for easier chaining
+        * @param string $key A key such as "rev_comment" identifying the comment
+        *  field being fetched.
+        * @return CommentStore
+        */
+       public static function newKey( $key ) {
+               return new CommentStore( $key );
+       }
+
+       /**
+        * Get SELECT fields for the comment key
+        *
+        * Each resulting row should be passed to `self::getCommentLegacy()` to get the
+        * actual comment.
+        *
+        * @note Use of this method may require a subsequent database query to
+        *  actually fetch the comment. If possible, use `self::getJoin()` instead.
+        * @return string[] to include in the `$vars` to `IDatabase->select()`. All
+        *  fields are aliased, so `+` is safe to use.
+        */
+       public function getFields() {
+               $fields = [];
+               if ( $this->stage === MIGRATION_OLD ) {
+                       $fields["{$this->key}_text"] = $this->key;
+                       $fields["{$this->key}_data"] = 'NULL';
+                       $fields["{$this->key}_cid"] = 'NULL';
+               } else {
+                       if ( $this->stage < MIGRATION_NEW ) {
+                               $fields["{$this->key}_old"] = $this->key;
+                       }
+                       if ( isset( self::$tempTables[$this->key] ) ) {
+                               $fields["{$this->key}_pk"] = self::$tempTables[$this->key]['joinPK'];
+                       } else {
+                               $fields["{$this->key}_id"] = "{$this->key}_id";
+                       }
+               }
+               return $fields;
+       }
+
+       /**
+        * Get SELECT fields and joins for the comment key
+        *
+        * Each resulting row should be passed to `self::getComment()` to get the
+        * actual comment.
+        *
+        * @return array With three keys:
+        *   - tables: (string[]) to include in the `$table` to `IDatabase->select()`
+        *   - fields: (string[]) to include in the `$vars` to `IDatabase->select()`
+        *   - joins: (array) to include in the `$join_conds` to `IDatabase->select()`
+        *  All tables, fields, and joins are aliased, so `+` is safe to use.
+        */
+       public function getJoin() {
+               if ( $this->joinCache === null ) {
+                       $tables = [];
+                       $fields = [];
+                       $joins = [];
+
+                       if ( $this->stage === MIGRATION_OLD ) {
+                               $fields["{$this->key}_text"] = $this->key;
+                               $fields["{$this->key}_data"] = 'NULL';
+                               $fields["{$this->key}_cid"] = 'NULL';
+                       } else {
+                               $join = $this->stage === MIGRATION_NEW ? 'JOIN' : 'LEFT JOIN';
+
+                               if ( isset( self::$tempTables[$this->key] ) ) {
+                                       $t = self::$tempTables[$this->key];
+                                       $alias = "temp_$this->key";
+                                       $tables[$alias] = $t['table'];
+                                       $joins[$alias] = [ $join, "{$alias}.{$t['pk']} = {$t['joinPK']}" ];
+                                       $joinField = "{$alias}.{$t['field']}";
+                               } else {
+                                       $joinField = "{$this->key}_id";
+                               }
+
+                               $alias = "comment_$this->key";
+                               $tables[$alias] = 'comment';
+                               $joins[$alias] = [ $join, "{$alias}.comment_id = {$joinField}" ];
+
+                               if ( $this->stage === MIGRATION_NEW ) {
+                                       $fields["{$this->key}_text"] = "{$alias}.comment_text";
+                               } else {
+                                       $fields["{$this->key}_text"] = "COALESCE( {$alias}.comment_text, $this->key )";
+                               }
+                               $fields["{$this->key}_data"] = "{$alias}.comment_data";
+                               $fields["{$this->key}_cid"] = "{$alias}.comment_id";
+                       }
+
+                       $this->joinCache = [
+                               'tables' => $tables,
+                               'fields' => $fields,
+                               'joins' => $joins,
+                       ];
+               }
+
+               return $this->joinCache;
+       }
+
+       /**
+        * Extract the comment from a row
+        *
+        * Shared implementation for getComment() and getCommentLegacy()
+        *
+        * @param IDatabase|null $db Database handle for getCommentLegacy(), or null for getComment()
+        * @param object|array $row
+        * @param bool $fallback
+        * @return CommentStoreComment
+        */
+       private function getCommentInternal( IDatabase $db = null, $row, $fallback = false ) {
+               $key = $this->key;
+               $row = (array)$row;
+               if ( array_key_exists( "{$key}_text", $row ) && array_key_exists( "{$key}_data", $row ) ) {
+                       $cid = isset( $row["{$key}_cid"] ) ? $row["{$key}_cid"] : null;
+                       $text = $row["{$key}_text"];
+                       $data = $row["{$key}_data"];
+               } elseif ( $this->stage === MIGRATION_OLD ) {
+                       $cid = null;
+                       if ( $fallback && isset( $row[$key] ) ) {
+                               wfLogWarning( "Using deprecated fallback handling for comment $key" );
+                               $text = $row[$key];
+                       } else {
+                               wfLogWarning( "Missing {$key}_text and {$key}_data fields in row with MIGRATION_OLD" );
+                               $text = '';
+                       }
+                       $data = null;
+               } else {
+                       if ( isset( self::$tempTables[$key] ) ) {
+                               if ( array_key_exists( "{$key}_pk", $row ) ) {
+                                       if ( !$db ) {
+                                               throw new InvalidArgumentException(
+                                                       "\$row does not contain fields needed for comment $key and getComment(), but "
+                                                       . "does have fields for getCommentLegacy()"
+                                               );
+                                       }
+                                       $t = self::$tempTables[$key];
+                                       $id = $row["{$key}_pk"];
+                                       $row2 = $db->selectRow(
+                                               [ $t['table'], 'comment' ],
+                                               [ 'comment_id', 'comment_text', 'comment_data' ],
+                                               [ $t['pk'] => $id ],
+                                               __METHOD__,
+                                               [],
+                                               [ 'comment' => [ 'JOIN', [ "comment_id = {$t['field']}" ] ] ]
+                                       );
+                               } elseif ( $fallback && isset( $row[$key] ) ) {
+                                       wfLogWarning( "Using deprecated fallback handling for comment $key" );
+                                       $row2 = (object)[ 'comment_text' => $row[$key], 'comment_data' => null ];
+                               } else {
+                                       throw new InvalidArgumentException( "\$row does not contain fields needed for comment $key" );
+                               }
+                       } else {
+                               if ( array_key_exists( "{$key}_id", $row ) ) {
+                                       if ( !$db ) {
+                                               throw new InvalidArgumentException(
+                                                       "\$row does not contain fields needed for comment $key and getComment(), but "
+                                                       . "does have fields for getCommentLegacy()"
+                                               );
+                                       }
+                                       $id = $row["{$key}_id"];
+                                       $row2 = $db->selectRow(
+                                               'comment',
+                                               [ 'comment_id', 'comment_text', 'comment_data' ],
+                                               [ 'comment_id' => $id ],
+                                               __METHOD__
+                                       );
+                               } elseif ( $fallback && isset( $row[$key] ) ) {
+                                       wfLogWarning( "Using deprecated fallback handling for comment $key" );
+                                       $row2 = (object)[ 'comment_text' => $row[$key], 'comment_data' => null ];
+                               } else {
+                                       throw new InvalidArgumentException( "\$row does not contain fields needed for comment $key" );
+                               }
+                       }
+
+                       if ( $row2 ) {
+                               $cid = $row2->comment_id;
+                               $text = $row2->comment_text;
+                               $data = $row2->comment_data;
+                       } elseif ( $this->stage < MIGRATION_NEW && array_key_exists( "{$key}_old", $row ) ) {
+                               $cid = null;
+                               $text = $row["{$key}_old"];
+                               $data = null;
+                       } else {
+                               // @codeCoverageIgnoreStart
+                               wfLogWarning( "Missing comment row for $key, id=$id" );
+                               $cid = null;
+                               $text = '';
+                               $data = null;
+                               // @codeCoverageIgnoreEnd
+                       }
+               }
+
+               $msg = null;
+               if ( $data !== null ) {
+                       $data = FormatJson::decode( $data );
+                       if ( !is_object( $data ) ) {
+                               // @codeCoverageIgnoreStart
+                               wfLogWarning( "Invalid JSON object in comment: $data" );
+                               $data = null;
+                               // @codeCoverageIgnoreEnd
+                       } else {
+                               $data = (array)$data;
+                               if ( isset( $data['_message'] ) ) {
+                                       $msg = self::decodeMessage( $data['_message'] )
+                                               ->setInterfaceMessageFlag( true );
+                               }
+                               if ( !empty( $data['_null'] ) ) {
+                                       $data = null;
+                               } else {
+                                       foreach ( $data as $k => $v ) {
+                                               if ( substr( $k, 0, 1 ) === '_' ) {
+                                                       unset( $data[$k] );
+                                               }
+                                       }
+                               }
+                       }
+               }
+
+               return new CommentStoreComment( $cid, $text, $msg, $data );
+       }
+
+       /**
+        * Extract the comment from a row
+        *
+        * Use `self::getJoin()` to ensure the row contains the needed data.
+        *
+        * If you need to fake a comment in a row for some reason, set fields
+        * `{$key}_text` (string) and `{$key}_data` (JSON string or null).
+        *
+        * @param object|array $row Result row.
+        * @param bool $fallback If true, fall back as well as possible instead of throwing an exception.
+        * @return CommentStoreComment
+        */
+       public function getComment( $row, $fallback = false ) {
+               return $this->getCommentInternal( null, $row, $fallback );
+       }
+
+       /**
+        * Extract the comment from a row, with legacy lookups.
+        *
+        * If `$row` might have been generated using `self::getFields()` rather
+        * than `self::getJoin()`, use this. Prefer `self::getComment()` if you
+        * know callers used `self::getJoin()` for the row fetch.
+        *
+        * If you need to fake a comment in a row for some reason, set fields
+        * `{$key}_text` (string) and `{$key}_data` (JSON string or null).
+        *
+        * @param IDatabase $db Database handle to use for lookup
+        * @param object|array $row Result row.
+        * @param bool $fallback If true, fall back as well as possible instead of throwing an exception.
+        * @return CommentStoreComment
+        */
+       public function getCommentLegacy( IDatabase $db, $row, $fallback = false ) {
+               return $this->getCommentInternal( $db, $row, $fallback );
+       }
+
+       /**
+        * Create a new CommentStoreComment, inserting it into the database if necessary
+        *
+        * If a comment is going to be passed to `self::insert()` or the like
+        * multiple times, it will be more efficient to pass a CommentStoreComment
+        * once rather than making `self::insert()` do it every time through.
+        *
+        * @note When passing a CommentStoreComment, this may set `$comment->id` if
+        *  it's not already set. If `$comment->id` is already set, it will not be
+        *  verified that the specified comment actually exists or that it
+        *  corresponds to the comment text, message, and/or data in the
+        *  CommentStoreComment.
+        * @param IDatabase $dbw Database handle to insert on. Unused if `$comment`
+        *  is a CommentStoreComment and `$comment->id` is set.
+        * @param string|Message|CommentStoreComment $comment Comment text or Message object, or
+        *  a CommentStoreComment.
+        * @param array|null $data Structured data to store. Keys beginning with '_' are reserved.
+        *  Ignored if $comment is a CommentStoreComment.
+        * @return CommentStoreComment
+        */
+       public function createComment( IDatabase $dbw, $comment, array $data = null ) {
+               global $wgContLang;
+
+               if ( !$comment instanceof CommentStoreComment ) {
+                       if ( $data !== null ) {
+                               foreach ( $data as $k => $v ) {
+                                       if ( substr( $k, 0, 1 ) === '_' ) {
+                                               throw new InvalidArgumentException( 'Keys in $data beginning with "_" are reserved' );
+                                       }
+                               }
+                       }
+                       if ( $comment instanceof Message ) {
+                               $message = clone $comment;
+                               $text = $message->inLanguage( $wgContLang ) // Avoid $wgForceUIMsgAsContentMsg
+                                       ->setInterfaceMessageFlag( true )
+                                       ->text();
+                               $comment = new CommentStoreComment( null, $text, $message, $data );
+                       } else {
+                               $comment = new CommentStoreComment( null, $comment, null, $data );
+                       }
+               }
+
+               if ( $this->stage > MIGRATION_OLD && !$comment->id ) {
+                       $dbData = $comment->data;
+                       if ( !$comment->message instanceof RawMessage ) {
+                               if ( $dbData === null ) {
+                                       $dbData = [ '_null' => true ];
+                               }
+                               $dbData['_message'] = self::encodeMessage( $comment->message );
+                       }
+                       if ( $dbData !== null ) {
+                               $dbData = FormatJson::encode( (object)$dbData, false, FormatJson::ALL_OK );
+                       }
+
+                       $hash = self::hash( $comment->text, $dbData );
+                       $comment->id = $dbw->selectField(
+                               'comment',
+                               'comment_id',
+                               [
+                                       'comment_hash' => $hash,
+                                       'comment_text' => $comment->text,
+                                       'comment_data' => $dbData,
+                               ],
+                               __METHOD__
+                       );
+                       if ( !$comment->id ) {
+                               $dbw->insert(
+                                       'comment',
+                                       [
+                                               'comment_hash' => $hash,
+                                               'comment_text' => $comment->text,
+                                               'comment_data' => $dbData,
+                                       ],
+                                       __METHOD__
+                               );
+                               $comment->id = $dbw->insertId();
+                       }
+               }
+
+               return $comment;
+       }
+
+       /**
+        * Implementation for `self::insert()` and `self::insertWithTempTable()`
+        * @param IDatabase $dbw
+        * @param string|Message|CommentStoreComment $comment
+        * @param array|null $data
+        * @return array [ array $fields, callable $callback ]
+        */
+       private function insertInternal( IDatabase $dbw, $comment, $data ) {
+               $fields = [];
+               $callback = null;
+
+               $comment = $this->createComment( $dbw, $comment, $data );
+
+               if ( $this->stage <= MIGRATION_WRITE_BOTH ) {
+                       $fields[$this->key] = $comment->text;
+               }
+
+               if ( $this->stage >= MIGRATION_WRITE_BOTH ) {
+                       if ( isset( self::$tempTables[$this->key] ) ) {
+                               $t = self::$tempTables[$this->key];
+                               $func = __METHOD__;
+                               $commentId = $comment->id;
+                               $callback = function ( $id ) use ( $dbw, $commentId, $t, $func ) {
+                                       $dbw->insert(
+                                               $t['table'],
+                                               [
+                                                       $t['pk'] => $id,
+                                                       $t['field'] => $commentId,
+                                               ],
+                                               $func
+                                       );
+                               };
+                       } else {
+                               $fields["{$this->key}_id"] = $comment->id;
+                       }
+               }
+
+               return [ $fields, $callback ];
+       }
+
+       /**
+        * Prepare for the insertion of a row with a comment
+        *
+        * @note It's recommended to include both the call to this method and the
+        *  row insert in the same transaction.
+        * @param IDatabase $dbw Database handle to insert on
+        * @param string|Message|CommentStoreComment $comment As for `self::createComment()`
+        * @param array|null $data As for `self::createComment()`
+        * @return array Fields for the insert or update
+        */
+       public function insert( IDatabase $dbw, $comment, $data = null ) {
+               if ( isset( self::$tempTables[$this->key] ) ) {
+                       throw new InvalidArgumentException( "Must use insertWithTempTable() for $this->key" );
+               }
+
+               list( $fields ) = $this->insertInternal( $dbw, $comment, $data );
+               return $fields;
+       }
+
+       /**
+        * Prepare for the insertion of a row with a comment and temporary table
+        *
+        * This is currently needed for "rev_comment" and "img_description". In the
+        * future that requirement will be removed.
+        *
+        * @note It's recommended to include both the call to this method and the
+        *  row insert in the same transaction.
+        * @param IDatabase $dbw Database handle to insert on
+        * @param string|Message|CommentStoreComment $comment As for `self::createComment()`
+        * @param array|null $data As for `self::createComment()`
+        * @return array Two values:
+        *  - array Fields for the insert or update
+        *  - callable Function to call when the primary key of the row being
+        *    inserted/updated is known. Pass it that primary key.
+        */
+       public function insertWithTempTable( IDatabase $dbw, $comment, $data = null ) {
+               if ( isset( self::$formerTempTables[$this->key] ) ) {
+                       wfDeprecated( __METHOD__ . " for $this->key", self::$formerTempTables[$this->key] );
+               } elseif ( !isset( self::$tempTables[$this->key] ) ) {
+                       throw new InvalidArgumentException( "Must use insert() for $this->key" );
+               }
+
+               list( $fields, $callback ) = $this->insertInternal( $dbw, $comment, $data );
+               if ( !$callback ) {
+                       $callback = function () {
+                               // Do nothing.
+                       };
+               }
+               return [ $fields, $callback ];
+       }
+
+       /**
+        * Encode a Message as a PHP data structure
+        * @param Message $msg
+        * @return array
+        */
+       protected static function encodeMessage( Message $msg ) {
+               $key = count( $msg->getKeysToTry() ) > 1 ? $msg->getKeysToTry() : $msg->getKey();
+               $params = $msg->getParams();
+               foreach ( $params as &$param ) {
+                       if ( $param instanceof Message ) {
+                               $param = [
+                                       'message' => self::encodeMessage( $param )
+                               ];
+                       }
+               }
+               array_unshift( $params, $key );
+               return $params;
+       }
+
+       /**
+        * Decode a message that was encoded by self::encodeMessage()
+        * @param array $data
+        * @return Message
+        */
+       protected static function decodeMessage( $data ) {
+               $key = array_shift( $data );
+               foreach ( $data as &$param ) {
+                       if ( is_object( $param ) ) {
+                               $param = (array)$param;
+                       }
+                       if ( is_array( $param ) && count( $param ) === 1 && isset( $param['message'] ) ) {
+                               $param = self::decodeMessage( $param['message'] );
+                       }
+               }
+               return new Message( $key, $data );
+       }
+
+       /**
+        * Hashing function for comment storage
+        * @param string $text Comment text
+        * @param string|null $data Comment data
+        * @return int 32-bit signed integer
+        */
+       public static function hash( $text, $data ) {
+               $hash = crc32( $text ) ^ crc32( (string)$data );
+
+               // 64-bit PHP returns an unsigned CRC, change it to signed for
+               // insertion into the database.
+               if ( $hash >= 0x80000000 ) {
+                       $hash |= -1 << 32;
+               }
+
+               return $hash;
+       }
+
+}
diff --git a/includes/CommentStoreComment.php b/includes/CommentStoreComment.php
new file mode 100644 (file)
index 0000000..afc1374
--- /dev/null
@@ -0,0 +1,57 @@
+<?php
+/**
+ * Value object for CommentStore
+ *
+ * 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 Wikimedia\Rdbms\IDatabase;
+
+/**
+ * CommentStoreComment represents a comment stored by CommentStore. The fields
+ * should be considered read-only.
+ * @since 1.30
+ */
+class CommentStoreComment {
+
+       /** @var int|null Comment ID, if any */
+       public $id;
+
+       /** @var string Text version of the comment */
+       public $text;
+
+       /** @var Message Message version of the comment. Might be a RawMessage */
+       public $message;
+
+       /** @var array|null Structured data of the comment */
+       public $data;
+
+       /**
+        * @private For use by CommentStore only
+        * @param int|null $id
+        * @param string $text
+        * @param Message|null $message
+        * @param array|null $data
+        */
+       public function __construct( $id, $text, Message $message = null, array $data = null ) {
+               $this->id = $id;
+               $this->text = $text;
+               $this->message = $message ?: new RawMessage( '$1', [ $text ] );
+               $this->data = $data;
+       }
+}
index 5d95964..cf3e569 100644 (file)
@@ -2055,8 +2055,8 @@ $wgDBmysql5 = false;
 $wgDBOracleDRCP = false;
 
 /**
- * Other wikis on this site, can be administered from a single developer
- * account.
+ * Other wikis on this site, can be administered from a single developer account.
+ *
  * Array numeric key => database name
  */
 $wgLocalDatabases = [];
@@ -8303,8 +8303,6 @@ $wgHTTPProxy = false;
  *   subdomain thereof, then no proxy will be used.
  *   Command-line scripts are not affected by this setting and will always use
  *   the proxy if it is configured.
- * - ChronologyProtector: Decide to shutdown LBFactory asynchronously instead
- *   synchronously if the current response redirects to a local virtual host.
  *
  * @since 1.25
  */
@@ -8765,6 +8763,13 @@ $wgExperiencedUserMemberSince = 30; # days
  */
 $wgInterwikiPrefixDisplayTypes = [];
 
+/**
+ * Comment table schema migration stage.
+ * @since 1.30
+ * @var int One of the MIGRATION_* constants
+ */
+$wgCommentTableSchemaMigrationStage = MIGRATION_OLD;
+
 /**
  * For really cool vim folding this needs to be at the end:
  * vim: foldmarker=@{,@} foldmethod=marker
index 0e1438f..d1e9435 100644 (file)
@@ -2658,8 +2658,7 @@ class EditPage {
                $wgOut->addHTML( Html::openElement(
                        'form',
                        [
-                               // Keep mw-editform-ooui class for backwards-compatibility temporarily
-                               'class' => 'mw-editform mw-editform-ooui',
+                               'class' => 'mw-editform',
                                'id' => self::EDITFORM_ID,
                                'name' => self::EDITFORM_ID,
                                'method' => 'post',
@@ -2702,7 +2701,7 @@ class EditPage {
 
                if ( $this->wasDeletedSinceLastEdit() && 'save' == $this->formtype ) {
                        $username = $this->lastDelete->user_name;
-                       $comment = $this->lastDelete->log_comment;
+                       $comment = CommentStore::newKey( 'log_comment' )->getComment( $this->lastDelete )->text;
 
                        // It is better to not parse the comment at all than to have templates expanded in the middle
                        // TODO: can the checkLabel be moved outside of the div so that wrapWikiMsg could be used?
@@ -3065,9 +3064,51 @@ class EditPage {
                ];
        }
 
+       /**
+        * Standard summary input and label (wgSummary), abstracted so EditPage
+        * subclasses may reorganize the form.
+        * Note that you do not need to worry about the label's for=, it will be
+        * inferred by the id given to the input. You can remove them both by
+        * passing [ 'id' => false ] to $userInputAttrs.
+        *
+        * @deprecated since 1.30 Use getSummaryInputWidget() instead
+        * @param string $summary The value of the summary input
+        * @param string $labelText The html to place inside the label
+        * @param array $inputAttrs Array of attrs to use on the input
+        * @param array $spanLabelAttrs Array of attrs to use on the span inside the label
+        * @return array An array in the format [ $label, $input ]
+        */
+       public function getSummaryInput( $summary = "", $labelText = null,
+               $inputAttrs = null, $spanLabelAttrs = null
+       ) {
+               wfDeprecated( __METHOD__, '1.30' );
+               $inputAttrs = $this->getSummaryInputAttributes( $inputAttrs );
+               $inputAttrs += Linker::tooltipAndAccesskeyAttribs( 'summary' );
+
+               $spanLabelAttrs = ( is_array( $spanLabelAttrs ) ? $spanLabelAttrs : [] ) + [
+                       'class' => $this->missingSummary ? 'mw-summarymissed' : 'mw-summary',
+                       'id' => "wpSummaryLabel"
+               ];
+
+               $label = null;
+               if ( $labelText ) {
+                       $label = Xml::tags(
+                               'label',
+                               $inputAttrs['id'] ? [ 'for' => $inputAttrs['id'] ] : null,
+                               $labelText
+                       );
+                       $label = Xml::tags( 'span', $spanLabelAttrs, $label );
+               }
+
+               $input = Html::input( 'wpSummary', $summary, 'text', $inputAttrs );
+
+               return [ $label, $input ];
+       }
+
        /**
         * Builds a standard summary input with a label.
         *
+        * @deprecated since 1.30 Use getSummaryInputWidget() instead
         * @param string $summary The value of the summary input
         * @param string $labelText The html to place inside the label
         * @param array $inputAttrs Array of attrs to use on the input
@@ -3075,6 +3116,20 @@ class EditPage {
         * @return OOUI\FieldLayout OOUI FieldLayout with Label and Input
         */
        function getSummaryInputOOUI( $summary = "", $labelText = null, $inputAttrs = null ) {
+               wfDeprecated( __METHOD__, '1.30' );
+               $this->getSummaryInputWidget( $summary, $labelText, $inputAttrs );
+       }
+
+       /**
+        * Builds a standard summary input with a label.
+        *
+        * @param string $summary The value of the summary input
+        * @param string $labelText The html to place inside the label
+        * @param array $inputAttrs Array of attrs to use on the input
+        *
+        * @return OOUI\FieldLayout OOUI FieldLayout with Label and Input
+        */
+       function getSummaryInputWidget( $summary = "", $labelText = null, $inputAttrs = null ) {
                $inputAttrs = OOUI\Element::configFromHtmlAttributes(
                        $this->getSummaryInputAttributes( $inputAttrs )
                );
@@ -3123,7 +3178,7 @@ class EditPage {
                }
 
                $labelText = $this->context->msg( $isSubjectPreview ? 'subject' : 'summary' )->parse();
-               $wgOut->addHTML( $this->getSummaryInputOOUI(
+               $wgOut->addHTML( $this->getSummaryInputWidget(
                                $summary,
                                $labelText,
                                [ 'class' => $summaryClass ]
@@ -3166,7 +3221,7 @@ class EditPage {
                $wgOut->addHTML( Html::hidden( 'wpStarttime', $this->starttime ) );
                $wgOut->addHTML( Html::hidden( 'wpEdittime', $this->edittime ) );
                $wgOut->addHTML( Html::hidden( 'editRevId', $this->editRevId ) );
-               $wgOut->addHTML( Html::hidden( 'wpScrolltop', $this->scrolltop ) );
+               $wgOut->addHTML( Html::hidden( 'wpScrolltop', $this->scrolltop, [ 'id' => 'wpScrolltop' ] ) );
 
                if ( !$this->checkUnicodeCompliantBrowser() ) {
                        $wgOut->addHTML( Html::hidden( 'safemode', '1' ) );
@@ -3538,7 +3593,7 @@ class EditPage {
                        $wgOut->addHTML( $this->getSummaryPreview( false, $this->summary ) );
                }
 
-               $checkboxes = $this->getCheckboxesOOUI(
+               $checkboxes = $this->getCheckboxesWidget(
                        $tabindex,
                        [ 'minor' => $this->minoredit, 'watch' => $this->watchthis ]
                );
@@ -3688,8 +3743,9 @@ class EditPage {
         */
        protected function getLastDelete() {
                $dbr = wfGetDB( DB_REPLICA );
+               $commentQuery = CommentStore::newKey( 'log_comment' )->getJoin();
                $data = $dbr->selectRow(
-                       [ 'logging', 'user' ],
+                       [ 'logging', 'user' ] + $commentQuery['tables'],
                        [
                                'log_type',
                                'log_action',
@@ -3697,11 +3753,10 @@ class EditPage {
                                'log_user',
                                'log_namespace',
                                'log_title',
-                               'log_comment',
                                'log_params',
                                'log_deleted',
                                'user_name'
-                       ], [
+                       ] + $commentQuery['fields'], [
                                'log_namespace' => $this->mTitle->getNamespace(),
                                'log_title' => $this->mTitle->getDBkey(),
                                'log_type' => 'delete',
@@ -3709,7 +3764,10 @@ class EditPage {
                                'user_id=log_user'
                        ],
                        __METHOD__,
-                       [ 'LIMIT' => 1, 'ORDER BY' => 'log_timestamp DESC' ]
+                       [ 'LIMIT' => 1, 'ORDER BY' => 'log_timestamp DESC' ],
+                       [
+                               'user' => [ 'JOIN', 'user_id=log_user' ],
+                       ] + $commentQuery['joins']
                );
                // Quick paranoid permission checks...
                if ( is_object( $data ) ) {
@@ -3718,7 +3776,8 @@ class EditPage {
                        }
 
                        if ( $data->log_deleted & LogPage::DELETED_COMMENT ) {
-                               $data->log_comment = $this->context->msg( 'rev-deleted-comment' )->escaped();
+                               $data->log_comment_text = $this->context->msg( 'rev-deleted-comment' )->escaped();
+                               $data->log_comment_data = null;
                        }
                }
 
@@ -4083,7 +4142,7 @@ class EditPage {
         *   where bool indicates the checked status of the checkbox
         * @return array
         */
-       protected function getCheckboxesDefinition( $checked ) {
+       public function getCheckboxesDefinition( $checked ) {
                global $wgUser;
                $checkboxes = [];
 
@@ -4122,6 +4181,7 @@ class EditPage {
         * Returns an array of html code of the following checkboxes old style:
         * minor and watch
         *
+        * @deprecated since 1.30 Use getCheckboxesWidget() or getCheckboxesDefinition() instead
         * @param int &$tabindex Current tabindex
         * @param array $checked See getCheckboxesDefinition()
         * @return array
@@ -4177,21 +4237,34 @@ class EditPage {
        }
 
        /**
-        * Returns an array of html code of the following checkboxes:
-        * minor and watch
+        * Returns an array of checkboxes for the edit form, including 'minor' and 'watch' checkboxes and
+        * any other added by extensions.
         *
+        * @deprecated since 1.30 Use getCheckboxesWidget() or getCheckboxesDefinition() instead
         * @param int &$tabindex Current tabindex
         * @param array $checked Array of checkbox => bool, where bool indicates the checked
         *                 status of the checkbox
         *
-        * @return array
+        * @return array Associative array of string keys to OOUI\FieldLayout instances
         */
        public function getCheckboxesOOUI( &$tabindex, $checked ) {
+               return $this->getCheckboxesWidget( $tabindex, $checked );
+       }
+
+       /**
+        * Returns an array of checkboxes for the edit form, including 'minor' and 'watch' checkboxes and
+        * any other added by extensions.
+        *
+        * @param int &$tabindex Current tabindex
+        * @param array $checked Array of checkbox => bool, where bool indicates the checked
+        *                 status of the checkbox
+        *
+        * @return array Associative array of string keys to OOUI\FieldLayout instances
+        */
+       public function getCheckboxesWidget( &$tabindex, $checked ) {
                $checkboxes = [];
                $checkboxesDef = $this->getCheckboxesDefinition( $checked );
 
-               $origTabindex = $tabindex;
-
                foreach ( $checkboxesDef as $name => $options ) {
                        $legacyName = isset( $options['legacy-name'] ) ? $options['legacy-name'] : $name;
 
@@ -4204,9 +4277,6 @@ class EditPage {
                        if ( isset( $options['title-message'] ) ) {
                                $title = $this->context->msg( $options['title-message'] )->text();
                        }
-                       if ( isset( $options['label-id'] ) ) {
-                               $labelAttribs['id'] = $options['label-id'];
-                       }
 
                        $checkboxes[ $legacyName ] = new OOUI\FieldLayout(
                                new OOUI\CheckboxInputWidget( [
@@ -4230,7 +4300,19 @@ class EditPage {
                // Backwards-compatibility hack to run the EditPageBeforeEditChecks hook. It's important,
                // people have used it for the weirdest things completely unrelated to checkboxes...
                // And if we're gonna run it, might as well allow its legacy checkboxes to be shown.
-               $legacyCheckboxes = $this->getCheckboxes( $origTabindex, $checked );
+               $legacyCheckboxes = [];
+               if ( !$this->isNew ) {
+                       $legacyCheckboxes['minor'] = '';
+               }
+               $legacyCheckboxes['watch'] = '';
+               // Copy new-style checkboxes into an old-style structure
+               foreach ( $checkboxes as $name => $oouiLayout ) {
+                       $legacyCheckboxes[$name] = (string)$oouiLayout;
+               }
+               // Avoid PHP 7.1 warning of passing $this by reference
+               $ep = $this;
+               Hooks::run( 'EditPageBeforeEditChecks', [ &$ep, &$legacyCheckboxes, &$tabindex ], '1.29' );
+               // Copy back any additional old-style checkboxes into the new-style structure
                foreach ( $legacyCheckboxes as $name => $html ) {
                        if ( $html && !isset( $checkboxes[$name] ) ) {
                                $checkboxes[$name] = new OOUI\Widget( [ 'content' => new OOUI\HtmlSnippet( $html ) ] );
index 96a88d3..0def6a0 100644 (file)
@@ -72,7 +72,8 @@ class FeedUtils {
        /**
         * Format a diff for the newsfeed
         *
-        * @param object $row Row from the recentchanges table
+        * @param object $row Row from the recentchanges table, including fields as
+        *  appropriate for CommentStore
         * @return string
         */
        public static function formatDiff( $row ) {
@@ -88,7 +89,9 @@ class FeedUtils {
                        $timestamp,
                        $row->rc_deleted & Revision::DELETED_COMMENT
                                ? wfMessage( 'rev-deleted-comment' )->escaped()
-                               : $row->rc_comment,
+                               : CommentStore::newKey( 'rc_comment' )
+                                       // Legacy from RecentChange::selectFields() via ChangesListSpecialPage::doMainQuery()
+                                       ->getCommentLegacy( wfGetDB( DB_REPLICA ), $row )->text,
                        $actiontext
                );
        }
index d55f0e0..aedb704 100644 (file)
@@ -1624,14 +1624,16 @@ class Linker {
                $link, $fallbackAnchor = false
        ) {
                $anchorEscaped = htmlspecialchars( $anchor );
-               $ret = "<h$level$attribs"
-                       . "<span class=\"mw-headline\" id=\"$anchorEscaped\">$html</span>"
-                       . $link
-                       . "</h$level>";
+               $fallback = '';
                if ( $fallbackAnchor !== false && $fallbackAnchor !== $anchor ) {
                        $fallbackAnchor = htmlspecialchars( $fallbackAnchor );
-                       $ret = "<div id=\"$fallbackAnchor\"></div>$ret";
+                       $fallback = "<span id=\"$fallbackAnchor\"></span>";
                }
+               $ret = "<h$level$attribs"
+                       . "$fallback<span class=\"mw-headline\" id=\"$anchorEscaped\">$html</span>"
+                       . $link
+                       . "</h$level>";
+
                return $ret;
        }
 
index 7461191..5856e21 100644 (file)
@@ -95,13 +95,22 @@ class MagicWordArray {
        public function getBaseRegex() {
                if ( is_null( $this->baseRegex ) ) {
                        $this->baseRegex = [ 0 => '', 1 => '' ];
+                       $allGroups = [];
                        foreach ( $this->names as $name ) {
                                $magic = MagicWord::get( $name );
                                $case = intval( $magic->isCaseSensitive() );
                                foreach ( $magic->getSynonyms() as $i => $syn ) {
                                        // Group name must start with a non-digit in PCRE 8.34+
                                        $it = strtr( $i, '0123456789', 'abcdefghij' );
-                                       $group = "(?P<{$it}_{$name}>" . preg_quote( $syn, '/' ) . ')';
+                                       $groupName = $it . '_' . $name;
+                                       $group = '(?P<' . $groupName . '>' . preg_quote( $syn, '/' ) . ')';
+                                       // look for same group names to avoid same named subpatterns in the regex
+                                       if ( isset( $allGroups[$groupName] ) ) {
+                                               throw new MWException(
+                                                       __METHOD__ . ': duplicate internal name in magic word array: ' . $name
+                                               );
+                                       }
+                                       $allGroups[$groupName] = true;
                                        if ( $this->baseRegex[$case] === '' ) {
                                                $this->baseRegex[$case] = $group;
                                        } else {
index 10b9e2b..7b59ee9 100644 (file)
@@ -607,7 +607,7 @@ class MediaWiki {
                        $request->wasPosted() &&
                        $output->getRedirect() &&
                        $lbFactory->hasOrMadeRecentMasterChanges( INF )
-               ) ? self::getUrlDomainDistance( $output->getRedirect(), $context ) : false;
+               ) ? self::getUrlDomainDistance( $output->getRedirect() ) : false;
 
                $allowHeaders = !( $output->isDisabled() || headers_sent() );
                if ( $urlDomainDistance === 'local' || $urlDomainDistance === 'remote' ) {
@@ -676,34 +676,14 @@ class MediaWiki {
 
        /**
         * @param string $url
-        * @param IContextSource $context
         * @return string Either "local", "remote" if in the farm, "external" otherwise
         */
-       private static function getUrlDomainDistance( $url, IContextSource $context ) {
-               static $relevantKeys = [ 'host' => true, 'port' => true ];
-
-               $infoCandidate = wfParseUrl( $url );
-               if ( $infoCandidate === false ) {
-                       return 'external';
-               }
-
-               $infoCandidate = array_intersect_key( $infoCandidate, $relevantKeys );
-               $clusterHosts = array_merge(
-                       // Local wiki host (the most common case)
-                       [ $context->getConfig()->get( 'CanonicalServer' ) ],
-                       // Any local/remote wiki virtual hosts for this wiki farm
-                       $context->getConfig()->get( 'LocalVirtualHosts' )
-               );
-
-               foreach ( $clusterHosts as $i => $clusterHost ) {
-                       $parseUrl = wfParseUrl( $clusterHost );
-                       if ( !$parseUrl ) {
-                               continue;
-                       }
-                       $infoHost = array_intersect_key( $parseUrl, $relevantKeys );
-                       if ( $infoCandidate === $infoHost ) {
-                               return ( $i === 0 ) ? 'local' : 'remote';
-                       }
+       private static function getUrlDomainDistance( $url ) {
+               $clusterWiki = WikiMap::getWikiFromUrl( $url );
+               if ( $clusterWiki === wfWikiID() ) {
+                       return 'local'; // the current wiki
+               } elseif ( $clusterWiki !== false ) {
+                       return 'remote'; // another wiki in this cluster/farm
                }
 
                return 'external';
index dac756e..ff8deee 100644 (file)
@@ -242,6 +242,8 @@ class PageProps {
        private function getGoodIDs( $titles ) {
                $result = [];
                if ( is_array( $titles ) ) {
+                       ( new LinkBatch( $titles ) )->execute();
+
                        foreach ( $titles as $title ) {
                                $pageID = $title->getArticleID();
                                if ( $pageID > 0 ) {
index e457beb..99d15a7 100644 (file)
@@ -192,7 +192,9 @@ class Revision implements IDBAccessObject {
                $attribs = $overrides + [
                        'page'       => isset( $row->ar_page_id ) ? $row->ar_page_id : null,
                        'id'         => isset( $row->ar_rev_id ) ? $row->ar_rev_id : null,
-                       'comment'    => $row->ar_comment,
+                       'comment'    => CommentStore::newKey( 'ar_comment' )
+                               // Legacy because $row probably came from self::selectArchiveFields()
+                               ->getCommentLegacy( wfGetDB( DB_REPLICA ), $row, true )->text,
                        'user'       => $row->ar_user,
                        'user_text'  => $row->ar_user_text,
                        'timestamp'  => $row->ar_timestamp,
@@ -443,6 +445,8 @@ class Revision implements IDBAccessObject {
        /**
         * Return the list of revision fields that should be selected to create
         * a new revision.
+        * @todo Deprecate this in favor of a method that returns tables and joins
+        *  as well, and use CommentStore::getJoin().
         * @return array
         */
        public static function selectFields() {
@@ -453,7 +457,6 @@ class Revision implements IDBAccessObject {
                        'rev_page',
                        'rev_text_id',
                        'rev_timestamp',
-                       'rev_comment',
                        'rev_user_text',
                        'rev_user',
                        'rev_minor_edit',
@@ -463,6 +466,8 @@ class Revision implements IDBAccessObject {
                        'rev_sha1',
                ];
 
+               $fields += CommentStore::newKey( 'rev_comment' )->getFields();
+
                if ( $wgContentHandlerUseDB ) {
                        $fields[] = 'rev_content_format';
                        $fields[] = 'rev_content_model';
@@ -474,6 +479,8 @@ class Revision implements IDBAccessObject {
        /**
         * Return the list of revision fields that should be selected to create
         * a new revision from an archive row.
+        * @todo Deprecate this in favor of a method that returns tables and joins
+        *  as well, and use CommentStore::getJoin().
         * @return array
         */
        public static function selectArchiveFields() {
@@ -485,7 +492,6 @@ class Revision implements IDBAccessObject {
                        'ar_text',
                        'ar_text_id',
                        'ar_timestamp',
-                       'ar_comment',
                        'ar_user_text',
                        'ar_user',
                        'ar_minor_edit',
@@ -495,6 +501,8 @@ class Revision implements IDBAccessObject {
                        'ar_sha1',
                ];
 
+               $fields += CommentStore::newKey( 'ar_comment' )->getFields();
+
                if ( $wgContentHandlerUseDB ) {
                        $fields[] = 'ar_content_format';
                        $fields[] = 'ar_content_model';
@@ -568,7 +576,9 @@ class Revision implements IDBAccessObject {
                        $this->mId = intval( $row->rev_id );
                        $this->mPage = intval( $row->rev_page );
                        $this->mTextId = intval( $row->rev_text_id );
-                       $this->mComment = $row->rev_comment;
+                       $this->mComment = CommentStore::newKey( 'rev_comment' )
+                               // Legacy because $row probably came from self::selectFields()
+                               ->getCommentLegacy( wfGetDB( DB_REPLICA ), $row, true )->text;
                        $this->mUser = intval( $row->rev_user );
                        $this->mMinorEdit = intval( $row->rev_minor_edit );
                        $this->mTimestamp = $row->rev_timestamp;
@@ -1432,10 +1442,8 @@ class Revision implements IDBAccessObject {
 
                # Record the text (or external storage URL) to the text table
                if ( $this->mTextId === null ) {
-                       $old_id = $dbw->nextSequenceValue( 'text_old_id_seq' );
                        $dbw->insert( 'text',
                                [
-                                       'old_id' => $old_id,
                                        'old_text' => $data,
                                        'old_flags' => $flags,
                                ], __METHOD__
@@ -1448,14 +1456,9 @@ class Revision implements IDBAccessObject {
                }
 
                # Record the edit in revisions
-               $rev_id = $this->mId !== null
-                       ? $this->mId
-                       : $dbw->nextSequenceValue( 'revision_rev_id_seq' );
                $row = [
-                       'rev_id'         => $rev_id,
                        'rev_page'       => $this->mPage,
                        'rev_text_id'    => $this->mTextId,
-                       'rev_comment'    => $this->mComment,
                        'rev_minor_edit' => $this->mMinorEdit ? 1 : 0,
                        'rev_user'       => $this->mUser,
                        'rev_user_text'  => $this->mUserText,
@@ -1469,6 +1472,13 @@ class Revision implements IDBAccessObject {
                                ? self::base36Sha1( $this->mText )
                                : $this->mSha1,
                ];
+               if ( $this->mId !== null ) {
+                       $row['rev_id'] = $this->mId;
+               }
+
+               list( $commentFields, $commentCallback ) =
+                       CommentStore::newKey( 'rev_comment' )->insertWithTempTable( $dbw, $this->mComment );
+               $row += $commentFields;
 
                if ( $wgContentHandlerUseDB ) {
                        // NOTE: Store null for the default model and format, to save space.
@@ -1495,9 +1505,10 @@ class Revision implements IDBAccessObject {
                $dbw->insert( 'revision', $row, __METHOD__ );
 
                if ( $this->mId === null ) {
-                       // Only if nextSequenceValue() was called
+                       // Only if auto-increment was used
                        $this->mId = $dbw->insertId();
                }
+               $commentCallback( $this->mId );
 
                // Assertion to try to catch T92046
                if ( (int)$this->mId === 0 ) {
index 05f85fa..0687a15 100644 (file)
@@ -1036,6 +1036,7 @@ class Title implements LinkTarget {
         * Can this title have a corresponding talk page?
         *
         * @see MWNamespace::hasTalkNamespace
+        * @since 1.30
         *
         * @return bool True if this title either is a talk page or can have a talk page associated.
         */
@@ -1324,7 +1325,7 @@ class Title implements LinkTarget {
         *
         * @since 1.30
         *
-        * @return Title The object for the talk page,
+        * @return Title|null The object for the talk page,
         *         or null if no associated talk page can exist, according to canHaveTalkPage().
         */
        public function getTalkPageIfDefined() {
@@ -2669,24 +2670,33 @@ class Title implements LinkTarget {
 
                if ( $this->mTitleProtection === null ) {
                        $dbr = wfGetDB( DB_REPLICA );
+                       $commentStore = new CommentStore( 'pt_reason' );
+                       $commentQuery = $commentStore->getJoin();
                        $res = $dbr->select(
-                               'protected_titles',
+                               [ 'protected_titles' ] + $commentQuery['tables'],
                                [
                                        'user' => 'pt_user',
-                                       'reason' => 'pt_reason',
                                        'expiry' => 'pt_expiry',
                                        'permission' => 'pt_create_perm'
-                               ],
+                               ] + $commentQuery['fields'],
                                [ 'pt_namespace' => $this->getNamespace(), 'pt_title' => $this->getDBkey() ],
-                               __METHOD__
+                               __METHOD__,
+                               [],
+                               $commentQuery['joins']
                        );
 
                        // fetchRow returns false if there are no rows.
                        $row = $dbr->fetchRow( $res );
                        if ( $row ) {
-                               $row['expiry'] = $dbr->decodeExpiry( $row['expiry'] );
+                               $this->mTitleProtection = [
+                                       'user' => $row['user'],
+                                       'expiry' => $dbr->decodeExpiry( $row['expiry'] ),
+                                       'permission' => $row['permission'],
+                                       'reason' => $commentStore->getComment( $row )->text,
+                               ];
+                       } else {
+                               $this->mTitleProtection = false;
                        }
-                       $this->mTitleProtection = $row;
                }
                return $this->mTitleProtection;
        }
index 1fafb24..d0f45be 100644 (file)
@@ -55,6 +55,10 @@ class WatchedItemQueryService {
        /** @var WatchedItemQueryServiceExtension[]|null */
        private $extensions = null;
 
+       /**
+        * @var CommentStore|null */
+       private $commentStore = null;
+
        public function __construct( LoadBalancer $loadBalancer ) {
                $this->loadBalancer = $loadBalancer;
        }
@@ -78,6 +82,13 @@ class WatchedItemQueryService {
                return $this->loadBalancer->getConnectionRef( DB_REPLICA, [ 'watchlist' ] );
        }
 
+       private function getCommentStore() {
+               if ( !$this->commentStore ) {
+                       $this->commentStore = new CommentStore( 'rc_comment' );
+               }
+               return $this->commentStore;
+       }
+
        /**
         * @param User $user
         * @param array $options Allowed keys:
@@ -172,13 +183,9 @@ class WatchedItemQueryService {
                        );
                }
 
-               $tables = [ 'recentchanges', 'watchlist' ];
-               if ( !$options['allRevisions'] ) {
-                       $tables[] = 'page';
-               }
-
                $db = $this->getConnection();
 
+               $tables = $this->getWatchedItemsWithRCInfoQueryTables( $options );
                $fields = $this->getWatchedItemsWithRCInfoQueryFields( $options );
                $conds = $this->getWatchedItemsWithRCInfoQueryConds( $db, $user, $options );
                $dbOptions = $this->getWatchedItemsWithRCInfoQueryDbOptions( $options );
@@ -320,6 +327,17 @@ class WatchedItemQueryService {
                return array_intersect_key( $allFields, array_flip( $rcKeys ) );
        }
 
+       private function getWatchedItemsWithRCInfoQueryTables( array $options ) {
+               $tables = [ 'recentchanges', 'watchlist' ];
+               if ( !$options['allRevisions'] ) {
+                       $tables[] = 'page';
+               }
+               if ( in_array( self::INCLUDE_COMMENT, $options['includeFields'] ) ) {
+                       $tables += $this->getCommentStore()->getJoin()['tables'];
+               }
+               return $tables;
+       }
+
        private function getWatchedItemsWithRCInfoQueryFields( array $options ) {
                $fields = [
                        'rc_id',
@@ -355,7 +373,7 @@ class WatchedItemQueryService {
                        $fields[] = 'rc_user';
                }
                if ( in_array( self::INCLUDE_COMMENT, $options['includeFields'] ) ) {
-                       $fields[] = 'rc_comment';
+                       $fields += $this->getCommentStore()->getJoin()['fields'];
                }
                if ( in_array( self::INCLUDE_PATROL_INFO, $options['includeFields'] ) ) {
                        $fields = array_merge( $fields, [ 'rc_patrolled', 'rc_log_type' ] );
@@ -657,6 +675,9 @@ class WatchedItemQueryService {
                if ( !$options['allRevisions'] ) {
                        $joinConds['page'] = [ 'LEFT JOIN', 'rc_cur_id=page_id' ];
                }
+               if ( in_array( self::INCLUDE_COMMENT, $options['includeFields'] ) ) {
+                       $joinConds += $this->getCommentStore()->getJoin()['joins'];
+               }
                return $joinConds;
        }
 
index 6a532e5..4f3c461 100644 (file)
  * @file
  */
 
+use MediaWiki\MediaWikiServices;
+
 /**
- * Helper tools for dealing with other wikis.
+ * Helper tools for dealing with other locally-hosted wikis.
  */
 class WikiMap {
 
@@ -81,7 +83,7 @@ class WikiMap {
         * @return WikiReference|null WikiReference object or null if the wiki was not found
         */
        private static function getWikiWikiReferenceFromSites( $wikiID ) {
-               $siteLookup = \MediaWiki\MediaWikiServices::getInstance()->getSiteLookup();
+               $siteLookup = MediaWikiServices::getInstance()->getSiteLookup();
                $site = $siteLookup->getSite( $wikiID );
 
                if ( !$site instanceof MediaWikiSite ) {
@@ -174,4 +176,67 @@ class WikiMap {
 
                return false;
        }
+
+       /**
+        * Get canonical server info for all local wikis in the map that have one
+        *
+        * @return array Map of (local wiki ID => map of (url,parts))
+        * @since 1.30
+        */
+       public static function getCanonicalServerInfoForAllWikis() {
+               $cache = MediaWikiServices::getInstance()->getLocalServerObjectCache();
+
+               return $cache->getWithSetCallback(
+                       $cache->makeGlobalKey( 'wikimap', 'canonical-urls' ),
+                       $cache::TTL_DAY,
+                       function () {
+                               global $wgLocalDatabases, $wgCanonicalServer;
+
+                               $infoMap = [];
+                               // Make sure at least the current wiki is set, for simple configurations.
+                               // This also makes it the first in the map, which is useful for common cases.
+                               $infoMap[wfWikiID()] = [
+                                       'url' => $wgCanonicalServer,
+                                       'parts' => wfParseUrl( $wgCanonicalServer )
+                               ];
+
+                               foreach ( $wgLocalDatabases as $wikiId ) {
+                                       $wikiReference = self::getWiki( $wikiId );
+                                       if ( $wikiReference ) {
+                                               $url = $wikiReference->getCanonicalServer();
+                                               $infoMap[$wikiId] = [ 'url' => $url, 'parts' => wfParseUrl( $url ) ];
+                                       }
+                               }
+
+                               return $infoMap;
+                       }
+               );
+       }
+
+       /**
+        * @param string $url
+        * @return bool|string Wiki ID or false
+        * @since 1.30
+        */
+       public static function getWikiFromUrl( $url ) {
+               $urlPartsCheck = wfParseUrl( $url );
+               if ( $urlPartsCheck === false ) {
+                       return false;
+               }
+
+               $urlPartsCheck = array_intersect_key( $urlPartsCheck, [ 'host' => 1, 'port' => 1 ] );
+               foreach ( self::getCanonicalServerInfoForAllWikis() as $wikiId => $info ) {
+                       $urlParts = $info['parts'];
+                       if ( $urlParts === false ) {
+                               continue; // sanity
+                       }
+
+                       $urlParts = array_intersect_key( $urlParts, [ 'host' => 1, 'port' => 1 ] );
+                       if ( $urlParts == $urlPartsCheck ) {
+                               return $wikiId;
+                       }
+               }
+
+               return false;
+       }
 }
index 021f426..7025477 100644 (file)
@@ -131,7 +131,7 @@ class CreditsAction extends FormlessAction {
                $anon_ips = [];
 
                # Sift for real versus user names
-               /** @var $user User */
+               /** @var User $user */
                foreach ( $contributors as $user ) {
                        $cnt--;
                        if ( $user->isLoggedIn() ) {
index 68dda37..d3ba0aa 100644 (file)
@@ -848,7 +848,7 @@ class InfoAction extends FormlessAction {
                $linkRenderer = MediaWikiServices::getInstance()->getLinkRenderer();
 
                # Sift for real versus user names
-               /** @var $user User */
+               /** @var User $user */
                foreach ( $contributors as $user ) {
                        $page = $user->isAnon()
                                ? SpecialPage::getTitleFor( 'Contributions', $user->getName() )
index 2245195..4360b4d 100644 (file)
@@ -62,7 +62,7 @@ class ApiEditPage extends ApiBase {
 
                                $redirValues = [];
 
-                               /** @var $newTitle Title */
+                               /** @var Title $newTitle */
                                foreach ( $titles as $id => $newTitle ) {
                                        if ( !isset( $titles[$id - 1] ) ) {
                                                $titles[$id - 1] = $oldTitle;
@@ -359,7 +359,7 @@ class ApiEditPage extends ApiBase {
                $articleContext->setWikiPage( $pageObj );
                $articleContext->setUser( $this->getUser() );
 
-               /** @var $articleObject Article */
+               /** @var Article $articleObject */
                $articleObject = Article::newFromWikiPage( $pageObj, $articleContext );
 
                $ep = new EditPage( $articleObject );
index 1fb034f..e7b2808 100644 (file)
@@ -59,7 +59,7 @@ class ApiMove extends ApiBase {
                if ( !$toTitle || $toTitle->isExternal() ) {
                        $this->dieWithError( [ 'apierror-invalidtitle', wfEscapeWikiText( $params['to'] ) ] );
                }
-               $toTalk = $toTitle->canTalk() ? $toTitle->getTalkPage() : null;
+               $toTalk = $toTitle->getTalkPageIfDefined();
 
                if ( $toTitle->getNamespace() == NS_FILE
                        && !RepoGroup::singleton()->getLocalRepo()->findFile( $toTitle )
index e6f3fc4..987bb99 100644 (file)
@@ -245,7 +245,7 @@ class ApiQuery extends ApiBase {
                $cacheMode = $this->mPageSet->getCacheMode();
 
                // Execute all unfinished modules
-               /** @var $module ApiQueryBase */
+               /** @var ApiQueryBase $module */
                foreach ( $modules as $module ) {
                        $params = $module->extractRequestParams();
                        $cacheMode = $this->mergeCacheMode(
@@ -381,7 +381,7 @@ class ApiQuery extends ApiBase {
                        ];
                }
                // Report special pages
-               /** @var $title Title */
+               /** @var Title $title */
                foreach ( $pageSet->getSpecialTitles() as $fakeId => $title ) {
                        $vals = [];
                        ApiQueryBase::addTitleInfo( $vals, $title );
@@ -434,7 +434,7 @@ class ApiQuery extends ApiBase {
                $titles = $pageSet->getGoodTitles();
                if ( count( $titles ) ) {
                        $user = $this->getUser();
-                       /** @var $title Title */
+                       /** @var Title $title */
                        foreach ( $titles as $title ) {
                                if ( $title->userCan( 'read', $user ) ) {
                                        $exportTitles[] = $title;
index fd95e17..d594ad4 100644 (file)
@@ -49,6 +49,7 @@ class ApiQueryAllUsers extends ApiQueryBase {
                $activeUserDays = $this->getConfig()->get( 'ActiveUserDays' );
 
                $db = $this->getDB();
+               $commentStore = new CommentStore( 'ipb_reason' );
 
                $prop = $params['prop'];
                if ( !is_null( $prop ) ) {
@@ -263,7 +264,7 @@ class ApiQueryAllUsers extends ApiQueryBase {
                                $data['blockedby'] = $row->ipb_by_text;
                                $data['blockedbyid'] = (int)$row->ipb_by;
                                $data['blockedtimestamp'] = wfTimestamp( TS_ISO_8601, $row->ipb_timestamp );
-                               $data['blockreason'] = $row->ipb_reason;
+                               $data['blockreason'] = $commentStore->getComment( $row )->text;
                                $data['blockexpiry'] = $row->ipb_expiry;
                        }
                        if ( $row->ipb_deleted ) {
index 56cbaac..54be254 100644 (file)
@@ -228,7 +228,7 @@ class ApiQueryBacklinks extends ApiQueryGeneratorBase {
                $titleWhere = [];
                $allRedirNs = [];
                $allRedirDBkey = [];
-               /** @var $t Title */
+               /** @var Title $t */
                foreach ( $this->redirTitles as $t ) {
                        $redirNs = $t->getNamespace();
                        $redirDBkey = $t->getDBkey();
index 44526e8..fe16134 100644 (file)
@@ -456,10 +456,13 @@ abstract class ApiQueryBase extends ApiBase {
                                'ipb_id',
                                'ipb_by',
                                'ipb_by_text',
-                               'ipb_reason',
                                'ipb_expiry',
                                'ipb_timestamp'
                        ] );
+                       $commentQuery = CommentStore::newKey( 'ipb_reason' )->getJoin();
+                       $this->addTables( $commentQuery['tables'] );
+                       $this->addFields( $commentQuery['fields'] );
+                       $this->addJoinConds( $commentQuery['joins'] );
                }
 
                // Don't show hidden names
index 076a09e..698c13c 100644 (file)
@@ -37,6 +37,7 @@ class ApiQueryBlocks extends ApiQueryBase {
 
        public function execute() {
                $db = $this->getDB();
+               $commentStore = new CommentStore( 'ipb_reason' );
                $params = $this->extractRequestParams();
                $this->requireMaxOneParameter( $params, 'users', 'ip' );
 
@@ -61,12 +62,18 @@ class ApiQueryBlocks extends ApiQueryBase {
                $this->addFieldsIf( 'ipb_by_text', $fld_by );
                $this->addFieldsIf( 'ipb_by', $fld_byid );
                $this->addFieldsIf( 'ipb_expiry', $fld_expiry );
-               $this->addFieldsIf( 'ipb_reason', $fld_reason );
                $this->addFieldsIf( [ 'ipb_range_start', 'ipb_range_end' ], $fld_range );
                $this->addFieldsIf( [ 'ipb_anon_only', 'ipb_create_account', 'ipb_enable_autoblock',
                        'ipb_block_email', 'ipb_deleted', 'ipb_allow_usertalk' ],
                        $fld_flags );
 
+               if ( $fld_reason ) {
+                       $commentQuery = $commentStore->getJoin();
+                       $this->addTables( $commentQuery['tables'] );
+                       $this->addFields( $commentQuery['fields'] );
+                       $this->addJoinConds( $commentQuery['joins'] );
+               }
+
                $this->addOption( 'LIMIT', $params['limit'] + 1 );
                $this->addTimestampWhereRange(
                        'ipb_timestamp',
@@ -205,7 +212,7 @@ class ApiQueryBlocks extends ApiQueryBase {
                                $block['expiry'] = ApiResult::formatExpiry( $row->ipb_expiry );
                        }
                        if ( $fld_reason ) {
-                               $block['reason'] = $row->ipb_reason;
+                               $block['reason'] = $commentStore->getComment( $row )->text;
                        }
                        if ( $fld_range && !$row->ipb_auto ) {
                                $block['rangestart'] = IP::formatHex( $row->ipb_range_start );
index 2a3bf38..25e9b27 100644 (file)
@@ -47,7 +47,7 @@ class ApiQueryCategoryInfo extends ApiQueryBase {
                $titles = $this->getPageSet()->getGoodAndMissingTitles();
                $cattitles = [];
                foreach ( $categories as $c ) {
-                       /** @var $t Title */
+                       /** @var Title $t */
                        $t = $titles[$c];
                        $cattitles[$c] = $t->getDBkey();
                }
index b68a868..5dd007b 100644 (file)
@@ -44,6 +44,7 @@ class ApiQueryDeletedrevs extends ApiQueryBase {
 
                $user = $this->getUser();
                $db = $this->getDB();
+               $commentStore = new CommentStore( 'ar_comment' );
                $params = $this->extractRequestParams( false );
                $prop = array_flip( $params['prop'] );
                $fld_parentid = isset( $prop['parentid'] );
@@ -115,11 +116,17 @@ class ApiQueryDeletedrevs extends ApiQueryBase {
                $this->addFieldsIf( 'ar_rev_id', $fld_revid );
                $this->addFieldsIf( 'ar_user_text', $fld_user );
                $this->addFieldsIf( 'ar_user', $fld_userid );
-               $this->addFieldsIf( 'ar_comment', $fld_comment || $fld_parsedcomment );
                $this->addFieldsIf( 'ar_minor_edit', $fld_minor );
                $this->addFieldsIf( 'ar_len', $fld_len );
                $this->addFieldsIf( 'ar_sha1', $fld_sha1 );
 
+               if ( $fld_comment || $fld_parsedcomment ) {
+                       $commentQuery = $commentStore->getJoin();
+                       $this->addTables( $commentQuery['tables'] );
+                       $this->addFields( $commentQuery['fields'] );
+                       $this->addJoinConds( $commentQuery['joins'] );
+               }
+
                if ( $fld_tags ) {
                        $this->addTables( 'tag_summary' );
                        $this->addJoinConds(
@@ -322,12 +329,13 @@ class ApiQueryDeletedrevs extends ApiQueryBase {
                                        $anyHidden = true;
                                }
                                if ( Revision::userCanBitfield( $row->ar_deleted, Revision::DELETED_COMMENT, $user ) ) {
+                                       $comment = $commentStore->getComment( $row )->text;
                                        if ( $fld_comment ) {
-                                               $rev['comment'] = $row->ar_comment;
+                                               $rev['comment'] = $comment;
                                        }
                                        if ( $fld_parsedcomment ) {
                                                $title = Title::makeTitle( $row->ar_namespace, $row->ar_title );
-                                               $rev['parsedcomment'] = Linker::formatComment( $row->ar_comment, $title );
+                                               $rev['parsedcomment'] = Linker::formatComment( $comment, $title );
                                        }
                                }
                        }
index 2ebd6de..0eaeaec 100644 (file)
@@ -91,7 +91,7 @@ class ApiQueryDuplicateFiles extends ApiQueryGeneratorBase {
 
                $sha1s = [];
                foreach ( $files as $file ) {
-                       /** @var $file File */
+                       /** @var File $file */
                        $sha1s[$file->getName()] = $file->getSha1();
                }
 
@@ -114,7 +114,7 @@ class ApiQueryDuplicateFiles extends ApiQueryGeneratorBase {
                        if ( $params['dir'] == 'descending' ) {
                                $dupFiles = array_reverse( $dupFiles );
                        }
-                       /** @var $dupFile File */
+                       /** @var File $dupFile */
                        foreach ( $dupFiles as $dupFile ) {
                                $dupName = $dupFile->getName();
                                if ( $image == $dupName && $dupFile->isLocal() ) {
index 7383cba..212b613 100644 (file)
@@ -43,6 +43,7 @@ class ApiQueryFilearchive extends ApiQueryBase {
 
                $user = $this->getUser();
                $db = $this->getDB();
+               $commentStore = new CommentStore( 'fa_description' );
 
                $params = $this->extractRequestParams();
 
@@ -66,13 +67,19 @@ class ApiQueryFilearchive extends ApiQueryBase {
                $this->addFieldsIf( 'fa_sha1', $fld_sha1 );
                $this->addFieldsIf( [ 'fa_user', 'fa_user_text' ], $fld_user );
                $this->addFieldsIf( [ 'fa_height', 'fa_width', 'fa_size' ], $fld_dimensions || $fld_size );
-               $this->addFieldsIf( 'fa_description', $fld_description );
                $this->addFieldsIf( [ 'fa_major_mime', 'fa_minor_mime' ], $fld_mime );
                $this->addFieldsIf( 'fa_media_type', $fld_mediatype );
                $this->addFieldsIf( 'fa_metadata', $fld_metadata );
                $this->addFieldsIf( 'fa_bits', $fld_bitdepth );
                $this->addFieldsIf( 'fa_archive_name', $fld_archivename );
 
+               if ( $fld_description ) {
+                       $commentQuery = $commentStore->getJoin();
+                       $this->addTables( $commentQuery['tables'] );
+                       $this->addFields( $commentQuery['fields'] );
+                       $this->addJoinConds( $commentQuery['joins'] );
+               }
+
                if ( !is_null( $params['continue'] ) ) {
                        $cont = explode( '|', $params['continue'] );
                        $this->dieContinueUsageIf( count( $cont ) != 3 );
@@ -165,10 +172,10 @@ class ApiQueryFilearchive extends ApiQueryBase {
                        if ( $fld_description &&
                                Revision::userCanBitfield( $row->fa_deleted, File::DELETED_COMMENT, $user )
                        ) {
-                               $file['description'] = $row->fa_description;
+                               $file['description'] = $commentStore->getComment( $row )->text;
                                if ( isset( $prop['parseddescription'] ) ) {
                                        $file['parseddescription'] = Linker::formatComment(
-                                               $row->fa_description, $title );
+                                               $file['description'], $title );
                                }
                        }
                        if ( $fld_user &&
index 7b0080e..b1df982 100644 (file)
@@ -124,7 +124,7 @@ class ApiQueryImageInfo extends ApiQueryBase {
                                        }
                                }
 
-                               /** @var $img File */
+                               /** @var File $img */
                                $img = $images[$title];
 
                                if ( self::getTransformCount() >= self::TRANSFORM_LIMIT ) {
@@ -199,7 +199,7 @@ class ApiQueryImageInfo extends ApiQueryBase {
                                // Get one more to facilitate query-continue functionality
                                $count = ( $gotOne ? 1 : 0 );
                                $oldies = $img->getHistory( $params['limit'] - $count + 1, $start, $params['end'] );
-                               /** @var $oldie File */
+                               /** @var File $oldie */
                                foreach ( $oldies as $oldie ) {
                                        if ( ++$count > $params['limit'] ) {
                                                // We've reached the extra one which shows that there are
index ecdebd4..bff1978 100644 (file)
@@ -372,7 +372,7 @@ class ApiQueryInfo extends ApiQueryBase {
                        $this->getDisplayTitle();
                }
 
-               /** @var $title Title */
+               /** @var Title $title */
                foreach ( $this->everything as $pageid => $title ) {
                        $pageInfo = $this->extractPageInfo( $pageid, $title );
                        $fit = $pageInfo !== null && $result->addValue( [
@@ -548,7 +548,7 @@ class ApiQueryInfo extends ApiQueryBase {
 
                        $res = $this->select( __METHOD__ );
                        foreach ( $res as $row ) {
-                               /** @var $title Title */
+                               /** @var Title $title */
                                $title = $this->titles[$row->pr_page];
                                $a = [
                                        'type' => $row->pr_type,
@@ -688,7 +688,7 @@ class ApiQueryInfo extends ApiQueryBase {
        private function getTSIDs() {
                $getTitles = $this->talkids = $this->subjectids = [];
 
-               /** @var $t Title */
+               /** @var Title $t */
                foreach ( $this->everything as $t ) {
                        if ( MWNamespace::isTalk( $t->getNamespace() ) ) {
                                if ( $this->fld_subjectid ) {
index 3639c06..d29a763 100644 (file)
@@ -137,7 +137,7 @@ class ApiQueryLinks extends ApiQueryGeneratorBase {
 
                $order[] = $this->prefix . '_title' . $sort;
                $this->addOption( 'ORDER BY', $order );
-               $this->addOption( 'USE INDEX', $this->prefix . '_from' );
+               $this->addOption( 'USE INDEX', [ $this->table => 'PRIMARY' ] );
                $this->addOption( 'LIMIT', $params['limit'] + 1 );
 
                $res = $this->select( __METHOD__ );
index 3e8bccc..3066720 100644 (file)
@@ -31,6 +31,8 @@
  */
 class ApiQueryLogEvents extends ApiQueryBase {
 
+       private $commentStore;
+
        public function __construct( ApiQuery $query, $moduleName ) {
                parent::__construct( $query, $moduleName, 'le' );
        }
@@ -43,6 +45,7 @@ class ApiQueryLogEvents extends ApiQueryBase {
        public function execute() {
                $params = $this->extractRequestParams();
                $db = $this->getDB();
+               $this->commentStore = new CommentStore( 'log_comment' );
                $this->requireMaxOneParameter( $params, 'title', 'prefix', 'namespace' );
 
                $prop = array_flip( $params['prop'] );
@@ -91,9 +94,15 @@ class ApiQueryLogEvents extends ApiQueryBase {
                        [ 'log_namespace', 'log_title' ],
                        $this->fld_title || $this->fld_parsedcomment
                );
-               $this->addFieldsIf( 'log_comment', $this->fld_comment || $this->fld_parsedcomment );
                $this->addFieldsIf( 'log_params', $this->fld_details );
 
+               if ( $this->fld_comment || $this->fld_parsedcomment ) {
+                       $commentQuery = $this->commentStore->getJoin();
+                       $this->addTables( $commentQuery['tables'] );
+                       $this->addFields( $commentQuery['fields'] );
+                       $this->addJoinConds( $commentQuery['joins'] );
+               }
+
                if ( $this->fld_tags ) {
                        $this->addTables( 'tag_summary' );
                        $this->addJoinConds( [ 'tag_summary' => [ 'LEFT JOIN', 'log_id=ts_log_id' ] ] );
@@ -327,18 +336,19 @@ class ApiQueryLogEvents extends ApiQueryBase {
                        $vals['timestamp'] = wfTimestamp( TS_ISO_8601, $row->log_timestamp );
                }
 
-               if ( ( $this->fld_comment || $this->fld_parsedcomment ) && isset( $row->log_comment ) ) {
+               if ( $this->fld_comment || $this->fld_parsedcomment ) {
                        if ( LogEventsList::isDeleted( $row, LogPage::DELETED_COMMENT ) ) {
                                $vals['commenthidden'] = true;
                                $anyHidden = true;
                        }
                        if ( LogEventsList::userCan( $row, LogPage::DELETED_COMMENT, $user ) ) {
+                               $comment = $this->commentStore->getComment( $row )->text;
                                if ( $this->fld_comment ) {
-                                       $vals['comment'] = $row->log_comment;
+                                       $vals['comment'] = $comment;
                                }
 
                                if ( $this->fld_parsedcomment ) {
-                                       $vals['parsedcomment'] = Linker::formatComment( $row->log_comment, $title );
+                                       $vals['parsedcomment'] = Linker::formatComment( $comment, $title );
                                }
                        }
                }
index 5f6510e..b69a299 100644 (file)
@@ -55,10 +55,17 @@ class ApiQueryProtectedTitles extends ApiQueryGeneratorBase {
 
                $prop = array_flip( $params['prop'] );
                $this->addFieldsIf( 'pt_user', isset( $prop['user'] ) || isset( $prop['userid'] ) );
-               $this->addFieldsIf( 'pt_reason', isset( $prop['comment'] ) || isset( $prop['parsedcomment'] ) );
                $this->addFieldsIf( 'pt_expiry', isset( $prop['expiry'] ) );
                $this->addFieldsIf( 'pt_create_perm', isset( $prop['level'] ) );
 
+               if ( isset( $prop['comment'] ) || isset( $prop['parsedcomment'] ) ) {
+                       $commentStore = new CommentStore( 'pt_reason' );
+                       $commentQuery = $commentStore->getJoin();
+                       $this->addTables( $commentQuery['tables'] );
+                       $this->addFields( $commentQuery['fields'] );
+                       $this->addJoinConds( $commentQuery['joins'] );
+               }
+
                $this->addTimestampWhereRange( 'pt_timestamp', $params['dir'], $params['start'], $params['end'] );
                $this->addWhereFld( 'pt_namespace', $params['namespace'] );
                $this->addWhereFld( 'pt_create_perm', $params['level'] );
@@ -127,11 +134,13 @@ class ApiQueryProtectedTitles extends ApiQueryGeneratorBase {
                                }
 
                                if ( isset( $prop['comment'] ) ) {
-                                       $vals['comment'] = $row->pt_reason;
+                                       $vals['comment'] = $commentStore->getComment( $row )->text;
                                }
 
                                if ( isset( $prop['parsedcomment'] ) ) {
-                                       $vals['parsedcomment'] = Linker::formatComment( $row->pt_reason, $title );
+                                       $vals['parsedcomment'] = Linker::formatComment(
+                                               $commentStore->getComment( $row )->text, $titles
+                                       );
                                }
 
                                if ( isset( $prop['expiry'] ) ) {
index caa5f05..46c2265 100644 (file)
@@ -59,7 +59,7 @@ class ApiQueryQueryPage extends ApiQueryGeneratorBase {
                $params = $this->extractRequestParams();
                $result = $this->getResult();
 
-               /** @var $qp QueryPage */
+               /** @var QueryPage $qp */
                $qp = new $this->qpMap[$params['page']]();
                if ( !$qp->userCanExecute( $this->getUser() ) ) {
                        $this->dieWithError( 'apierror-specialpage-cantexecute' );
@@ -129,7 +129,7 @@ class ApiQueryQueryPage extends ApiQueryGeneratorBase {
        }
 
        public function getCacheMode( $params ) {
-               /** @var $qp QueryPage */
+               /** @var QueryPage $qp */
                $qp = new $this->qpMap[$params['page']]();
                if ( $qp->getRestriction() != '' ) {
                        return 'private';
index 0dc01aa..9af4e3e 100644 (file)
@@ -36,6 +36,8 @@ class ApiQueryRecentChanges extends ApiQueryGeneratorBase {
                parent::__construct( $query, $moduleName, 'rc' );
        }
 
+       private $commentStore;
+
        private $fld_comment = false, $fld_parsedcomment = false, $fld_user = false, $fld_userid = false,
                $fld_flags = false, $fld_timestamp = false, $fld_title = false, $fld_ids = false,
                $fld_sizes = false, $fld_redirect = false, $fld_patrolled = false, $fld_loginfo = false,
@@ -274,7 +276,6 @@ class ApiQueryRecentChanges extends ApiQueryGeneratorBase {
 
                        /* Add fields to our query if they are specified as a needed parameter. */
                        $this->addFieldsIf( [ 'rc_this_oldid', 'rc_last_oldid' ], $this->fld_ids );
-                       $this->addFieldsIf( 'rc_comment', $this->fld_comment || $this->fld_parsedcomment );
                        $this->addFieldsIf( 'rc_user', $this->fld_user || $this->fld_userid );
                        $this->addFieldsIf( 'rc_user_text', $this->fld_user );
                        $this->addFieldsIf( [ 'rc_minor', 'rc_type', 'rc_bot' ], $this->fld_flags );
@@ -286,6 +287,14 @@ class ApiQueryRecentChanges extends ApiQueryGeneratorBase {
                        );
                        $showRedirects = $this->fld_redirect || isset( $show['redirect'] )
                                || isset( $show['!redirect'] );
+
+                       if ( $this->fld_comment || $this->fld_parsedcomment ) {
+                               $this->commentStore = new CommentStore( 'rc_comment' );
+                               $commentQuery = $this->commentStore->getJoin();
+                               $this->addTables( $commentQuery['tables'] );
+                               $this->addFields( $commentQuery['fields'] );
+                               $this->addJoinConds( $commentQuery['joins'] );
+                       }
                }
                $this->addFieldsIf( [ 'rc_this_oldid' ],
                        $resultPageSet && $params['generaterevisions'] );
@@ -500,12 +509,13 @@ class ApiQueryRecentChanges extends ApiQueryGeneratorBase {
                                $anyHidden = true;
                        }
                        if ( Revision::userCanBitfield( $row->rc_deleted, Revision::DELETED_COMMENT, $user ) ) {
-                               if ( $this->fld_comment && isset( $row->rc_comment ) ) {
-                                       $vals['comment'] = $row->rc_comment;
+                               $comment = $this->commentStore->getComment( $row )->text;
+                               if ( $this->fld_comment ) {
+                                       $vals['comment'] = $comment;
                                }
 
-                               if ( $this->fld_parsedcomment && isset( $row->rc_comment ) ) {
-                                       $vals['parsedcomment'] = Linker::formatComment( $row->rc_comment, $title );
+                               if ( $this->fld_parsedcomment ) {
+                                       $vals['parsedcomment'] = Linker::formatComment( $comment, $title );
                                }
                        }
                }
index a4f0315..2dfa42a 100644 (file)
@@ -166,7 +166,7 @@ class ApiQueryRevisions extends ApiQueryRevisionsBase {
                        // For each page we will request, the user must have read rights for that page
                        $user = $this->getUser();
                        $status = Status::newGood();
-                       /** @var $title Title */
+                       /** @var Title $title */
                        foreach ( $pageSet->getGoodTitles() as $title ) {
                                if ( !$title->userCan( 'read', $user ) ) {
                                        $status->fatal( ApiMessage::create(
index 181cddb..bb0f335 100644 (file)
@@ -36,7 +36,7 @@ class ApiQueryContributions extends ApiQueryBase {
        }
 
        private $params, $prefixMode, $userprefix, $multiUserMode, $idMode, $usernames, $userids,
-               $parentLens;
+               $parentLens, $commentStore;
        private $fld_ids = false, $fld_title = false, $fld_timestamp = false,
                $fld_comment = false, $fld_parsedcomment = false, $fld_flags = false,
                $fld_patrolled = false, $fld_tags = false, $fld_size = false, $fld_sizediff = false;
@@ -45,6 +45,8 @@ class ApiQueryContributions extends ApiQueryBase {
                // Parse some parameters
                $this->params = $this->extractRequestParams();
 
+               $this->commentStore = new CommentStore( 'rev_comment' );
+
                $prop = array_flip( $this->params['prop'] );
                $this->fld_ids = isset( $prop['ids'] );
                $this->fld_title = isset( $prop['title'] );
@@ -341,12 +343,18 @@ class ApiQueryContributions extends ApiQueryBase {
                $this->addFieldsIf( 'rev_page', $this->fld_ids );
                $this->addFieldsIf( 'page_latest', $this->fld_flags );
                // $this->addFieldsIf( 'rev_text_id', $this->fld_ids ); // Should this field be exposed?
-               $this->addFieldsIf( 'rev_comment', $this->fld_comment || $this->fld_parsedcomment );
                $this->addFieldsIf( 'rev_len', $this->fld_size || $this->fld_sizediff );
                $this->addFieldsIf( 'rev_minor_edit', $this->fld_flags );
                $this->addFieldsIf( 'rev_parent_id', $this->fld_flags || $this->fld_sizediff || $this->fld_ids );
                $this->addFieldsIf( 'rc_patrolled', $this->fld_patrolled );
 
+               if ( $this->fld_comment || $this->fld_parsedcomment ) {
+                       $commentQuery = $this->commentStore->getJoin();
+                       $this->addTables( $commentQuery['tables'] );
+                       $this->addFields( $commentQuery['fields'] );
+                       $this->addJoinConds( $commentQuery['joins'] );
+               }
+
                if ( $this->fld_tags ) {
                        $this->addTables( 'tag_summary' );
                        $this->addJoinConds(
@@ -416,7 +424,7 @@ class ApiQueryContributions extends ApiQueryBase {
                        $vals['top'] = $row->page_latest == $row->rev_id;
                }
 
-               if ( ( $this->fld_comment || $this->fld_parsedcomment ) && isset( $row->rev_comment ) ) {
+               if ( $this->fld_comment || $this->fld_parsedcomment ) {
                        if ( $row->rev_deleted & Revision::DELETED_COMMENT ) {
                                $vals['commenthidden'] = true;
                                $anyHidden = true;
@@ -428,12 +436,13 @@ class ApiQueryContributions extends ApiQueryBase {
                        );
 
                        if ( $userCanView ) {
+                               $comment = $this->commentStore->getComment( $row )->text;
                                if ( $this->fld_comment ) {
-                                       $vals['comment'] = $row->rev_comment;
+                                       $vals['comment'] = $comment;
                                }
 
                                if ( $this->fld_parsedcomment ) {
-                                       $vals['parsedcomment'] = Linker::formatComment( $row->rev_comment, $title );
+                                       $vals['parsedcomment'] = Linker::formatComment( $comment, $title );
                                }
                        }
                }
index 2a0eadd..fbf1f9e 100644 (file)
@@ -99,6 +99,7 @@ class ApiQueryUsers extends ApiQueryBase {
 
        public function execute() {
                $db = $this->getDB();
+               $commentStore = new CommentStore( 'ipb_reason' );
 
                $params = $this->extractRequestParams();
                $this->requireMaxOneParameter( $params, 'userids', 'users' );
@@ -236,7 +237,7 @@ class ApiQueryUsers extends ApiQueryBase {
                                        $data[$key]['blockedby'] = $row->ipb_by_text;
                                        $data[$key]['blockedbyid'] = (int)$row->ipb_by;
                                        $data[$key]['blockedtimestamp'] = wfTimestamp( TS_ISO_8601, $row->ipb_timestamp );
-                                       $data[$key]['blockreason'] = $row->ipb_reason;
+                                       $data[$key]['blockreason'] = $commentStore->getComment( $row )->text;
                                        $data[$key]['blockexpiry'] = $row->ipb_expiry;
                                }
 
index 9883480..2ab8524 100644 (file)
@@ -34,6 +34,8 @@ use MediaWiki\MediaWikiServices;
  */
 class ApiQueryWatchlist extends ApiQueryGeneratorBase {
 
+       private $commentStore;
+
        public function __construct( ApiQuery $query, $moduleName ) {
                parent::__construct( $query, $moduleName, 'wl' );
        }
@@ -85,6 +87,10 @@ class ApiQueryWatchlist extends ApiQueryGeneratorBase {
                                        $this->dieWithError( 'apierror-permissiondenied-patrolflag', 'patrol' );
                                }
                        }
+
+                       if ( $this->fld_comment || $this->fld_parsedcomment ) {
+                               $this->commentStore = new CommentStore( 'rc_comment' );
+                       }
                }
 
                $options = [
@@ -353,12 +359,13 @@ class ApiQueryWatchlist extends ApiQueryGeneratorBase {
                                Revision::DELETED_COMMENT,
                                $user
                        ) ) {
-                               if ( $this->fld_comment && isset( $recentChangeInfo['rc_comment'] ) ) {
-                                       $vals['comment'] = $recentChangeInfo['rc_comment'];
+                               $comment = $this->commentStore->getComment( $recentChangeInfo )->text;
+                               if ( $this->fld_comment ) {
+                                       $vals['comment'] = $comment;
                                }
 
-                               if ( $this->fld_parsedcomment && isset( $recentChangeInfo['rc_comment'] ) ) {
-                                       $vals['parsedcomment'] = Linker::formatComment( $recentChangeInfo['rc_comment'], $title );
+                               if ( $this->fld_parsedcomment ) {
+                                       $vals['parsedcomment'] = Linker::formatComment( $comment, $title );
                                }
                        }
                }
index 663416e..b6a0a78 100644 (file)
@@ -150,7 +150,7 @@ class ApiSetNotificationTimestamp extends ApiBase {
                                );
 
                                // Now, put the valid titles into the result
-                               /** @var $title Title */
+                               /** @var Title $title */
                                foreach ( $pageSet->getTitles() as $title ) {
                                        $ns = $title->getNamespace();
                                        $dbkey = $title->getDBkey();
index a283b5a..cfe1968 100644 (file)
@@ -71,7 +71,7 @@ class ApiUpload extends ApiBase {
                $this->checkPermissions( $user );
 
                // Fetch the file (usually a no-op)
-               /** @var $status Status */
+               /** @var Status $status */
                $status = $this->mUpload->fetchFile();
                if ( !$status->isGood() ) {
                        $this->dieStatus( $status );
@@ -772,7 +772,7 @@ class ApiUpload extends ApiBase {
                        $this->mParams['text'] = $this->mParams['comment'];
                }
 
-               /** @var $file LocalFile */
+               /** @var LocalFile $file */
                $file = $this->mUpload->getLocalFile();
 
                // For preferences mode, we want to watch if 'watchdefault' is set,
@@ -829,7 +829,7 @@ class ApiUpload extends ApiBase {
                        $result['result'] = 'Poll';
                        $result['stage'] = 'queued';
                } else {
-                       /** @var $status Status */
+                       /** @var Status $status */
                        $status = $this->mUpload->performUpload( $this->mParams['comment'],
                                $this->mParams['text'], $watch, $this->getUser(), $this->mParams['tags'] );
 
index 2353a62..a473893 100644 (file)
        "api-help-param-upload": "Muss als Dateiupload mithilfe eines multipart/form-data-Formular bereitgestellt werden.",
        "api-help-param-multi-separate": "Werte mit <kbd>|</kbd> trennen oder [[Special:ApiHelp/main#main/datatypes|Alternative]].",
        "api-help-param-multi-max": "Maximale Anzahl der Werte ist {{PLURAL:$1|$1}} ({{PLURAL:$2|$2}} für Bots).",
+       "api-help-param-multi-max-simple": "Die maximale Anzahl der Werte ist {{PLURAL:$1|$1}}.",
        "api-help-param-multi-all": "Um alle Werte anzugeben, verwende <kbd>$1</kbd>.",
        "api-help-param-default": "Standard: $1",
        "api-help-param-default-empty": "Standard: <span class=\"apihelp-empty\">(leer)</span>",
index 6272f4e..9b6b81d 100644 (file)
        "apihelp-expandtemplates-param-generatexml": "Generar un árbol de análisis XML (remplazado por $1prop=parsetree).",
        "apihelp-expandtemplates-example-simple": "Expandir el wikitexto <kbd><nowiki>{{Project:Sandbox}}</nowiki></kbd>.",
        "apihelp-feedcontributions-summary": "Devuelve el canal de contribuciones de un usuario.",
-       "apihelp-feedcontributions-param-feedformat": "El formato del canal.",
+       "apihelp-feedcontributions-param-feedformat": "El formato del suministro.",
        "apihelp-feedcontributions-param-user": "De qué usuarios recibir contribuciones.",
        "apihelp-feedcontributions-param-namespace": "Espacio de nombre para filtrar las contribuciones.",
        "apihelp-feedcontributions-param-year": "A partir del año (y anteriores).",
        "apihelp-feedcontributions-param-showsizediff": "Mostrar la diferencia de tamaño entre revisiones.",
        "apihelp-feedcontributions-example-simple": "Devolver las contribuciones del usuario <kbd>Example</kbd>.",
        "apihelp-feedrecentchanges-summary": "Devuelve un canal de cambios recientes.",
-       "apihelp-feedrecentchanges-param-feedformat": "El formato del canal.",
+       "apihelp-feedrecentchanges-param-feedformat": "El formato del suministro.",
        "apihelp-feedrecentchanges-param-namespace": "Espacio de nombres al cual limitar los resultados.",
        "apihelp-feedrecentchanges-param-invert": "Todos los espacios de nombres menos el que está seleccionado.",
        "apihelp-feedrecentchanges-param-associated": "Incluir el espacio de nombres asociado (discusión o principal).",
        "apihelp-feedrecentchanges-example-simple": "Mostrar los cambios recientes.",
        "apihelp-feedrecentchanges-example-30days": "Mostrar los cambios recientes limitados a 30 días.",
        "apihelp-feedwatchlist-summary": "Devuelve el canal de una lista de seguimiento.",
-       "apihelp-feedwatchlist-param-feedformat": "El formato del canal.",
+       "apihelp-feedwatchlist-param-feedformat": "El formato del suministro.",
        "apihelp-feedwatchlist-param-hours": "Listar las páginas modificadas desde estas horas hasta ahora.",
        "apihelp-feedwatchlist-param-linktosections": "Enlazar directamente a las secciones cambiadas de ser posible.",
        "apihelp-feedwatchlist-example-default": "Mostrar el canal de la lista de seguimiento.",
        "apihelp-query+revisions+base-param-section": "Recuperar solamente el contenido de este número de sección.",
        "apihelp-query+revisions+base-param-contentformat": "Formato de serialización utilizado para <var>$1difftotext</var> y esperado para la salida de contenido.",
        "apihelp-query+search-summary": "Realizar una búsqueda de texto completa.",
-       "apihelp-query+search-param-namespace": "Buscar sólo en estos espacios de nombres.",
+       "apihelp-query+search-param-namespace": "Buscar solo en estos espacios de nombres.",
        "apihelp-query+search-param-what": "Tipo de búsqueda que realizar.",
        "apihelp-query+search-param-info": "Qué metadatos devolver.",
        "apihelp-query+search-param-prop": "Qué propiedades se devolverán:",
        "apihelp-query+watchlistraw-param-limit": "Número de resultados que devolver en cada petición.",
        "apihelp-query+watchlistraw-param-prop": "Qué propiedades adicionales se obtendrán:",
        "apihelp-query+watchlistraw-paramvalue-prop-changed": "Añade la marca de tiempo de la última notificación al usuario sobre la edición.",
-       "apihelp-query+watchlistraw-param-show": "Sólo listar los elementos que cumplen estos criterios.",
+       "apihelp-query+watchlistraw-param-show": "Mostrar solo los elementos que cumplen con estos criterios.",
        "apihelp-query+watchlistraw-param-owner": "Utilizado junto con $1token para acceder a la lista de seguimiento de otro usuario.",
        "apihelp-query+watchlistraw-param-dir": "La dirección en la que se listará.",
        "apihelp-query+watchlistraw-param-fromtitle": "Título (con el prefijo de espacio de nombres) desde el que se empezará a enumerar.",
index efee015..9a16e81 100644 (file)
@@ -29,6 +29,8 @@
        "apihelp-compare-param-toid": "Aldaratzeko bigarren orri IDa.",
        "apihelp-compare-param-torev": "Aldaratzeko bigarren berrikusketa.",
        "apihelp-compare-param-prop": "Hartu beharreko informazio zatiak.",
+       "apihelp-compare-paramvalue-prop-diff": "HTML diff-a",
+       "apihelp-compare-paramvalue-prop-diffsize": "HTML diff-aren tamainia, byte-tan",
        "apihelp-compare-example-1": "1. eta 2. berrikusketen arteko \"diff\"-a sortu.",
        "apihelp-createaccount-summary": "Erabiltzaile kontu berria sortu.",
        "apihelp-createaccount-param-name": "Erabiltzaile izena.",
        "apihelp-feedrecentchanges-example-simple": "Erakutsi aldaketa berriak",
        "apihelp-feedrecentchanges-example-30days": "Erakutsi aldaketa berriak 30 egunez",
        "apihelp-feedwatchlist-param-feedformat": "Produktuaren formatua.",
+       "apihelp-filerevert-summary": "Artxibo bat bertsio zaharrera bueltatu.",
        "apihelp-filerevert-param-comment": "Iruzkina igo.",
        "apihelp-help-example-recursive": "Laguntza guztia orrialde batean.",
        "apihelp-imagerotate-summary": "Irudi bat edo gehiago biratu.",
        "apihelp-imagerotate-param-rotation": "Irudia erloju-orratzen norabidean biratzeko graduak.",
        "apihelp-import-param-summary": "Inportazioaren laburpena.",
        "apihelp-import-param-xml": "XML fitxategia igo da.",
+       "apihelp-import-param-tags": "Aldatu etiketak sarrera aplikatzeko inportatzeko sarreran eta inportatutako orrialdeetan berrikuspena kentzeko.",
        "apihelp-login-param-name": "Erabiltzaile izena.",
        "apihelp-login-param-password": "Pasahitza.",
        "apihelp-login-param-domain": "Domeinua (hautazkoa).",
index b73d537..4c6da2f 100644 (file)
        "api-help-param-upload": "Doit être envoyé comme un fichier importé utilisant multipart/form-data.",
        "api-help-param-multi-separate": "Valeurs séparées par <kbd>|</kbd> ou [[Special:ApiHelp/main#main/datatypes|autre]].",
        "api-help-param-multi-max": "Le nombre maximal de valeurs est {{PLURAL:$1|$1}} ({{PLURAL:$2|$2}} pour les robots).",
+       "api-help-param-multi-max-simple": "Le nombre maximum de valeurs est {{PLURAL:$1|$1}}.",
        "api-help-param-multi-all": "Pour spécifier toutes les valeurs, utiliser <kbd>$1</kbd>.",
        "api-help-param-default": "Par défaut : $1",
        "api-help-param-default-empty": "Par défaut : <span class=\"apihelp-empty\">(vide)</span>",
index 1a0cad9..c873685 100644 (file)
        "api-help-param-upload": "Debe ser enviado como un ficheiro importado usando multipart/form-data.",
        "api-help-param-multi-separate": "Separe os valores con <kbd>|</kbd> ou [[Special:ApiHelp/main#main/datatypes|outros]].",
        "api-help-param-multi-max": "O número máximo de valores é {{PLURAL:$1|$1}} ({{PLURAL:$2|$2}} para os bots).",
+       "api-help-param-multi-max-simple": "O número máximo de valores é {{PLURAL:1$|1$}}.",
        "api-help-param-multi-all": "Para especificar tódolos valores use <kbd>$1</kbd>.",
        "api-help-param-default": "Por defecto: $1",
        "api-help-param-default-empty": "Por defecto: <span class=\"apihelp-empty\">(baleiro)</span>",
index aa06dcf..dcb4efb 100644 (file)
        "api-help-param-upload": "חייב להישלח (posted) בתור העלאת קובץ באמצעות multipart/form-data.",
        "api-help-param-multi-separate": "הפרדה בין ערכים נעשית באמצעות <kbd>|</kbd> או [[Special:ApiHelp/main#main/datatypes|תו חלופי]].",
        "api-help-param-multi-max": "מספר הערכים המרבי הוא {{PLURAL:$1|$1}} (עבור בוטים – {{PLURAL:$2|$2}}).",
+       "api-help-param-multi-max-simple": "המספר המרבי של הערכים הוא {{PLURAL:$1|$1}}.",
        "api-help-param-multi-all": "כדי לתת את כל הערכים, יש להשתמש ב־<kbd>$1</kbd>.",
        "api-help-param-default": "ברירת מחדל: $1",
        "api-help-param-default-empty": "ברירת מחדל: <span class=\"apihelp-empty\">(ריק)</span>",
index 23b86ab..fd88c18 100644 (file)
        "api-help-param-integer-minmax": "{{PLURAL:$1|1=Il valore deve essere compreso|2=I valori devono essere compresi}} tra $2 e $3.",
        "api-help-param-multi-separate": "Separa i valori con <kbd>|</kbd> o [[Special:ApiHelp/main#main/datatypes|alternativa]].",
        "api-help-param-multi-max": "Il numero massimo di valori è {{PLURAL:$1|$1}} ({{PLURAL:$2|$2}} per i bot).",
+       "api-help-param-multi-max-simple": "Il numero massimo di valori è {{PLURAL:$1|$1}}.",
        "api-help-param-multi-all": "Per specificare tutti i valori, utilizza <kbd>$1</kbd>.",
        "api-help-param-default": "Predefinito: $1",
        "api-help-param-default-empty": "Predefinito: <span class=\"apihelp-empty\">(vuoto)</span>",
index bff361e..edcd41b 100644 (file)
        "api-help-param-upload": "여러 부분/폼 데이터를 사용한 파일 업로드로 게시되어야 합니다.",
        "api-help-param-multi-separate": "<kbd>|</kbd> 또는 [[Special:ApiHelp/main#main/datatypes|대안]]으로 값을 구분합니다.",
        "api-help-param-multi-max": "값들의 최대 수는 {{PLURAL:$1|$1}}입니다. (봇의 경우 {{PLURAL:$2|$2}})",
+       "api-help-param-multi-max-simple": "값의 최대 수는 {{PLURAL:$1|$1}}입니다.",
        "api-help-param-default": "기본값: $1",
        "api-help-param-default-empty": "기본값: <span class=\"apihelp-empty\">(비어 있음)</span>",
        "api-help-param-token": "\"$1\" 토큰은 [[Special:ApiHelp/query+tokens|action=query&meta=tokens]]에서 가져옵니다",
index 085821c..0d5f224 100644 (file)
        "api-help-param-required": "Dëse Parameter ass obligatoresch.",
        "api-help-datatypes-header": "Datentypen",
        "api-help-param-type-user": "Typ: {{PLURAL:$1|1=Benotzernumm|2=Lëscht vu Benotzernimm}}",
+       "api-help-param-multi-max-simple": "Maximal Zuel vun de Wäerter ass {{PLURAL:$1|$1}}.",
        "api-help-examples": "{{PLURAL:$1|Beispill|Beispiler}}:",
        "api-help-permissions": "{{PLURAL:$1|Autorisatioun|Autorisatiounen}}:",
        "api-help-open-in-apisandbox": "<small>[an der Sandkëscht opmaachen]</small>",
index b09f570..0b9a57b 100644 (file)
        "api-help-param-upload": "Deve ser postado como um upload de arquivo usando multipart/form-data.",
        "api-help-param-multi-separate": "Valores separados com <kbd>|</kbd> ou [[Special:ApiHelp/main#main/datatypes|alternativas]].",
        "api-help-param-multi-max": "O número máximo de valores é {{PLURAL:$1|$1}} ({{PLURAL:$2|$2}} para bots).",
+       "api-help-param-multi-max-simple": "O número máximo de valores é {{PLURAL:$1|$1}}.",
        "api-help-param-multi-all": "Para especificar todos os valores, use <kbd>$1</kbd>.",
        "api-help-param-default": "Padrão: $1",
        "api-help-param-default-empty": "Padrão: <span class=\"apihelp-empty\">(vazio)</span>",
index 775cd15..299cb5e 100644 (file)
        "api-help-param-upload": "Tem ser enviado (''posted'') como um carregamento de ficheiro usando multipart/form-data.",
        "api-help-param-multi-separate": "Separar os valores com <kbd>|</kbd> ou [[Special:ApiHelp/main#main/datatypes|alternativas]].",
        "api-help-param-multi-max": "O número máximo de valores é {{PLURAL:$1|$1}} ({{PLURAL:$2|$2}} para robôs).",
+       "api-help-param-multi-max-simple": "O número máximo de valores é {{PLURAL:$1|$1}}.",
        "api-help-param-multi-all": "Para especificar todos os valores, use <kbd>$1</kbd>.",
        "api-help-param-default": "Valor por omissão: $1",
        "api-help-param-default-empty": "Padrão: <span class=\"apihelp-empty\">(vazio)</span>",
index d8fbfe0..dbd4d0e 100644 (file)
        "api-help-param-upload": "必须被公布为使用multipart/form-data的一次文件上传。",
        "api-help-param-multi-separate": "通过<kbd>|</kbd>或[[Special:ApiHelp/main#main/datatypes|替代物]]隔开各值。",
        "api-help-param-multi-max": "值的最大数量是{{PLURAL:$1|$1}}(对于机器人则是{{PLURAL:$2|$2}})。",
+       "api-help-param-multi-max-simple": "值的最大数量为{{PLURAL:$1|$1}}。",
        "api-help-param-multi-all": "要指定所有值,请使用<kbd>$1</kbd>。",
        "api-help-param-default": "默认:$1",
        "api-help-param-default-empty": "默认:<span class=\"apihelp-empty\">(空)</span>",
index b2528fe..9407c42 100644 (file)
@@ -975,7 +975,7 @@ class AuthManager implements LoggerAwareInterface {
        public function checkAccountCreatePermissions( User $creator ) {
                // Wiki is read-only?
                if ( wfReadOnly() ) {
-                       return Status::newFatal( 'readonlytext', wfReadOnlyReason() );
+                       return Status::newFatal( wfMessage( 'readonlytext', wfReadOnlyReason() ) );
                }
 
                // This is awful, this permission check really shouldn't go through Title.
@@ -1579,7 +1579,7 @@ class AuthManager implements LoggerAwareInterface {
                        ] );
                        $user->setId( 0 );
                        $user->loadFromId();
-                       return Status::newFatal( 'readonlytext', wfReadOnlyReason() );
+                       return Status::newFatal( wfMessage( 'readonlytext', wfReadOnlyReason() ) );
                }
 
                // Check the session, if we tried to create this user already there's
index 38cb6be..30d105b 100644 (file)
@@ -43,7 +43,7 @@ class LinkBatch {
        protected $caller;
 
        /**
-        * @param LinkTarget[] $arr Initial items to be added to the batch
+        * @param Traversable|LinkTarget[] $arr Initial items to be added to the batch
         */
        public function __construct( $arr = [] ) {
                foreach ( $arr as $item ) {
index 01e67f5..913bd38 100644 (file)
@@ -66,6 +66,13 @@ class ChangesListBooleanFilter extends ChangesListFilter {
         */
        protected $queryCallable;
 
+       /**
+        * Value that defined when this filter is considered active
+        *
+        * @var bool $activeValue
+        */
+       protected $activeValue;
+
        /**
         * Create a new filter with the specified configuration.
         *
@@ -90,6 +97,8 @@ class ChangesListBooleanFilter extends ChangesListFilter {
         *     to true.  It does not need to be set if the exact same filter is simply visible
         *     on both.
         * * $filterDefinition['default'] bool Default
+        * * $filterDefinition['activeValue'] bool This filter is considered active when
+        *     its value is equal to its activeValue. Default is true.
         * * $filterDefinition['priority'] int Priority integer.  Higher value means higher
         *     up in the group's filter list.
         * * $filterDefinition['queryCallable'] callable Callable accepting parameters, used
@@ -126,6 +135,12 @@ class ChangesListBooleanFilter extends ChangesListFilter {
                if ( isset( $filterDefinition['queryCallable'] ) ) {
                        $this->queryCallable = $filterDefinition['queryCallable'];
                }
+
+               if ( isset( $filterDefinition['activeValue'] ) ) {
+                       $this->activeValue = $filterDefinition['activeValue'];
+               } else {
+                       $this->activeValue = true;
+               }
        }
 
        /**
@@ -136,7 +151,7 @@ class ChangesListBooleanFilter extends ChangesListFilter {
         */
        public function getDefault( $structuredUI = false ) {
                return $this->isReplacedInStructuredUi && $structuredUI ?
-                       false :
+                       !$this->activeValue :
                        $this->defaultValue;
        }
 
@@ -225,4 +240,17 @@ class ChangesListBooleanFilter extends ChangesListFilter {
                                return $opts[ $sibling->getName() ];
                        } );
        }
+
+       /**
+        * @param FormOptions $opts Query parameters merged with defaults
+        * @param bool $isStructuredUI Whether the structured UI is currently enabled
+        * @return bool Whether this filter should be considered active
+        */
+       public function isActive( FormOptions $opts, $isStructuredUI ) {
+               if ( $this->isReplacedInStructuredUi && $isStructuredUI ) {
+                       return false;
+               }
+
+               return $opts[ $this->getName() ] === $this->activeValue;
+       }
 }
index 21a811e..8e24efe 100644 (file)
@@ -515,7 +515,7 @@ class EnhancedChangesList extends ChangesList {
 
                $sinceLast = 0;
                $unvisitedOldid = null;
-               /** @var $rcObj RCCacheEntry */
+               /** @var RCCacheEntry $rcObj */
                foreach ( $block as $rcObj ) {
                        // Same logic as below inside main foreach
                        if ( $rcObj->watched && $rcObj->mAttribs['rc_timestamp'] >= $rcObj->watched ) {
@@ -537,7 +537,7 @@ class EnhancedChangesList extends ChangesList {
 
                # Total change link
                $links = [];
-               /** @var $block0 RecentChange */
+               /** @var RecentChange $block0 */
                $block0 = $block[0];
                $last = $block[count( $block ) - 1];
                if ( !$allLogs ) {
index f123363..cd11070 100644 (file)
  * temporary:       not stored in the database
  *      notificationtimestamp
  *      numberofWatchingusers
+ *
+ * @todo Deprecate access to mAttribs (direct or via getAttributes). Right now
+ *  we're having to include both rc_comment and rc_comment_text/rc_comment_data
+ *  so random crap works right.
  */
 class RecentChange {
        // Constants for the rc_source field.  Extensions may also have
@@ -199,6 +203,8 @@ class RecentChange {
        /**
         * Return the list of recentchanges fields that should be selected to create
         * a new recentchanges object.
+        * @todo Deprecate this in favor of a method that returns tables and joins
+        *  as well, and use CommentStore::getJoin().
         * @return array
         */
        public static function selectFields() {
@@ -209,7 +215,6 @@ class RecentChange {
                        'rc_user_text',
                        'rc_namespace',
                        'rc_title',
-                       'rc_comment',
                        'rc_minor',
                        'rc_bot',
                        'rc_new',
@@ -227,7 +232,7 @@ class RecentChange {
                        'rc_log_type',
                        'rc_log_action',
                        'rc_params',
-               ];
+               ] + CommentStore::newKey( 'rc_comment' )->getFields();
        }
 
        # Accessors
@@ -315,15 +320,24 @@ class RecentChange {
 
                # Fixup database timestamps
                $this->mAttribs['rc_timestamp'] = $dbw->timestamp( $this->mAttribs['rc_timestamp'] );
-               $this->mAttribs['rc_id'] = $dbw->nextSequenceValue( 'recentchanges_rc_id_seq' );
 
                # # If we are using foreign keys, an entry of 0 for the page_id will fail, so use NULL
                if ( $this->mAttribs['rc_cur_id'] == 0 ) {
                        unset( $this->mAttribs['rc_cur_id'] );
                }
 
+               # Convert mAttribs['rc_comment'] for CommentStore
+               $row = $this->mAttribs;
+               $comment = $row['rc_comment'];
+               unset( $row['rc_comment'], $row['rc_comment_text'], $row['rc_comment_data'] );
+               $row += CommentStore::newKey( 'rc_comment' )->insert( $dbw, $comment );
+
+               # Don't reuse an existing rc_id for the new row, if one happens to be
+               # set for some reason.
+               unset( $row['rc_id'] );
+
                # Insert new row
-               $dbw->insert( 'recentchanges', $this->mAttribs, __METHOD__ );
+               $dbw->insert( 'recentchanges', $row, __METHOD__ );
 
                # Set the ID
                $this->mAttribs['rc_id'] = $dbw->insertId();
@@ -586,7 +600,9 @@ class RecentChange {
                        'rc_cur_id' => $title->getArticleID(),
                        'rc_user' => $user->getId(),
                        'rc_user_text' => $user->getName(),
-                       'rc_comment' => $comment,
+                       'rc_comment' => &$comment,
+                       'rc_comment_text' => &$comment,
+                       'rc_comment_data' => null,
                        'rc_this_oldid' => $newId,
                        'rc_last_oldid' => $oldId,
                        'rc_bot' => $bot ? 1 : 0,
@@ -659,7 +675,9 @@ class RecentChange {
                        'rc_cur_id' => $title->getArticleID(),
                        'rc_user' => $user->getId(),
                        'rc_user_text' => $user->getName(),
-                       'rc_comment' => $comment,
+                       'rc_comment' => &$comment,
+                       'rc_comment_text' => &$comment,
+                       'rc_comment_data' => null,
                        'rc_this_oldid' => $newId,
                        'rc_last_oldid' => 0,
                        'rc_bot' => $bot ? 1 : 0,
@@ -789,7 +807,9 @@ class RecentChange {
                        'rc_cur_id' => $target->getArticleID(),
                        'rc_user' => $user->getId(),
                        'rc_user_text' => $user->getName(),
-                       'rc_comment' => $logComment,
+                       'rc_comment' => &$logComment,
+                       'rc_comment_text' => &$logComment,
+                       'rc_comment_data' => null,
                        'rc_this_oldid' => $revId,
                        'rc_last_oldid' => 0,
                        'rc_bot' => $user->isAllowed( 'bot' ) ? (int)$wgRequest->getBool( 'bot', true ) : 0,
@@ -862,7 +882,9 @@ class RecentChange {
                        'rc_cur_id' => $pageTitle->getArticleID(),
                        'rc_user' => $user ? $user->getId() : 0,
                        'rc_user_text' => $user ? $user->getName() : '',
-                       'rc_comment' => $comment,
+                       'rc_comment' => &$comment,
+                       'rc_comment_text' => &$comment,
+                       'rc_comment_data' => null,
                        'rc_this_oldid' => $newRevId,
                        'rc_last_oldid' => $oldRevId,
                        'rc_bot' => $bot ? 1 : 0,
@@ -922,6 +944,13 @@ class RecentChange {
                                $this->mAttribs['rc_ip'] = substr( $this->mAttribs['rc_ip'], 0, $n );
                        }
                }
+
+               $comment = CommentStore::newKey( 'rc_comment' )
+                       // Legacy because $row probably came from self::selectFields()
+                       ->getCommentLegacy( wfGetDB( DB_REPLICA ), $row, true )->text;
+               $this->mAttribs['rc_comment'] = &$comment;
+               $this->mAttribs['rc_comment_text'] = &$comment;
+               $this->mAttribs['rc_comment_data'] = null;
        }
 
        /**
@@ -931,6 +960,9 @@ class RecentChange {
         * @return mixed
         */
        public function getAttribute( $name ) {
+               if ( $name === 'rc_comment' ) {
+                       return CommentStore::newKey( 'rc_comment' )->getComment( $this->mAttribs, true )->text;
+               }
                return isset( $this->mAttribs[$name] ) ? $this->mAttribs[$name] : null;
        }
 
index d7dc45a..0ec21cb 100644 (file)
@@ -228,7 +228,7 @@ class EtcdConfig implements Config, LoggerAwareInterface {
                // Retrieve all the values under the MediaWiki config directory
                list( $rcode, $rdesc, /* $rhdrs */, $rbody, $rerr ) = $this->http->run( [
                        'method' => 'GET',
-                       'url' => "{$this->protocol}://{$address}/v2/keys/{$this->directory}/",
+                       'url' => "{$this->protocol}://{$address}/v2/keys/{$this->directory}/?recursive=true",
                        'headers' => [ 'content-type' => 'application/json' ]
                ] );
 
@@ -240,28 +240,65 @@ class EtcdConfig implements Config, LoggerAwareInterface {
                                empty( $terminalCodes[$rcode] )
                        ];
                }
+               try {
+                       return [ $this->parseResponse( $rbody ), null, false ];
+               } catch ( EtcdConfigParseError $e ) {
+                       return [ null, $e->getMessage(), false ];
+               }
+       }
 
+       /**
+        * Parse a response body, throwing EtcdConfigParseError if there is a validation error
+        *
+        * @param string $rbody
+        * @return array
+        */
+       protected function parseResponse( $rbody ) {
                $info = json_decode( $rbody, true );
-               if ( $info === null || !isset( $info['node']['nodes'] ) ) {
-                       return [ null, "Unexpected JSON response; missing 'nodes' list.", false ];
+               if ( $info === null ) {
+                       throw new EtcdConfigParseError( "Error unserializing JSON response." );
+               }
+               if ( !isset( $info['node'] ) || !is_array( $info['node'] ) ) {
+                       throw new EtcdConfigParseError(
+                               "Unexpected JSON response: Missing or invalid node at top level." );
                }
-
                $config = [];
-               foreach ( $info['node']['nodes'] as $node ) {
+               $this->parseDirectory( '', $info['node'], $config );
+               return $config;
+       }
+
+       /**
+        * Recursively parse a directory node and populate the array passed by
+        * reference, throwing EtcdConfigParseError if there is a validation error
+        *
+        * @param string $dirName The relative directory name
+        * @param array $dirNode The decoded directory node
+        * @param array &$config The output array
+        */
+       protected function parseDirectory( $dirName, $dirNode, &$config ) {
+               if ( !isset( $dirNode['nodes'] ) ) {
+                       throw new EtcdConfigParseError(
+                               "Unexpected JSON response in dir '$dirName'; missing 'nodes' list." );
+               }
+               if ( !is_array( $dirNode['nodes'] ) ) {
+                       throw new EtcdConfigParseError(
+                               "Unexpected JSON response in dir '$dirName'; 'nodes' is not an array." );
+               }
+
+               foreach ( $dirNode['nodes'] as $node ) {
+                       $baseName = basename( $node['key'] );
+                       $fullName = $dirName === '' ? $baseName : "$dirName/$baseName";
                        if ( !empty( $node['dir'] ) ) {
-                               continue; // skip directories
-                       }
+                               $this->parseDirectory( $fullName, $node, $config );
+                       } else {
+                               $value = $this->unserialize( $node['value'] );
+                               if ( !is_array( $value ) || !array_key_exists( 'val', $value ) ) {
+                                       throw new EtcdConfigParseError( "Failed to parse value for '$fullName'." );
+                               }
 
-                       $name = basename( $node['key'] );
-                       $value = $this->unserialize( $node['value'] );
-                       if ( !is_array( $value ) || !array_key_exists( 'val', $value ) ) {
-                               return [ null, "Failed to parse value for '$name'.", false ];
+                               $config[$fullName] = $value['val'];
                        }
-
-                       $config[$name] = $value['val'];
                }
-
-               return [ $config, null, false ];
        }
 
        /**
diff --git a/includes/config/EtcdConfigParseError.php b/includes/config/EtcdConfigParseError.php
new file mode 100644 (file)
index 0000000..cab90a8
--- /dev/null
@@ -0,0 +1,4 @@
+<?php
+
+class EtcdConfigParseError extends Exception {
+}
index 556fe75..e2feb1f 100644 (file)
@@ -37,9 +37,6 @@ class DatabaseOracle extends Database {
        /** @var int The number of rows affected as an integer */
        protected $mAffectedRows;
 
-       /** @var int */
-       private $mInsertId = null;
-
        /** @var bool */
        private $ignoreDupValOnIndex = false;
 
@@ -319,12 +316,10 @@ class DatabaseOracle extends Database {
                return oci_field_name( $stmt, $n );
        }
 
-       /**
-        * This must be called after nextSequenceVal
-        * @return null|int
-        */
        function insertId() {
-               return $this->mInsertId;
+               $res = $this->query( "SELECT lastval_pkg.getLastval FROM dual" );
+               $row = $this->fetchRow( $res );
+               return is_null( $row[0] ) ? null : (int)$row[0];
        }
 
        /**
@@ -649,20 +644,6 @@ class DatabaseOracle extends Database {
                return preg_replace( '/.*\.(.*)/', '$1', $name );
        }
 
-       /**
-        * Return the next in a sequence, save the value for retrieval via insertId()
-        *
-        * @param string $seqName
-        * @return null|int
-        */
-       function nextSequenceValue( $seqName ) {
-               $res = $this->query( "SELECT $seqName.nextval FROM dual" );
-               $row = $this->fetchRow( $res );
-               $this->mInsertId = $row[0];
-
-               return $this->mInsertId;
-       }
-
        /**
         * Return sequence_name if table has a sequence
         *
index 470086a..7fafc0e 100644 (file)
@@ -49,11 +49,12 @@ class CdnCacheUpdate implements DeferrableUpdate, MergeableUpdate {
        /**
         * Create an update object from an array of Title objects, or a TitleArray object
         *
-        * @param Traversable|array $titles
+        * @param Traversable|Title[] $titles
         * @param string[] $urlArr
         * @return CdnCacheUpdate
         */
        public static function newFromTitles( $titles, $urlArr = [] ) {
+               ( new LinkBatch( $titles ) )->execute();
                /** @var Title $title */
                foreach ( $titles as $title ) {
                        $urlArr = array_merge( $urlArr, $title->getCdnUrls() );
index 40069f3..e8e250b 100644 (file)
@@ -149,7 +149,7 @@ class DeferredUpdates {
                if ( $update instanceof MergeableUpdate ) {
                        $class = get_class( $update ); // fully-qualified class
                        if ( isset( $queue[$class] ) ) {
-                               /** @var $existingUpdate MergeableUpdate */
+                               /** @var MergeableUpdate $existingUpdate */
                                $existingUpdate = $queue[$class];
                                $existingUpdate->merge( $update );
                        } else {
index 18a87e8..33d4e70 100644 (file)
@@ -548,7 +548,6 @@ class LinksUpdate extends DataUpdate implements EnqueueableDataUpdate {
                foreach ( $diffs as $url => $dummy ) {
                        foreach ( wfMakeUrlIndexes( $url ) as $index ) {
                                $arr[] = [
-                                       'el_id' => $this->getDB()->nextSequenceValue( 'externallinks_el_id_seq' ),
                                        'el_from' => $this->mId,
                                        'el_to' => $url,
                                        'el_index' => $index,
index e0ebaa2..6e2a5a4 100644 (file)
@@ -260,7 +260,7 @@ class WikiExporter {
        protected function dumpFrom( $cond = '', $orderRevs = false ) {
                # For logging dumps...
                if ( $this->history & self::LOGS ) {
-                       $where = [ 'user_id = log_user' ];
+                       $where = [];
                        # Hide private logs
                        $hideLogs = LogEventsList::getExcludeClause( $this->db );
                        if ( $hideLogs ) {
@@ -277,12 +277,16 @@ class WikiExporter {
                                $prev = $this->db->bufferResults( false );
                        }
                        $result = null; // Assuring $result is not undefined, if exception occurs early
+
+                       $commentQuery = CommentStore::newKey( 'log_comment' )->getJoin();
+
                        try {
-                               $result = $this->db->select( [ 'logging', 'user' ],
-                                       [ "{$logging}.*", 'user_name' ], // grab the user name
+                               $result = $this->db->select( [ 'logging', 'user' ] + $commentQuery['tables'],
+                                       [ "{$logging}.*", 'user_name' ] + $commentQuery['fields'], // grab the user name
                                        $where,
                                        __METHOD__,
-                                       [ 'ORDER BY' => 'log_id', 'USE INDEX' => [ 'logging' => 'PRIMARY' ] ]
+                                       [ 'ORDER BY' => 'log_id', 'USE INDEX' => [ 'logging' => 'PRIMARY' ] ],
+                                       [ 'user' => [ 'JOIN', 'user_id = log_user' ] ] + $commentQuery['joins']
                                );
                                $this->outputLogStream( $result );
                                if ( $this->buffer == self::STREAM ) {
@@ -395,8 +399,17 @@ class WikiExporter {
                                Hooks::run( 'ModifyExportQuery',
                                                [ $this->db, &$tables, &$cond, &$opts, &$join ] );
 
+                               $commentQuery = CommentStore::newKey( 'rev_comment' )->getJoin();
+
                                # Do the query!
-                               $result = $this->db->select( $tables, '*', $cond, __METHOD__, $opts, $join );
+                               $result = $this->db->select(
+                                       $tables + $commentQuery['tables'],
+                                       [ '*' ] + $commentQuery['fields'],
+                                       $cond,
+                                       __METHOD__,
+                                       $opts,
+                                       $join + $commentQuery['joins']
+                               );
                                # Output dump results
                                $this->outputPageStream( $result );
 
index 943408c..990f16d 100644 (file)
@@ -218,8 +218,11 @@ class XmlDumpWriter {
                }
                if ( isset( $row->rev_deleted ) && ( $row->rev_deleted & Revision::DELETED_COMMENT ) ) {
                        $out .= "      " . Xml::element( 'comment', [ 'deleted' => 'deleted' ] ) . "\n";
-               } elseif ( $row->rev_comment != '' ) {
-                       $out .= "      " . Xml::elementClean( 'comment', [], strval( $row->rev_comment ) ) . "\n";
+               } else {
+                       $comment = CommentStore::newKey( 'rev_comment' )->getComment( $row )->text;
+                       if ( $comment != '' ) {
+                               $out .= "      " . Xml::elementClean( 'comment', [], strval( $comment ) ) . "\n";
+                       }
                }
 
                if ( isset( $row->rev_content_model ) && !is_null( $row->rev_content_model ) ) {
@@ -299,8 +302,11 @@ class XmlDumpWriter {
 
                if ( $row->log_deleted & LogPage::DELETED_COMMENT ) {
                        $out .= "    " . Xml::element( 'comment', [ 'deleted' => 'deleted' ] ) . "\n";
-               } elseif ( $row->log_comment != '' ) {
-                       $out .= "    " . Xml::elementClean( 'comment', null, strval( $row->log_comment ) ) . "\n";
+               } else {
+                       $comment = CommentStore::newKey( 'log_comment' )->getComment( $row )->text;
+                       if ( $comment != '' ) {
+                               $out .= "    " . Xml::elementClean( 'comment', null, strval( $comment ) ) . "\n";
+                       }
                }
 
                $out .= "    " . Xml::element( 'type', null, strval( $row->log_type ) ) . "\n";
index 6bb1618..e5d36e1 100644 (file)
@@ -92,9 +92,8 @@ class ExternalStoreDB extends ExternalStoreMedium {
 
        public function store( $location, $data ) {
                $dbw = $this->getMaster( $location );
-               $id = $dbw->nextSequenceValue( 'blob_blob_id_seq' );
                $dbw->insert( $this->getTable( $dbw ),
-                       [ 'blob_id' => $id, 'blob_text' => $data ],
+                       [ 'blob_text' => $data ],
                        __METHOD__ );
                $id = $dbw->insertId();
                if ( !$id ) {
index 20d51c2..ed00793 100644 (file)
@@ -274,14 +274,13 @@ class LocalRepo extends FileRepo {
                        );
                };
 
-               $that = $this;
                $applyMatchingFiles = function ( ResultWrapper $res, &$searchSet, &$finalFiles )
-                       use ( $that, $fileMatchesSearch, $flags )
+                       use ( $fileMatchesSearch, $flags )
                {
                        global $wgContLang;
-                       $info = $that->getInfo();
+                       $info = $this->getInfo();
                        foreach ( $res as $row ) {
-                               $file = $that->newFileFromRow( $row );
+                               $file = $this->newFileFromRow( $row );
                                // There must have been a search for this DB key, but this has to handle the
                                // cases were title capitalization is different on the client and repo wikis.
                                $dbKeysLook = [ strtr( $file->getName(), ' ', '_' ) ];
index 6984d48..758fb4b 100644 (file)
@@ -215,6 +215,8 @@ class ArchivedFile {
 
        /**
         * Fields in the filearchive table
+        * @todo Deprecate this in favor of a method that returns tables and joins
+        *  as well, and use CommentStore::getJoin().
         * @return array
         */
        static function selectFields() {
@@ -232,14 +234,13 @@ class ArchivedFile {
                        'fa_media_type',
                        'fa_major_mime',
                        'fa_minor_mime',
-                       'fa_description',
                        'fa_user',
                        'fa_user_text',
                        'fa_timestamp',
                        'fa_deleted',
                        'fa_deleted_timestamp', /* Used by LocalFileRestoreBatch */
                        'fa_sha1',
-               ];
+               ] + CommentStore::newKey( 'fa_description' )->getFields();
        }
 
        /**
@@ -261,7 +262,9 @@ class ArchivedFile {
                $this->metadata = $row->fa_metadata;
                $this->mime = "$row->fa_major_mime/$row->fa_minor_mime";
                $this->media_type = $row->fa_media_type;
-               $this->description = $row->fa_description;
+               $this->description = CommentStore::newKey( 'fa_description' )
+                       // Legacy because $row probably came from self::selectFields()
+                       ->getCommentLegacy( wfGetDB( DB_REPLICA ), $row )->text;
                $this->user = $row->fa_user;
                $this->user_text = $row->fa_user_text;
                $this->timestamp = $row->fa_timestamp;
index 460fe51..32f4504 100644 (file)
@@ -1147,7 +1147,7 @@ abstract class File implements IDBAccessObject {
                if ( !$thumb ) { // bad params?
                        $thumb = false;
                } elseif ( $thumb->isError() ) { // transform error
-                       /** @var $thumb MediaTransformError */
+                       /** @var MediaTransformError $thumb */
                        $this->lastError = $thumb->toText();
                        // Ignore errors if requested
                        if ( $wgIgnoreImageErrors && !( $flags & self::RENDER_NOW ) ) {
@@ -1282,11 +1282,10 @@ abstract class File implements IDBAccessObject {
                // Thumbnailing a very large file could result in network saturation if
                // everyone does it at once.
                if ( $this->getSize() >= 1e7 ) { // 10MB
-                       $that = $this;
                        $work = new PoolCounterWorkViaCallback( 'GetLocalFileCopy', sha1( $this->getName() ),
                                [
-                                       'doWork' => function () use ( $that ) {
-                                               return $that->getLocalRefPath();
+                                       'doWork' => function () {
+                                               return $this->getLocalRefPath();
                                        }
                                ]
                        );
index 33177d3..9af0c6d 100644 (file)
@@ -193,6 +193,8 @@ class LocalFile extends File {
 
        /**
         * Fields in the image table
+        * @todo Deprecate this in favor of a method that returns tables and joins
+        *  as well, and use CommentStore::getJoin().
         * @return array
         */
        static function selectFields() {
@@ -206,12 +208,11 @@ class LocalFile extends File {
                        'img_media_type',
                        'img_major_mime',
                        'img_minor_mime',
-                       'img_description',
                        'img_user',
                        'img_user_text',
                        'img_timestamp',
                        'img_sha1',
-               ];
+               ] + CommentStore::newKey( 'img_description' )->getFields();
        }
 
        /**
@@ -1299,6 +1300,8 @@ class LocalFile extends File {
        function recordUpload2(
                $oldver, $comment, $pageText, $props = false, $timestamp = false, $user = null, $tags = []
        ) {
+               global $wgCommentTableSchemaMigrationStage;
+
                if ( is_null( $user ) ) {
                        global $wgUser;
                        $user = $wgUser;
@@ -1334,6 +1337,9 @@ class LocalFile extends File {
                # Test to see if the row exists using INSERT IGNORE
                # This avoids race conditions by locking the row until the commit, and also
                # doesn't deadlock. SELECT FOR UPDATE causes a deadlock for every race condition.
+               $commentStore = new CommentStore( 'img_description' );
+               list( $commentFields, $commentCallback ) =
+                       $commentStore->insertWithTempTable( $dbw, $comment );
                $dbw->insert( 'image',
                        [
                                'img_name' => $this->getName(),
@@ -1345,17 +1351,16 @@ class LocalFile extends File {
                                'img_major_mime' => $this->major_mime,
                                'img_minor_mime' => $this->minor_mime,
                                'img_timestamp' => $timestamp,
-                               'img_description' => $comment,
                                'img_user' => $user->getId(),
                                'img_user_text' => $user->getName(),
                                'img_metadata' => $dbw->encodeBlob( $this->metadata ),
                                'img_sha1' => $this->sha1
-                       ],
+                       ] + $commentFields,
                        __METHOD__,
                        'IGNORE'
                );
-
                $reupload = ( $dbw->affectedRows() == 0 );
+
                if ( $reupload ) {
                        if ( $allowTimeKludge ) {
                                # Use LOCK IN SHARE MODE to ignore any transaction snapshotting
@@ -1376,33 +1381,65 @@ class LocalFile extends File {
                                }
                        }
 
+                       $tables = [ 'image' ];
+                       $fields = [
+                               'oi_name' => 'img_name',
+                               'oi_archive_name' => $dbw->addQuotes( $oldver ),
+                               'oi_size' => 'img_size',
+                               'oi_width' => 'img_width',
+                               'oi_height' => 'img_height',
+                               'oi_bits' => 'img_bits',
+                               'oi_timestamp' => 'img_timestamp',
+                               'oi_user' => 'img_user',
+                               'oi_user_text' => 'img_user_text',
+                               'oi_metadata' => 'img_metadata',
+                               'oi_media_type' => 'img_media_type',
+                               'oi_major_mime' => 'img_major_mime',
+                               'oi_minor_mime' => 'img_minor_mime',
+                               'oi_sha1' => 'img_sha1',
+                       ];
+                       $joins = [];
+
+                       if ( $wgCommentTableSchemaMigrationStage <= MIGRATION_WRITE_BOTH ) {
+                               $fields['oi_description'] = 'img_description';
+                       }
+                       if ( $wgCommentTableSchemaMigrationStage >= MIGRATION_WRITE_BOTH ) {
+                               $tables[] = 'image_comment_temp';
+                               $fields['oi_description_id'] = 'imgcomment_description_id';
+                               $joins['image_comment_temp'] = [
+                                       $wgCommentTableSchemaMigrationStage === MIGRATION_NEW ? 'JOIN' : 'LEFT JOIN',
+                                       [ 'imgcomment_name = img_name' ]
+                               ];
+                       }
+
+                       if ( $wgCommentTableSchemaMigrationStage !== MIGRATION_OLD &&
+                               $wgCommentTableSchemaMigrationStage !== MIGRATION_NEW
+                       ) {
+                               // Upgrade any rows that are still old-style. Otherwise an upgrade
+                               // might be missed if a deletion happens while the migration script
+                               // is running.
+                               $res = $dbw->select(
+                                       [ 'image', 'image_comment_temp' ],
+                                       [ 'img_name', 'img_description' ],
+                                       [ 'img_name' => $this->getName(), 'imgcomment_name' => null ],
+                                       __METHOD__,
+                                       [],
+                                       [ 'image_comment_temp' => [ 'LEFT JOIN', [ 'imgcomment_name = img_name' ] ] ]
+                               );
+                               foreach ( $res as $row ) {
+                                       list( , $callback ) = $commentStore->insertWithTempTable( $dbw, $row->img_description );
+                                       $callback( $row->img_name );
+                               }
+                       }
+
                        # (T36993) Note: $oldver can be empty here, if the previous
                        # version of the file was broken. Allow registration of the new
                        # version to continue anyway, because that's better than having
                        # an image that's not fixable by user operations.
                        # Collision, this is an update of a file
                        # Insert previous contents into oldimage
-                       $dbw->insertSelect( 'oldimage', 'image',
-                               [
-                                       'oi_name' => 'img_name',
-                                       'oi_archive_name' => $dbw->addQuotes( $oldver ),
-                                       'oi_size' => 'img_size',
-                                       'oi_width' => 'img_width',
-                                       'oi_height' => 'img_height',
-                                       'oi_bits' => 'img_bits',
-                                       'oi_timestamp' => 'img_timestamp',
-                                       'oi_description' => 'img_description',
-                                       'oi_user' => 'img_user',
-                                       'oi_user_text' => 'img_user_text',
-                                       'oi_metadata' => 'img_metadata',
-                                       'oi_media_type' => 'img_media_type',
-                                       'oi_major_mime' => 'img_major_mime',
-                                       'oi_minor_mime' => 'img_minor_mime',
-                                       'oi_sha1' => 'img_sha1'
-                               ],
-                               [ 'img_name' => $this->getName() ],
-                               __METHOD__
-                       );
+                       $dbw->insertSelect( 'oldimage', $tables, $fields,
+                               [ 'img_name' => $this->getName() ], __METHOD__, [], [], $joins );
 
                        # Update the current image row
                        $dbw->update( 'image',
@@ -1415,16 +1452,20 @@ class LocalFile extends File {
                                        'img_major_mime' => $this->major_mime,
                                        'img_minor_mime' => $this->minor_mime,
                                        'img_timestamp' => $timestamp,
-                                       'img_description' => $comment,
                                        'img_user' => $user->getId(),
                                        'img_user_text' => $user->getName(),
                                        'img_metadata' => $dbw->encodeBlob( $this->metadata ),
                                        'img_sha1' => $this->sha1
-                               ],
+                               ] + $commentFields,
                                [ 'img_name' => $this->getName() ],
                                __METHOD__
                        );
+                       if ( $wgCommentTableSchemaMigrationStage > MIGRATION_OLD ) {
+                               // So $commentCallback can insert the new row
+                               $dbw->delete( 'image_comment_temp', [ 'imgcomment_name' => $this->getName() ], __METHOD__ );
+                       }
                }
+               $commentCallback( $this->getName() );
 
                $descTitle = $this->getTitle();
                $descId = $descTitle->getArticleID();
@@ -1515,7 +1556,7 @@ class LocalFile extends File {
                                                );
 
                                                if ( isset( $status->value['revision'] ) ) {
-                                                       /** @var $rev Revision */
+                                                       /** @var Revision $rev */
                                                        $rev = $status->value['revision'];
                                                        // Associate new page revision id
                                                        $logEntry->setAssociatedRevId( $rev->getId() );
@@ -1523,7 +1564,7 @@ class LocalFile extends File {
                                                // This relies on the resetArticleID() call in WikiPage::insertOn(),
                                                // which is triggered on $descTitle by doEditContent() above.
                                                if ( isset( $status->value['revision'] ) ) {
-                                                       /** @var $rev Revision */
+                                                       /** @var Revision $rev */
                                                        $rev = $status->value['revision'];
                                                        $updateLogPage = $rev->getPage();
                                                }
@@ -2255,8 +2296,16 @@ class LocalFileDeleteBatch {
        }
 
        protected function doDBInserts() {
+               global $wgCommentTableSchemaMigrationStage;
+
                $now = time();
                $dbw = $this->file->repo->getMasterDB();
+
+               $commentStoreImgDesc = new CommentStore( 'img_description' );
+               $commentStoreOiDesc = new CommentStore( 'oi_description' );
+               $commentStoreFaDesc = new CommentStore( 'fa_description' );
+               $commentStoreFaReason = new CommentStore( 'fa_deleted_reason' );
+
                $encTimestamp = $dbw->addQuotes( $dbw->timestamp( $now ) );
                $encUserId = $dbw->addQuotes( $this->user->getId() );
                $encReason = $dbw->addQuotes( $this->reason );
@@ -2274,39 +2323,70 @@ class LocalFileDeleteBatch {
                }
 
                if ( $deleteCurrent ) {
-                       $dbw->insertSelect(
-                               'filearchive',
-                               'image',
-                               [
-                                       'fa_storage_group' => $encGroup,
-                                       'fa_storage_key' => $dbw->conditional(
-                                               [ 'img_sha1' => '' ],
-                                               $dbw->addQuotes( '' ),
-                                               $dbw->buildConcat( [ "img_sha1", $encExt ] )
-                                       ),
-                                       'fa_deleted_user' => $encUserId,
-                                       'fa_deleted_timestamp' => $encTimestamp,
-                                       'fa_deleted_reason' => $encReason,
-                                       'fa_deleted' => $this->suppress ? $bitfield : 0,
-                                       'fa_name' => 'img_name',
-                                       'fa_archive_name' => 'NULL',
-                                       'fa_size' => 'img_size',
-                                       'fa_width' => 'img_width',
-                                       'fa_height' => 'img_height',
-                                       'fa_metadata' => 'img_metadata',
-                                       'fa_bits' => 'img_bits',
-                                       'fa_media_type' => 'img_media_type',
-                                       'fa_major_mime' => 'img_major_mime',
-                                       'fa_minor_mime' => 'img_minor_mime',
-                                       'fa_description' => 'img_description',
-                                       'fa_user' => 'img_user',
-                                       'fa_user_text' => 'img_user_text',
-                                       'fa_timestamp' => 'img_timestamp',
-                                       'fa_sha1' => 'img_sha1'
-                               ],
-                               [ 'img_name' => $this->file->getName() ],
-                               __METHOD__
-                       );
+                       $tables = [ 'image' ];
+                       $fields = [
+                               'fa_storage_group' => $encGroup,
+                               'fa_storage_key' => $dbw->conditional(
+                                       [ 'img_sha1' => '' ],
+                                       $dbw->addQuotes( '' ),
+                                       $dbw->buildConcat( [ "img_sha1", $encExt ] )
+                               ),
+                               'fa_deleted_user' => $encUserId,
+                               'fa_deleted_timestamp' => $encTimestamp,
+                               'fa_deleted' => $this->suppress ? $bitfield : 0,
+                               'fa_name' => 'img_name',
+                               'fa_archive_name' => 'NULL',
+                               'fa_size' => 'img_size',
+                               'fa_width' => 'img_width',
+                               'fa_height' => 'img_height',
+                               'fa_metadata' => 'img_metadata',
+                               'fa_bits' => 'img_bits',
+                               'fa_media_type' => 'img_media_type',
+                               'fa_major_mime' => 'img_major_mime',
+                               'fa_minor_mime' => 'img_minor_mime',
+                               'fa_user' => 'img_user',
+                               'fa_user_text' => 'img_user_text',
+                               'fa_timestamp' => 'img_timestamp',
+                               'fa_sha1' => 'img_sha1'
+                       ];
+                       $joins = [];
+
+                       $fields += $commentStoreFaReason->insert( $dbw, $encReason );
+
+                       if ( $wgCommentTableSchemaMigrationStage <= MIGRATION_WRITE_BOTH ) {
+                               $fields['fa_description'] = 'img_description';
+                       }
+                       if ( $wgCommentTableSchemaMigrationStage >= MIGRATION_WRITE_BOTH ) {
+                               $tables[] = 'image_comment_temp';
+                               $fields['fa_description_id'] = 'imgcomment_description_id';
+                               $joins['image_comment_temp'] = [
+                                       $wgCommentTableSchemaMigrationStage === MIGRATION_NEW ? 'JOIN' : 'LEFT JOIN',
+                                       [ 'imgcomment_name = img_name' ]
+                               ];
+                       }
+
+                       if ( $wgCommentTableSchemaMigrationStage !== MIGRATION_OLD &&
+                               $wgCommentTableSchemaMigrationStage !== MIGRATION_NEW
+                       ) {
+                               // Upgrade any rows that are still old-style. Otherwise an upgrade
+                               // might be missed if a deletion happens while the migration script
+                               // is running.
+                               $res = $dbw->select(
+                                       [ 'image', 'image_comment_temp' ],
+                                       [ 'img_name', 'img_description' ],
+                                       [ 'img_name' => $this->file->getName(), 'imgcomment_name' => null ],
+                                       __METHOD__,
+                                       [],
+                                       [ 'image_comment_temp' => [ 'LEFT JOIN', [ 'imgcomment_name = img_name' ] ] ]
+                               );
+                               foreach ( $res as $row ) {
+                                       list( , $callback ) = $commentStoreImgDesc->insertWithTempTable( $dbw, $row->img_description );
+                                       $callback( $row->img_name );
+                               }
+                       }
+
+                       $dbw->insertSelect( 'filearchive', $tables, $fields,
+                               [ 'img_name' => $this->file->getName() ], __METHOD__, [], [], $joins );
                }
 
                if ( count( $oldRels ) ) {
@@ -2321,34 +2401,38 @@ class LocalFileDeleteBatch {
                                [ 'FOR UPDATE' ]
                        );
                        $rowsInsert = [];
-                       foreach ( $res as $row ) {
-                               $rowsInsert[] = [
-                                       // Deletion-specific fields
-                                       'fa_storage_group' => 'deleted',
-                                       'fa_storage_key' => ( $row->oi_sha1 === '' )
+                       if ( $res->numRows() ) {
+                               $reason = $commentStoreFaReason->createComment( $dbw, $this->reason );
+                               foreach ( $res as $row ) {
+                                       // Legacy from OldLocalFile::selectFields() just above
+                                       $comment = $commentStoreOiDesc->getCommentLegacy( $dbw, $row );
+                                       $rowsInsert[] = [
+                                               // Deletion-specific fields
+                                               'fa_storage_group' => 'deleted',
+                                               'fa_storage_key' => ( $row->oi_sha1 === '' )
                                                ? ''
                                                : "{$row->oi_sha1}{$dotExt}",
-                                       'fa_deleted_user' => $this->user->getId(),
-                                       'fa_deleted_timestamp' => $dbw->timestamp( $now ),
-                                       'fa_deleted_reason' => $this->reason,
-                                       // Counterpart fields
-                                       'fa_deleted' => $this->suppress ? $bitfield : $row->oi_deleted,
-                                       'fa_name' => $row->oi_name,
-                                       'fa_archive_name' => $row->oi_archive_name,
-                                       'fa_size' => $row->oi_size,
-                                       'fa_width' => $row->oi_width,
-                                       'fa_height' => $row->oi_height,
-                                       'fa_metadata' => $row->oi_metadata,
-                                       'fa_bits' => $row->oi_bits,
-                                       'fa_media_type' => $row->oi_media_type,
-                                       'fa_major_mime' => $row->oi_major_mime,
-                                       'fa_minor_mime' => $row->oi_minor_mime,
-                                       'fa_description' => $row->oi_description,
-                                       'fa_user' => $row->oi_user,
-                                       'fa_user_text' => $row->oi_user_text,
-                                       'fa_timestamp' => $row->oi_timestamp,
-                                       'fa_sha1' => $row->oi_sha1
-                               ];
+                                               'fa_deleted_user' => $this->user->getId(),
+                                               'fa_deleted_timestamp' => $dbw->timestamp( $now ),
+                                               // Counterpart fields
+                                               'fa_deleted' => $this->suppress ? $bitfield : $row->oi_deleted,
+                                               'fa_name' => $row->oi_name,
+                                               'fa_archive_name' => $row->oi_archive_name,
+                                               'fa_size' => $row->oi_size,
+                                               'fa_width' => $row->oi_width,
+                                               'fa_height' => $row->oi_height,
+                                               'fa_metadata' => $row->oi_metadata,
+                                               'fa_bits' => $row->oi_bits,
+                                               'fa_media_type' => $row->oi_media_type,
+                                               'fa_major_mime' => $row->oi_major_mime,
+                                               'fa_minor_mime' => $row->oi_minor_mime,
+                                               'fa_user' => $row->oi_user,
+                                               'fa_user_text' => $row->oi_user_text,
+                                               'fa_timestamp' => $row->oi_timestamp,
+                                               'fa_sha1' => $row->oi_sha1
+                                       ] + $commentStoreFaReason->insert( $dbw, $reason )
+                                       + $commentStoreFaDesc->insert( $dbw, $comment );
+                               }
                        }
 
                        $dbw->insert( 'filearchive', $rowsInsert, __METHOD__ );
@@ -2356,6 +2440,8 @@ class LocalFileDeleteBatch {
        }
 
        function doDBDeletes() {
+               global $wgUpdateCompatibleMetadata;
+
                $dbw = $this->file->repo->getMasterDB();
                list( $oldRels, $deleteCurrent ) = $this->getOldRels();
 
@@ -2369,6 +2455,11 @@ class LocalFileDeleteBatch {
 
                if ( $deleteCurrent ) {
                        $dbw->delete( 'image', [ 'img_name' => $this->file->getName() ], __METHOD__ );
+                       if ( $wgUpdateCompatibleMetadata > MIGRATION_OLD ) {
+                               $dbw->delete(
+                                       'image_comment_temp', [ 'imgcomment_name' => $this->file->getName() ], __METHOD__
+                               );
+                       }
                }
        }
 
@@ -2537,6 +2628,11 @@ class LocalFileRestoreBatch {
                $lockOwnsTrx = $this->file->lock();
 
                $dbw = $this->file->repo->getMasterDB();
+
+               $commentStoreImgDesc = new CommentStore( 'img_description' );
+               $commentStoreOiDesc = new CommentStore( 'oi_description' );
+               $commentStoreFaDesc = new CommentStore( 'fa_description' );
+
                $status = $this->file->repo->newGood();
 
                $exists = (bool)$dbw->selectField( 'image', '1',
@@ -2621,9 +2717,13 @@ class LocalFileRestoreBatch {
                                ];
                        }
 
+                       // Legacy from ArchivedFile::selectFields() just above
+                       $comment = $commentStoreFaDesc->getCommentLegacy( $dbw, $row );
                        if ( $first && !$exists ) {
                                // This revision will be published as the new current version
                                $destRel = $this->file->getRel();
+                               list( $commentFields, $commentCallback ) =
+                                       $commentStoreImgDesc->insertWithTempTable( $dbw, $comment );
                                $insertCurrent = [
                                        'img_name' => $row->fa_name,
                                        'img_size' => $row->fa_size,
@@ -2634,12 +2734,11 @@ class LocalFileRestoreBatch {
                                        'img_media_type' => $props['media_type'],
                                        'img_major_mime' => $props['major_mime'],
                                        'img_minor_mime' => $props['minor_mime'],
-                                       'img_description' => $row->fa_description,
                                        'img_user' => $row->fa_user,
                                        'img_user_text' => $row->fa_user_text,
                                        'img_timestamp' => $row->fa_timestamp,
                                        'img_sha1' => $sha1
-                               ];
+                               ] + $commentFields;
 
                                // The live (current) version cannot be hidden!
                                if ( !$this->unsuppress && $row->fa_deleted ) {
@@ -2671,7 +2770,6 @@ class LocalFileRestoreBatch {
                                        'oi_width' => $row->fa_width,
                                        'oi_height' => $row->fa_height,
                                        'oi_bits' => $row->fa_bits,
-                                       'oi_description' => $row->fa_description,
                                        'oi_user' => $row->fa_user,
                                        'oi_user_text' => $row->fa_user_text,
                                        'oi_timestamp' => $row->fa_timestamp,
@@ -2680,7 +2778,8 @@ class LocalFileRestoreBatch {
                                        'oi_major_mime' => $props['major_mime'],
                                        'oi_minor_mime' => $props['minor_mime'],
                                        'oi_deleted' => $this->unsuppress ? 0 : $row->fa_deleted,
-                                       'oi_sha1' => $sha1 ];
+                                       'oi_sha1' => $sha1
+                               ] + $commentStoreOiDesc->insert( $dbw, $comment );
                        }
 
                        $deleteIds[] = $row->fa_id;
@@ -2738,6 +2837,7 @@ class LocalFileRestoreBatch {
                // This is not ideal, which is why it's important to lock the image row.
                if ( $insertCurrent ) {
                        $dbw->insert( 'image', $insertCurrent, __METHOD__ );
+                       $commentCallback( $insertCurrent['img_name'] );
                }
 
                if ( $insertBatch ) {
index dfaae73..b46e1e4 100644 (file)
@@ -103,6 +103,8 @@ class OldLocalFile extends LocalFile {
 
        /**
         * Fields in the oldimage table
+        * @todo Deprecate this in favor of a method that returns tables and joins
+        *  as well, and use CommentStore::getJoin().
         * @return array
         */
        static function selectFields() {
@@ -117,13 +119,12 @@ class OldLocalFile extends LocalFile {
                        'oi_media_type',
                        'oi_major_mime',
                        'oi_minor_mime',
-                       'oi_description',
                        'oi_user',
                        'oi_user_text',
                        'oi_timestamp',
                        'oi_deleted',
                        'oi_sha1',
-               ];
+               ] + CommentStore::newKey( 'oi_description' )->getFields();
        }
 
        /**
@@ -367,6 +368,7 @@ class OldLocalFile extends LocalFile {
                        return false;
                }
 
+               $commentFields = CommentStore::newKey( 'oi_description' )->insert( $dbw, $comment );
                $dbw->insert( 'oldimage',
                        [
                                'oi_name' => $this->getName(),
@@ -376,7 +378,6 @@ class OldLocalFile extends LocalFile {
                                'oi_height' => intval( $props['height'] ),
                                'oi_bits' => $props['bits'],
                                'oi_timestamp' => $dbw->timestamp( $timestamp ),
-                               'oi_description' => $comment,
                                'oi_user' => $user->getId(),
                                'oi_user_text' => $user->getName(),
                                'oi_metadata' => $props['metadata'],
@@ -384,7 +385,7 @@ class OldLocalFile extends LocalFile {
                                'oi_major_mime' => $props['major_mime'],
                                'oi_minor_mime' => $props['minor_mime'],
                                'oi_sha1' => $props['sha1'],
-                       ], __METHOD__
+                       ] + $commentFields, __METHOD__
                );
 
                return true;
index 2099709..9066079 100644 (file)
@@ -813,7 +813,7 @@ class WikiImporter {
                $this->debug( "Enter revision handler" );
                $revisionInfo = [];
 
-               $normalFields = [ 'id', 'timestamp', 'comment', 'minor', 'model', 'format', 'text' ];
+               $normalFields = [ 'id', 'timestamp', 'comment', 'minor', 'model', 'format', 'text', 'sha1' ];
 
                $skip = false;
 
@@ -916,6 +916,9 @@ class WikiImporter {
                } else {
                        $revision->setUsername( 'Unknown user' );
                }
+               if ( isset( $revisionInfo['sha1'] ) ) {
+                       $revision->setSha1Base36( $revisionInfo['sha1'] );
+               }
                $revision->setNoUpdates( $this->mNoUpdates );
 
                return $this->revisionCallback( $revision );
index f6becb9..edb0c9a 100644 (file)
@@ -607,11 +607,12 @@ class WikiRevision {
                        $pageId = $page->getId();
                        $created = false;
 
+                       // Note: sha1 has been in XML dumps since 2012. If you have an
+                       // older dump, the duplicate detection here won't work.
                        $prior = $dbw->selectField( 'revision', '1',
                                [ 'rev_page' => $pageId,
                                        'rev_timestamp' => $dbw->timestamp( $this->timestamp ),
-                                       'rev_user_text' => $userText,
-                                       'rev_comment' => $this->getComment() ],
+                                       'rev_sha1' => $this->sha1base36 ],
                                __METHOD__
                        );
                        if ( $prior ) {
@@ -708,7 +709,6 @@ class WikiRevision {
                                'log_timestamp' => $dbw->timestamp( $this->timestamp ),
                                'log_namespace' => $this->getTitle()->getNamespace(),
                                'log_title' => $this->getTitle()->getDBkey(),
-                               'log_comment' => $this->getComment(),
                                # 'log_user_text' => $this->user_text,
                                'log_params' => $this->params ],
                        __METHOD__
@@ -720,9 +720,7 @@ class WikiRevision {
                                . $this->timestamp . "\n" );
                        return false;
                }
-               $log_id = $dbw->nextSequenceValue( 'logging_log_id_seq' );
                $data = [
-                       'log_id' => $log_id,
                        'log_type' => $this->type,
                        'log_action' => $this->action,
                        'log_timestamp' => $dbw->timestamp( $this->timestamp ),
@@ -730,9 +728,8 @@ class WikiRevision {
                        'log_user_text' => $userText,
                        'log_namespace' => $this->getTitle()->getNamespace(),
                        'log_title' => $this->getTitle()->getDBkey(),
-                       'log_comment' => $this->getComment(),
                        'log_params' => $this->params
-               ];
+               ] + CommentStore::newKey( 'log_comment' )->insert( $dbw, $this->getComment() );
                $dbw->insert( 'logging', $data, __METHOD__ );
 
                return true;
index b832d45..645fa8a 100644 (file)
@@ -1190,4 +1190,25 @@ abstract class DatabaseUpdater {
                        $wgContentHandlerUseDB = $this->holdContentHandlerUseDB;
                }
        }
+
+       /**
+        * Migrate comments to the new 'comment' table
+        * @since 1.30
+        */
+       protected function migrateComments() {
+               global $wgCommentTableSchemaMigrationStage;
+               if ( $wgCommentTableSchemaMigrationStage >= MIGRATION_WRITE_NEW &&
+                       !$this->updateRowExists( 'MigrateComments' )
+               ) {
+                       $this->output(
+                               "Migrating comments to the 'comments' table, printing progress markers. For large\n" .
+                               "databases, you may want to hit Ctrl-C and do this manually with\n" .
+                               "maintenance/migrateComments.php.\n"
+                       );
+                       $task = $this->maintenance->runChild( 'MigrateComments', 'migrateComments.php' );
+                       $task->execute();
+                       $this->output( "done.\n" );
+               }
+       }
+
 }
index ae80c8b..52be321 100644 (file)
@@ -1389,7 +1389,7 @@ abstract class Installer {
                        }
                }
                closedir( $dh );
-               natcasesort( $exts );
+               uksort( $exts, 'strnatcasecmp' );
 
                return $exts;
        }
index 43d3574..d01f954 100644 (file)
@@ -266,7 +266,7 @@ class MssqlInstaller extends DatabaseInstaller {
                if ( !$status->isOK() ) {
                        return false;
                }
-               /** @var $conn Database */
+               /** @var Database $conn */
                $conn = $status->value;
 
                // We need the server-level ALTER ANY LOGIN permission to create new accounts
index 0250b6f..dc63899 100644 (file)
@@ -275,7 +275,7 @@ class MysqlInstaller extends DatabaseInstaller {
                if ( !$status->isOK() ) {
                        return false;
                }
-               /** @var $conn Database */
+               /** @var Database $conn */
                $conn = $status->value;
 
                // Get current account name
index 58728a3..b42ae46 100644 (file)
@@ -170,7 +170,6 @@ class MysqlUpdater extends DatabaseUpdater {
                        [ 'doLogUsertextPopulation' ],
                        [ 'doLogSearchPopulation' ],
                        [ 'addTable', 'l10n_cache', 'patch-l10n_cache.sql' ],
-                       [ 'addIndex', 'log_search', 'ls_field_val', 'patch-log_search-rename-index.sql' ],
                        [ 'addIndex', 'change_tag', 'change_tag_rc_tag', 'patch-change_tag-indexes.sql' ],
                        [ 'addField', 'redirect', 'rd_interwiki', 'patch-rd_interwiki.sql' ],
                        [ 'doUpdateTranscacheField' ],
@@ -305,6 +304,29 @@ class MysqlUpdater extends DatabaseUpdater {
                        // 1.30
                        [ 'modifyField', 'image', 'img_media_type', 'patch-add-3d.sql' ],
                        [ 'addTable', 'ip_changes', 'patch-ip_changes.sql' ],
+                       [ 'renameIndex', 'categorylinks', 'cl_from', 'PRIMARY', false,
+                               'patch-categorylinks-fix-pk.sql' ],
+                       [ 'renameIndex', 'templatelinks', 'tl_from', 'PRIMARY', false,
+                               'patch-templatelinks-fix-pk.sql' ],
+                       [ 'renameIndex', 'pagelinks', 'pl_from', 'PRIMARY', false, 'patch-pagelinks-fix-pk.sql' ],
+                       [ 'renameIndex', 'text', 'old_id', 'PRIMARY', false, 'patch-text-fix-pk.sql' ],
+                       [ 'renameIndex', 'imagelinks', 'il_from', 'PRIMARY', false, 'patch-imagelinks-fix-pk.sql' ],
+                       [ 'renameIndex', 'iwlinks', 'iwl_from', 'PRIMARY', false, 'patch-iwlinks-fix-pk.sql' ],
+                       [ 'renameIndex', 'langlinks', 'll_from', 'PRIMARY', false, 'patch-langlinks-fix-pk.sql' ],
+                       [ 'renameIndex', 'log_search', 'ls_field_val', 'PRIMARY', false, 'patch-log_search-fix-pk.sql' ],
+                       [ 'renameIndex', 'module_deps', 'md_module_skin', 'PRIMARY', false,
+                               'patch-module_deps-fix-pk.sql' ],
+                       [ 'renameIndex', 'objectcache', 'keyname', 'PRIMARY', false, 'patch-objectcache-fix-pk.sql' ],
+                       [ 'renameIndex', 'querycache_info', 'qci_type', 'PRIMARY', false,
+                               'patch-querycache_info-fix-pk.sql' ],
+                       [ 'renameIndex', 'site_stats', 'ss_row_id', 'PRIMARY', false, 'patch-site_stats-fix-pk.sql' ],
+                       [ 'renameIndex', 'transcache', 'tc_url_idx', 'PRIMARY', false, 'patch-transcache-fix-pk.sql' ],
+                       [ 'renameIndex', 'user_former_groups', 'ufg_user_group', 'PRIMARY', false,
+                               'patch-user_former_groups-fix-pk.sql' ],
+                       [ 'renameIndex', 'user_properties', 'user_properties_user_property', 'PRIMARY', false,
+                               'patch-user_properties-fix-pk.sql' ],
+                       [ 'addTable', 'comment', 'patch-comment-table.sql' ],
+                       [ 'migrateComments' ],
                ];
        }
 
index e262eda..00b9661 100644 (file)
@@ -123,6 +123,9 @@ class OracleUpdater extends DatabaseUpdater {
                        [ 'addField', 'externallinks', 'el_index_60', 'patch-externallinks-el_index_60.sql' ],
                        [ 'addField', 'user_groups', 'ug_expiry', 'patch-user_groups-ug_expiry.sql' ],
 
+                       // 1.30
+                       [ 'doAutoIncrementTriggers' ],
+
                        // KEEP THIS AT THE BOTTOM!!
                        [ 'doRebuildDuplicateFunction' ],
 
@@ -273,6 +276,30 @@ class OracleUpdater extends DatabaseUpdater {
                $this->output( "ok\n" );
        }
 
+       /**
+        * Add auto-increment triggers
+        */
+       protected function doAutoIncrementTriggers() {
+               $this->output( "Adding auto-increment triggers ... " );
+
+               $meta = $this->db->query( 'SELECT trigger_name FROM user_triggers WHERE table_owner = \'' .
+                       strtoupper( $this->db->getDBname() ) .
+                       '\' AND trigger_name = \'' .
+                       $this->db->tablePrefix() .
+                       'PAGE_DEFAULT_PAGE_ID\''
+               );
+               $row = $meta->fetchRow();
+               if ( $row['column_name'] ) {
+                       $this->output( "seems to be up to date.\n" );
+
+                       return;
+               }
+
+               $this->applyPatch( 'patch-auto_increment_triggers.sql', false );
+
+               $this->output( "ok\n" );
+       }
+
        /**
         * rebuilding of the function that duplicates tables for tests
         */
index b501cb3..1a3fb10 100644 (file)
@@ -594,7 +594,7 @@ class PostgresInstaller extends DatabaseInstaller {
                        return $status;
                }
 
-               /** @var $conn DatabasePostgres */
+               /** @var DatabasePostgres $conn */
                $conn = $status->value;
 
                if ( $conn->tableExists( 'archive' ) ) {
index d8db6a2..e5a5c94 100644 (file)
@@ -455,6 +455,32 @@ class PostgresUpdater extends DatabaseUpdater {
 
                        // 1.30
                        [ 'modifyField', 'image', 'img_media_type', 'patch-add-3d.sql' ],
+                       [ 'setDefault', 'revision', 'rev_comment', '' ],
+                       [ 'changeNullableField', 'revision', 'rev_comment', 'NOT NULL', true ],
+                       [ 'setDefault', 'archive', 'ar_comment', '' ],
+                       [ 'changeNullableField', 'archive', 'ar_comment', 'NOT NULL', true ],
+                       [ 'addPgField', 'archive', 'ar_comment_id', 'INTEGER NOT NULL DEFAULT 0' ],
+                       [ 'setDefault', 'ipblocks', 'ipb_reason', '' ],
+                       [ 'addPgField', 'ipblocks', 'ipb_reason_id', 'INTEGER NOT NULL DEFAULT 0' ],
+                       [ 'setDefault', 'image', 'img_description', '' ],
+                       [ 'setDefault', 'oldimage', 'oi_description', '' ],
+                       [ 'changeNullableField', 'oldimage', 'oi_description', 'NOT NULL', true ],
+                       [ 'addPgField', 'oldimage', 'oi_description_id', 'INTEGER NOT NULL DEFAULT 0' ],
+                       [ 'setDefault', 'filearchive', 'fa_deleted_reason', '' ],
+                       [ 'changeNullableField', 'filearchive', 'fa_deleted_reason', 'NOT NULL', true ],
+                       [ 'addPgField', 'filearchive', 'fa_deleted_reason_id', 'INTEGER NOT NULL DEFAULT 0' ],
+                       [ 'setDefault', 'filearchive', 'fa_description', '' ],
+                       [ 'addPgField', 'filearchive', 'fa_description_id', 'INTEGER NOT NULL DEFAULT 0' ],
+                       [ 'setDefault', 'recentchanges', 'rc_comment', '' ],
+                       [ 'changeNullableField', 'recentchanges', 'rc_comment', 'NOT NULL', true ],
+                       [ 'addPgField', 'recentchanges', 'rc_comment_id', 'INTEGER NOT NULL DEFAULT 0' ],
+                       [ 'setDefault', 'logging', 'log_comment', '' ],
+                       [ 'changeNullableField', 'logging', 'log_comment', 'NOT NULL', true ],
+                       [ 'addPgField', 'logging', 'log_comment_id', 'INTEGER NOT NULL DEFAULT 0' ],
+                       [ 'setDefault', 'protected_titles', 'pt_reason', '' ],
+                       [ 'changeNullableField', 'protected_titles', 'pt_reason', 'NOT NULL', true ],
+                       [ 'addPgField', 'protected_titles', 'pt_reason_id', 'INTEGER NOT NULL DEFAULT 0' ],
+                       [ 'addTable', 'comment', 'patch-comment-table.sql' ],
                ];
        }
 
@@ -761,7 +787,7 @@ END;
                }
        }
 
-       protected function changeNullableField( $table, $field, $null ) {
+       protected function changeNullableField( $table, $field, $null, $update = false ) {
                $fi = $this->db->fieldInfo( $table, $field );
                if ( is_null( $fi ) ) {
                        $this->output( "...ERROR: expected column $table.$field to exist\n" );
@@ -771,6 +797,9 @@ END;
                        # # It's NULL - does it need to be NOT NULL?
                        if ( 'NOT NULL' === $null ) {
                                $this->output( "Changing '$table.$field' to not allow NULLs\n" );
+                               if ( $update ) {
+                                       $this->db->query( "UPDATE $table SET $field = DEFAULT WHERE $field IS NULL" );
+                               }
                                $this->db->query( "ALTER TABLE $table ALTER $field SET NOT NULL" );
                        } else {
                                $this->output( "...column '$table.$field' is already set as NULL\n" );
index 1e43d3e..d0ed822 100644 (file)
@@ -54,7 +54,6 @@ class SqliteUpdater extends DatabaseUpdater {
                        [ 'doLogUsertextPopulation' ],
                        [ 'doLogSearchPopulation' ],
                        [ 'addTable', 'l10n_cache', 'patch-l10n_cache.sql' ],
-                       [ 'addIndex', 'log_search', 'ls_field_val', 'patch-log_search-rename-index.sql' ],
                        [ 'addIndex', 'change_tag', 'change_tag_rc_tag', 'patch-change_tag-indexes.sql' ],
                        [ 'addField', 'redirect', 'rd_interwiki', 'patch-rd_interwiki.sql' ],
                        [ 'doUpdateTranscacheField' ],
@@ -169,6 +168,29 @@ class SqliteUpdater extends DatabaseUpdater {
                        // 1.30
                        [ 'modifyField', 'image', 'img_media_type', 'patch-add-3d.sql' ],
                        [ 'addTable', 'ip_changes', 'patch-ip_changes.sql' ],
+                       [ 'renameIndex', 'categorylinks', 'cl_from', 'PRIMARY', false,
+                               'patch-categorylinks-fix-pk.sql' ],
+                       [ 'renameIndex', 'templatelinks', 'tl_from', 'PRIMARY', false,
+                               'patch-templatelinks-fix-pk.sql' ],
+                       [ 'renameIndex', 'pagelinks', 'pl_from', 'PRIMARY', false, 'patch-pagelinks-fix-pk.sql' ],
+                       [ 'renameIndex', 'text', 'old_id', 'PRIMARY', false, 'patch-text-fix-pk.sql' ],
+                       [ 'renameIndex', 'imagelinks', 'il_from', 'PRIMARY', false, 'patch-imagelinks-fix-pk.sql' ],
+                       [ 'renameIndex', 'iwlinks', 'iwl_from', 'PRIMARY', false, 'patch-iwlinks-fix-pk.sql' ],
+                       [ 'renameIndex', 'langlinks', 'll_from', 'PRIMARY', false, 'patch-langlinks-fix-pk.sql' ],
+                       [ 'renameIndex', 'log_search', 'ls_field_val', 'PRIMARY', false, 'patch-log_search-fix-pk.sql' ],
+                       [ 'renameIndex', 'module_deps', 'md_module_skin', 'PRIMARY', false,
+                               'patch-module_deps-fix-pk.sql' ],
+                       [ 'renameIndex', 'objectcache', 'keyname', 'PRIMARY', false, 'patch-objectcache-fix-pk.sql' ],
+                       [ 'renameIndex', 'querycache_info', 'qci_type', 'PRIMARY', false,
+                               'patch-querycache_info-fix-pk.sql' ],
+                       [ 'renameIndex', 'site_stats', 'ss_row_id', 'PRIMARY', false, 'patch-site_stats-fix-pk.sql' ],
+                       [ 'renameIndex', 'transcache', 'tc_url_idx', 'PRIMARY', false, 'patch-transcache-fix-pk.sql' ],
+                       [ 'renameIndex', 'user_former_groups', 'ufg_user_group', 'PRIMARY', false,
+                               'patch-user_former_groups-fix-pk.sql' ],
+                       [ 'renameIndex', 'user_properties', 'user_properties_user_property', 'PRIMARY', false,
+                               'patch-user_properties-fix-pk.sql' ],
+                       [ 'addTable', 'comment', 'patch-comment-table.sql' ],
+                       [ 'migrateComments' ],
                ];
        }
 
index dacdf81..2afd2ca 100644 (file)
@@ -6,7 +6,8 @@
                        "Tjernobyl",
                        "Thomsen",
                        "MGA73",
-                       "Mads Haupt"
+                       "Mads Haupt",
+                       "Joedalton"
                ]
        },
        "config-desc": "Installationsprogrammet til MediaWiki",
        "config-localsettings-upgrade": "En <code>LocalSettings.php</code>-fil er blevet fundet.\nFor at opgradere imstallationen, skriv venligst værdien af <code>$wgUpgradeKey</code> i boksen nedenfor.\nDu finder denne i <code>LocalSettings.php</code>.",
        "config-localsettings-cli-upgrade": "En <code>LocalSettings.php</code>-fil er blevet fundet.\nFor at opgradere installationen skal du køre <code>update.php</code> i stedet for",
        "config-localsettings-key": "Opgraderingsnøgle:",
-       "config-localsettings-badkey": "Den nøgle du indtastede er forkert.",
+       "config-localsettings-badkey": "Den indtastede opgraderingsnøgle er forkert.",
        "config-upgrade-key-missing": "En eksisterende installation af MediaWiki er blevet fundet.\nFor at opgradere denne installation skal du tilføje følgende linje i bunden af din <code>LocalSettings.php</code>:\n\n$1",
+       "config-localsettings-incomplete": "Den eksisterende <code>LocalSettings.php</code> ser ud til at være ufuldstændig.\nVariablen $1 er ikke angivet.\nÆndr venligst <code>LocalSettings.php</code> så denne variabel er angivet, og klik på »{{int:Config-continue}}«.",
+       "config-localsettings-connection-error": "Der opstod en fejl under tilslutningen til databasen med indstillingerne angivet i <code>LocalSettings.php</code>. Ret venligst disse indstillinger og prøv igen.\n\n$1",
+       "config-session-error": "Der opstod en fejl under start af session: $1",
        "config-your-language": "Dit sprog:",
        "config-your-language-help": "Vælg et sprog som du vil bruge under installationen.",
        "config-wiki-language": "Wiki-sprog:",
        "config-db-type": "Databasetype:",
        "config-db-host": "Databasevært:",
        "config-db-name": "Databasenavn:",
+       "config-db-install-account": "Brugerkonto for installation",
+       "config-db-username": "Databasens brugernavn:",
+       "config-db-password": "Databasens adgangskode:",
+       "config-db-install-username": "Indtast brugernavnet som vil blive brugt til at forbinde til databasen under installationsprocessen.\nDette er ikke brugernavnet for MediaWiki-kontoen; det er brugernavnet på din database.",
        "config-mysql-old": "MySQL $1 eller nyere kræves. Du har $2.",
+       "config-type-mssql": "Microsoft SQL-server",
        "config-header-mysql": "MySQL-indstillinger",
        "config-header-postgres": "PostgreSQL-indstillinger",
        "config-header-sqlite": "SQLite-indstillinger",
        "config-header-oracle": "Oracle-indstillinger",
        "config-invalid-db-type": "Ugyldig databasetype",
+       "config-mssql-windowsauth": "Windows-godkendelse",
+       "config-site-name": "Navn på wiki:",
+       "config-site-name-blank": "Indtast et hjemmesidenavn.",
+       "config-ns-generic": "Projekt",
+       "config-admin-box": "Administratorkonto",
+       "config-admin-name": "Dit brugernavn:",
+       "config-admin-password": "Adgangskode:",
+       "config-admin-password-confirm": "Tast adgangskoden igen:",
+       "config-admin-email": "E-postadresse:",
+       "config-optional-continue": "Stil mig flere spørgsmål.",
+       "config-profile-wiki": "Åbn wiki",
+       "config-profile-no-anon": "Kontooprettelse er krævet",
+       "config-profile-fishbowl": "Kun godkendte redaktører",
+       "config-profile-private": "Privat wiki",
+       "config-license": "Ophavsret og licens:",
+       "config-license-pd": "Offentlig ejendom",
        "config-email-usertalk": "Aktiver notifikationer for brugerdiskussionsside",
+       "config-upload-deleted": "Mappe for slettede filer:",
+       "config-help": "hjælp",
+       "config-help-tooltip": "klik for at udvide",
        "mainpagetext": "'''MediaWiki er nu installeret.'''",
        "mainpagedocfooter": "Se [https://meta.wikimedia.org/wiki/Help:Contents brugervejledningen] for oplysninger om brugen af wikiprogrammellet.\n\n== At komme i gang ==\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Configuration_settings Listen over opsætningsmuligheder]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ MediaWiki ofte stillede spørgsmål]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce Postliste angående udgivelser af MediaWiki]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Localisation#Translation_resources Oversæt MediaWiki til dit sprog]"
 }
index 021aa5d..be2e65a 100644 (file)
        "config-connection-error": "$1.\n\nVerifica el servidor, el nombre de usuario y la contraseña, e intenta de nuevo.",
        "config-invalid-schema": "El esquema de la base de datos \"$1\"  es inválido.\nUse sólo carateres ASCII: letras (a-z, A-Z), guarismos (0-9) y guiones bajos (_).",
        "config-db-sys-create-oracle": "El instalador sólo admite el empleo de cuentas SYSDBA como método para crear una cuenta nueva.",
-       "config-db-sys-user-exists-oracle": "La cuenta de usuario \"$1\" ya existe. ¡SYSDBA sólo puede utilizarse para crear una nueva cuenta!",
+       "config-db-sys-user-exists-oracle": "La cuenta de usuario «$1» ya existe. SYSDBA solo puede utilizarse para crear cuentas nuevas.",
        "config-postgres-old": "Se requiere PostgreSQL $1 o posterior. Tienes la versión $2.",
        "config-mssql-old": "Se requiere Microsoft SQL Server $1 o posterior. Tienes la versión $2.",
        "config-sqlite-name-help": "Elige el nombre que identificará a tu wiki.\nNo uses espacios o guiones.\nEste nombre se usará como nombre del archivo de datos de SQLite.",
        "config-pingback-help": "Si seleccionas esta opción, MediaWiki enviará periódicamente a https://www.mediawiki.org datos básicos sobre esta instancia de MediaWiki. Se trata de datos tales como el tipo de sistema, la versión de PHP y la base de datos elegida. La Fundación Wikimedia comparte estos datos con los desarrolladores de MediaWiki para ayudar a guiar el desarrollo futuro. Se enviarán los siguientes datos para tu sistema:\n<pre>$1</pre>",
        "config-almost-done": "¡Ya casi has terminado!\nAhora puedes saltarte el resto de los pasos e instalar el wiki ya.",
        "config-optional-continue": "Hazme más preguntas.",
-       "config-optional-skip": "Ya estoy aburrido, sólo instala el wiki.",
+       "config-optional-skip": "Ya me aburrí. Tan solo instala el wiki.",
        "config-profile": "Perfil de derechos de usuario:",
        "config-profile-wiki": "Wiki abierto",
        "config-profile-no-anon": "Creación de cuenta requerida",
-       "config-profile-fishbowl": "Sólo editores autorizados",
+       "config-profile-fishbowl": "Solo editores autorizados",
        "config-profile-private": "Wiki privado",
        "config-profile-help": "Los wikis funcionan mejor cuando dejas que los edite tanta gente como sea posible.\nEn MediaWiki, es fácil revisar los cambios recientes y revertir los daños realizados por usuarios malintencionados o novatos.\nSin embargo, muchos han encontrado que MediaWiki es útil para una amplia variedad de funciones, y a veces no es fácil convencer a todos de los beneficios de la forma wiki.\nPor lo tanto tienes la elección.\n\nEl modelo <strong>{{int:config-profile-wiki}}</strong> permite que cualquiera pueda editar, sin siquiera iniciar sesión.\nUn wiki con <strong>{{int:config-profile-no-anon}}</strong> ofrece rendición de cuentas adicional, pero puede disuadir a colaboradores casuales.\n\nEl modelo <strong>{{int:config-profile-fishbowl}}</strong> permite editar a los usuarios autorizados, pero el público puede ver las páginas, incluyendo el historial.\nUn <strong>{{int:config-profile-private}}</strong> sólo permite ver páginas a los usuarios autorizados, el mismo grupo al que le está permitido editar.\n\nConfiguraciones más complejas de permisos de usuario están disponibles después de la instalación. Consulta [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:User_rights la entrada correspondiente del manual].",
        "config-license": "Derechos de autor y licencia:",
index 430345e..0591cbb 100644 (file)
@@ -4,7 +4,8 @@
                        "An13sa",
                        "පසිඳු කාවින්ද",
                        "Subi",
-                       "Sator"
+                       "Sator",
+                       "Mikel Ibaiba"
                ]
        },
        "config-desc": "MediaWiki instalatzailea",
        "config-license-pd": "Domeinu Askea",
        "config-license-cc-choose": "Aukeratu Creative Commons lizentzia pertsonalizatua",
        "config-email-settings": "E-posta hobespenak",
+       "config-email-sender": "Itzuli helbide elektronikoa:",
        "config-upload-settings": "Irudi eta fitxategi igoerak",
        "config-upload-enable": "Fitxategi igoera gaitu",
+       "config-upload-deleted": "Ezabatutako artxiboentzako direktorioa:",
        "config-logo": "Logo URL:",
        "config-instantcommons": "Instant Commons gaitu",
        "config-cc-again": "Berriz aukeratu...",
        "config-extensions": "Luzapenak",
        "config-skins": "Itxurak",
        "config-install-step-done": "egina",
+       "config-install-step-failed": "Huts egin du",
        "config-install-extensions": "Luzapenak barne",
        "config-install-database": "Datu-basea konfiguratu",
        "config-install-schema": "Eskema sortu",
+       "config-install-user": "Datubase erabiltzailea sortzen",
        "config-install-user-alreadyexists": "\"$1\" erabiltzailea badago.",
+       "config-install-user-create-failed": "$1 erabiltzailea sortzerakoan huts egin du: $2",
+       "config-install-user-grant-failed": "$1ri baimena emateak huts egin du: $2",
        "config-install-tables": "Taulak sortzen",
        "config-install-interwiki-list": "Ezin izan da <code>interwiki.list</code> fitxategia irakurri.",
        "config-install-stats": "Estatistikak hasten",
index 32d7358..50521f6 100644 (file)
        "config-help-tooltip": "cliquer pour agrandir",
        "config-nofile": "Le fichier « $1 » est introuvable. A-t-il été supprimé ?",
        "config-extension-link": "Saviez-vous que votre wiki prend en charge [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Extensions des extensions] ?\n\nVous pouvez consulter les [https://www.mediawiki.org/wiki/Special:MyLanguage/Category:Extensions_by_category extensions par catégorie] ou la [https://www.mediawiki.org/wiki/Extension_Matrix matrice des extensions] pour voir la liste complète des extensions.",
-       "config-skins-screenshots": "$1 (captures d'écran : $2)",
+       "config-skins-screenshots": "$1 (captures décran : $2)",
        "config-screenshot": "Captures d’écrans",
        "mainpagetext": "<strong>MediaWiki a été installé.</strong>",
        "mainpagedocfooter": "Consultez le [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Contents Guide de l’utilisateur du contenu] pour plus d’informations sur l’utilisation de ce logiciel de wiki.\n\n== Pour démarrer ==\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Configuration_settings Liste des paramètres de configuration]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ/fr Questions courantes sur MediaWiki]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce Liste de discussion sur les distributions de MediaWiki]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Localisation#Translation_resources Adaptez MediaWiki dans votre langue]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Combating_spam Apprendre comment lutter contre le pourriel dans votre wiki]"
index 5ae3a0c..7a49051 100644 (file)
@@ -98,6 +98,7 @@
        "config-no-cli-uploads-check": "<strong>Atenção:</strong> O seu diretório padrão para envios (<code>$1</code>) não está marcado para vulnerabilidade\npara execução de script arbitrário durante a instalação do CLI.",
        "config-brokenlibxml": "O sistema tem uma combinação de PHP e libxml2 que é conflitante e pode causar corrupção de dados ocultos no MediaWiki e outros aplicativos da web.\nAtualize para o libxml2 2.7.3 ou mais recente ([https://bugs.php.net/bug.php?id=45996 bugs com o PHP]).\nInstalação abortada.",
        "config-suhosin-max-value-length": "O Suhosin está instalado e limita o parâmetro GET <code>length</code> para $1 bytes. O componente ResourceLoader trabalhará em torno deste limite, mas degradará a performance.\nSe possível, defina <code>suhosin.get.max_value_length</code> em <code>php.ini</code> para 1024 ou mais e defina <code>$wgResourceLoaderMaxQueryLength</code> em <code>LocalSettings.php</code> para o mesmo valor.",
+       "config-using-32bit": "<strong>Aviso:</strong> o seu sistema parece estar sendo executado com inteiros de 32 bits. Isto [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:32-bit não é recomendado].",
        "config-db-type": "Tipo do banco de dados:",
        "config-db-host": "Servidor do banco de dados:",
        "config-db-host-help": "Se a banco de dados do seu servidor está em um servidor diferente, digite o nome do host ou o endereço IP aqui.\n\nSe você está utilizando uma hospedagem web compartilhada, o seu provedor de hospedagem deverá fornecer o nome do host correto na sua documentação.\n\nSe você está instalando em um servidor Windows e usando o MySQL, usar \"localhost\" pode não funcionar para o nome de servidor. Se não funcionar, tente \"127.0.0.1\" para o endereço de IP local.\n\nSe você está usando PostgreSQl, deixe este campo em branco para se conectar através de um socket Unix.",
        "config-help-tooltip": "clique para expandir",
        "config-nofile": "O arquivo \"$1\" não foi encontrado. Ele foi apagado?",
        "config-extension-link": "Você sabia que sua wiki suporta [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Extensions extensões]?\n\nVocê pode explorar as [https://www.mediawiki.org/wiki/Special:MyLanguage/Category:Extensions_by_category extensões por categoria] ou visitar a [https://www.mediawiki.org/wiki/Extension_Matrix Matriz de Extensões] para ver a lista completa.",
+       "config-skins-screenshots": "$1 (screenshots: $2)",
+       "config-screenshot": "screenshot",
        "mainpagetext": "<strong>O MediaWiki foi instalado.</strong>",
        "mainpagedocfooter": "Consulte o [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Contents Manual de Usuário] para informações de como usar o software wiki.\n\n== Começando ==\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Configuration_settings Lista de opções de configuração]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ FAQ do MediaWiki]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce Lista de discussão com avisos de novas versões do MediaWiki]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Localisation#Translation_resources Traduza o MediaWiki para seu idioma]"
 }
index 7873035..54339c3 100644 (file)
@@ -88,6 +88,7 @@
        "config-no-cli-uploads-check": "'''Увага:''' Ваша типова папка для завантажень (<code>$1</code>) не перевірялась на вразливість до виконання довільних скриптів під час встановлення CLI.",
        "config-brokenlibxml": "У Вашій системі невдале поєднання версій PHP і libxml2, яке може спричинити пошкодження прихованих даних у MediaWiki та інших веб-застосунках.\nОновіть libxml2 до версії 2.7.3 або пізнішої  ([https://bugs.php.net/bug.php?id=45996 відомості про помилку]).\nВстановлення перервано.",
        "config-suhosin-max-value-length": "Suhosin встановлено і обмежує параметра GET  <code>length</code> до $1 байта. Компонент MediaWiki ResourceLoader буде обходити це обмеження, однак це зменшить продуктивність. Якщо це можливо, Вам варто встановити значення <code>suhosin.get.max_value_length</code> як 1024 і більше у <code>php.ini</code> і встановити таке ж значення <code>$wgResourceLoaderMaxQueryLength</code> у LocalSettings.php .",
+       "config-using-32bit": "<strong>Попередження:</strong> схоже, що Ваша система працює з 32-бітними цілими числами. Таке [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:32-bit не рекомендується].",
        "config-db-type": "Тип бази даних:",
        "config-db-host": "Хост бази даних:",
        "config-db-host-help": "Якщо сервер бази даних знаходиться на іншому сервері, введіть тут ім'я хосту і IP адресу.\n\nЯкщо Ви використовуєте віртуальний хостинг, Ваш хостинг-провайдер має надати Вам правильне ім'я хосту у його документації.\n\nЯкщо у Вас сервер із Windows Ви використовуєте MySQL, параметр \"localhost\" може не працювати для імені сервера. Якщо не працює, використайте \"127.0.0.1\" як локальну IP-адресу.\n\nЯкщо Ви використовуєте PostgreSQL, залиште це поле пустим, щоб під'єднатись через сокет Unix.",
        "config-help-tooltip": "натисніть, щоб розгорнути",
        "config-nofile": "Файл \"$1\" не знайдено. Його видалено?",
        "config-extension-link": "Чи знаєте ви, що ваше вікі підтримує [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Extensions розширення]?\n\nВи можете переглядати [https://www.mediawiki.org/wiki/Special:MyLanguage/Category:Extensions_by_category розширення по категорії] або в [https://www.mediawiki.org/wiki/Extension_Matrix матрицю розширень] щоб побачити повний список розширень.",
+       "config-skins-screenshots": "$1 (скріншоти: $2)",
+       "config-screenshot": "скріншот",
        "mainpagetext": "<strong>Програмне забезпечення «MediaWiki» встановлено.</strong>",
        "mainpagedocfooter": "Інформацію про роботу з цією вікі можна знайти на сторінці [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Contents Довідка:Вміст].\n\n== Деякі корисні ресурси ==\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Configuration_settings Список налаштувань];\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ Часті питання з приводу MediaWiki];\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce Розсилка повідомлень про появу нових версій MediaWiki];\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Localisation#Translation_resources Локалізувати MediaWiki своєю мовою]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Combating_spam Дізнатися, як боротися зі спамом у своїй вікі]"
 }
index 0a7f8cd..1c441cd 100644 (file)
@@ -82,6 +82,7 @@
        "config-no-cli-uploads-check": "<strong>Cảnh báo:</strong> Thư mục tải lên mặc định của bạn (<code>$1</code>) không được kiểm tra lỗ hỏng bảo mật dễ bị khai thác bởi các đoạn mã thực thi xấu trong quá trình cài đặt giao diện dòng lệnh.",
        "config-brokenlibxml": "Hệ thống của bạn có kết hợp các phiên bản lỗi lầm của PHP và libxml2, điều này có thể gây ra tổn thương không nhìn thấy được đối với dữ liệu trong MediaWiki và các ứng dụng Web khác.\nHãy nâng cấp lên phiên bản libxml2 2.7.3 trở lên ([https://bugs.php.net/bug.php?id=45996 lỗi nộp PHP]).\nCài đặt bị hủy bỏ.",
        "config-suhosin-max-value-length": "Suhosin được cài đặt và hạn chế tham số GET <code>length</code> (độ dài) không thể vượt quá $1 byte.\nThành phần ResourceLoader của MediaWiki sẽ khắc phục giới hạn này, nhưng điều này sẽ làm giảm hiệu suất.\nNếu có thể, bạn nên tăng <code>suhosin.get.max_value_length</code> lên 1024 trở lên trong <code>php.ini</code>, và đặt <code>$wgResourceLoaderMaxQueryLength</code> cùng giá trị trong <code>LocalSettings.php</code>.",
+       "config-using-32bit": "<strong>Cảnh báo:</strong> Máy của bạn hình như sử dụng các số nguyên 32 bit. Chế độ này [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:32-bit không được khuyên khích].",
        "config-db-type": "Kiểu cơ sở dữ liệu:",
        "config-db-host": "Máy chủ của cơ sở dữ liệu:",
        "config-db-host-help": "Nếu máy chủ cơ sở dữ liệu của bạn nằm trên máy chủ khác, hãy điền tên hoặc địa chỉ IP của máy chủ vào đây.\n\nNếu bạn đang dùng Web hosting chia sẻ, tài liệu của nhà cung cấp hosting của bạn sẽ có tên chính xác của máy chủ.\n\nNếu bạn đang cài đặt trên một máy chủ Windows và sử dụng MySQL, việc dùng “localhost” có thể không hợp với tên máy chủ. Nếu bị như vậy, hãy thử “127.0.0.1” tức địa chỉ IP địa phương.\n\nNếu bạn đang dùng PostgreSQL, hãy để trống mục này để kết nối với một ổ cắm Unix.",
        "config-help-tooltip": "nhấn chuột để mở rộng",
        "config-nofile": "Không tìm thấy tập tin “$1”. Nó có phải bị xóa không?",
        "config-extension-link": "Bạn có biết rằng wiki của bạn có hỗ trợ [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Extensions mở rộng]?\n\nBạn có thể truy cập [https://www.mediawiki.org/wiki/Special:MyLanguage/Category:Extensions_by_category phần mở rộng theo thể loại] hoặc [https://www.mediawiki.org/wiki/Extension_Matrix Ma trận Mở rộng] để xem danh sách đầy đủ các phần mở rộng.",
+       "config-skins-screenshots": "$1 (ảnh chụp màn hình: $2)",
+       "config-screenshot": "ảnh chụp màn hình",
        "mainpagetext": "'''MediaWiki đã được cài đặt.'''",
        "mainpagedocfooter": "Xin đọc [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Contents Hướng dẫn sử dụng] để biết thêm thông tin về cách sử dụng phần mềm wiki.\n\n== Để bắt đầu ==\n\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Configuration_settings Danh sách các thiết lập cấu hình]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ Các câu hỏi thường gặp MediaWiki]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce Danh sách gửi thư về việc phát hành MediaWiki]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Combating_spam Tìm hiểu cách chống spam tại wiki của bạn]"
 }
index b5f331b..b68fdae 100644 (file)
@@ -734,7 +734,6 @@ class JobQueueDB extends JobQueue {
                        'job_title' => $job->getTitle()->getDBkey(),
                        'job_params' => self::makeBlob( $job->getParams() ),
                        // Additional job metadata
-                       'job_id' => $dbw->nextSequenceValue( 'job_job_id_seq' ),
                        'job_timestamp' => $dbw->timestamp(),
                        'job_sha1' => Wikimedia\base_convert(
                                sha1( serialize( $job->getDeduplicationInfo() ) ),
index 9d0f87c..4c16d7f 100644 (file)
@@ -113,6 +113,10 @@ class HTMLCacheUpdateJob extends Job {
                // before the link jobs, so using the current timestamp instead of the root timestamp is
                // not expected to invalidate these cache entries too often.
                $touchTimestamp = wfTimestampNow();
+               // If page_touched is higher than this, then something else already bumped it after enqueue
+               $condTimestamp = isset( $this->params['rootJobTimestamp'] )
+                       ? $this->params['rootJobTimestamp']
+                       : $touchTimestamp;
 
                $dbw = wfGetDB( DB_MASTER );
                $factory = MediaWikiServices::getInstance()->getDBLoadBalancerFactory();
@@ -126,7 +130,7 @@ class HTMLCacheUpdateJob extends Job {
                                [ 'page_touched' => $dbw->timestamp( $touchTimestamp ) ],
                                [ 'page_id' => $batch,
                                        // don't invalidated pages that were already invalidated
-                                       "page_touched < " . $dbw->addQuotes( $dbw->timestamp( $touchTimestamp ) )
+                                       "page_touched < " . $dbw->addQuotes( $dbw->timestamp( $condTimestamp ) )
                                ],
                                __METHOD__
                        );
index bde8c69..3bfb531 100644 (file)
 
 use IPSet\IPSet;
 
-// Some regex definition to "play" with IP address and IP address blocks
+// Some regex definition to "play" with IP address and IP address ranges
 
 // An IPv4 address is made of 4 bytes from x00 to xFF which is d0 to d255
 define( 'RE_IP_BYTE', '(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|0?[0-9]?[0-9])' );
 define( 'RE_IP_ADD', RE_IP_BYTE . '\.' . RE_IP_BYTE . '\.' . RE_IP_BYTE . '\.' . RE_IP_BYTE );
-// An IPv4 block is an IP address and a prefix (d1 to d32)
+// An IPv4 range is an IP address and a prefix (d1 to d32)
 define( 'RE_IP_PREFIX', '(3[0-2]|[12]?\d)' );
-define( 'RE_IP_BLOCK', RE_IP_ADD . '\/' . RE_IP_PREFIX );
+define( 'RE_IP_RANGE', RE_IP_ADD . '\/' . RE_IP_PREFIX );
 
 // An IPv6 address is made up of 8 words (each x0000 to xFFFF).
 // However, the "::" abbreviation can be used on consecutive x0000 words.
@@ -47,8 +47,8 @@ define( 'RE_IPV6_ADD',
                RE_IPV6_WORD . '(?::' . RE_IPV6_WORD . '){7}' .
        ')'
 );
-// An IPv6 block is an IP address and a prefix (d1 to d128)
-define( 'RE_IPV6_BLOCK', RE_IPV6_ADD . '\/' . RE_IPV6_PREFIX );
+// An IPv6 range is an IP address and a prefix (d1 to d128)
+define( 'RE_IPV6_RANGE', RE_IPV6_ADD . '\/' . RE_IPV6_PREFIX );
 // For IPv6 canonicalization (NOT for strict validation; these are quite lax!)
 define( 'RE_IPV6_GAP', ':(?:0+:)*(?::(?:0+:)*)?' );
 define( 'RE_IPV6_V4_PREFIX', '0*' . RE_IPV6_GAP . '(?:ffff:)?' );
@@ -64,7 +64,7 @@ define( 'IP_ADDRESS_STRING',
 
 /**
  * A collection of public static functions to play with IP address
- * and IP blocks.
+ * and IP ranges.
  */
 class IP {
 
@@ -116,16 +116,30 @@ class IP {
        }
 
        /**
-        * Validate an IP Block (valid address WITH a valid prefix).
+        * Validate an IP range (valid address with a valid CIDR prefix).
         * SIIT IPv4-translated addresses are rejected.
         * @note canonicalize() tries to convert translated addresses to IPv4.
         *
-        * @param string $ipblock
+        * @deprecated since 1.30. Use the equivalent IP::isValidRange().
+        * @param string $ipRange
         * @return bool True if it is valid
         */
-       public static function isValidBlock( $ipblock ) {
-               return ( preg_match( '/^' . RE_IPV6_BLOCK . '$/', $ipblock )
-                       || preg_match( '/^' . RE_IP_BLOCK . '$/', $ipblock ) );
+       public static function isValidBlock( $ipRange ) {
+               return self::isValidRange( $ipRange );
+       }
+
+       /**
+        * Validate an IP range (valid address with a valid CIDR prefix).
+        * SIIT IPv4-translated addresses are rejected.
+        * @note canonicalize() tries to convert translated addresses to IPv4.
+        *
+        * @param string $ipRange
+        * @return bool True if it is valid
+        * @since 1.30
+        */
+       public static function isValidRange( $ipRange ) {
+               return ( preg_match( '/^' . RE_IPV6_RANGE . '$/', $ipRange )
+                       || preg_match( '/^' . RE_IP_RANGE . '$/', $ipRange ) );
        }
 
        /**
index eb72edc..de5a103 100644 (file)
@@ -1250,7 +1250,7 @@ class SwiftFileBackend extends FileBackendStore {
         * @return StatusValue[]
         */
        protected function doExecuteOpHandlesInternal( array $fileOpHandles ) {
-               /** @var $statuses StatusValue[] */
+               /** @var StatusValue[] $statuses */
                $statuses = [];
 
                $auth = $this->getAuthentication();
index f002d3e..8121654 100644 (file)
@@ -315,7 +315,7 @@ class ChronologyProtector implements LoggerAwareInterface {
         * @return array
         */
        private static function mergePositions( $curValue, array $shutdownPositions ) {
-               /** @var $curPositions DBMasterPos[] */
+               /** @var DBMasterPos[] $curPositions */
                if ( $curValue === false ) {
                        $curPositions = $shutdownPositions;
                } else {
index b925e2c..4c3cbdd 100644 (file)
@@ -34,7 +34,7 @@ use IP;
  * @see Database
  */
 class DatabaseMysqli extends DatabaseMysqlBase {
-       /** @var $mConn mysqli */
+       /** @var mysqli $mConn */
 
        /**
         * @param string $sql
index bdac06c..ac59bd6 100644 (file)
@@ -39,8 +39,6 @@ class DatabasePostgres extends Database {
        /** @var int The number of rows affected as an integer */
        protected $mAffectedRows = null;
 
-       /** @var int */
-       private $mInsertId = null;
        /** @var float|string */
        private $numericVersion = null;
        /** @var string Connect string to open a PostgreSQL connection */
@@ -352,14 +350,10 @@ class DatabasePostgres extends Database {
                return pg_field_name( $res, $n );
        }
 
-       /**
-        * Return the result of the last call to nextSequenceValue();
-        * This must be called after nextSequenceValue().
-        *
-        * @return int|null
-        */
        public function insertId() {
-               return $this->mInsertId;
+               $res = $this->query( "SELECT lastval()" );
+               $row = $this->fetchRow( $res );
+               return is_null( $row[0] ) ? null : (int)$row[0];
        }
 
        public function dataSeek( $res, $row ) {
@@ -521,6 +515,10 @@ __INDEXATTR__;
        public function selectSQLText(
                $table, $vars, $conds = '', $fname = __METHOD__, $options = [], $join_conds = []
        ) {
+               if ( is_string( $options ) ) {
+                       $options = [ $options ];
+               }
+
                // Change the FOR UPDATE option as necessary based on the join conditions. Then pass
                // to the parent function to get the actual SQL text.
                // In Postgres when using FOR UPDATE, only the main table and tables that are inner joined
@@ -532,12 +530,28 @@ __INDEXATTR__;
                        $forUpdateKey = array_search( 'FOR UPDATE', $options, true );
                        if ( $forUpdateKey !== false && $join_conds ) {
                                unset( $options[$forUpdateKey] );
+                               $options['FOR UPDATE'] = [];
+
+                               // All tables not in $join_conds are good
+                               foreach ( $table as $alias => $name ) {
+                                       if ( is_numeric( $alias ) ) {
+                                               $alias = $name;
+                                       }
+                                       if ( !isset( $join_conds[$alias] ) ) {
+                                               $options['FOR UPDATE'][] = $alias;
+                                       }
+                               }
 
                                foreach ( $join_conds as $table_cond => $join_cond ) {
                                        if ( 0 === preg_match( '/^(?:LEFT|RIGHT|FULL)(?: OUTER)? JOIN$/i', $join_cond[0] ) ) {
                                                $options['FOR UPDATE'][] = $table_cond;
                                        }
                                }
+
+                               // Quote alias names so $this->tableName() won't mangle them
+                               $options['FOR UPDATE'] = array_map( function ( $name ) use ( $table ) {
+                                       return isset( $table[$name] ) ? $this->addIdentifierQuotes( $name ) : $name;
+                               }, $options['FOR UPDATE'] );
                        }
 
                        if ( isset( $options['ORDER BY'] ) && $options['ORDER BY'] == 'NULL' ) {
@@ -756,12 +770,7 @@ __INDEXATTR__;
        }
 
        public function nextSequenceValue( $seqName ) {
-               $safeseq = str_replace( "'", "''", $seqName );
-               $res = $this->query( "SELECT nextval('$safeseq')" );
-               $row = $this->fetchRow( $res );
-               $this->mInsertId = is_null( $row[0] ) ? null : (int)$row[0];
-
-               return $this->mInsertId;
+               return new NextSequenceValue;
        }
 
        /**
@@ -1204,6 +1213,8 @@ SQL;
                                $s = pg_escape_bytea( $conn, $s->fetch() );
                        }
                        return "'$s'";
+               } elseif ( $s instanceof NextSequenceValue ) {
+                       return 'DEFAULT';
                }
 
                return "'" . pg_escape_string( $conn, $s ) . "'";
index 9375efc..0283c4b 100644 (file)
@@ -420,12 +420,9 @@ interface IDatabase {
        /**
         * Get the inserted value of an auto-increment row
         *
-        * The value inserted should be fetched from nextSequenceValue()
-        *
-        * Example:
-        * $id = $dbw->nextSequenceValue( 'page_page_id_seq' );
-        * $dbw->insert( 'page', [ 'page_id' => $id ] );
-        * $id = $dbw->insertId();
+        * This should only be called after an insert that used an auto-incremented
+        * value. If no such insert was previously done in the current database
+        * session, the return value is undefined.
         *
         * @return int
         */
@@ -1114,15 +1111,20 @@ interface IDatabase {
        public function anyString();
 
        /**
-        * Returns an appropriately quoted sequence value for inserting a new row.
-        * MySQL has autoincrement fields, so this is just NULL. But the PostgreSQL
-        * subclass will return an integer, and save the value for insertId()
+        * Deprecated method, calls should be removed.
+        *
+        * This was formerly used for PostgreSQL and Oracle to handle
+        * self::insertId() auto-incrementing fields. It is no longer necessary
+        * since DatabasePostgres::insertId() has been reimplemented using
+        * `lastval()` and Oracle has been reimplemented using triggers.
+        *
+        * Implementations should return null if inserting `NULL` into an
+        * auto-incrementing field works, otherwise it should return an instance of
+        * NextSequenceValue and filter it on calls to relevant methods.
         *
-        * Any implementation of this function should *not* involve reusing
-        * sequence numbers created for rolled-back transactions.
-        * See https://bugs.mysql.com/bug.php?id=30767 for details.
+        * @deprecated since 1.30, no longer needed
         * @param string $seqName
-        * @return null|int
+        * @return null|NextSequenceValue
         */
        public function nextSequenceValue( $seqName );
 
index 493cde8..12e59b5 100644 (file)
@@ -9,7 +9,7 @@ use stdClass;
  * doesn't go anywhere near an actual database.
  */
 class FakeResultWrapper extends ResultWrapper {
-       /** @var $result stdClass[] */
+       /** @var stdClass[] $result */
 
        /**
         * @param stdClass[] $rows
diff --git a/includes/libs/rdbms/database/utils/NextSequenceValue.php b/includes/libs/rdbms/database/utils/NextSequenceValue.php
new file mode 100644 (file)
index 0000000..44bf0dd
--- /dev/null
@@ -0,0 +1,12 @@
+<?php
+
+namespace Wikimedia\Rdbms;
+
+/**
+ * Used by Database::nextSequenceValue() so Database::insert() can detect
+ * values coming from the deprecated function.
+ * @since 1.30
+ * @deprecated since 1.30, only exists for backwards compatibility
+ */
+class NextSequenceValue {
+}
index 0091524..91d98dc 100644 (file)
@@ -28,7 +28,7 @@ class DBConnectionError extends DBExpectedError {
         * @param IDatabase $db Object throwing the error
         * @param string $error Error text
         */
-       function __construct( IDatabase $db = null, $error = 'unknown error' ) {
+       public function __construct( IDatabase $db = null, $error = 'unknown error' ) {
                $msg = 'Cannot access the database';
                if ( trim( $error ) != '' ) {
                        $msg .= ": $error";
index d65e2d3..2f7499b 100644 (file)
@@ -36,7 +36,7 @@ class DBError extends Exception {
         * @param IDatabase $db Object which threw the error
         * @param string $error A simple error message to be used for debugging
         */
-       function __construct( IDatabase $db = null, $error ) {
+       public function __construct( IDatabase $db = null, $error ) {
                $this->db = $db;
                parent::__construct( $error );
        }
index 4f65efa..31d8c27 100644 (file)
@@ -36,7 +36,7 @@ class DBExpectedError extends DBError implements MessageSpecifier, ILocalizedExc
        /** @var string[] Message parameters */
        protected $params;
 
-       function __construct( IDatabase $db = null, $error, array $params = [] ) {
+       public function __construct( IDatabase $db = null, $error, array $params = [] ) {
                parent::__construct( $db, $error );
                $this->params = $params;
        }
index 6a4076f..a8ea3ad 100644 (file)
@@ -41,7 +41,7 @@ class DBQueryError extends DBExpectedError {
         * @param string $sql
         * @param string $fname
         */
-       function __construct( IDatabase $db, $error, $errno, $sql, $fname ) {
+       public function __construct( IDatabase $db, $error, $errno, $sql, $fname ) {
                if ( $db instanceof Database && $db->wasConnectionError( $errno ) ) {
                        $message = "A connection error occured. \n" .
                                "Query: $sql\n" .
index e45b9f3..d2622e1 100644 (file)
@@ -25,7 +25,7 @@ namespace Wikimedia\Rdbms;
  * @ingroup Database
  */
 class DBTransactionSizeError extends DBTransactionError {
-       function getKey() {
+       public function getKey() {
                return 'transaction-duration-limit-exceeded';
        }
 }
index 4cfa542..f6d080e 100644 (file)
@@ -239,7 +239,7 @@ interface ILBFactory {
         *   - cluster : wait on the given external load balancer DBs
         *   - timeout : Max wait time. Default: ~60 seconds
         *   - ifWritesSince: Only wait if writes were done since this UNIX timestamp
-        * @throws DBReplicationWaitError If a timeout or error occured waiting on a DB cluster
+        * @throws DBReplicationWaitError If a timeout or error occurred waiting on a DB cluster
         */
        public function waitForReplication( array $opts = [] );
 
index 36de39e..8393e2b 100644 (file)
@@ -384,9 +384,9 @@ class LoadBalancer implements ILoadBalancer {
                        throw new InvalidArgumentException( "Empty server array given to LoadBalancer" );
                }
 
-               /** @var $i int|bool Index of selected server */
+               /** @var int|bool $i Index of selected server */
                $i = false;
-               /** @var $laggedReplicaMode bool Whether server is considered lagged */
+               /** @var bool $laggedReplicaMode Whether server is considered lagged */
                $laggedReplicaMode = false;
 
                // Quickly look through the available servers for a server that meets criteria...
@@ -538,7 +538,7 @@ class LoadBalancer implements ILoadBalancer {
        public function getAnyOpenConnection( $i ) {
                foreach ( $this->mConns as $connsByServer ) {
                        if ( !empty( $connsByServer[$i] ) ) {
-                               /** @var $serverConns IDatabase[] */
+                               /** @var IDatabase[] $serverConns */
                                $serverConns = $connsByServer[$i];
 
                                return reset( $serverConns );
index 1da9468..6494c26 100644 (file)
@@ -56,7 +56,7 @@ class SamplingStatsdClient extends StatsdClient {
                }
                if ( $samplingRates ) {
                        array_walk( $data, function ( $item ) use ( $samplingRates ) {
-                               /** @var $item StatsdData */
+                               /** @var StatsdData $item */
                                foreach ( $samplingRates as $pattern => $rate ) {
                                        if ( fnmatch( $pattern, $item->getKey(), FNM_NOESCAPE ) ) {
                                                $item->setSampleRate( $item->getSampleRate() * $rate );
index fa94fe5..6197d40 100644 (file)
@@ -170,19 +170,21 @@ class DatabaseLogEntry extends LogEntryBase {
         * @return array
         */
        public static function getSelectQueryData() {
-               $tables = [ 'logging', 'user' ];
+               $commentQuery = CommentStore::newKey( 'log_comment' )->getJoin();
+
+               $tables = [ 'logging', 'user' ] + $commentQuery['tables'];
                $fields = [
                        'log_id', 'log_type', 'log_action', 'log_timestamp',
                        'log_user', 'log_user_text',
                        'log_namespace', 'log_title', // unused log_page
-                       'log_comment', 'log_params', 'log_deleted',
+                       'log_params', 'log_deleted',
                        'user_id', 'user_name', 'user_editcount',
-               ];
+               ] + $commentQuery['fields'];
 
                $joins = [
                        // IPs don't have an entry in user table
                        'user' => [ 'LEFT JOIN', 'log_user=user_id' ],
-               ];
+               ] + $commentQuery['joins'];
 
                return [
                        'tables' => $tables,
@@ -322,7 +324,7 @@ class DatabaseLogEntry extends LogEntryBase {
        }
 
        public function getComment() {
-               return $this->row->log_comment;
+               return CommentStore::newKey( 'log_comment' )->getComment( $this->row )->text;
        }
 
        public function getDeleted() {
@@ -380,7 +382,9 @@ class RCDatabaseLogEntry extends DatabaseLogEntry {
        }
 
        public function getComment() {
-               return $this->row->rc_comment;
+               return CommentStore::newKey( 'rc_comment' )
+                       // Legacy because the row probably used RecentChange::selectFields()
+                       ->getCommentLegacy( wfGetDB( DB_REPLICA ), $this->row )->text;
        }
 
        public function getDeleted() {
@@ -592,7 +596,6 @@ class ManualLogEntry extends LogEntryBase {
                global $wgContLang;
 
                $dbw = $dbw ?: wfGetDB( DB_MASTER );
-               $id = $dbw->nextSequenceValue( 'logging_log_id_seq' );
 
                if ( $this->timestamp === null ) {
                        $this->timestamp = wfTimestampNow();
@@ -615,7 +618,6 @@ class ManualLogEntry extends LogEntryBase {
                }
 
                $data = [
-                       'log_id' => $id,
                        'log_type' => $this->getType(),
                        'log_action' => $this->getSubtype(),
                        'log_timestamp' => $dbw->timestamp( $this->getTimestamp() ),
@@ -624,12 +626,12 @@ class ManualLogEntry extends LogEntryBase {
                        'log_namespace' => $this->getTarget()->getNamespace(),
                        'log_title' => $this->getTarget()->getDBkey(),
                        'log_page' => $this->getTarget()->getArticleID(),
-                       'log_comment' => $comment,
                        'log_params' => LogEntryBase::makeParamBlob( $params ),
                ];
                if ( isset( $this->deleted ) ) {
                        $data['log_deleted'] = $this->deleted;
                }
+               $data += CommentStore::newKey( 'log_comment' )->insert( $dbw, $comment );
 
                $dbw->insert( 'logging', $data, __METHOD__ );
                $this->id = $dbw->insertId();
index a085e3e..3b200fa 100644 (file)
@@ -90,12 +90,10 @@ class LogPage {
                global $wgLogRestrictions;
 
                $dbw = wfGetDB( DB_MASTER );
-               $log_id = $dbw->nextSequenceValue( 'logging_log_id_seq' );
 
                // @todo FIXME private/protected/public property?
                $this->timestamp = $now = wfTimestampNow();
                $data = [
-                       'log_id' => $log_id,
                        'log_type' => $this->type,
                        'log_action' => $this->action,
                        'log_timestamp' => $dbw->timestamp( $now ),
@@ -104,9 +102,9 @@ class LogPage {
                        'log_namespace' => $this->target->getNamespace(),
                        'log_title' => $this->target->getDBkey(),
                        'log_page' => $this->target->getArticleID(),
-                       'log_comment' => $this->comment,
                        'log_params' => $this->params
                ];
+               $data += CommentStore::newKey( 'log_comment' )->insert( $dbw, $this->comment );
                $dbw->insert( 'logging', $data, __METHOD__ );
                $newId = $dbw->insertId();
 
index 32208cc..de438da 100644 (file)
@@ -221,7 +221,7 @@ abstract class TransformationalImageHandler extends ImageHandler {
                }
 
                # Try a hook. Called "Bitmap" for historical reasons.
-               /** @var $mto MediaTransformOutput */
+               /** @var MediaTransformOutput $mto */
                $mto = null;
                Hooks::run( 'BitmapHandlerTransform', [ $this, $image, &$scalerParams, &$mto ] );
                if ( !is_null( $mto ) ) {
index 11e1a30..f6580e9 100644 (file)
@@ -171,20 +171,21 @@ class PageArchive {
 
        /**
         * List the revisions of the given page. Returns result wrapper with
-        * (ar_minor_edit, ar_timestamp, ar_user, ar_user_text, ar_comment) fields.
+        * various archive table fields.
         *
         * @return ResultWrapper
         */
        public function listRevisions() {
                $dbr = wfGetDB( DB_REPLICA );
+               $commentQuery = CommentStore::newKey( 'ar_comment' )->getJoin();
 
-               $tables = [ 'archive' ];
+               $tables = [ 'archive' ] + $commentQuery['tables'];
 
                $fields = [
                        'ar_minor_edit', 'ar_timestamp', 'ar_user', 'ar_user_text',
-                       'ar_comment', 'ar_len', 'ar_deleted', 'ar_rev_id', 'ar_sha1',
+                       'ar_len', 'ar_deleted', 'ar_rev_id', 'ar_sha1',
                        'ar_page_id'
-               ];
+               ] + $commentQuery['fields'];
 
                if ( $this->config->get( 'ContentHandlerUseDB' ) ) {
                        $fields[] = 'ar_content_format';
@@ -196,7 +197,7 @@ class PageArchive {
 
                $options = [ 'ORDER BY' => 'ar_timestamp DESC' ];
 
-               $join_conds = [];
+               $join_conds = [] + $commentQuery['joins'];
 
                ChangeTags::modifyDisplayQuery(
                        $tables,
@@ -248,11 +249,13 @@ class PageArchive {
         */
        public function getRevision( $timestamp ) {
                $dbr = wfGetDB( DB_REPLICA );
+               $commentQuery = CommentStore::newKey( 'ar_comment' )->getJoin();
+
+               $tables = [ 'archive' ] + $commentQuery['tables'];
 
                $fields = [
                        'ar_rev_id',
                        'ar_text',
-                       'ar_comment',
                        'ar_user',
                        'ar_user_text',
                        'ar_timestamp',
@@ -262,19 +265,27 @@ class PageArchive {
                        'ar_deleted',
                        'ar_len',
                        'ar_sha1',
-               ];
+               ] + $commentQuery['fields'];
 
                if ( $this->config->get( 'ContentHandlerUseDB' ) ) {
                        $fields[] = 'ar_content_format';
                        $fields[] = 'ar_content_model';
                }
 
-               $row = $dbr->selectRow( 'archive',
+               $join_conds = [] + $commentQuery['joins'];
+
+               $row = $dbr->selectRow(
+                       $tables,
                        $fields,
-                       [ 'ar_namespace' => $this->title->getNamespace(),
+                       [
+                               'ar_namespace' => $this->title->getNamespace(),
                                'ar_title' => $this->title->getDBkey(),
-                               'ar_timestamp' => $dbr->timestamp( $timestamp ) ],
-                       __METHOD__ );
+                               'ar_timestamp' => $dbr->timestamp( $timestamp )
+                       ],
+                       __METHOD__,
+                       [],
+                       $join_conds
+               );
 
                if ( $row ) {
                        return Revision::newFromArchiveRow( $row, [ 'title' => $this->title ] );
@@ -552,12 +563,15 @@ class PageArchive {
                        $oldWhere['ar_timestamp'] = array_map( [ &$dbw, 'timestamp' ], $timestamps );
                }
 
+               $commentQuery = CommentStore::newKey( 'ar_comment' )->getJoin();
+
+               $tables = [ 'archive', 'revision' ] + $commentQuery['tables'];
+
                $fields = [
                        'ar_id',
                        'ar_rev_id',
                        'rev_id',
                        'ar_text',
-                       'ar_comment',
                        'ar_user',
                        'ar_user_text',
                        'ar_timestamp',
@@ -568,24 +582,28 @@ class PageArchive {
                        'ar_page_id',
                        'ar_len',
                        'ar_sha1'
-               ];
+               ] + $commentQuery['fields'];
 
                if ( $this->config->get( 'ContentHandlerUseDB' ) ) {
                        $fields[] = 'ar_content_format';
                        $fields[] = 'ar_content_model';
                }
 
+               $join_conds = [
+                       'revision' => [ 'LEFT JOIN', 'ar_rev_id=rev_id' ],
+               ] + $commentQuery['joins'];
+
                /**
                 * Select each archived revision...
                 */
                $result = $dbw->select(
-                       [ 'archive', 'revision' ],
+                       $tables,
                        $fields,
                        $oldWhere,
                        __METHOD__,
                        /* options */
                        [ 'ORDER BY' => 'ar_timestamp' ],
-                       [ 'revision' => [ 'LEFT JOIN', 'ar_rev_id=rev_id' ] ]
+                       $join_conds
                );
 
                $rev_count = $result->numRows();
index d5a2f3f..21c298e 100644 (file)
@@ -878,11 +878,10 @@ class WikiPage implements Page, IDBAccessObject {
                }
 
                // Update the DB post-send if the page has not cached since now
-               $that = $this;
                $latest = $this->getLatest();
                DeferredUpdates::addCallableUpdate(
-                       function () use ( $that, $retval, $latest ) {
-                               $that->insertRedirectEntry( $retval, $latest );
+                       function () use ( $retval, $latest ) {
+                               $this->insertRedirectEntry( $retval, $latest );
                        },
                        DeferredUpdates::POSTSEND,
                        wfGetDB( DB_MASTER )
@@ -1166,11 +1165,10 @@ class WikiPage implements Page, IDBAccessObject {
         *   page ID is already in use.
         */
        public function insertOn( $dbw, $pageId = null ) {
-               $pageIdForInsert = $pageId ?: $dbw->nextSequenceValue( 'page_page_id_seq' );
+               $pageIdForInsert = $pageId ? [ 'page_id' => $pageId ] : [];
                $dbw->insert(
                        'page',
                        [
-                               'page_id'           => $pageIdForInsert,
                                'page_namespace'    => $this->mTitle->getNamespace(),
                                'page_title'        => $this->mTitle->getDBkey(),
                                'page_restrictions' => '',
@@ -1180,7 +1178,7 @@ class WikiPage implements Page, IDBAccessObject {
                                'page_touched'      => $dbw->timestamp(),
                                'page_latest'       => 0, // Fill this in shortly...
                                'page_len'          => 0, // Fill this in shortly...
-                       ],
+                       ] + $pageIdForInsert,
                        __METHOD__,
                        'IGNORE'
                );
@@ -1659,7 +1657,7 @@ class WikiPage implements Page, IDBAccessObject {
                // Convenience variables
                $now = wfTimestampNow();
                $oldid = $meta['oldId'];
-               /** @var $oldContent Content|null */
+               /** @var Content|null $oldContent */
                $oldContent = $meta['oldContent'];
                $newsize = $content->getSize();
 
@@ -2302,7 +2300,7 @@ class WikiPage implements Page, IDBAccessObject {
                global $wgCascadingRestrictionLevels, $wgContLang;
 
                if ( wfReadOnly() ) {
-                       return Status::newFatal( 'readonlytext', wfReadOnlyReason() );
+                       return Status::newFatal( wfMessage( 'readonlytext', wfReadOnlyReason() ) );
                }
 
                $this->loadPageData( 'fromdbmaster' );
@@ -2446,7 +2444,6 @@ class WikiPage implements Page, IDBAccessObject {
                                        $dbw->insert(
                                                'page_restrictions',
                                                [
-                                                       'pr_id' => $dbw->nextSequenceValue( 'page_restrictions_pr_id_seq' ),
                                                        'pr_page' => $id,
                                                        'pr_type' => $action,
                                                        'pr_level' => $restrictions,
@@ -2484,6 +2481,7 @@ class WikiPage implements Page, IDBAccessObject {
                        $cascade = false;
 
                        if ( $limit['create'] != '' ) {
+                               $commentFields = CommentStore::newKey( 'pt_reason' )->insert( $dbw, $reason );
                                $dbw->replace( 'protected_titles',
                                        [ [ 'pt_namespace', 'pt_title' ] ],
                                        [
@@ -2493,8 +2491,7 @@ class WikiPage implements Page, IDBAccessObject {
                                                'pt_timestamp' => $dbw->timestamp(),
                                                'pt_expiry' => $dbw->encodeExpiry( $expiry['create'] ),
                                                'pt_user' => $user->getId(),
-                                               'pt_reason' => $reason,
-                                       ], __METHOD__
+                                       ] + $commentFields, __METHOD__
                                );
                                $logParamsDetails[] = [
                                        'type' => 'create',
@@ -2746,7 +2743,7 @@ class WikiPage implements Page, IDBAccessObject {
                $reason, $suppress = false, $u1 = null, $u2 = null, &$error = '', User $user = null,
                $tags = [], $logsubtype = 'delete'
        ) {
-               global $wgUser, $wgContentHandlerUseDB;
+               global $wgUser, $wgContentHandlerUseDB, $wgCommentTableSchemaMigrationStage;
 
                wfDebug( __METHOD__ . "\n" );
 
@@ -2810,6 +2807,9 @@ class WikiPage implements Page, IDBAccessObject {
                        $content = null;
                }
 
+               $revCommentStore = new CommentStore( 'rev_comment' );
+               $arCommentStore = new CommentStore( 'ar_comment' );
+
                $fields = Revision::selectFields();
                $bitfield = false;
 
@@ -2827,20 +2827,23 @@ class WikiPage implements Page, IDBAccessObject {
                // the rev_deleted field, which is reserved for this purpose.
 
                // Get all of the page revisions
+               $commentQuery = $revCommentStore->getJoin();
                $res = $dbw->select(
-                       'revision',
-                       $fields,
+                       [ 'revision' ] + $commentQuery['tables'],
+                       $fields + $commentQuery['fields'],
                        [ 'rev_page' => $id ],
                        __METHOD__,
-                       'FOR UPDATE'
+                       'FOR UPDATE',
+                       $commentQuery['joins']
                );
                // Build their equivalent archive rows
                $rowsInsert = [];
+               $revids = [];
                foreach ( $res as $row ) {
+                       $comment = $revCommentStore->getComment( $row );
                        $rowInsert = [
                                'ar_namespace'  => $namespace,
                                'ar_title'      => $dbKey,
-                               'ar_comment'    => $row->rev_comment,
                                'ar_user'       => $row->rev_user,
                                'ar_user_text'  => $row->rev_user_text,
                                'ar_timestamp'  => $row->rev_timestamp,
@@ -2854,12 +2857,13 @@ class WikiPage implements Page, IDBAccessObject {
                                'ar_page_id'    => $id,
                                'ar_deleted'    => $suppress ? $bitfield : $row->rev_deleted,
                                'ar_sha1'       => $row->rev_sha1,
-                       ];
+                       ] + $arCommentStore->insert( $dbw, $comment );
                        if ( $wgContentHandlerUseDB ) {
                                $rowInsert['ar_content_model'] = $row->rev_content_model;
                                $rowInsert['ar_content_format'] = $row->rev_content_format;
                        }
                        $rowsInsert[] = $rowInsert;
+                       $revids[] = $row->rev_id;
                }
                // Copy them into the archive table
                $dbw->insert( 'archive', $rowsInsert, __METHOD__ );
@@ -2874,6 +2878,9 @@ class WikiPage implements Page, IDBAccessObject {
                // Now that it's safely backed up, delete it
                $dbw->delete( 'page', [ 'page_id' => $id ], __METHOD__ );
                $dbw->delete( 'revision', [ 'rev_page' => $id ], __METHOD__ );
+               if ( $wgCommentTableSchemaMigrationStage > MIGRATION_OLD ) {
+                       $dbw->delete( 'revision_comment_temp', [ 'revcomment_rev' => $revids ], __METHOD__ );
+               }
 
                // Log the deletion, if the page was suppressed, put it in the suppression log instead
                $logtype = $suppress ? 'suppress' : 'delete';
index f0f1f5f..3d26262 100644 (file)
@@ -582,14 +582,14 @@ class CoreParserFunctions {
        }
        public static function talkspace( $parser, $title = null ) {
                $t = Title::newFromText( $title );
-               if ( is_null( $t ) || !$t->canTalk() ) {
+               if ( is_null( $t ) || !$t->canHaveTalkPage() ) {
                        return '';
                }
                return str_replace( '_', ' ', $t->getTalkNsText() );
        }
        public static function talkspacee( $parser, $title = null ) {
                $t = Title::newFromText( $title );
-               if ( is_null( $t ) || !$t->canTalk() ) {
+               if ( is_null( $t ) || !$t->canHaveTalkPage() ) {
                        return '';
                }
                return wfUrlencode( $t->getTalkNsText() );
@@ -632,14 +632,14 @@ class CoreParserFunctions {
        }
        public static function fullpagename( $parser, $title = null ) {
                $t = Title::newFromText( $title );
-               if ( is_null( $t ) || !$t->canTalk() ) {
+               if ( is_null( $t ) || !$t->canHaveTalkPage() ) {
                        return '';
                }
                return wfEscapeWikiText( $t->getPrefixedText() );
        }
        public static function fullpagenamee( $parser, $title = null ) {
                $t = Title::newFromText( $title );
-               if ( is_null( $t ) || !$t->canTalk() ) {
+               if ( is_null( $t ) || !$t->canHaveTalkPage() ) {
                        return '';
                }
                return wfEscapeWikiText( $t->getPrefixedURL() );
@@ -688,14 +688,14 @@ class CoreParserFunctions {
        }
        public static function talkpagename( $parser, $title = null ) {
                $t = Title::newFromText( $title );
-               if ( is_null( $t ) || !$t->canTalk() ) {
+               if ( is_null( $t ) || !$t->canHaveTalkPage() ) {
                        return '';
                }
                return wfEscapeWikiText( $t->getTalkPage()->getPrefixedText() );
        }
        public static function talkpagenamee( $parser, $title = null ) {
                $t = Title::newFromText( $title );
-               if ( is_null( $t ) || !$t->canTalk() ) {
+               if ( is_null( $t ) || !$t->canHaveTalkPage() ) {
                        return '';
                }
                return wfEscapeWikiText( $t->getTalkPage()->getPrefixedURL() );
index 3f0e38f..988e248 100644 (file)
@@ -2296,11 +2296,8 @@ class Parser {
                                                $this->mOutput->addLanguageLink( $nt->getFullText() );
                                        }
 
-                                       /**
-                                        * Strip the whitespace interwiki links produce, see T10897
-                                        */
                                        $s = rtrim( $s . $prefix );
-                                       $s .= rtrim( $trail, "\n" );
+                                       $s .= trim( $trail, "\n" ) == '' ? '' : $prefix . $trail;
                                        continue;
                                }
 
@@ -2325,11 +2322,7 @@ class Parser {
                                                continue;
                                        }
                                } elseif ( $ns == NS_CATEGORY ) {
-                                       /**
-                                        * Strip the whitespace Category links produce, see T2087
-                                        */
-                                       $s = rtrim( $s . $prefix ); # T2087, T87753
-                                       $s .= rtrim( $trail, "\n" );
+                                       $s = rtrim( $s . "\n" ); # T2087
 
                                        if ( $wasblank ) {
                                                $sortkey = $this->getDefaultSort();
@@ -2341,6 +2334,11 @@ class Parser {
                                        $sortkey = $this->getConverterLanguage()->convertCategoryKey( $sortkey );
                                        $this->mOutput->addCategory( $nt->getDBkey(), $sortkey );
 
+                                       /**
+                                        * Strip the whitespace Category links produce, see T2087
+                                        */
+                                       $s .= trim( $prefix . $trail, "\n" ) == '' ? '' : $prefix . $trail;
+
                                        continue;
                                }
                        }
@@ -2586,7 +2584,7 @@ class Parser {
                                ) ) );
                                break;
                        case 'talkpagename':
-                               if ( $this->mTitle->canTalk() ) {
+                               if ( $this->mTitle->canHaveTalkPage() ) {
                                        $talkPage = $this->mTitle->getTalkPage();
                                        $value = wfEscapeWikiText( $talkPage->getPrefixedText() );
                                } else {
@@ -2594,7 +2592,7 @@ class Parser {
                                }
                                break;
                        case 'talkpagenamee':
-                               if ( $this->mTitle->canTalk() ) {
+                               if ( $this->mTitle->canHaveTalkPage() ) {
                                        $talkPage = $this->mTitle->getTalkPage();
                                        $value = wfEscapeWikiText( $talkPage->getPrefixedURL() );
                                } else {
@@ -2694,12 +2692,12 @@ class Parser {
                                $value = $this->mTitle->getNamespace();
                                break;
                        case 'talkspace':
-                               $value = $this->mTitle->canTalk()
+                               $value = $this->mTitle->canHaveTalkPage()
                                        ? str_replace( '_', ' ', $this->mTitle->getTalkNsText() )
                                        : '';
                                break;
                        case 'talkspacee':
-                               $value = $this->mTitle->canTalk() ? wfUrlencode( $this->mTitle->getTalkNsText() ) : '';
+                               $value = $this->mTitle->canHaveTalkPage() ? wfUrlencode( $this->mTitle->getTalkNsText() ) : '';
                                break;
                        case 'subjectspace':
                                $value = str_replace( '_', ' ', $this->mTitle->getSubjectNsText() );
index 48a9f94..afe900d 100644 (file)
@@ -52,7 +52,7 @@ abstract class FormattedRCFeed extends RCFeed {
         */
        public function notify( RecentChange $rc, $actionComment = null ) {
                $params = $this->params;
-               /** @var $formatter RCFeedFormatter */
+               /** @var RCFeedFormatter $formatter */
                $formatter = is_object( $params['formatter'] ) ? $params['formatter'] : new $params['formatter'];
 
                $line = $formatter->getLine( $params, $rc, $actionComment );
index ddea695..10ba83f 100644 (file)
@@ -89,7 +89,9 @@ class IRCColourfulRCFeedFormatter implements RCFeedFormatter {
                        ) );
                        $flag = $attribs['rc_log_action'];
                } else {
-                       $comment = self::cleanupForIRC( $attribs['rc_comment'] );
+                       $comment = self::cleanupForIRC(
+                               CommentStore::newKey( 'rc_comment' )->getComment( $attribs )->text
+                       );
                        $flag = '';
                        if ( !$attribs['rc_patrolled']
                                && ( $wgUseRCPatrol || $attribs['rc_type'] == RC_NEW && $wgUseNPPatrol )
index 8973fe3..d535ffc 100644 (file)
@@ -296,6 +296,16 @@ class ResourceLoaderStartUpModule extends ResourceLoaderModule {
                return true;
        }
 
+       /**
+        * @return array
+        */
+       public function getPreloadLinks( ResourceLoaderContext $context ) {
+               $url = self::getStartupModulesUrl( $context );
+               return [
+                       $url => [ 'as' => 'script' ]
+               ];
+       }
+
        /**
         * Base modules required for the base environment of ResourceLoader
         *
@@ -359,6 +369,7 @@ class ResourceLoaderStartUpModule extends ResourceLoaderModule {
                }, [
                        '$VARS.wgLegacyJavaScriptGlobals' => $this->getConfig()->get( 'LegacyJavaScriptGlobals' ),
                        '$VARS.configuration' => $this->getConfigSettings( $context ),
+                       // This url may be preloaded. See getPreloadLinks().
                        '$VARS.baseModulesUri' => self::getStartupModulesUrl( $context ),
                ] );
                $pairs['$CODE.registrations()'] = str_replace(
index 32d4891..b098422 100644 (file)
@@ -23,8 +23,8 @@
  * Item class for a filearchive table row
  */
 class RevDelArchivedFileItem extends RevDelFileItem {
-       /** @var $list RevDelArchivedFileList */
-       /** @var $file ArchivedFile */
+       /** @var RevDelArchivedFileList $list */
+       /** @var ArchivedFile $file */
        /** @var LocalFile */
        protected $lockFile;
 
index a2c58e6..011c7b0 100644 (file)
@@ -83,7 +83,7 @@ abstract class RevDelList extends RevisionListBase {
        public function areAnySuppressed() {
                $bit = $this->getSuppressBit();
 
-               /** @var $item RevDelItem */
+               /** @var RevDelItem $item */
                foreach ( $this as $item ) {
                        if ( $item->getBits() & $bit ) {
                                return true;
@@ -151,7 +151,7 @@ abstract class RevDelList extends RevisionListBase {
                // passed to doPostCommitUpdates().
                $visibilityChangeMap = [];
 
-               /** @var $item RevDelItem */
+               /** @var RevDelItem $item */
                foreach ( $this as $item ) {
                        unset( $missing[$item->getId()] );
 
@@ -294,7 +294,7 @@ abstract class RevDelList extends RevisionListBase {
 
        final protected function acquireItemLocks() {
                $status = Status::newGood();
-               /** @var $item RevDelItem */
+               /** @var RevDelItem $item */
                foreach ( $this as $item ) {
                        $status->merge( $item->lock() );
                }
@@ -304,7 +304,7 @@ abstract class RevDelList extends RevisionListBase {
 
        final protected function releaseItemLocks() {
                $status = Status::newGood();
-               /** @var $item RevDelItem */
+               /** @var RevDelItem $item */
                foreach ( $this as $item ) {
                        $status->merge( $item->unlock() );
                }
index 047d6cf..998c695 100644 (file)
@@ -102,8 +102,9 @@ class RevDelLogItem extends RevDelItem {
                // User links and action text
                $action = $formatter->getActionText();
                // Comment
+               $comment = CommentStore::newKey( 'log_comment' )->getComment( $this->row )->text;
                $comment = $this->list->getLanguage()->getDirMark()
-                       . Linker::commentBlock( $this->row->log_comment );
+                       . Linker::commentBlock( $comment );
 
                if ( LogEventsList::isDeleted( $this->row, LogPage::DELETED_COMMENT ) ) {
                        $comment = '<span class="history-deleted">' . $comment . '</span>';
@@ -135,7 +136,7 @@ class RevDelLogItem extends RevDelItem {
                }
                if ( LogEventsList::userCan( $this->row, LogPage::DELETED_COMMENT, $user ) ) {
                        $ret += [
-                               'comment' => $this->row->log_comment,
+                               'comment' => CommentStore::newKey( 'log_comment' )->getComment( $this->row )->text,
                        ];
                }
 
index 1932778..ceb97e4 100644 (file)
@@ -63,7 +63,11 @@ class RevDelLogList extends RevDelList {
        public function doQuery( $db ) {
                $ids = array_map( 'intval', $this->ids );
 
-               return $db->select( 'logging', [
+               $commentQuery = CommentStore::getKey( 'log_comment' )->getJoin();
+
+               return $db->select(
+                       [ 'logging' ] + $commentQuery['tables'],
+                       [
                                'log_id',
                                'log_type',
                                'log_action',
@@ -73,13 +77,13 @@ class RevDelLogList extends RevDelList {
                                'log_namespace',
                                'log_title',
                                'log_page',
-                               'log_comment',
                                'log_params',
                                'log_deleted'
-                       ],
+                       ] + $commentQuery['fields'],
                        [ 'log_id' => $ids ],
                        __METHOD__,
-                       [ 'ORDER BY' => 'log_id DESC' ]
+                       [ 'ORDER BY' => 'log_id DESC' ],
+                       $commentQuery['joins']
                );
        }
 
index e106f37..7fcfbe5 100644 (file)
@@ -214,8 +214,6 @@ class DBSiteStore implements SiteStore {
                                        'sites', $fields, [ 'site_id' => $rowId ], __METHOD__
                                ) && $success;
                        } else {
-                               $rowId = $dbw->nextSequenceValue( 'sites_site_id_seq' );
-                               $fields['site_id'] = $rowId;
                                $success = $dbw->insert( 'sites', $fields, __METHOD__ ) && $success;
                                $rowId = $dbw->insertId();
                        }
index e1d0034..df7a9ed 100644 (file)
@@ -1251,11 +1251,10 @@ abstract class Skin extends ContextSource {
        function buildSidebar() {
                global $wgEnableSidebarCache, $wgSidebarCacheExpiry;
 
-               $that = $this;
-               $callback = function () use ( $that ) {
+               $callback = function () {
                        $bar = [];
-                       $that->addToSidebar( $bar, 'sidebar' );
-                       Hooks::run( 'SkinBuildSidebar', [ $that, &$bar ] );
+                       $this->addToSidebar( $bar, 'sidebar' );
+                       Hooks::run( 'SkinBuildSidebar', [ $this, &$bar ] );
 
                        return $bar;
                };
index 500c2e9..0cdc55f 100644 (file)
@@ -688,7 +688,7 @@ abstract class AuthManagerSpecialPage extends SpecialPage {
 
                        if ( isset( $singleFieldInfo['options'] ) ) {
                                $descriptor['options'] = array_flip( array_map( function ( $message ) {
-                                       /** @var $message Message */
+                                       /** @var Message $message */
                                        return $message->parse();
                                }, $singleFieldInfo['options'] ) );
                        }
index 52db51a..acd5d14 100644 (file)
@@ -598,7 +598,9 @@ abstract class ChangesListSpecialPage extends SpecialPage {
                                [
                                        'maxDays' => (int)$this->getConfig()->get( 'RCMaxAge' ) / ( 24 * 3600 ), // Translate to days
                                        'limitArray' => $this->getConfig()->get( 'RCLinkLimits' ),
+                                       'limitDefault' => $this->getDefaultLimit(),
                                        'daysArray' => $this->getConfig()->get( 'RCLinkDays' ),
+                                       'daysDefault' => $this->getDefaultDays(),
                                ]
                        );
                }
@@ -902,6 +904,7 @@ abstract class ChangesListSpecialPage extends SpecialPage {
                $opts->add( 'invert', false );
                $opts->add( 'associated', false );
                $opts->add( 'urlversion', 1 );
+               $opts->add( 'tagfilter', '' );
 
                return $opts;
        }
@@ -1153,6 +1156,7 @@ abstract class ChangesListSpecialPage extends SpecialPage {
                &$join_conds, FormOptions $opts
        ) {
                $dbr = $this->getDB();
+               $isStructuredUI = $this->isStructuredFilterUiEnabled();
 
                foreach ( $this->filterGroups as $filterGroup ) {
                        // URL parameters can be per-group, like 'userExpLevel',
@@ -1162,7 +1166,7 @@ abstract class ChangesListSpecialPage extends SpecialPage {
                                        $query_options, $join_conds, $opts[$filterGroup->getName()] );
                        } else {
                                foreach ( $filterGroup->getFilters() as $filter ) {
-                                       if ( $opts[$filter->getName()] ) {
+                                       if ( $filter->isActive( $opts, $isStructuredUI ) ) {
                                                $filter->modifyQuery( $dbr, $this, $tables, $fields, $conds,
                                                        $query_options, $join_conds );
                                        }
@@ -1535,4 +1539,8 @@ abstract class ChangesListSpecialPage extends SpecialPage {
        protected function isStructuredFilterUiEnabled() {
                return $this->getUser()->getOption( 'rcenhancedfilters' );
        }
+
+       abstract function getDefaultLimit();
+
+       abstract function getDefaultDays();
 }
index 0a653e7..693b8aa 100644 (file)
@@ -155,7 +155,6 @@ class SpecialNewFiles extends IncludableSpecialPage {
 
                        'mediatype' => [
                                'type' => 'multiselect',
-                               'dropdown' => true,
                                'flatlist' => true,
                                'name' => 'mediatype',
                                'label-message' => 'newimages-mediatype',
index ede4898..61590d7 100644 (file)
@@ -299,7 +299,7 @@ class SpecialNewpages extends IncludableSpecialPage {
         */
        protected function revisionFromRcResult( stdClass $result ) {
                return new Revision( [
-                       'comment' => $result->rc_comment,
+                       'comment' => CommentStore::newKey( 'rc_comment' )->getComment( $result )->text,
                        'deleted' => $result->rc_deleted,
                        'user_text' => $result->rc_user_text,
                        'user' => $result->rc_user,
index 4659b9d..547a1b0 100644 (file)
@@ -241,7 +241,6 @@ class SpecialRecentChanges extends ChangesListSpecialPage {
 
                $opts->add( 'categories', '' );
                $opts->add( 'categories_any', false );
-               $opts->add( 'tagfilter', '' );
 
                return $opts;
        }
@@ -636,7 +635,21 @@ class SpecialRecentChanges extends ChangesListSpecialPage {
 
                $message = $this->msg( 'recentchangestext' )->inContentLanguage();
                if ( !$message->isDisabled() ) {
-                       $content = $message->parse();
+                       // Parse the message in this weird ugly way to preserve the ability to include interlanguage
+                       // links in it (T172461). In the future when T66969 is resolved, perhaps we can just use
+                       // $message->parse() instead. This code is copied from Message::parseText().
+                       $parserOutput = MessageCache::singleton()->parse(
+                               $message->plain(),
+                               $this->getPageTitle(),
+                               /*linestart*/true,
+                               // Message class sets the interface flag to false when parsing in a language different than
+                               // user language, and this is wiki content language
+                               /*interface*/false,
+                               $wgContLang
+                       );
+                       $content = $parserOutput->getText();
+                       // Add only metadata here (including the language links), text is added below
+                       $this->getOutput()->addParserOutputMetadata( $parserOutput );
 
                        $langAttributes = [
                                'lang' => $wgContLang->getHtmlCode(),
@@ -991,4 +1004,12 @@ class SpecialRecentChanges extends ChangesListSpecialPage {
        protected function getCacheTTL() {
                return 60 * 5;
        }
+
+       function getDefaultLimit() {
+               return $this->getUser()->getIntOption( 'rclimit' );
+       }
+
+       function getDefaultDays() {
+               return $this->getUser()->getIntOption( 'rcdays' );
+       }
 }
index 4cdc78f..d0eb8e3 100644 (file)
@@ -1256,7 +1256,6 @@ class UploadForm extends HTMLForm {
                $out->addJsConfigVars( $scriptVars );
 
                $out->addModules( [
-                       'mediawiki.action.edit', // For <charinsert> support
                        'mediawiki.special.upload', // Extras for thumbnail and license preview.
                ] );
        }
index cecc182..ba3cb87 100644 (file)
@@ -97,11 +97,17 @@ class SpecialWatchlist extends ChangesListSpecialPage {
                parent::execute( $subpage );
 
                if ( $this->isStructuredFilterUiEnabled() ) {
+                       $output->addModuleStyles( [ 'mediawiki.rcfilters.highlightCircles.seenunseen.styles' ] );
+
                        $output->addJsConfigVars( 'wgStructuredChangeFiltersLiveUpdateSupported', false );
                        $output->addJsConfigVars(
                                'wgStructuredChangeFiltersSavedQueriesPreferenceName',
                                'rcfilters-wl-saved-queries'
                        );
+                       $output->addJsConfigVars(
+                               'wgStructuredChangeFiltersEditWatchlistUrl',
+                               SpecialPage::getTitleFor( 'EditWatchlist' )->getLocalURL()
+                       );
                }
        }
 
@@ -142,6 +148,40 @@ class SpecialWatchlist extends ChangesListSpecialPage {
        protected function registerFilters() {
                parent::registerFilters();
 
+               // legacy 'extended' filter
+               $this->registerFilterGroup( new ChangesListBooleanFilterGroup( [
+                       'name' => 'extended-group',
+                       'filters' => [
+                               [
+                                       'name' => 'extended',
+                                       'isReplacedInStructuredUi' => true,
+                                       'activeValue' => false,
+                                       'default' => $this->getUser()->getBoolOption( 'extendwatchlist' ),
+                                       'queryCallable' => function ( $specialClassName, $ctx, $dbr, &$tables,
+                                                                                                 &$fields, &$conds, &$query_options, &$join_conds ) {
+                                               $nonRevisionTypes = [ RC_LOG ];
+                                               Hooks::run( 'SpecialWatchlistGetNonRevisionTypes', [ &$nonRevisionTypes ] );
+                                               if ( $nonRevisionTypes ) {
+                                                       $conds[] = $dbr->makeList(
+                                                               [
+                                                                       'rc_this_oldid=page_latest',
+                                                                       'rc_type' => $nonRevisionTypes,
+                                                               ],
+                                                               LIST_OR
+                                                       );
+                                               }
+                                       },
+                               ]
+                       ],
+
+               ] ) );
+
+               if ( $this->isStructuredFilterUiEnabled() ) {
+                       $this->getFilterGroup( 'lastRevision' )
+                               ->getFilter( 'hidepreviousrevisions' )
+                               ->setDefault( !$this->getUser()->getBoolOption( 'extendwatchlist' ) );
+               }
+
                $this->registerFilterGroup( new ChangesListStringOptionsFilterGroup( [
                        'name' => 'watchlistactivity',
                        'title' => 'rcfilters-filtergroup-watchlistactivity',
@@ -234,7 +274,6 @@ class SpecialWatchlist extends ChangesListSpecialPage {
                $user = $this->getUser();
 
                $opts->add( 'days', $user->getOption( 'watchlistdays' ), FormOptions::FLOAT );
-               $opts->add( 'extended', $user->getBoolOption( 'extendwatchlist' ) );
                $opts->add( 'limit', $user->getIntOption( 'wllimit' ), FormOptions::INT );
 
                return $opts;
@@ -298,8 +337,11 @@ class SpecialWatchlist extends ChangesListSpecialPage {
                        // unchecked boxes.
                        foreach ( $this->filterGroups as $filterGroup ) {
                                if ( $filterGroup instanceof ChangesListBooleanFilterGroup ) {
+                                       /** @var ChangesListBooleanFilter $filter */
                                        foreach ( $filterGroup->getFilters() as $filter ) {
-                                               $allBooleansFalse[$filter->getName()] = false;
+                                               if ( $filter->displaysOnUnstructuredUi() ) {
+                                                       $allBooleansFalse[$filter->getName()] = false;
+                                               }
                                        }
                                }
                        }
@@ -341,29 +383,9 @@ class SpecialWatchlist extends ChangesListSpecialPage {
                $dbr = $this->getDB();
                $user = $this->getUser();
 
-               # Toggle watchlist content (all recent edits or just the latest)
-               if ( !$opts['extended'] ) {
-                       # Top log Ids for a page are not stored
-                       $nonRevisionTypes = [ RC_LOG ];
-                       Hooks::run( 'SpecialWatchlistGetNonRevisionTypes', [ &$nonRevisionTypes ] );
-                       if ( $nonRevisionTypes ) {
-                               $conds[] = $dbr->makeList(
-                                       [
-                                               'rc_this_oldid=page_latest',
-                                               'rc_type' => $nonRevisionTypes,
-                                       ],
-                                       LIST_OR
-                               );
-                       }
-               }
-
                $tables = array_merge( [ 'recentchanges', 'watchlist' ], $tables );
                $fields = array_merge( RecentChange::selectFields(), $fields );
 
-               $query_options = array_merge( [
-                       'ORDER BY' => 'rc_timestamp DESC',
-                       'LIMIT' => $opts['limit']
-               ], $query_options );
                $join_conds = array_merge(
                        [
                                'watchlist' => [
@@ -400,13 +422,14 @@ class SpecialWatchlist extends ChangesListSpecialPage {
                        ], LIST_OR );
                }
 
+               $tagFilter = $opts['tagfilter'] ? explode( '|', $opts['tagfilter'] ) : [];
                ChangeTags::modifyDisplayQuery(
                        $tables,
                        $fields,
                        $conds,
                        $join_conds,
                        $query_options,
-                       ''
+                       $tagFilter
                );
 
                $this->runMainQueryHook( $tables, $fields, $conds, $query_options, $join_conds, $opts );
@@ -415,6 +438,23 @@ class SpecialWatchlist extends ChangesListSpecialPage {
                        return false;
                }
 
+               $orderByAndLimit = [
+                       'ORDER BY' => 'rc_timestamp DESC',
+                       'LIMIT' => $opts['limit']
+               ];
+               if ( in_array( 'DISTINCT', $query_options ) ) {
+                       // ChangeTags::modifyDisplayQuery() adds DISTINCT when filtering on multiple tags.
+                       // In order to prevent DISTINCT from causing query performance problems,
+                       // we have to GROUP BY the primary key. This in turn requires us to add
+                       // the primary key to the end of the ORDER BY, and the old ORDER BY to the
+                       // start of the GROUP BY
+                       $orderByAndLimit['ORDER BY'] = 'rc_timestamp DESC, rc_id DESC';
+                       $orderByAndLimit['GROUP BY'] = 'rc_timestamp, rc_id';
+               }
+               // array_merge() is used intentionally here so that hooks can, should
+               // they so desire, override the ORDER BY / LIMIT condition(s)
+               $query_options = array_merge( $orderByAndLimit, $query_options );
+
                return $dbr->select(
                        $tables,
                        $fields,
@@ -793,21 +833,29 @@ class SpecialWatchlist extends ChangesListSpecialPage {
                $showUpdatedMarker = $this->getConfig()->get( 'ShowUpdatedMarker' );
 
                // Show watchlist header
-               $form .= "<p>";
+               $watchlistHeader = '';
                if ( $numItems == 0 ) {
-                       $form .= $this->msg( 'nowatchlist' )->parse() . "\n";
+                       $watchlistHeader = $this->msg( 'nowatchlist' )->parse();
                } else {
-                       $form .= $this->msg( 'watchlist-details' )->numParams( $numItems )->parse() . "\n";
+                       $watchlistHeader .= $this->msg( 'watchlist-details' )->numParams( $numItems )->parse() . "\n";
                        if ( $this->getConfig()->get( 'EnotifWatchlist' )
                                && $user->getOption( 'enotifwatchlistpages' )
                        ) {
-                               $form .= $this->msg( 'wlheader-enotif' )->parse() . "\n";
+                               $watchlistHeader .= $this->msg( 'wlheader-enotif' )->parse() . "\n";
                        }
                        if ( $showUpdatedMarker ) {
-                               $form .= $this->msg( 'wlheader-showupdated' )->parse() . "\n";
+                               $watchlistHeader .= $this->msg(
+                                       $this->isStructuredFilterUiEnabled() ?
+                                               'rcfilters-watchlist-showupdated' :
+                                               'wlheader-showupdated'
+                               )->parse() . "\n";
                        }
                }
-               $form .= "</p>";
+               $form .= Html::rawElement(
+                       'div',
+                       [ 'class' => 'watchlistDetails' ],
+                       $watchlistHeader
+               );
 
                if ( $numItems > 0 && $showUpdatedMarker ) {
                        $form .= Xml::openElement( 'form', [ 'method' => 'post',
@@ -858,4 +906,12 @@ class SpecialWatchlist extends ChangesListSpecialPage {
                $count = $store->countWatchedItems( $this->getUser() );
                return floor( $count / 2 );
        }
+
+       function getDefaultLimit() {
+               return $this->getUser()->getIntOption( 'wllimit' );
+       }
+
+       function getDefaultDays() {
+               return $this->getUser()->getIntOption( 'watchlistdays' );
+       }
 }
index 51e446d..924fd06 100644 (file)
@@ -79,7 +79,7 @@ class BlockListPager extends TablePager {
                        }
                }
 
-               /** @var $row object */
+               /** @var object $row */
                $row = $this->mCurrentRow;
 
                $language = $this->getLanguage();
@@ -173,6 +173,7 @@ class BlockListPager extends TablePager {
                                break;
 
                        case 'ipb_reason':
+                               $value = CommentStore::newKey( 'ipb_reason' )->getComment( $row )->text;
                                $formatted = Linker::formatComment( $value );
                                break;
 
@@ -208,8 +209,10 @@ class BlockListPager extends TablePager {
        }
 
        function getQueryInfo() {
+               $commentQuery = CommentStore::newKey( 'ipb_reason' )->getJoin();
+
                $info = [
-                       'tables' => [ 'ipblocks', 'user' ],
+                       'tables' => [ 'ipblocks', 'user' ] + $commentQuery['tables'],
                        'fields' => [
                                'ipb_id',
                                'ipb_address',
@@ -217,7 +220,6 @@ class BlockListPager extends TablePager {
                                'ipb_by',
                                'ipb_by_text',
                                'by_user_name' => 'user_name',
-                               'ipb_reason',
                                'ipb_timestamp',
                                'ipb_auto',
                                'ipb_anon_only',
@@ -229,9 +231,9 @@ class BlockListPager extends TablePager {
                                'ipb_deleted',
                                'ipb_block_email',
                                'ipb_allow_usertalk',
-                       ],
+                       ] + $commentQuery['fields'],
                        'conds' => $this->conds,
-                       'join_conds' => [ 'user' => [ 'LEFT JOIN', 'user_id = ipb_by' ] ]
+                       'join_conds' => [ 'user' => [ 'LEFT JOIN', 'user_id = ipb_by' ] ] + $commentQuery['joins']
                ];
 
                # Filter out any expired blocks
index 43d7ad4..38a332e 100644 (file)
@@ -69,14 +69,17 @@ class DeletedContribsPager extends IndexPager {
                                ' != ' . Revision::SUPPRESSED_USER;
                }
 
+               $commentQuery = CommentStore::newKey( 'ar_comment' )->getJoin();
+
                return [
-                       'tables' => [ 'archive' ],
+                       'tables' => [ 'archive' ] + $commentQuery['tables'],
                        'fields' => [
-                               'ar_rev_id', 'ar_namespace', 'ar_title', 'ar_timestamp', 'ar_comment',
+                               'ar_rev_id', 'ar_namespace', 'ar_title', 'ar_timestamp',
                                'ar_minor_edit', 'ar_user', 'ar_user_text', 'ar_deleted'
-                       ],
+                       ] + $commentQuery['fields'],
                        'conds' => $conds,
-                       'options' => [ 'USE INDEX' => $index ]
+                       'options' => [ 'USE INDEX' => [ 'archive' => $index ] ],
+                       'join_conds' => $commentQuery['joins'],
                ];
        }
 
@@ -253,7 +256,7 @@ class DeletedContribsPager extends IndexPager {
                $rev = new Revision( [
                        'title' => $page,
                        'id' => $row->ar_rev_id,
-                       'comment' => $row->ar_comment,
+                       'comment' => CommentStore::newKey( 'ar_comment' )->getComment( $row )->text,
                        'user' => $row->ar_user,
                        'user_text' => $row->ar_user_text,
                        'timestamp' => $row->ar_timestamp,
index 47b059b..813d1d4 100644 (file)
@@ -244,7 +244,9 @@ class ImageListPager extends TablePager {
                $prefix = $table === 'oldimage' ? 'oi' : 'img';
 
                $tables = [ $table ];
-               $fields = array_keys( $this->getFieldNames() );
+               $fields = $this->getFieldNames();
+               unset( $fields['img_description'] );
+               $fields = array_keys( $fields );
 
                if ( $table === 'oldimage' ) {
                        foreach ( $fields as $id => &$field ) {
@@ -264,6 +266,13 @@ class ImageListPager extends TablePager {
 
                $options = $join_conds = [];
 
+               # Description field
+               $commentQuery = CommentStore::newKey( $prefix . '_description' )->getJoin();
+               $tables += $commentQuery['tables'];
+               $fields += $commentQuery['fields'];
+               $join_conds += $commentQuery['joins'];
+               $fields['description_field'] = "'{$prefix}_description'";
+
                # Depends on $wgMiserMode
                # Will also not happen if mShowAll is true.
                if ( isset( $this->mFieldNames['count'] ) ) {
@@ -497,6 +506,8 @@ class ImageListPager extends TablePager {
                        case 'img_size':
                                return htmlspecialchars( $this->getLanguage()->formatSize( $value ) );
                        case 'img_description':
+                               $field = $this->mCurrentRow->description_field;
+                               $value = CommentStore::newKey( $field )->getComment( $this->mCurrentRow )->text;
                                return Linker::formatComment( $value );
                        case 'count':
                                return $this->getLanguage()->formatNum( intval( $value ) + 1 );
index dafd244..53362d9 100644 (file)
@@ -90,15 +90,17 @@ class NewPagesPager extends ReverseChronologicalPager {
                        $conds['page_is_redirect'] = 0;
                }
 
+               $commentQuery = CommentStore::newKey( 'rc_comment' )->getJoin();
+
                // Allow changes to the New Pages query
-               $tables = [ 'recentchanges', 'page' ];
+               $tables = [ 'recentchanges', 'page' ] + $commentQuery['tables'];
                $fields = [
                        'rc_namespace', 'rc_title', 'rc_cur_id', 'rc_user', 'rc_user_text',
-                       'rc_comment', 'rc_timestamp', 'rc_patrolled', 'rc_id', 'rc_deleted',
+                       'rc_timestamp', 'rc_patrolled', 'rc_id', 'rc_deleted',
                        'length' => 'page_len', 'rev_id' => 'page_latest', 'rc_this_oldid',
                        'page_namespace', 'page_title'
-               ];
-               $join_conds = [ 'page' => [ 'INNER JOIN', 'page_id=rc_cur_id' ] ];
+               ] + $commentQuery['fields'];
+               $join_conds = [ 'page' => [ 'INNER JOIN', 'page_id=rc_cur_id' ] ] + $commentQuery['joins'];
 
                // Avoid PHP 7.1 warning from passing $this by reference
                $pager = $this;
index 823b5da..1587abc 100644 (file)
@@ -120,7 +120,7 @@ class ProtectedPagesPager extends TablePager {
         * @throws MWException
         */
        function formatValue( $field, $value ) {
-               /** @var $row object */
+               /** @var object $row */
                $row = $this->mCurrentRow;
 
                switch ( $field ) {
@@ -236,6 +236,7 @@ class ProtectedPagesPager extends TablePager {
                                                LogPage::DELETED_COMMENT,
                                                $this->getUser()
                                        ) ) {
+                                               $value = CommentStore::newKey( 'log_comment' )->getComment( $row )->text;
                                                $formatted = Linker::formatComment( $value !== null ? $value : '' );
                                        } else {
                                                $formatted = $this->msg( 'rev-deleted-comment' )->escaped();
@@ -284,8 +285,10 @@ class ProtectedPagesPager extends TablePager {
                        $conds[] = 'page_namespace=' . $this->mDb->addQuotes( $this->namespace );
                }
 
+               $commentQuery = CommentStore::newKey( 'log_comment' )->getJoin();
+
                return [
-                       'tables' => [ 'page', 'page_restrictions', 'log_search', 'logging' ],
+                       'tables' => [ 'page', 'page_restrictions', 'log_search', 'logging' ] + $commentQuery['tables'],
                        'fields' => [
                                'pr_id',
                                'page_namespace',
@@ -297,9 +300,8 @@ class ProtectedPagesPager extends TablePager {
                                'pr_cascade',
                                'log_timestamp',
                                'log_user',
-                               'log_comment',
                                'log_deleted',
-                       ],
+                       ] + $commentQuery['fields'],
                        'conds' => $conds,
                        'join_conds' => [
                                'log_search' => [
@@ -312,7 +314,7 @@ class ProtectedPagesPager extends TablePager {
                                                'ls_log_id = log_id'
                                        ]
                                ]
-                       ]
+                       ] + $commentQuery['joins']
                ];
        }
 
index 7d697a1..f5367bb 100644 (file)
@@ -287,7 +287,7 @@ class UploadFromUrl extends UploadBase {
 
                wfDebugLog( 'fileupload', $status );
                if ( $status->isOK() ) {
-                       wfDebugLog( 'fileupload', 'Download by URL completed successfuly.' );
+                       wfDebugLog( 'fileupload', 'Download by URL completed successfully.' );
                } else {
                        wfDebugLog(
                                'fileupload',
index 48477f8..755f9fd 100644 (file)
@@ -290,7 +290,6 @@ class UploadStash {
                }
 
                $this->fileMetadata[$key] = [
-                       'us_id' => $dbw->nextSequenceValue( 'uploadstash_us_id_seq' ),
                        'us_user' => $this->userId,
                        'us_key' => $key,
                        'us_orig_path' => $path,
index 08f054d..8506846 100644 (file)
@@ -4109,12 +4109,10 @@ class User implements IDBAccessObject {
                        unset( $params['options'] );
                }
                $dbw = wfGetDB( DB_MASTER );
-               $seqVal = $dbw->nextSequenceValue( 'user_user_id_seq' );
 
                $noPass = PasswordFactory::newInvalidPassword()->toString();
 
                $fields = [
-                       'user_id' => $seqVal,
                        'user_name' => $name,
                        'user_password' => $noPass,
                        'user_newpassword' => $noPass,
@@ -4179,10 +4177,8 @@ class User implements IDBAccessObject {
                $noPass = PasswordFactory::newInvalidPassword()->toString();
 
                $dbw = wfGetDB( DB_MASTER );
-               $seqVal = $dbw->nextSequenceValue( 'user_user_id_seq' );
                $dbw->insert( 'user',
                        [
-                               'user_id' => $seqVal,
                                'user_name' => $this->mName,
                                'user_password' => $noPass,
                                'user_newpassword' => $noPass,
index 8970b40..e2ed910 100644 (file)
@@ -404,6 +404,7 @@ class Names {
                'sw' => 'Kiswahili', # Swahili
                'szl' => 'ślůnski', # Silesian
                'ta' => 'தமிழ்', # Tamil
+               'tay' => 'Tayal', # Atayal
                'tcy' => 'ತುಳು', # Tulu
                'te' => 'తెలుగు', # Telugu
                'tet' => 'tetun', # Tetun
diff --git a/languages/i18n/ais.json b/languages/i18n/ais.json
new file mode 100644 (file)
index 0000000..b9db9f7
--- /dev/null
@@ -0,0 +1,856 @@
+{
+       "@metadata": {
+               "authors": [
+                       "Akamycoco",
+                       "Benel",
+                       "Bunukwiki",
+                       "Tokoabibi"
+               ]
+       },
+       "underline-never": "caaytu",
+       "sunday": "pilipayan",
+       "monday": "sakacacay a demied nu lipay",
+       "tuesday": "sakatusa a demied nu lipay",
+       "wednesday": "sakatulu a demied nu lipay",
+       "thursday": "sakasepat a demied nu lipay",
+       "friday": "sakalima a demied nu lipay",
+       "saturday": "sakaenem a demied nu lipay",
+       "sun": "pilipayan",
+       "mon": "sakacacay a demied nu lipay",
+       "tue": "sakatusa a demied nu lipay",
+       "wed": "sakatulu a demied nu lipay",
+       "thu": "sakasepat a demied nu lipay",
+       "fri": "sakalima a demied nu lipay",
+       "sat": "sakaenem a demied nu lipay",
+       "january": "cacay bulad",
+       "february": "tusa bulad",
+       "march": "tulu bulad",
+       "april": "sepat bulad",
+       "may_long": "lima bulad",
+       "june": "enem bulad",
+       "july": "pitu bulad",
+       "august": "walu bulad",
+       "september": "siwa bulad",
+       "october": "cacay bataan bulad",
+       "november": "sabaw cacay bulad",
+       "december": "sabaw tusa bulad",
+       "january-gen": "cacay bulad",
+       "february-gen": "tusa bulad",
+       "march-gen": "tulu bulad",
+       "april-gen": "sepat bulad",
+       "may-gen": "lima bulad",
+       "june-gen": "enem bulad",
+       "july-gen": "pitu bulad",
+       "august-gen": "walu bulad",
+       "september-gen": "siwa bulad",
+       "october-gen": "cacay bataan bulad",
+       "november-gen": "sabaw cacay bulad",
+       "december-gen": "sabaw tusa bulad",
+       "jan": "cacay bulad",
+       "feb": "tusa bulad",
+       "mar": "tulu bulad",
+       "apr": "sepat bulad",
+       "may": "lima bulad",
+       "jun": "enem bulad",
+       "jul": "pitu bulad",
+       "aug": "walu bulad",
+       "sep": "siwa bulad",
+       "oct": "cacay bataan bulad",
+       "nov": "sabaw cacay bulad",
+       "dec": "sabaw tusa bulad",
+       "january-date": "cacay bulad $1",
+       "february-date": "tusa bulad $1",
+       "march-date": "tulu bulad $1",
+       "april-date": "sepat bulad $1",
+       "may-date": "lima bulad $1",
+       "june-date": "enem bulad $1",
+       "july-date": "pitu bulad $1",
+       "august-date": "walu bulad $1",
+       "september-date": "siwa bulad $1",
+       "october-date": "cacay bataan bulad $1",
+       "november-date": "sabaw cacay bulad $1",
+       "december-date": "sabaw tusa bulad $1",
+       "period-am": "AM",
+       "period-pm": "PM",
+       "pagecategories": "{{PLURAL:$1|kakuniza}}",
+       "category_header": "abuay nu kasasizuma \"$1\" a kasabelih",
+       "subcategories": "sailuc-kasasizuma",
+       "category-media-header": "kakuniza labuay \"$1\" a myiti",
+       "hidden-categories": "{{PLURAL:$1|midimut kakuniza}}",
+       "category-subcat-count": "{{PLURAL:$2|uyni kakuniza hatiza ku cacay yamalyilu sailuc-kakuniza. kina kakuniza yamalyilu isasa $2 a sailuc-kasasizuma, ilabu {{PLURAL:$1}}mahiza ku isasaay}}",
+       "category-article-count": "{{PLURAL:$2|uyni kakuniza hatiza ku cacay yamalyilu sailuc-kakuniza. kina kakuniza yamalyilu isasa $2 a sailuc-kasasizuma, ilabu {{PLURAL:$1}}mahiza ku isasaay}}",
+       "category-file-count": "{{PLURAL:$2|kakuniza yamalyilu isasaay a cacay ku tangan. kakuniza yamalyilu isasaay izaway $1 ku tangan, pulung $2 makalaan.}}",
+       "listingcontinuesabbrev": "palalid",
+       "about": "mahizaay",
+       "newwindow": "(paynin baluhay a azih-sasingalan miwawah)",
+       "cancel": "palawpes",
+       "moredotdotdot": "yadah...",
+       "mypage": "kasabelih",
+       "mytalk": "sasukamu",
+       "anontalk": "sasukamu",
+       "navigation": "pasubana’ tu miidangay",
+       "and": "&#32;",
+       "actions": "saungay",
+       "namespaces": "pangangananay a salaedan",
+       "variants": "masazumaay",
+       "navigation-heading": "pasubana’ tu miidangay pipili’an",
+       "errorpagetitle": "mungangaw",
+       "returnto": "tatiku tazuma至 $1.",
+       "tagline": "makayzaay i {{SITENAME}}",
+       "help": "buhci tu kamu",
+       "search": "kilim",
+       "searchbutton": "kilim",
+       "go": "mileku",
+       "searcharticle": "mileku",
+       "history": "kasabelih nazipa’an",
+       "history_short": "nazipa’an",
+       "history_small": "nazipa’an",
+       "printableversion": "kapah tu insace baziyong / sapad",
+       "permalink": "saluimengay misiket",
+       "print": "insace",
+       "view": "ciwsace",
+       "view-foreign": "i $1 miciwsace",
+       "edit": "mikawaway-kalumyiti",
+       "create": "patizeng",
+       "create-local": "cunusen itiniay a buhci tu kamu",
+       "delete": "misipu",
+       "protect_change": "misumad",
+       "newpage": "baluhayay a kasabelih",
+       "talkpagelinktext": "sasukamu",
+       "personaltools": "teked sakaluk",
+       "talk": "matatengil",
+       "views": "ciwsace",
+       "toolbox": "sakaluk",
+       "otherlanguages": "zumaay a kamu",
+       "redirectedfrom": "(miliyawtu tazuma nay $1)",
+       "redirectpagesub": "miliyaw tazuma kasabelih",
+       "redirectto": "miliyaw tazuma tu:",
+       "lastmodifiedat": "uyni kasabelih sazikuz mikawaway tu kalumyiti i $1 $2.",
+       "jumpto": "taayaw:",
+       "jumptonavigation": "pasubana’ tu miidangay",
+       "jumptosearch": "kilim",
+       "aboutsite": "mahizaay {{SITENAME}}",
+       "aboutpage": "Project:mahizaay",
+       "copyright": "anu izaw ku zuma buhci tu kamu, kasabelih aazihen a lacul i labu, pisaungay hamin $1 sapabeli tu kinli a ceding.",
+       "copyrightpage": "{{ns:project}}:nisanga’an niza tu tungus a kawaw",
+       "currentevents": "ayzaay a sinbun",
+       "currentevents-url": "Project:Current events",
+       "disclaimers": "caay pimuku tu sikining",
+       "disclaimerpage": "Project:habutud a pimuku tu sikining",
+       "edithelp": "mikawaway tu kalumyiti buhci tu kamu",
+       "helppage-top-gethelp": "buhci tu kamu",
+       "mainpage": "saayaway a belih",
+       "mainpage-description": "saayaway a belih",
+       "policy-url": "Project:Policy",
+       "portal": "komiyonityi sacumudan",
+       "portal-url": "Project:komiyonityi sacumudan",
+       "privacy": "salimek a mikuwanay a kawaw",
+       "privacypage": "Project:salimek a mikuwanay a kawaw",
+       "ok": "malucekay",
+       "retrievedfrom": "miala i \"$1\"",
+       "editsection": "mikawaway-kalumyiti",
+       "editold": "mikawaway tu kalumyiti",
+       "viewsourceold": "ciwsace sakatizeng bangu",
+       "editlink": "mikawaway-kalumyiti",
+       "viewsourcelink": "ciwsace sakatizeng bangu",
+       "editsectionhint": "mikawaway tu kalumyiti tusil: $1",
+       "toc": "dilyikotoling",
+       "showtoc": "paazih",
+       "hidetoc": "midimut",
+       "collapsible-expand": "micuwat",
+       "confirmable-yes": "hang",
+       "confirmable-no": "caay",
+       "site-atom-feed": "$1 a Atom saangangan",
+       "page-atom-feed": "$1 a Atom saangangan",
+       "red-link-title": "$1 (kasabelih nayai’ tu)",
+       "nstab-main": "kasabelih",
+       "nstab-user": "misaungayay a kasabelih",
+       "nstab-special": "sazumaay a kasabelih",
+       "nstab-project": "cwanan kasabelih",
+       "nstab-image": "tangan",
+       "nstab-mediawiki": "palatuh",
+       "nstab-template": "taazihan mitudung",
+       "nstab-category": "kakuniza",
+       "mainpage-nstab": "saayaway a belih",
+       "error": "mungangaw",
+       "databaseerror-query": "palalitemuh tu kawaw: $1",
+       "databaseerror-function": "sakapaluwaluway: $1",
+       "databaseerror-error": "mungangaw: $1",
+       "badtitle": "a’cusay a pyawti",
+       "badtitletext": "matuzu’ay a kasabelih pyawti u la’cusay、nayi’ ku cacan, caaysa tatenga’ay tu misiket kamu Wikiay a pyawti.\ntebanay pyawti akay amalyilu la’cusay pisaungay i pyawtayi a tatebanan nu nisulitan.",
+       "viewsource": "ciwsace sakatizeng bangu",
+       "welcomeuser": "manamuh tu tayniay, $1!",
+       "yourname": "misaungayay a kalungangan:",
+       "userlogin-yourname": "misaungayay a kalungangan",
+       "userlogin-yourname-ph": "pisulitan tu nu misay a misaungayay a kalungangan",
+       "yourpassword": "mima:",
+       "userlogin-yourpassword": "mima",
+       "userlogin-yourpassword-ph": "suliten nu misuay a mima",
+       "createacct-yourpassword-ph": "pisulitan ku mima",
+       "createacct-yourpasswordagain": "malucekay tu mima",
+       "createacct-yourpasswordagain-ph": "pisulitan ku mima kinacacay aca",
+       "userlogin-remembermypassword": "i balucu’en aku patalabu setyitase",
+       "login": "patalabu",
+       "nav-login-createaccount": "patalabu / panganganen ku canghaw",
+       "logout": "katahkal",
+       "userlogin-noaccount": "inayi’ ku canghaw kisu haw?",
+       "userlogin-joinproject": "micunus {{SITENAME}}",
+       "createaccount": "panganganen ku canghaw",
+       "userlogin-resetpassword-link": "maliyuh ku mima kisu haw?",
+       "userlogin-helplink2": "patalabu miedap",
+       "createacct-emailoptional": "imyiyo(email) tigami (u pili’ay sasulitan)",
+       "createacct-email-ph": "pisulitan ku imyiyo(email) nu misu",
+       "createacct-reason": "mahicaay",
+       "createacct-submit": "panganganen ku misuay a canghaw",
+       "createacct-another-submit": "panganganen ku canghaw",
+       "createacct-benefit-heading": "{{SITENAME}} paanin tu nisulitan tu nu tapangay mahiza kisuan.",
+       "createacct-benefit-body1": "saka{{PLURAL:$1|ku mikawaway tu kalumyiti}}",
+       "createacct-benefit-body2": "{{PLURAL:$1| kasabelih}}",
+       "createacct-benefit-body3": "cay katenesay{{PLURAL:$1|paaninay tu kalusasing}}",
+       "loginsuccesstitle": "patalabutu",
+       "loginlanguagelabel": "kamu: $1",
+       "pt-login": "patalabu",
+       "pt-login-button": "patalabu",
+       "pt-createaccount": "panganganen ku canghaw",
+       "pt-userlogout": "katahkal",
+       "botpasswords-label-create": "patizeng",
+       "botpasswords-label-update": "misabaluhay",
+       "botpasswords-label-cancel": "palawpes",
+       "botpasswords-label-delete": "masipu",
+       "botpasswords-label-grants-column": "pabeli tu kinli",
+       "resetpass-submit-cancel": "palawpes",
+       "passwordreset": "miliyaw miteka setin mima",
+       "passwordreset-username": "misaungayay a kalungangan:",
+       "changeemail-none": "(nayi’)",
+       "resettokens-tokens": "sabuhat:",
+       "bold_sample": "kibetulay a sulit",
+       "bold_tip": "kibetulay a sulit",
+       "italic_sample": "tukenihay nisulit",
+       "italic_tip": "tukenihay nisulit",
+       "link_sample": "misiket satangahan a sulit",
+       "link_tip": "labu-labu misiket",
+       "extlink_sample": "http://www.example.com misiket satangahan a sulit",
+       "extlink_tip": "hekal-hekal misiket (amana katawal saka http:// paangangan)",
+       "headline_sample": "sakacacay a selal nu satangahan a sulit",
+       "headline_tip": "sakatusa a selal nu satangahan a sulit",
+       "nowiki_sample": "pacucuk caayay kesehwaay a cudad",
+       "nowiki_tip": "sekipo Wiki kesehwa sulit nu kamu",
+       "image_tip": "nicunusay a tangan",
+       "media_tip": "tangan-tangan misiket",
+       "sig_tip": "misuay a sulit nu ngangan atu demiad, tuki",
+       "hr_tip": "Sapisasuala (cayka yadah kawiza)",
+       "summary": "pecu’ nu lacul:",
+       "subject": "taazihan tu kawaw:",
+       "minoredit": "payni mikilulay a mikawaway tu kalumyiti",
+       "watchthis": "miazih tuyni kasabelih",
+       "savearticle": "misuped kasabelih",
+       "preview": "pataayaway miazih",
+       "showpreview": "paazih pataayaway miazih",
+       "showdiff": "paazih ku masumaday",
+       "anoneditwarning": "<strong>patalaw:</strong>caay henay kisu patalabu. anu miteka mikawaway tu kalumyiti, IP adolyise nu misu ama mitilak. anu kisu <strong>[$1  patalabu ]</strong> acasa <strong>[$2 panganganen ku canghaw ]</strong>, misuay mikawaway tu kalumyiti payni tu nu misuay misaungayay kalungangan sacuzu’ ,izaway zuma kapahayay.",
+       "loginreqlink": "patalabu",
+       "newarticle": "(baluhay)",
+       "newarticletext": "masasiket kisu tu nayi’ay tu kasabelih.\namipatizeng tina kasabelih, kaisasa mikawaway tu kalumyiti atilad misulit ku lacul (kahica nu kawaw piazih tu tatenga’ay [$1 misaungay a buhci tu kamu  kasabelih ]).\namahica caay padeteng tayza tina kasabelih kisu haw, pihaymaw sapecec saazihay a <strong>tatiku</strong> pipenecan.",
+       "noarticletext": "kina kasabelih inayi’ lacul ayza,kapah tu kisu i zumaay a kasabelih [[Special:Search/{{PAGENAME}}| mikilim kina kasabelih pyawti ]]、<span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}}  mikilim sasuala nasulitan nakawawan ] caay sa[{{fullurl:{{FULLPAGENAME}}|action=edit}} patizeng kina kasabelih ]</span>.",
+       "noarticletext-nopermission": "tina kasabelih ayza inayi’ lacul,\nkapah tu kisu i zuma kasabelih [[Special:Search/{{PAGENAME}}| kilim kina kasabelih pyawti ]],acasa <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}}  kilim sasuala nasulitan nakawawan ]</span>,uyzasa  inayi’  ku tungus patizeng tina kasabelih.",
+       "updated": "(misabaluhay)",
+       "editing": "mikawaway tu kalumyiti  $1 ayza",
+       "creating": "patizeng ayza $1",
+       "editingsection": "mikawaway tu kalumyiti ayza $1 (tusil)",
+       "yourdiff": "sasizuma",
+       "templatesused": "uyni kasabelih pisaungay tu isasaay {{PLURAL:$1|taazihan mitudung}}:",
+       "template-protected": "(madiputay)",
+       "template-semiprotected": "(madiputay a kasabelih - satizep mikawaway tu kalumyiti)",
+       "hiddencategories": "kina kasabelih tungusay nu {{PLURAL:$1|1 midimut kakuniza }}mamikawaw:",
+       "permissionserrorstext-withaction": "namakay isasaay {{PLURAL:$1|mahicaay}}, inayi’ kisu situngus miteka $2 miteka tuway misaungay:",
+       "moveddeleted-notice": "kina kasabelih masipu tu.\nisasa nipabeli kina kasabelihay a masipu atu milimad nasulitan nakawawan, taneng miazih tu tatenga’ay.",
+       "content-json-empty-object": "inayi’ay a tuutuud",
+       "content-json-empty-array": "inayi’ay a papazengan tu nisulitan",
+       "viewpagelogs": "ciwsace kina kasabelih a nasulitan nakawawan",
+       "currentrev-asof": "i $1 a sabaluhay masumad",
+       "revisionasof": "$1 a sumad",
+       "revision-info": "i $1 tuyni a {{GENDER:$6|$2}} u nasumad nu nikawawan",
+       "previousrevision": "← masumad nu ayaway",
+       "nextrevision": "kilulay masumad →",
+       "currentrevisionlink": "sabaluhay masumad",
+       "cur": "ayza",
+       "next": "nuzikuzan",
+       "last": "ayaway",
+       "page_last": "sazikuzay a kasabelih",
+       "histfirst": "sakasumamadan",
+       "histlast": "sabaluhay",
+       "historyempty": "(inayi’)",
+       "rev-showdeleted": "paazih",
+       "revdelete-show-file-submit": "hang",
+       "revdelete-radio-set": "midimut",
+       "revdelete-log": "mahicaay:",
+       "mergehistory-reason": "mahicaay:",
+       "history-title": "\"$1\" masumaday a nazipa’an",
+       "difference-title": "\"$1\" misumad laeday sasizuma",
+       "lineno": "silsil $1:",
+       "editundo": "patiku",
+       "diff-multi-sameuser": "(malecaday misaungayay {{PLURAL:$1| ilaed izaw ku $1 a sumad}}inayi’ paazih)",
+       "searchresults": "heci nu makatepa",
+       "searchresults-title": "$1 heci nu makatepa",
+       "prevn": "ayaw saka {{PLURAL:$1|$1}}",
+       "nextn": "zikuzan saka {{PLURAL:$1|$1}}",
+       "nextn-title": "nuzikuzan saka {{PLURAL:$1|a heci}}",
+       "shown-title": "paybelih {{PLURAL:$1|$1 ku heci}} paazih",
+       "viewprevnext": "ciwsace ($1 {{int:pipe-separator}} $2) ($3)",
+       "searchmenu-new": "<strong> uyni Wiki patizeng ku kasabelih  \"[[:$1]]\"!</strong>{{PLURAL:$2|0=| acasa miazih tu tatenga’ay patalabuay a matepa’ay a heci. |acasa miazih tu tatenga’ay zuma matepa’ay a heci.}}",
+       "searchprofile-articles": "lacul kasabelih",
+       "searchprofile-images": "malocimyidiya",
+       "searchprofile-everything": "hamin",
+       "searchprofile-advanced": "tapabaw",
+       "searchprofile-articles-tooltip": "i labu nu $1 mikilim",
+       "searchprofile-images-tooltip": "mikilim tu tangan",
+       "searchprofile-everything-tooltip": "kilim saca hamin lacul (yamalyilu sasukamu kasabelih)",
+       "searchprofile-advanced-tooltip": "mikilim pakuniza misanga’ pangangananay a salaedan",
+       "search-result-size": "$1 ({{PLURAL:$2|$2 ku sulit}})",
+       "search-redirect": "(miliyaw tazuma namakay $1)",
+       "search-section": "(tusil $1)",
+       "search-suggest": "u tuzu’ nu misu ku:$1 haw?",
+       "search-interwiki-more": "(yadah)",
+       "search-relatedarticle": "mahizaay",
+       "searchall": "hamin",
+       "search-showingresults": "{{PLURAL:$4|saka <strong>$1</strong> a heci, pulung <strong>$3</strong>|saka <strong>$1-$2</strong> a heci, pulung <strong>$3</strong>}}",
+       "search-nonefound": "nayi’ matatungusay palalitemuh tu kawaw maheciay.",
+       "powersearch-toggleall": "hamin",
+       "powersearch-togglenone": "nayi’",
+       "mypreferences": "setin tu kanamuhan",
+       "prefs-skin": "nuhekalan",
+       "skin-preview": "pataayaway miazih",
+       "prefs-rc": "capi a demaiday a sumad",
+       "prefs-misc": "zuma",
+       "prefs-rendering": "nuhekalan",
+       "saveprefs": "suped",
+       "prefs-editing": "mikawaway-kalumyiti",
+       "searchresultshead": "kilim",
+       "stub-threshold-sample-link": "maaziahan",
+       "stub-threshold-disabled": "mapasatezep",
+       "timezoneregion-africa": "Afulika",
+       "timezoneregion-america": "Amilikaco",
+       "timezoneregion-antarctica": "Nancico",
+       "timezoneregion-arctic": "Sasaamisan",
+       "timezoneregion-asia": "Yaco",
+       "timezoneregion-australia": "Awco",
+       "timezoneregion-europe": "Oco",
+       "timezoneregion-indian": "Intuyang-bayu’",
+       "prefs-searchoptions": "kilim",
+       "default": "pataayaw tu kawaw",
+       "prefs-custom-css": "pakuniza misanga’ CSS",
+       "yourlanguage": "kamu:",
+       "prefs-i18n": "masakitakiay",
+       "prefs-signature": "sulitan a ngangan",
+       "prefs-timeoffset": "ilaed nu tuki",
+       "prefs-editor": "mikawaway-kalumyitiay",
+       "prefs-preview": "pataayaway miazih",
+       "prefs-tokenwatchlist": "sabuhat",
+       "prefs-diffs": "sasizuma",
+       "userrights-reason": "mahicaay:",
+       "userrights-expiry-current": "kakatekuhan $1",
+       "userrights-expiry": "kakatekuhan:",
+       "group": "luyaluy:",
+       "group-user": "misaungayay",
+       "group-bot": "kikay a tademaw",
+       "group-sysop": "mikuwanay",
+       "group-bureaucrat": "situngusay a mikawaway",
+       "group-all": "(hamin)",
+       "group-bot-member": "{{GENDER:$1|kikay a tademaw}}",
+       "grouppage-bot": "{{ns:project}}:kikay a tademaw",
+       "grouppage-sysop": "{{ns:project}}:mikuwanay",
+       "grouppage-bureaucrat": "{{ns:project}}:situngusay a mikawaway",
+       "right-writeapi": "pisaungay suliten API",
+       "grant-createaccount": "panganganen ku canghaw",
+       "newuserlogpage": "patizeng misaungayay nasulitan nakawawan",
+       "action-edit": "mikawaway tu kalumyiti uyni kasabelih",
+       "enhancedrc-history": "nazipa’an",
+       "recentchanges": "capi a demaiday a sumad",
+       "recentchanges-legend": "capi a demiad masumaday a mapiliay",
+       "recentchanges-summary": "mikilul nazikuzan ilabu nu Wikiay a kasabelihay a capi demiad a nasumaday.",
+       "recentchanges-label-newpage": "uyni mikawaway tu kalumyiti patizengtu baluhay kasabelih",
+       "recentchanges-label-minor": "payni mikilulay a mikawaway tu kalumyiti",
+       "recentchanges-label-bot": "uyni mikawaway tu kalumyiti u kikay a tademaw mileku",
+       "recentchanges-label-unpatrolled": "mikawaway tu kalumyiti caay henay ka tayza mikibi",
+       "recentchanges-label-plusminus": "na kasabelih misumad hacica ku tabaki (wyiyincu )",
+       "recentchanges-legend-heading": "<strong>u tinaku nu kulit:</strong>",
+       "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (piazih tu tatenga’ay [[Special:NewPages| baluhayay a kasabelih]])",
+       "recentchanges-submit": "paazih",
+       "rcfilters-savedqueries-new-name-label": "kalungangan",
+       "rcfilters-savedqueries-cancel-label": "palawpes",
+       "rcfilters-filterlist-title": "kilim",
+       "rcfilters-filter-user-experience-level-newcomer-label": "baluhayay a misaungayay",
+       "rcfilters-filter-user-experience-level-learner-label": "mahananamay",
+       "rcfilters-filter-bots-label": "kikay a tademaw",
+       "rcfilters-filter-minor-label": "cayka yadah ku misumad",
+       "rclistfrom": "paazih nay $3 $2 baluhayay a sumad katukuh ayza",
+       "rcshowhideminor": "$1 mikilulay mikawaway tu kalumyiti",
+       "rcshowhideminor-show": "paazih",
+       "rcshowhideminor-hide": "Hide",
+       "rcshowhidebots": "$1 kikay a tademaw",
+       "rcshowhidebots-show": "paazih",
+       "rcshowhidebots-hide": "midimut",
+       "rcshowhideliu": "$1 mapangangan tuway a misaungayay",
+       "rcshowhideliu-show": "paazih",
+       "rcshowhideliu-hide": "midimut",
+       "rcshowhideanons": "$1 paceba panganganay a misaungayay",
+       "rcshowhideanons-show": "paazih",
+       "rcshowhideanons-hide": "midimut",
+       "rcshowhidepatr-show": "paazih",
+       "rcshowhidepatr-hide": "midimut",
+       "rcshowhidemine": "$1 mikawaway tu kalumyiti nu maku",
+       "rcshowhidemine-show": "paazih",
+       "rcshowhidemine-hide": "midimut",
+       "rcshowhidecategorization-show": "paazih",
+       "rcshowhidecategorization-hide": "midimut",
+       "rclinks": "paazih capi a demiad $2 a demiaday a saka $1 a sumad.",
+       "diff": "sasizuma",
+       "hist": "nazipa’an",
+       "hide": "midimut",
+       "show": "paazih",
+       "minoreditletter": "adidi’",
+       "newpageletter": "baluhay",
+       "boteditletter": "kikay a tademaw",
+       "rc-change-size-new": "masumadtu sa u $1 {{PLURAL:$1|wyiyincu}}",
+       "newsectionsummary": "/* $1 */ baluhay a tusil",
+       "recentchangeslinked": "sasuala a sumad",
+       "recentchangeslinked-feed": "sasuala a sumad",
+       "recentchangeslinked-toolbox": "sasuala a sumad",
+       "recentchangeslinked-title": "pulung \"$1\" sasuala a sumaday",
+       "recentchangeslinked-summary": "uyni kasabelih pasilsil micuzu’ kasabelih masasiketay saca hamin kasabelihan (hakya u matuzu’ay kakuniza\nilabu saca hamin mamikawaw)izaw ku  misumaday kasabelih piazihan tu sulit.\nizawtu ku [[Special:Watchlist|sapacukat a sulit nu misu]] ilabuay a kasabelih apatahkal ku <strong>kibetulay a sulit</strong> sacuzu’.",
+       "recentchangeslinked-page": "kasabelih kalungangan:",
+       "recentchangeslinked-to": "Show changes to pages linked to the given page instead\nmisumad ku paazih masasiket tayza matuzu’ay kasabelih a nisumad",
+       "upload": "patapabaw ku tangan",
+       "filedesc": "pecu’ nu lacul",
+       "fileuploadsummary": "pecu’ nu lacul:",
+       "filesource": "saangangan:",
+       "upload-dialog-button-cancel": "palawpes",
+       "upload-dialog-button-back": "tatiku",
+       "upload-dialog-button-done": "pahezek",
+       "upload-dialog-button-save": "suped",
+       "upload-dialog-button-upload": "patapabaw",
+       "upload-form-label-infoform-name": "kalungangan",
+       "upload-form-label-infoform-description": "patahkal",
+       "upload-form-label-infoform-categories": "kakuniza",
+       "upload-form-label-infoform-date": "demiad",
+       "license": "sapabeli tu kinli a cedang",
+       "license-header": "sapabeli tu kinli a cedang",
+       "listfiles-delete": "misipu",
+       "imgfile": "tangan",
+       "listfiles": "tangan-tangan misiket",
+       "listfiles_thumb": "sukep tu zunga",
+       "listfiles_date": "demiad",
+       "listfiles_name": "kalungangan",
+       "listfiles_user": "misaungayay",
+       "listfiles_size": "hacica-tabaki",
+       "listfiles_description": "patahkal",
+       "listfiles_count": "baziyong",
+       "listfiles-latestversion-yes": "hang",
+       "listfiles-latestversion-no": "caay",
+       "file-anchor-link": "tangan",
+       "filehist": "tangan nu nazipa’an",
+       "filehist-help": "sapecec ku demiad/tuki sapiciwsace ku tuki nina demiad a tangan baziyong",
+       "filehist-current": "ayza",
+       "filehist-datetime": "demiad/tuki",
+       "filehist-thumb": "sukep tu zunga",
+       "filehist-thumbtext": "nu $1 baziyongay a sukep tu zunga",
+       "filehist-user": "misaungayay",
+       "filehist-dimensions": "ditek",
+       "filehist-comment": "pacunus sakacaay kapawan",
+       "imagelinks": "tangan sadama tu kawaw",
+       "linkstoimage": "isasaay {{PLURAL:$1| kasabelih  misiket |saka $1 a kasabelih misiket}}katukuh tina tangan:",
+       "nolinkstoimage": "nayi’ ku kasabelih masasiket katukuh tini a tangan.",
+       "sharedupload-desc-here": "kina tangan nay $1 hakay satu pisaungay tu zuma a cwanan.\nisasaay paazih kuyniay a tangan i [$2 tangan patahkal kasabelih] a patahkalay a lacul.",
+       "shared-repo-from": "nay $1",
+       "upload-disallowed-here": "la’cus kisu mitahpu tuyni a tangan.",
+       "filerevert-comment": "mahicaay:",
+       "filedelete-comment": "mahicaay:",
+       "filedelete-submit": "masipu",
+       "download": "patasasa'",
+       "randompage": "kakibalucu’ ay a kasabelih",
+       "randomincategory-submit": "mileku",
+       "statistics": "sausi",
+       "pageswithprop-submit": "mileku",
+       "brokenredirects-delete": "misipu",
+       "withoutinterwiki-legend": "saayaway a sulit",
+       "withoutinterwiki-submit": "paazih",
+       "nbytes": "$1 {{PLURAL:$1|wyiyincu}}",
+       "ncategories": "{{PLURAL:$1|kakuniza}}",
+       "nmembers": "$1 {{PLURAL:$1|ku mamikawaw}}",
+       "prefixindex-submit": "paazih",
+       "protectedpages-page": "kasabelih",
+       "protectedpages-expiry": "kakatekuhan",
+       "protectedpages-reason": "mahicaay",
+       "newpages": "baluhay kasabelih",
+       "newpages-submit": "paazih",
+       "move": "milimad",
+       "pager-older-n": "{{PLURAL:$1| kusa malumanay}}",
+       "suppress": "malangat",
+       "apisandbox-reset": "palawpis",
+       "apisandbox-retry": "miliyaw mitaneng",
+       "apisandbox-examples": "tinaku",
+       "apisandbox-results": "heci",
+       "apisandbox-continue": "palalid",
+       "apisandbox-continue-clear": "palawpis",
+       "booksources": "nu cudad atu laculaculan",
+       "booksources-search-legend": "mikilim ku cudad atu laculaculan",
+       "booksources-search": "kilim",
+       "log": "nasulitan nakawawan",
+       "logeventslist-submit": "paazih",
+       "checkbox-select": "mipili’: $1",
+       "checkbox-all": "hamin",
+       "checkbox-none": "nayi’",
+       "allpages": "hamin nu kasabelih",
+       "allarticles": "hamin nu kasabelih",
+       "allpagessubmit": "mileku",
+       "categories": "kakuniza",
+       "categories-submit": "paazih",
+       "linksearch-ns": "pangangananay a salaedan:",
+       "linksearch-ok": "kilim",
+       "listusers-submit": "paazih",
+       "listgrouprights-group": "luyaluy",
+       "listgrants": "pabeli tu kinli",
+       "listgrants-rights": "kinli",
+       "emailusernamesubmit": "patayzaan",
+       "emailfrom": "nay:",
+       "emailto": "katukuh:",
+       "emailsubject": "taazihan tu kawaw:",
+       "emailmessage": "palatuh:",
+       "emailsend": "patigamitu",
+       "watchlist": "miazihay a piazihan tu sulit",
+       "mywatchlist": "miazihay a piazihan tu sulit",
+       "watch": "miazih",
+       "watchlist-hide": "midimut",
+       "wlshowhideminor": "cayka yadah ku misumad",
+       "wlshowhidebots": "kikay a tademaw",
+       "confirm": "malucekaytu",
+       "delete-confirm": "misipu \"$1\"",
+       "historyaction-submit": "paazih",
+       "dellogpage": "masipu ku nasulitan nakawawan",
+       "deletecomment": "mahicaay:",
+       "rollbacklink": "panukasan",
+       "rollbacklinkcount": "patiku {{PLURAL:$1|mikawaway tu kalumyiti}}",
+       "changecontentmodel-reason-label": "mahicaay:",
+       "protectlogpage": "midiput nasulitan nakawawan",
+       "protectcomment": "mahicaay:",
+       "protectexpiry": "kakatekuhan:",
+       "protect-summary-cascade": "patatusul",
+       "protect-expiring": "kakatekuhan $1 (UTC)",
+       "protect-expiry-indefinite": "inayi’ u sungliw",
+       "restriction-edit": "mikawaway-kalumyiti",
+       "restriction-move": "milimad",
+       "restriction-create": "patizeng",
+       "restriction-upload": "patapabaw",
+       "undeletebtn": "patiku",
+       "undeletecomment": "mahicaay:",
+       "undelete-search-submit": "kilim",
+       "undelete-show-file-submit": "hang",
+       "namespace": "pangangananay a salaedan:",
+       "invert": "kabelihan mipili’",
+       "tooltip-invert": "pili’en hatizaay kuyni mapili’ay atilad i midimut mipili’panganganan a salaedan blabuay kasabelih sumad (anu hatizaay sasuala panganganan a salaedan, mama palecad midimut sasuala panganganan a salaedan)",
+       "namespace_association": "sasuala panganganan a salaedan",
+       "tooltip-namespace_association": "pili’en hatizaay kuyni mapili’ay atilad i yamalyilu atu mipili’ sasuala panganganan a salaedan sasukamu atu satangahan panganganan a salaedan",
+       "blanknamespace": "(sausi)",
+       "contributions": "{{GENDER:$1| misaungayay}}paanin tu nisulitan",
+       "mycontris": "paanin",
+       "anoncontribs": "paanin",
+       "uctop": "(ayza)",
+       "month": "sazikuzay demiad nabuladan:",
+       "year": "sazikuzay demiad mihcaan:",
+       "sp-contributions-blocklog": "milangat tu nasulitan nakawawan",
+       "sp-contributions-uploads": "patapabaw",
+       "sp-contributions-logs": "nasulitan nakawawan",
+       "sp-contributions-talk": "sasukamu",
+       "sp-contributions-submit": "kilim",
+       "whatlinkshere": "masasiket katukuh uyniyay a kasabelih",
+       "whatlinkshere-title": "masasiket tazumaay a \"$1\" kasabelih",
+       "whatlinkshere-page": "Kasabelih:",
+       "linkshere": "isasaay a kasabelih masasiket tazuma tu <strong>[[:$1]]</strong>:",
+       "isredirect": "miliyaw tazuma kasabelih",
+       "istemplate": "nicaliwan",
+       "isimage": "tangan-tangan misiket",
+       "whatlinkshere-prev": "saka {{PLURAL:$1|nuayaway}}",
+       "whatlinkshere-next": "saka {{PLURAL:$1|nuzikuzan}}",
+       "whatlinkshere-links": "← masasiket",
+       "whatlinkshere-hideredirs": "$1 miliyaw tazuma",
+       "whatlinkshere-hidetrans": "$1 nicaliwan",
+       "whatlinkshere-hidelinks": "$1 masasiket",
+       "whatlinkshere-hideimages": "$1 tangan-tangan misiket",
+       "whatlinkshere-filters": "kilim",
+       "whatlinkshere-submit": "mileku",
+       "ipbexpiry": "kakatekuhan:",
+       "ipbreason": "mahicaay:",
+       "ipb-blocklist-duration-left": "$1 pakawili",
+       "autoblocklist-submit": "kilim",
+       "blocklist-target": "pabalucu’an",
+       "blocklist-expiry": "kakatekuhan",
+       "blocklist-reason": "mahicaay",
+       "ipblocklist-submit": "kilim",
+       "infiniteblock": "inayi’ u sungliw",
+       "blocklink": "malangat",
+       "contribslink": "paanin",
+       "blocklogpage": "milangat tu nasulitan nakawawan",
+       "movelogpage": "milimad ku nasulitan nakawawan",
+       "movereason": "mahicaay:",
+       "export": "patahkal ku kasabelih",
+       "export-submit": "patahkal",
+       "allmessagesname": "kalungangan",
+       "allmessages-filter-legend": "kilim",
+       "allmessages-filter-all": "hamin",
+       "allmessages-filter-modified": "masumad tuway",
+       "allmessages-language": "kamu:",
+       "allmessages-filter-submit": "mileku",
+       "allmessages-filter-translate": "mibelih",
+       "thumbnail-more": "patabaki(micuwat)",
+       "import-interwiki-submit": "pacumud",
+       "import-comment": "pacunus sakacaay kapawan:",
+       "tooltip-pt-userpage": "{{GENDER:|misaungayay nu misu}} kasabelih",
+       "tooltip-pt-mytalk": "{{GENDER:|misuay }}sasukamu a kasabelih",
+       "tooltip-pt-preferences": "{{GENDER:|misuay}} setin tu kanamuhan",
+       "tooltip-pt-watchlist": "miazih kisu misumad kasabelih piazihan tu sulit ayza",
+       "tooltip-pt-mycontris": "{{GENDER:|misuay}}paaninay a piazihan tu sulit",
+       "tooltip-pt-login": "patahkal nizateng kisu ayaw patalabu, uyza sa kapah tu amana.",
+       "tooltip-pt-logout": "katahkal",
+       "tooltip-pt-createaccount": "taneng kami pauuh kisuan panganganen tu cacay canghaw atu patalabu, anu caay ku tabakiay a pisaungay.",
+       "tooltip-ca-talk": "matatengil tu mahizaay lacul nu kasabelih",
+       "tooltip-ca-edit": "mikawaway tu kalumyiti uyni kasabelih",
+       "tooltip-ca-viewsource": "uyni kasabelih madiputay tuway.\nkapah kisu miciwsace tuyni kasabelih sakatizeng bangu",
+       "tooltip-ca-history": "uyini kasabelih nasawniay a sumad",
+       "tooltip-ca-move": "milimad tina kasabelih",
+       "tooltip-ca-watch": "paynien kasabelih micunus misuay cyinse piazihan tu sulit",
+       "tooltip-search": "kilim {{SITENAME}}",
+       "tooltip-search-go": "amahica milihiza tuyni kalungangan malalanepay kasabelih izaay tu, taayawen ku tiza kasabelih",
+       "tooltip-search-fulltext": "mikilim pisaungay tina paycudadcudad a kasabelih",
+       "tooltip-p-logo": "taayaw saayaway a belih",
+       "tooltip-n-mainpage": "taayaw saayaway a belih",
+       "tooltip-n-mainpage-description": "taayaw saayaway a belih",
+       "tooltip-n-portal": "mahizaay uyni a cwanan, amihica kisu kapah tu、icuwa amatepa maydihay a kawaw atu duut nu misu",
+       "tooltip-n-currentevents": "i labu nu sinbun a kawaw, matepa sasuala tada kalunasulitan",
+       "tooltip-n-recentchanges": "pasilsil tuyni Wiki labuay a sapisumaday a piazihan tu sulit",
+       "tooltip-n-randompage": "kakibalucu’ ay micumud cacay a kasabelih",
+       "tooltip-n-help": "mamiedapay a kakitizaan",
+       "tooltip-t-whatlinkshere": "pasilsil saca hamin masasiket uyni kasabelihay a kasabelih",
+       "tooltip-t-recentchangeslinked": "uyni kasabelih masasiket tayza i zuma  kasabelih capi demiaday a sumad",
+       "tooltip-feed-atom": "uyni a kasabelih nu Atom saanganga",
+       "tooltip-t-contributions": "{{GENDER:$1| tina misaungayay}} a paanin tu nisulitan piazihan tu sulit",
+       "tooltip-t-upload": "patapabaw ku tangan",
+       "tooltip-t-specialpages": "hamin sazumaay kasabelih piazihan tu sulit",
+       "tooltip-t-print": "uyni kasabelihay a taneng insace a baziyong",
+       "tooltip-t-permalink": "uyni kasabelih masumaday saluimengay misiket",
+       "tooltip-ca-nstab-main": "ciwsace kasabelihay a lacul",
+       "tooltip-ca-nstab-user": "ciwsace misaungayay a kasabelih",
+       "tooltip-ca-nstab-special": "uyni kasabelih u sazumaay belih, cayka tineng mikawaway tu kalumyiti",
+       "tooltip-ca-nstab-project": "ciwsace cwanan kasabelih",
+       "tooltip-ca-nstab-image": "ciwsace tangan kasabelih",
+       "tooltip-ca-nstab-template": "ciwsace taazihan mitudung",
+       "tooltip-ca-nstab-category": "ciwsace kakuniza a kasabelih",
+       "tooltip-save": "misuped misuay a pisumad",
+       "tooltip-preview": "kay iayaw nu pisuped miazih tu nu misuay nisumad.",
+       "tooltip-diff": "paazih hica sa kisu labuay a nisumadan",
+       "tooltip-watch": "paynien kasabelih micunus misuay cyinse piazihan tu sulit",
+       "tooltip-rollback": "sapecec \"patiku\" misiket, kapah patiku tayza nuayawanay a paanin tu nisulitan tina kasabelih mikawaway tu kalumyiti",
+       "tooltip-undo": "\"patiku\" kapah tu patiku tuyni mikawaway tu kalumyiti payni pataayaway miazih muse miwawah mikawaway tu kalumyiti aazihan cudad, saka caay cayaw nu labu micunus mahicaay.",
+       "tooltip-summary": "kapisulitan apuyu’ay a pecu’ nu lacul",
+       "others": "zuma",
+       "simpleantispam-label": "sapi tena’ babakahen a sulit kinsa.\nyu <strong>amana</strong> misulit kuyni pisinga’an!",
+       "pageinfo-language-change": "misumad",
+       "pageinfo-content-model-change": "misumad",
+       "pageinfo-robot-noindex": "amana",
+       "pageinfo-toolboxlink": "kasabelih cesyun",
+       "pageinfo-redirectsto-info": "katinengan",
+       "pageinfo-contentpage-yes": "hang",
+       "pageinfo-protect-cascading-yes": "hang",
+       "confirm-markpatrolled-button": "malucekay",
+       "previousdiff": "← malumanay a mikawaway tu kalumyiti",
+       "nextdiff": "baluhayay mikawaway tu kalumyit →",
+       "widthheightpage": "$1 × $2, $3 {{PLURAL:$3|ku kasabelih}}",
+       "file-info-size": "$1 × $2 syangsu, hacica ku tabaki nu tangan: $3, MIME kakuniza: $4",
+       "file-info-size-pages": "$1 × $2 syangsu, hacica ku tabaki nu tangan:$3,MIME kakuniza: $4, $5 {{PLURAL:$5|ku kasabelih}}",
+       "file-nohires": "inay ku sangaleb takalaway a katingalaw, kapah tu nipabeli.",
+       "svg-long-desc": "SVG tangan, maazihay hacica ku tabaki $1 × $2  syangsu, tangan hacica ku tabaki: $3",
+       "show-big-image": "saayaway a tangan",
+       "show-big-image-preview": "pataayaway miazih hacica ku tabaki: $1.",
+       "show-big-image-size": "$1 × $2 syangsu",
+       "file-info-gif-looped": "palalacalen",
+       "file-info-gif-frames": "$1 {{PLURAL:$1|misabacu}}",
+       "file-info-png-frames": "$1 {{PLURAL:$1|misabacu}}",
+       "newimages-legend": "kilim",
+       "ilsubmit": "kilim",
+       "bydate": "ahizan tu demiad",
+       "just-now": "nasawni",
+       "metadata": "pulita tu kalunasulitan",
+       "metadata-help": "uyni tangan labuay amin yamalyilu zuma cesyun, uyni a cesyun akay nay suewyi  sasasing asaca sapisekyin i tapang asaca suwyihwa saayaw katukuh pahzekan a nakawawan mapacunusay. anu nay tangan saayaway setyitase masumadtu, hatizaay pulita kalunasulitan akay la’cus mileku mabetil a misumad tu tangan.",
+       "metadata-fields": "i tini palatuh patahkal i labuay a EXIF pulita tu kalunasulitanay a kakitizaan, yamalyilu i zunga paazih kasabelih, sapipulita tu cudad nu nasulitan malepi’ paazih palatuh.\nzumaay a pulita tu cudad pataayaw tu kawaw midimut.\n* make\n* model\n* datetimeoriginal\n* exposuretime\n* fnumber\n* isospeedratings\n* focallength\n* artist\n* copyright\n* imagedescription\n* gpslatitude\n* gpslongitude\n* gpsaltitude",
+       "exif-imagewidth": "ahebal",
+       "exif-imagelength": "u takalaw",
+       "exif-orientation": "papayzaan",
+       "exif-xresolution": "sasuala katingalaw",
+       "exif-yresolution": "mitelekay katingalaw",
+       "exif-datetime": "tangan misumaday a demiad atu tuki",
+       "exif-make": "sasasing misanga’ay tu kalutuud",
+       "exif-model": "sasasing silosi nu nisanga’an",
+       "exif-software": "pisaungay zwanti",
+       "exif-artist": "masacudaday",
+       "exif-exifversion": "Exif baziyong / sapad",
+       "exif-colorspace": "kalukulit salaedan",
+       "exif-datetimeoriginal": "kalunasulitan masangaay’ a demiad atu tuki",
+       "exif-datetimedigitized": "suwyihwaay a demiad atu tuki",
+       "exif-lightsource": "katahkalan nu likat",
+       "exif-flash": "sabelabelatay a tinghuy",
+       "exif-focallength": "saed nu sapisasing",
+       "exif-contrast": "e-contrast",
+       "exif-keywords": "aazihen dulit",
+       "exif-objectname": "sapuyuay a ngangan",
+       "exif-headline": "satangahan",
+       "exif-source": "saangangan",
+       "exif-writer": "misacudaday",
+       "exif-languagecode": "kamu",
+       "exif-iimcategory": "kakuniza",
+       "exif-identifier": "mapulitaay a kodo",
+       "exif-label": "aazihen paya",
+       "exif-orientation-1": "tatungus",
+       "exif-componentsconfiguration-0": "inayi’",
+       "exif-exposureprogram-1": "palima",
+       "exif-meteringmode-255": "zuma",
+       "exif-lightsource-1": "edil",
+       "exif-lightsource-2": "inkwang a tinghuy",
+       "exif-lightsource-4": "sabelabelatay a tinghuy",
+       "exif-lightsource-9": "cilalah a demiad",
+       "exif-lightsource-10": "kenutan",
+       "exif-focalplaneresolutionunit-2": "incun",
+       "exif-scenecapturetype-0": "tatungus",
+       "exif-scenecapturetype-1": "makaazihay",
+       "exif-scenecapturetype-2": "sassing nu tademaw",
+       "exif-scenecapturetype-3": "makaazihay nu labiyi",
+       "exif-gaincontrol-0": "nayi’",
+       "exif-gaincontrol-1": "adidi’ tu cunusan",
+       "exif-gaincontrol-2": "takalaw ku cunusan",
+       "exif-gaincontrol-3": "adidi’ tu selepan",
+       "exif-gaincontrol-4": "takalaw ku selepan",
+       "exif-contrast-0": "tatungus",
+       "exif-contrast-1": "pu’nel",
+       "exif-contrast-2": "takalaw",
+       "exif-saturation-0": "tatungus",
+       "exif-sharpness-0": "tatungus",
+       "exif-sharpness-1": "pu’nel",
+       "exif-sharpness-2": "takalaw",
+       "exif-subjectdistancerange-2": "pakatepalay a azih",
+       "exif-subjectdistancerange-3": "pakabatatay a azih",
+       "exif-gpslatitude-n": "pyiwyi",
+       "exif-gpslatitude-s": "nanwyi",
+       "exif-gpslongitude-e": "tongcing",
+       "exif-gpslongitude-w": "sicing",
+       "exif-gpsdestdistance-k": "kungli",
+       "exif-gpsdestdistance-m": "inli",
+       "exif-gpsdestdistance-n": "hayli",
+       "exif-objectcycle-a": "namalamam a cacay",
+       "exif-objectcycle-p": "nakalahukan a cacay",
+       "exif-dc-contributor": "paaninay tu kalusasing",
+       "exif-dc-date": "demiad",
+       "exif-dc-rights": "kinli",
+       "exif-iimcategory-edu": "pasubana’ay a kawaw",
+       "exif-iimcategory-evn": "liwliw",
+       "exif-iimcategory-hth": "kapah ku uzip",
+       "exif-iimcategory-lab": "makawaw",
+       "exif-iimcategory-spo": "wundukay",
+       "exif-iimcategory-wea": "demidad",
+       "exif-urgency-normal": "tatungus ($1)",
+       "namespacesall": "hamin",
+       "monthsall": "hamin",
+       "confirm_purge_button": "malucekay",
+       "confirm-watch-button": "malucekay",
+       "confirm-unwatch-button": "malucekay",
+       "confirm-rollback-button": "malucekay",
+       "imgmultigo": "mileku!",
+       "img-lang-go": "mileku",
+       "ascending_abbrev": "masalaylay adidi’ay katukuh tabakiay",
+       "descending_abbrev": "masalaylay tabakiay katukuh adidi’ay",
+       "table_pager_last": "sazikuzay a kasabelih",
+       "table_pager_limit_submit": "mileku",
+       "signature": "[[{{ns:user}}:$1|$2]] ([[{{ns:user_talk}}:$1| sasukamu ]])",
+       "timezone-local": "itizaay",
+       "version": "baziyong",
+       "version-specialpages": "sazumaay a kasabelih",
+       "version-other": "zuma",
+       "version-hooks": "kulawid",
+       "version-hook-subscribedby": "pangangan",
+       "version-skin-colheader-name": "nuhekalan",
+       "version-ext-colheader-version": "baziyong",
+       "version-ext-colheader-description": "patahkal",
+       "version-ext-colheader-credits": "masacudaday",
+       "version-poweredby-others": "zuma",
+       "version-software-product": "nasang’ay a tuutuud",
+       "version-software-version": "baziyong",
+       "version-entrypoints-header-url": "URL",
+       "version-libraries-library": "sulu nu cengse",
+       "version-libraries-version": "baziyong",
+       "version-libraries-description": "patahkal",
+       "version-libraries-authors": "masacudaday",
+       "redirect-submit": "mileku",
+       "fileduplicatesearch-submit": "kilim",
+       "specialpages": "sazumaay a kasabelih",
+       "specialpages-group-login": "patalabu / panganganen ku canghaw",
+       "tag-filter": "[[Special:Tags|aazihen paya]] kilim:",
+       "tag-filter-submit": "kilim",
+       "tag-list-wrapper": "([[Special:Tags|{{PLURAL:$1|aazihen paya’}}]]: $2)",
+       "tags-source-header": "saangangan",
+       "tags-actions-header": "saungay",
+       "tags-active-yes": "hang",
+       "tags-active-no": "caay",
+       "tags-delete": "masipu",
+       "tags-activate": "miteka’",
+       "tags-deactivate": "mapasatezep",
+       "tags-create-reason": "mahicaay:",
+       "tags-create-submit": "patizeng",
+       "tags-delete-reason": "mahicaay:",
+       "tags-activate-reason": "mahicaay:",
+       "tags-activate-submit": "miteka’",
+       "tags-deactivate-reason": "mahicaay:",
+       "tags-edit-reason": "mahicaay:",
+       "compare-submit": "sasutili’ay",
+       "diff-form": "sasizuma",
+       "permanentlink": "saluimengay misiket",
+       "htmlform-submit": "patayzaan",
+       "htmlform-selectorother-other": "zuma",
+       "htmlform-no": "caay",
+       "htmlform-yes": "hang",
+       "htmlform-cloner-delete": "milimad",
+       "htmlform-title-not-exists": "$1 inayi’",
+       "htmlform-user-not-exists": "<strong>$1</strong> inayi’",
+       "logentry-delete-delete": "$1 {{GENDER:$2|masiputu}} kasabelih $3",
+       "restore-count-files": "{{PLURAL:$1|1 tangan}}",
+       "logentry-move-move": "$1 {{GENDER:$2|milimad tuway}} kasabelih $3 katukuh $4",
+       "logentry-newusers-create": "{{GENDER:$2|patizeng}} misaungayay canghaw tuway $1",
+       "logentry-upload-upload": "$1 {{GENDER:$2|masayacay tuway}} $3",
+       "rightsnone": "(nayi’)",
+       "feedback-back": "tatiku",
+       "feedback-cancel": "palawpes",
+       "feedback-close": "pahezek",
+       "feedback-message": "palatuh:",
+       "feedback-subject": "taazihan tu kawaw:",
+       "feedback-submit": "patayzaan",
+       "searchsuggest-search": "kilim {{SITENAME}}",
+       "expand_templates_output": "heci",
+       "expand_templates_ok": "malucekay",
+       "expand_templates_preview": "pataayaway miazih",
+       "pagelang-language": "kamu",
+       "pagelang-reason": "mahicaay:",
+       "pagelang-submit": "patayzaan",
+       "mediastatistics-header-bitmap": "pacepacekan a zunga",
+       "mediastatistics-header-audio": "ludihang",
+       "mediastatistics-header-video": "yiga",
+       "mediastatistics-header-office": "zimusiw",
+       "mediastatistics-header-executable": "kapah tu mileku",
+       "special-characters-group-latin": "u sulit nu Latin",
+       "special-characters-group-symbols": "sawantan",
+       "special-characters-group-greek": "u sulit nu Sila",
+       "special-characters-group-devanagari": "Devanagari a kamu",
+       "special-characters-group-thai": "u sulit nu Tayko",
+       "special-characters-group-lao": "u sulit nu Liau",
+       "special-characters-group-khmer": "u sulit nu Kaomien",
+       "special-characters-title-minus": "selep a bacu",
+       "log-action-filter-all": "hamin",
+       "log-action-filter-block-block": "malangat",
+       "log-action-filter-protect-protect": "midiput",
+       "authprovider-resetpass-skip-label": "sekipo"
+}
index a00d2a7..626cf61 100644 (file)
        "recentchanges-legend-heading": "<strong>شرح:</strong>",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (راجع أيضا [[Special:NewPages|قائمة الصفحات الجديدة]])",
        "recentchanges-submit": "أظهر",
+       "rcfilters-tag-remove": "أزل '$1'",
        "rcfilters-legend-heading": "<strong>قائمة الاختصارات:</strong>",
        "rcfilters-other-review-tools": "<strong>أدوات مراجعة أخرى</strong>",
        "rcfilters-group-results-by-page": "جمع النتائج حسب الصفحة",
        "rcfilters-hours-title": "عدد الساعات الأخيرة",
        "rcfilters-days-show-days": "{{PLURAL:$1|يوما واحدا|يومان|$1 أيام|$1 يوما}}",
        "rcfilters-days-show-hours": "{{PLURAL:$1|ساعة واحدة|ساعتان|$1 ساعات|$1 ساعة}}",
+       "rcfilters-highlighted-filters-list": "معلمة: $1",
        "rcfilters-quickfilters": "المرشحات المحفوظة",
        "rcfilters-quickfilters-placeholder-title": "لا وصلات تم حفظها بعد",
        "rcfilters-quickfilters-placeholder-description": "لحفظ إعدادات الفلتر وإعادة استخدامها في وقت لاحق; انقر فوق رمز الإشارة المرجعية في منطقة الفلتر النشط أدناه.",
        "rcfilters-filterlist-noresults": "لم يتم العثور على مرشحات",
        "rcfilters-noresults-conflict": "لا نتائج تم العثور عليها لأن محددات البحث تعارض بعضها البعض",
        "rcfilters-state-message-subset": "هذا المرشح ليس له تأثير لأن نتائجه متضمنة في {{PLURAL:$2|المرشح التالي|المرشحات التالية}} الأكثر عمومية (جرب التعليم لتمييزه): $1",
-       "rcfilters-state-message-fullcoverage": "اختيار كل المرشحات في مجموعة له نفس التأثير كاختيار لا شيء، لذا فهذا المرشح ليس له تأثير. المجموعة تتضمن: $1",
+       "rcfilters-state-message-fullcoverage": "اختÙ\8aار Ù\83Ù\84 Ø§Ù\84Ù\85رشحات Ù\81Ù\8a Ù\87Ø°Ù\87 Ø§Ù\84Ù\85جÙ\85Ù\88عة Ù\84Ù\87 Ù\86Ù\81س Ø§Ù\84تأثÙ\8aر Ù\83اختÙ\8aار Ù\84ا Ø´Ù\8aØ¡Ø\8c Ù\84ذا Ù\81Ù\87ذا Ø§Ù\84Ù\85رشح Ù\84Ù\8aس Ù\84Ù\87 ØªØ£Ø«Ù\8aر. Ø§Ù\84Ù\85جÙ\85Ù\88عة ØªØªØ¶Ù\85Ù\86: $1",
        "rcfilters-filtergroup-authorship": "ملكية التعديلات",
        "rcfilters-filter-editsbyself-label": "تعديلاتك الشخصية",
        "rcfilters-filter-editsbyself-description": "مساهماتك الشخصية.",
        "rcfilters-filter-watchlist-watchednew-description": "التغييرات التي حدثت على الصفحات التي تراقبها ولم تزرها منذ ذلك الحين.",
        "rcfilters-filter-watchlist-notwatched-label": "ليس في قائمة المراقبة",
        "rcfilters-filter-watchlist-notwatched-description": "كل شيء باستثناء التغييرات في صفحات قائمة مراقبتك.",
+       "rcfilters-filtergroup-watchlistactivity": "نشاط قائمة المراقبة",
+       "rcfilters-filter-watchlistactivity-unseen-label": "تغييرات غير مرئية",
+       "rcfilters-filter-watchlistactivity-unseen-description": "التغييرات للصفحات التي لم تزرها منذ حدوث هذه التغييرات.",
+       "rcfilters-filter-watchlistactivity-seen-label": "التغييرات المرئية",
+       "rcfilters-filter-watchlistactivity-seen-description": "التغييرات للصفحات التي زرتها منذ حدوث هذه التغييرات.",
        "rcfilters-filtergroup-changetype": "نوع التغيير",
        "rcfilters-filter-pageedits-label": "تعديلات الصفحة",
        "rcfilters-filter-pageedits-description": "التعديلات لمحتوى الويكي، النقاشات، وصوفات التصنيفات…",
        "rcfilters-liveupdates-button": "تحديثات حية",
        "rcfilters-liveupdates-button-title-on": "إيقاف التحديثات الحية",
        "rcfilters-liveupdates-button-title-off": "عرض التغييرات الجديدة فور حدوثها",
+       "rcfilters-watchlist-markseen-button": "التعليم على كل التغييرات كمرئية",
+       "rcfilters-watchlist-edit-watchlist-button": "تعديل قائمة الصفحات المراقبة",
        "rcnotefrom": "بالأسفل {{PLURAL:$5|التغيير|التغييرات}} منذ <strong>$2</strong> (إلى <strong>$1</strong> معروضة).",
        "rclistfromreset": "إعادة ضبط خيار التاريخ",
        "rclistfrom": "أظهر التغييرات بدء من $3 $2",
        "apisandbox-sending-request": "إرسال طلب API ...",
        "apisandbox-loading-results": "استقبال طلبات API ...",
        "apisandbox-results-error": "حدث خطأ أثناء تحميل رد استعدلام الAPI: $1.",
+       "apisandbox-results-login-suppressed": "هذا الطلب تمت معالجته كمستخدم مسجل الخروج حيث أنه يمكن استخدامه لتجاوز سرية نفس-الأصل للمتصفح. لاحظ أن معالجة توكين ملعب الAPI لا يعمل بشكل جيد مع مثل هذه الطلبات، من فضلك املأها يدويا.",
        "apisandbox-request-selectformat-label": "عرض بيانات الطلب ك:",
        "apisandbox-request-format-url-label": "سلسلة حروف استعلام المسار",
        "apisandbox-request-url-label": "مسار الطلب:",
        "version-credits-not-found": "لم يتم العثور على أي معلومات للعاملين على هذا الامتداد.",
        "version-poweredby-credits": "تدار هذه الويكي بواسطة '''[https://www.mediawiki.org/ ميدياويكي]'''، حقوق النشر © 2001-$1 $2.",
        "version-poweredby-others": "آخرون",
-       "version-poweredby-translators": "مترجمو translatewiki.net",
+       "version-poweredby-translators": "مترجمو ترانسليت ويكي دوت نت",
        "version-credits-summary": "نود أن نعرف بالأشخاص التالية أسماؤهم لمساهمتهم في [[Special:Version|ميدياويكي]].",
        "version-license-info": "ميدياويكي برنامج حر، يحق لك توزيعه و/أو تعديله وفقاً لبنود رخصة غنو العمومية كما نشرتها مؤسسة البرمجيات الحرة، الإصدار الثاني أو (وفقا لاختيارك أنت) أي إصدار لاحق.\n\nهذا البرنامج يوزع على أمل أن يكون مفيداً، ولكن '''دون أية ضمانات'''، بما في ذلك ضمانات '''التسويق''' أو '''الملاءمة لغرض معين'''. انظر رخصة غنو العمومية لمزيد من التفاصيل.\n\nينبغي أن تكون قد تلقيت نسخة من رخصة غنو العمومية إذا لم يتم ذلك، اكتب إلى: Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA أو [//www.gnu.org/licenses/old-licenses/gpl-2.0.html اقرأ على الإنترنت].",
        "version-software": "البرنامج المثبت",
        "undelete-cantedit": "أنت لا يمكنك استرجاع هذه الصفحة حيث أنه لا يمكنك تعديل هذه الصفحة.",
        "undelete-cantcreate": "أنت لا يمكنك استرجاع هذه الصفحة حيث أنه لا توجد صفحة بهذا الاسم وأنت غير مسموح لك بإنشاء هذه الصفحة.",
        "pagedata-title": "بيانات الصفحة",
+       "pagedata-text": "هذه الصفحة توفر واجهة بيانات للصفحات. من فضلك وفر عنوان الصفحة في المسار، باستخدام صيغة الصفحات الفرعية.\n* تفاوض المحتوى يطبق بناء على الAccept header الخاص بعميلك. هذا يعني أن بيانات الصفحة سيتم توفيرها بالصيغة المفضلة لعميلك.",
        "pagedata-not-acceptable": "لم يتم العثور على هيئة مطابقة. أنماط MIME المدعومة: $1",
        "pagedata-bad-title": "عنوان خاطئ: $1."
 }
index bb82b6e..60607f4 100644 (file)
        "permissionserrorstext": "আপোনাৰ এই কামটো কৰিবলৈ অনুমতি নাই, যাৰ {{PLURAL:$1|কাৰণ|কাৰণসমূহ}} হ'ল:",
        "permissionserrorstext-withaction": "আপোনাৰ $2 কৰিবলৈ অনুমতি নাই, যাৰ {{PLURAL:$1|কাৰণ|কাৰণসমূহ}} হ'ল:",
        "recreate-moveddeleted-warn": "'''সাৱধান: আগতে বিলোপ কৰা পৃষ্ঠা এটা আপুনি পুনঃনিৰ্মাণ কৰি আছে। '''\n\nএই পৃষ্ঠাটো সম্পাদনা কৰা উচিত হব নে নহয় আপুনি বিবেচনা কৰি চাওক।\nএই পৃষ্ঠাটো বিলোপ আৰু স্থানান্তৰ কৰাৰ অভিলেখ আপোনাৰ সুবিধাৰ্থে ইয়াত দিয়া হৈছে।",
-       "moveddeleted-notice": "এই পৃষ্ঠা বিলোপ কৰা হৈছে।\nপৃষ্ঠাৰ বিলোপ আৰু স্থানান্তৰণ অভিলেখ তলত দিয়া হ'ল।",
+       "moveddeleted-notice": "এই পৃষ্ঠা বিলোপ কৰা হৈছে।\nপৃষ্ঠাৰ বিলোপন, সুৰক্ষা আৰু স্থানান্তৰণ অভিলেখ তলত দিয়া হ'ল।",
        "log-fulllog": "সম্পূৰ্ণ অভিলেখ চাওক",
        "edit-hook-aborted": "হুকৰ দ্বাৰা সম্পাদনা প্ৰত্যাখ্যান কৰা হৈছে।\nইয়াৰ কোনো ব্যাখ্যা নাই।",
        "edit-gone-missing": "পৃষ্ঠাটো নবীকৰণ কৰিব পৰা নগ’ল।\nসম্ভৱতঃ পৃষ্ঠাটো বিলোপ কৰা হৈছে।",
        "page_first": "প্ৰথম",
        "page_last": "অন্তিম",
        "histlegend": "পাৰ্থক্য বাছনি: পাৰ্থক্য চাবলৈ সংকলনবোৰৰ সম্মুখত থকা ৰেডিঅ' বুটামবোৰ বাচনী কৰি এণ্টাৰ টিপক অথবা একেবাৰে তলত দিয়া বুটামতো ক্লিক কৰক <br />\nলিজেণ্ড: '''({{int:cur}})''' = বৰ্তমানৰ সংকলনৰ লগত পাৰ্থক্য,\n'''({{int:last}})''' = আগৰ সংকলনৰ লগত পাৰ্থক্য, '''{{int:minoreditletter}}'' = অগুৰুত্বপূৰ্ণ সম্পাদনা।",
-       "history-fieldset-title": "à¦\87তিহাসত à¦\85নà§\81সন্ধান কৰক",
+       "history-fieldset-title": "সà¦\82শà§\8bধিত à¦¸à¦\82সà§\8dà¦\95ৰণ সন্ধান কৰক",
        "history-show-deleted": "মাথোঁ বিলোপ কৰা",
        "histfirst": "আটাইতকৈ পুৰণি",
        "histlast": "শেহতীয়া",
index c5b80ae..d2173a2 100644 (file)
        "retypenew": "Yeni parolu təkrar yazın:",
        "resetpass_submit": "Parol yaradın və sistemə daxil olun",
        "changepassword-success": "Sizin parol uğurla dəyişdirildi!",
+       "botpasswords-label-appid": "Bot adı:",
+       "botpasswords-label-create": "Yarat",
+       "botpasswords-label-update": "Yenilə",
+       "botpasswords-label-cancel": "Ləğv et",
+       "botpasswords-label-delete": "Sil",
        "resetpass_forbidden": "Parolu dəyişmək mümkün deyil",
        "resetpass-no-info": "Bu səhifəni birbaşa açmaq üçün sistemə daxil olmalısınız.",
        "resetpass-submit-loggedin": "Parolu dəyiş",
        "userrights-changeable-col": "Dəyişdirə bildiyiniz qruplar",
        "userrights-unchangeable-col": "Dəyişdirə bilmədiyiniz qruplar",
        "userrights-irreversible-marker": "$1*",
+       "userrights-expiry-othertime": "Başqa vaxt:",
        "group": "Qrup:",
        "group-user": "İstifadəçilər",
        "group-autoconfirmed": "Avtotəsdiqlənmiş istifadəçilər",
        "right-userrights-interwiki": "Digər vikilərdəki istifadəçilərin istifadəçi hüquqlarını dəyişdir",
        "right-siteadmin": "Məlumatlar bazasının bloklanması və blokun götürülməsi",
        "right-sendemail": "Digər istifadəçilərə elektron poçt göndər",
+       "grant-group-email": "E-məktub göndər",
        "grant-editmywatchlist": "İzləmə siyahınızda redaktə",
        "newuserlogpage": "Yeni istifadəçilərin qeydiyyatı",
        "newuserlogpagetext": "Yeni qeydiyyatdan keçmiş istifadəçilərin siyahısı.",
        "recentchanges-label-plusminus": "Səhifənin ölçüsündəki dəyişiklik (baytlarla)",
        "recentchanges-legend-heading": "<strong>Legenda:</strong>",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (həmçinin bax: [[Special:NewPages|yeni səhifələrin siyahısı]])",
+       "recentchanges-submit": "Göstər",
+       "rcfilters-savedqueries-new-name-label": "Ad",
+       "rcfilters-savedqueries-cancel-label": "Ləğv et",
+       "rcfilters-filterlist-title": "Filtrlər",
+       "rcfilters-filter-bots-label": "Bot",
+       "rcfilters-filter-minor-label": "Kiçik redaktələr",
        "rcnotefrom": "Aşağıda <strong>$2</strong>-dən bu yana olan dəyişikliklər göstərilib (<strong>$1</strong>-dən çox olmayaraq).",
        "rclistfrom": "$3 $2 vaxtından başlayaraq yeni dəyişiklikləri göstər",
        "rcshowhideminor": "Kiçik redaktələri $1",
        "upload-http-error": " HTTP xətası var : $1",
        "upload-dialog-title": "Fayl yüklə",
        "upload-dialog-button-cancel": "İmtina",
+       "upload-dialog-button-back": "Əvvəlki",
        "upload-dialog-button-done": "Oldu",
        "upload-dialog-button-save": "Qeyd et",
        "upload-dialog-button-upload": "Yüklə",
        "fewestrevisions": "Az dəyişiklik edilmiş məqalələr",
        "nbytes": "$1 {{PLURAL:$1|bayt|bayt}}",
        "ncategories": "$1 {{PLURAL:$1|kateqoriya|kateqoriya}}",
+       "ninterwikis": "$1 {{PLURAL:$1|interviki|intervikilər}}",
        "nlinks": "$1 {{PLURAL:$1|keçid|keçid}}",
        "nmembers": "$1 {{PLURAL:$1|üzv|üzv}}",
+       "nmemberschanged": "$1 → $2 {{PLURAL:$2|üzv|üzvlər}}",
        "nrevisions": "$1 dəyişiklik",
        "nimagelinks": "$1 səhifədə istifadə olunmur",
        "ntransclusions": "$1 səhifədə istifadə olunur",
        "mostimages": "Ən çox istifadə edilmiş şəkillər",
        "mostrevisions": "Ən çox nəzərdən keçirilmiş (versiyalı) məqalələr",
        "prefixindex": "Prefiks indeksli bütün səhifələr",
+       "prefixindex-submit": "Göstər",
        "shortpages": "Qısa səhifələr",
        "longpages": "Uzun səhifələr",
        "deadendpages": "Keçid verməyən səhifələr",
        "protectedpages-cascade": "Yalnız kaskad mühafizələr",
        "protectedpagesempty": "Hal-hazırda bu parametrə uyğun heç bir mühafizəli səhifə yoxdur",
        "protectedpages-page": "Səhifə",
+       "protectedpages-reason": "Səbəb",
        "protectedpages-unknown-timestamp": "Naməlum",
        "protectedtitles": "Mühafizəli başlıqlar",
        "listusers": "İstifadəçi siyahısı",
        "usereditcount": "$1 {{PLURAL:$1|redaktə}}",
        "usercreated": "Saat $2, $1 tarixində {{GENDER:$3|qeydiyyatdan keçib}}",
        "newpages": "Yeni səhifələr",
+       "newpages-submit": "Göstər",
        "newpages-username": "İstifadəçi adı:",
        "ancientpages": "Ən köhnə səhifələr",
        "move": "Adını dəyiş",
        "specialloguserlabel": "İcraçı:",
        "speciallogtitlelabel": "Məqsəd (başlıq və ya istifadəçi):",
        "log": "Qeydlər",
+       "logeventslist-submit": "Göstər",
        "all-logs-page": "Bütün ictimai qeydlər",
        "alllogstext": "{{SITENAME}} üçün bütün mövcud qeydlərin birgə göstərişi.\nQeyd növü, istifadəçi adı və ya təsir edilmiş səhifəni seçməklə daha spesifik ola bilərsiniz.",
        "logempty": "Jurnalda uyğun qeyd tapılmadı.",
        "allpagesprefix": "Bu prefiksli səhifələri göstər:",
        "allpages-hide-redirects": "Yönləndirmələri gizlət",
        "categories": "Kateqoriyalar",
+       "categories-submit": "Göstər",
        "categoriespagetext": "Aşağıdakı {{PLURAL:$1|kateqoriyada|kateqoriyalarda}} səhifələr, yaxud media-fayllar var.\n[[Special:UnusedCategories|İstifadə olunmayan kateqoriyalar]] burada göstərilməyib.\nHəmçinin, [[Special:WantedCategories|tələb olunan kateqoriyalara]] baxın.",
        "deletedcontributions": "Silinmiş istifadəçi fəaliyyətləri",
        "deletedcontributions-title": "Silinmiş istifadəçi fəaliyyətləri",
        "wlheader-showupdated": "Son ziyarətinizdən sonra edilən dəyişikliklər '''qalın şriftlərlə''' göstərilmişdir.",
        "wlnote": "Aşağıdakı {{PLURAL:$1|'''$1''' dəyişiklik|'''$1''' dəyişiklik}} son {{PLURAL:$2|saatda|'''$2''' saatda}} edilmişdir.",
        "wlshowlast": "Son $1 saatı $2 günü göstər",
+       "watchlist-hide": "Gizlət",
+       "watchlist-submit": "Göstər",
+       "wlshowhideminor": "kiçik redaktələr",
+       "wlshowhidebots": "botlar",
        "wlshowhidemine": "mənimn redaktələrim",
        "watchlist-options": "İzləmə siyahısının nizamlamaları",
        "watching": "İzlənilir...",
        "enotif_lastdiff": "Bu dəyişikliyi görmək üçün $1 səhifəsinə baxın.",
        "enotif_anon_editor": "qeydiyyatsız istifadəçi $1",
        "enotif_body": "Hörmətli $WATCHINGUSERNAME,\n\n{{SITENAME}} veb-saytındakı $PAGETITLE adlı səhifə $PAGEEDITDATE tarixində $PAGEEDITOR tərəfindən $CHANGEDORCREATED. Səhifənin sonuncu versiyasına baxmaq üçün $PAGETITLE_URL keçidindən istifadə edin.\n\n$NEWPAGE\n\nDəyişikliyi edən istifadəçinin izahı: $PAGESUMMARY $PAGEMINOREDIT\n\nSəhifəni dəyişdirən istifadəçinin əlaqə məlumatları:\ne-poçt: $PAGEEDITOR_EMAIL\nviki: $PAGEEDITOR_WIKI\n\nSiz haqqında söhbət gedən səhifəyə baxanadək səhifədəki digər dəyişikliklərlə bağlı başqa bildiriş məktubu almayacaqsınız. Siz həmçinin, izləmə siyahınızdakı bütün səhifələrlə bağlı bildiriş məlumatlarını silə bilərsiniz.\n\n               {{SITENAME}} saytının xəbərdarlıq sistemi.\n\n--\nİzləmə siyahısının tənzimləmələrini dəyişmək üçün:\n{{canonicalurl:Special:Watchlist/edit}}\n\nYardım və təklifləriniz üçün:\n$HELPPAGE",
+       "enotif_minoredit": "Bu kiçik redaktədir",
        "created": "yaradıldı",
        "changed": "dəyişdi",
        "deletepage": "Səhifəni sil",
        "unblocked-range": "$1-nin bloku götürüldü",
        "unblocked-id": "$1-nin bloku götürüldü",
        "blocklist": "Bloklanmış istifadəçilər",
+       "autoblocklist": "Avtobloklar",
+       "autoblocklist-submit": "Axtar",
+       "autoblocklist-legend": "Avtoblokların siyahısı",
+       "autoblocklist-localblocks": "Lokal {{PLURAL:$1|avtoblok|avtobloklar}}",
+       "autoblocklist-otherblocks": "Digər {{PLURAL:$1|avtoblok|avtobloklar}}",
        "ipblocklist": "Bloklanmış istifadəçilər",
        "ipblocklist-legend": "Bloklanmış istifadəçini axtar",
        "blocklist-userblocks": "Hesab bloklarını gizlət",
        "pageinfo-length": "Səhifənin ölçüsü (baytla)",
        "pageinfo-article-id": "Səhifə ID-si",
        "pageinfo-language": "Səhifənin dili",
+       "pageinfo-language-change": "dəyiş",
        "pageinfo-content-model": "Səhifə məzmunu modeli",
+       "pageinfo-content-model-change": "dəyiş",
        "pageinfo-robot-policy": "Robotlar tərəfindən indeksləşmə",
        "pageinfo-robot-index": "İcazə verilir",
        "pageinfo-robot-noindex": "İcazə verilmədi",
index b4b348b..0207a06 100644 (file)
        "rcfilters-empty-filter": "Няма актыўных фільтраў. Паказаны ўвесь унёсак.",
        "rcfilters-filterlist-title": "Фільтры",
        "rcfilters-filterlist-whatsthis": "Як гэта працуе?",
-       "rcfilters-filterlist-feedbacklink": "Ð\9fакÑ\96нÑ\83Ñ\86Ñ\8c Ð²Ð¾Ð´Ð³Ñ\83к Ð¿Ñ\80а Ð½Ð¾Ð²Ñ\8bÑ\8f (бÑ\8dÑ\82а) фільтры",
+       "rcfilters-filterlist-feedbacklink": "РаÑ\81кажÑ\8bÑ\86е Ð½Ð°Ð¼, Ñ\88Ñ\82о Ð²Ñ\8b Ð´Ñ\83маеÑ\86е Ð¿Ñ\80а Ð³Ñ\8dÑ\82Ñ\8bÑ\8f (новÑ\8bÑ\8f) фільтры",
        "rcfilters-highlightbutton-title": "Вылучыць вынікі",
        "rcfilters-highlightmenu-title": "Абярыце колер",
        "rcfilters-highlightmenu-help": "Абярыце колер для вылучэньня гэтай уласьцівасьці",
        "rcfilters-filter-watchlistactivity-unseen-label": "Непрагледжаныя зьмены",
        "rcfilters-filter-watchlistactivity-unseen-description": "Зьмены старонак, якія вы не наведвалі пасьля гэтых зьменаў.",
        "rcfilters-filter-watchlistactivity-seen-label": "Прагледжаныя зьмены",
+       "rcfilters-filter-watchlistactivity-seen-description": "Зьмены старонак, якія вы наведвалі пасьля гэтых зьменаў.",
        "rcfilters-filtergroup-changetype": "Тып зьмены",
        "rcfilters-filter-pageedits-label": "Рэдагаваньні старонкі",
        "rcfilters-filter-pageedits-description": "Рэдагаваньні вікізьместу, абмеркаваньняў, апісаньняў катэгорыяў…",
        "rcfilters-liveupdates-button": "Імгненныя абнаўленьні",
        "rcfilters-liveupdates-button-title-on": "Адключыць аўтаматычнае абнаўленьне",
        "rcfilters-liveupdates-button-title-off": "Паказваць новыя зьмены як толькі яны адбываюцца",
+       "rcfilters-watchlist-markseen-button": "Пазначыць усе зьмены як прагледжаныя",
+       "rcfilters-watchlist-edit-watchlist-button": "Рэдагаваць ваш сьпіс назіраньня за старонкамі",
+       "rcfilters-watchlist-showupdated": "Зьмены старонак, якія вы не наведвалі пасьля гэтых зьменаў, пазначаныя <strong>тоўстым</strong> з адпаведнымі пазнакамі.",
        "rcnotefrom": "Ніжэй {{PLURAL:$5|знаходзіцца зьмена|знаходзяцца зьмены}} з <strong>$4 $3</strong> (да <strong>$1</strong> на старонку).",
        "rclistfromreset": "Скінуць выбар даты",
        "rclistfrom": "Паказаць зьмены з $2 $3",
        "unwatchthispage": "Перастаць назіраць",
        "notanarticle": "Не старонка зьместу",
        "notvisiblerev": "Вэрсія была выдаленая",
-       "watchlist-details": "У Ð\92аÑ\88Ñ\8bм Ñ\81Ñ\8cпÑ\96Ñ\81е Ð½Ð°Ð·Ñ\96Ñ\80анÑ\8cнÑ\8f $1 {{PLURAL:$1|Ñ\81Ñ\82аÑ\80онка|Ñ\81Ñ\82аÑ\80онкÑ\96\81Ñ\82аÑ\80онак}} Ð·Ð° Ð²Ñ\8bклÑ\8eÑ\87Ñ\8dнÑ\8cнем Ñ\81Ñ\82аÑ\80онак Ð°Ð±Ð¼ÐµÑ\80каванÑ\8cнÑ\8f.",
+       "watchlist-details": "У Ð²Ð°Ñ\88Ñ\8bм Ñ\81Ñ\8cпÑ\96Ñ\81е Ð½Ð°Ð·Ñ\96Ñ\80анÑ\8cнÑ\8f $1 {{PLURAL:$1|Ñ\81Ñ\82аÑ\80онка|Ñ\81Ñ\82аÑ\80онкÑ\96\81Ñ\82аÑ\80онак}} (плÑ\8eÑ\81 Ñ\81Ñ\82аÑ\80онкÑ\96 Ñ\80азмоваÑ\9e).",
        "wlheader-enotif": "Апавяшчэньне па e-mail уключанае.",
        "wlheader-showupdated": "Старонкі, зьмененыя з часу вашага апошняга візыту, вылучаныя '''тоўстым''' шрыфтам.",
        "wlnote": "Ніжэй {{PLURAL:$1|паказаная <strong>$1</strong> апошняя зьмена|паказаныя <strong>$1</strong> апошнія зьмены|паказаныя <strong>$1</strong> апошніх зьменаў}} за <strong>$2</strong> {{PLURAL:$2|гадзіну|гадзіны|гадзінаў}}, па стане на $4 $3.",
        "enotif_lastdiff": "Глядзіце $1, каб пабачыць гэтую зьмену.",
        "enotif_anon_editor": "ананімны ўдзельнік $1",
        "enotif_body": "Вітаем, $WATCHINGUSERNAME.\n\n$PAGEINTRO $NEWPAGE\n\nАпісаньне зьменаў: $PAGESUMMARY $PAGEMINOREDIT\n\nЗьвязацца з рэдактарам:\nпраз электронную пошту: $PAGEEDITOR_EMAIL\nпразь вікі-старонку: $PAGEEDITOR_WIKI\n\nПаведамленьні ня будуць дасылацца ў выпадку новых дзеяньняў, пакуль Вы не наведаеце гэтую старонку па ўваходзе ў сыстэму. Вы таксама можаце адключыць паведамленьні пра зьмены для ўсіх старонак з Вашага сьпісу назіраньня.\n\n             Сыстэма паведамленьняў {{GRAMMAR:родны|{{SITENAME}}}}\n\n--\nКаб зьмяніць налады абвяшчэньня праз электронную пошту, наведайце:\n{{canonicalurl:{{#special:Preferences}}}}\n\nКаб зьмяніць налады сьпісу назіраньня, наведайце:\n{{canonicalurl:{{#special:Preferences}}}}\n\nКаб выдаліць старонку з Вашага сьпісу назіраньня, наведайце:\n$UNWATCHURL\n\nЗваротная сувязь і дапамога:\n$HELPPAGE",
+       "enotif_minoredit": "Гэта дробная праўка",
        "created": "створаная",
        "changed": "зьмененая",
        "deletepage": "Выдаліць старонку",
        "delete-warning-toobig": "Гэтая старонка мае доўгую гісторыю рэдагаваньняў, больш за $1 {{PLURAL:$1|вэрсію|вэрсіі|вэрсіяў}}.\nЯе выдаленьне можа выклікаць праблемы ў працы базы зьвестак {{GRAMMAR:родны|{{SITENAME}}}}; будзьце асьцярожны.",
        "deleteprotected": "Вы ня можаце выдаліць гэтую старонку, таму што яна абароненая.",
        "deleting-backlinks-warning": "<strong>Увага:</strong> [[Special:WhatLinksHere/{{FULLPAGENAME}}|іншыя старонкі]] ўключаюць або спасылаюцца на старонку, якую вы зьбіраецеся выдаліць.",
+       "deleting-subpages-warning": "<strong>Папярэджаньне:</strong> старонка, якую вы зьбіраецеся выдаліць, мае [[Special:PrefixIndex/{{FULLPAGENAME}}/|{{PLURAL:$1|$1 падстаронку|$1 падстаронкі|$1 падстаронак|51=болей за 50 падстаронак}}]].",
        "rollback": "Адкаціць рэдагаваньні",
        "rollbacklink": "адкат",
        "rollbacklinkcount": "адкаціць $1 {{PLURAL:$1|рэдагаваньне|рэдагаваньні|рэдагаваньняў}}",
        "redirect-submit": "Перайсьці",
        "redirect-lookup": "Шукаць паводле:",
        "redirect-value": "Значэньне:",
-       "redirect-user": "Ідэнтыфікатара ўдзельніка",
-       "redirect-page": "Ідэнтыфікатар старонкі",
+       "redirect-user": "Ідэнтыфікатару ўдзельніка",
+       "redirect-page": "Ідэнтыфікатару старонкі",
        "redirect-revision": "Вэрсіі старонкі",
-       "redirect-file": "Ð\86мÑ\8f Ñ\84айла",
+       "redirect-file": "Ð\9dазва Ñ\84айлÑ\83",
        "redirect-logid": "ID журнала",
        "redirect-not-exists": "Значэньне ня знойдзена",
        "fileduplicatesearch": "Пошук дублікатаў файлаў",
        "fileduplicatesearch-noresults": "Файл з назвай «$1» ня знойдзены.",
        "specialpages": "Спэцыяльныя старонкі",
        "specialpages-note-top": "Легенда",
+       "specialpages-note-restricted": "* Звычайныя спэцыяльныя старонкі.\n* <span class=\"mw-specialpagerestricted\">Спэцыяльныя старонкі з абмежаваным доступам.</span>",
        "specialpages-group-maintenance": "Тэхнічныя справаздачы",
        "specialpages-group-other": "Іншыя спэцыяльныя старонкі",
        "specialpages-group-login": "Уваход / стварэньне рахунку",
        "compare-title-not-exists": "Пазначаная старонка не існуе.",
        "compare-revision-not-exists": "Пазначаная вэрсія не існуе.",
        "diff-form": "Адрозьненьні",
+       "diff-form-oldid": "Ідэнтыфікатар старой вэрсіі (неабавязкова)",
+       "diff-form-revid": "Ідэнтыфікатар вэрсіі з адрозьненьнямі",
+       "diff-form-submit": "Паказаць адрозьненьні",
        "dberr-problems": "Прабачце! На гэтым сайце ўзьніклі тэхнічныя цяжкасьці.",
        "dberr-again": "Паспрабуйце пачакаць некалькі хвілінаў і абнавіць.",
        "dberr-info": "(Немагчыма злучыцца з базай зьвестак: $1)",
index df73812..f443e19 100644 (file)
        "cannotloginnow-title": "Не може да влезете сега",
        "cannotloginnow-text": "Влизането не е възможно, когато се използва $1.",
        "cannotcreateaccount-title": "Невъзможно е да бъде създадена потребителска сметка",
-       "cannotcreateaccount-text": "Директното създаване на сметки не е позволено в това Уики.",
+       "cannotcreateaccount-text": "Директното създаване на сметки не е позволено в това уики.",
        "yourdomainname": "Вашият домейн:",
        "password-change-forbidden": "Не можете да променяте пароли в това уики.",
        "externaldberror": "Възникна грешка в базата от данни при външното удостоверяване, или не ви е позволено да обновявате външната си сметка.",
        "recentchangescount": "Брой показвани редакции по подразбиране:",
        "prefs-help-recentchangescount": "Това включва последните промени, историите на страниците и дневниците.",
        "savedprefs": "Настройките ви бяха съхранени.",
+       "savedrights": "Потребителските групи на {{GENDER:$1|$1}} са запазени.",
        "timezonelegend": "Часова зона:",
        "localtime": "Местно време:",
        "timezoneuseserverdefault": "По подразбиране от уикито ($1)",
index 9f20ded..6812863 100644 (file)
        "linksearch-pat": "অনুসন্ধান প্যাটার্ন:",
        "linksearch-ns": "নামস্থান:",
        "linksearch-ok": "অনুসন্ধান",
-       "linksearch-text": "\"*.wikipedia.org\" à¦\8fর à¦®à¦¤ à¦\93য়াà¦\87লà§\8dড à¦\95ারà§\8dড à¦¬à§\8dযবহার à¦\95রা à¦¯à§\87তà§\87 à¦ªà¦¾à¦°à§\87।\nনà§\82নà§\8dযতম à¦\8fà¦\95à¦\9fি à¦\9fপ à¦²à§\87ভà§\87ল à¦¡à§\8bমà§\87à¦\87ন à¦ªà§\8dরয়à§\8bà¦\9cন, à¦¯à§\87মন \"*.org\"।<br />\nযà§\87 à¦¸à¦\95ল {{PLURAL:$2|পà§\8dরà§\8bà¦\9fà§\8bà¦\95ল|পà§\8dরà§\8bà¦\9fà§\8bà¦\95লসমà§\82হ}} à¦¸à¦®à¦°à§\8dথন à¦\95রà§\87: $1 (পà§\8dরà§\8bà¦\9fà§\8bà¦\95ল à¦\89লà§\8dলà§\87à¦\96 à¦\95রা à¦¨à¦¾ à¦¹à¦²à§\87 http:// à¦¡à¦¿à¦«à¦²à§\8dà¦\9f à¦¹à¦¿à¦¸à¦¾à¦¬à§\87 ব্যবহৃত হবে)।",
+       "linksearch-text": "\"*.wikipedia.org\" à¦\8fর à¦®à¦¤ à¦\93য়াà¦\87লà§\8dড à¦\95ারà§\8dড à¦¬à§\8dযবহার à¦\95রা à¦¯à§\87তà§\87 à¦ªà¦¾à¦°à§\87।\nনà§\82নà§\8dযতম à¦\8fà¦\95à¦\9fি à¦¶à§\80রà§\8dষ à¦¸à§\8dতরà§\87র à¦¡à§\8bমà§\87à¦\87ন à¦ªà§\8dরয়à§\8bà¦\9cন, à¦¯à§\87মন \"*.org\"।<br />\nযà§\87 à¦¸à¦\95ল {{PLURAL:$2|পà§\8dরà§\8bà¦\9fà§\8bà¦\95ল|পà§\8dরà§\8bà¦\9fà§\8bà¦\95লসমà§\82হ}} à¦¸à¦®à¦°à§\8dথন à¦\95রà§\87: $1 (পà§\8dরà§\8bà¦\9fà§\8bà¦\95ল à¦\89লà§\8dলà§\87à¦\96 à¦\95রা à¦¨à¦¾ à¦¹à¦²à§\87 à¦¡à¦¿à¦«à¦²à§\8dà¦\9f à¦¹à¦¿à¦¸à¦¾à¦¬à§\87 http:// ব্যবহৃত হবে)।",
        "linksearch-line": "$2 থেকে $1 এ লিংক করা হয়েছে",
        "linksearch-error": "হোস্ট নামের শুরুতে কেবলমাত্র ওয়াইল্ডকার্ড ব্যবহার করা যায়।",
        "listusersfrom": "সেই সব ব্যবহারকারী দেখাও যাদের নাম এই অক্ষর দিয়ে শুরু:",
index d58caf3..941f9af 100644 (file)
        "recentchanges-legend-heading": "<strong>Alc'hwez :</strong>",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (gwelet ivez [[Special:NewPages|roll ar pajennoù nevez]])",
        "recentchanges-submit": "Diskouez",
+       "rcfilters-tag-remove": "Dilemel '$1'",
+       "rcfilters-group-results-by-page": "Strollañ an disoc'hoù dre bajenn",
+       "rcfilters-grouping-title": "O strollañ",
        "rcfilters-activefilters": "Siloù oberiant",
-       "rcfilters-quickfilters": "Liammoù prim",
+       "rcfilters-days-title": "Deizioù paseet",
+       "rcfilters-hours-title": "Eurioù paseet",
+       "rcfilters-days-show-days": "($1 {{PLURAL:$1|deiz}})",
+       "rcfilters-days-show-hours": "$1 {{PLURAL:$1|eur}}",
+       "rcfilters-highlighted-filters-list": "Lakaet war wel : $1",
+       "rcfilters-quickfilters": "Siloù enrollet",
+       "rcfilters-quickfilters-placeholder-title": "Liamm ebet enrollet evit c'hoazh",
        "rcfilters-savedqueries-defaultlabel": "Siloù enrollet",
        "rcfilters-savedqueries-rename": "Adenvel",
        "rcfilters-savedqueries-setdefault": "Gweredekaat dre ziouer",
        "rcfilters-noresults-conflict": "N'eus bet kavet disoc'h ebet rak dezverkoù klask kontrol zo",
        "rcfilters-state-message-subset": "Ar sil-mañ ne ra netra rak kavet e vez e zisoc'hoù e-mesk ar {{PLURAL:$2|sil|siloù}} klask da heul (klaskit e lakaat war wel evit diforc'han anezhañ) : $1",
        "rcfilters-state-message-fullcoverage": "Diuzañ an holl siloù en ur strollad zo evel diuzañ netra, setu ne raio ket netra ar sil-mañ. Er strollad emañ : $1",
-       "rcfilters-filtergroup-registration": "Enskrivadur an implijer",
-       "rcfilters-filter-registered-label": "Marilhet",
-       "rcfilters-filter-registered-description": "Aozerien gevreet.",
-       "rcfilters-filter-unregistered-label": "Divarilh",
-       "rcfilters-filter-unregistered-description": "Aozerien n'int ket kevreet.",
-       "rcfilters-filter-unregistered-conflicts-user-experience-level": "Tabut zo etre ar sil-mañ hag ar {{PLURAL:$2|sil|siloù}} Arroutet, na {{PLURAL:$2|gav|gavont}} nemet an implijerien enrollet : $1",
        "rcfilters-filtergroup-authorship": "Aozer ar c'hemmoù",
        "rcfilters-filter-editsbyself-label": "Kemmet ganeoc'h",
        "rcfilters-filter-editsbyself-description": "Ar c'hemmoù graet ganeoc'h.",
        "rcfilters-filter-editsbyother-label": "Kemmet gant tud all",
        "rcfilters-filter-editsbyother-description": "An holl gemmoù nemet ar re graet ganeoc'h.",
        "rcfilters-filtergroup-userExpLevel": "Live skiant-prenañ (evit an implijer enrollet hepken)",
-       "rcfilters-filtergroup-user-experience-level-conflicts-unregistered": "Ar siloù Arroutet ne gavont nemet implijerien enrollet, se zo kaoz zo tabut etre ar sil-mañ hag ar sil \"Dienroll\".",
-       "rcfilters-filtergroup-user-experience-level-conflicts-unregistered-global": "Emañ ar sil \"Dienroll\" o tabutal gant gant ur sil Arroutet pe gant meur a hini. Ar siloù Arroutet a gav implijerien enrollet hepken. Ar siloù o tabutal zo merket en takad Siloù oberiant a-us.",
+       "rcfilters-filter-user-experience-level-registered-label": "Marilhet",
+       "rcfilters-filter-user-experience-level-registered-description": "Aozerien gevreet.",
+       "rcfilters-filter-user-experience-level-unregistered-label": "Divarilh",
+       "rcfilters-filter-user-experience-level-unregistered-description": "Aozerien n'int ket kevreet.",
        "rcfilters-filter-user-experience-level-newcomer-label": "Tud nevez-deuet",
        "rcfilters-filter-user-experience-level-newcomer-description": "Nebeutoc'h eget 10 kemm ha 4 devezh obererezh.",
        "rcfilters-filter-user-experience-level-learner-label": "Deskarded",
        "fileduplicatesearch-noresults": "N'eus bet kavet restr ebet anvet \"$1\".",
        "specialpages": "Pajennoù dibar",
        "specialpages-note-top": "Alc'hwez",
-       "specialpages-note": "* Pajennoù dibar ordinal.\n* <span class=\"mw-specialpagerestricted\">Pajennoù dibar miret strizh.</span>",
        "specialpages-group-maintenance": "Rentaoù-kont trezalc'h",
        "specialpages-group-other": "Pajennoù dibar all",
        "specialpages-group-login": "Kevreañ / krouiñ ur gont",
        "compare-invalid-title": "Kamm eo an titl hoc'h eus merket.",
        "compare-title-not-exists": "N'eus ket eus an titl spisaet ganeoc'h.",
        "compare-revision-not-exists": "N'eus ket eus an adweladenn spisaet ganeoc'h.",
+       "diff-form": "ur '''furmskrid'''",
        "dberr-problems": "Ho tigarez ! Kudennoù teknikel zo gant al lec'hienn-mañ.",
        "dberr-again": "Gortozit un nebeud munutennoù a-raok adkargañ.",
        "dberr-info": "(Dibosupl kevreañ ouzh an diaz roadennoù : $1)",
index 3cecdd7..d99bf55 100644 (file)
        "hidden-category-category": "Categories ocultes",
        "category-subcat-count": "{{PLURAL:$2|Aquesta categoria només té la següent subcategoria.|Aquesta categoria conté {{PLURAL:$1|la següent subcategoria|les següents $1 subcategories}}, d'un total de $2.}}",
        "category-subcat-count-limited": "Aquesta categoria conté {{PLURAL:$1|la següent subcategoria|les següents $1 subcategories}}.",
-       "category-article-count": "{{PLURAL:$2|Aquesta categoria només té la següent pàgina.|{{PLURAL:$1|La següent pàgina és|Les següents $1 pàgines són}} dins d'aquesta categoria, d'un total de $2.}}",
+       "category-article-count": "{{PLURAL:$2|Aquesta categoria només té la pàgina següent.|{{PLURAL:$1|La pàgina següent és|Les $1 pàgines següents són}} dins d’aquesta categoria, d’un total de $2.}}",
        "category-article-count-limited": "{{PLURAL:$1|La següent pàgina és|Les següents $1 pàgines són}} dins la categoria actual.",
-       "category-file-count": "{{PLURAL:$2|Aquesta categoria només té el següent fitxer.|{{PLURAL:$1|El següent fitxer és|Els següents $1 fitxers són}} dins d'aquesta categoria, d'un total de $2.}}",
+       "category-file-count": "{{PLURAL:$2|Aquesta categoria només té el fitxer següent.|{{PLURAL:$1|El fitxer següent és|Els $1 fitxers següents són}} dins d’aquesta categoria, d’un total de $2.}}",
        "category-file-count-limited": "{{PLURAL:$1|El següent fitxer és|Els següents $1 fitxers són}} dins la categoria actual.",
        "listingcontinuesabbrev": " cont.",
        "index-category": "Pàgines indexades",
index d150323..39267bf 100644 (file)
        "clearyourcache": "'''注意:'''保存以後,汝可能固著刷新汝其瀏覽器緩存來看遘變化。\n* '''火狐/Safari:'''擪下''Shift''篤蜀篤''重新載入'',或者擪蜀擪''Ctrl+F5''或者''Ctrl+R'' (''⌘-R''敆Mac懸頂)\n* '''Google Chrome:'''擪''Ctrl+Shift+R''(敆Mac𡅏使''⌘-Shift-R'')\n* '''Internet Explorer:'''擪''Ctrl''其時候篤蜀篤''刷新'',或者擪''Ctrl+F5''\n* '''Opera:'''敆''工具→首選項''𡅏清除緩存",
        "note": "<strong>注意:</strong>",
        "previewnote": "'''記定茲若是蜀萆預覽。'''\n汝其改變固𡅏未保存!",
-       "continue-editing": "行去編輯區",
+       "continue-editing": "繼續修改",
        "editing": "修改 $1",
        "creating": "創建$1",
        "editingsection": "修改$1(段)",
index b46df0f..57d2a7a 100644 (file)
@@ -39,7 +39,7 @@
        "tog-enotifminoredits": "Хаам бо зӀе чухул, цхьа жимма а хийцамаш биняхь",
        "tog-enotifrevealaddr": "Гайта сан зlе оцу хаамаш барехь",
        "tog-shownumberswatching": "Гайта декъашхойн терахь, агӀо латийна болу шай тергаме могӀанан юкъа",
-       "tog-oldsig": "Карара куьгтаӀорна:",
+       "tog-oldsig": "Карара хьан куьг:",
        "tog-fancysig": "Шен вики-къастаман куьгтаӀдар (ша шех хьажорг йоцуш)",
        "tog-uselivepreview": "Лелае чехка хьалха хьажар",
        "tog-forceeditsummary": "Дага даийта, нагахь нисйарх лаьцна чохь язйина яцахь",
        "nosuchspecialpage": "Иштта белхан агӀо яц",
        "nospecialpagetext": "<strong>Иштта белхан агӀо яц.</strong>\n\nБелхан агӀонийн могӀам: [[Special:SpecialPages|{{int:specialpages}}]].",
        "error": "ГӀалат",
-       "databaseerror": "Ð\93Ó\80алаÑ\82 Ñ\85аамийн Ð±Ñ\83Ñ\85еÑ\80а",
+       "databaseerror": "Хаамийн Ð±Ð°Ð·Ð°Ð½ Ð³Ó\80алаÑ\82",
        "databaseerror-text": "Хаамийн базан гӀалат даьлла.\nИза хила мега программин гӀалат.",
        "databaseerror-textcl": "Хаамийн базан гӀалат даьлла.",
        "databaseerror-query": "Дехар: $1",
        "readonly_lag": "Хаамашан базина цхьана хан блоктоьхна, хаамашан базан сервераш нисялца.",
        "internalerror": "Чоьхьара гӀалат",
        "internalerror_info": "Чоьхьара гӀалат: $1",
+       "internalerror-fatal-exception": "Нисдан цало юкъарадаккхар «$1» тайпана",
        "filecopyerror": "Йиш яц копий ян «$1» оцунах «$2».",
        "filerenameerror": "Файлан «$1» цӀе хийца «$2» йиш яц.",
        "filedeleteerror": "ДӀаяккха цатарло файл «$1».",
        "recentchanges-legend-heading": "<strong>Легенда:&nbsp;</strong>",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (хьажа кхин [[Special:NewPages|керла агӀонийн могӀа]])",
        "recentchanges-submit": "Гайта",
-       "rcfilters-savedqueries-defaultlabel": "Ӏалашъе луьттург",
+       "rcfilters-other-review-tools": "<strong>Талларан кхин гӀирсаш</strong>",
+       "rcfilters-group-results-by-page": "Карийнарш, агӀонгахь тобанаш ян",
+       "rcfilters-grouping-title": "Тобанашца нисъяр",
+       "rcfilters-activefilters": "Жигара литтарш",
+       "rcfilters-limit-title": "Гойту хийцамаш",
+       "rcfilters-limit-shownum": "Гайта тӀеххьара {{PLURAL:$1|хийцам}}",
+       "rcfilters-days-title": "ТӀеххьара денош",
+       "rcfilters-hours-title": "ТӀеххьара сахьташ",
+       "rcfilters-days-show-days": "$1 {{PLURAL:$1|де}}",
+       "rcfilters-days-show-hours": "$1 {{PLURAL:$1|сахьт}}",
+       "rcfilters-quickfilters": "Ӏалашдина литтарш",
+       "rcfilters-quickfilters-placeholder-description": "Литтаран буламаш (хьайна) Ӏалашбан лаахь а, йуха уьш лелабан лаахь а, тӀетаӀйе \"жигара литтаран\" уллера хьаьрка.",
+       "rcfilters-savedqueries-defaultlabel": "Ӏалашдина литтарш",
        "rcfilters-savedqueries-rename": "ЦӀе хийцар",
        "rcfilters-savedqueries-setdefault": "Ӏадйитаран кеп хӀоттае",
        "rcfilters-savedqueries-unsetdefault": "Ӏадйитаран кеп дӀаяккха",
        "rcfilters-savedqueries-add-new-title": "Ӏалашде литтар нисъяр",
        "rcfilters-restore-default-filters": "Литтарш Ӏадйитаран кепе меттахӀоттае",
        "rcfilters-clear-all-filters": "Ерриге литтарш цӀанъян",
+       "rcfilters-show-new-changes": "ТӀеххьара хийцамаш",
+       "rcfilters-search-placeholder": "Литтаран керла хийцамаш лахар",
        "rcfilters-filterlist-title": "Литтарш",
+       "rcfilters-filterlist-feedbacklink": "Керла (бета) литтарех лаьцна хьайна хеттарг язде",
+       "rcfilters-highlightbutton-title": "Билгалде карийнарш",
+       "rcfilters-highlightmenu-help": "Билгалонан бос харжа",
        "rcfilters-filterlist-noresults": "Литтарш цакарий",
        "rcfilters-filtergroup-authorship": "Нисде авторалла",
        "rcfilters-filter-editsbyself-label": "Хьан дисдарш",
        "rcfilters-filter-editsbyself-description": "Хьан нисдарш.",
        "rcfilters-filter-editsbyother-label": "Кхечу декъашхойн нисдарш",
+       "rcfilters-filtergroup-userExpLevel": "Декъашхочун регистраци а, цуна зеделларг а",
        "rcfilters-filter-user-experience-level-registered-label": "Регистрацийинарш",
+       "rcfilters-filter-user-experience-level-registered-description": "Чубаьлла декъашхой.",
        "rcfilters-filter-user-experience-level-unregistered-label": "Регистрацицайинарш",
+       "rcfilters-filter-user-experience-level-unregistered-description": "Системин чубалаза декъашхой.",
        "rcfilters-filter-user-experience-level-newcomer-label": "Керланиш",
+       "rcfilters-filter-user-experience-level-newcomer-description": "10 нисдар дина а, 4 дийнахь болх бина а регистрацийина декъашхой",
        "rcfilters-filter-user-experience-level-learner-label": "Доьшуш берш",
+       "rcfilters-filtergroup-automated": "Авто-къинхьегам",
        "rcfilters-filter-bots-label": "Бот",
+       "rcfilters-filter-bots-description": "Авто-гӀирсашца дина нисдарш.",
+       "rcfilters-filter-humans-label": "Адам ду (бот яц)",
+       "rcfilters-filter-humans-description": "Декъашхоша дина нисдарш.",
        "rcfilters-filter-patrolled-label": "Патрулйина",
+       "rcfilters-filtergroup-significance": "МаьӀна",
+       "rcfilters-filter-minor-label": "Жим нисдарш",
+       "rcfilters-filter-minor-description": "Авторс жима ду аьлла билгалдина нисдарш.",
+       "rcfilters-filter-major-label": "Гуттарлера нисдарш",
+       "rcfilters-filter-major-description": "Жима санна билгалдаза нисдарш.",
+       "rcfilters-filtergroup-watchlist": "Тергаме могӀаман юкъара агӀонаш",
+       "rcfilters-filter-watchlist-watched-label": "Тергаме могӀамехь",
+       "rcfilters-filter-watchlist-watched-description": "Хьан тергаме могӀамехь болу хийцамаш.",
+       "rcfilters-filter-watchlist-watchednew-label": "Тергаме могӀаман керла хийцамаш",
+       "rcfilters-filter-watchlist-watchednew-description": "Хьан тергаме могӀаман юкъара хьуна гина боцу хийцамаш.",
+       "rcfilters-filter-watchlist-notwatched-label": "Тергаме могӀаман юкъахь яц",
+       "rcfilters-filter-watchlist-notwatched-description": "Ерриге, хьан тергаме могӀаман юкъахь ерш ца гойту.",
+       "rcfilters-filtergroup-changetype": "Хийцамийн тайпа",
+       "rcfilters-filter-pageedits-label": "АгӀонан нисдарш",
+       "rcfilters-filter-pageedits-description": "Дийцарийн а, категорийн а чулацаман дина нисдарш...",
+       "rcfilters-filter-newpages-label": "АгӀонаш кхоллар",
+       "rcfilters-filter-newpages-description": "АгӀонаш кхуллуш дина нисдарш.",
+       "rcfilters-filter-categorization-label": "Категорийн хийцамаш",
+       "rcfilters-filter-categorization-description": "Категорийн, агӀонаш тӀетохар а, дӀаяхар а.",
+       "rcfilters-filter-logactions-label": "Урхаллица динарш",
+       "rcfilters-filter-logactions-description": "Куьйгалхоша динарг, дӀабазбалар, агӀонаш дӀаяхар, файлаш чуяхар...",
        "rcfilters-filtergroup-lastRevision": "Карара верси",
        "rcfilters-filter-lastrevision-label": "Карара верси",
        "rcfilters-filter-lastrevision-description": "АгӀона уггаре тӀеххьара хийцамаш.",
        "rcfilters-filter-previousrevision-label": "Хьалхара версеш",
+       "rcfilters-filter-previousrevision-description": "Дерриге нисдарш, «тӀеххьара верси» йоцу.",
        "rcfilters-filter-excluded": "ДӀаяьккхина",
        "rcfilters-tag-prefix-namespace-inverted": "<strong>:not</strong> $1",
+       "rcfilters-view-advanced-filters-label": "Шуьйра литтарш",
        "rcfilters-view-tags": "Билгалонаш",
+       "rcfilters-view-namespaces-tooltip": "Меттигийн цӀерашца литтаран карийнарш",
+       "rcfilters-view-tags-tooltip": "Нисдарийн билгало йолу литтаран карийна хийцамаш",
        "rcnotefrom": "Лахахь гайтина тӀера <strong>$2</strong> (хийцамаш <strong>$1</strong> кӀезиг).",
        "rclistfromreset": "Терахь харжар дӀадаккха",
        "rclistfrom": "Гайта хийцам {{CURRENTYEAR}} шеран {{CURRENTDAY}} {{CURRENTMONTHNAMEGEN}} {{CURRENTTIME}} бина болу",
        "uctop": "(карара)",
        "month": "Баттачохь (я хьалхе):",
        "year": "Шерачохь (я хьалхе):",
-       "sp-contributions-newbies": "Ð\93айÑ\82а Ð±ÐµÐºÑ\8a ÐºÑ\8aинÑ\85Ñ\8cегам, ÐºÐµÑ\80ла Ð´lабазбинаÑ\87аÑ\80а Ð±Ð¸Ð½Ð° Ð±Ð¾Ð»Ñ\83",
+       "sp-contributions-newbies": "Ð\9aеÑ\80ла Ð´ÐµÐºÑ\8aаÑ\88Ñ\85ойн ÐºÑ\8aинÑ\85Ñ\8cегам Ð±ÐµÐ½ Ð¼Ð° Ð³Ð°Ð¹Ñ\82а",
        "sp-contributions-newbies-sub": "Керла декъашхойн дӀаяздаршкара",
        "sp-contributions-newbies-title": "Дукху хан йоцуш кхоьллинчу декъашхойн дӀаяздарийн къинхьегам",
        "sp-contributions-blocklog": "блоктоьхнарш",
        "newimages-summary": "ХӀокху белхан агӀона чохь гойтуш ю дукха хан йоццуш чуяьхна файлаш.",
        "newimages-legend": "Луьттург",
        "newimages-user": "Декъашхочун цӀе я IP-адрес",
+       "newimages-newbies": "Керла декъашхойн къинхьегам бен ма гайта",
        "newimages-showbots": "Гайта боташ чуяьхна файлаш",
        "newimages-hidepatrolled": "Къайлаяха патруль йина файлаш",
        "newimages-mediatype": "Медиа тайпа:",
        "exif-whitebalance-0": "Къайн автоматически баланс",
        "exif-whitebalance-1": "Куьйга хӀоттийна къайн баланс",
        "exif-scenecapturetype-0": "Стандартан",
+       "exif-scenecapturetype-1": "Ландшафт",
+       "exif-scenecapturetype-2": "Сурт",
        "exif-scenecapturetype-3": "Буса даьккхина сурт",
        "exif-gaincontrol-0": "Яц",
        "exif-gaincontrol-1": "ГӀеххьа доккха дар",
        "htmlform-cloner-create": "ТӀетоха кхин",
        "htmlform-cloner-delete": "ДӀаяккха",
        "htmlform-date-placeholder": "ШШШШ-ББ-ДД",
+       "htmlform-time-placeholder": "СС:ММ:СС",
        "htmlform-datetime-placeholder": "ШШШШ-ББ-ДД СС:ММ:СС",
        "htmlform-title-not-exists": "«$1» яц.",
        "htmlform-user-not-exists": "<strong>$1</strong> яц.",
        "pagelang-language": "Мотт",
        "pagelang-use-default": "Ӏадйитаран кепаца мотт",
        "pagelang-select-lang": "Харжа мотт",
+       "pagelang-reason": "Бахьана",
        "pagelang-submit": "ДӀадахьийта",
+       "pagelang-nonexistent-page": "$1 агӀо яц.",
        "right-pagelang": "АгӀона мотт хийца",
        "action-pagelang": "агӀона мотт хийца",
        "log-name-pagelang": "Мотт хийцаран тептар",
        "date-range-to": "Терхье:",
        "sessionprovider-generic": "$1 сесси",
        "randomrootpage": "Цахууш нисъелла ораман агӀо",
+       "log-action-filter-block-block": "Блоктохар",
+       "log-action-filter-block-reblock": "Блоктохар хийцар",
+       "log-action-filter-block-unblock": "БлокдӀаяхарш",
+       "log-action-filter-rights-autopromote": "Авто хийцар",
+       "log-action-filter-upload-upload": "Керла чудаккхар",
+       "log-action-filter-upload-overwrite": "Юху чуяккха",
+       "authmanager-email-label": "Электронан пошт",
        "authmanager-provider-temporarypassword": "Ханна пароль",
        "changecredentials": "Декъашхочун дӀаяздаран хийцам",
        "removecredentials": "ДӀадаха декъашхойн дӀаяздарш",
index 7435ca6..11d151f 100644 (file)
        "revdelete-restricted": "ئەو سنووری بەرگریانەی خستراوەتە سەر بەڕێوبەران",
        "revdelete-unrestricted": "ئەو سنووری بەرگریانەی لابردراوە لە سەر بەڕێوبەران",
        "logentry-block-block": "$1 {{GENDER:$4|$3}}ی بۆ ماوەی $5 {{GENDER:$2|بەربەست کرد}} $6",
+       "logentry-import-upload": "$1 {{GENDER:$2|بارکرد}} $3 بە بەکارھێنانی [[special:Import|بارکەر]]",
        "logentry-move-move": "$1 پەڕەی $3ی {{GENDER:$2|گواستەوە}} بۆ $4",
        "logentry-move-move-noredirect": "$1 پەڕەی $3ی بە بێ بەجێھشتنی ڕەوانەکەرێک {{GENDER:$2|گواستەوە}} بۆ $4",
        "logentry-move-move_redir": "$1 پەڕەی $3 {{GENDER:$2|گواستەوە}} بۆ $4 کە پێشتر ڕەوانەکەر بوو",
index 05b8b2e..f9a4353 100644 (file)
        "rcfilters-empty-filter": "Žádné aktivní filtry. Zobrazeny jsou všechny příspěvky.",
        "rcfilters-filterlist-title": "Filtry",
        "rcfilters-filterlist-whatsthis": "Jak to funguje?",
-       "rcfilters-filterlist-feedbacklink": "Poskytnout novým (beta) filtrům zpětnou vazbu",
+       "rcfilters-filterlist-feedbacklink": "Řekněte nám, co si myslíte o těchto (nových) filtrech",
        "rcfilters-highlightbutton-title": "Zvýraznit výsledky",
        "rcfilters-highlightmenu-title": "Vybrat barvu",
        "rcfilters-highlightmenu-help": "Vyberte barvu pro zvýraznění této vlastnosti",
        "rcfilters-filter-watchlist-notwatched-description": "Vše kromě změn vašich sledovaných stránek.",
        "rcfilters-filtergroup-watchlistactivity": "Aktivita ve sledovaných stránkách",
        "rcfilters-filter-watchlistactivity-unseen-label": "Nezobrazené změny",
-       "rcfilters-filter-watchlistactivity-unseen-description": "Změny stránek, které jste od jejich změny nenavštívili",
+       "rcfilters-filter-watchlistactivity-unseen-description": "Změny stránek, které jste od jejich změny nenavštívili.",
        "rcfilters-filter-watchlistactivity-seen-label": "Zobrazené změny",
-       "rcfilters-filter-watchlistactivity-seen-description": "Změny stránek, které jste od jejich změny nenavštívili.",
+       "rcfilters-filter-watchlistactivity-seen-description": "Změny stránek, které jste od jejich změny již navštívili.",
        "rcfilters-filtergroup-changetype": "Typ změny",
        "rcfilters-filter-pageedits-label": "Editace stránek",
        "rcfilters-filter-pageedits-description": "Editace obsahu wiki, diskusí, popisů kategorií…",
        "rcfilters-liveupdates-button": "Živé aktualizace",
        "rcfilters-liveupdates-button-title-on": "Vypnout živé aktualizace",
        "rcfilters-liveupdates-button-title-off": "Zobrazovat nové změny, jakmile jsou zveřejněny",
-       "rcfilters-watchlist-markSeen-button": "Označit všechny změny jako zkontrolované",
+       "rcfilters-watchlist-markseen-button": "Označit všechny změny jako zkontrolované",
+       "rcfilters-watchlist-edit-watchlist-button": "Editovat seznam sledovaných stránek",
+       "rcfilters-watchlist-showupdated": "Změny stránek, které jste od provedení změn nenavštívili, jsou zobrazeny <strong>tučně</strong> s vyplněnou značkou.",
        "rcnotefrom": "Níže {{PLURAL:$5|je změna|jsou změny}} od <strong>$3, $4</strong> ({{PLURAL:$1|zobrazena|zobrazeny|zobrazeno}} nejvýše <strong>$1</strong>).",
        "rclistfromreset": "Obnovit výběr data",
        "rclistfrom": "Ukázat nové změny, počínaje od $2, $3",
        "unwatchthispage": "Nesledovat tuto stránku",
        "notanarticle": "Toto není stránka",
        "notvisiblerev": "Verze byla smazána",
-       "watchlist-details": "Na vašem seznamu sledovaných stránek {{PLURAL:$1|je $1 stránka|jsou $1 stránky|je $1 stránek}}, nepočítaje v to diskusní stránky.",
+       "watchlist-details": "Na vašem seznamu sledovaných stránek {{PLURAL:$1|je $1 stránka|jsou $1 stránky|je $1 stránek}} (a k tomu diskusní stránky).",
        "wlheader-enotif": "Upozorňování e-mailem je zapnuto.",
-       "wlheader-showupdated": "Stránky, které se změnily od vaší poslední návštěvy, jsou zobrazeny '''tučně'''.",
+       "wlheader-showupdated": "Stránky, které se změnily od vaší poslední návštěvy, jsou zobrazeny <strong>tučně</strong>.",
        "wlnote": "Níže {{PLURAL:$1|je poslední změna|jsou poslední <strong>$1</strong> změny|je posledních <strong>$1</strong> změn}} za {{PLURAL:$2|poslední hodinu|poslední <strong>$2</strong> hodiny|posledních <strong>$2</strong> hodin}} do $4, $3.",
        "wlshowlast": "Ukázat posledních $1 hodin $2 dnů",
        "watchlist-hide": "Skrýt",
index 71b6189..1f118bb 100644 (file)
        "botpasswords-label-delete": "Slet",
        "botpasswords-label-resetpassword": "Nulstil adgangskode",
        "botpasswords-label-grants": "Tilgængelige bevillinger:",
+       "botpasswords-label-grants-column": "Tildelt",
+       "botpasswords-bad-appid": "Robotnavnet »$1« er ikke gyldigt.",
+       "botpasswords-insert-failed": "Kunne ikke tilføje robotnavnet »$1«. Var det allerede tilføjet?",
+       "botpasswords-update-failed": "Kunne ikke tilføje robotnavnet »$1«. Er det slettet?",
        "botpasswords-created-title": "Botkodeord oprettet",
+       "botpasswords-created-body": "Robottens adgangskode for robotnavn »$1« for bruger »$2« blev oprettet.",
        "botpasswords-updated-title": "Bot kodeord opdateret",
        "botpasswords-deleted-title": "Bot kodeord slettet",
        "resetpass_forbidden": "Adgangskoder kan ikke ændres",
        "search-external": "Brug anden søgemaskine",
        "searchdisabled": "<p>Beklager! Fuldtekstsøgningen er midlertidigt afbrudt på grund af for stor belastning på serverne. I mellemtidem kan du anvende Google- eller Yahoo!-søgefelterne herunder. Bemærk at deres kopier af {{SITENAME}}s indhold kan være forældet.</p>",
        "search-error": "Der opstod en fejl under søgning: $1",
+       "search-warning": "Der opstod en advarsel under søgning: $1",
        "preferences": "Indstillinger",
        "mypreferences": "Indstillinger",
        "prefs-edits": "Antal redigeringer:",
        "prefs-editwatchlist-clear": "Ryd din overvågningsliste",
        "prefs-watchlist-days": "Antal dage der skal vises i overvågningslisten:",
        "prefs-watchlist-days-max": "Højst $1 {{PLURAL:$1|dag|dage}}",
-       "prefs-watchlist-edits": "Antal redigeringer der vises i udvidet overvågningsliste:",
+       "prefs-watchlist-edits": "Maksimalt antal redigeringer der vises i overvågningsliste:",
        "prefs-watchlist-edits-max": "Maks. 1000",
        "prefs-watchlist-token": "Overvågningslistenøgle:",
        "prefs-misc": "Forskelligt",
        "prefs-editing": "Redigering",
        "searchresultshead": "Søgeresultater",
        "stub-threshold": "Grænse før formatering af stublink ($1):",
+       "stub-threshold-sample-link": "eksempel",
        "stub-threshold-disabled": "Deaktiveret",
        "recentchangesdays": "Antal dage som skal vises i seneste ændringer:",
        "recentchangesdays-max": "(maks. $1 {{PLURAL:$1|dag|dage}})",
        "prefs-help-recentchangescount": "Det gælder for seneste ændringer, historikker og logger.",
        "prefs-help-watchlist-token2": "Dette er den hemmelige nøgle til web-feed af din overvågningsliste.\nHvis andre kender den, vil man være i stand til at læse din overvågningsliste, så del den ikke.\n[[Special:ResetTokens|Klik her hvis du har brug at nulstille den]].",
        "savedprefs": "Dine indstillinger er blevet gemt.",
+       "savedrights": "Brugergrupperne for {{GENDER:$1|$1}} er blevet gemt.",
        "timezonelegend": "Tidszone:",
        "localtime": "Lokaltid:",
        "timezoneuseserverdefault": "Brug wiki'ens standardindstilling ($1)",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (se også [[Special:NewPages|listen over nye sider]])",
        "recentchanges-legend-plusminus": "(''±123'')",
        "recentchanges-submit": "Vis",
+       "rcfilters-tag-remove": "Fjern »$1«",
+       "rcfilters-legend-heading": "<strong>Liste over forkortelser:</strong>",
+       "rcfilters-other-review-tools": "<strong>Andre gennemgangsværktøjer</strong>",
        "rcfilters-group-results-by-page": "Grupper resultater efter side",
        "rcfilters-grouping-title": "Gruppering",
        "rcfilters-activefilters": "Aktive filtre",
        "rcfilters-advancedfilters": "Avancerede filtre",
        "rcfilters-limit-title": "Ændringer som skal vises",
+       "rcfilters-limit-shownum": "Vis seneste {{PLURAL:$1|ændring|$1 ændringer}}",
        "rcfilters-days-title": "De sidste dage",
        "rcfilters-hours-title": "De sidste timer",
        "rcfilters-days-show-days": "$1 {{PLURAL:$1|dag|dage}}",
        "rcfilters-filter-watchlist-watchednew-description": "Ændringer af overvågede sider du ikke har besøgt siden ændringerne blev gjort.",
        "rcfilters-filter-watchlist-notwatched-label": "Ikke på overvågningsliste",
        "rcfilters-filter-watchlist-notwatched-description": "Alt undtagen ændringer af sider på din overvågningsliste.",
+       "rcfilters-filter-watchlistactivity-unseen-label": "Usete ændringer",
+       "rcfilters-filter-watchlistactivity-seen-label": "Sete ændringer",
        "rcfilters-filtergroup-changetype": "Type ændring",
        "rcfilters-filter-pageedits-label": "Sideredigeringer",
        "rcfilters-filter-pageedits-description": "Ændringer af wikiindhold, diskussioner, kategoribeskrivelser...",
        "rcfilters-filter-lastrevision-description": "Den nyeste ændring af en side.",
        "rcfilters-filter-previousrevision-label": "Tidligere revisioner",
        "rcfilters-filter-previousrevision-description": "Alle ændringer som ikke er den nyeste ændring af en side.",
+       "rcfilters-view-advanced-filters-label": "Avancerede filtre",
+       "rcfilters-view-tags": "Mærkede redigeringer",
+       "rcfilters-view-namespaces-tooltip": "Filtrer resultater efter navnerum",
        "rcnotefrom": "Nedenfor er op til '''$1''' {{PLURAL:$5|ændring|ændringer}} siden '''$2''' vist.",
        "rclistfromreset": "Nulstil datovalg",
        "rclistfrom": "Vis nye ændringer startende fra den $3 kl. $2",
        "changecontentmodel-title-label": "Sidetitel",
        "changecontentmodel-model-label": "Ny indholdsmodel",
        "changecontentmodel-reason-label": "Begrundelse:",
+       "changecontentmodel-emptymodels-title": "Ingen indholdsmodeller er tilgængelige",
+       "changecontentmodel-emptymodels-text": "Indholdet på [[:$1]] kan ikke konverteres til en anden type.",
        "protectlogpage": "Skrivebeskyttelseslog",
        "protectlogtext": "Herunder er en liste over ændringer til sidebeskyttelser.\nSe [[Special:ProtectedPages|listen over beskyttede sider]] for listen over sidebeskyttelser, der er i kraft i øjeblikket.",
        "protectedarticle": "[[$1]] beskyttet",
        "newimages-legend": "Filter",
        "newimages-label": "Filnavn (eller en del af det):",
        "newimages-user": "IP-adresse eller brugernavn",
+       "newimages-newbies": "Vis kun bidrag fra nye konti",
        "newimages-showbots": "Vis oplægninger af robotter",
        "newimages-hidepatrolled": "Skjul patruljerede uploads",
+       "newimages-mediatype": "Medietype:",
        "noimages": "Ingen filer fundet.",
        "gallery-slideshow-toggle": "Til- eller fravælg thumbnails",
        "ilsubmit": "Søg",
        "confirmemail_body_set": "En person, sandsynligvis dig, har fra IP-adressen $1,\nangivet denne e-mailadresse til kontoen \"$2\" på {{SITENAME}}.\n\nFor at bekræfte, at denne konto virkelig tilhører dig og aktivere\ne-mailfunktionerne på {{SITENAME}}, åbn dette link i din browser:\n\n$3\n\nHvis kontoen *ikke* tilhører dig, så følg dette link\nfor at annullere e-mailadressens bekræftelse:\n\n$5\n\nDenne bekræftelseskode vil udløbe den $4.",
        "confirmemail_invalidated": "E-mail-bekræftelse afvist",
        "invalidateemail": "Cancel e-mail confirmation",
+       "notificationemail_subject_changed": "Registreret e-postadresse for {{SITENAME}} er blevet ændret",
+       "notificationemail_subject_removed": "Registreret e-postadresse på {{SITENAME}} er blevet fjernet",
        "scarytranscludedisabled": "[Interwiki-tilkobling er deaktiveret]",
        "scarytranscludefailed": "[Hentning af skabelon for $1 mislykkedes]",
        "scarytranscludefailed-httpstatus": "[Hentning af skabelon for $1 mislykkedes: HTTP $2]",
        "watchlistedit-clear-titles": "Sider:",
        "watchlistedit-clear-submit": "Ryd overvågningslisten (dette er permanent!)",
        "watchlistedit-clear-done": "Din overvågningsliste er blevet ryddet.",
+       "watchlistedit-too-many": "Der er for mange sider til, at de kan vises her.",
        "watchlisttools-clear": "Ryd overvågningsliste",
        "watchlisttools-view": "Se ændrede sider i overvågningslisten",
        "watchlisttools-edit": "Rediger overvågningsliste",
        "tags-activate": "aktiver",
        "tags-deactivate": "deaktiver",
        "tags-hitcount": "{{PLURAL:$1|en ændring|$1 ændringer}}",
+       "tags-create-tag-name": "Mærkenavn:",
        "tags-create-reason": "Årsag:",
        "tags-create-submit": "Opret",
+       "tags-create-no-name": "Du skal angive et mærkenavn.",
        "tags-create-already-exists": "Mærket »$1« findes allerede.",
+       "tags-delete-title": "Slet mærke",
+       "tags-delete-explanation-initial": "Du er ved at slette mærket »$1« fra databasen.",
        "tags-delete-reason": "Årsag:",
+       "tags-activate-title": "Aktiver mærke",
+       "tags-activate-question": "Du er ved at aktivere mærket »$1«.",
        "tags-activate-reason": "Årsag:",
+       "tags-activate-not-allowed": "Det er ikke muligt at aktivere mærket »$1«.",
+       "tags-activate-not-found": "Mærket »$1« findes ikke.",
        "tags-activate-submit": "Aktiver",
+       "tags-deactivate-title": "Deaktiver mærke",
+       "tags-deactivate-question": "Du er ved at deaktivere mærket »$1«.",
        "tags-deactivate-reason": "Årsag:",
+       "tags-deactivate-not-allowed": "Det er ikke muligt at deaktivere mærket »$1«.",
        "tags-deactivate-submit": "Deaktiver",
+       "tags-apply-no-permission": "Du har ikke rettigheder til at anvende ændringsmærker sammen med dine ændringer.",
+       "tags-update-blocked": "Du kan ikke tilføje eller fjerne ændringsmærker mens {{GENDER:$1|du}} er blokeret.",
+       "tags-edit-title": "Rediger mærker",
+       "tags-edit-manage-link": "Håndter mærker",
        "tags-edit-existing-tags": "Eksisterende mærker:",
        "tags-edit-existing-tags-none": "<em>Ingen</em>",
        "tags-edit-new-tags": "Nye mærker:",
        "mw-widgets-titleinput-description-new-page": "side eksisterer ikke endnu",
        "mw-widgets-titleinput-description-redirect": "omdiriger til $1",
        "mw-widgets-categoryselector-add-category-placeholder": "Tilføj en kategori...",
+       "mw-widgets-usersmultiselect-placeholder": "Tilføj flere ...",
        "date-range-from": "Fra dato:",
        "date-range-to": "Til dato:",
+       "sessionmanager-tie": "Kan ikke kombinere flere forespørgselgodkendelsetyper: $1.",
+       "sessionprovider-generic": "$1 sessioner",
        "randomrootpage": "Tilfældig stamside",
        "log-action-filter-block": "Blokeringstype:",
        "log-action-filter-delete": "Sletningstype:",
        "log-action-filter-protect-modify": "Ændring af beskyttelse",
        "log-action-filter-protect-unprotect": "Fjernede beskyttelse",
        "log-action-filter-protect-move_prot": "Flyttede beskyttelse",
+       "log-action-filter-upload-upload": "Ny overførsel",
+       "authmanager-create-from-login": "For at oprette din konto, så udfyld venligst felterne.",
+       "authmanager-email-label": "E-post",
+       "authmanager-email-help": "E-postadresse",
        "authmanager-provider-temporarypassword": "Midlertidig adgangskode",
+       "specialpage-securitylevel-not-allowed-title": "Ikke tilladt",
        "cannotauth-not-allowed-title": "Adgang nægtet",
        "cannotauth-not-allowed": "Du har ikke tilladelse til at bruge denne side",
+       "removecredentials": "Fjern akkreditiver",
+       "removecredentials-submit": "Fjern akkreditiver",
+       "removecredentials-invalidsubpage": "$1 er ikke en gyldig type for akkreditiver.",
+       "removecredentials-success": "Dine akkreditiver er blevet fjernet.",
+       "credentialsform-provider": "Akkreditivtype:",
        "credentialsform-account": "Kontonavn:"
 }
index c4c6984..a719fb6 100644 (file)
@@ -72,6 +72,7 @@
        "yourdomainname": "Ihre Domain:",
        "password-change-forbidden": "Sie können auf diesem Wiki keine Passwörter ändern.",
        "externaldberror": "Entweder liegt ein Fehler bei der externen Authentifizierung vor oder Sie dürfen Ihr externes Benutzerkonto nicht aktualisieren.",
+       "login-security": "Verifizieren Sie Ihre Identität",
        "userlogin-noaccount": "Sie haben noch kein Benutzerkonto?",
        "userlogin-loggedin": "Sie sind bereits als {{GENDER:$1|$1}} angemeldet.\nBenutzen Sie das unten stehende Formular, um sich unter einem anderen Benutzernamen anzumelden.",
        "createacct-email-ph": "Geben Sie Ihre E-Mail-Adresse ein",
index adda8db..4e4a469 100644 (file)
@@ -89,7 +89,8 @@
                        "Predatorix",
                        "Matma Rex",
                        "ThePiscin",
-                       "Osnard"
+                       "Osnard",
+                       "Suriyaa Kudo"
                ]
        },
        "tog-underline": "Links unterstreichen:",
        "tog-extendwatchlist": "Alle und nicht nur die aktuellsten Änderungen in der Beobachtungsliste anzeigen",
        "tog-usenewrc": "Änderungen auf „Letzte Änderungen“ und der Beobachtungsliste nach Seite gruppieren",
        "tog-numberheadings": "Überschriften automatisch nummerieren",
-       "tog-showtoolbar": "Bearbeiten-Werkzeugleiste aktivieren",
+       "tog-showtoolbar": "Bearbeiten-Werkzeugleiste anzeigen",
        "tog-editondblclick": "Seiten mit Doppelklick bearbeiten",
        "tog-editsectiononrightclick": "Einzelne Abschnitte per Rechtsklick bearbeiten",
        "tog-watchcreations": "Selbst erstellte Seiten und hochgeladene Dateien automatisch beobachten",
        "rcfilters-empty-filter": "Keine aktiven Filter. Es werden alle Beiträge angezeigt.",
        "rcfilters-filterlist-title": "Filter",
        "rcfilters-filterlist-whatsthis": "Wie funktioniert das?",
-       "rcfilters-filterlist-feedbacklink": "Rückmeldung zu den neuen (Beta-)Filtern hinterlassen",
+       "rcfilters-filterlist-feedbacklink": "Erzähle uns, was du über diese (neuen) Filterwerkzeuge denkst.",
        "rcfilters-highlightbutton-title": "Ergebnisse hervorheben",
        "rcfilters-highlightmenu-title": "Eine Farbe auswählen",
        "rcfilters-highlightmenu-help": "Eine Farbe auswählen, um diese Eigenschaft hervorzuheben.",
        "rcfilters-liveupdates-button": "Live-Aktualisierungen",
        "rcfilters-liveupdates-button-title-on": "Live-Aktualisierungen ausschalten",
        "rcfilters-liveupdates-button-title-off": "Neue Änderungen bei Auftreten anzeigen",
-       "rcfilters-watchlist-markSeen-button": "Alle Änderungen als gesehen markieren",
+       "rcfilters-watchlist-markseen-button": "Alle Änderungen als gesehen markieren",
+       "rcfilters-watchlist-edit-watchlist-button": "Deine Liste der beobachteten Seiten bearbeiten",
+       "rcfilters-watchlist-showupdated": "Änderungen an Seiten, die du seit ihrem Auftreten nicht besucht hast, sind <strong>fett</strong> markiert.",
        "rcnotefrom": "Angezeigt {{PLURAL:$5|wird die Änderung|werden die Änderungen}} seit <strong>$3, $4</strong> (max. <strong>$1</strong> Einträge).",
        "rclistfromreset": "Datumsauswahl zurücksetzen",
        "rclistfrom": "Nur Änderungen seit $3, $2 Uhr zeigen.",
        "unwatchthispage": "Nicht mehr beobachten",
        "notanarticle": "Keine Seite",
        "notvisiblerev": "Version wurde gelöscht",
-       "watchlist-details": "Du beobachtest {{PLURAL:$1|eine Seite|$1 Seiten}}, ohne dass Diskussionsseiten getrennt gezählt werden.",
+       "watchlist-details": "{{PLURAL:$1|Eine Seite ist|$1 Seiten sind}} auf deiner Beobachtungsliste (sowie Diskussionsseiten).",
        "wlheader-enotif": "Der E-Mail-Benachrichtigungsdienst ist aktiviert.",
        "wlheader-showupdated": "Seiten mit noch nicht gesehenen Änderungen werden '''fett''' dargestellt.",
        "wlnote": "Es {{PLURAL:$1|folgt die letzte Änderung|folgen die letzten <strong>$1</strong> Änderungen}} der letzten {{PLURAL:$2|Stunde|<strong>$2</strong> Stunden}}. Stand: $3, $4 Uhr.",
index 62bbc75..9a8983b 100644 (file)
        "semiprotectedpagewarning": "'''Σημείωση:''' Αυτή η σελίδα έχει κλειδωθεί ώστε μόνο εγγεγραμμένοι χρήστες μπορούν να την επεξεργαστούν.\nΗ πιο πρόσφατη καταχώρηση στο αρχείο καταγραφής παρέχεται παρακάτω για αναφορά:",
        "cascadeprotectedwarning": "<strong>Προσοχή:</strong> Αυτή η σελίδα έχει κλειδωθεί ώστε μόνο χρήστες με [[Special:ListGroupRights|συγκεκριμένα δικαιώματα]] να μπορούν να την επεξεργαστούν, επειδή περιλαμβάνεται {{PLURAL:$1|στην ακόλουθη|στις ακόλουθες}} διαδοχικά (cascaded) {{PLURAL:$1|προστατευμένη σελίδα|προστατευμένες σελίδες}}:",
        "titleprotectedwarning": "'''Προειδοποίηση: Αυτή η σελίδα έχει κλειδωθεί ώστε χρειάζονται [[Special:ListGroupRights|ειδικά δικαιώματα]] για να δημιουργηθεί.'''\nΗ πιο πρόσφατη καταχώρηση στο αρχείο καταγραφής παρέχεται παρακάτω για αναφορά:",
-       "templatesused": "{{PLURAL:$1|Πρότυπο που χρησιμοποιείται|Πρότυπα που χρησιμοποιούνται}} στη σελίδα αυτή:",
-       "templatesusedpreview": "{{PLURAL:$1|Πρότυπο που χρησιμοποιείται|Πρότυπα που χρησιμοποιούνται}} σε αυτήν την προεπισκόπηση:",
+       "templatesused": "{{PLURAL:$1|Πρότυπο που χρησιμοποιείται|Πρότυπα που χρησιμοποιούνται}} σε αυτή τη σελίδα:",
+       "templatesusedpreview": "{{PLURAL:$1|Πρότυπο που χρησιμοποιείται|Πρότυπα που χρησιμοποιούνται}} σε αυτή την προεπισκόπηση:",
        "templatesusedsection": "{{PLURAL:$1|Πρότυπο|Πρότυπα}} που χρησιμοποιούνται σε αυτή την ενότητα:",
        "template-protected": "(προστατευμένη)",
        "template-semiprotected": "(ημιπροστατευμένη)",
index a44b3cf..a22e3f0 100644 (file)
        "rcfilters-empty-filter": "No active filters. All contributions are shown.",
        "rcfilters-filterlist-title": "Filters",
        "rcfilters-filterlist-whatsthis": "How do these work?",
-       "rcfilters-filterlist-feedbacklink": "Provide feedback on the new (beta) filters",
+       "rcfilters-filterlist-feedbacklink": "Tell us what you think about these (new) filtering tools",
        "rcfilters-highlightbutton-title": "Highlight results",
        "rcfilters-highlightmenu-title": "Select a color",
        "rcfilters-highlightmenu-help": "Select a color to highlight this property",
        "rcfilters-liveupdates-button": "Live updates",
        "rcfilters-liveupdates-button-title-on": "Turn off live updates",
        "rcfilters-liveupdates-button-title-off": "Display new changes as they happen",
-       "rcfilters-watchlist-markSeen-button": "Mark all changes as seen",
+       "rcfilters-watchlist-markseen-button": "Mark all changes as seen",
+       "rcfilters-watchlist-edit-watchlist-button": "Edit your list of watched pages",
+       "rcfilters-watchlist-showupdated": "Changes to pages you haven't visited since the changes occurred are in <strong>bold</strong>, with solid markers.",
        "rcnotefrom": "Below {{PLURAL:$5|is the change|are the changes}} since <strong>$3, $4</strong> (up to <strong>$1</strong> shown).",
        "rclistfromreset": "Reset date selection",
        "rclistfrom": "Show new changes starting from $2, $3",
        "unwatchthispage": "Stop watching",
        "notanarticle": "Not a content page",
        "notvisiblerev": "The last revision by a different user has been deleted",
-       "watchlist-details": "{{PLURAL:$1|$1 page|$1 pages}} on your watchlist, not separately counting talk pages.",
+       "watchlist-details": "{{PLURAL:$1|$1 page is|$1 pages are}} on your Watchlist (plus talk pages).",
        "wlheader-enotif": "Email notification is enabled.",
        "wlheader-showupdated": "Pages that have been changed since you last visited them are shown in <strong>bold</strong>.",
        "wlnote": "Below {{PLURAL:$1|is the last change|are the last <strong>$1</strong> changes}} in the last {{PLURAL:$2|hour|<strong>$2</strong> hours}}, as of $3, $4.",
        "undelete-cantedit": "You cannot undelete this page as you are not allowed to edit this page.",
        "undelete-cantcreate": "You cannot undelete this page as there is no existing page with this name and you are not allowed to create this page.",
        "pagedata-title": "Page data",
-       "pagedata-text": "This page provides a data interface to pages. Please provide the page title in the URL, using subpage syntax.\n* Content negotiation applies based on you client's Accept header. This means that the page data will be provided in the format preferred by your client.",
+       "pagedata-text": "This page provides a data interface to pages. Please provide the page title in the URL, using subpage syntax.\n* Content negotiation applies based on your client's Accept header. This means that the page data will be provided in the format preferred by your client.",
        "pagedata-not-acceptable": "No matching format found. Supported MIME types: $1",
        "pagedata-bad-title": "Invalid title: $1."
 }
index e882acd..335700f 100644 (file)
        "tog-watchlisthideminor": "Ocultar las ediciones menores de la lista de seguimiento",
        "tog-watchlisthideliu": "Ocultar las ediciones de los usuarios registrados de la lista de seguimiento",
        "tog-watchlistreloadautomatically": "Recargar la lista de seguimiento automáticamente cuando se modifica un filtro (requiere JavaScript)",
+       "tog-watchlistunwatchlinks": "Añadir enlaces directos para seguir o dejar de seguir las entradas de la lista de seguimiento (se requiere JavaScript para utilizar esta funcionalidad)",
        "tog-watchlisthideanons": "Ocultar las ediciones de los usuarios anónimos de la lista de seguimiento",
        "tog-watchlisthidepatrolled": "Ocultar las ediciones verificadas de la lista de seguimiento",
        "tog-watchlisthidecategorization": "Ocultar la categorización de páginas",
        "thisisdeleted": "¿Ver o restaurar $1?",
        "viewdeleted": "¿Quieres ver $1?",
        "restorelink": "{{PLURAL:$1|una edición borrada|$1 ediciones borradas}}",
-       "feedlinks": "Canal:",
+       "feedlinks": "Suministro:",
        "feed-invalid": "El tipo de canal de suscripción no es correcto.",
        "feed-unavailable": "Los canales de sindicación no están disponibles",
-       "site-rss-feed": "Canal RSS de $1",
-       "site-atom-feed": "Canal Atom de $1",
-       "page-rss-feed": "Canal RSS «$1»",
-       "page-atom-feed": "Canal Atom de «$1»",
+       "site-rss-feed": "Suministro RSS de $1",
+       "site-atom-feed": "Suministro Atom de $1",
+       "page-rss-feed": "Suministro RSS de «$1»",
+       "page-atom-feed": "Suministro Atom de «$1»",
        "feed-atom": "Atom",
        "red-link-title": "$1 (la página no existe)",
        "sort-descending": "Orden descendente",
        "permissionserrorstext-withaction": "No tienes permiso para $2, por {{PLURAL:$1|el siguiente motivo|los siguientes motivos}}:",
        "contentmodelediterror": "No puedes editar esta revisión porque su modelo de contenido es <code>$1</code>, que difiere del modelo actual de contenido de la página <code>$2</code>.",
        "recreate-moveddeleted-warn": "<strong>Atención: estás volviendo a crear una página que ha sido borrada anteriormente.</strong>\n\nPiensa si es adecuado continuar editando la página.\nA continuación, se proporciona el registro de borrado y traslados de esta página para más información:",
-       "moveddeleted-notice": "Esta página ha sido borrada.\nA continuación, se proporciona el registro de borrados y traslados de la página para más información.",
-       "moveddeleted-notice-recent": "Esta página se ha eliminado recientemente (durante las últimas 24 horas).\nEl registro de eliminación y traslado de la página se muestran a continuación como referencia.",
+       "moveddeleted-notice": "Esta página ha sido borrada.\nA continuación, se muestra el registro de eliminaciones, protecciones y traslados de la página a modo de referencia.",
+       "moveddeleted-notice-recent": "Esta página se ha eliminado recientemente (durante las últimas 24 horas).\nA continuación, se muestra el registro de eliminaciones, protecciones y traslados de la página a modo de referencia.",
        "log-fulllog": "Ver el registro completo",
        "edit-hook-aborted": "Una extensión ha evitado la edición.\nNo hay explicación disponible.",
        "edit-gone-missing": "No se ha podido actualizar la página.\nParece haber sido borrada.",
        "rcfilters-empty-filter": "No hay filtros activos. Se muestran todas las contribuciones.",
        "rcfilters-filterlist-title": "Filtros",
        "rcfilters-filterlist-whatsthis": "¿Cómo funcionan?",
-       "rcfilters-filterlist-feedbacklink": "Comparte tus comentarios sobre los filtros (beta) nuevos",
+       "rcfilters-filterlist-feedbacklink": "Comparte tus comentarios sobre estas (nuevas) herramientas de filtrado",
        "rcfilters-highlightbutton-title": "Resaltar los resultados",
        "rcfilters-highlightmenu-title": "Selecciona un color",
        "rcfilters-highlightmenu-help": "Selecciona un color para resaltar esta propiedad",
        "rcfilters-filterlist-noresults": "No se encontraron filtros",
        "rcfilters-noresults-conflict": "No se encontraron resultados porque los criterios de búsqueda están en conflicto.",
        "rcfilters-state-message-subset": "Este filtro no tiene ningún efecto debido a que sus resultados se incluyen con los de los siguientes: {{PLURAL:$2|filtro|filtros}} (intente destacarlo para distinguirlo): $1",
-       "rcfilters-state-message-fullcoverage": "Seleccionar todos los filtros de un grupo es lo mismo que seleccionar ninguno, por lo que este filtro no tiene efecto. El grupo incluye: $1",
+       "rcfilters-state-message-fullcoverage": "Seleccionar todos los filtros de este grupo es lo mismo que no seleccionar ninguno, por lo que este filtro no tiene efecto. El grupo incluye $1",
        "rcfilters-filtergroup-authorship": "Autoría de la contribución",
        "rcfilters-filter-editsbyself-label": "Cambios tuyos",
        "rcfilters-filter-editsbyself-description": "Tus propias contribuciones",
        "rcfilters-liveupdates-button": "Actualizaciones en directo",
        "rcfilters-liveupdates-button-title-on": "Apagar actualizaciones en directo",
        "rcfilters-liveupdates-button-title-off": "Mostar los cambios en tiempo real",
-       "rcfilters-watchlist-markSeen-button": "Marcar todos los cambios como vistos",
+       "rcfilters-watchlist-markseen-button": "Marcar todos los cambios como vistos",
+       "rcfilters-watchlist-showupdated": "Los cambios hechos a páginas que no has visitado desde que se efectuaron aparecen en <strong>negrita</strong>, acompañados de marcadores sólidos.",
        "rcnotefrom": "Debajo {{PLURAL:$5|aparece el cambio|aparecen los cambios}} desde <strong>$3, $4</strong> (se muestran hasta <strong>$1</strong>).",
        "rclistfromreset": "Restablecer selección de fecha",
        "rclistfrom": "Mostrar cambios nuevos desde las $2 del $3",
        "deadendpages": "Páginas sin salida",
        "deadendpagestext": "Las siguientes páginas no enlazan a otras páginas de {{SITENAME}}.",
        "protectedpages": "Páginas protegidas",
-       "protectedpages-indef": "Sólo protecciones indefinidas",
+       "protectedpages-indef": "Solo protecciones indefinidas",
        "protectedpages-summary": "Esta página enumera las páginas existentes que actualmente están protegidas. Para obtener una lista de títulos que están protegidos desde su creación, véase [[{{#special:ProtectedTitles}}|{{int:protectedtitles}}]].",
-       "protectedpages-cascade": "Sólo protecciones en cascada",
+       "protectedpages-cascade": "Solo protecciones en cascada",
        "protectedpages-noredirect": "Ocultar redirecciones",
        "protectedpagesempty": "Actualmente no hay ninguna página protegida con esos parámetros.",
        "protectedpages-timestamp": "Fecha y hora",
        "changecontentmodel-submit": "Cambiar",
        "changecontentmodel-success-title": "Se cambió el modelo de contenido",
        "changecontentmodel-success-text": "Se ha cambiado el tipo de contenido de [[:$1]].",
-       "changecontentmodel-cannot-convert": "El contenido de [[:$1]] no se puede convertir a un tipo de $2.",
+       "changecontentmodel-cannot-convert": "No se puede convertir el contenido de [[:$1]] en un tipo de $2.",
        "changecontentmodel-nodirectediting": "El modelo de contenido $1 no admite la edición directa",
        "changecontentmodel-emptymodels-title": "No hay modelos de contenido disponibles",
        "changecontentmodel-emptymodels-text": "El contenido de [[:$1]] no se puede convertir a ningún tipo.",
        "ipblocklist-otherblocks": "{{PLURAL:$1|Otro bloqueo|Otros bloqueos}}",
        "infiniteblock": "infinito",
        "expiringblock": "expira el $1 a las $2",
-       "anononlyblock": "sólo anón.",
+       "anononlyblock": "solo anón.",
        "noautoblockblock": "bloqueo automático desactivado",
        "createaccountblock": "creación de cuenta bloqueada",
        "emailblock": "correo electrónico bloqueado",
index 9fab7c2..2ccddbf 100644 (file)
        "changepassword-throttled": "Oled hiljuti proovinud liiga palju kordi sisse logida.\nPalun oota $1, enne kui uuesti proovid.",
        "botpasswords": "Robotiparoolid",
        "botpasswords-summary": "<em>Robotiparoolid</em> võimaldavad API-põhist juurdepääsu kasutajakontole, ilma kasutamata konto peamisi autentimisandmeid. Kui konto on sisse logitud robotiparooliga, võivad saadaolevad kasutajaõigused olla piiratud.\n\nKui sa ei tea, miks sul on vaja robotiparooli, siis on parem seda mitte kasutada. Mitte keegi ei peaks paluma sul robotiparooli genereerida ja seda talle edasi anda.",
+       "botpasswords-disabled": "Robotiparoolid on keelatud.",
+       "botpasswords-no-central-id": "Et robotiparoole kasutada, pead olema ühendkontoga sisse logitud.",
+       "botpasswords-existing": "Olemasolevad robotiparoolid",
        "botpasswords-createnew": "Uue robotiparooli loomine",
-       "botpasswords-label-appid": "Roboti nimi:",
+       "botpasswords-editexisting": "Olemasoleva robotiparooli muutmine",
+       "botpasswords-label-appid": "Robotinimi:",
        "botpasswords-label-create": "Loo",
+       "botpasswords-label-update": "Uuenda",
+       "botpasswords-label-cancel": "Loobu",
+       "botpasswords-label-delete": "Kustuta",
+       "botpasswords-label-resetpassword": "Lähtesta parool",
+       "botpasswords-label-grants": "Rakendatavad volitused:",
+       "botpasswords-help-grants": "Volitused võimaldavad juurdepääsu õigustele, mis su kontol juba on. Siin volituse lubamine ei võimalda juurdepääsu õigustele, mida su kontol muidu pole. Lisateavet leiad [[Special:ListGrants|volituste loetelust]].",
+       "botpasswords-label-grants-column": "Volitatud",
+       "botpasswords-bad-appid": "Robotinimi \"$1\" ei sobi.",
+       "botpasswords-insert-failed": "Ei õnnestunud lisada robotinime \"$1\". Kas see on juba lisatud?",
+       "botpasswords-update-failed": "Ei õnnestunud uuendada robotinime \"$1\". Kas see on kustutatud?",
+       "botpasswords-created-title": "Robotiparool loodud",
+       "botpasswords-created-body": "Robotiparool kasutaja \"$2\" robotinimele \"$1\" on loodud.",
+       "botpasswords-updated-title": "Robotiparool uuendatud",
+       "botpasswords-updated-body": "Robotiparool kasutaja \"$2\" robotinimele \"$1\" on uuendatud.",
+       "botpasswords-deleted-title": "Robotiparool kustutatud",
+       "botpasswords-deleted-body": "Robotiparool kasutaja \"$2\" robotinimele \"$1\" on kustutatud.",
+       "botpasswords-newpassword": "Uus parool, millega kontole <strong>$1</strong> sisse logida, on <strong>$2</strong>. <em>Palun kirjuta see edaspidiseks üles.</em> <br> (Mõni vana robot nõuab, et sisselogimisnimi langeb kokku edaspidise kasutajanimega. Sellisel juhul saad kasutada nime <strong>$3</strong> ja parooli <strong>$4</strong>.)",
+       "botpasswords-no-provider": "BotPasswordsSessionProvider pole saadaval.",
+       "botpasswords-restriction-failed": "Robotiparooli piirangud takistavad sisselogimist.",
+       "botpasswords-invalid-name": "Määratud kasutajanimi ei sisalda robotiparooli eraldajat (\"$1\").",
+       "botpasswords-not-exist": "Kasutaja \"$1\" robotinimele \"$2\" vastav robotiparool puudub.",
        "resetpass_forbidden": "Paroole ei saa muuta",
        "resetpass_forbidden-reason": "Paroole ei saa muuta: $1",
        "resetpass-no-info": "Pead olema sisselogitud, et sellele lehele pääseda.",
        "passwordreset-emailelement": "Kasutajanimi: \n$1\n\nAjutine parool: \n$2",
        "passwordreset-emailsentemail": "Kui oled sidunud konto selle e-posti aadressiga, siis saadetakse sulle parooli lähtestamise e-kiri.",
        "passwordreset-emailsentusername": "Parooli lähtestamise e-kiri saadetakse, kui olemas on kontoga seotud e-posti aadress.",
+       "passwordreset-nocaller": "Kutse saatja peab olema ära toodud",
+       "passwordreset-nosuchcaller": "Kutse saatjat pole olemas: $1",
        "passwordreset-ignored": "Parooli lähtestamine jäi rahuldamata. Võimalik, et ühtegi pakkujat polnud häälestatud.",
        "passwordreset-invalidemail": "Vigane e-posti aadress",
        "passwordreset-nodata": "Ära toomata jäid nii kasutajanimi kui ka e-posti aadress",
        "recentchanges-legend-heading": "<strong>Seletus:</strong>",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (vaata ka [[Special:NewPages|uute lehekülgede loendit]])",
        "recentchanges-submit": "Näita",
+       "rcfilters-tag-remove": "Eemalda \"$1\"",
        "rcfilters-legend-heading": "<strong>Lühendite loetelu:</strong>",
        "rcfilters-other-review-tools": "<strong>Muud ülevaatusriistad</strong>",
        "rcfilters-group-results-by-page": "Rühmita tulemused lehekülje kaupa",
        "rcfilters-hours-title": "Viimased tunnid",
        "rcfilters-days-show-days": "$1 {{PLURAL:$1|päev|päeva}}",
        "rcfilters-days-show-hours": "$1 {{PLURAL:$1|tund|tundi}}",
+       "rcfilters-highlighted-filters-list": "Esile tõstetud: $1",
        "rcfilters-quickfilters": "Salvestatud filtrid",
        "rcfilters-quickfilters-placeholder-title": "Linke pole veel salvestatud",
        "rcfilters-quickfilters-placeholder-description": "Et filtri sätted salvestada ja et neid hiljem uuesti kasutada, klõpsa alloleva aktiivsete filtrite loendi juures järjehoidjaikooni.",
        "rcfilters-filter-watchlist-watchednew-description": "Muudatused jälgimisloendi lehekülgedel, mida sa pole pärast muudatuse tegemist külastanud.",
        "rcfilters-filter-watchlist-notwatched-label": "Pole jälgimisloendis",
        "rcfilters-filter-watchlist-notwatched-description": "Kõik muu peale sinu jälgimisloendi lehekülgedel tehtud muudatuste.",
+       "rcfilters-filtergroup-watchlistactivity": "Jälgimisloendi tegevused",
+       "rcfilters-filter-watchlistactivity-unseen-label": "Nägemata muudatused",
+       "rcfilters-filter-watchlistactivity-unseen-description": "Muudatused lehekülgedel, mida sa pole pärast muudatuste tegemist külastanud.",
+       "rcfilters-filter-watchlistactivity-seen-label": "Nähtud muudatused",
+       "rcfilters-filter-watchlistactivity-seen-description": "Muudatused lehekülgedel, mida oled pärast muudatuste tegemist külastanud.",
        "rcfilters-filtergroup-changetype": "Muudatuse tüüp",
        "rcfilters-filter-pageedits-label": "Lehekülgede muutmine",
        "rcfilters-filter-pageedits-description": "Näiteks viki sisu, arutelude ja kategooriate kirjelduste muutmine.",
        "rcfilters-liveupdates-button": "Uuendused reaalajas",
        "rcfilters-liveupdates-button-title-on": "Lülita reaalajas uuendamine välja",
        "rcfilters-liveupdates-button-title-off": "Näita uusi muudatusi kohe nende tegemise järel",
+       "rcfilters-watchlist-markseen-button": "Märgi kõik muudatused nähtuks",
        "rcnotefrom": "Allpool on toodud {{PLURAL:$5|muudatus|muudatused}} alates: <strong>$3, kell $4</strong> (näidatakse kuni <strong>$1</strong> muudatust)",
        "rclistfromreset": "Lähtesta kuupäeva valik",
        "rclistfrom": "Näita muudatusi alates: $3, kell $2",
index 667470d..fa46550 100644 (file)
        "title-invalid-interwiki": "Eskatutako orriaren tituluak bertan erabili ezin den interwiki linka darama.",
        "title-invalid-talk-namespace": "Eskatutako orriaren izenburuak agian existitzen ez den eztabaida-orri bati egiten dio erreferentzia.",
        "title-invalid-characters": "Eskatutako orriaren izenburuak baliagarri ez diren karaktereak ditu: \"$1\".",
+       "title-invalid-leading-colon": "Eskatutako orriaren izenburua puntuazio baliogabea dauka hasieran.",
        "perfcached": "Hurrengo datuak katxean gordeta daude eta litekeena da guztiz eguneratuta ez egotea. Gehienez {{PLURAL:$1|emaitza 1 dago|$1 emaitza daude}} eskuragarri katxean.",
        "perfcachedts": "Hurrengo datuak katxean daude, $1 eguneratu zen azkenekoz. {{PLURAL:$4|emaitza 1 dago|$4 emaitza daude}} eskuragarri katxean.",
        "querypage-no-updates": "Orrialde honen berritzeak ez dira baimentzen. Hemen dagoen data ez da zuzenean berrituko.",
        "createaccount-text": "Norbaitek zure e-postarekin kontu bat sortu du {{SITENAME}}(e)n ($4) \"$2\" izenarekin eta \"$3\" pasahitzarekin.\nOrain bertan sar zaitezke eta zure pasahitza aldatu.\n\nKontu honen sorrera akats bat dela uste baduzu mezu honi ez diozu zertan jaramonik egin.",
        "login-throttled": "Saioa hasteko saiakera gehiegi egin berri dituzu.\nBerriro saiatu aurretik $1 itxoin, mesedez.",
        "login-abort-generic": "Zure sarrerak akatsa izan du - Abortatua",
+       "login-migrated-generic": "Zure kontua migratu da, eta zure erabiltzaile-izena ez dago jadanik wiki honetan.",
        "loginlanguagelabel": "Hizkuntza: $1",
        "suspicious-userlogout": "Saioa amaitzeko egin duzun eskaria ukatu da. Izan ere, ematen du eskari hori gaizki dabilen nabigatzaile edo cache proxy batek bidali duela.",
        "createacct-another-realname-tip": "Benetako izena hautazkoa da.\nEmatea erabakitzen baduzu hori erabiliko da lanaren atribuzioa egiterako garaian.",
        "editundo": "desegin",
        "diff-empty": "(Ez dago alderik)",
        "diff-multi-sameuser": "(Erabiltzaile berdinaren {{PLURAL:$1|erdiko ekarpen bat ez da|$1 erdiko ekarpen ez dira}} erakusten)",
-       "diff-multi-otherusers": "(Erabiltzaile berdinaren {{PLURAL:$1|erdiko ekarpen bat ez da|$1 erdiko ekarpen ez dira}} erakusten)",
+       "diff-multi-otherusers": "({{PLURAL:$1|Tarteko berrikusketa bat|$1 tarteko berrikusketak}}  {{PLURAL:$2|beste erabiltzaile bat|$2 erabiltzaileak}} egina ez da erakusten)",
        "searchresults": "Bilaketaren emaitzak",
        "searchresults-title": "«$1» bilaketaren  emaitzak",
        "titlematches": "Emaitzak artikuluen izenburuetan",
        "rcfilters-tag-remove": "$1 ezabatu",
        "rcfilters-legend-heading": "<indartsu>Laburpenen zerrenda:</indartsu>",
        "rcfilters-other-review-tools": "<strong>Beste berrikusketa tresna:</strong>",
+       "rcfilters-group-results-by-page": "Talde emaitzak orrika",
        "rcfilters-grouping-title": "Taldekatzen",
        "rcfilters-activefilters": "Iragazki aktiboak",
        "rcfilters-advancedfilters": "Iragazki aurreratuak",
        "rcfilters-view-return-to-default-tooltip": "Oinarrizko iragazketa menura bueltatu",
        "rcfilters-liveupdates-button": "Zuzenean egindako eguneraketak",
        "rcfilters-liveupdates-button-title-on": "Desgaitu zuzenean egindako eguneraketak",
-       "rcfilters-watchlist-markSeen-button": "Aldaketa guztiak ikusitakoak bezala markatu",
+       "rcfilters-watchlist-markseen-button": "Aldaketa guztiak ikusitakoak bezala markatu",
        "rcnotefrom": "Jarraian azaltzen diren {{PLURAL:$5|aldaketak}} data honetatik aurrerakoak dira: <strong>$3,$4</strong> (gehienez <b>$1</b> erakusten dira).",
        "rclistfromreset": "Data aukeraketa berrezarri",
        "rclistfrom": "Erakutsi $3 $2 ondorengo aldaketa berriak",
        "compare-title-not-exists": "Adierazi duzun izenburua ez da existitzen.",
        "compare-revision-not-exists": "Zehazturiko berrikuspena ez da existitzen.",
        "diff-form": "Ezberdintasunak",
+       "diff-form-revid": "Ezberdintasunaren ID berrikusketa",
        "diff-form-submit": "Erakutsi ezberdintasunak",
        "permanentlink": "Lotura finkoa",
        "permanentlink-revid": "Berrikuspen IDa",
        "feedback-subject": "Gaia:",
        "feedback-submit": "Bidali",
        "feedback-thanks-title": "Eskerrik asko!",
+       "feedback-useragent": "Erabiltzaile agentea:",
        "searchsuggest-search": "{{SITENAME}} wikian bilatu",
        "searchsuggest-containing": "edukian...",
        "api-error-badtoken": "Barne akatsa: token okerra.",
        "authprovider-resetpass-skip-label": "Utzi",
        "authform-wrongtoken": "Token okerra",
        "specialpage-securitylevel-not-allowed-title": "Baimenik gabe",
+       "authpage-cannot-login": "Saio hasiera ezin izan da burutu.",
        "cannotauth-not-allowed-title": "Ez da baimendu",
        "cannotauth-not-allowed": "Ez duzu baimenik orri hau erabiltzeko",
        "changecredentials": "Kredentzialak aldatu",
        "removecredentials-submit": "Kredentzialak kendu",
        "credentialsform-provider": "Kredentzial mota:",
        "credentialsform-account": "Kontuaren izena:",
+       "linkaccounts": "Kontuak lotu",
+       "linkaccounts-success-text": "Kontua lotu da.",
+       "linkaccounts-submit": "Kontuak lotu",
+       "unlinkaccounts": "Kontuak desestekatu",
+       "unlinkaccounts-success": "Kontua desestekatu da.",
+       "revid": "$1 berrikusi",
+       "pageid": "$1 orri IDa",
        "gotointerwiki": "{{SITENAME}}(e)tik irteten",
-       "pagedata-title": "Orri data"
+       "pagedata-title": "Orri data",
+       "pagedata-bad-title": "Izenburu baliogabea: $1"
 }
index 80b2b81..d376427 100644 (file)
        "rcfilters-empty-filter": "پالایه‌ای فعال نیست. همهٔ مشارکت‌های دیده می‌شوند.",
        "rcfilters-filterlist-title": "پالایه‌ها",
        "rcfilters-filterlist-whatsthis": "این چطور کار می‌کند؟",
-       "rcfilters-filterlist-feedbacklink": "ارساÙ\84 Ø¨Ø§Ø²Ø®Ù\88رد Ø¨Ø±Ø§Û\8c Ù¾Ø§Ù\84اÛ\8cÙ\87â\80\8cÙ\87اÛ\8c Ø¬Ø¯Û\8cد (آزÙ\85اÛ\8cØ´Û\8c)",
+       "rcfilters-filterlist-feedbacklink": "بÙ\87 Ù\85ا Ø¯Ø± Ù\85Ù\88رد Ø§Û\8cÙ\86 Ù¾Ø§Ù\84اÛ\8cÙ\87â\80\8cÙ\87اÛ\8c Ø¬Ø¯Û\8cد Ø¨Ø§Ø²Ø®Ù\88رد Ø¯Ù\87Û\8cد",
        "rcfilters-highlightbutton-title": "پررنگ کردن نتایج",
        "rcfilters-highlightmenu-title": "انتخاب رنگ",
        "rcfilters-highlightmenu-help": "یک رنگ انتخاب کنید تا این خصوصیت پر رنگ شود",
        "rcfilters-liveupdates-button": "به‌روزرسانی‌های زنده",
        "rcfilters-liveupdates-button-title-on": "خاموش کردن به‌روزرسانی خودکار",
        "rcfilters-liveupdates-button-title-off": "نمایش تغییرات جدید همچنان که رخ می‌دهند",
-       "rcfilters-watchlist-markSeen-button": "نشانه‌گذاری تمام تغییرات به‌عنوان خوانده‌شده",
+       "rcfilters-watchlist-markseen-button": "نشانه‌گذاری تمام تغییرات به‌عنوان خوانده‌شده",
+       "rcfilters-watchlist-edit-watchlist-button": "ویرایش فهرست صفحه‌های پی‌گیری‌هایتان",
        "rcnotefrom": "در زیر تغییرات از <strong>$3, $4</strong> (تا <strong>$1</strong> {{PLURAL:$5|نشان داده شده‌است|نشان داده شده‌اند}}).",
        "rclistfromreset": "از نو کردن انتخاب تاریخ",
        "rclistfrom": "نمایش تغییرات تازه با شروع از $3 $2",
        "apisandbox-sending-request": "ارسال درخواست ای‌پی‌آی...",
        "apisandbox-loading-results": "دریافت درخواست‌های ای‌پی‌آی...",
        "apisandbox-results-error": "در زمان بارگیری پاسخ پرسمان از رابط برنامه‌نویسی خطایی رخ داد: $1.",
+       "apisandbox-results-login-suppressed": "این درخواست به عنوان یک کاربر خارج شده از سامانه بررسی شد تا بتواند قانون امنیتی یک منبع را دور بزند. توجه کنید که سامانه افزودن خودکار توکن در صفحه تمرین API با چنین درخواست‌هایی درست کار نمی‌کند. لطفا توکن را دستی وارد کنید.",
        "apisandbox-request-selectformat-label": "نمایش داده‌های درخواست به عنوان:",
        "apisandbox-request-format-url-label": "آدرس اینترنتی متن پرسمان",
        "apisandbox-request-url-label": "درخواست آدرس:",
        "unwatchthispage": "توقف پی‌گیری",
        "notanarticle": "صفحه محتوایی نیست",
        "notvisiblerev": "آخرین نسخه توسط کاربری دیگر حذف شده‌است",
-       "watchlist-details": "بدون احتساب صفحه‌های جداگانهٔ بحث، {{PLURAL:$1|$1 صفحه|$1 صفحه}} در فهرست پی‌گیری‌های شما قرار {{PLURAL:$1|دارد|دارند}}.",
+       "watchlist-details": "{{PLURAL:$1|$1 صفحه|$1 صفحه}} در فهرست پی‌گیری‌های شما قرار {{PLURAL:$1|دارد|دارند}}.",
        "wlheader-enotif": "ایمیل‌های اعلان فعال است.",
        "wlheader-showupdated": "صفحه‌هایی که پس از آخرین بازدید شما تغییر کرده‌اند <strong>پررنگ</strong> نمایش داده شده‌اند.",
        "wlnote": "در زیر {{PLURAL:$1|تغییری|<strong>$1</strong> تغییری}} که در {{PLURAL:$2|ساعت|<strong>$2</strong> ساعت}} گذشته انجام شده موجود است، تاریخ آخرین بازیابی: $3، $4",
        "unprotectedarticle": "صفحهٔ «[[$1]]» را از محافظت بیرون آورد",
        "movedarticleprotection": "تنظیمات محافظت را از «[[$2]]» به «[[$1]]» منتقل کرد",
        "protectedarticle-comment": "«[[$1]]» را {{GENDER:$2|محافظت کرد}}",
-       "modifiedarticleprotection-comment": "سطح محاظفت «[[$1]]» را {{GENDER:$2|تغییر داد}}",
+       "modifiedarticleprotection-comment": "سطح محافظت «[[$1]]» را {{GENDER:$2|تغییر داد}}",
        "unprotectedarticle-comment": "«[[$1]]» را از محافظت {{GENDER:$2|در آورد}}",
        "protect-title": "تغییر وضعیت محافظت «$1»",
        "protect-title-notallowed": "مشاهدهٔ سطح محافظت «$1»",
        "undelete-cantedit": "شما نمی‌توانید این صفحه را احیا کنید چون مجاز به ویرایش این صفحه نیستید.",
        "undelete-cantcreate": "شما نمی‌توانید این صفحه را احیا کنید چرا که صفحه‌ای به این نام همینک وجود ندارد و شما مجاز به ساختن آن نیستید.",
        "pagedata-title": "اطلاعات صفحه",
+       "pagedata-text": "این صفحه یک رابط داده به صفحات است. لطفا نام صفحه را در آدرس به شکل زیرصفحه وارد کنید.\n* مذاکره محتوا با استفاده از هدر Accept ممکن است. این به این معنی است که داده‌ّای صفحه در قالبی که ترجیح دهید باز خواهد شد.",
        "pagedata-not-acceptable": "هیچ قالب تطبیقی یافت نشد. انواع MIME پشتیبانی شده: $1",
        "pagedata-bad-title": "عنوان نامعتبر: «$1»."
 }
index 87183fa..3dcb491 100644 (file)
        "editingsection": "Muokataan osiota sivusta $1",
        "editingcomment": "Muokataan uutta osiota sivulla $1",
        "editconflict": "Päällekkäinen muokkaus: $1",
-       "explainconflict": "Joku muu on muuttanut tätä sivua sen jälkeen, kun aloit muokata sitä.\nYlempi tekstialue sisältää tämänhetkisen tekstin.\nTekemäsi muutokset näkyvät alemmassa ikkunassa.\nSinun täytyy yhdistää muutoksesi olemassa olevaan tekstiin.\n'''Vain''' ylemmässä alueessa oleva teksti tallentuu, kun tallennat sivun.",
+       "explainconflict": "Joku muu on muuttanut tätä sivua sen jälkeen, kun aloit muokata sitä.\nYlempi tekstialue sisältää tämänhetkisen tekstin.\nTekemäsi muutokset näkyvät alemmassa ikkunassa.\nSinun täytyy yhdistää muutoksesi olemassa olevaan tekstiin.\n<strong>Vain</strong> ylemmässä alueessa oleva teksti tallentuu, kun napsautat \"$1\".",
        "yourtext": "Oma tekstisi",
        "storedversion": "Tallennettu versio",
        "nonunicodebrowser": "'''Selaimesi ei ole Unicode-yhteensopiva. Ole hyvä ja vaihda selainta, ennen kuin muokkaat sivua.'''",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (katso myös [[Special:NewPages|lista uusista sivuista]])",
        "recentchanges-legend-plusminus": "(''±123'')",
        "recentchanges-submit": "Näytä",
+       "rcfilters-tag-remove": "Poista '$1'",
        "rcfilters-legend-heading": "<strong>Luettelo lyhenteistä:</strong>",
        "rcfilters-other-review-tools": "<strong>Muut arviointityökalut</strong>",
        "rcfilters-group-results-by-page": "Ryhmitä tulokset sivujen mukaan",
        "rcfilters-grouping-title": "Ryhmitys",
        "rcfilters-activefilters": "Aktiiviset suodattimet",
+       "rcfilters-advancedfilters": "Kehittyneet suodattimet",
        "rcfilters-limit-title": "Näytettävät muutokset",
        "rcfilters-limit-shownum": "Näytä {{PLURAL:$1|viimeisin muutos|$1 viimeisintä muutosta}}",
        "rcfilters-days-title": "Viimeisimmät päivät",
        "rcfilters-hours-title": "Viimeisimmät tunnit",
        "rcfilters-days-show-days": "$1 {{PLURAL:$1|päivä|päivää}}",
        "rcfilters-days-show-hours": "$1 {{PLURAL:$1|tunti|tuntia}}",
+       "rcfilters-highlighted-filters-list": "Korostettu: $1",
        "rcfilters-quickfilters": "Tallennetut suodattimet",
        "rcfilters-quickfilters-placeholder-title": "Ei vielä tallennettuja linkkejä",
        "rcfilters-savedqueries-defaultlabel": "Tallennetut suodattimet",
        "rcfilters-savedqueries-unsetdefault": "Poista oletuksena",
        "rcfilters-savedqueries-remove": "Poista",
        "rcfilters-savedqueries-new-name-label": "Nimi",
+       "rcfilters-savedqueries-new-name-placeholder": "Kuvaa suodattimen tarkoitusta",
        "rcfilters-savedqueries-apply-label": "Luo suodatin",
        "rcfilters-savedqueries-apply-and-setdefault-label": "Luo oletussuodatin",
        "rcfilters-savedqueries-cancel-label": "Peru",
        "rcfilters-filterlist-noresults": "Ei löytynyt suodattimia",
        "rcfilters-noresults-conflict": "Tuloksia ei löytynyt, koska hakuehdot ovat ristiriidassa",
        "rcfilters-state-message-subset": "Tällä suodattimella ei ole vaikutusta, koska sen tulokset sisältyvät {{PLURAL:$2|seuraavaan laajempaan suodattimeen|seuraaviin laajempiin suodattimiin}} (kokeile korostusta sen erottamiseksi): $1",
-       "rcfilters-state-message-fullcoverage": "Ryhmän kaikkien suodattimien valitseminen on sama, kuin ei valitse mitään, joten tällä suodattimella ei ole vaikutusta. Ryhmään sisältyy: $1",
+       "rcfilters-state-message-fullcoverage": "Tässä ryhmässä kaikkien suodattimien valitseminen on sama, kuin ei valitse mitään, joten tällä suodattimella ei ole vaikutusta. Ryhmään sisältyy: $1",
        "rcfilters-filtergroup-authorship": "Muutoksen tekijä",
-       "rcfilters-filter-editsbyself-label": "Muutoksesi",
+       "rcfilters-filter-editsbyself-label": "Sinun tekemät muutokset",
        "rcfilters-filter-editsbyself-description": "Tekemäsi muutokset.",
        "rcfilters-filter-editsbyother-label": "Muiden muutokset",
        "rcfilters-filter-editsbyother-description": "Muiden käyttäjien tekemät muutokset.",
        "rcfilters-filter-watchlist-watched-label": "Tarkkailulistalla",
        "rcfilters-filter-watchlist-watched-description": "Muutokset tarkkailulistalla oleviin sivuihin.",
        "rcfilters-filter-watchlist-watchednew-label": "Uudet tarkkailulistan muutokset",
+       "rcfilters-filter-watchlist-watchednew-description": "Muutokset tarkkailulistalla oleviin sivuihin, joilla et ole vieraillut sen jälkeen, kun sivuille on tehty muutoksia.",
        "rcfilters-filter-watchlist-notwatched-label": "Ei tarkkailulistalla",
        "rcfilters-filtergroup-changetype": "Muutoksen tyyppi",
        "rcfilters-filter-pageedits-label": "Sivun muokkaukset",
        "rcfilters-typeofchange-conflicts-hideminor": "\"Muutoksen tyyppi\" on ristiriidassa \"Pienet muutokset\" -suodattimen kanssa. Joitain muutostyyppejä ei voida merkitä \"pieniksi\".",
        "rcfilters-filtergroup-lastRevision": "Viimeisimmät versiot",
        "rcfilters-filter-lastrevision-label": "Viimeisin versio",
-       "rcfilters-filter-lastrevision-description": "Viimeisin muutos sivulle.",
-       "rcfilters-filter-previousrevision-label": "Aikaisemman versiot",
+       "rcfilters-filter-lastrevision-description": "Vain viimeisin muutos sivulle.",
+       "rcfilters-filter-previousrevision-label": "Ei viimeisin muutos",
+       "rcfilters-view-advanced-filters-label": "Kehittyneet suodattimet",
        "rcfilters-view-namespaces-tooltip": "Suodata tuloksia nimiavaruuden mukaan",
        "rcnotefrom": "Alla ovat muutokset <strong>$3, $4</strong> lähtien. (Enintään <strong>$1</strong> näytetään.)",
+       "rclistfromreset": "Tyhjennä ajankohdan valinta",
        "rclistfrom": "Näytä uudet muutokset $3 kello $2 alkaen",
        "rcshowhideminor": "$1 pienet muutokset",
        "rcshowhideminor-show": "Näytä",
        "newimages-user": "IP-osoite tai käyttäjänimi:",
        "newimages-showbots": "Näytä bottien tekemät tallennukset",
        "newimages-hidepatrolled": "Piilota tarkastetut tiedostotallennukset",
+       "newimages-mediatype": "Median tyyppi:",
        "noimages": "Ei uusia tiedostoja.",
        "gallery-slideshow-toggle": "Vaihda pienoiskuvaa",
        "ilsubmit": "Hae",
index f392436..4fb2636 100644 (file)
                        "Archaeodontosaurus",
                        "Trizek (WMF)",
                        "Framawiki",
-                       "Jona"
+                       "Jona",
+                       "Epok",
+                       "DePlusJean"
                ]
        },
        "tog-underline": "Soulignement des liens :",
        "tog-watchdeletion": "Ajouter à ma liste de suivi les pages et les fichiers que je supprime",
        "tog-watchuploads": "Ajouter les nouveaux fichiers que j’importe à ma liste de suivi",
        "tog-watchrollback": "Ajouter à ma liste de suivi les pages sur lesquelles j’ai effectué une révocation",
-       "tog-minordefault": "Marquer toutes les modifications comme étant mineures par défaut",
-       "tog-previewontop": "Afficher la prévisualisation avant la zone d’édition",
+       "tog-minordefault": "Marquer toutes mes modifications comme étant mineures par défaut",
+       "tog-previewontop": "Afficher la prévisualisation au dessus de la zone d’édition",
        "tog-previewonfirst": "Afficher la prévisualisation lors de la première modification",
        "tog-enotifwatchlistpages": "M’avertir par courriel lorsqu’une page ou un fichier de ma liste de suivi est modifié",
-       "tog-enotifusertalkpages": "M’avertir par courriel si ma page de discussion est modifiée",
+       "tog-enotifusertalkpages": "M’avertir par courriel lorsque ma page de discussion est modifiée",
        "tog-enotifminoredits": "M’avertir par courriel également lors des modifications mineures des pages ou des fichiers",
        "tog-enotifrevealaddr": "Afficher mon adresse électronique dans les courriels de notification",
        "tog-shownumberswatching": "Afficher le nombre d’utilisateurs en cours",
        "tog-watchlisthideminor": "Masquer les modifications mineures dans la liste de suivi",
        "tog-watchlisthideliu": "Masquer les modifications faites par des utilisateurs inscrits dans la liste de suivi",
        "tog-watchlistreloadautomatically": "Recharger automatiquement la liste de suivi lorsque les options de filtrage sont modifiées (JavaScript requis)",
-       "tog-watchlistunwatchlinks": "Ajouter des liens directs de suivi/non suivi pour les entrées de la liste de suivi (JavaScript requis pour utiliser la fonctionnalité)",
+       "tog-watchlistunwatchlinks": "Ajouter des liens directs pour suivre ou arrêter de suivre les entrées de la liste de suivi (JavaScript est nécessaire pour utiliser la fonctionnalité)",
        "tog-watchlisthideanons": "Masquer les modifications d’utilisateurs anonymes dans la liste de suivi",
        "tog-watchlisthidepatrolled": "Masquer les modifications relues dans la liste de suivi",
        "tog-watchlisthidecategorization": "Masquer la catégorisation des pages",
        "tog-showhiddencats": "Afficher les catégories cachées",
        "tog-norollbackdiff": "Ne pas afficher le diff après avoir révoqué",
        "tog-useeditwarning": "M’avertir quand je quitte une page en cours de modification sans avoir sauvegardé",
-       "tog-prefershttps": "Utilisez toujours une connexion sécurisée pour vous connecter",
+       "tog-prefershttps": "Toujours utiliser une connexion sécurisée lorsque je suis connecté",
        "underline-always": "Toujours",
        "underline-never": "Jamais",
        "underline-default": "Valeur par défaut du thème ou du navigateur",
        "october-gen": "octobre",
        "november-gen": "novembre",
        "december-gen": "décembre",
-       "jan": "jan",
-       "feb": "fév",
-       "mar": "mar",
-       "apr": "avr",
+       "jan": "janv.",
+       "feb": "fév.",
+       "mar": "mars",
+       "apr": "avr.",
        "may": "mai",
        "jun": "juin",
-       "jul": "juil",
+       "jul": "juill.",
        "aug": "août",
-       "sep": "sep",
-       "oct": "oct",
-       "nov": "nov",
-       "dec": "déc",
+       "sep": "sept.",
+       "oct": "oct.",
+       "nov": "nov.",
+       "dec": "déc.",
        "january-date": "{{PLURAL:$1|1=1ᵉʳ|$1}} janvier",
        "february-date": "{{PLURAL:$1|1=1ᵉʳ|$1}} février",
        "march-date": "{{PLURAL:$1|1=1ᵉʳ|$1}} mars",
        "category-header-numerals": "$1–$2",
        "about": "À propos",
        "article": "Page de contenu",
-       "newwindow": "(ouvre dans une nouvelle fenêtre)",
+       "newwindow": "(s’ouvre dans une nouvelle fenêtre)",
        "cancel": "Annuler",
        "moredotdotdot": "Plus...",
        "morenotlisted": "Cette liste peut être incomplète.",
        "returnto": "Revenir à la page $1.",
        "tagline": "De {{SITENAME}}",
        "help": "Aide",
-       "search": "Rechercher",
-       "search-ignored-headings": " #<!-- laisser cette ligne comme telle --><pre>\n# Titres des sections qui seront ignorés par la recherche\n# Les changements effectués ici prennent effet dès lors que la page avec le titre est indexée.\n# Vous pouvez forcer la réindexation de la page en effectuant une modification vide\n# La syntaxe est la suivante :\n#   * Toute ligne précédée d’un « # » est un commentaire\n#   * Toute ligne non-vide est le titre exact à ignorer, casse comprise\nRéférences\nLiens externes\nVoir aussi\n #</pre><!-- laisser cette ligne comme telle -->",
-       "searchbutton": "Rechercher",
+       "search": "Chercher",
+       "search-ignored-headings": " #<!-- ne pas modifier cette ligne --><pre>\n# Titres des sections qui seront ignorés par la recherche.\n# Les changements effectués ici prennent effet dès lors que la page avec le titre est indexée.\n# Vous pouvez forcer la réindexation de la page en effectuant une modification vide.\n# La syntaxe est la suivante :\n#   * Toute ce qui suit un « # » jusqu’à la fin de la ligne est un commentaire.\n#   * Toute ligne non-vide est le titre exact à ignorer, casse comprise.\nRéférences\nLiens externes\nVoir aussi\n #</pre><!-- ne pas modifier cette ligne -->",
+       "searchbutton": "Chercher",
        "go": "Consulter",
-       "searcharticle": "Lire",
+       "searcharticle": "Continuer",
        "history": "Historique de la page",
        "history_short": "Historique",
        "history_small": "historique",
        "updatedmarker": "modifié depuis ma dernière visite",
        "printableversion": "Version imprimable",
-       "permalink": "Adresse permanente",
+       "permalink": "Lien permanent",
        "print": "Imprimer",
        "view": "Lire",
        "view-foreign": "Voir sur $1",
        "redirectedfrom": "(Redirigé depuis $1)",
        "redirectpagesub": "Page de redirection",
        "redirectto": "Rediriger vers :",
-       "lastmodifiedat": "Cette page a été modifiée pour la dernière fois le $1 à $2.",
+       "lastmodifiedat": "La dernière modification de cette page a été faite le $1 à $2.",
        "viewcount": "Cette page {{PLURAL:$1|0=n’a jamais été consultée|1=a été consultée une seule fois|a été consultée $1 fois}}.",
        "protectedpage": "Page protégée",
        "jumpto": "Aller à :",
        "pool-servererror": "Le service de réservation n’est pas disponible ($1).",
        "poolcounter-usage-error": "Erreur d’utilisation : $1",
        "aboutsite": "À propos de {{SITENAME}}",
-       "aboutpage": "Project:À propos",
+       "aboutpage": "Project: À propos de",
        "copyright": "Le contenu est disponible sous licence $1 sauf mention contraire.",
        "copyrightpage": "{{ns:project}}:Copyrights",
        "currentevents": "Actualités",
-       "currentevents-url": "Project:Actualités",
+       "currentevents-url": "Project: Actualités",
        "disclaimers": "Avertissements",
-       "disclaimerpage": "Project:Avertissements généraux",
+       "disclaimerpage": "Project: Avertissements généraux",
        "edithelp": "Aide pour l'édition",
        "helppage-top-gethelp": "Aide",
        "mainpage": "Accueil",
        "mainpage-description": "Accueil",
        "policy-url": "Project:Règles",
        "portal": "Communauté",
-       "portal-url": "Project:Accueil",
+       "portal-url": "Project: portail communautaire",
        "privacy": "Politique de confidentialité",
-       "privacypage": "Project:Confidentialité",
+       "privacypage": "Project: Politique de confidentialité",
        "badaccess": "Erreur de permissions",
        "badaccess-group0": "Vous n’avez pas les droits suffisants pour réaliser l’action demandée.",
        "badaccess-groups": "L’action que vous essayez de réaliser n’est permise qu’aux utilisateurs {{PLURAL:$2|du groupe|d’un des groupes}} : $1.",
        "missing-article": "La base de données n’a pas trouvé le texte d’une page qu’elle aurait dû trouver, intitulée « $1 » $2.\n\nGénéralement, cela survient en suivant un lien vers un diff périmé ou vers l’historique d’une page supprimée.\n\nSi ce n’est pas le cas, il peut s’agir d’une anomalie dans le programme.\nVeuillez la signaler à un [[Special:ListUsers/sysop|administrateur]] sans oublier de lui indiquer l’URL de la page.",
        "missingarticle-rev": "(numéro de version : $1)",
        "missingarticle-diff": "(diff : $1, $2)",
-       "readonly_lag": "La base de données a été automatiquement verrouillée pendant que les serveurs secondaires se réalignent sur le serveur principal.",
+       "readonly_lag": "La base de données a été automatiquement verrouillée pendant que les serveurs secondaires se réalignent sur le serveur principal",
        "nonwrite-api-promise-error": "L’entête HTTP « <code>Promise-Non-Write-API-Action:</code> » a été envoyé mais la requête a été faite à un module d’écriture de l’API.",
        "internalerror": "Erreur interne",
        "internalerror_info": "Erreur interne : $1",
        "title-invalid-interwiki": "La page cible contient un lien interwiki ne pouvant être utilisé dans les titres.",
        "title-invalid-talk-namespace": "Le titre de la page demandée fait référence à une page de discussion qui peut ne pas exister.",
        "title-invalid-characters": "Le titre de la page demandée contient des caractères non valides : « $1 ».",
-       "title-invalid-relative": "Le titre contient un chemin relatif. Les titres référençant des pages relatives (./, ../) sont non valides car il seront souvent inaccessibles pour certains explorateurs des utilisateurs.",
+       "title-invalid-relative": "Le titre contient un chemin relatif. Les titres référençant des pages relatives (./, ../) sont non valides car il seront souvent inaccessibles lorsque utilisés par le navigateur de l'utilisateur.",
        "title-invalid-magic-tilde": "Le titre de la page demandée contient une séquence de tilde magiques non valide (<nowiki>~~~</nowiki>).",
        "title-invalid-too-long": "La titre de la page demandée est trop long. Il ne doit pas dépasser $1 {{PLURAL:$1|octet|octets}} dans l’encodage UTF-8.",
        "title-invalid-leading-colon": "Le titre de la page demandée contient un deux-points invalide au début.",
        "translateinterface": "Pour ajouter ou modifier des traductions pour tous les wikis, veuillez utiliser [https://translatewiki.net/ translatewiki.net], le projet de localisation linguistique de MediaWiki.",
        "cascadeprotected": "Cette page est protégée contre les modifications car elle est transcluse par {{PLURAL:$1|la page suivante, qui a été protégée|les pages suivantes, qui ont été protégées}} avec l’option « protection en cascade » activée :\n$2",
        "namespaceprotected": "Vous n’avez pas la permission de modifier les pages de l’espace de noms « <strong>$1</strong> ».",
-       "customcssprotected": "Vous n’avez pas la permission de modifier cette page de CSS, car elle contient les paramètres personnels d’un autre utilisateur.",
+       "customcssprotected": "Vous n’avez pas la permission de modifier cette feuille de style CSS, car elle contient les paramètres personnels d’un autre utilisateur.",
        "customjsprotected": "Vous n’avez pas la permission de modifier cette page de JavaScript, car elle contient les paramètres personnels d’un autre utilisateur.",
        "mycustomcssprotected": "Vous n’avez pas le droit de modifier cette page CSS.",
        "mycustomjsprotected": "Vous n’avez pas le droit de modifier cette page JavaScript.",
        "exception-nologin-text": "Veuillez vous connecter pour pouvoir accéder à cette page ou cette action.",
        "exception-nologin-text-manual": "Veuillez vous $1 pour pouvoir accéder à cette page ou cette action.",
        "virus-badscanner": "Mauvaise configuration : analyseur de virus inconnu : <em>$1</em>",
-       "virus-scanfailed": "Ã\89chec de la recherche (code $1)",
+       "virus-scanfailed": "échec de lâ\80\99analyse (code $1)",
        "virus-unknownscanner": "antivirus inconnu :",
        "logouttext": "<strong>Vous êtes à présent déconnecté{{GENDER:||e|(e)}}.</strong>\n\nNotez que certaines pages peuvent être encore affichées comme si vous étiez toujours connecté, jusqu’à ce que vous effaciez le cache de votre navigateur.",
        "cannotlogoutnow-title": "Impossible de se déconnecter maintenant",
        "cannotlogoutnow-text": "La déconnexion n’est pas possible en utilisant $1.",
        "welcomeuser": "Bienvenue, $1 !",
-       "welcomecreation-msg": "Votre compte a été créé.\nVous pouvez modifier [[Special:Preferences|vos préférences pour {{SITENAME}}]] si vous le souhaitez.",
+       "welcomecreation-msg": "Votre compte a été créé.\nVous pouvez modifier [[Special:Preferences|vos préférences]] pour {{SITENAME}} si vous le souhaitez.",
        "yourname": "Nom d’utilisateur :",
        "userlogin-yourname": "Nom d’utilisateur",
        "userlogin-yourname-ph": "Entrez votre nom d’utilisateur",
        "createacct-benefit-body3": "{{PLURAL:$1|contributeur récent|contributeurs récents}}",
        "badretype": "Les mots de passe que vous avez saisis ne correspondent pas.",
        "usernameinprogress": "Une création de compte pour ce nom d’utilisateur est déjà en cours.\nVeuillez patienter.",
-       "userexists": "Nom d’utilisateur entré déjà utilisé.\nVeuillez choisir un nom différent.",
+       "userexists": "Le nom d’utilisateur saisi est déjà utilisé.\nVeuillez choisir un nom différent.",
        "loginerror": "Erreur de connexion",
        "createacct-error": "Erreur lors de la création du compte",
        "createaccounterror": "Impossible de créer le compte : $1",
        "nosuchuser": "L’utilisateur « $1 » n’existe pas.\nLes noms d’utilisateur sont sensibles à la casse.\nVérifiez l’orthographe, ou [[Special:CreateAccount|créez un nouveau compte]].",
        "nosuchusershort": "Il n’y a pas de contributeur avec le nom « $1 ».\nVeuillez vérifier l’orthographe.",
        "nouserspecified": "Vous devez saisir un nom d’utilisateur.",
-       "login-userblocked": "Cet utilisateur est bloqué. Connexion non autorisée.",
+       "login-userblocked": "{{GENDER:$1|Cet utilisateur|Cette utilisatrice}} est bloqué{{GENDER:$1||e}}. La connexion n’est pas autorisée.",
        "wrongpassword": "Le mot de passe est incorrect.\nVeuillez essayer à nouveau.",
        "wrongpasswordempty": "Vous n’avez entré aucun mot de passe.\nVeuillez essayer à nouveau.",
        "passwordtooshort": "Votre mot de passe doit contenir au moins $1 caractère{{PLURAL:$1||s}}.",
        "mailmypassword": "Réinitialiser le mot de passe",
        "passwordremindertitle": "Nouveau mot de passe temporaire pour {{SITENAME}}",
        "passwordremindertext": "Quelqu’un (probablement vous, ayant l’adresse IP $1) a demandé un nouveau mot de\npasse pour {{SITENAME}} ($4). Un mot de passe temporaire pour l’utilisateur\n« $2 » a été créé et est « $3 ». Si cela était votre intention,\nvous devrez vous connecter et choisir un nouveau mot de passe.\nVotre mot de passe temporaire expirera dans $5 jour{{PLURAL:$5||s}}.\n\nSi vous n’êtes pas l’auteur de cette demande, ou si vous vous souvenez à présent de\nvotre mot de passe et ne souhaitez plus en changer, vous pouvez ignorer ce message\net continuer à utiliser votre ancien mot de passe.",
-       "noemail": "Aucune adresse de courriel n’a été enregistrée pour l'utilisateur « $1 ».",
+       "noemail": "Aucune adresse de courriel n’a été enregistrée pour l’utilisat{{GENDER:$1|eur|rice}} « $1 ».",
        "noemailcreate": "Vous devez fournir une adresse de courriel valide",
-       "passwordsent": "Un nouveau mot de passe a été envoyé à l’adresse de courriel de l’utilisateur « $1 ».\nVeuillez vous reconnecter après l’avoir reçu.",
+       "passwordsent": "Un nouveau mot de passe a été envoyé à l’adresse de courriel de l’utilisat{{GENDER:$1|eur|rice}} « $1 ».\nVeuillez vous reconnecter après l’avoir reçu.",
        "blocked-mailpassword": "Votre adresse IP est bloquée en modification. Pour éviter les abus, il n’est pas autorisé d’utiliser la récupération de mot de passe à partir de cette adresse IP.",
        "eauthentsent": "Un courriel de confirmation a été envoyé à l’adresse indiquée.\nAvant qu’un autre courriel ne soit envoyé à ce compte, vous devrez suivre les instructions du courriel et confirmer que le compte est bien le vôtre.",
        "throttled-mailpassword": "Un courriel de réinitialisation de votre mot de passe a déjà été envoyé durant {{PLURAL:$1|la dernière heure|les $1 dernières heures}}. \nAfin d’éviter les abus, un seul courriel de réinitialisation de votre mot de passe sera envoyé par {{PLURAL:$1|heure|intervalle de $1 heures}}.",
        "emailnotauthenticated": "Votre adresse de courriel n’est pas encore confirmée.\nAucun courriel ne sera envoyé pour chacune des fonctions suivantes.",
        "noemailprefs": "Indiquez une adresse de courriel dans vos préférences pour utiliser ces fonctions.",
        "emailconfirmlink": "Confirmez votre adresse de courriel",
-       "invalidemailaddress": "Cette adresse courriel ne peut pas être acceptée car son format paraît incorrect.\nEntrez une adresse bien formatée ou laissez ce champ vide.",
+       "invalidemailaddress": "Cette adresse courriel ne peut pas être acceptée car son format paraît incorrect.\nEntrez une adresse correctement formatée ou laissez ce champ vide.",
        "cannotchangeemail": "Les adresses de courriel des comptes ne peuvent pas être modifiées sur ce wiki.",
        "emaildisabled": "Ce site ne peut pas envoyer de courriels.",
        "accountcreated": "Compte créé",
        "botpasswords-updated-title": "Mot de passe de robots mis à jour",
        "botpasswords-updated-body": "Le mot de passe pour le robot « $1 » de l'utilisateur « $2 » a été mis à jour.",
        "botpasswords-deleted-title": "Mot de passe de robots supprimé",
-       "botpasswords-deleted-body": "Le mot de passe pour le robot « $1 » de l'utilisateur « $2 » a été supprimé.",
+       "botpasswords-deleted-body": "Le mot de passe pour le robot « $1 » de l'{{GENDER:$2|utilisateur|utilisatrice}} « $2 » a été supprimé.",
        "botpasswords-newpassword": "Le nouveau mot de passe pour se connecter à <strong>$1</strong> est <strong>$2</strong>. <em>Veuillez l’enregistrer pour y faire référence ultérieurement.</em><br> (Pour les anciens robots qui nécessitent que le nom fourni à la connexion soit le même que le nom d'utilisateur éventuel, vous pouvez aussi utiliser  <strong>$3</strong> comme nom d'utilisateur et <strong>$4</strong> comme mot de passe).",
        "botpasswords-no-provider": "BotPasswordsSessionProvider n’est pas disponible.",
        "botpasswords-restriction-failed": "Les restrictions de mot de passe de robots empêchent cette connexion.",
        "botpasswords-invalid-name": "Le nom d’utilisateur spécifié ne contient pas de séparateur de mot de passe de robots (« $1 »).",
-       "botpasswords-not-exist": "L’utilisateur « $1 » n’a pas le mot de passe de robots intitulé « $2 ».",
+       "botpasswords-not-exist": "L’{{GENDER:$1|utilisateur|utilisatrice}} « $1 » n’a pas de mot de passe de robots intitulé « $2 ».",
        "resetpass_forbidden": "Les mots de passe ne peuvent pas être changés",
        "resetpass_forbidden-reason": "Les mots de passe ne peuvent pas être modifiés : $1",
        "resetpass-no-info": "Vous devez être connecté pour avoir accès directement à cette page.",
        "gender-unknown": "Lorsqu’il fera mention de vous, le logiciel utilisera des mots de genre neutre, quand c’est possible",
        "gender-male": "Il modifie des pages du wiki",
        "gender-female": "Elle modifie des pages du wiki",
-       "prefs-help-gender": "Définir cette préférence est facultatif.\nLe logiciel utilise la valeur pour s’adresser à vous ou pour vous mentionner aux autres en utilisant le bon genre grammatical.\nCette information sera publique.",
+       "prefs-help-gender": "La définition de cette préférence est facultative.\nLe logiciel utilise cette valeur pour s’adresser à vous ou pour faire mention de vous aux autres en utilisant le bon genre grammatical.\nCette information sera publique.",
        "email": "Courriel",
        "prefs-help-realname": "Le vrai nom est facultatif.\nS’il est fourni, il sera utilisé pour vous attribuer vos contributions.",
        "prefs-help-email": "L'adresse de courriel est facultative, mais elle est nécessaire pour réinitialiser votre mot de passe, si vous veniez à l'oublier.",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (voir aussi la [[Special:NewPages|liste des nouvelles pages]]).",
        "recentchanges-legend-plusminus": "(''±123'')",
        "recentchanges-submit": "Lister",
-       "rcfilters-tag-remove": "Supprimer '$1'",
+       "rcfilters-tag-remove": "Supprimer « $1 »",
        "rcfilters-legend-heading": "<strong>Liste des abréviations :</strong>",
        "rcfilters-other-review-tools": "<strong>Autres outils de relecture</strong>",
        "rcfilters-group-results-by-page": "Grouper les résultats par page",
        "rcfilters-empty-filter": "Aucun filtre actif. Toutes les contributions sont affichées.",
        "rcfilters-filterlist-title": "Filtres",
        "rcfilters-filterlist-whatsthis": "Comment ça marche ?",
-       "rcfilters-filterlist-feedbacklink": "Fournir un commentaire sur les nouveaux filtres (en bêta)",
+       "rcfilters-filterlist-feedbacklink": "Nous dire ce que vous pensez de ces (nouveaux) outils de filtrage",
        "rcfilters-highlightbutton-title": "Mettre en valeur les résultats",
        "rcfilters-highlightmenu-title": "Choisir une couleur",
        "rcfilters-highlightmenu-help": "Sélectionner une couleur pour mettre en évidence cette propriété",
        "rcfilters-filter-user-experience-level-unregistered-label": "Non connecté",
        "rcfilters-filter-user-experience-level-unregistered-description": "Éditeurs qui ne sont pas connectés.",
        "rcfilters-filter-user-experience-level-newcomer-label": "Nouveaux arrivants",
-       "rcfilters-filter-user-experience-level-newcomer-description": "Editeurs connectés avec moins de 10 modifications et 4 jours d’activité.",
+       "rcfilters-filter-user-experience-level-newcomer-description": "Éditeurs connectés avec moins de 10 modifications et 4 jours d’activité.",
        "rcfilters-filter-user-experience-level-learner-label": "Apprentis",
-       "rcfilters-filter-user-experience-level-learner-description": "Editeurs connectés dont l'expérience se situe entre  « Nouveaux arrivants » et  « Utilisateurs expérimentés ».",
+       "rcfilters-filter-user-experience-level-learner-description": "Éditeurs connectés dont l’expérience se situe entre  « Nouveaux arrivants » et  « Utilisateurs expérimentés ».",
        "rcfilters-filter-user-experience-level-experienced-label": "Utilisateurs expérimentés",
-       "rcfilters-filter-user-experience-level-experienced-description": "Editeurs connectés avec plus de 500 modifications et 30 jours d'activité.",
+       "rcfilters-filter-user-experience-level-experienced-description": "Éditeurs connectés avec plus de 500 modifications et 30 jours d’activité.",
        "rcfilters-filtergroup-automated": "Contributions automatisées",
        "rcfilters-filter-bots-label": "Robot",
        "rcfilters-filter-bots-description": "Modifications faites par des outils automatisés.",
        "rcfilters-filter-watchlist-notwatched-description": "Tout sauf des modifications de pages de la liste de suivi.",
        "rcfilters-filtergroup-watchlistactivity": "Activité sur la liste de suivi",
        "rcfilters-filter-watchlistactivity-unseen-label": "Modifications non-visibles",
-       "rcfilters-filter-watchlistactivity-unseen-description": "Modifications sur les pages que vous n'avez pas visitées depuis.",
+       "rcfilters-filter-watchlistactivity-unseen-description": "Modifications sur les pages que vous navez pas visitées depuis.",
        "rcfilters-filter-watchlistactivity-seen-label": "Voir les modifications",
        "rcfilters-filter-watchlistactivity-seen-description": "Modifications sur les pages que vous avez visitées depuis.",
        "rcfilters-filtergroup-changetype": "Type de modification",
        "rcfilters-liveupdates-button": "Mises à jour en direct",
        "rcfilters-liveupdates-button-title-on": "Désactiver les mises à jour à chaud",
        "rcfilters-liveupdates-button-title-off": "Afficher les nouveaux changements dès qu'ils se produisent",
-       "rcfilters-watchlist-markSeen-button": "Marquer toutes les modifications comme vues",
+       "rcfilters-watchlist-markseen-button": "Marquer toutes les modifications comme vues",
+       "rcfilters-watchlist-edit-watchlist-button": "Modifier votre liste de pages suivies",
+       "rcfilters-watchlist-showupdated": "Les modifications faites aux pages que vous n’avez pas visitées depuis qu’elles ont été modifiées sont en <strong>gras</strong>, avec des balises unies.",
        "rcnotefrom": "Ci-dessous {{PLURAL:$5|la modification effectuée|les modifications effectuées}} depuis le <strong>$3, $4</strong> (affichées jusqu’à <strong>$1</strong>).",
        "rclistfromreset": "Réinitialiser la sélection de la date",
        "rclistfrom": "Afficher les nouvelles modifications depuis le $3 à $2",
        "filehist-datetime": "Date et heure",
        "filehist-thumb": "Vignette",
        "filehist-thumbtext": "Vignette pour la version du $1",
-       "filehist-nothumb": "Pas de miniature",
+       "filehist-nothumb": "Aucune miniature",
        "filehist-user": "Utilisateur",
        "filehist-dimensions": "Dimensions",
        "filehist-filesize": "Taille du fichier",
        "unwatchthispage": "Ne plus suivre",
        "notanarticle": "Ce n'est pas une page de contenu",
        "notvisiblerev": "La dernière version relue par un utilisateur différent, a été supprimée",
-       "watchlist-details": "{{PLURAL:$1|$1 page|$1 pages}} dans votre liste de suivi, sans compter les pages de discussion.",
+       "watchlist-details": "{{PLURAL:$1|$1 page est|$1 pages sont}} dans votre liste de suivi (plus les pages de discussion).",
        "wlheader-enotif": "La notification par courriel est activée.",
        "wlheader-showupdated": "Les pages qui ont été modifiées depuis votre dernière visite sont affichées en <strong>gras</strong>.",
        "wlnote": "Ci-dessous {{PLURAL:$1|figure la dernière modification effectuée|figurent les <strong>$1</strong> dernières modifications effectuées}} durant {{PLURAL:$2|la dernière heure|les <strong>$2</strong> dernières heures}}, jusqu'au $3, $4.",
        "tooltip-pt-watchlist": "Une liste des pages dont vous suivez les modifications",
        "tooltip-pt-mycontris": "La liste de {{GENDER:|vos}} contributions",
        "tooltip-pt-anoncontribs": "Une liste des modifications effectuées depuis cette adresse IP",
-       "tooltip-pt-login": "Il est recommandé de vous identifier ; ce n'est cependant pas obligatoire.",
+       "tooltip-pt-login": "Sans être obligatoire, il est recommandé de vous connecter.",
        "tooltip-pt-login-private": "Vous devez vous connecter pour utiliser ce wiki",
        "tooltip-pt-logout": "Se déconnecter",
-       "tooltip-pt-createaccount": "Il vous est conseillé de créer un compte et de vous connecter ; cependant, ce n’est pas obligatoire",
+       "tooltip-pt-createaccount": "Sans être obligatoire, il vous est conseillé de créer un compte utilisateur pour vous connecter",
        "tooltip-ca-talk": "Discussion au sujet de cette page de contenu",
        "tooltip-ca-edit": "Modifier le wikicode",
        "tooltip-ca-addsection": "Commencer une nouvelle section",
        "tooltip-ca-viewsource": "Cette page est protégée.\nVous pouvez toutefois en visualiser la source.",
-       "tooltip-ca-history": "Les versions passées de cette page (avec leurs contributeurs)",
+       "tooltip-ca-history": "Historique des versions de cette page",
        "tooltip-ca-protect": "Protéger cette page",
        "tooltip-ca-unprotect": "Changer la protection de cette page",
        "tooltip-ca-delete": "Supprimer cette page",
        "tooltip-ca-watch": "Ajouter cette page à votre liste de suivi",
        "tooltip-ca-unwatch": "Retirer cette page de votre liste de suivi",
        "tooltip-search": "Rechercher dans {{SITENAME}}",
-       "tooltip-search-go": "Aller vers une page portant exactement ce nom si elle existe.",
+       "tooltip-search-go": "Accédez à une page du même nom si elle existe",
        "tooltip-search-fulltext": "Rechercher les pages comportant ce texte.",
-       "tooltip-p-logo": "Page principale",
+       "tooltip-p-logo": "Accueil général",
        "tooltip-n-mainpage": "Visiter la page d'accueil du site",
-       "tooltip-n-mainpage-description": "Aller à l'accueil",
-       "tooltip-n-portal": "À propos du projet, ce que vous pouvez faire, où trouver des informations",
-       "tooltip-n-currentevents": "Trouver les informations de fond sur l'actualité du moment",
+       "tooltip-n-mainpage-description": "Accueil général",
+       "tooltip-n-portal": "À propos du projet, ce que vous pouvez faire, où trouver les informations",
+       "tooltip-n-currentevents": "Trouver plus d'informations sur les actualités en cours",
        "tooltip-n-recentchanges": "Liste des modifications récentes sur le wiki",
        "tooltip-n-randompage": "Afficher une page au hasard",
-       "tooltip-n-help": "Aide",
+       "tooltip-n-help": "Accès à l'aide",
        "tooltip-t-whatlinkshere": "Liste des pages liées qui pointent sur celle-ci",
        "tooltip-t-recentchangeslinked": "Liste des modifications récentes des pages appelées par celle-ci",
        "tooltip-feed-rss": "Flux RSS pour cette page",
        "tooltip-t-contributions": "Voir la liste des contributions de {{GENDER:$1|cet utilisateur|cette utilisatrice}}",
        "tooltip-t-emailuser": "Envoyer un courriel à {{GENDER:$1|cet utilisateur|cette utilisatrice}}",
        "tooltip-t-info": "Plus d’information sur cette page",
-       "tooltip-t-upload": "Téléverser des fichiers",
+       "tooltip-t-upload": "Importer des fichiers",
        "tooltip-t-specialpages": "Liste de toutes les pages spéciales",
        "tooltip-t-print": "Version imprimable de cette page",
        "tooltip-t-permalink": "Adresse permanente de cette version de la page",
-       "tooltip-ca-nstab-main": "Voir la page de contenu",
+       "tooltip-ca-nstab-main": "Voir le contenu de la page",
        "tooltip-ca-nstab-user": "Voir la page utilisateur",
        "tooltip-ca-nstab-media": "Voir la page du média",
        "tooltip-ca-nstab-special": "Ceci est une page spéciale, et elle ne peut pas être modifiée.",
        "pageinfo-content-model-change": "modifier",
        "pageinfo-robot-policy": "Indexation par robots",
        "pageinfo-robot-index": "Autorisée",
-       "pageinfo-robot-noindex": "Interdite",
+       "pageinfo-robot-noindex": "Non autorisé",
        "pageinfo-watchers": "Nombre de contributeurs ayant la page dans leur liste de suivi",
        "pageinfo-visiting-watchers": "Nombre d’observateurs de la page ayant consulté les modifications récentes de la page",
        "pageinfo-few-watchers": "Moins de $1 {{PLURAL:$1|observateur|observateurs}}",
        "pageinfo-few-visiting-watchers": "Il peut ou non y avoir un observateur regardant les modifications récentes",
        "pageinfo-redirects-name": "Nombre de redirections vers cette page",
-       "pageinfo-subpages-name": "Sous-pages de cette page",
+       "pageinfo-subpages-name": "Nombre de sous-pages de cette page",
        "pageinfo-subpages-value": "$1 ($2 {{PLURAL:$2|redirection|redirections}}; $3 {{PLURAL:$3|non-redirection|non-redirections}})",
        "pageinfo-firstuser": "Créateur de la page",
        "pageinfo-firsttime": "Date de création de la page",
        "pageinfo-hidden-categories": "{{PLURAL:$1|Catégorie cachée|Catégories cachées}} ($1)",
        "pageinfo-templates": "{{PLURAL:$1|Modèle inclu|Modèles inclus}} ($1)",
        "pageinfo-transclusions": "{{PLURAL:$1|Page dans laquelle|Pages dans lesquelles}} cette page est incluse ($1)",
-       "pageinfo-toolboxlink": "Information sur la page",
+       "pageinfo-toolboxlink": "Plus d’informations",
        "pageinfo-redirectsto": "Rediriger vers",
        "pageinfo-redirectsto-info": "info",
        "pageinfo-contentpage": "Comptée comme page de contenu",
        "widthheightpage": "$1 × $2, $3 page{{PLURAL:$3||s}}",
        "file-info": "Taille du fichier : $1, type MIME : $2",
        "file-info-size": "$1 × $2 pixels, taille du fichier : $3, type MIME : $4",
-       "file-info-size-pages": "$1 × $2 pixels, taille de fichier : $3, type MIME : $4, $5 page{{PLURAL:$5||s}}",
+       "file-info-size-pages": "$1 × $2 pixels, taille du fichier : $3, type MIME: $4, $5 page{{PLURAL:$5||s}}",
        "file-nohires": "Pas de plus haute résolution disponible.",
        "svg-long-desc": "Fichier SVG, résolution de $1 × $2 pixels, taille : $3",
        "svg-long-desc-animated": "Fichier SVG animé, résolution $1 × $2 pixels, taille du fichier : $3",
        "feedback-thanks": "Merci ! Votre commentaire a été publié sur la page « [$2 $1] ».",
        "feedback-thanks-title": "Merci !",
        "feedback-useragent": "Agent utilisateur :",
-       "searchsuggest-search": "Rechercher sur {{SITENAME}}",
+       "searchsuggest-search": "Rechercher dans {{SITENAME}}",
        "searchsuggest-containing": "contenant...",
        "api-error-badtoken": "Erreur interne : mauvais « jeton ».",
        "api-error-emptypage": "Création de pages vide n'est pas autorisée.",
index b1c3880..8390907 100644 (file)
        "minoredit": "Utiye biloli'o ngo'idi",
        "watchthis": "Dahayi halaman botiye",
        "savearticle": "Tahuwa halaman",
+       "preview": "Bilohipo",
        "showpreview": "Bilohi pratayang",
        "showdiff": "Popobilohe u loboli'a",
        "anoneditwarning": "<strong>Mopo'eela:</strong> Yi'o diipo tilumuwo. Alamat IP olemu ma ontonga lo tawu daata wonu yi'o momoli'o. Wonu Yi'o <strong>[$1 tumuwoto log]</strong> meyalo <strong>[$2 mohutu akun]</strong>, u biloli'umu madiatribusikan ode tanggulumu, wolo huna uweewoliyo.",
+       "blockedtext": "'''Tanggulumu meyalo alamat IP ulemu ma diblokir.'''\n\nBlokir pilohutu lo $1.\nAlasani u yilohiliyo de'uwito ''$2''.\n\n* Blokir tilumula lonto: $8\n* Blokir mopulita to: $6\n* Sasaran pemblokiran: $7\n\nYi'o mowali mohubungi $1 meyalo [[{{MediaWiki:Grouppage-sysop}}|pengurus uweewo]] motombilu lo masalah botiye.\n\nYi'o ja mowali mopohuna fitur ''molawo surel ode pengguna botiye'' ngopohiya yi'o ma lopotuwoto alamat surel u sah to[[Special:Preferences|preferensi akun]] wawu yi'o didu diblokir mopomake.\n\nAlamat IP ulemu de'uwito $3, wawu ID pemblokiran de'uwito $5.\nWuduwa mayi tala tuwawu meyalo oluwo lo habari botiye to timi'idu yiyintu monto olemu.",
        "loginreqlink": "tumuwoto log",
        "newarticletext": "Yi'o lodudu'a wumbuta ode halaman diya'a. \nWonu mohutu halaman botiye, ketik tuwango halaman to kotak to tibawa botiye (bilohi [$1 halaman wubodu] ode habari wumbutiyo). \nWonu Yi'o ja sangaja tilumuwota ode halaman botiye, kutiya tombol <strong>mohuwalingo</strong>.",
+       "anontalkpagetext": "---\n<em>Utiya halaman lo'iya ode pengguna anonim ta diipo lohutu akun, meyalo tita ta ja lopohuna.<em>\nSababu uwito, ami lopohuna alamat IP u pilomakeliyo molapu oliyo.\nAlamat IP odito mowali pomake lotawu ngolo lota pe'eenta.\nWonu yi'o pengguna anonim wawu lorasa lo'iya lotawu ja mopiyohu ode olemu, toduwolo [[Special:CreateAccount|create a account]] meyalo [[Special:UserLogin|log in]] alihu mopelehiya u molilingu wolo pengguna anonim to sa'ati tuwawu.",
        "noarticletext": "Sa'ati botiye diya'a teks to halaman botiye.\nYi'o mowali [[Special:Search/{{PAGENAME}}|mololohu  judul halaman botiye]] to halaman-halaman uweewo, <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} mololohu log a'ayita], meyalo [{{fullurl:{{FULLPAGENAME}}|action=edit}} mohutu halaman botiye]</span>.",
        "noarticletext-nopermission": "!Sa'ati botiye diya'a teks to halaman boptiye.\nYi'o mowali [[Special:Search/{{PAGENAME}}|mololohu judul halaman botiye]] to halaman-halaman uweewo, meyalo <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} mololohu log a'ayita]</span>, dabo Yi'o ja o ijin mohutu halaman botiye.",
        "userpage-userdoesnotexist-view": "Ta ohu'uwo \"$1\" diyaalu to daputari.",
+       "clearyourcache": "<strong>Tuladu:</strong>Yilapato tilahu, yi'o musti lumawode to cache browser web bolo mo'oonto u yiloboli'a.\n* <strong>Firefox/Safari:</strong> Tahan <em>Shift</em> to'u yiloduto <em>Reload</em>, meyalo woduta <em>Ctrl-F5</em> meyalo <em>Ctrl-R</em> (<em>⌘-R</em> di Mac)\n* <strong>Google Chrome:</strong> Woduta <em>Ctrl-Shift-R</em> (<em>⌘-Shift-R</em> di Mac)\n* <strong>Internet Explorer:</strong> Woduta <em>Ctrl</em> to'u yiloduto <em>Refresh</em>, meyalo woduta <em>Ctrl-F5</em>\n* <strong>Opera:</strong> Pergi ke <em>Menu → Settings </em> (<em>Opera → Preferences</em> di Mac) lalu ke <em>Privacy & security → Clear browsing data → Cached images and files</em>.",
+       "previewnote": "<Strong>Elayi utiye bo mopobilohu.<strong>\nU biloli'umu diipo tilahu!",
+       "continue-editing": "Ntali ode area momoli'o",
        "editing": "Momoli'o $1",
        "creating": "Mohutu $1",
        "editingsection": "Momoli'o $1 (tayadu)",
        "yourdiff": "Hihede",
        "templatesused": "{{PLURAL:$1|Template}} pilopohuna to halaman botiye:",
+       "templatesusedpreview": "{{PLURAL:$1|Template|Templates}} pilomake to'u mopobilohu.",
        "template-protected": "(he dahalo)",
        "template-semiprotected": "(dahalo-ngowa)",
        "hiddencategories": "Halaman botiye woluwo anggota {{PLURAL:$1|1 kategori wanto-wanto'o $1}}:",
+       "permissionserrors": "Tilala haku momu'o",
        "permissionserrorstext-withaction": "Yi'o ja haku akses $2, sababu {{PLURAL:$1|alasani}} botiya:",
-       "moveddeleted-notice": "Halaman botiye ma yiluluto.\nSebagai referensi, botiya log piloluluta wawu piloheyiya halaman botiye.",
+       "recreate-moveddeleted-warn": "<Strong>Mopo'ota: Yi'o lohutu ulangi hlaman u ma yiluluto.<strong>\n\nPopotimbangiyapo huhutumu botiye delo mowali poturusiyolo.\nBotiya log piloluluta wawu piloheyiya halaman botiye.",
+       "moveddeleted-notice": "Halaman botiye ma yiluluto.\nLog piloluluta, pilodahawa wawu piloheyiya halaman botiye woluwo to tibawa pohutu referensi.",
        "postedit-confirmation-saved": "Biloli'umu ma tilahu.",
        "edit-already-exists": "Ja mowali mohutu halaman bohu. Ma woluwo.",
        "content-model-wikitext": "tuladu wiki",
+       "undo-failure": "U biloli'a botiya ja mowali pohuwalingo sababu lodulehe ta lomoli'o.",
        "viewpagelogs": "Bilohi log lo halaman botiye",
        "currentrev-asof": "Biloli'o pulitiyo to $1",
        "revisionasof": "Biloli'o to $1",
        "currentrevisionlink": "Biloli'o pulitiyo",
        "cur": "mst",
        "last": "diipo",
+       "histlegend": "Tulawota diff: Tuwoti kasi lo radio loboli'a u mopobandingiyo wawu woduta enter meyalo tombol to tibawa.<br />\nLegenda: <strong>({{int:cur}})</strong> = hihede wolo biloli'a pulitiyo, <strong>({{int:last}})</strong> = hihede wolo u biloli'a muloolo, <strong>{{int:minoreditletter}}</strong> = bilili'o ngo'idi.",
        "history-fieldset-title": "Lolohe u biloli'o",
        "histfirst": "mohihewo da'a",
        "histlast": "bohu da'a",
        "history-feed-description": "Riwayati bilolio to halaman wiki botiye",
        "history-feed-item-nocomment": "$1 to $2",
        "rev-delundel": "popobilohe/wanto'a",
+       "mergelog": "Log mopohimbunguwo",
        "history-title": "Riwayati lo'u loboli'a lonto \"$1\"",
        "difference-title": "$1 hihede revisi",
        "lineno": "Baarisi $1:",
        "compareselectedversions": "Popotadenga u tilulawoto",
        "editundo": "pohuwalinga",
+       "diff-empty": "(Diya'a hihedeliyo)",
        "diff-multi-sameuser": "({{PLURAL:$1|$1 revisi wolota}} pilohutu lo tawu ngota ja pilopobilohu)",
+       "diff-multi-otherusers": "({{PLURAL:$1|Tuwawu lopo'opiyohu wolota|$1 lopo'opiyohu wolota}} pilohutu {{PLURAL:$2|ngota ta ohu'uwo uweewo|$2 ta ohu'uwo}} ja pilopobilohu)",
        "searchresults": "U yilotapu",
        "searchresults-title": "U yilotapu lololohe \"$1\"",
        "prevn": "{{PLURAL:$1|$1}} to'udiipo",
        "nextn": "{{PLURAL:$1|$1}} lapatiyoma'o",
+       "prevn-title": "To'u diipo $1 {{PLURAL:$1|hasili}}",
        "nextn-title": "$1 {{PLURAL:$1|hasili}}lapatiyoma'o",
        "shown-title": "Popobilohe $1 {{PLURAL:$1|haasili}} per halaman",
        "viewprevnext": "Bilohi ($1 {{int:pipe-separator}} $2) ($3)",
+       "searchmenu-exists": "<strong>Woluwo halaman otanggula \"[[:$1]]\" to wiki botiye. </ strong> {{PLURAL: $2|0=|Bilohi olo u yilotapu uweewo.}}",
        "searchmenu-new": "<strong>mohutu halaman \"[[:$1]]\" to wiki botiya! {{PLURAL:$2|0=Bilohi halaman u yilotapu yilolohumu.|Bilohi hasili u yilotapu to'u yilolohu}}",
        "searchprofile-articles": "Tuwango halaman",
        "searchprofile-images": "Multimedia",
        "searchprofile-everything-tooltip": "Mololohe nga'amila tuwango situs (wolo halaman polo'iyalo)",
        "searchprofile-advanced-tooltip": "Mololohu to huwali lo tanggulo biasa",
        "search-result-size": "$1 ({{PLURAL:$2|1 tahe|$2 tahe}})",
+       "search-result-category-size": "{{PLURAL:$1|1 anggota|$1 anggota}} ({{PLURAL:$2|1 subkategori|$2 subkategori}}, {{PLURAL:$3|1 berkas|$3 berkas}})",
        "search-redirect": "(pilobale lonto $1)",
        "search-section": "(tayadu) $1",
        "search-file-match": "(sama lo tuwango berkas)",
        "default": "kakali",
        "yourrealname": "Tanggula banari",
        "yourlanguage": "Bahasa",
+       "group-bot": "Bot",
+       "group-sysop": "Pengurus",
        "grouppage-bot": "{{ns:project}}:Bot",
+       "grouppage-sysop": "{{ns:project}}:Pengurus",
        "right-writeapi": "Mopohuna API moluladu",
        "newuserlogpage": "Log ta ohu'uwo bohu",
+       "rightslog": "Log haku ta ohu'uwo",
        "action-edit": "boli'a halaman botiye",
+       "action-createaccount": "mohutu akun lo ta ohu'uwo botiya",
        "enhancedrc-history": "riwayati",
        "recentchanges": "Boheli loboli'a mola",
        "recentchanges-legend": "Tulawotolo boheli loboli'a mola",
        "recentchanges-label-plusminus": "Loboli'o tu'udu halaman boti to delomo bita",
        "recentchanges-legend-heading": "<strong>Keterangan:</strong>",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (bilohi olo [[Special:NewPages|list of new pages]])",
+       "rcnotefrom": "To tibawa botiye {{PLURAL:$5|loboli'a}} anggadu <strong>$3, $4</strong> (popobilohe sambe <strong>$1</strong> loboli'a).",
        "rclistfrom": "Popobilohe u loboli'a lonto $2, $3",
        "rcshowhideminor": "$1 biloli'o ngo'idi",
        "rcshowhideminor-show": "Popobilohe",
        "rcshowhideanons": "$1 biloli'o lo tawu weewo",
        "rcshowhideanons-show": "Popobilohe",
        "rcshowhideanons-hide": "Wanto'a",
+       "rcshowhidepatr": "$1 biloli'o terpatroli",
        "rcshowhidemine": "$1 biloli'u'u",
        "rcshowhidemine-show": "Popobilohe",
        "rcshowhidemine-hide": "Wanto'a",
        "rc-change-size-new": "$1 {{PLURAL:$1|bita}} lapato biloli'o",
        "rc-old-title": "bohuliyo pilohutu odelo \"$1\"",
        "recentchangeslinked": "Loboli'a wayitiyo",
+       "recentchangeslinked-feed": "Loboli'a wayitiyo",
        "recentchangeslinked-toolbox": "Loboli'o wayitiyo",
        "recentchangeslinked-title": "Loboli'a a'aayita wolo $1",
        "recentchangeslinked-summary": "Utiye daputari lo'ubawa to halaman a'ayita wolo halaman tuwawu (meyalo tayadu to kategori tuwawu)\nHalaman to [[Special:Watchlist|he'awasiyamu]] ontonga <strong>cetakiya mohulodu</strong>.",
        "license": "Lisensi",
        "license-header": "Tayadu lisensi",
        "imgfile": "berkas",
+       "listfiles": "Daputari berkas",
        "file-anchor-link": "Berkas",
        "filehist": "Riwaayati lo berkas",
        "filehist-help": "Klik to tanggal/wakutu momilohe berkas to saa'ati botiye.",
        "filehist-datetime": "Tanggal/Wakutu",
        "filehist-thumb": "Kiki'o",
        "filehist-thumbtext": "u kiki'o versi lo $1",
+       "filehist-nothumb": "Diya'a gambari kikino",
        "filehist-user": "Ta ohu'uwo",
        "filehist-dimensions": "Dimensi",
        "filehist-comment": "Lo'iya",
        "imagelinks": "Berkas u pilopohuna",
        "linkstoimage": "{{PLURAL:$1|halaman lapatiyoma'o}} o wumbuta ode berkas botiye:",
+       "linkstoimage-more": "Limbata lo $1 {{PLURAL:$1|halaman}} o wumbuta ode berkas botiye.\nDaputari botiya mopobilohu {{PLURAL:$1|wumbuta halaman bungaliyo}} ode berkas botiye wamba'o.\nWoluwo [[Special:WhatLinksHere/$2|daputari ganapu]] u sadi-sadiya.",
        "nolinkstoimage": "Diya'a halaman u owumbuta ode berkas botiye",
+       "linkstoimage-redirect": "$1 (mopobale berkas) $2",
        "sharedupload-desc-here": "Berkas botiye lonto $1 wawu hepohunaliyo to poroyek uweewo.\nDeskripsi lonto [$2 halaman deskripsiliyo] woluwo to tibawa botiya.",
        "filepage-nofile": "Diya'a berkas lo tanggula botiye",
        "upload-disallowed-here": "Yi'o diila mowali modeehe berkas botiye",
        "randompage": "Halaman totonula",
        "statistics": "Statistik",
+       "double-redirect-fixer": "Revisi mopobale",
        "nbytes": "$1 {{PLURAL:$1|bita}}",
        "nmembers": "$1 {{PLURAL:$1|tuwango}}",
+       "prefixindex": "Nga'amila halaman woluwo awalan",
        "listusers": "Daputari ta ohu'uwo",
        "newpages": "Halaman bohu",
        "move": "Heyiya",
        "booksources": "Bungo buku",
        "booksources-search-legend": "Lolohe to bungo lo buku",
        "booksources-search": "Lolohe",
+       "specialloguserlabel": "Ta ohu'uwo",
+       "speciallogtitlelabel": "Target (judul meyalo{{ns:ta ohu'uwo}}:tanggulo ta ohu'uwo ode ta ohu'uwo)",
        "log": "Log",
        "all-logs-page": "Nga'amila log publik",
+       "alllogstext": "Himbunguwa nga'amila log u sadi-sadiya to {{SITENAME}}.\nYi'o mowali mopo'okikingo bibilohu lo'u molulawota tayadu log, tanggulo ta ohu'uwo (sensitif kapitalisasi), meyalo judul halaman (sensitif kapitalisasi olo).",
+       "logempty": "Ja yilotapu entri log u mohumayawa.",
        "allpages": "Nga'amila halaman",
        "allarticles": "Nga'amila halaman",
        "allpagessubmit": "Ntali",
+       "allpages-hide-redirects": "Wanto'a mopobale",
        "categories": "Kategori",
+       "listgrouprights-members": "(daputari lo anggota)",
+       "emailuser": "Lawola surel ta ohu'uwo botiye",
        "usermessage-editor": "Sistem lo tahuli",
        "watchlist": "U he'awasiyalo",
        "mywatchlist": "Daputari he'awasiyalo",
+       "watchlistfor2": "Ode $1 $2",
        "watch": "Dahayi",
        "unwatch": "Batali mongawasi",
+       "watchlist-details": "{{PLURAL:$1|$1 halaman}} to dputari he'awasiyamu, ja wayitiyo halaman lo'iya.",
+       "wlheader-showupdated": "Halaman ma loboli'a to pulitiyo nila'omu mowali bilohela to <strong>bold</strong>.",
+       "wlnote": "To tibawa botiye {{PLURAL:$1|loboli'a|<strong>$1</strong> loboli'a}} pulitiyo to delomo {{PLURAL:$2|jam|<strong>$2</strong> jam}}, per $3, $4.",
        "wlshowlast": "Popobilohe $1 jam $2 dulahe pulitiyo",
+       "watchlist-options": "Tulawoto daputari he'awasiyalo",
+       "enotif_reset": "Tuwoti nga'amila halaman ma nila'o",
        "dellogpage": "Log loluluto",
        "rollbacklink": "wuwalinga",
        "rollbacklinkcount": "pohuwalinga $1 {{PLURAL:$1|biloli'o}}",
        "protectlogpage": "Log mopo'aamani",
        "protectedarticle": "modaha \"[[$1]]\"",
+       "modifiedarticleprotection": "momoli'a lenggota lo dudaha ode \"[[$1]]\"",
        "protect-default": "Poluliya nga'amila ta ohu'uwo",
        "restriction-edit": "Boli'a",
        "restriction-move": "Heyiya",
        "tooltip-namespace_association": "Centang halaman botiye u mopowayito huwali lo tanggulo lo'iyawa meyalo subjek u a'ayita wolo huwali lo tanggulo u tilulawoto.",
        "blanknamespace": "(Bungaliyo)",
        "contributions": "Kontribusi {{GENDER:$1|Ta ohu'uwo}}",
+       "contributions-title": "Kontribusi ta ohu'uwo ode $1",
        "mycontris": "Kontribusi",
        "anoncontribs": "Kontribusi",
        "contribsub2": "Ode {{GENDER:$3|$1}} ($2)",
+       "nocontribs": "Diya'a u loboli'a mohumayawa lo kriteria botiya.",
        "uctop": "(masatiya)",
        "month": "Lonto hulalo (wawu to'udiipo)",
        "year": "Lonto taawunu (wawu to'udiipo)",
        "whatlinkshere-hideimages": "$1 berkas wumbuta",
        "whatlinkshere-filters": "U'ayahu",
        "ipboptions": "2 jam:2 hours,1 huyi:1 day,3 huyi:3 days,1 diminggu:1 week,2 diminggu:2 weeks,1 hula:1 month,3 hula:3 months,6 hula:6 months,1 taawunu:1 year,layito:infinite",
+       "infiniteblock": "ja to enggade",
        "blocklink": "tangguwalo",
        "contribslink": "kontrib",
        "blocklogpage": "Bubuli log",
        "blocklogentry": "momubulo [[$1]] wolo pulito wakutu $2 $3",
+       "reblock-logentry": "momoli'o blokir [[$1]] wolo wakutu pulitiyo $2 $3",
+       "block-log-flags-nocreate": "mohutu akun pilateyaliyo",
        "proxyblocker": "Bubulo proxi",
        "movelogpage": "Log piloheyiya",
        "export": "Ekspor halaman",
        "thumbnail-more": "Po'odamanga",
+       "importlogpage": "Log impor",
        "tooltip-pt-userpage": "Halaman {{GENDER:|Yi'o ta ohu'uwo}}",
        "tooltip-pt-mytalk": "Halaman {{GENDER:|posilitamu}}",
        "tooltip-pt-preferences": "Preferensi{{GENDER:|Yi'o}}",
        "tooltip-t-recentchangeslinked": "Boheli loboli'a mola to halaman owumbuta ode halaman botiye",
        "tooltip-feed-atom": "Paalo atom ode halaman botiya",
        "tooltip-t-contributions": "Daputari kontribusi {{GENDER:$1|ta ohu'uwo botiye}}",
+       "tooltip-t-emailuser": "Lawola surel ode {{GENDER:$1|ta ohu'uwo botiye}}",
        "tooltip-t-upload": "Detohe berkas-berkas",
        "tooltip-t-specialpages": "Daputari nga'amila halaman spesial",
        "tooltip-t-print": "Persi ciletaki halaman botiye",
        "tooltip-ca-nstab-mediawiki": "Bilohi tahuli lo sistem",
        "tooltip-ca-nstab-template": "Bilohi template",
        "tooltip-ca-nstab-category": "Bilohi kategori halaman",
+       "tooltip-minoredit": "Tuwoti utiye biloli'a kiki'o",
        "tooltip-save": "Tahuwa u biloli'umu",
        "tooltip-preview": "Bilohipo u biloli'umu. Popopasiya utiye to'u diipo molahu.",
        "tooltip-diff": "Bilohi u loboli'o pilohutumu",
        "simpleantispam-label": "Momarakisa anti-spam.\n<strong>kekeya</strong> tuwangalo!",
        "pageinfo-title": "Informasi untuk \"$1\"",
        "pageinfo-header-basic": "Bungo lo habari",
+       "pageinfo-header-edits": "Riwayati lomoli'o",
        "pageinfo-header-restrictions": "Dudaha halaman",
+       "pageinfo-header-properties": "Properti halaman",
        "pageinfo-display-title": "Judul bibilohu",
+       "pageinfo-default-sort": "Tunuhe u'unti kakali",
        "pageinfo-length": "Haya'o halaman (to delomo bita)",
        "pageinfo-article-id": "ID Halaman",
        "pageinfo-language": "Bahasa tuwango halaman",
+       "pageinfo-content-model": "Model tuwango halaman",
        "pageinfo-robot-policy": "Pengindeksan monto robot",
+       "pageinfo-robot-index": "Mowali (lo'otapu ijini)",
+       "pageinfo-robot-noindex": "Ja mowali",
        "pageinfo-watchers": "Jumula lo ta hemongawasi halaman",
+       "pageinfo-few-watchers": "I'ilangi to'u $1 {{PLURAL:$1|pengunjung}}",
        "pageinfo-redirects-name": "Jumula u pilobale ode halaman botiya",
+       "pageinfo-subpages-name": "Nomoro meyalo tayadu halaman botiye",
+       "pageinfo-subpages-value": "$1 ($2 {{PLURAL:$2|mopobale}}; $3 {{PLURAL:$3|non-mopobale}})",
+       "pageinfo-firstuser": "Ta lohutu halaman",
        "pageinfo-firsttime": "Tanggal pilohutuwa halaman",
+       "pageinfo-lastuser": "Ta lolulade pulitiyo",
+       "pageinfo-lasttime": "Tanggal lomoli'a pulitiyo",
+       "pageinfo-edits": "Jumula nga'amila u biloli'o",
+       "pageinfo-authors": "Jumula nga'amila ta hepolulade hihihede",
        "pageinfo-recent-edits": "Jumula boheli biloli'a mola (to delomo $1 pulitiyo)",
+       "pageinfo-recent-authors": "Jumula lo ta hepolulade bohu hihihede",
+       "pageinfo-magic-words": "{{PLURAL:$1|kata}} ajaib ($1)",
+       "pageinfo-hidden-categories": "{{PLURAL:$1|dalala}} wanto-wanto'o ($1)",
+       "pageinfo-templates": "{{PLURAL:$1|templat}} yang ditransklusi ($1)",
        "pageinfo-toolboxlink": "Halaman habari",
+       "pageinfo-contentpage": "Yirekeni odelo halaman konten",
        "pageinfo-contentpage-yes": "Jo",
+       "patrol-log-page": "Log patroli",
        "previousdiff": "← Biloli'o to'udiipo",
        "nextdiff": "Biloli'o lapatiyoma'o →",
+       "widthheightpage": "$1 × $2, $3 {{PLURAL:$3|halaman}}",
        "file-info-size": "$1 x $2 piksel, tu'udu berkas:$3, MIME tipe: $4",
+       "file-info-size-pages": "$1 × $2 piksel, ukuran berkas: $3, tipe MIME: $4, $5 {{PLURAL:$5|halaman}}",
        "file-nohires": "Diya'a resolusi damango",
        "svg-long-desc": "Berkas SGV, nominal $1 x $2 piksel, damango berkas:$3",
        "show-big-image": "Berkas asli",
        "exif-orientation-1": "Normal",
        "namespacesall": "nga'amila",
        "monthsall": "nga'amila",
+       "imgmultipagenext": "halaman wumbutiyo",
+       "imgmultigo": "Ntali",
+       "imgmultigoto": "Ntali ode halaman $1",
+       "watchlisttools-clear": "Luluta daputari he'awasiyalo",
+       "watchlisttools-view": "Popobilohe u loboli'a wayitiyo",
+       "watchlisttools-edit": "Popobilohe wawu boli'a daputari he'awasiyalo",
+       "watchlisttools-raw": "Boli'a daputari he'awasiyalo meenggo",
        "signature": "[[{{ns:user}}:$1|$2]] ([[{{ns:user_talk}}:$1|bisala]])",
+       "redirect": "Lopobale payu ID berkas, ta ohu'uwo, halaman, revisi, meyalo log",
+       "redirect-summary": "Halaman istimewa botiye loheyi ode berkas (odelo tanggulo berkasliyo), halaman (sesuai ID revisinya), meyalo halaman pengguna (sesuai ID numerik penggunanya). Penggunaan: [[{{#Special:Redirect}}/file/Example.jpg]], [[{{#Special:Redirect}}/revision/328429]], meyalo[[{{#Special:Redirect}}/user/101]].",
        "redirect-submit": "Ntali",
        "redirect-lookup": "Yilolohu",
+       "redirect-value": "Niai",
+       "redirect-user": "ID lo ta ohu'uwo",
        "redirect-page": "ID Halaman",
        "redirect-revision": "Halaman biloli'o",
        "redirect-file": "Tanggulo berkas",
        "tag-filter": "[[Special:Tags|Tag]]filter:",
        "tag-list-wrapper": "([[Special:Tags|{{PLURAL:$1|Tag}}]]: $2)",
        "tags-active-yes": "Jo",
+       "tags-active-no": "De'e",
+       "tags-hitcount": "$1 {{PLURAL:$1|boli'o|loboli'a}}",
        "logentry-delete-delete": "$1 {{GENDER:$2|moluluto}}halaman $3",
+       "logentry-delete-restore": "$1 {{GENDER:$2|mopowuwalingo}} halaman $3 ($4)",
+       "logentry-delete-revision": "$1 {{GENDER:$2|momoli'o}} bibilohu {{PLURAL:$5|$5  revisi}} to halaman $3: $4",
        "revdelete-content-hid": "tuwango yilanto'o",
        "logentry-move-move": "$1 {{GENDER:$2|moheyi}} halaman $3 ode $4",
        "logentry-move-move-noredirect": "$1 {{GENDER:$2|loheyi}} halaman $3 ode $4 ja lohutu pengalihan",
        "logentry-move-move_redir": "$1 {{GENDER:$2|loheyi}} halaman $3 ode $4 lodeehu pengalihan",
+       "logentry-patrol-patrol-auto": "$1 otomatis {{GENDER:$2|tuwoti}} biloli'o $4 lonto halaman $3 pilatroli",
        "logentry-newusers-create": "Ta ohu'uwo akun $1 {{GENDER:$2|mohutu}}",
        "logentry-newusers-autocreate": "Akun $1 {{GENDER:$2|pilohutu}} otomatis",
        "logentry-upload-upload": "$1 {{GENDER:$2|mengunggah}} $3",
+       "logentry-upload-overwrite": "$1 {{GENDER:$2|mopodetohu}} versi bohu lo $3",
        "searchsuggest-search": "Lolohe {{SITENAME}}",
        "duration-days": "$1 {{PLURAL:$1|huyi}}",
        "randomrootpage": "Halaman totonulalo"
index 6bfcda3..27758c3 100644 (file)
@@ -30,7 +30,8 @@
                        "Matma Rex",
                        "Bhatakati aatma",
                        "YmKavishwar",
-                       "Kevin Kovadia"
+                       "Kevin Kovadia",
+                       "Drashti4"
                ]
        },
        "tog-underline": "કડીઓની નીચે લીટી (અંડરલાઇન):",
@@ -48,6 +49,8 @@
        "tog-watchdefault": "હું ફેરફાર કરૂં તે પાનાં અને ફાઇલ્સ મારી ધ્યાનસૂચિમાં ઉમેરો",
        "tog-watchmoves": "હું ખસેડું તે પાનાં અને ફાઇલ્સ મારી ધ્યાનસૂચિમાં ઉમેરો",
        "tog-watchdeletion": "હું દૂર કરું તે પાનાં અને ફાઇલ્સ મારી ધ્યાનસૂચિમાં ઉમેરો",
+       "tog-watchuploads": "મારી જોવાનીસૂચિ પર અપલોડ કરેલી નવી ફાઇલોને ઉમેરો",
+       "tog-watchrollback": "પૃષ્ઠોને ઉમેરો જ્યાં મેં મારી જોવાની સૂચિમાં રોલબેક કર્યું છે",
        "tog-minordefault": "બધા નવા ફેરફારો નાના તરીકે માર્ક કરો.",
        "tog-previewontop": "ફેરફાર પેટી પહેલાં પૂર્વાલોકન દર્શાવો",
        "tog-previewonfirst": "પ્રથમ ફેરફાર વખતે પૂર્વાલોકન બતાવો",
        "tog-shownumberswatching": "ધ્યાન રાખતા સભ્યોની સંખ્યા બતાવો",
        "tog-oldsig": "તમારા હાલના હસ્તાક્ષર:",
        "tog-fancysig": "હસ્તાક્ષરનો વિકિલખાણ તરીકે ઉપયોગ કરો (સ્વચાલિત કડી વગર)",
-       "tog-uselivepreview": "àª\9cà«\80વàª\82ત àªªà«\82રà«\8dવદરà«\8dશન àªµàª¾àªªàª°ો",
+       "tog-uselivepreview": "પà«\83ષà«\8dઠ àª«àª°à«\80થà«\80 àª²à«\8bડ àª\95રà«\8dયા àªµàª\97ર àªªà«\82રà«\8dવાવલà«\8bàª\95નà«\8b àª¬àª¤àª¾àªµો",
        "tog-forceeditsummary": "કોરો 'ફેરફાર સારાંશ' ઉમેરતા પહેલા મને ચેતવો",
        "tog-watchlisthideown": "'મારી ધ્યાનસુચી'માં મે કરેલા ફેરફારો છુપાવો",
        "tog-watchlisthidebots": "ધ્યાનસુચીમાં બોટ દ્વારા થયેલા ફેરફાર સંતાડો.",
        "tog-watchlisthideminor": "'મારી ધ્યાનસુચી'માં નાનાં ફેરફારો છુપાવો",
        "tog-watchlisthideliu": "લોગ થયેલા સભ્ય દ્વારા કરવામાં આવેલ ફેરફાર ધ્યાનસુચીમાં છુપાવો.",
+       "tog-watchlistreloadautomatically": "જ્યારેપણ ફિલ્ટર બદલાઈ જાય ત્યારે આપમેળે જોવાની સૂચિ ફરીથી લોડ કરો (JavaScript આવશ્યક છે)",
+       "tog-watchlistunwatchlinks": "દૃશ્યયાદી પ્રવેશોમાં સીધી નિષ્ક્રિય/દૃશ્ય લિંક્સ ઉમેરો (ટૉગલ કાર્યક્ષમતા માટે આવશ્યક JavaScript)",
        "tog-watchlisthideanons": "અજાણ્યા સભ્ય દ્વારા થયેલ ફેરફાર મારી ધ્યાનસુચીમાં છુપાવો",
        "tog-watchlisthidepatrolled": "સુરક્ષા કાજે કરવામાં આવેલ ફેરફાર મારી ધ્યાનસુચીમાં છુપાવો",
        "tog-watchlisthidecategorization": "પાનાંઓનું વર્ગીકરણ છુપાવો",
        "october-date": "ઓક્ટોબર $1",
        "november-date": "નવેમ્બર $1",
        "december-date": "ડિસેમ્બર $1",
+       "period-am": "સવારે",
+       "period-pm": "સાંજે",
        "pagecategories": "{{PLURAL:$1|શ્રેણી|શ્રેણીઓ}}",
        "category_header": "શ્રેણી \"$1\" ના પાનાં",
        "subcategories": "ઉપશ્રેણીઓ",
        "talk": "ચર્ચા",
        "views": "દેખાવ",
        "toolbox": "સાધનો",
+       "tool-link-userrights": "બદલો {{GENDER:$1|સભ્ય}} સમુહો",
+       "tool-link-userrights-readonly": "દેખાડો {{GENDER:$1|સભ્ય}} સમુહો",
        "tool-link-emailuser": "આ {{GENDER:$1|સભ્ય}}ને ઇમેલ કરો",
        "imagepage": "ફાઇલનું પાનું જુઓ",
        "mediawikipage": "સંદેશનું પાનું જુઓ",
        "virus-scanfailed": "સ્કેન અસફળ (code $1)",
        "virus-unknownscanner": "અજાણ્યું એન્ટીવાઇરસ:",
        "logouttext": "'''તમે સફળતાપૂર્વક બહાર નીકળી ચૂક્યા છો.'''\n\nધ્યાન રાખો કે જ્યાં સુધી તમે તમારા બ્રાઉઝરની કૅશ સાફ નહીં કરો ત્યાં સુધી કેટલાક પાનાં તમે પ્રવેશ કરેલો છે તેમ બતાવશે.",
+       "cannotlogoutnow-title": "હવે લૉગ આઉટ કરી શકાતું નથી",
+       "cannotlogoutnow-text": "$1 નો ઉપયોગ કરતી વખતે લૉગ આઉટ શક્ય નથી.",
        "welcomeuser": "સુસ્વાગતમ્, $1!",
        "welcomecreation-msg": "તમારૂં ખાતું ખુલી ગયું છે.\nતમારી [[Special:Preferences|{{SITENAME}} પસંદ]] બદલવાનું ભૂલશો નહીં.",
        "yourname": "સભ્ય નામ:",
        "createacct-yourpasswordagain-ph": "પાસવર્ડ ફરીથી દાખલ કરો",
        "userlogin-remembermypassword": "મને પ્રવેશિત રાખો",
        "userlogin-signwithsecure": "સલામત જોડાણ વાપરો",
+       "cannotlogin-title": "લૉગ ઇન કરી શકતા નથી",
+       "cannotlogin-text": "લોગ ઇન કરવું શક્ય નથી.",
+       "cannotloginnow-title": "હવે લૉગ ઇન કરી શકાતું નથી",
+       "cannotloginnow-text": "$1 નો ઉપયોગ કરતી વખતે લૉગ ઇન શક્ય નથી.",
+       "cannotcreateaccount-title": "ખાતું ખોલી શકાય તેમ નથી",
        "yourdomainname": "તમારૂં ડોમેઇન:",
        "password-change-forbidden": "તમે આ વિકિ માટે પાસવર્ડ્સ બદલી શકતા નથી.",
        "externaldberror": "પ્રમાણભૂતતાની ત્રુટી આવી અથવા તમારૂ બહારનુ ખાતું અપડેટ કરવાનો અધિકાર તમને નથી.",
        "recentchangeslinked-feed": "આની સાથે જોડાયેલા ફેરફાર",
        "recentchangeslinked-toolbox": "આની સાથે જોડાયેલા ફેરફાર",
        "recentchangeslinked-title": "\"$1\" ને લગતા ફેરફારો",
-       "recentchangeslinked-summary": "આ એવા ફેરફારોની યાદી છે જે આ ચોક્કસ પાના (કે શ્રેણીનાં સભ્ય પાનાઓ) સાથે જોડાયેલા પાનાઓમાં તાજેતરમાં કરવામાં આવ્યા હોય.\n[[Special:Watchlist|તમારી ધ્યાનસૂચિમાં]] હોય તેવા પાનાં '''ઘાટા અક્ષર'''માં વર્ણવ્યાં છે.",
+       "recentchangeslinked-summary": "આ એવા ફેરફારોની યાદી છે જે આ ચોક્કસ પાના (કે શ્રેણીનાં સભ્ય પાનાઓ) સાથે જોડાયેલા પાનાઓમાં તાજેતરમાં કરવામાં આવ્યા હોય.\n[[Special:Watchlist|તમારી ધ્યાનસૂચિમાં]] હોય તેવા પાનાં <strong>ઘાટા અક્ષર</strong>માં વર્ણવ્યાં છે.",
        "recentchangeslinked-page": "પાનાનું નામ:",
        "recentchangeslinked-to": "આને બદલે આપેલા પાનાં સાથે જોડાયેલા લેખોમાં થયેલા ફેરફારો શોધો",
        "upload": "ફાઇલ ચડાવો",
        "apisandbox-examples": "ઉદાહરણો",
        "apisandbox-results": "પરિણામો",
        "booksources": "પુસ્તક સ્રોત",
-       "booksources-search-legend": "પà«\81સà«\8dતàª\95 àª¸à«\8dરà«\8bત àª®àª¾àª\9fà«\87 àª¶à«\8bધà«\8b",
+       "booksources-search-legend": "પુસ્તક સ્રોત શોધો",
        "booksources-isbn": "આઇએસબીએન:",
        "booksources-search": "શોધ",
        "booksources-text": "નીચે દર્શાવેલ યાદી એ કડીઓ બતાવે છે જેઓ નવા અને જૂના પુસ્તકો  વેચે છે , અને તમે માંગેલ વસ્તુ સંબંધિ વધુ મહિતી પણ ધરાવી શકે છે.",
        "deletecomment": "કારણ:",
        "deleteotherreason": "અન્ય/વધારાનું કારણ:",
        "deletereasonotherlist": "અન્ય કારણ",
-       "deletereason-dropdown": "* àª¦à«\82ર àª\95રવાના àª¸àª¾àª®àª¾àª¨à«\8dય àª\95ારણà«\8b\n** àª¸à«\8dપામ\n** àª­àª¾àª\82àª\97ફà«\8bડà«\80યા àªªà«\8dરવà«\83તà«\8dતિ\n** àªªà«\8dરàª\95ાશનાધિàª\95ાર àª­àª\82àª\97 \n** àª²à«\87àª\96àª\95નà«\80 àªµàª¿àª¨àª\82તà«\80\n** àª­àª¾àª\82àª\97à«\87લ àªµàª³àª¾àª\82àª\95",
+       "deletereason-dropdown": "* àª¦à«\82ર àª\95રવાના àª¸àª¾àª®àª¾àª¨à«\8dય àª\95ારણà«\8b\n** àª¸à«\8dપામ\n** àª­àª¾àª\82àª\97ફà«\8bડà«\80યા àªªà«\8dરવà«\83તà«\8dતિ\n** àªªà«\8dરàª\95ાશનાધિàª\95ાર àª­àª\82àª\97 \n** àª²à«\87àª\96àª\95નà«\80 àªµàª¿àª¨àª\82તà«\80\n** àª­àª¾àª\82àª\97à«\87લ àª¦àª¿àª¶àª¾àª¨àª¿àª°à«\8dદà«\87શ",
        "delete-edit-reasonlist": "ભુંસવાનું કારણ બદલો.",
        "delete-toobig": "આ પાનાના ફેરફારોનો ઇતિહાસ ખૂબ લાંબો છે , $1 {{PLURAL:$1|ફેરફાર|ફેરફારો}}થી પણ વધારે.\n{{SITENAME}}ને અક્સ્માતે ખોરવાતું અટકાવવા આવા પાનાને હટાવવા પર પ્રતિબંધ છે.",
        "delete-warning-toobig": "આ પાનાનો ઇતિહાસ ઘણો લાંબો છે લગભગ  $1 {{PLURAL:$1|ફેરફાર|ફેરફારો}}.\nતેને ભૂંસતા {{SITENAME}}ના માહિતીસંચને લાગતા કામકાજ પર અસર થૈ શકે છે;\nસંભાળ પૂર્વક આગળ વધો.\n\n\nDeleting it may disrupt database operations of {{SITENAME}};",
        "version-libraries-library": "લાઇબ્રેરી",
        "version-libraries-version": "આવૃત્તિ",
        "redirect": "ફાઇલ, સભ્ય, પાનું, આવૃત્તિ, અથવા લૉગ ઓળખ વડે દિશાનિર્દેશન",
+       "redirect-summary": "આ વિશિષ્ટ પૃષ્ઠ ફાઇલને (ફાઇલ નામ આપવામાં આવે છે), એક પૃષ્ઠ (પુનરાવર્તન ID અથવા પૃષ્ઠ ID આપવામાં આવે છે), વપરાશકર્તા પૃષ્ઠ (એક આંકડાકીય વપરાશકર્તા ID આપવામાં આવે છે), અથવા લોગ એન્ટ્રી (લોગ ID ને આપવામાં આવે છે) પર પુનર્નિર્દેશન કરે છે. વપરાશ:[[{{#Special:Redirect}}/file/Example.jpg]], [[{{#Special:Redirect}}/page/64308]], [[{{#Special:Redirect}}/revision/328429]], [[{{#Special:Redirect}}/user/101]], અથવા [[{{#Special:Redirect}}/logid/186]].",
        "redirect-submit": "જાઓ",
        "redirect-lookup": "જુઓ:",
        "redirect-value": "કિંમત:",
index a46eebc..63517be 100644 (file)
        "showpreview": "Chán-sṳ yi-lám",
        "showdiff": "Chán-sṳ chhâ-phe̍t",
        "anoneditwarning": "<strong>Kín-ko:</strong> Ngì hàn-m̀ tên-ngi̍p. Ngì ke IP vi-chí voi ki-liu̍k chhai liá ya̍p ke phiên-siá li̍t-sṳ́ tú. Na-he ngì <strong>[$1 tên-ngi̍p]</strong> fe̍t-chá <strong>[$2 khôi fu-thèu]</strong>, ngì ke phiên-siá voi hién-sṳ ngì ke yung-fu miàng-sṳ, pin-chhiâ yû khì-thâ ke yù-tiám.",
-       "anonpreviewwarning": "“警告:汝還吂登入。汝嘅IP地址將會記錄在邇頁嘅編輯歷史中”",
+       "anonpreviewwarning": "'''Kín-ko:''' Ngì hàn-màng tên-ngi̍p. Ngì ke IP vi-chí voi ki-liu̍k chhai liá-ya̍p ke siû-kói li̍t-sṳ́ tú.",
        "missingsummary": "'''提示:''' 汝無提供一隻編寫摘要。假使汝再次單擊「$1」,汝嘅編寫將毋帶編寫摘要保存。",
        "missingcommenttext": "請在下背輸入評論。",
        "missingcommentheader": "'''提示:''' 汝還無為邇條評論提供一隻標題。假使汝再次單擊「$1」,您嘅編寫將毋帶標題保存。",
        "updated": "(Yí-kîn kiên-sîn)",
        "note": "<strong>Chu-yi:</strong>",
        "previewnote": "'''請記到邇單淨係預覽。'''\n汝嘅更改還吂保存!",
+       "continue-editing": "Ki-siu̍k siû-kói",
        "previewconflict": "邇隻預覽展示矣上片文字編寫區肚嘅內容。其將在汝選擇保存後出現。",
        "session_fail_preview": "'''好抱歉!由於部份數據遺失,𠊎兜無辦法處理汝嘅編寫。'''\n請試多一擺。\n係講還係失敗,請[[Special:UserLogout|登出]]後重新登入。",
        "session_fail_preview_html": "'''Chṳ̂n tui-put-hí! Phu-fun chṳ̂-liau yí-kîn yì-sṳt, mò-fap chhú-lî ngì-ke phiên-siá.'''\n\n'''Kó-yèn liá-ke phiên-siá ko-chhàng mò-yû mun-thì, chhiáng chai-chhṳ yit-chhṳ. Yìn-yèn yû mun-thì, chhiáng tên-chhut heu chhùng-sîn tên-ngi̍p yit-chhṳ.'''",
index 86e2005..b4f87e5 100644 (file)
        "rcfilters-empty-filter": "אין מסננים פעילים. כל התרומות מוצגות.",
        "rcfilters-filterlist-title": "מסננים",
        "rcfilters-filterlist-whatsthis": "איך הם עובדים?",
-       "rcfilters-filterlist-feedbacklink": "ש×\9c×\99×\97ת ×\9eש×\95×\91 ×¢×\9c ×\94×\9eסננ×\99×\9d ×\94×\97×\93ש×\99×\9d (×\91×\98×\90)",
+       "rcfilters-filterlist-feedbacklink": "×\91×\90פשר×\95ת×\9a ×\9cספר ×\9c× ×\95 ×\9e×\94 ×\93עת×\9a ×¢×\9c ×\9b×\9c×\99 ×\94ס×\99× ×\95×\9f (×\94×\97×\93ש×\99×\9d) ×\94×\90×\9c×\94",
        "rcfilters-highlightbutton-title": "הבלטת התוצאות",
        "rcfilters-highlightmenu-title": "בחירת צבע",
        "rcfilters-highlightmenu-help": "בחירת צבע להדגשת מאפיין זה",
        "rcfilters-liveupdates-button": "עדכונים חיים",
        "rcfilters-liveupdates-button-title-on": "כיבוי העדכונים החיים",
        "rcfilters-liveupdates-button-title-off": "הצגת שינויים חדשים כשהם מתרחשים",
-       "rcfilters-watchlist-markSeen-button": "סימון כל השינויים כאילו נצפו",
+       "rcfilters-watchlist-markseen-button": "סימון כל השינויים כאילו נצפו",
+       "rcfilters-watchlist-edit-watchlist-button": "עריכת רשימת הדפים במעקב שלך",
+       "rcfilters-watchlist-showupdated": "שינויים בדפים שלא ביקרת בהם מאז ביצוע השינויים מופיעים בכתב <strong>מודגש</strong>, ומודגשים בצבע.",
        "rcnotefrom": "להלן {{PLURAL:$5|השינוי שבוצע|השינויים שבוצעו}} מאז <strong>$3, $4</strong> (מוצגים עד <strong>$1</strong>).",
        "rclistfromreset": "איפוס בחירת התאריך",
        "rclistfrom": "הצגת שינויים חדשים החל מ־$2, $3",
        "unwatchthispage": "הפסקת המעקב אחרי דף זה",
        "notanarticle": "זהו אינו דף תוכן",
        "notvisiblerev": "הגרסה האחרונה שנוצרה על־ידי משתמש אחר נמחקה",
-       "watchlist-details": "×\91רש×\99×\9eת ×\94×\9eעק×\91 ×\99ש {{PLURAL:$1|×\93×£ ×\90×\97×\93|$1 ×\93פ×\99×\9d}}, ×\9b×\90שר ×\93פ×\99 ×\94ש×\99×\97×\94 ×\90×\99× ×\9d × ×¡×¤×¨×\99×\9d ×\91נפר×\93.",
+       "watchlist-details": "×\91רש×\99×\9eת ×\94×\9eעק×\91 ×©×\9c×\9a ×\99ש {{PLURAL:$1|×\93×£ ×\90×\97×\93|$1 ×\93פ×\99×\9d}} (×\95×\91× ×\95סף ×\9c×\94×\9d, ×\93פ×\99 ×©×\99×\97×\94).",
        "wlheader-enotif": "הודעות דוא\"ל מאופשרות.",
        "wlheader-showupdated": "דפים שהשתנו מאז ביקורך האחרון בהם מוצגים ב'''הדגשה'''.",
        "wlnote": "להלן {{PLURAL:$1|השינוי האחרון|<strong>$1</strong> השינויים האחרונים}} {{PLURAL:$2|בשעה האחרונה|בשעתיים האחרונות|ב־<strong>$2</strong> השעות האחרונות}}, עד $4, $3.",
index 075c3f3..c0950d6 100644 (file)
        "rcfilters-empty-filter": "कोई सक्रिय फिल्टर नहीं। सभी योगदान दिखाए गए है।",
        "rcfilters-filterlist-title": "फिल्टर",
        "rcfilters-filterlist-whatsthis": "यह कैसे कार्य करता है?",
-       "rcfilters-filterlist-feedbacklink": "नà¤\8f (बà¥\80à¤\9fा) à¤«à¤¿à¤²à¥\8dà¤\9fर à¤ªà¤° à¤ªà¥\8dरतिà¤\95à¥\8dरिया à¤¦à¥\87ं",
+       "rcfilters-filterlist-feedbacklink": "हमà¥\87à¤\82 à¤¬à¤¤à¤¾à¤\8fà¤\82 à¤\95ि à¤\86प à¤\87न (नयà¥\87) à¤¨à¤¿à¤¸à¥\8dपà¤\82दन à¤\94à¤\9cारà¥\8bà¤\82 à¤\95à¥\87 à¤¬à¤¾à¤°à¥\87 à¤®à¥\87à¤\82 à¤\95à¥\8dया à¤¸à¥\8bà¤\9aतà¥\87 à¤¹à¥\88ं",
        "rcfilters-highlightbutton-title": "Highlight results",
        "rcfilters-highlightmenu-title": "रंग चुनें",
        "rcfilters-highlightmenu-help": "इस गुण को हाइलाइट करने के लिए एक रंग चुनें",
        "rcfilters-liveupdates-button": "जीवंत अद्यतन",
        "rcfilters-liveupdates-button-title-on": "जीवंत अद्यतन बंद करें",
        "rcfilters-liveupdates-button-title-off": "नये परिवर्तन प्रदर्शित करें जैसे ही वे घटित होते हैं",
-       "rcfilters-watchlist-markSeen-button": "देखे गए के रूप में सभी परिवर्तनों को चिह्नित करें",
+       "rcfilters-watchlist-markseen-button": "देखे गए के रूप में सभी परिवर्तनों को चिह्नित करें",
+       "rcfilters-watchlist-edit-watchlist-button": "देखे गए पन्नों की सूची को संपादित करें",
+       "rcfilters-watchlist-showupdated": "उन पन्नों में परिवर्तन जिनपर आप परिवर्तन के बाद से नहीं गए हैं, ठोस चिन्ह के साथ <strong>bold</strong> दिखाए गए हैं।",
        "rcnotefrom": "नीचे <strong>$2</strong> के बाद से (<strong>$1</strong> तक) {{PLURAL:$5|हुआ बदलाव दर्शाया गया है|हुए बदलाव दर्शाए गये हैं}}।",
        "rclistfromreset": "चुने दिनांक पहले जैसा करें",
        "rclistfrom": "$3 $2 से नये बदलाव दिखाएँ",
index d479a22..2857f4a 100644 (file)
        "tog-shownumberswatching": "Prikaži broj suradnika koji prate stranicu (u nedavnim izmjenama, popisu praćenja i samim člancima)",
        "tog-oldsig": "Vaš postojeći potpis:",
        "tog-fancysig": "Običan potpis kao wikitekst (bez automatske poveznice)",
-       "tog-uselivepreview": "Uključi trenutačni pretpregled",
+       "tog-uselivepreview": "Prikaži trenutačni pretpregled bez ponovnoga učitavanja stranice",
        "tog-forceeditsummary": "Podsjeti me ako sažetak uređivanja ostavljam praznim",
        "tog-watchlisthideown": "Sakrij moja uređivanja s popisa praćenja",
        "tog-watchlisthidebots": "Sakrij uređivanja botova s popisa praćenja",
        "tog-watchlisthideminor": "Sakrij manje promjene s popisa praćenja",
        "tog-watchlisthideliu": "Sakrij uređivanja prijavljenih s popisa praćenja",
        "tog-watchlistreloadautomatically": "Ponovo učitaj popis praćenja kad god dođe do promjene filtra (potreban JavaScript)",
+       "tog-watchlistunwatchlinks": "Dodaj poveznice za izravno dodavanje/uklanjanje stranica s popisa praćenja (za funkcionalnost mogućnosti potreban je JavaScript)",
        "tog-watchlisthideanons": "Sakrij uređivanja neprijavljenih s popisa praćenja",
        "tog-watchlisthidepatrolled": "Sakrij pregledane izmjene u popisu praćenja",
        "tog-watchlisthidecategorization": "Sakrij kategorizaciju stranica",
        "cannotloginnow-title": "Prijava trenutno nije moguća.",
        "cannotloginnow-text": "Prijava nije moguća tijekom uporabe $1.",
        "cannotcreateaccount-title": "Nije moguće stvoriti račune",
+       "cannotcreateaccount-text": "Direktno stvaranje računa nije omogućeno na ovome wikiju.",
        "yourdomainname": "Vaša domena",
        "password-change-forbidden": "Ne možete promjeniti zaporku na ovom projektu.",
        "externaldberror": "Došlo je do pogreške s vanjskom autorizacijom ili Vam nije dopušteno osvježavanje vanjskog suradničkog računa.",
        "createacct-email-ph": "Upišite svoju adresu e-pošte",
        "createacct-another-email-ph": "Upišite adresu e-pošte",
        "createaccountmail": "Uporabite nasumice odabranu privremenu zaporku i pošaljite ju na navedenu adresu e-pošte",
+       "createaccountmail-help": "Može se rabiti da se nekome stvori račun bez da se sazna zaporka.",
        "createacct-realname": "Stvarno ime (neobvezatno)",
        "createacct-reason": "Razlog",
        "createacct-reason-ph": "Zašto stvarate drugi račun",
+       "createacct-reason-help": "Poruka koja se prikazuje u evidenciji stvaranja suradničkih računa",
        "createacct-submit": "Stvorite svoj suradnički račun",
        "createacct-another-submit": "Otvori račun",
        "createacct-continue-submit": "Pritisni za stvaranje računa",
        "createacct-benefit-body2": "{{PLURAL:$1|stranica|stranice|stranica}}",
        "createacct-benefit-body3": "{{PLURAL:$1|nedavni suradnik|nedavnih suradnika}}",
        "badretype": "Unesene zaporke nisu istovjetne.",
+       "usernameinprogress": "Stvaranje računa za ovo suradničko ime upravo je u tijeku.\nMolimo, pričekajte.",
        "userexists": "Uneseno suradničko ime već je u upotrebi.\nUnesite neko drugo ime.",
        "loginerror": "Pogrješka u prijavi",
        "createacct-error": "Pogrješka u stvaranju računa",
        "changeemail-nochange": "Molimo vas, upišite neku novu adresu e-pošte.",
        "resettokens": "Ponovo postavljanje tajnoga ključa",
        "resettokens-text": "Možete ponovo postaviti tajni ključ koji Vam dopušta pristupanje određenim osobnim podatcima povezanim s Vašim ovdje navedenim suradničkim računom.\n\nTrebali bi to načiniti ukoliko ga kojim slučajem priopćite nekome ili ukoliko je Vaš suradnički račun ugrožen.",
+       "resettokens-no-tokens": "Nema tajnih ključeva za ponovno postavljanje",
        "resettokens-tokens": "Tajni ključevi:",
        "resettokens-token-label": "$1 (trenutačna postavka: $2)",
        "resettokens-watchlist-token": "Tajni ključ za uvoženje u mrežno sjedište (Atom/RSS) [[Special:Watchlist|promjena na stranicama s Vašega popisa praćenih stranica]]",
+       "resettokens-done": "Ponovno postavljanje tajnih ključeva",
        "resettokens-resetbutton": "Ponovo postavi odabrane tajne ključeve",
        "bold_sample": "Podebljani tekst",
        "bold_tip": "Podebljani tekst",
        "mergelogpagetext": "Slijedi popis posljednjih spajanja povijesti stranica.",
        "history-title": "Povijest izmjena stranice »$1«",
        "difference-title": "Razlika između inačica stranice »$1«",
-       "difference-title-multipage": "Razlika između stranica \"$1\" i \"$2\"",
+       "difference-title-multipage": "Razlika između stranica »$1« i »$2«",
        "difference-multipage": "(Razlika između stranica)",
        "lineno": "Redak $1:",
        "compareselectedversions": "Usporedi odabrane inačice",
        "search-interwiki-caption": "Rezultati sa sestrinskih projekata",
        "search-interwiki-default": "Rezultati s projekta $1:",
        "search-interwiki-more": "(više)",
+       "search-interwiki-more-results": "više rezultata",
        "search-relatedarticle": "Povezano",
        "searchrelated": "povezano",
        "searchall": "sve",
        "prefs-editing": "Uređivanje",
        "searchresultshead": "Prikaz rezultata pretrage",
        "stub-threshold": "Prag za formatiranje poveznice na mrve ($1):",
+       "stub-threshold-sample-link": "primjer",
        "stub-threshold-disabled": "Onemogućeno",
        "recentchangesdays": "Broj dana prikazanih u nedavnim promjenama:",
        "recentchangesdays-max": "(maksimalno $1 {{PLURAL:$1|dan|dana}})",
        "prefs-registration": "Vrijeme prijave:",
        "yourrealname": "Pravo ime (nije obvezno)*",
        "yourlanguage": "Jezik:",
-       "yourvariant": "Inačica jezika:",
-       "prefs-help-variant": "Željena varijanta ili pravopis za prikaz stranica ovog wikija.",
+       "yourvariant": "Jezična inačica sadržaja:",
+       "prefs-help-variant": "Vaša preferirana inačica ili pravopis za prikaz sadržaja stranica na ovom wikiju.",
        "yournick": "Vaš nadimak (za potpisivanje)",
        "prefs-help-signature": "Komentari na stranicama za razgovor trebali bi biti potpisani s \"<nowiki>~~~~</nowiki>\" što će biti pretvoreno u Vaš potpis i datum.",
        "badsig": "Kôd Vašeg potpisa nije valjan; provjerite HTML tagove.",
        "userrights-expiry-existing": "Postojeće vrijeme isteka: $3, $2",
        "userrights-expiry-othertime": "Drugo vrijeme:",
        "userrights-expiry-options": "1 dan:1 day,1 tjedan:1 week,1 mjesec:1 month,3 mjeseca:3 months,6 mjeseci:6 months,1 godina:1 year",
+       "userrights-invalid-expiry": "Rok isteka prava iz skupine »$1« nije valjano upisano.",
+       "userrights-expiry-in-past": "Rok isteka prava iz skupine »$1« zadan je u vremenu koje je proteklo.",
+       "userrights-cannot-shorten-expiry": "Ne možete ubrzati vrijeme isteka pripadništva skupini »$1«. Prethodno navedeno jedino mogu ubrzati suradnici koji mogu dodjeljivati i uklanjati ovu suradničku skupinu.",
        "userrights-conflict": "Sukob promjene suradničkih prava! Molimo provjerite i potvrdite svoje promjene.",
        "group": "Skupina:",
        "group-user": "Suradnici",
        "right-createpage": "Stvaranje stranica (stranica koje nisu razgovor)",
        "right-createtalk": "Stvaranje stranica za razgovor",
        "right-createaccount": "Stvaranje novog suradničkog računa",
+       "right-autocreateaccount": "Automatska prijava s vanjskim suradničkim računom",
        "right-minoredit": "Označavanje izmjene manjom",
        "right-move": "Premještanje stranica",
        "right-move-subpages": "Premještanje stranica s njihovim podstranicama",
        "right-siteadmin": "Zaključavanje i otključavanje baze podataka",
        "right-override-export-depth": "Izvezi stranice uključujući i povezane stranice do dubine od 5",
        "right-sendemail": "Slanje e-pošte drugim suradnicima",
+       "grant-generic": "Snop prava »$1«",
        "grant-group-email": "Pošalji e-mail",
        "grant-blockusers": "Blokiraj i odblokiraj korisnike",
        "grant-createaccount": "Otvori račune",
        "rcfilters-savedqueries-unsetdefault": "Ukloni kao zadano",
        "rcfilters-savedqueries-remove": "Ukloni",
        "rcfilters-savedqueries-new-name-label": "Ime",
-       "rcfilters-savedqueries-apply-label": "Spremi postavke",
+       "rcfilters-savedqueries-apply-label": "Stvori filtar",
        "rcfilters-savedqueries-cancel-label": "Odustani",
        "rcfilters-savedqueries-add-new-title": "Spremi trenutačne postavke filtera",
        "rcfilters-restore-default-filters": "Vrati zadane filtre",
        "rcfilters-filter-editsbyother-label": "Promjene drugih suradnika",
        "rcfilters-filter-editsbyother-description": "Sve promjene osim Vaših.",
        "rcfilters-filtergroup-userExpLevel": "Napredna razina (samo za registrirane suradnike)",
-       "rcfilters-filter-user-experience-level-registered-label": "Prijavljeni",
+       "rcfilters-filter-user-experience-level-registered-label": "Registrirani",
        "rcfilters-filter-user-experience-level-registered-description": "Prijavljeni suradnici.",
-       "rcfilters-filter-user-experience-level-unregistered-label": "Neprijavljeni",
+       "rcfilters-filter-user-experience-level-unregistered-label": "Neregistrirani",
        "rcfilters-filter-user-experience-level-unregistered-description": "Suradnici koji nisu prijavljeni.",
        "rcfilters-filter-user-experience-level-newcomer-label": "Novopridošli",
        "rcfilters-filter-user-experience-level-newcomer-description": "Registrirani suradnici s manje od 10 uređivanja i 4 dana aktivnosti.",
        "rcfilters-filter-user-experience-level-experienced-label": "Iskusni suradnici",
        "rcfilters-filter-user-experience-level-experienced-description": "Registrirani suradnici s više od 500 uređivanja i 30 dana aktivnosti.",
        "rcfilters-filtergroup-automated": "Automatizirani doprinosi",
+       "rcfilters-filter-bots-label": "Botovi",
        "rcfilters-filter-bots-description": "Uređivanja učinjena automatiziranim alatima.",
        "rcfilters-filter-humans-label": "Osoba (ne bot)",
        "rcfilters-filter-humans-description": "Uređivanja koja su napravili suradnici.",
        "uploadstash-badtoken": "Obavljanje akcije je bilo neuspješano, možda jer je vaša prijava istekla. Pokušajte ponovno.",
        "uploadstash-errclear": "Brisanje neobjavljenih datoteka nije uspjelo.",
        "uploadstash-refresh": "Osvježi popis datoteka",
+       "uploadstash-thumbnail": "pogledaj kao minijaturu",
        "invalid-chunk-offset": "Nevaljana točka nastavka snimanja",
        "img-auth-accessdenied": "Pristup onemogućen",
        "img-auth-nopathinfo": "Nedostaje PATH_INFO.\nVaš poslužitelj nije postavljen da prosljeđuje ovu informaciju.\nMožda se temelji na CGI skripti i ne može podržavati img_auth.\n[https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Image_Authorization?uselang=hr Pogledajte stranicu o autorizaciji slika]",
        "listredirects": "Popis preusmjeravanja",
        "listduplicatedfiles": "Popis kopija datoteka",
        "listduplicatedfiles-summary": "Ovo je popis datoteka kojima je zadnja inačica kopija zadnje inačice druge datoteke. Na popisu su samo lokalno postavljene datoteke.",
+       "listduplicatedfiles-entry": "[[:File:$1|$1]] ima [[$3|{{PLURAL:$2|jedan duplikat|$2 duplikata}}]].",
        "unusedtemplates": "Nekorišteni predlošci",
        "unusedtemplatestext": "Slijedi popis svih stranica imenskog prostora {{ns:template}}, koje nisu umetnute na drugim stranicama. Pripazite da prije brisanja provjerite druge poveznice koje vode na te predloške.",
        "unusedtemplateswlh": "druge poveznice",
        "randompage-nopages": "Nema stranica u {{PLURAL:$2|imenskom prostoru|imenskim prostorima}}: $1.",
        "randomincategory": "Slučajna stranica u kategoriji",
        "randomincategory-invalidcategory": "\"$1\" nije valjano ime kategorije.",
+       "randomincategory-nopages": "Nema stranica u kategoriji [[:Category:$1|$1]].",
        "randomincategory-category": "Kategorija:",
        "randomincategory-legend": "Slučajna stranica u kategoriji",
        "randomincategory-submit": "Kreni",
        "ninterwikis": "$1 međuwiki {{PLURAL:$1|poveznica|poveznice|poveznica}}",
        "nlinks": "$1 {{PLURAL:$1|poveznica|poveznice|poveznica}}",
        "nmembers": "$1 {{PLURAL:$1|član|člana|članova}}",
+       "nmemberschanged": "$1 → $2 {{PLURAL:$2|član|člana|članova}}",
        "nrevisions": "$1 {{PLURAL:$1|inačica|inačice|inačica}}",
        "nimagelinks": "Koristi se na $1 {{PLURAL:$1|stranici|stranice|stranica}}",
        "ntransclusions": "koristi se na $1 {{PLURAL:$1|stranici|stranice|stranica}}",
        "wantedtemplates": "Traženi predlošci",
        "mostlinked": "Stranice na koje vodi najviše poveznica",
        "mostlinkedcategories": "Kategorije na koje vodi najviše poveznica",
-       "mostlinkedtemplates": "Predlošci na koje vodi najviše poveznica",
+       "mostlinkedtemplates": "Stranice na koje vodi najviše transkluzija",
        "mostcategories": "Popis stranica po broju kategorija",
        "mostimages": "Slike na koje vodi najviše poveznica",
        "mostinterwikis": "Stranice s najviše međuwiki poveznica",
        "apisandbox-unfullscreen": "Prikaži stranicu",
        "apisandbox-submit": "Napraviti zahtjev",
        "apisandbox-reset": "Očisti",
+       "apisandbox-retry": "Pokušaj ponovo",
+       "apisandbox-loading": "Učitavam podatke o API modulu »$1«...",
+       "apisandbox-helpurls": "Poveznice za pomoć",
        "apisandbox-examples": "Primjeri",
+       "apisandbox-dynamic-parameters": "Dodatni parametri",
+       "apisandbox-dynamic-parameters-add-label": "Dodaj parametar:",
+       "apisandbox-dynamic-parameters-add-placeholder": "Ime parametra",
+       "apisandbox-dynamic-error-exists": "Parametar s imenom »$1« već postoji.",
+       "apisandbox-deprecated-parameters": "Zastarjeli parametri",
+       "apisandbox-fetch-token": "Automatski ispuni tajni ključ",
+       "apisandbox-submit-invalid-fields-title": "Neka polja nisu vrijedeća",
        "apisandbox-results": "Rezultati",
+       "apisandbox-request-time": "Vrijeme za izvršavanje zahtjeva: {{PLURAL:$1|$1 milisekunda|$1 milisekunde|$1 milisekundi}}",
        "booksources": "Pretraživanje po ISBN-u",
        "booksources-search-legend": "Traženje izvora za knjigu",
        "booksources-search": "Traži",
        "logempty": "Nema pronađenih stavki u evidenciji.",
        "log-title-wildcard": "Traži stranice koje počinju s navedenim izrazom",
        "showhideselectedlogentries": "Otkrij/sakrij odabrane evidencije",
+       "log-edit-tags": "Uredi oznake izabranih unosa u evidencijama",
        "checkbox-select": "Odaberite: $1",
        "checkbox-all": "Sve",
        "checkbox-none": "Ništa",
        "enotif_lastdiff": "Pogledajte $1 kako biste mogli vidjeti tu izmjenu.",
        "enotif_anon_editor": "neprijavljeni suradnik $1",
        "enotif_body": "Poštovani $WATCHINGUSERNAME,\n\n$PAGEINTRO $NEWPAGE\n\nSažetak urednika: $PAGESUMMARY $PAGEMINOREDIT\n\nMožete kontaktirati suradnika koji je posljednji uređivao stranicu:\nmail: $PAGEEDITOR_EMAIL\nwiki: $PAGEEDITOR_WIKI\n\nDo Vašeg ponovnog posjeta stranici nećete dobivati nove obavijesti. Postavke za izvješćivanje možete vratiti na prvotno zadane za sve praćene stranice svog popisa praćenja.\n\nVaš sustav izvješćivanja {{SITENAME}}.\n\n--\nZa promjene postavki izvješćivanja putem e-pošte, posjetite\n{{canonicalurl:{{#special:Preferences}}}}\n\nZa promjene svog popisa praćenja, posjetite\n{{canonicalurl:{{#special:EditWatchlist}}}}\n\nZa brisanje stranica iz svog popisa praćenja, posjetite\n$UNWATCHURL\n\nZa povratne informacije i pomoć posjetite:\n$HELPPAGE",
+       "enotif_minoredit": "Ovo je sitnije uređivanje",
        "created": "stvorio",
        "changed": "promijenio",
        "deletepage": "Izbriši stranicu",
        "tags-hitcount": "$1 {{PLURAL:$1|izmjena|izmjene|izmjena}}",
        "tags-manage-no-permission": "Nemate pravo upravljati promjenama oznaka.",
        "tags-create-heading": "Stvori novu oznaku",
+       "tags-create-explanation": "Predodređeno je da će novostvorene oznake biti omogućene za upotrebu suradnicima i botovima.",
        "tags-create-tag-name": "Naziv oznake:",
        "tags-create-reason": "Razlog:",
        "tags-create-submit": "Stvori",
        "compare-invalid-title": "Naslov koji ste naveli nije valjan.",
        "compare-title-not-exists": "Naslov koji ste naveli ne postoji.",
        "compare-revision-not-exists": "Navedena izmjena stranice ne postoji.",
-       "diff-form": "'''form'''",
+       "diff-form": "Razlikovne poveznice",
+       "diff-form-oldid": "ID stare inačice (neobvezan unos)",
+       "diff-form-revid": "ID inačice za izradbu razlikovne poveznice",
+       "diff-form-submit": "Prikaži razlikovnu poveznicu",
+       "permanentlink": "Trajna poveznica",
+       "permanentlink-revid": "ID inačice (oldid)",
+       "permanentlink-submit": "Idi na inačicu",
        "dberr-problems": "Ispričavamo se! Ova stranica ima tehničkih poteškoća.",
        "dberr-again": "Pričekajte nekoliko minuta i ponovno učitajte.",
        "dberr-info": "(Ne mogu pristupiti bazi podataka: $1)",
        "dberr-outofdate": "Imajte na umu da su njihova kazala našeg sadržaja možda zastarjela.",
        "dberr-cachederror": "Sljedeće je dohvaćena kopija tražene stranice, te možda nije ažurirana.",
        "htmlform-invalid-input": "Postoje problemi s dijelom Vašeg unosa",
-       "htmlform-select-badoption": "Vrijednost koju ste naveli nije ispravan izbor.",
+       "htmlform-select-badoption": "Vrijednost koju ste naveli nije vrijedeća mogućnost.",
        "htmlform-int-invalid": "Vrijednost koju ste naveli nije cijeli broj.",
        "htmlform-float-invalid": "Vrijednost koju ste naveli nije broj.",
        "htmlform-int-toolow": "Vrijednost koju ste naveli je ispod minimuma od $1",
        "log-name-pagelang": "Evidencija mijenjanja jezika",
        "mediastatistics": "Statistika datoteka",
        "mediastatistics-summary": "Slijede statistike postavljenih datoteka koje pokazuju zadnju inačicu datoteke. Starije ili izbrisane inačice nisu prikazane.",
+       "mediastatistics-nbytes": "{{PLURAL:$1|$1 bajt|$1 bajta|$1 bajtova}} ($2; $3 %)",
        "mediastatistics-bytespertype": "Ukupna veličina datoteka za ovaj odlomak: {{PLURAL:$1|$1 bajt|$1 bajta|$1 bajtova}} ($2; $3%).",
        "mediastatistics-allbytes": "Ukupna veličina svih datoteka: {{PLURAL:$1|$1 bajt|$1 bajta|$1 bajtova}} ($2).",
-       "mediastatistics-header-unknown": "Nepoznato",
+       "mediastatistics-header-unknown": "Nepoznata",
        "mediastatistics-header-bitmap": "Rasterske slike",
        "mediastatistics-header-drawing": "Crteži (vektorske slike)",
        "mediastatistics-header-audio": "Zvukovne datoteke",
-       "mediastatistics-header-video": "Video datoteke",
+       "mediastatistics-header-video": "Videodatoteke",
        "mediastatistics-header-multimedia": "Datoteke digitalnih kontejnerskih formata",
        "mediastatistics-header-office": "Datoteke uredskih formata",
        "mediastatistics-header-text": "Tekstualne datoteke",
        "mw-widgets-mediasearch-noresults": "Nema rezultata.",
        "mw-widgets-titleinput-description-new-page": "stranica još ne postoji",
        "mw-widgets-titleinput-description-redirect": "preusmjeravanje na $1",
+       "mw-widgets-usersmultiselect-placeholder": "Dodaj još...",
        "date-range-from": "Od nadnevka:",
        "date-range-to": "Do nadnevka:",
        "randomrootpage": "Slučajna korijenska stranica",
index 2ae1aa3..3ebee17 100644 (file)
        "anontalk": "Diskusija",
        "navigation": "Nawigacija",
        "and": "&#32;a",
-       "qbfind": "Namakać",
-       "qbbrowse": "Přepytować",
-       "qbedit": "Wobdźěłać",
-       "qbpageoptions": "Tuta strona",
-       "qbmyoptions": "Moje strony",
        "faq": "Husto stajene prašenja (FAQ)",
-       "faqpage": "Project:Husto stajene prašenja (FAQ)",
        "actions": "Akcije",
        "namespaces": "Mjenowe rumy",
        "variants": "Warianty",
        "edit-local": "Lokalny wopis wobdźěłać .",
        "create": "Wutworić",
        "create-local": "Lokalny wopis přidać",
-       "editthispage": "Tutu stronu wobdźěłać",
-       "create-this-page": "Stronu wutworić",
        "delete": "wušmórnyć",
-       "deletethispage": "Stronu wušmórnyć",
-       "undeletethispage": "Tutu stronu wobnowić",
        "undelete_short": "{{PLURAL:$1|jednu wersiju|$1 wersiji|$1 wersije|$1 wersijow}} wobnowić",
        "viewdeleted_short": "{{PLURAL:$1|jednu wušmórnjenu změnu|$1 wušmórnjenej změnje|$1 wušmórnjene změny|$1 wušmórnjenych změnow}} sej wobhladać",
        "protect": "škitać",
        "protect_change": "změnić",
-       "protectthispage": "Stronu škitać",
        "unprotect": "Škit wotstronić",
-       "unprotectthispage": "Tutu stronu hižo nješkitać",
        "newpage": "Nowa strona",
-       "talkpage": "Tutu stronu diskutować",
        "talkpagelinktext": "diskusija",
        "specialpage": "Specialna strona",
        "personaltools": "Wosobinske nastroje",
-       "articlepage": "Nastawk",
        "talk": "diskusija",
        "views": "Zwobraznjenja",
        "toolbox": "Nastroje",
        "tool-link-emailuser": "{{GENDER:$1|Tutomu wužiwarjej|Tutej wužiwarce}} mejlku pósłać",
-       "userpage": "Wužiwarsku stronu pokazać",
-       "projectpage": "Projektowu stronu pokazać",
        "imagepage": "Datajowu stronu sej wobhladać",
        "mediawikipage": "Zdźělenku pokazać",
        "templatepage": "Předłohu pokazać",
        "rcfilters-invalid-filter": "Njepłaćiwy filter",
        "rcfilters-filterlist-whatsthis": "Što je to?",
        "rcfilters-highlightmenu-title": "Barbu wubrać",
-       "rcfilters-filtergroup-registration": "Registrowanje wužiwarja",
        "rcfilters-filter-user-experience-level-newcomer-label": "Nowački",
        "rcfilters-filter-user-experience-level-newcomer-description": "Mjenje hač 10 změnow a štyri aktiwne dny.",
        "rcfilters-filter-user-experience-level-learner-label": "Započatkarjo",
        "booksources-search": "Pytać",
        "booksources-text": "To je lisćina wotkazow k druhim sydłam, kotrež nowe a trjebane knihi předawaja. Tam móžeš tež dalše informacije wo knihach dóstać, kotrež pytaš:",
        "booksources-invalid-isbn": "Podate ISBN-čisło njezda so płaćiwe być; přepruwuj za zmylkami, z tym zo z orginialneho žórła kopěruješ.",
+       "magiclink-tracking-isbn": "Strony, kotrež wužiwaja magiske ISBN-wotkazy",
        "specialloguserlabel": "Wukonjer:",
        "speciallogtitlelabel": "Cil (titul abo {{ns:user}}:wužiwarske mjeno za wužiwarja):",
        "log": "Protokole",
        "fileduplicatesearch-noresults": "Žana dataja z mjenom \"$1\" namakana.",
        "specialpages": "Specialne strony",
        "specialpages-note-top": "Legenda",
-       "specialpages-note": "* Normalne specialne strony.\n* <span class=\"mw-specialpagerestricted\">Specialne strony z wobmjezowanym přistupom.</span>",
        "specialpages-group-maintenance": "Hladanske lisćiny",
        "specialpages-group-other": "Druhe specialne strony",
        "specialpages-group-login": "Přizjewić/Konto załožić",
        "compare-invalid-title": "Titul, kotryž sy podał, je njepłaćiwy.",
        "compare-title-not-exists": "Titul, kotryž sy podał, njeeksistuje.",
        "compare-revision-not-exists": "Wersija, kotruž sy podał, njeeksistuje.",
+       "diff-form": "'''formular'''",
        "dberr-problems": "Wodaj! Tute sydło ma techniske ćežkosće.",
        "dberr-again": "Počakń někotre mjeńšiny a zaktualizuj stronu.",
        "dberr-info": "(Njeje móžno na datowu banku přistup měć: $1)",
index 6a925ac..6ab149a 100644 (file)
        "rcfilters-view-return-to-default-tooltip": "Vissza a főszűrőmenübe.",
        "rcfilters-liveupdates-button": "Élő frissítések",
        "rcfilters-liveupdates-button-title-on": "Élő frissítések kikapcsolása",
-       "rcfilters-watchlist-markSeen-button": "Összes változtatás megjelölése olvasottként",
+       "rcfilters-watchlist-markseen-button": "Összes változtatás megjelölése olvasottként",
        "rcnotefrom": "Alább a <strong>$3 $4</strong> óta történt változtatások láthatóak (legfeljebb <b>$1</b> db).",
        "rclistfromreset": "Dátumválasztás visszaállítása",
        "rclistfrom": "$3, $2 után történt változtatások megtekintése",
        "version-libraries-license": "Licenc",
        "version-libraries-description": "Leírás",
        "version-libraries-authors": "Szerzők",
-       "redirect": "Átirányítás fájl, szerkesztő, olda, oldalváltozat vagy naplóazonosító alapján",
+       "redirect": "Átirányítás fájl, szerkesztő, oldal, oldalváltozat vagy naplóazonosító alapján",
        "redirect-summary": "Ez a speciális lap átirányít egy fájlra (megadott fájlnévvel), lapra (megadott lapváltozat- vagy lapazonosító számmal), felhasználóra (felhasználó azonosítószáma alapján) vagy naplóbejegyzésre (naplóazonosító alapján). Használat: [[{{#Special:Redirect}}/file/Example.jpg]], [[{{#Special:Redirect}}/page/64308]], [[{{#Special:Redirect}}/revision/328429]], [[{{#Special:Redirect}}/user/101]] vagy [[{{#Special:Redirect}}/logid/186]].",
        "redirect-submit": "Mehet",
        "redirect-lookup": "Keresés:",
index bd41893..d5fce20 100644 (file)
        "changeemail-oldemail": "Ներկա էլ․ հասցե․",
        "changeemail-newemail": "Նոր էլ․ հասցե․",
        "changeemail-none": "(ոչ մի)",
-       "changeemail-password": "Õ\94Õ¸ {{SITENAME}} գաղտնաբառը՝",
+       "changeemail-password": "Õ\81Õ¥Ö\80 {{SITENAME}} գաղտնաբառը՝",
        "changeemail-submit": "Փոխել էլ․ հասցեն",
        "changeemail-nochange": "Խնդրում ենք մուտքագրեք այլ նոր էլեկտրոնային փոստի հասցեն։",
        "resettokens-tokens": "Կտրոններ՝",
        "emaillink": "ուղարկել էլ. նամակ",
        "autoblocker": "Դուք ավտոմատիկ արգելափակվել եք «$1» մասնակցի հետ ձեր IP-հասցեի համընկնելու պատճառով։ Նրա արգելափակման պատճառն է՝ «$2»։",
        "blocklogpage": "Արգելափակման տեղեկամատյան",
-       "blocklogentry": "[[$1]] արգելափակվել է $2 տևողությամբ $3",
+       "blocklogentry": "արգելափակեց [[$1]] $2 $3 տևողությամբ",
        "reblock-logentry": "փոխեց [[$1]]ի արգելափակումը՝ դարձնելով $2 տևողությամբ $3",
        "blocklogtext": "Սա մասնակիցների արգելափակման և արգելափակումից հանման տեղեկամատյանն է։\nԱվտոմատ կերպով արգելափակված IP-հասցեներն այստեղ ընդգրկված չեն։\nՏես [[Special:BlockList|այս պահին ակտիվ արգելափակումների ցանկը]]։",
        "unblocklogentry": "արգելափակումից հանված է $1",
index 5480a2e..9e4317b 100644 (file)
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (vide etiam le [[Special:NewPages|lista de nove paginas]])",
        "recentchanges-legend-plusminus": "(''±123'')",
        "recentchanges-submit": "Monstrar",
+       "rcfilters-tag-remove": "Remover '$1'",
        "rcfilters-legend-heading": "<strong>Lista de abbreviationes:</strong>",
        "rcfilters-other-review-tools": "<strong>Altere instrumentos de revision</strong>",
        "rcfilters-group-results-by-page": "Gruppar resultatos per pagina",
index f1f8938..439edb6 100644 (file)
@@ -54,7 +54,8 @@
                        "Hidayatsrf",
                        "MF-Warburg",
                        "Rachmat04",
-                       "Arifpedia"
+                       "Arifpedia",
+                       "Uchup19"
                ]
        },
        "tog-underline": "Garis bawahi pranala:",
        "rcfilters-liveupdates-button": "Perubahan langsung",
        "rcfilters-liveupdates-button-title-on": "Matikan perubahan langsung",
        "rcfilters-liveupdates-button-title-off": "Tampilkan perubahan baru ketika perubahan tersebut terjadi",
-       "rcfilters-watchlist-markSeen-button": "Tandai semua perubahan sebagai terlihat",
+       "rcfilters-watchlist-markseen-button": "Tandai semua perubahan sebagai terlihat",
        "rcnotefrom": "Di bawah ini adalah {{PLURAL:$5|perubahan}} sejak <strong>$3, $4</strong> (ditampilkan sampai <strong>$1</strong> perubahan).",
        "rclistfromreset": "Atur ulang pilihan tanggal",
        "rclistfrom": "Perlihatkan perubahan terbaru sejak $3 $2",
index 3b85292..6629710 100644 (file)
@@ -56,7 +56,7 @@
        "tog-shownumberswatching": "Sýna fjölda vaktandi notenda",
        "tog-oldsig": "Núverandi undirskriftin þín:",
        "tog-fancysig": "Meðhöndla undirskrift sem wikitexta (án sjálfvirks tengils)",
-       "tog-uselivepreview": "Nota beina forskoðun",
+       "tog-uselivepreview": "Nota beina forskoðun án þess að endurhlaða síðuna",
        "tog-forceeditsummary": "Birta áminningu þegar breytingarágripið er tómt",
        "tog-watchlisthideown": "Ekki sýna mínar breytingar á vaktlistanum",
        "tog-watchlisthidebots": "Ekki sýna breytingar vélmenna á vaktlistanum",
        "anontalk": "Spjall",
        "navigation": "Flakk",
        "and": "&#32;og",
-       "qbfind": "Finna",
-       "qbbrowse": "Flakka",
-       "qbedit": "Breyta",
-       "qbpageoptions": "Þessi síða",
-       "qbmyoptions": "Mínar síður",
        "faq": "Algengar spurningar",
-       "faqpage": "Project:Algengar spurningar",
        "actions": "Aðgerðir",
        "namespaces": "Nafnrými",
        "variants": "Útgáfur",
        "edit-local": "Breyta staðbundinni lýsingu",
        "create": "Skapa",
        "create-local": "Bæta við staðbundinni lýsingu",
-       "editthispage": "Breyta þessari síðu",
-       "create-this-page": "Skapa þessari síðu",
        "delete": "Eyða",
-       "deletethispage": "Eyða þessari síðu",
-       "undeletethispage": "Endurvekja þessa síðu",
        "undelete_short": "Endurvekja {{PLURAL:$1|$1 breytingu|$1 breytingar}}",
        "viewdeleted_short": "Skoða $1 {{PLURAL:$1|eydda breytingu|eyddar breytingar}}",
        "protect": "Vernda",
        "protect_change": "breyta",
-       "protectthispage": "Vernda þessa síðu",
        "unprotect": "Afvernda",
-       "unprotectthispage": "Afvernda þessa síðu",
        "newpage": "Ný síða",
-       "talkpage": "Ræða um þessa síðu",
        "talkpagelinktext": "Spjall",
        "specialpage": "Kerfissíða",
        "personaltools": "Tenglar",
-       "articlepage": "Sýna núverandi síðu",
        "talk": "Spjall",
        "views": "Sýn",
        "toolbox": "Verkfæri",
        "tool-link-userrights": "Breyta {{GENDER:$1|notanda}} hópum",
        "tool-link-userrights-readonly": "Skoða {{GENDER:$1|notanda}} hópa",
        "tool-link-emailuser": "Senda þessum {{GENDER:$1|notanda}} tölvupóst",
-       "userpage": "Skoða notandasíðu",
-       "projectpage": "Skoða verkefnissíðu",
        "imagepage": "Skoða skráarsíðu",
        "mediawikipage": "Skoða skilaboðasíðu",
        "templatepage": "Skoða sniðmátasíðu",
        "filereadonlyerror": "Ekki var hægt að breyta skránni \"$1\" því skráin í skráarsafninu \"$2\" er engöngu hægt að lesa.\n\nKerfisstjórinn sem læsti skránni gaf þessa ástæðu: \"$3\".",
        "invalidtitle-knownnamespace": "Ógildur titill í nafnrými \"$2\" og með textann \"$3\"",
        "invalidtitle-unknownnamespace": "Ógildur titill með óþekkt nafnrými númer $1 og texta \"$2\"",
-       "exception-nologin": "Óinnskráð(ur)",
+       "exception-nologin": "Ekki skráð/ur inn",
        "exception-nologin-text": "Skráðu þig inn til þess að fá aðgang að þessari síðu eða aðgerð.",
        "exception-nologin-text-manual": "$1 til þess að fá aðgang að þessari síðu eða aðgerð.",
        "virus-badscanner": "Slæm stilling: óþekktur veiruskannari: <em>$1</em>",
        "welcomecreation-msg": "Aðgangurinn þinn hefur verið búinn til.\nEkki gleyma að breyta [[Special:Preferences|{{SITENAME}} stillingunum]] þínum.",
        "yourname": "Notandanafn:",
        "userlogin-yourname": "Notandanafn",
-       "userlogin-yourname-ph": "Skrifaðu inn notandanafnið þitt",
-       "createacct-another-username-ph": "Skrifaðu inn notandanafnið",
+       "userlogin-yourname-ph": "Settu inn notandanafnið þitt",
+       "createacct-another-username-ph": "Settu inn notandanafnið",
        "yourpassword": "Lykilorð:",
        "userlogin-yourpassword": "Lykilorð",
-       "userlogin-yourpassword-ph": "Skrifaðu niður lykilorðið þitt",
-       "createacct-yourpassword-ph": "Skrifaðu niður lykilorð",
+       "userlogin-yourpassword-ph": "Settu inn lykilorðið þitt",
+       "createacct-yourpassword-ph": "Settu inn lykilorð",
        "yourpasswordagain": "Endurrita lykilorð:",
        "createacct-yourpasswordagain": "Staðfestu lykilorðið",
        "createacct-yourpasswordagain-ph": "Sláðu inn lykilorðið aftur",
        "userlogin-remembermypassword": "Muna innskráningu mína",
        "userlogin-signwithsecure": "Nota örugga tengingu",
+       "cannotlogin-title": "Get ekki skráð inn",
+       "cannotlogin-text": "Innskráning er ekki möguleg.",
        "cannotloginnow-title": "Get ekki skráð inn núna",
        "cannotloginnow-text": "Innskráning er ekki möguleg þegar verið er að nota $1.",
+       "cannotcreateaccount-title": "Ekki hægt að búa til aðganga",
        "yourdomainname": "Þitt lén:",
        "password-change-forbidden": "Þú getur ekki breytt lykilorðum á þessum wiki.",
        "externaldberror": "Uppfærsla mistókst. Annaðhvort varð villa í gagnasafninu eða að þér sé óheimilt að uppfæra aðra aðganga.",
-       "login": "Innskrá",
-       "nav-login-createaccount": "Innskrá / Búa til aðgang",
+       "login": "Skrá inn",
+       "login-security": "Sannreyndu auðkennin þín",
+       "nav-login-createaccount": "Skrá inn / Búa til aðgang",
        "logout": "Útskráning",
        "userlogout": "Útskrá",
-       "notloggedin": "Ekki innskráð(ur)",
-       "userlogin-noaccount": "Áttu ekki aðgang?",
+       "notloggedin": "Ekki skráð/ur inn",
+       "userlogin-noaccount": "Ertu ekki með aðgang?",
        "userlogin-joinproject": "Sameina {{SITENAME}}",
        "createaccount": "Nýskrá",
-       "userlogin-resetpassword-link": "Gleymdiru lykilorðinu þínu?",
+       "userlogin-resetpassword-link": "Gleymdirðu lykilorðinu þínu?",
        "userlogin-helplink2": "Hjálp við innskráningu",
        "userlogin-loggedin": "Þú ert búin(n) að skrá þig inn sem {{GENDER:$1|$1}}.\nNotaðu eyðablaðið fyrir neðan til að skrá þig inn sem annar notandi.",
+       "userlogin-reauth": "Þú verður að skrá þig aftur inn til að sannreyna að þú sért {{GENDER:$1|$1}}.",
        "userlogin-createanother": "Stofna annan aðgang",
        "createacct-emailrequired": "Netfang",
        "createacct-emailoptional": "Netfang (valfrjálst)",
-       "createacct-email-ph": "Skrifaðu niður netfangið þitt",
+       "createacct-email-ph": "Settu inn netfangið þitt",
        "createacct-another-email-ph": "Skrifaðu netfang",
        "createaccountmail": "Nota handahófsvalið bráðabirgðalykilorð og senda það á netfangið sem er tilgreint hér fyrir neðan",
        "createacct-realname": "Raunverulegt nafn (valfrjálst)",
        "createacct-reason-ph": "Afhverju ertu að búa til annan aðgang",
        "createacct-submit": "Búa til aðganginn",
        "createacct-another-submit": "Stofna aðgang",
+       "createacct-continue-submit": "Halda áfram við að búa til aðgang",
+       "createacct-another-continue-submit": "Halda áfram við að búa til aðgang",
        "createacct-benefit-heading": "{{SITENAME}} er skrifuð af fólki eins og þér.",
        "createacct-benefit-body1": "{{PLURAL:$1|breyting|breytingar}}",
        "createacct-benefit-body2": "{{PLURAL:$1|síða|síður}}",
        "emaildisabled": "Þessi síða getur ekki sent tölvupóst.",
        "accountcreated": "Aðgangur búinn til",
        "accountcreatedtext": "Notandaaðgangurinn fyrir [[{{ns:User}}:$1|$1]] ([[{{ns:User talk}}:$1|spjall]]) hefur verið búinn til.",
-       "createaccount-title": "Innskráningagerð á {{SITENAME}}",
+       "createaccount-title": "Gerð notandaaðgangs á {{SITENAME}}",
        "createaccount-text": "Einhver bjó til aðgang fyrir netfangið þitt á {{SITENAME}} ($4) undir nafninu „$2“, með lykilorðið „$3“.\nÞú ættir að skrá þig inn og breyta lykilorðinu núna.\n\nÞú getur hunsað þessi skilaboð, ef villa hefur átt sér stað.",
        "login-throttled": "Þér hefur of oft mistekist að skrá þig inn með þessu notandanafni.\nBíddu $1 áður en þú reynir aftur.",
        "login-abort-generic": "Innskráningin misheppnaðist - hætt var við hana.",
        "loginlanguagelabel": "Tungumál: $1",
        "suspicious-userlogout": "Beiðni um útskráningu hafnað því hún var líklegast send frá biluðum vafra eða vefseli sem hefur vistað vefsíðuna í flýtiminni.",
        "createacct-another-realname-tip": "Alvöru nafn er valfrjálst. Ef þú kýst að gefa það upp, verður það notað til að gefa þér heiður af verkum þínum.",
-       "pt-login": "Innskrá",
-       "pt-login-button": "Innskrá",
+       "pt-login": "Skrá inn",
+       "pt-login-button": "Skrá inn",
+       "pt-login-continue-button": "Halda áfram við að skrá þig inn",
        "pt-createaccount": "Stofna aðgang",
        "pt-userlogout": "Útskrá",
        "php-mail-error-unknown": "Óþekkt villa í PHP mail() aðgerð.",
        "botpasswords-label-delete": "Eyða",
        "botpasswords-label-resetpassword": "Endurstilla lykilorðið",
        "resetpass_forbidden": "Ekki er hægt að breyta lykilorðum",
+       "resetpass_forbidden-reason": "Ekki er hægt að breyta lykilorðum: $1",
        "resetpass-no-info": "Þú verður að vera skráð(ur) inn til að hafa aðgang að þessari síðu.",
        "resetpass-submit-loggedin": "Breyta lykilorði",
        "resetpass-submit-cancel": "Hætta við",
        "passwordreset-emailelement": "Notandanafn: \n$1\n\nBráðabirgðalykilorð: \n$2",
        "passwordreset-emailsentemail": "Ef þetta netfang er skráð fyrir aðganginum þínum þá hefur töluvpóstur verið sendur til að endursetja lykilorðið.",
        "passwordreset-emailsentusername": "Ef eitthvað netfang er skráð fyrir aðganginum þínum, þá mun verða sendur töluvpóstur til að endursetja lykilorðið.",
+       "passwordreset-invalidemail": "Ógilt tölvupóstfang",
        "changeemail": "Breyta eða fjarlægja netfang",
        "changeemail-header": "Fylltu út þetta eyðublað til að breyta netfanginu þínu. Ef þú vilt fjarlægja tengingu allra netfanga frá aðganginum þínum skildu þá netfangs reitinn eftir tóman.",
        "changeemail-no-info": "Þú verður að vera skráð(ur) inn til að hafa aðgang að þessari síðu.",
        "showdiff": "Sýna breytingar",
        "blankarticle": "<strong>Viðvörun:</strong> Síðan sem þú ert að búa til er tóm.\nEf þú smellir aftur á \"$1\", verður síðan búin til án innihalds.",
        "anoneditwarning": "<strong>Viðvörun:</strong> Þú ert ekki innskráð(ur). Vistfang þitt verður sýnt opinberlega ef þú gerir einhverjar breytingar. Ef þú <strong>[$1 skráir þig inn]</strong> eða <strong>[$2 stofnar aðgang]</strong> munu breytingarnar þínar vera tengdar við notandanafn þitt, ásamt öðrum kostum.",
-       "anonpreviewwarning": "Þú ert ekki innskráð(ur). Vistfang þitt skráist í breytingaskrá síðunnar.",
+       "anonpreviewwarning": "<em>Þú ert ekki skráð(ur) inn. Vistfang þitt skráist í breytingaskrá síðunnar.</em>",
        "missingsummary": "'''Áminning:''' Þú hefur ekki skrifað breytingarágrip.\nEf þú smellir á Vista aftur, verður breyting þín vistuð án þess.",
        "missingcommenttext": "Gerðu svo vel og skrifaðu athugasemd fyrir neðan.",
        "missingcommentheader": "<strong>Áminning:</strong> Þú hefur ekki gefið upp umræðuefni.\nEf þú smellir á \"$1\" aftur, verður breyting þín vistuð án þess.",
        "summary-preview": "Forskoða breytingarágrip:",
-       "subject-preview": "Forskoðun umræðuefnis:",
+       "subject-preview": "Forskoðun viðfangsefnis:",
        "blockedtitle": "Notandi er bannaður",
        "blockedtext": "'''Notandanafn þitt eða vistfang hefur verið bannað.'''\n\nBannið var sett af $1.\nÁstæðan er eftirfarandi: ''$2''.\n\n* Bannið hófst: $8\n* Banninu lýkur: $6\n* Sá sem banna átti: $7\n\nÞú getur haft samband við $1 eða annan [[{{MediaWiki:Grouppage-sysop}}|stjórnanda]] til að ræða bannið.\nÞú getur ekki notað „Senda þessum notanda tölvupóst“ aðgerðina nema gilt netfang sé skráð í [[Special:Preferences|kjörstillingum þínum]] og að þér hafi ekki verið óheimilað það.\nNúverandi vistfang þitt er $3, og bannnúmerið er #$5.\nHafðu með allar þessar upplýsingar hér fyrir ofan í fyrirspurnum þínum.",
        "autoblockedtext": "Vistfang þitt hefur verið sjálfvirkt bannað því það var notað af öðrum notanda, sem var bannaður af $1.\nÁstæðan er eftirfarandi:\n\n:''$2''\n\n* Bannið hófst: $8\n* Banninu lýkur: $6\n* Sá sem banna átti: $7\n\nÞú getur haft samband við $1 eða annan [[{{MediaWiki:Grouppage-sysop}}|stjórnanda]] til að ræða bannið.\n\nAthugaðu að þú getur ekki notað „Senda þessum notanda tölvupóst“ aðgerðina nema gilt netfang sé skráð í [[Special:Preferences|kjörstillingum þínum]] og að þér hafi ekki verið óheimilað það.\n\nNúverandi vistfang þitt er $3, og bannnúmerið er #$5.\nHafðu með allar þessar upplýsingar hér fyrir ofan í fyrirspurnum þínum.",
        "nosuchsectiontitle": "Hluti ekki til",
        "nosuchsectiontext": "Þú reyndir að breyta hluta sem er ekki til.\nHlutinn gæti hafa verið fluttur til eða hent á meðan þú varst að skoða síðuna.",
        "loginreqtitle": "Innskráningar krafist",
-       "loginreqlink": "innskrá",
+       "loginreqlink": "skrá inn",
        "loginreqpagetext": "Þú þarft að $1 þig til að geta séð aðrar síður.",
        "accmailtitle": "Lykilorð sent.",
        "accmailtext": "Lykilorðið fyrir [[User talk:$1|$1]] hefur verið sent á $2. Hægt er að breyta því á síðunni ''[[Special:ChangePassword|breyta lykilorði]]'' þegar notandinn hefur skráð sig inn.",
        "readonlywarning": "<strong>AÐVÖRUN: Gagnagrunninum hefur verið læst til að unnt sé að framkvæma viðhaldsaðgerðir, svo þú getur ekki vistað breytingar þínar núna.</strong>\nÞú ættir að klippa og líma textann yfir í textaskjal til þess að geyma hann til seinni tíma.\n\nKerfisstjórinn sem læsti honum gaf þessa skýringu: $1",
        "protectedpagewarning": "'''Viðvörun: Þessari síðu hefur verið læst svo aðeins notendur með möppudýraréttindi geti breytt henni.'''\nSíðasta færsla síðunnar úr verndunarskrá er sýnd til skýringar:",
        "semiprotectedpagewarning": "'''Athugið''': Þessari síðu hefur verið læst þannig að aðeins innskráðir notendur geti breytt henni.\nSíðasta færsla síðunnar úr verndunarskrá er sýnd til skýringar:",
-       "cascadeprotectedwarning": "<strong>Viðvörun:</strong> Þessari síðu hefur verið læst svo aðeins möppudýr geta breytt henni, því hún er ítengd keðjuvörn eftirfarandi {{PLURAL:$1|síðu|síðna}}:",
+       "cascadeprotectedwarning": "<strong>Viðvörun:</strong> Þessari síðu hefur verið læst þannig að aðeins notendur með [[Special:ListGroupRights|sérstök réttindi]] geta breytt henni, því hún er ítengd keðjuvörn eftirfarandi {{PLURAL:$1|síðu|síðna}}:",
        "titleprotectedwarning": "''VIÐVÖRUN: Þessari síðu hefur verið læst svo aðeins [[Special:ListGroupRights|sérstakir notendur]] geta breytt henni.'''\nVerndunarskrá síðunnar er gefin fyrir neðan til tilvísunar.",
        "templatesused": "Sniðmát {{PLURAL:$1|notað|notuð}} á þessari síðu:",
        "templatesusedpreview": "Sniðmát {{PLURAL:$1|notað|notuð}} í forskoðuninni:",
        "permissionserrorstext": "Þú hefur ekki leyfi til að gera þetta, af eftirfarandi {{PLURAL:$1|ástæðu|ástæðum}}:",
        "permissionserrorstext-withaction": "Þú hefur ekki réttindi til að $2, af eftirfarandi {{PLURAL:$1|ástæðu|ástæðum}}:",
        "recreate-moveddeleted-warn": "'''Viðvörun: Þú ert að endurskapa síðu sem áður hefur verið eytt.'''\n\nAthuga skal hvort viðeigandi sé að gera þessa síðu.\nEyðingarskrá og flutningaskrá fyrir þessa síðu eru útvegaðar hér til þæginda:",
-       "moveddeleted-notice": "Þessari síðu hefur verið eytt.\nEyðingaskrá og flutningaskrá síðunnar eru gefnar fyrir neðan til tilvísunar.",
-       "moveddeleted-notice-recent": "Því miður var þessari síðu eytt nýlega (innan síðustu 24 tímana).\nEyðingar og færsluskráin fyrir síðuna eru gefnar hér fyrir neðan til glöggvunar.",
+       "moveddeleted-notice": "Þessari síðu hefur verið eytt.\nEyðinga-, verndunar- og flutningaskrá síðunnar eru gefnar fyrir neðan til tilvísunar.",
+       "moveddeleted-notice-recent": "Því miður var þessari síðu eytt nýlega (innan síðustu 24 klst).\nEyðingar-, verndunar- og færsluskrár fyrir síðuna eru gefnar hér fyrir neðan til glöggvunar.",
        "log-fulllog": "Skoða alla aðgerðaskrána",
        "edit-hook-aborted": "Breyting síðu stöðvuð af viðbótarkrók (extension hook).\nEngin skýring gefin.",
        "edit-gone-missing": "Gat ekki uppfært síðu.\nSvo virðist sem henni hafi verið eytt.",
        "search-file-match": "(passar við innihald skráa)",
        "search-suggest": "Varstu að leita að: $1",
        "search-rewritten": "Sýni niðurstöður $1. Leita í staðinn að $2.",
-       "search-interwiki-caption": "Systurverkefni",
+       "search-interwiki-caption": "Niðurstöður úr systurverkefnum",
        "search-interwiki-default": "Útkomur frá $1:",
        "search-interwiki-more": "(fleiri)",
+       "search-interwiki-more-results": "fleiri niðurstöður",
        "search-relatedarticle": "Tengt",
        "searchrelated": "tengt",
        "searchall": "öllum",
        "search-external": "Ytri leit",
        "searchdisabled": "{{SITENAME}}-leit er óvirk.\nÞú getur leitað í genum Google á meðan.\nAthugaðu að skrár þeirra yfir {{SITENAME}}-efni kunna að vera úreltar.",
        "search-error": "Villa kom upp við leit að: $1",
+       "search-warning": "Aðvörun kom upp við leit: $1",
        "preferences": "Kjörstillingar",
        "mypreferences": "Kjörstillingar",
        "prefs-edits": "Fjöldi breytinga:",
        "prefs-editwatchlist-clear": "Hreinsa vaktlista",
        "prefs-watchlist-days": "Fjöldi daga sem vaktlistinn nær yfir:",
        "prefs-watchlist-days-max": "Hámark $1 {{PLURAL:$1|dagur|dagar}}",
-       "prefs-watchlist-edits": "Fjöldi breytinga sem vaktlistinn nær yfir:",
+       "prefs-watchlist-edits": "Hámarksfjöldi breytinga sem birta skal í vaktlista:",
        "prefs-watchlist-edits-max": "Hámarkstala: 1000",
        "prefs-watchlist-token": "Tóki vaktlistans:",
        "prefs-misc": "Aðrar stillingar",
        "username": "{{Gender:$1|Notandanafn}}:",
        "prefs-memberingroups": "{{GENDER:$2|Meðlimur}} {{PLURAL:$1|hóps|hópa}}:",
        "prefs-memberingroups-type": "$1",
+       "group-membership-link-with-expiry": "$1 (til $2)",
        "prefs-registration": "Skráningartími:",
        "prefs-registration-date-time": "$1",
        "yourrealname": "Fullt nafn:",
        "prefs-diffs": "Breytingar",
        "prefs-help-prefershttps": "Þessi stilling tekur gildi í næsta skiptið sem þú skráir þig inn.",
        "prefswarning-warning": "Þú hefur gert breytingar á kjörstillingum þínum sem ekki er búið að vista.\nEf þú ferð af þessari síðu án þess að smella á \"$1\" verða kjörstillingar þínar ekki uppfærðar.",
-       "userrights": "Breyta notandaréttindum",
+       "userrights": "Notandaréttindi",
        "userrights-lookup-user": "Velja notanda",
        "userrights-user-editname": "Skráðu notandanafn:",
        "editusergroup": "Hlaða inn notanda hópum",
        "editinguser": "Breyti réttindum {{GENDER:$1|notandans}} <strong>[[User:$1|$1]]</strong> $2",
-       "userrights-editusergroup": "Breyta notandahópum",
+       "userrights-editusergroup": "Breyta hópum {{GENDER:$1|notanda}}",
+       "userrights-viewusergroup": "Skoða hópa {{GENDER:$1|notanda}}",
        "saveusergroups": "Vista {{GENDER:$1|notanda}} hópa",
        "userrights-groupsmember": "Meðlimur:",
        "userrights-groupsmember-auto": "Sjálfvirkt bætt við sem meðlimur í:",
        "userrights-groupsmember-type": "$1",
-       "userrights-groups-help": "Þú getur breytt hópunum sem að þessi notandi er í.\n* Valinn reitur þýðir að notandinn er í hópnum.\n* Óvalinn reitur þýðir að notandinn er ekki í hópnum.\n* Stjarnan (*) þýðir að þú getur ekki fært hópinn eftir að þú hefur breytt honum, eða öfugt.",
+       "userrights-groups-help": "Þú getur breytt hópunum sem að þessi notandi er í.\n* Valinn reitur þýðir að notandinn er í hópnum.\n* Óvalinn reitur þýðir að notandinn er ekki í hópnum.\n* Stjarnan (*) þýðir að þú getur ekki fært hópinn eftir að þú hefur breytt honum, eða öfugt.\n* Myllumerki (#) þýðir að þú getur flutt til baka úreldingartíma á þátttöku í þessum hópi; þú getur ekki lengt hann.",
        "userrights-reason": "Ástæða:",
        "userrights-no-interwiki": "Þú hefur ekki leyfi til að breyta notandaréttindum á öðrum wiki-síðum.",
        "userrights-nodatabase": "Gagnagrunnurinn $1 er ekki til eða ekki staðbundinn.",
        "userrights-changeable-col": "Hópar sem þú getur breytt",
        "userrights-unchangeable-col": "Hópar sem þú getur ekki breytt",
        "userrights-irreversible-marker": "$1*",
+       "userrights-expiry-current": "Rennur út $1",
+       "userrights-expiry-none": "Rennur ekki út",
+       "userrights-expiry": "Rennur út:",
+       "userrights-expiry-existing": "Núverandi gildislok: $3, $2",
+       "userrights-expiry-othertime": "Annar tími:",
+       "userrights-expiry-options": "1 dagur:1 dagur,1 vika:1 vika,1 mánuður:1 mánuður,3 mánuðir:3 mánuðir,6 mánuðir:6 mánuðir,1 ár:1 ár",
        "userrights-conflict": "Árekstur í að breyta notandaréttindum! Skoðaðu þetta aftur og staðfestu breytingar þínar.",
        "group": "Hópur:",
        "group-user": "Notendur",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (sjá einng [[Special:NewPages|lista yfir nýjar síður]])",
        "recentchanges-legend-plusminus": "(<em>±123</em>)",
        "recentchanges-submit": "Sýna",
+       "rcfilters-tag-remove": "Fjarlægja '$1'",
+       "rcfilters-legend-heading": "<strong>Listi yfir styttingar</strong>",
+       "rcfilters-grouping-title": "Hópun",
+       "rcfilters-activefilters": "Virkar síur",
+       "rcfilters-advancedfilters": "Ítarlegar síur",
+       "rcfilters-limit-title": "Breytingar sem á að sýna",
+       "rcfilters-limit-shownum": "Birta síðustu {{PLURAL:$1|breytingu|$1 breytingar}}",
+       "rcfilters-days-title": "Síðustu daga",
+       "rcfilters-hours-title": "Síðustu klukkutíma",
+       "rcfilters-days-show-days": "$1 {{PLURAL:$1|dag|daga}}",
+       "rcfilters-days-show-hours": "$1 {{PLURAL:$1|klukkustund|klukkustundir}}",
+       "rcfilters-highlighted-filters-list": "Áherslulitað: $1",
+       "rcfilters-quickfilters": "Vistaðar síur",
+       "rcfilters-savedqueries-defaultlabel": "Vistaðar síur",
+       "rcfilters-savedqueries-rename": "Endurnefna",
+       "rcfilters-savedqueries-setdefault": "Setja sem sjálfgefið",
+       "rcfilters-savedqueries-unsetdefault": "Fjarlægja sjálfgefið",
+       "rcfilters-savedqueries-remove": "Fjarlægja",
+       "rcfilters-savedqueries-new-name-label": "Heiti",
+       "rcfilters-savedqueries-new-name-placeholder": "Lýstu markmiði síunnar",
+       "rcfilters-savedqueries-apply-label": "Búa til síu",
+       "rcfilters-savedqueries-apply-and-setdefault-label": "Búa til sjálfgefna síu",
+       "rcfilters-savedqueries-cancel-label": "Hætta við",
+       "rcfilters-clear-all-filters": "Hreinsa allar síur",
+       "rcfilters-show-new-changes": "Skoða nýjustu breytingarnar",
+       "rcfilters-filterlist-title": "Síur",
+       "rcfilters-highlightbutton-title": "Áherslulita niðurstöður",
+       "rcfilters-highlightmenu-title": "Veldu lit",
+       "rcfilters-filter-editsbyself-label": "Breytingar eftir þig",
+       "rcfilters-filter-editsbyself-description": "Þín eigin framlög.",
+       "rcfilters-filter-editsbyother-label": "Breytingar eftir aðra",
+       "rcfilters-filter-editsbyother-description": "Allir breytingar nema þínar eigin.",
+       "rcfilters-filtergroup-userExpLevel": "Skráning notanda og reynsla",
+       "rcfilters-filter-user-experience-level-registered-label": "Skráð/ur",
+       "rcfilters-filter-user-experience-level-unregistered-label": "Óskráður",
+       "rcfilters-filter-user-experience-level-newcomer-label": "Byrjendur",
+       "rcfilters-filter-user-experience-level-learner-label": "Námshestar",
+       "rcfilters-filter-user-experience-level-experienced-label": "Vanir notendur",
+       "rcfilters-filtergroup-automated": "Sjálfvirk framlög",
+       "rcfilters-filter-bots-label": "Vélmenni",
+       "rcfilters-filter-humans-label": "Manneskja (ekki vélmenni)",
+       "rcfilters-filtergroup-reviewstatus": "Staða yfirferðar",
+       "rcfilters-filter-patrolled-label": "Vaktað",
+       "rcfilters-filter-minor-label": "Minniháttar breytingar",
+       "rcfilters-filter-watchlist-watched-label": "Á vaktlista",
        "rcnotefrom": "Að neðan {{PLURAL:$5|er breyting síðan|eru breytingar síðan}} <strong>$3, $4</strong> (allt að <strong>$1</strong> sýndar).",
        "rclistfrom": "Sýna breytingar frá og með $3 $2",
        "rcshowhideminor": "$1 minniháttar breytingar",
        "rcshowhideliu": "$1 skráða notendur",
        "rcshowhideliu-show": "Sýna",
        "rcshowhideliu-hide": "Fela",
-       "rcshowhideanons": "$1 óinnskráða notendur",
+       "rcshowhideanons": "$1 nafnlausa notendur",
        "rcshowhideanons-show": "Sýna",
        "rcshowhideanons-hide": "Fela",
        "rcshowhidepatr": "$1 vaktaðar breytingar",
        "uploadbtn": "Hlaða inn skrá",
        "reuploaddesc": "Hætta við og fara aftur á innhleðsluformið.",
        "upload-tryagain": "Sendu breytta myndlýsingu",
-       "uploadnologin": "Óinnskráð(ur)",
+       "uploadnologin": "Ekki skráð/ur inn",
        "uploadnologintext": "Þú verður $1 til að hlaða inn skrám.",
        "upload_directory_missing": "Innhleðslumappan ($1) er týnd og vefþjónninn gat ekki búið hana til.",
        "upload_directory_read_only": "Mistókst að skrifa í innhleðslumöppu ($1) á vefþjóninum.",
        "upload-copy-upload-invalid-domain": "Lokað er fyrir afritun skráa frá öðrum vefþjónum á þessu vefsvæði.",
        "upload-dialog-title": "Hlaða inn skrá",
        "upload-dialog-button-cancel": "Hætta við",
+       "upload-dialog-button-back": "Til baka",
        "upload-dialog-button-done": "Lokið",
        "upload-dialog-button-save": "Vista",
        "upload-dialog-button-upload": "Hlaða inn",
        "uploadstash-badtoken": "Þessi aðgerð misheppnaðist, kannski hafa réttindi þín til breytinga runnið út.\nReyndu aftur.",
        "uploadstash-errclear": "Tæming listans mistókst.",
        "uploadstash-refresh": "Endurhlaða listann",
+       "uploadstash-thumbnail": "skoða smámynd",
        "invalid-chunk-offset": "Ógild raðbreyting bunka",
        "img-auth-accessdenied": "Aðgangur óheimill",
        "img-auth-nopathinfo": "PATH_INFO vantar.\nBiðlarinn þínn er ekki stilltur til að gefa upp þessar upplýsingar.\nÞær mega vera CGI-byggðar og mega ekki styðja img_auth.\nhttps://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Image_Authorization",
        "apisandbox-submit-invalid-fields-title": "Sumir reitir eru ógildir",
        "apisandbox-results": "Niðurstöður",
        "apisandbox-alert-field": "Gildi þessa reits er ekki leyfilegt.",
+       "apisandbox-continue": "Halda áfram",
+       "apisandbox-continue-clear": "Hreinsa",
        "booksources": "Bókaleit",
        "booksources-search-legend": "Leita að bókaheimildum",
        "booksources-isbn": "ISBN:",
        "trackingcategories-nodesc": "Enginn lýsing tiltæk.",
        "trackingcategories-disabled": "Flokkurinn er óvirkur",
        "mailnologin": "Ekkert netfang til að senda á",
-       "mailnologintext": "Þú verður að vera [[Special:UserLogin|innskráð(ur)]] auk þess að hafa gilt netfang í [[Special:Preferences|stillingunum]] þínum til að senda tölvupóst til annara notenda.",
+       "mailnologintext": "Þú verður að vera [[Special:UserLogin|skráð(ur) inn]] auk þess að hafa gilt netfang í [[Special:Preferences|stillingunum]] þínum til að senda tölvupóst til annara notenda.",
        "emailuser": "Senda þessum notanda tölvupóst",
        "emailuser-title-target": "Sendu þessum {{GENDER:$1|notanda}} tölvupóst",
        "emailuser-title-notarget": "Senda tölvupóst",
        "emailccsubject": "Afrit af skilaboðinu þínu til $1: $2",
        "emailsent": "Sending tókst",
        "emailsenttext": "Skilaboðin þín hafa verið send.",
-       "emailuserfooter": "Þessi tölvupóstur var {{GENDER:$1|sendur}} af $1 til {{GENDER:$2|$2}} með möguleikanum \"{{int:emailuser}}\" á {{SITENAME}}. Netfangið {{GENDER:$2|þitt}} verður sent {{GENDER:$1|upphaflega sendandanum}}, sem uppljóstrar netfangi {{GENDER:$2|þínu}} til hans.",
+       "emailuserfooter": "Þessi tölvupóstur var {{GENDER:$1|sendur}} af $1 til {{GENDER:$2|$2}} með möguleikanum \"{{int:emailuser}}\" á {{SITENAME}}.Ef {{GENDER:$2|þú}} svarar þessum pósti, verður netfangið {{GENDER:$2|þitt}} sent {{GENDER:$1|upphaflega sendandanum}}, sem uppljóstrar netfangi {{GENDER:$2|þínu}} til  {{GENDER:$1|þeirra}}.",
        "usermessage-summary": "Skil eftir kerfismeldingu.",
        "usermessage-editor": "Skilaboðakerfi",
        "watchlist": "Vaktlistinn",
        "watchlistfor2": "Eftir $1 $2",
        "nowatchlist": "Vaktlistinn er tómur.",
        "watchlistanontext": "Skráðu þig til að skoða eða breyta hlutum á vaktlistanum þínum.",
-       "watchnologin": "Óinnskráð(ur)",
+       "watchnologin": "Ekki skráð/ur inn",
        "addwatch": "Bæta á vaktlistann",
        "addedwatchtext": "Síðunni „[[:$1]]“ og spjallsíðu hennar hafa verið bætt á [[Special:Watchlist|vaktlistann]] þinn.",
        "addedwatchtext-short": "Síðunni  \"$1\" hefur verið bætt við á vaktlistann þinn.",
        "unwatchthispage": "Hætta vöktun",
        "notanarticle": "Ekki efnisleg síða",
        "notvisiblerev": "Síðasta breyting eftir annan notanda hefur verið eytt.",
-       "watchlist-details": "{{PLURAL:$1|$1 síða|$1 síður}} á vaktlistanum þínum, fyrir utan spjallsíður.",
+       "watchlist-details": "{{PLURAL:$1|$1 síða|$1 síður}} á vaktlistanum þínum (fyrir utan spjallsíður).",
        "wlheader-enotif": "Tilkynning með tölvupósti er virk.",
        "wlheader-showupdated": "Síðum sem hefur verið breytt síðan þú skoðaðir þær síðast eru '''feitletraðar'''.",
        "wlnote": "Hér fyrir neðan {{PLURAL:$1|er síðasta <strong>$1</strong> breyting|eru síðustu <strong>$1</strong> breytingar}} {{PLURAL:$2|síðasta <strong>$2</strong> klukkutímann|síðustu <strong>$2</strong> klukkutímana}}, frá $3, $4.",
        "enotif_body_intro_moved": "Síðan „$1” sem þú hefur beðið um að fylgjast með á {{SITENAME}} hefur verið færð $PAGEEDITDATE af {{gender:$2|$2}}. Þetta er tengill á síðuna: $3.",
        "enotif_body_intro_restored": "Síðan „$1” sem þú hefur beðið um að fylgjast með á {{SITENAME}} hefur verið endurvakin $PAGEEDITDATE af {{gender:$2|$2}}. Þetta er tengill á síðuna: $3.",
        "enotif_body_intro_changed": "Síðan „$1” sem þú hefur beðið um að fylgjast með á {{SITENAME}} hefur verið breytt $PAGEEDITDATE af {{gender:$2|$2}}. Þetta er tengill á síðuna: $3.",
-       "enotif_lastvisited": "Heimsóttu eftirfarandi tengil til að sjá allar breytingar síðan \nþú heimsóttir síðuna síðast:\n  $1",
-       "enotif_lastdiff": "Einnig getur þú heimsótt eftirfarandi tengil til að skoða þessa breytingu:\n  $1",
+       "enotif_lastvisited": "Til að sjá allar breytingar síðan þú heimsóttir síðuna síðast, skoðaðu $1",
+       "enotif_lastdiff": "Til að sjá þessa breytingu, skoðaðu $1",
        "enotif_anon_editor": "ónefndum notanda $1",
        "enotif_body": "Kæri $WATCHINGUSERNAME,\n\n$PAGEINTRO\n$NEWPAGE\n\n$PAGEEDITOR skildi eftir eftirfarandi breytingarágrip: $PAGESUMMARY $PAGEMINOREDIT\n\nTil þess að hafa samband við $PAGEEDITOR, smelltu á $PAGEEDITOR_WIKI eða sentu tölvupóst á $PAGEEDITOR_EMAIL\n\nAthugaðu að frekari aðgerðir á $PAGETITLE leiða\nekki af sér fleiri tilkynningar fyrr en þú hefur heimsótt síðuna á meðan þú ert skráð/ur inn. Þú getur einnig endursett tilkynningar fyrir allar þær síður sem þú fylgist með.\n\nKveðja,\n{{SITENAME}}\n\n--\n\nTil þess að breyta stillingum um hvenær þú færð sendar tilkynningar, smelltu á:\n\n{{canonicalurl:{{#special:Preferences}}}}\n\n\nTil þess að hætta að fylgjast með „$PAGETITLE”, smelltu á:\n\n$UNWATCHURL\n\nFrekari hjálp er að finna á $HELPPAGE.",
+       "enotif_minoredit": "Þetta er minniháttar breyting",
        "created": "búin til",
        "changed": "breytt",
        "deletepage": "Eyða",
        "editcomment": "Beytingaágripið var: <em>$1</em>.",
        "revertpage": "Tók aftur breytingar [[Special:Contributions/$2|$2]] ([[User talk:$2|spjall]]), breytt til síðustu útgáfu [[User:$1|$1]]",
        "revertpage-nouser": "Tók aftur breytingar falins notanda til síðustu útgáfu {{GENDER:$1|[[User:$1|$1]]}}",
-       "rollback-success": "Tók til baka breytingar eftir $1; núverandi $2.",
+       "rollback-success": "Tók til baka breytingar eftir {{GENDER:$3|$1}};\nsetti yfir á síðustu útgáfu eftir {{GENDER:$4|$2}}.",
        "sessionfailure-title": "Mistök í setu",
-       "sessionfailure": "Líklega er vandamál með innskráningar setuna þína;\nhætt hefur verið við þessa aðgerð sem vörn gegn mögulegu samskiptaráni setunar.\nFarðu aftur á fyrri síðu, endurhladdu hana og reyndu aftur.",
+       "sessionfailure": "Líklega er vandamál með innskráningarsetuna þína;\nhætt hefur verið við þessa aðgerð sem vörn gegn mögulegu samskiptaráni setunar.\nFarðu aftur á fyrri síðu, endurhladdu hana og reyndu aftur.",
        "changecontentmodel-title-label": "Titill síðu",
        "changecontentmodel-reason-label": "Ástæða:",
+       "changecontentmodel-submit": "Breyta",
        "logentry-contentmodel-change-revertlink": "taka aftur",
        "logentry-contentmodel-change-revert": "taka aftur",
        "protectlogpage": "Verndunarskrá",
        "sp-contributions-uploads": "innsendingar",
        "sp-contributions-logs": "aðgerðaskrá",
        "sp-contributions-talk": "spjall",
-       "sp-contributions-userrights": "Breyta notandaréttindum",
+       "sp-contributions-userrights": "Breyta {{GENDER:$1|notandaréttindum}}",
        "sp-contributions-blocked-notice": "Þessi notandi er í banni.\nSíðasta færsla notandans úr bannskrá er sýnd hér fyrir neðan til skýringar:",
        "sp-contributions-blocked-notice-anon": "Þetta vistfang er í banni.\nSíðasta færsla vistfangsins úr bannskrá er sýnd hér fyrir neðan til skýringar:",
        "sp-contributions-search": "Leita að framlögum",
        "ipbexpiry": "Bannið rennur út:",
        "ipbreason": "Ástæða:",
        "ipbreason-dropdown": "* Algengar bannástæður\n** Setur inn rangar upplýsingar\n** Fjarlægir efni af síðum\n** Setur inn rusltengla á utanaðkomandi síður\n** Setur inn vitleysu/þvaður á síður\n** Yfirþyrmandi framkoma/áreitni\n** Misnotkun á fjölda notandanafna\n** Óásættanlegt notandanafn",
-       "ipb-hardblock": "Banna innskráðum notendum að breyta frá þessu vistfangi.",
+       "ipb-hardblock": "Banna innskráðum notendum að breyta frá þessu IP-vistfangi.",
        "ipbcreateaccount": "Banna nýskráningu notandanafns",
        "ipbemailban": "Banna notanda að senda tölvupóst",
        "ipbenableautoblock": "Banna síðasta vistfang notanda sjálfkrafa; og þau vistföng sem viðkomandi notar til að breyta síðum",
        "ipb-unblock": "Afbanna notanda eða vistfang",
        "ipb-blocklist": "Sjá núverandi bönn",
        "ipb-blocklist-contribs": "Framlög fyrir {{GENDER:$1|$1}}",
+       "ipb-blocklist-duration-left": "$1 eftir",
        "unblockip": "Afbanna notanda",
        "unblockiptext": "Endurvekja skrifréttindi bannaðra notenda eða vistfanga.",
        "ipusubmit": "Afbanna",
        "unblocked-id": "Bann $1 hefur verið fjarlægt",
        "unblocked-ip": "[[Special:Contributions/$1|$1]] hefur verið afbannaður.",
        "blocklist": "Bannaðir notendur og vistföng",
+       "autoblocklist-submit": "Leita",
        "ipblocklist": "Bannaðir notendur og vistföng",
        "ipblocklist-legend": "Finna bannaðan notanda",
        "blocklist-userblocks": "Fela notendabönn",
        "movepagetalktext": "Ef þú hakar við þennan reit mun viðeigandi spjallsíða vera færð sjálfkrafa á nýja titilinn, nema að spjallsíða sem er ekki tóm sé þegar til staðar.\n\nÍ því tilfelli þarft þú að færa eða sameina síðuna handvirkt ef þess er óskað.",
        "moveuserpage-warning": "<strong>Viðvörun:</strong> Þú ert í þann mund að færa notandasíðu. Athugaðu aðeins síðan verður færð og notandanafni hans verður <em>ekki</em> breytt.",
        "movecategorypage-warning": "<strong>Viðvörun:</strong> Þú ert í þann mund að færa flokkssíðu. Athugaðu aðeins síðan verður færð og allar síður í gamla flokknum verða <em>ekki</em> endurflokkaðar í nýja flokkinn.",
-       "movenologintext": "Þú verður að vera [[Special:UserLogin|innskráð(ur)]] til að geta fært síður.",
+       "movenologintext": "Þú verður að vera [[Special:UserLogin|skráð(ur) inn]] til að geta fært síður.",
        "movenotallowed": "Þú hefur ekki leyfi til að færa síður.",
        "movenotallowedfile": "Þú hefur ekki leyfi til að færa skrár.",
        "cant-move-user-page": "Þú hefur ekki leyfi til að færa notandasíðu (fyrir utan undirsíður).",
        "import-nonewrevisions": "Engar breytingar voru fluttar inn (þær voru allar annaðhvort þegar til eða sleppt vegna villna).",
        "xml-error-string": "$1 í línu $2, dálki $3 ($4 bæt): $5",
        "import-upload": "Hlaða inn XML-gögnum",
-       "import-token-mismatch": "Týnd setugögn.\n\nÞú hefur kannski verið skráð/ur út. <strong>Athugaðu hvort þú sért ennþá skráð/ur inn og reyndu aftur</strong>.\nEf það virkar ekki, reyndu að [[Special:UserLogout|skrá þig út]], skrá þig aftur inn og gakktu úr skugga um að vafrinn þinn leyfi vefkökur frá þessu vefsvæði.",
+       "import-token-mismatch": "Týnd setugögn.\n\nÞú hefur kannski verið skráð/ur út. '''Athugaðu hvort þú sért ennþá skráð/ur inn og reyndu aftur'''.\nEf það virkar ekki, reyndu að [[Special:UserLogout|skrá þig út]], skrá þig aftur inn og gakktu úr skugga um að vafrinn þinn leyfi vefkökur frá þessu vefsvæði.",
        "import-invalid-interwiki": "Get ekki flutt inn frá þessum wiki.",
        "import-error-edit": "Síðan \"$1\" var ekki flutt inn því þú hefur ekki réttindi til að breyta henni.",
        "import-error-create": "Síðan \"$1\" var ekki flutt inn því þú hefur ekki réttindi til að stofna hana.",
        "tooltip-ca-nstab-category": "Sýna efnisflokkasíðuna",
        "tooltip-minoredit": "Merkja þessa breytingu sem minniháttar",
        "tooltip-save": "Vista breytingarnar",
+       "tooltip-publish": "Gefa út breytingarnar þínar",
        "tooltip-preview": "Forskoða breytingarnar þínar. Gerðu þetta áður en þú vistar.",
        "tooltip-diff": "Sýna hvaða breytingar þú gerðir á textanum.",
        "tooltip-compareselectedversions": "Sjá breytingarnar á þessari grein á milli útgáfanna sem þú valdir.",
        "pageinfo-length": "Lengd síðunnar (í bætum)",
        "pageinfo-article-id": "Einkennisnúmer síðunnar",
        "pageinfo-language": "Tungumál síðunnar",
+       "pageinfo-language-change": "breyta",
+       "pageinfo-content-model-change": "breyta",
        "pageinfo-robot-policy": "Attriðaskráning af vélmennum",
        "pageinfo-robot-index": "Heimilað",
        "pageinfo-robot-noindex": "Ekki heimilað",
        "pageinfo-category-pages": "Fjöldi síðna",
        "pageinfo-category-subcats": "Fjöldi undirflokka",
        "pageinfo-category-files": "Fjöldi skráa",
+       "pageinfo-user-id": "Notandanúmer",
        "markaspatrolleddiff": "Merkja sem yfirfarið",
        "markaspatrolledtext": "Merkja þessa síðu sem yfirfarna",
        "markaspatrolledtext-file": "Merkja þessa útgáfu skrár sem yfirfarna",
        "patrol-log-header": "Þetta er skrá yfir yfirfarnar breytingar.",
        "log-show-hide-patrol": "$1 listi yfir yfirfarnar síður",
        "log-show-hide-tag": "$1 merkjaannáll",
+       "confirm-markpatrolled-button": "Í lagi",
        "deletedrevision": "Eyddi gamla útgáfu $1",
        "filedeleteerror-short": "Villa við eyðingu: $1",
        "filedeleteerror-long": "Það kom upp villa við eyðingu skrárinnar: $1",
        "confirm-watch-top": "Bæta þessari síðu á vaktlistann þinn?",
        "confirm-unwatch-button": "Í lagi",
        "confirm-unwatch-top": "Fjarlægja þessa síðu af vaktlistanum þínum?",
+       "confirm-rollback-button": "Í lagi",
        "semicolon-separator": ";&#32;",
        "comma-separator": ",&#32;",
        "colon-separator": ":&#32;",
        "fileduplicatesearch-noresults": "Mistókst að finna skrána \"$1\"",
        "specialpages": "Kerfissíður",
        "specialpages-note-top": "Fyrirsögn",
-       "specialpages-note": "* Venjulegar kerfissíður.\n* <span class=\"mw-specialpagerestricted\">Kerfissíður með takmörkuðum aðgangi.</span>",
        "specialpages-group-maintenance": "Viðhaldsskýrslur",
        "specialpages-group-other": "Aðrar kerfissíður",
-       "specialpages-group-login": "Innskrá / Búa til aðgang",
+       "specialpages-group-login": "Skrá inn / Búa til aðgang",
        "specialpages-group-changes": "Nýlegar breytingar og skrár",
        "specialpages-group-media": "Skýrslur um gagnamiðla og innsendingar",
        "specialpages-group-users": "Notendur og réttindi",
        "tags-create-reason": "Ástæða:",
        "tags-create-submit": "Stofna",
        "tags-create-no-name": "Þú verður að gefa upp heiti merkisins.",
-       "tags-create-invalid-chars": "Heiti merkja mega ekki innihalda kommur (<code>,</code>) eða öfug skástrik (<code>/</code>).",
+       "tags-create-invalid-chars": "Heiti merkja mega ekki innihalda kommur (<code>,</code>), pípur (<code>|</code>), eða öfug skástrik (<code>/</code>).",
        "tags-create-invalid-title-chars": "Heiti merkja mega ekki innihalda stafi sem ekki má nota í síðutitlum.",
        "tags-create-already-exists": "Merkið \"$1\" er nú þegar til.",
        "tags-create-warnings-below": "Viltu halda áfram við að búa til merkið?",
        "tags-edit-chosen-placeholder": "Veldu einhver merki",
        "tags-edit-chosen-no-results": "Engin merki fundust sem samsvara",
        "tags-edit-reason": "Ástæða:",
+       "tags-edit-success": "Breytingarnar voru framkvæmdar.",
        "tags-edit-nooldid-title": "Ógild markútgáfa",
        "tags-edit-none-selected": "Vinsamlega veldu a.m.k. eitt merki til að bæta við eða fjarlægja.",
        "comparepages": "Bera saman síður",
        "compare-invalid-title": "Titillinn sem þú gafst upp er ógildur.",
        "compare-title-not-exists": "Umbeðinn titill er ekki til.",
        "compare-revision-not-exists": "Umbeðin útgáfa er ekki til.",
+       "diff-form": "Mismunur",
        "dberr-problems": "Því miður!Tæknilegir örðugleikar eru á þessari síðu.",
        "dberr-again": "Reyndu að bíða í nokkrar mínútur og endurhlaða síðan síðuna.",
        "dberr-info": "(Mistókst að fá aðgang að gagnaþjóni: $1)",
        "htmlform-cloner-create": "Bæta við meiru",
        "htmlform-cloner-delete": "Fjarlægja",
        "htmlform-cloner-required": "Það þarf allavega eitt gildi.",
+       "htmlform-date-placeholder": "ÁÁÁÁ-MM-DD",
+       "htmlform-time-placeholder": "KK:MM:SS",
+       "htmlform-datetime-placeholder": "ÁÁÁÁ-MM-DD KK:MM:SS",
        "htmlform-title-badnamespace": "[[:$1]] er ekki í \"{{ns:$2}}\" nafnrýminu.",
        "htmlform-title-not-creatable": "\"$1\" er ekki hægt að nota við að búa til titil á síðu",
        "htmlform-title-not-exists": "$1 er ekki til",
        "htmlform-user-not-exists": "<strong>$1</strong> er ekki til.",
        "htmlform-user-not-valid": "<strong>$1</strong> er ekki gilt notandanafn.",
        "logentry-delete-delete": "$1 {{GENDER:$2|eyddi}} síðunni $3",
-       "logentry-delete-restore": "$1 {{GENDER:$2|endurvakti}} $3",
+       "logentry-delete-restore": "$1 {{GENDER:$2|endurvakti}} síðu $3 ($4)",
        "logentry-delete-event": "$1 {{GENDER:$2|breytti}} sýnileika {{PLURAL:$5|færslu|$5 færslna}} á $3: $4",
        "logentry-delete-revision": "$1 {{GENDER:$2|breytti}} sýnileika {{PLURAL:$5|útgáfu|$5 útgáfna}} á $3: $4",
        "logentry-delete-event-legacy": "$1 {{GENDER:$2|breytti}} sýnileika færslna á $3",
        "api-error-emptypage": "Stofnun nýrra, tómra síðna er óheimil.",
        "api-error-publishfailed": "Innri villa: Vefþjónninn gat ekki gefið út bráðabirgðaskrá.",
        "api-error-stashfailed": "Innri villa: Vefþjónninn gat ekki geymt bráðabirgðaskrá.",
-       "api-error-unknown-warning": "Óþekkt viðvörun: $1",
+       "api-error-unknown-warning": "Óþekkt viðvörun: \"$1\".",
        "api-error-unknownerror": "Óþekkt villa: \"$1\".",
        "duration-seconds": "$1 {{PLURAL:$1|sekúnda|sekúndur}}",
        "duration-minutes": "$1 {{PLURAL:$1|mínúta|mínútur}}",
index c5f8303..6d7992b 100644 (file)
        "tog-watchlisthideminor": "Nascondi le modifiche minori negli osservati speciali",
        "tog-watchlisthideliu": "Nascondi le modifiche degli utenti registrati negli osservati speciali",
        "tog-watchlistreloadautomatically": "Ricarica automaticamente l'elenco degli osservati speciali ogni volta che si modifica un filtro (richiede JavaScript)",
+       "tog-watchlistunwatchlinks": "Aggiungi collegamenti diretti per seguire/non seguire gli elementi negli osservati speciali (richiede JavaScript per utilizzare questa funzionalità)",
        "tog-watchlisthideanons": "Nascondi le modifiche degli utenti anonimi negli osservati speciali",
        "tog-watchlisthidepatrolled": "Nascondi le modifiche verificate negli osservati speciali",
        "tog-watchlisthidecategorization": "Nascondi la categorizzazione delle pagine",
        "rcfilters-tag-remove": "Rimuovi '$1'",
        "rcfilters-legend-heading": "<strong>Elenco di abbreviazioni:</strong>",
        "rcfilters-other-review-tools": "<strong>Altri strumenti di revisione</strong>",
+       "rcfilters-group-results-by-page": "Raggruppa risultati per pagina",
        "rcfilters-grouping-title": "Raggruppamento",
        "rcfilters-activefilters": "Filtri attivi",
        "rcfilters-advancedfilters": "Filtri avanzati",
        "rcfilters-hours-title": "Ore recenti",
        "rcfilters-days-show-days": "$1 {{PLURAL:$1|giorno|giorni}}",
        "rcfilters-days-show-hours": "$1 {{PLURAL:$1|ora|ore}}",
+       "rcfilters-highlighted-filters-list": "Evidenziato: $1",
        "rcfilters-quickfilters": "Filtri salvati",
        "rcfilters-quickfilters-placeholder-title": "Nessun collegamento salvato ancora",
        "rcfilters-quickfilters-placeholder-description": "Per salvare le impostazioni del tuo filtro e riutilizzarle dopo, clicca l'icona segnalibro nell'area \"Filtri attivi\" qui sotto",
        "rcfilters-savedqueries-new-name-label": "Nome",
        "rcfilters-savedqueries-new-name-placeholder": "Descrivi lo scopo del filtro",
        "rcfilters-savedqueries-apply-label": "Crea filtro",
+       "rcfilters-savedqueries-apply-and-setdefault-label": "Crea filtro predefinito",
        "rcfilters-savedqueries-cancel-label": "Annulla",
        "rcfilters-savedqueries-add-new-title": "Salva le impostazioni attuali del filtro",
        "rcfilters-restore-default-filters": "Ripristina i filtri predefiniti",
        "rcfilters-empty-filter": "Nessun filtro attivo. Sono mostrati tutti i contributi.",
        "rcfilters-filterlist-title": "Filtri",
        "rcfilters-filterlist-whatsthis": "Come funzionano?",
-       "rcfilters-filterlist-feedbacklink": "Lascia un commento sulla nuova funzionalità sperimentale",
+       "rcfilters-filterlist-feedbacklink": "Dicci cosa ne pensi su questi (nuovi) strumenti di filtraggio",
        "rcfilters-highlightbutton-title": "Evidenzia risultati",
        "rcfilters-highlightmenu-title": "Seleziona un colore",
        "rcfilters-highlightmenu-help": "Seleziona un colore per evidenziare questa proprietà",
        "rcfilters-filter-previousrevision-description": "Tutte le modifiche che non sono la \"versione attuale\".",
        "rcfilters-filter-excluded": "Escluso",
        "rcfilters-tag-prefix-namespace-inverted": "<strong>:non</strong> $1",
-       "rcfilters-exclude-button-off": "Escludi selezionato",
-       "rcfilters-exclude-button-on": "Escludendo selezionato",
+       "rcfilters-exclude-button-off": "Escludi selezionati",
+       "rcfilters-exclude-button-on": "Escludendo selezionati",
        "rcfilters-view-advanced-filters-label": "Filtri avanzati",
        "rcfilters-view-tags": "Modifiche etichettate",
+       "rcfilters-view-namespaces-tooltip": "Filtra risultati per namespace",
+       "rcfilters-view-tags-tooltip": "Filtra risultati per etichette di modifica",
+       "rcfilters-view-return-to-default-tooltip": "Torna al menu filtri principale",
+       "rcfilters-watchlist-edit-watchlist-button": "Modifica il tuo elenco di pagine osservate",
        "rcnotefrom": "Di seguito {{PLURAL:$5|è elencata la modifica apportata|sono elencate le modifiche apportate}} a partire da <strong>$3, $4</strong> (mostrate fino a <strong>$1</strong>).",
        "rclistfromreset": "Reimposta la selezione della data",
        "rclistfrom": "Mostra le nuove modifiche a partire daː $2, $3",
        "enotif_lastdiff": "Per vedere questa modifica, vedi $1",
        "enotif_anon_editor": "utente anonimo $1",
        "enotif_body": "Gentile $WATCHINGUSERNAME,\n\n$PAGEINTRO $NEWPAGE\n\nOggetto dell'intervento, inserito dall'autore: $PAGESUMMARY $PAGEMINOREDIT\n\nContatta l'autore:\nvia posta elettronica: $PAGEEDITOR_EMAIL\nsul sito: $PAGEEDITOR_WIKI\n\nNon verranno inviate altre notifiche in caso di ulteriori attività, se non visiti la pagina dopo aver effettuato l'accesso. Inoltre, è possibile modificare le impostazioni di notifica per tutte le pagine nella lista degli osservati speciali.\n\nIl sistema di notifica di {{SITENAME}}, al tuo servizio\n\n--\nPer modificare le impostazioni delle notifiche via posta elettronica, visita \n{{canonicalurl:{{#special:Preferences}}}}\n\nPer modificare la lista degli osservati speciali, visita \n{{canonicalurl:{{#special:EditWatchlist}}}}\n\nPer rimuovere la pagina dalla lista degli osservati speciali, visita\n$UNWATCHURL\n\nPer commentare e ricevere aiuto:\n$HELPPAGE",
+       "enotif_minoredit": "Questa è una modifica minore",
        "created": "creata",
        "changed": "modificata",
        "deletepage": "Cancella pagina",
index d94dfb6..7991e23 100644 (file)
        "tog-shownumberswatching": "ページをウォッチしている利用者数を表示",
        "tog-oldsig": "既存の署名:",
        "tog-fancysig": "署名をウィキ文として扱う (自動リンクなし)",
-       "tog-uselivepreview": "ã\83©ã\82¤ã\83\96ã\83\97ã\83¬ã\83\93ã\83¥ã\83¼ã\82\92使ç\94¨",
+       "tog-uselivepreview": "ã\83\9aã\83¼ã\82¸ã\82\92å\86\8d読込ã\81\9bã\81\9aã\81«ã\83\97ã\83¬ã\83\93ã\83¥ã\83¼ã\82\92表示",
        "tog-forceeditsummary": "要約欄が空欄の場合に確認を促す",
        "tog-watchlisthideown": "自分の編集をウォッチリストに表示しない",
        "tog-watchlisthidebots": "ボットによる編集をウォッチリストに表示しない",
        "contentmodelediterror": "コンテンツモデルが <code>$1</code> であるため、この版を編集することができません。ページの現在のコンテンツモデルは <code>$2</code> です。",
        "recreate-moveddeleted-warn": "<strong>警告: 以前削除されたページを再作成しようとしています。</strong>\n\nこのページの編集を続行するのが適切かどうかご確認ください。\n参考までに、このページの削除と移動の記録を以下に示します:",
        "moveddeleted-notice": "このページは削除されています。\n参考のため、このページの削除と移動の記録を以下に表示します。",
-       "moveddeleted-notice-recent": "ç\94³ã\81\97訳ã\81\82ã\82\8aã\81¾ã\81\9bã\82\93ã\80\82ã\81\93ã\81®ã\83\9aã\83¼ã\82¸ã\81¯æ\9c\80è¿\91ï¼\8824æ\99\82é\96\93以å\86\85ï¼\89ã\81«å\89\8aé\99¤ã\81\95ã\82\8cã\81¾ã\81\97ã\81\9fã\80\82å\8f\82è\80\83ã\81®ã\81\9fã\82\81ã\80\81ã\81\93ã\81®ã\83\9aã\83¼ã\82¸ã\81®å\89\8aé\99¤ã\81¨移動の記録を以下に表示します。",
+       "moveddeleted-notice-recent": "ç\94³ã\81\97訳ã\81\82ã\82\8aã\81¾ã\81\9bã\82\93ã\80\82ã\81\93ã\81®ã\83\9aã\83¼ã\82¸ã\81¯æ\9c\80è¿\91ï¼\8824æ\99\82é\96\93以å\86\85ï¼\89ã\81«å\89\8aé\99¤ã\81\95ã\82\8cã\81¾ã\81\97ã\81\9fã\80\82å\8f\82è\80\83ã\81®ã\81\9fã\82\81ã\80\81ã\81\93ã\81®ã\83\9aã\83¼ã\82¸ã\81®å\89\8aé\99¤ã\80\81ä¿\9dè­·ã\80\81移動の記録を以下に表示します。",
        "log-fulllog": "完全な記録を閲覧",
        "edit-hook-aborted": "フックによって編集が破棄されました。\n理由は不明です。",
        "edit-gone-missing": "ページを更新できませんでした。\n既に削除されているようです。",
        "prefs-editwatchlist-clear": "ウォッチリストの全消去",
        "prefs-watchlist-days": "ウォッチリストの表示日数:",
        "prefs-watchlist-days-max": "最大 $1 {{PLURAL:$1|日間}}",
-       "prefs-watchlist-edits": "ウォッチリストの展開時の最大表示件数:",
+       "prefs-watchlist-edits": "ウォッチリストの最大表示件数:",
        "prefs-watchlist-edits-max": "最大数: 1000",
        "prefs-watchlist-token": "ウォッチリストのトークン:",
        "prefs-misc": "その他",
        "unwatchthispage": "ウォッチをやめる",
        "notanarticle": "記事ではありません",
        "notvisiblerev": "別の利用者による最終版は削除されました",
-       "watchlist-details": "ã\82¦ã\82©ã\83\83ã\83\81ã\83ªã\82¹ã\83\88ã\81«ã\81¯ {{PLURAL:$1|$1 ã\83\9aã\83¼ã\82¸}}ã\81\8cç\99»é\8c²ã\81\95ã\82\8cã\81¦ã\81\84ã\81¾ã\81\99 (ã\83\88ã\83¼ã\82¯ã\83\9aã\83¼ã\82¸ã\82\92é\99¤ã\81\8f)。",
+       "watchlist-details": "ã\82¦ã\82©ã\83\83ã\83\81ã\83ªã\82¹ã\83\88ã\81«ã\81¯ {{PLURAL:$1|$1 ã\83\9aã\83¼ã\82¸}}ã\81\8cç\99»é\8c²ã\81\95ã\82\8cã\81¦ã\81\84ã\81¾ã\81\99 (ã\83\88ã\83¼ã\82¯ã\83\9aã\83¼ã\82¸ã\82\82å\90«ã\82\80)。",
        "wlheader-enotif": "メール通知が有効になっています。",
        "wlheader-showupdated": "最終訪問以降に変更されたページは、<strong>太字</strong>で表示されます。",
        "wlnote": "$3 $4 までの{{PLURAL:$2|<strong>$2</strong>時間}}になされた{{PLURAL:$1|<strong>$1</strong>件の変更}}は以下の通りです。",
        "special-characters-title-endash": "en ダッシュ",
        "special-characters-title-emdash": "em ダッシュ",
        "special-characters-title-minus": "マイナス記号",
-       "mw-widgets-dateinput-no-date": "選択されたデータ無し",
+       "mw-widgets-dateinput-no-date": "日付未選択",
        "mw-widgets-mediasearch-input-placeholder": "メディアを検索",
        "mw-widgets-mediasearch-noresults": "見つかりませんでした。",
        "mw-widgets-titleinput-description-new-page": "ページは存在しません",
index fd55c88..17b1083 100644 (file)
        "emailtarget": "Lebokaké jeneng panganggo panampa",
        "emailusername": "Jeneng panganggo:",
        "emailusernamesubmit": "Kirim",
-       "email-legend": "KIrim layang-èl nyang panganggo  {{SITENAME}} liyané",
+       "email-legend": "Kirim layang-èl menyang panganggo {{SITENAME}} liyané",
        "emailfrom": "Saka:",
        "emailto": "Kanggo:",
        "emailsubject": "Prekara:",
        "protectedarticle": "ngreksa \"[[$1]]\"",
        "modifiedarticleprotection": "ngowahi tataran rereksané \"[[$1]]\"",
        "unprotectedarticle": "nyingkiraké panjagan saka \"[[$1]]\"",
-       "movedarticleprotection": "ngalih setèlan rereksan saka \"[[$2]]\" nyang \"[[$1]]\"",
+       "movedarticleprotection": "ngalih setèlan rereksan saka \"[[$2]]\" menyang \"[[$1]]\"",
        "protectedarticle-comment": "{{GENDER:$2|Ngreksa}} \"[[$1]]\"",
        "modifiedarticleprotection-comment": "{{GENDER:$2|Ngowahi tataran rereksan}} tumrap \"[[$1]]\"",
        "unprotectedarticle-comment": "{{GENDER:$2|Nyopot rereksan}} saka \"[[$1]]\"",
        "whatlinkshere": "Sing nggayut mréné",
        "whatlinkshere-title": "Kaca mawa pranala nggayut \"$1\"",
        "whatlinkshere-page": "Kaca:",
-       "linkshere": "Kaca-kaca ing ngisor iki nggayut nyang '''[[:$1]]''':",
+       "linkshere": "Kaca-kaca ing ngisor iki nggayut menyang <strong>[[:$1]]</strong>:",
        "nolinkshere": "Ora ana kaca sing nduwé pranala menyang '''[[:$1]]'''.",
        "nolinkshere-ns": " Ora ana kaca sing nduwé pranala menyang '''[[:$1]]''' ing bilik jeneng sing kapilih.",
        "isredirect": "kaca lih-lihan",
        "export-addns": "Tambah",
        "export-download": "Simpen dadi barkas",
        "export-templates": "Lebokaké cithakan",
-       "export-pagelinks": "Lebokaké kaca sing kagayut nyang jeroning:",
+       "export-pagelinks": "Lebokaké kaca sing kagayut ing sajeroning:",
        "export-manual": "Tambah kaca kanthi manual:",
        "allmessages": "Layang sistem",
        "allmessagesname": "Jeneng",
        "tooltip-ca-delete": "Busak kaca iki",
        "tooltip-ca-undelete": "Balèkna suntingan ing kaca iki sadurungé kaca iki dibusak",
        "tooltip-ca-move": "Lih kaca iki",
-       "tooltip-ca-watch": "Tambahaké kaca iki nyang pawawangan sapéyan",
+       "tooltip-ca-watch": "Tambahaké kaca iki menyang pawawangané panjenengan",
        "tooltip-ca-unwatch": "Busak kaca iki saka pawawanganing sampéyan",
        "tooltip-search": "Golèk ing {{SITENAME}}",
        "tooltip-search-go": "Jujug kaca asesirah persis mangkéné yèn ana",
        "tooltip-preview": "Pratuduhing owah-owahaning sampéyan. Anggoa cara iki sadurungé nyimpen.",
        "tooltip-diff": "Tuduhaké owah-owahan endi sing sampéyan gawé tumrap tulisan iki",
        "tooltip-compareselectedversions": "Delengen prabédan antara rong vèrsi kaca iki sing dipilih.",
-       "tooltip-watch": "Wuwuh kaca iki nyang pawawanganing sampéyan",
+       "tooltip-watch": "Wuwuh kaca iki menyang pawawangané panjenengan",
        "tooltip-watchlistedit-normal-submit": "Busak sesirah",
        "tooltip-watchlistedit-raw-submit": "Anyari daptar pangawasan",
        "tooltip-recreate": "Gawéa kaca iki manèh senadyan tau dibusak",
        "confirm-unwatch-button": "Oké",
        "confirm-unwatch-top": "Singkiraké kaca iki saka daptar pangawasan Sampéyan?",
        "confirm-rollback-button": "YA",
-       "confirm-rollback-top": "Pulihaké besutan nyang kaca iki?",
+       "confirm-rollback-top": "Pulihaké besutan menyang kaca iki?",
        "quotation-marks": "\"$1\"",
        "imgmultipageprev": "← kaca sadurungé",
        "imgmultipagenext": "kaca sabanjuré →",
        "pagelang-reason": "Alesan",
        "pagelang-submit": "Kirim",
        "pagelang-nonexistent-page": "Kaca $1 ora ana.",
-       "pagelang-unchanged-language": "Kaca $1 wis disetèl nyang basa $2.",
+       "pagelang-unchanged-language": "Kaca $1 wis disetèl menyang basa $2.",
        "mediastatistics-table-mimetype": "Jinis MIME",
        "mediastatistics-table-extensions": "Èkstènsi sing mungkin",
        "mediastatistics-table-count": "Cacah barkas",
index 75d63f9..f4e291f 100644 (file)
        "category-empty": "<em>Taggayt agi ur tesɛa asebtar, adu-taggayt neɣ afaylu agetmedia.</em>",
        "hidden-categories": "{{PLURAL:$1|Taggayt yeffren|Taggayin yeffren}}",
        "hidden-category-category": "Taggayin yeffren",
-       "category-subcat-count": "Taggayt agi tesɛa {{PLURAL:$2|adu-taggayt|$2 adu-taggayin, ɣef ayed {{PLURAL:$1|t-agi|t-igi $1}}}} ddaw agi.",
-       "category-subcat-count-limited": "Taggayt agi tesɛa {{PLURAL:$1|adu-taggayt agi|tid $1 adu-taggayin agi}} ddaw-agi.",
-       "category-article-count": "Taggayt agi tesɛa {{PLURAL:$2|asebter agi|$2 isebtaren, ɣef ayed {{PLURAL:$1|t-agi|t-igi $1}} ddaw-agi}}.",
+       "category-subcat-count": "Taggayt-agi {{PLURAL:$2|0=ur tegbir ula d yiwet n taggayt tasnawt|1=tegber kan taggayt tasnawant ddaw-a|tegber $2 n taggayin tisnawanin, gar-asent {{PLURAL:$1|0=ula d yiwet|1=tin|tigad $1}} ddaw-a}}.",
+       "category-subcat-count-limited": "Taggayt-agi tegber {{PLURAL:$1|n taggayt tasnawant|$1 n taggayin tisnawanin}} ddaw-a.",
+       "category-article-count": "Taggayt-agi{{PLURAL:$2|0=ur tegbur ula d yiwen n usebtert|1=tegber kan yiwen n usebterddaw-a|tegber $2 n isebtar, gar-asen {{PLURAL:$1|0=ula d yiwen|1=tin| $1}} n ddaw-a}}.",
        "category-article-count-limited": "{{PLURAL:$1|Asebter agi yella|$1 isebtar agi llan}} deg taggayt agi.",
        "category-file-count": "Taggayt agi tesɛa {{PLURAL:$2|afaylu agi|$2 ifuyla, ɣef ayed {{PLURAL:$1|t-agi|t-igi $1}} ddaw-agi}}.",
        "category-file-count-limited": "{{PLURAL:$1|Afaylu agi yella|$1 ifuyla agi llan}} deg taggayt agi.",
        "viewsource": "Ẓer aɣbalu",
        "viewsource-title": "Ẓeṛ aɣbalu n $1",
        "actionthrottled": "Tigawt tesɛa talast",
-       "actionthrottledtext": "Iwakken an ewwet mgal tira yerkan (SPAM), tigawt agi tesɛa talast n amḍan n tikwalt deg akud awezzlan. talast agi t-ɛedda.\nƐred tikkelt nniḍen deg kra n dqiqa.",
+       "actionthrottledtext": "Akken ad nsiḥbiber mgal tuzna n ispamen, aseqdec n tigawt-agi tesɛa talast n umḍan n tikalt n wakud wezzilen kan ihi tɛeddaḍ talast.\nƐred tikelt-nniḍen di kra n tisdatin.",
        "protectedpagetext": "Asebter-agi yetwaḥrez i uqareɛ n ubeddel neɣ tigawin nniḍen.",
        "viewsourcetext": "Tzemreḍ ad twaliḍ u txedmeḍ alsaru n uɣbalu n usebter-agi:",
        "viewyourtext": "Tzemṛeḍ ad ẓṛeḍ dɣa ad nɣeleḍ agbur n \"ibeddlen inek/inem\" deg usebter agi :",
        "protectedinterface": "Asebter-agi d amsekker axaṭer yettuseqdac i weḍris n software.",
-       "editinginterface": "'''Aɣtal:''' Aqla-k tettbeddileḍ asebter i yettuseqdac i weḍris n software. Tagmett n software i tt-ẓren yimseqdacen wiyaḍ ad tbeddel akk d ibeddlen inek.",
-       "cascadeprotected": "Asebter-agi yegdel axaṭer yettusekcem deg {{PLURAL:$1|asebter yegdelen agi|isebtar yegdelen agi}} s Taxtiṛit « amesten s uceṛcuṛ » isermeden :\n$2",
+       "editinginterface": "<strong>Ɣuṛ-k:</strong> Aqla-k tettbeddileḍ asebter yettuseqdacen i tmerna n uḍris n ugrudem n useɣẓan. \nIbeddilen ɣef usebter-agi ad ḥazen udem n ugrudem n useqdac i yiseqdacen-nniḍen n uwiki.",
+       "cascadeprotected": "Asebter-agi yettwammesten mgal abeddel acku yedda deh {{PLURAL:$1|usebter d-iteddun yettwammestnen|isebtar-agi d-itedduun yettwammestnen}} s usefran \"ammesten s udabdar\" urmid:\n$2",
        "namespaceprotected": "Ur tesɛiḍ ara turagt iwakken ad beddeleḍ isebtar n tallunt n isemawen \"'''$1'''\".",
        "customcssprotected": "Ur tesɛiḍ ara turagt iwakken ad beddeleḍ asebter agi n CSS, acku tesɛa iɣewwaren n yiwen useqdac nniḍen.",
        "customjsprotected": "Ur tesɛiḍ ara turagt iwakken ad beddeleḍ asebter agi n Javascript, acku tesɛa iɣewwaren n yiwen useqdac nniḍen.",
        "createacct-reason-help": "Izen yettwaseknen deg uɣmis n tmerna n umiḍan",
        "createacct-submit": "Rnu amiḍan-ik(m)",
        "createacct-another-submit": "Rnu amiḍan",
+       "createacct-continue-submit": "Kemmel timerna n umiḍan",
+       "createacct-another-continue-submit": "Kemmel timerna n umiḍan",
        "createacct-benefit-heading": "{{SITENAME}} yetwexdem sɣur medden am kečč/kem.",
        "createacct-benefit-body1": "{{PLURAL:$1|abeddel|ibeddilen}}",
        "createacct-benefit-body2": "{{PLURAL:$1|asebter|isebtar}}",
        "createacct-another-realname-tip": "* Isem n ṣṣeḥ d-axeṭran.\nMa teɛzemeḍ a t-tefkeḍ, ad yettuseqdac iwakken ad snen medden anwa yuran tikkin inek.",
        "pt-login": "Qqen",
        "pt-login-button": "Qqen",
+       "pt-login-continue-button": "Kemmel tuqqna",
        "pt-createaccount": "Rnu amiḍan",
        "pt-userlogout": "Ffeɣ",
        "php-mail-error-unknown": "anezri warisem deg tawuri mail() n PHP",
        "resetpass_submit": "Eg awal n tbaḍnit u kcem",
        "changepassword-success": "Awal n uɛaddi yettubeddel s lerbaḥ !",
        "changepassword-throttled": "Tɛerdeḍ ad qqeneḍ aṭas tiqwal deg dqiqat agi iɛddan.\nIlaq ad rǧuḍ $1 uqbel ad ɛerdeḍ tikkelt nniḍen.",
+       "botpasswords": "Iwalen uffiren n iṛubuten",
+       "botpasswords-disabled": "Awalen uffiren n iṛubuten nsan.",
+       "botpasswords-existing": "Awalen uffiren n uṛubuten yellan",
+       "botpasswords-createnew": "Rnu awal uffir n iṛubuten amaynut",
+       "botpasswords-editexisting": "Ẓreg awal uffir n iṛubuten yellan",
        "botpasswords-label-appid": "Isem n uṛubut:",
        "botpasswords-label-create": "Rnu",
        "botpasswords-label-update": "Leqqem",
        "botpasswords-label-grants": "Izerfan yettwasnasen:",
        "botpasswords-label-grants-column": "Ttunefken izerfan",
        "botpasswords-bad-appid": "Isem n uṛubut \"$1\" mačči d ameɣtu.",
+       "botpasswords-created-title": "Awal uffir n iṛubuten yettwarna",
+       "botpasswords-updated-title": "Awal uffir n iṛbuten ibeddel",
+       "botpasswords-deleted-title": "Awal uffir n iṛubuten yettwakkes",
+       "botpasswords-deleted-body": "Awal uffir n uṛubut \"$1\" n useqdac \"$2\" yettwakkes.",
+       "botpasswords-no-provider": "Asaǧǧaw n tɣimit n wawal uffir n iṛubuten ulac-it.",
        "resetpass_forbidden": "Ur zemreḍ ara ad beddeleḍ awalen n uɛaddi",
        "resetpass-no-info": "Ilaq ad qqeneḍ iwakken ad ẓṛeḍ asebter agi.",
        "resetpass-submit-loggedin": "Beddel awal n uɛaddi",
        "editundo": "ssefsu",
        "diff-empty": "(Ulac amgerrad)",
        "diff-multi-sameuser": "({{PLURAL:$1|Yiwen n uceggir askudan sɣuṛ aseqdac iman-is  ur d-yettwasken ara|$1 N iceggiren iskudanen sɣuṛ aseqdac iman-is ur d-ttwaseknen ara}})",
+       "diff-multi-otherusers": "({{PLURAL:$1|Yiwen n uceggir agrawan|$1 n iceggiren igrawanen}} sɣur {{PLURAL:$2|yiwen n useqdac-nniḍen|$2 n iseqdacen}} ur {{PLURAL:$1|d-yettwasken ara|d-ttwaseknen ara}})",
        "diff-multi-manyusers": "({{PLURAL:$1|Yiwen lqem agrawan|$1 ileqman igrawanen}} af {{PLURAL:$2|aseqdac|$2 iseqdacen}} {{PLURAL:$1|yeffer|ffren}})",
        "difference-missing-revision": "{{PLURAL:$1|Yiwet tacaggart|$1 ticaggartin}} n tameẓla agi ($1) {{PLURAL:$2|ur tella ara (ulac)|ur llant ara (ulac)}}.\n\nAcku azday n tameẓla, ɣef wayen tsennedeḍ, d-aqbur. Asebter yemḥa.\nTzemreḍ ad affeḍ tilɣa deg [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} uɣmis n isebtar yekksen].",
        "searchresults": "Igmad n unadi",
        "notextmatches": "ulac ayen yecban azwel n usebter",
        "prevn": "{{PLURAL:$1|$1}} ssabeq",
        "nextn": "{{PLURAL:$1|$1}} ameḍfir",
+       "prev-page": "Asebter yezrin",
+       "next-page": "Asebter d-iteddun",
        "prevn-title": "$1 {{PLURAL:$1|agmud n uqbel|igmad n uqbel}}",
        "nextn-title": "$1 {{PLURAL:$1|agmud n sakin|igmad n sakin}}",
        "shown-title": "Beqqeḍ $1 {{PLURAL:$1|agmud|igmad}} s usebter",
        "search-result-category-size": "$1 {{PLURAL:$1|amseqdac|imseqdacen}} $2 ({{PLURAL:$2|adu-taggayt|adu-tiggayin}}, $3 {{PLURAL:$3|afaylu|ifuyla}})",
        "search-redirect": "(awelleh seg $1)",
        "search-section": "(tigezmi $1)",
+       "search-category": "(taggayt $1)",
        "search-file-match": "(yzega i ugbur n ufaylu)",
        "search-suggest": "D awal $1 i tnadiḍ ?",
-       "search-interwiki-caption": "Isenfaren atmaten",
-       "search-interwiki-default": "Igemmaḍ ɣef $1 :",
+       "search-rewritten": "Igmaḍ yettwaseknen i $1. Anadi n $2 deg umḍiq-is.",
+       "search-interwiki-caption": "Igmaḍ n isenfaṛen atmaten",
+       "search-interwiki-default": "Igmaḍ si $1:",
        "search-interwiki-more": "(ugar)",
+       "search-interwiki-more-results": "ugar n igmaḍ",
        "search-relatedarticle": "Amassaɣ",
        "searchrelated": "ineqqes",
        "searchall": "akk",
        "powersearch-togglelabel": "Ɛellem :",
        "powersearch-toggleall": "Akkw",
        "powersearch-togglenone": "Ulac",
+       "powersearch-remember": "Cfu ɣef ufran n yinadiyen d-iteddun",
        "search-external": "Anadi yeffɣen",
        "searchdisabled": "Anadi deg {{SITENAME}} yettwakkes. Tzemreḍ ad tnadiḍ s Google. Meɛna ur tettuḍ ara, tasmult n google taqdimt.",
        "search-error": "Tella tuccḍa deg unadi n : $1",
+       "search-warning": "Alɣu yettwammel degu unadi n: $1",
        "preferences": "Ismenyifen",
        "mypreferences": "Ismenyifen",
        "prefs-edits": "Amḍan n ibeddlilen :",
        "prefs-personal": "Profile n wemseqdac",
        "prefs-rc": "Ibeddilen imaynuten",
        "prefs-watchlist": "Tabdart n uḍfaṛ",
+       "prefs-editwatchlist": "Ẓreg tabdart n uḍfaṛ",
+       "prefs-editwatchlist-label": "Ẓreg inekcam ɣef tedbart n uḍfaṛ:",
+       "prefs-editwatchlist-edit": "Wali sakin kkes izwal n tebdart-ik n uḍfaṛ",
+       "prefs-editwatchlist-raw": "Ẓreg tabdart n uḍfaṛ deg uskar arewway",
+       "prefs-editwatchlist-clear": "Sfeḍ tabdart-ik n uḍfaṛ",
        "prefs-watchlist-days": "Amḍan n ussan i ubeqqeḍ deg umuɣ n uɛassi :",
        "prefs-watchlist-days-max": "Afellay $1 {{PLURAL:$1|ass|ussan}}",
        "prefs-watchlist-edits": "Amḍan afellay n ubeddel ara d-ibabnen deg tebdart n uḍfaṛ:",
        "prefs-watchlist-token": "Tiddest  umuɣ n uɛassi :",
        "prefs-misc": "Ismenyifien-nniḍen",
        "prefs-resetpass": "Beddel awal n uɛaddi",
-       "prefs-changeemail": "Beddel tansa n e-mail",
+       "prefs-changeemail": "Beddel neɣ kkes tansan n yimayl",
        "prefs-setemail": "Sbadu yiwet tansa e-mail",
        "prefs-email": "Tixtiṛiyin n tira",
        "prefs-rendering": "Tummant",
        "restoreprefs": "Err akkw iɣewwaren s lexṣas (deg akkw tigezmiwin)",
        "prefs-editing": "Abedddil",
        "searchresultshead": "Anadi",
-       "stub-threshold": "Talast timinegt i <a href=\"#\" class=\"stub\">izdayen ɣer ibegzan</a> (itamḍanen) :",
+       "stub-threshold": "Talast i umasal n iseɣwan n isumar ($1) :",
+       "stub-threshold-sample-link": "amedya",
        "stub-threshold-disabled": "Yensa",
        "recentchangesdays": "Amḍan n ussan an beqqeḍ deg ibeddilen ineggura.",
        "recentchangesdays-max": "Afellay $1 {{PLURAL:$1|ass|ussan}}",
        "prefs-help-recentchangescount": "Wagi yesɛa deg-es ibeddilen ineggura, isebtar n umezruy d iɣmisen.",
        "prefs-help-watchlist-token2": "Hattan tasarut tufurt n usuddem Web n umuɣ inek/inem n uḍfar.\nAkkw amḍan yesɛan tasarut agi, ad yezmer ad i ɣer umuɣ inek/inem n uḍfar, ur d-sselɣu ara tasarut agi ihi.\n[[Special:ResetTokens|Nqer d-agi ma tebɣiḍ ad wennezeḍ tasarut agi]].",
        "savedprefs": "Ismenyifen-ik ttwaskelsen.",
+       "savedrights": "Izerfan n useqdac n {{GENDER:$1|$1}}  ttwaskelsen.",
        "timezonelegend": "Iẓḍi n ukud :",
        "localtime": "Asrag adigan :",
        "timezoneuseserverdefault": "Seqdec azal s lexṣas n wiki ($1)",
        "youremail": "E-mail *:",
        "username": "{{GENDER:$1|Isem n umseqdac|Isem n tamseqdact}} :",
        "prefs-memberingroups": "{{GENDER:$2|Aεeggal|Taɛggalt}} n {{PLURAL:$1|ugraw|igrawen}} :",
+       "group-membership-link-with-expiry": "$1 (arams d $2)",
        "prefs-registration": "Azmez n tiggezt :",
        "yourrealname": "Isem n ṣṣeḥ *:",
        "yourlanguage": "Tutlayt:",
        "prefs-diffs": "Timeẓliwin",
        "prefs-help-prefershttps": "Asmenyif agi, ad yelḥu ar tuqqna ay d-yetteddun.",
        "prefs-tabs-navigation-hint": "Taxbalut : Tzemreḍ ad seqdeceḍ tineccabin n uzelmaḍ d uyeffus iwakken ad ssileleḍ gar iccaren.",
-       "userrights": "Laɛej iserfan n wemseqdac",
-       "userrights-lookup-user": "Laɛej iderman n yimseqdacen",
+       "userrights": "Izerfan n useqdac",
+       "userrights-lookup-user": "Fren aseqdac",
        "userrights-user-editname": "Ssekcem isem n wemseqdac:",
-       "editusergroup": "Beddel iderman n yimseqdacen",
-       "editinguser": "Abeddel n izerfan n {{GENDER:$1|useqdac|taseqdact}} '''[[User:$1|$1]]''' $2",
-       "userrights-editusergroup": "Beddel iderman n wemseqdac",
-       "saveusergroups": "Smekti iderman n yimseqdacen",
+       "editusergroup": "Sali-d igrawen n iseqdacen",
+       "editinguser": "Abeddel n izerfan n {{GENDER:$1|useqdac|tseqdact}} <strong>[[User:$1|$1]]</strong> $2",
+       "viewinguserrights": "Askan n izefan iseqdacen n {{GENDER:$1|useqdac|tseqdact}} <strong>[[User:$1|$1]]</strong> $2",
+       "userrights-editusergroup": "Snifel izerfan n {{GENDER:$1|useqdsac|tseqdact}}",
+       "userrights-viewusergroup": "Sken igrawen n {{GENDER:$1|useqdac|tseqdact}}",
+       "saveusergroups": "Sekles igrawen n {{GENDER:$1|useqdac|tseqdact}}",
        "userrights-groupsmember": "Amaslad deg:",
        "userrights-groupsmember-auto": "Aεeggal udrig n :",
        "userrights-groups-help": "Tzemreḍ ad beddeleḍ igrawen anda yella aseqdac agi :\n* Taxxamt i tekkin : aseqdac yella deg ugraw agi.\n* Taxxamt ur tekkin ara : aseqdac ur yella ara deg ugraw agi\n* Titrit (*) : ur tzemreḍ ara ad ekkeseḍ agraw agi sakin i tid ernuḍ, naɣ bis-bersa.",
        "userrights-nodatabase": "Taffa n isefka « $1 » ulac itt naɣ mačči d tadigant.",
        "userrights-changeable-col": "Igrawen i tzemreḍ ad beddeleḍ",
        "userrights-unchangeable-col": "Igrawen ur tzemreḍ ara ad beddeleḍ",
+       "userrights-expiry-current": "Ad ifat di $1",
+       "userrights-expiry-none": "Ur yettfat ara",
+       "userrights-expiry": "Ad ifat di:",
+       "userrights-expiry-existing": "Azemz n ufati yellan: $3,  $2",
+       "userrights-expiry-othertime": "Akud-nniḍen:",
+       "userrights-expiry-options": "1 ass:1 day,1 amalas:1 week,1 aggur:1 month,3 agguren:3 montghs,6 agguren:6 month,1 aseggas:1 year",
+       "userrights-invalid-expiry": "Azemz n tagara i ugraw \"$1\" mačči d ameɣtu.",
+       "userrights-expiry-in-past": "Azemz n tagara i ugraw \"$1\" yezri.",
        "userrights-conflict": "Ccwal n ubeddel n izerfan n umseqdac ! Ilaq ad ɛzemeḍ tikelt nniḍen dɣa ad sergegeḍ ibeddilen.",
        "group": "Adrum:",
        "group-user": "Iseqdacen",
        "grouppage-bot": "{{ns:project}}:Iṛubuten",
        "grouppage-sysop": "{{ns:project}}:Inedbalen",
        "grouppage-bureaucrat": "{{ns:project}}:Imsfelluran",
-       "grouppage-suppress": "{{ns:project}}:Inemdayen",
+       "grouppage-suppress": "{{ns:project}}:Suppress",
        "right-read": "Ɣeṛ isebtar",
        "right-edit": "Beddel isebtar",
        "right-createpage": "Snulfud isebtar (mačči d-isebtar n umeslay)",
        "right-createtalk": "Snulfud isebtar n umeslay",
        "right-createaccount": "Snulfud imiḍanen n iseqdacen",
+       "right-autocreateaccount": "Tuqqna tawurmant s umiḍan n useqdac azɣaray",
        "right-minoredit": "Ffer ibeddilen yellan d-imectuḥen",
        "right-move": "Beddel isem n isebtar",
        "right-move-subpages": "Beddel isem n isebtar d adu-isebtar nsen",
        "right-move-rootuserpages": "Beddel isem n usebtar amenzawi n useqdac",
+       "right-move-categorypages": "Ugar n isebtar n taggayin",
        "right-movefile": "Beddel isem n ifuyla",
        "right-suppressredirect": "Ur snulfu ara asemmimeḍ seg azwel amezwaru s ubeddel n isem usebter",
        "right-upload": "Azen ifuyla",
        "right-deletedtext": "Ẓeṛ aḍris yemḥan d timeẓliwin gar ileqman yemḥan",
        "right-browsearchive": "Nadi ɣef isebtar yettumḥan",
        "right-undelete": "Erred asebter yemḥan",
-       "right-suppressrevision": "Ssekyed dɣa erred ileqman yefren i inedbalen",
+       "right-suppressrevision": "Sken, ffer, werri iceggiren n isebtar n yal aseqdac",
        "right-suppressionlog": "Ẓeṛ iɣmisen usligen",
        "right-block": "Kyef deg tira iseqdacen nniḍen",
        "right-blockemail": "Sḍiqqef aceggaɛ n tira (e-mail) i yiwen useqdac",
        "rcfilters-invalid-filter": "Yir imzizdig",
        "rcfilters-filterlist-title": "Imzizdigen",
        "rcfilters-filterlist-whatsthis": "Amek iteddu?",
+       "rcfilters-filterlist-feedbacklink": "Ini-yaɣ-d tiktiwin-ik ɣef ifecka n uzizdeg (imaynuten)",
        "rcfilters-highlightbutton-title": "Sebṛureq igmaḍ",
        "rcfilters-highlightmenu-title": "Fren ini",
        "rcfilters-highlightmenu-help": "Fren ini n usebṛuṛeq n tmeẓlit-agi",
        "boteditletter": "b",
        "number_of_watching_users_pageview": "[$1 {{PLURAL:$1|aɛessas|iɛessasen}}]",
        "rc_categories": "Ḥedded i taggayin (ferreq s \"|\")",
-       "rc_categories_any": "Ulayɣer",
+       "rc_categories_any": "Yiwet seg tid yettwafernen",
        "rc-change-size-new": "$1 {{PLURAL:$1|atamḍan|itamḍanen}} seld abeddel",
        "newsectionsummary": "/* $1 */ tigezmi tamaynut",
        "rc-enhanced-expand": "Ẓeṛ ttfaṣil",
        "uploaderror": "Agul deg usekcam",
        "upload-recreate-warning": "'''Ɣur-wet : Afaylu s isem agi yetwekkes naɣ yetembiwel.'''\nAɣmis n tukksiwin d win n ittembiwilen n usebter agi beqqeḍen d-agi i tilɣa :",
        "uploadtext": "Sseqdec tiferkit agi iwakken ad ktereḍ ifuyla ɣef uqeddac.\nIwakken ad ẓṛeḍ naɣ ad nadiḍ tugniwin i ktren uqbel, ẓeṛ [[Special:FileList|umuɣ n tugniwin]]. Taktert tella daɣen deg [[Special:Log/upload|aɣmis n taktert n ifuyla]], dɣa inuzal deg [[Special:Log/delete|aɣmis n inuzal]].\n\nAkken ad tessekcmeḍ afaylu deg usebter, seqdec azay am wagi\n* '''<code><nowiki>[[</nowiki>{{ns:file}}<nowiki>:afaylu.jpg]]</nowiki></code>''', iwakken ad beqqeḍeḍ afaylu deg tabadut tačurant (lukan d-tugna) ;\n* '''<code><nowiki>[[</nowiki>{{ns:file}}<nowiki>:afaylu.png|200px|thumb|left|aḍris n uglam]]</nowiki></code>''' i useqdac n uqmamaḍ n 200px s tehri deg tanaka af uzelmeḍ s « aḍris n uglam » am aglam ;\n* '''<code><nowiki>[[</nowiki>{{ns:media}}<nowiki>:afaylu.ogg]]</nowiki></code>''' iwakken ad qqeneḍ ɣer ufaylu war ubeqqeḍ.",
-       "upload-permitted": "Amasal n ifuyla i siregen : $1.",
-       "upload-preferred": "Amasal n ifuyla i smenyifen : $1.",
-       "upload-prohibited": "Amasal n ifuyla igdelen : $1.",
+       "upload-permitted": "{{PLURAL:$2|Amasal|Imasalen}} n ifuyla {{PLURAL:$2|yettwasireg|ttwasirgen}} : $1.",
+       "upload-preferred": "{{PLURAL:$2|Amasal|Imasalen}} n ifuyla {{PLURAL:$2|anurif|inurifen}} : $1.",
+       "upload-prohibited": "‎{{PLURAL:$2|Amasal|Imasalen}} n ifuyla {{PLURAL:$2|ugdil|ugdilen}} : $1.",
        "uploadlogpage": "Amezruy n usekcam",
        "uploadlogpagetext": "Hat-an umuɣ n ifuyla ineggura i kteren ɣef uqeddac.\nẒeṛ [[Special:NewFiles|tihawt n tugniwin timaynutin]].",
        "filename": "Isem n ufaylu",
        "sp-contributions-search": "Nadi i tikkin",
        "sp-contributions-username": "Tansa IP neɣ isem n wemseqdac:",
        "sp-contributions-toponly": "Sekned kan imagraden i beddeleɣ nekk d-aneggaru",
+       "sp-contributions-newonly": "Seken kan tiẓrigin n tmerna n isebtar.",
        "sp-contributions-submit": "Nadi",
        "whatlinkshere": "Ayen i d-yettawi ɣer da",
        "whatlinkshere-title": "Isebtaren i sɛan azday ɣer « $1 »",
        "thumbnail_gd-library": "Tawila tagermazt n tamkarḍit GD : ulac tasɣent $1",
        "thumbnail_image-missing": "Afaylu agi ulac-it : $1",
        "import": "Ssekcem isebtar",
-       "importinterwiki": "Assekcem n transwiki",
+       "importinterwiki": "kter seg uwiki-nniḍen",
        "import-interwiki-text": "Fren yiwen wiki d yiwen azwel n usebtar ad ketreḍ.\nIzemzen n ileqman d isemawen n ittekkiyen ad qqimen.\nAkkw tigawin n taktert ager-wiki ad illint deg [[Special:Log/import|umezruy n tiketrin]].",
        "import-interwiki-history": "Xdem alsaru n akk tisiwal umezruy n usebter-agi",
        "import-interwiki-templates": "Sekcem akkw talɣiwin",
        "scarytranscludetoolong": "[URL agi uffay aṭas]",
        "deletedwhileediting": "Aɣtal: Asebter-agi yettumḥa qbel ad tebdiḍ a t-tbeddleḍ!",
        "confirmrecreate": "Aseqdac [[User:$1|$1]] ([[User talk:$1|Asqerdec]]) yekkes asebter-agi makken tebdiḍ abeddel deg-s, ɣef sebba n :\n: <em>$2</em>\nMa ulac aɣilif, sentem d akken tebɣiḍ ad talseḍ timerna n usebter-agi.",
-       "confirmrecreate-noreason": "Amseqdac [[User:$1|$1]] ([[User talk:$1|Meslay]]) yemḥu asebter-agi wannag tebedduḍ att beddeleḍ. Ilaq ad sergegeḍ tebɣiḍ ad snulfuḍ tikkelt nniḍen asebtar agi.",
+       "confirmrecreate-noreason": "{{GENDER:$1|Aseqdac|Taseqdact}} [[User:$1|$1]] ([[User talk:$1|Asqerdec]]) {{GENDER:$1|yekkes|tekkes}} asebter-agi, makken tebdiḍ tettbeddileḍ-t. Sentem ma ulac aɣilif me tebɣiḍ ad talsseḍ timerna n usebter-agi.",
        "recreate": "Ɛiwed xleq",
        "confirm_purge_button": "Seɣbel",
        "confirm-purge-top": "Mḥu lkac n usebter-agi?",
        "watchlistedit-raw-done": "Umuɣ n uɛessi inek yettubeddel.",
        "watchlistedit-raw-added": "{{PLURAL:$1|1 wezwel |$1 yizwal}} nnernan:",
        "watchlistedit-raw-removed": "{{PLURAL:$1|1 wezwel yettwakkes|$1 yizwal ttwakksen}}:",
+       "watchlisttools-clear": "Sfeḍ tabdart n uḍfaṛ",
        "watchlisttools-view": "Umuɣ n uɛessi",
        "watchlisttools-edit": "Ẓer u beddel umuɣ n uɛessi",
        "watchlisttools-raw": "Beddel umuɣ n uɛessi (raw)",
        "compare-revision-not-exists": "Lqem id efkiḍ ulac-it.",
        "dberr-problems": "Ssurfet-aɣ ! Asmel agi yemliled ilɣiten itikniten.",
        "dberr-again": "Ɛreḍ ad arǧuḍ kra n tisdidin dɣa sismeḍ.",
-       "dberr-info": "(Ulamek an qqen ar uqeddac n taffa n isefka : $1)",
+       "dberr-info": "(Ur izmir ara ad yeqqen ar taffa n isefka: $1)",
        "dberr-info-hidden": "(Ur izmir ara ad yeqqen ara taffa n isefka)",
        "dberr-usegoogle": "Tzemreḍ ad ɛreḍeḍ anadi s Google deg ukud agi.",
        "dberr-outofdate": "Ani i imataren nsen n ugbur nneɣ zemren ad yetwagaren",
        "special-characters-group-greekextended": "Tagrigit taɣezfant",
        "special-characters-group-cyrillic": "Tasirilikt",
        "special-characters-group-arabic": "Taɛṛabt",
+       "randomrootpage": "Asebter aẓaṛ agacuran",
        "log-action-filter-upload-upload": "Asali amaynut",
        "authprovider-confirmlink-ok-help": "Kemmel deffir n uskan n yiznan n usdukkel ur yeddin ara."
 }
index b4cd8b7..3a29feb 100644 (file)
        "rcfilters-empty-filter": "활성화된 필터가 없습니다. 모든 기여가 표시됩니다.",
        "rcfilters-filterlist-title": "필터",
        "rcfilters-filterlist-whatsthis": "이것들이 어떻게 동작합니까?",
-       "rcfilters-filterlist-feedbacklink": "ì\83\88ë¡\9cì\9a´ (ë² í\83\80) í\95\84í\84°에 대한 의견을 주세요",
+       "rcfilters-filterlist-feedbacklink": "ì\9d´ (ì\83\88ë¡\9cì\9a´) í\95\84í\84° ë\8f\84구에 대한 의견을 주세요",
        "rcfilters-highlightbutton-title": "결과 강조",
        "rcfilters-highlightmenu-title": "색 선택",
        "rcfilters-highlightmenu-help": "이 속성을 강조할 색을 선택하십시오",
        "rcfilters-noresults-conflict": "검색 조건이 충돌하기 때문에 결과를 찾을 수 없습니다",
        "rcfilters-state-message-subset": "필터의 결과가 다음의 범위가 더 넓은 {{PLURAL:$2|필터}}의 결과에 포함되기 때문에 이 필터는 효력이 없습니다 (구별을 위해 강조해 보십시오): $1",
        "rcfilters-state-message-fullcoverage": "이 그룹의 모든 필터를 선택하는 것은 아무 것도 선택하지 않는 것과 동일하므로 이 필터는 효력이 없습니다. 그룹은 다음을 포함합니다: $1",
-       "rcfilters-filtergroup-authorship": "원작자 기여",
+       "rcfilters-filtergroup-authorship": "기여의 저자",
        "rcfilters-filter-editsbyself-label": "당신의 변경사항",
        "rcfilters-filter-editsbyself-description": "당신의 기여.",
        "rcfilters-filter-editsbyother-label": "다른 사용자의 변경사항",
        "rcfilters-liveupdates-button": "실시간 업데이트",
        "rcfilters-liveupdates-button-title-on": "실시간 업데이트 끄기",
        "rcfilters-liveupdates-button-title-off": "새로운 변경사항이 발생하면 표시",
-       "rcfilters-watchlist-markSeen-button": "모든 변경사항을 본 것으로 표시",
+       "rcfilters-watchlist-markseen-button": "모든 변경사항을 본 것으로 표시",
+       "rcfilters-watchlist-edit-watchlist-button": "내 주시문서 목록 편집",
+       "rcfilters-watchlist-showupdated": "변경이 발생한 이후로 방문한 적이 없는 문서의 변경사항은 <strong>굵게</strong> 표시됩니다.",
        "rcnotefrom": "아래는 <strong>$3, $4</strong>부터 시작하는 {{PLURAL:$5|바뀜이 있습니다}}. (최대 <strong>$1</strong>개가 표시됨)",
        "rclistfromreset": "날짜 선택 초기화",
        "rclistfrom": "$3 $2부터 시작하는 새로 바뀐 문서 보기",
        "apisandbox-sending-request": "API 요청을 보내는 중...",
        "apisandbox-loading-results": "API 결과를 받는 중...",
        "apisandbox-results-error": "API 질의 응답을 불러오는 도중 오류 발생: $1.",
-       "apisandbox-results-login-suppressed": "í\95´ë\8b¹ ì\9a\94ì²­ì\9d\80 ë¡\9cê·¸ì\9d¸ì\9d\84 í\95\98ì§\80 ì\95\8aì\9d\80 ì\82¬ì\9a©ì\9e\90ê°\80 ë\8f\99ì\9d¼ ì¶\9cì²\98 ë³´ì\95\88ì\9d\84 ì\9a°í\9a\8cí\95\98기 ì\9c\84í\95´ ì§\84í\96\89ë\90\98ì\97\88ì\8aµë\8b\88ë\8b¤. API ì\83\8cë\93\9cë°\95ì\8a¤ì\9d\98 ì\9e\90ë\8f\99 í\86 í\81° ì¡°ì \95ì\9d´ í\95´ë\8b¹ ì\9a\94ì²­ì\97\90 ë\8c\80í\95´ ì \9cë\8c\80ë¡\9c ì\9e\91ë\8f\99í\95\98ì§\80 ì\95\8aë\8a\94ì§\80 í\99\95ì\9d¸í\95\98ê³ , 수동으로 채워주세요.",
+       "apisandbox-results-login-suppressed": "í\95´ë\8b¹ ì\9a\94ì²­ì\9d\80 ë¸\8cë\9d¼ì\9a°ì \80ì\9d\98 ë\8f\99ì\9d¼ ì¶\9cì²\98 ë³´ì\95\88ì\9d\84 ì\9a°í\9a\8cí\95\98기 ì\9c\84í\95´ ì\82¬ì\9a©ë\90  ì\88\98 ì\9e\88기 ë\95\8c문ì\97\90 ë¡\9cê·¸ì\95\84ì\9b\83ë\90\9c ì\82¬ì\9a©ì\9e\90 ì\9e\90격ì\9c¼ë¡\9c ì²\98리ë\90\98ì\97\88ì\8aµë\8b\88ë\8b¤. API ì\83\8cë\93\9cë°\95ì\8a¤ì\9d\98 ì\9e\90ë\8f\99 í\86 í\81° ì¡°ì \95ì\9d´ í\95´ë\8b¹ ì\9a\94ì²­ì\97\90 ë\8c\80í\95´ ì \9cë\8c\80ë¡\9c ì\9e\91ë\8f\99í\95\98ì§\80 ì\95\8aì\9c¼ë\8b\88, 수동으로 채워주세요.",
        "apisandbox-request-selectformat-label": "요청한 데이터를 보여주기:",
        "apisandbox-request-format-url-label": "URL 쿼리 문자열",
        "apisandbox-request-url-label": "요청 URL:",
        "unwatchthispage": "주시 해제하기",
        "notanarticle": "문서가 아님",
        "notvisiblerev": "이 판은 삭제되었습니다.",
-       "watchlist-details": "토론 문서의 수는 제외하고, 주시문서 목록에 {{PLURAL:$1|문서 $1개}}가 있습니다.",
+       "watchlist-details": "{{PLURAL:$1|문서 $1개}}가 주시문서 목록에 있습니다. (토론 문서 포함)",
        "wlheader-enotif": "이메일 알림 기능이 활성화되었습니다.",
        "wlheader-showupdated": "마지막으로 방문한 이후에 바뀐 문서는 '''굵은 글씨'''로 보입니다.",
        "wlnote": "$3 $4 기준으로, 아래에 최근 {{PLURAL:$2|한 시간|<strong>$2</strong>시간}} 동안 {{PLURAL:$1|마지막 바뀜이|마지막 바뀜 <strong>$1</strong>개가}} 있습니다.",
index dab6ded..f9347ad 100644 (file)
@@ -19,7 +19,8 @@
                        "MikaelF",
                        "Macofe",
                        "Matma Rex",
-                       "Stryn"
+                       "Stryn",
+                       "Cûndûllah el-Kurdî"
                ]
        },
        "tog-underline": "Xetekê di bin girêdanê de çêke:",
        "unwatch": "Êdî neşopîne",
        "unwatchthispage": "Êdî neşopîne",
        "notanarticle": "Ne gotar e",
-       "watchlist-details": "{{PLURAL:$1|Rûpeleka|$1 rûpel}} li ser lîsteya te ya şopandinê, rûpelên gotûbêjê nayên jimartin.",
+       "watchlist-details": "{{PLURAL:$1|Rûpelekî|$1 rûpel}} li ser lîsteya te ya şopandinê ye (xeynî rûpelên gotûbêjê).",
        "wlheader-enotif": "Agahdariya e-nameyan hate çalakkirin",
        "wlheader-showupdated": "Ev rûpela hatî guhertin dema te lê meyzand bi '''nivîsa stûr''' tê xuyakirin.",
        "wlnote": "Niha {{PLURAL:$1|xeyrandinê|'''$1''' xeyrandinên}} dawî yê {{PLURAL:$2|seetê|'''$2''' seetên}} dawî {{PLURAL:$1|tê|tên}} dîtin.",
        "version-libraries-license": "Destûr",
        "version-libraries-description": "Danasîn",
        "version-libraries-authors": "Xwedî",
+       "redirect-submit": "Here",
+       "redirect-user": "ID'ya Bikarhêner",
+       "redirect-page": "ID'ya  Rûpelê",
        "fileduplicatesearch-filename": "Navê dosyeyê:",
        "fileduplicatesearch-submit": "Lê bigere",
        "specialpages": "Rûpelên taybet",
-       "specialpages-note": "* Rûpelên taybetî ji her kesan ra\n* <strong class=\"mw-specialpagerestricted\">Rûpelên taybetî ji bikarhêneran bi mafên zêdetir ra</strong>",
        "specialpages-group-other": "Rûpelên taybetî yên din",
        "specialpages-group-login": "Têkeve / hesabekî nû çêke",
        "specialpages-group-changes": "Guherandinên dawî û têketin",
index 6ecd2bd..7b13861 100644 (file)
        "post-expand-template-argument-category": "Säiten, op dene mindestens e Parameter vun enger Schabloun vergiess ginn ass",
        "parser-template-loop-warning": "Endlos Schleef an der Schabloun: [[$1]] entdeckt",
        "template-loop-category": "Säite mat Endlos-Schleefe vu Schablounen",
+       "template-loop-category-desc": "An der Säit ass eng Endlos-Schabloun, z. Bsp. eng Schabloun déi sech selwer rekursiv oprifft.",
        "parser-template-recursion-depth-warning": "D'Limit vun der Zuel vun de Verschachtelunge vu Schabloune gouf iwwerschratt ($1)",
        "language-converter-depth-warning": "D'Limite vun der déift vun der Sproochëmwandlung gouf iwwerschratt ($1)",
        "node-count-exceeded-category-desc": "D'Säit huet méi wéi déi maximal Zuel vu Kniet (Node-count).",
        "search-external": "Extern sichen",
        "searchdisabled": "D'Sichfunktioun op {{SITENAME}} ass ausgeschalt. Dir kënnt iwwerdeems mat Hëllef vu Google sichen. Bedenkt awer, datt deenen hire  Sichindex fir {{SITENAME}} eventuell net dem aktuellste Stand entsprecht.",
        "search-error": "Beim Sichen ass e Feeler geschitt: $1",
+       "search-warning": "Beim Sichen gouf eng Warnung gewisen: $1",
        "preferences": "Astellungen",
        "mypreferences": "Astellungen",
        "prefs-edits": "Zuel vun den Ännerungen:",
        "userrights-user-editname": "Benotzernumm uginn:",
        "editusergroup": "Benotzergruppe lueden",
        "editinguser": "Ännere vun de Rechter vum  {{GENDER:$1|Benotzer}} <strong>[[User:$1|$1]]</strong> $2",
+       "viewinguserrights": "Weise vun de Rechter vum {{GENDER:$1|Benotzer}} <strong>[[User:$1|$1]]</strong> $2",
        "userrights-editusergroup": "{{GENDER:$1|Benotzer}}gruppen änneren",
        "userrights-viewusergroup": "{{GENDER:$1|Benotzer}}gruppe weisen",
        "saveusergroups": "{{GENDER:$1|Benotzer}}gruppe späicheren",
        "recentchanges-submit": "Weisen",
        "rcfilters-tag-remove": "'$1' ewechhuelen",
        "rcfilters-legend-heading": "<strong>Lëscht vun Ofkierzungen:</strong>",
+       "rcfilters-grouping-title": "Gruppéieren",
        "rcfilters-activefilters": "Aktiv Filteren",
        "rcfilters-advancedfilters": "Erweidert Filteren",
        "rcfilters-limit-title": "Ännerunge fir ze weisen",
        "rcfilters-hours-title": "Rezent Stonnen",
        "rcfilters-days-show-days": "$1 {{PLURAL:$1|Dag|Deeg}}",
        "rcfilters-days-show-hours": "$1 {{PLURAL:$1|Stonn|Stonnen}}",
+       "rcfilters-highlighted-filters-list": "Ervirgehuewen: $1",
        "rcfilters-quickfilters": "Gespäichert Filteren",
        "rcfilters-quickfilters-placeholder-title": "Nach keng Linke gespäichert",
        "rcfilters-quickfilters-placeholder-description": "Fir Är Filterastellungen z'änneren a méi spéit nees ze benotzen, klickt op d'Zeeche  fir Lieszeechen (bookmark) am Beräich vun den Aktive Filteren hei drënner.",
        "rcfilters-savedqueries-unsetdefault": "Als Standard ewechhuelen",
        "rcfilters-savedqueries-remove": "Ewechhuelen",
        "rcfilters-savedqueries-new-name-label": "Numm",
+       "rcfilters-savedqueries-new-name-placeholder": "Den Zweck vum Filter beschreiwen",
        "rcfilters-savedqueries-apply-label": "Filter uleeën",
        "rcfilters-savedqueries-cancel-label": "Ofbriechen",
        "rcfilters-savedqueries-add-new-title": "Aktuell Filter-Astellunge späicheren",
        "rcfilters-filter-bots-label": "Bot",
        "rcfilters-filter-bots-description": "Ännerungen déi automatiséiert gemaacht goufen.",
        "rcfilters-filter-humans-label": "Mënsch (kee Bot)",
+       "rcfilters-filter-humans-description": "Ännerungen, déi vu mënschlechen Auteure gemaach goufen.",
        "rcfilters-filtergroup-reviewstatus": "Status nokucken",
        "rcfilters-filter-patrolled-label": "Nogekuckt",
        "rcfilters-filter-patrolled-description": "Ännerungen déi als nogekuckt markéiert sinn.",
        "rcfilters-filter-unpatrolled-label": "Net nogekuckt",
        "rcfilters-filter-unpatrolled-description": "Ännerungen déi net als nogekuckt markéiert sinn.",
+       "rcfilters-filtergroup-significance": "Bedeitung",
        "rcfilters-filter-minor-label": "Kleng Ännerungen",
+       "rcfilters-filter-minor-description": "Ännerungen déi den Auteur als kleng markéiert huet.",
        "rcfilters-filter-major-label": "Keng kleng Ännerungen",
+       "rcfilters-filter-major-description": "Ännerungen déi net als kleng markéiert sinn.",
        "rcfilters-filtergroup-watchlist": "Iwwerwaacht Säiten",
        "rcfilters-filter-watchlist-watched-label": "Op der Iwwerwaachungslëscht",
        "rcfilters-filter-watchlist-watched-description": "Ännerungen op Säiten op Ärer Iwwrwaachungslëscht",
        "rcfilters-filter-watchlistactivity-unseen-description": "Ännerungen op Säite déi Dir net besicht hutt säit d'Ännerunge gemaach goufen.",
        "rcfilters-filter-watchlistactivity-seen-label": "Ännerunge gesinn",
        "rcfilters-filter-watchlistactivity-seen-description": "Ännerungen op Säite déi Dir besicht hutt säit d'Ännerunge gemaach goufen.",
+       "rcfilters-filtergroup-changetype": "Typ vun der Ännerung",
        "rcfilters-filter-pageedits-label": "Säitenännerungen",
        "rcfilters-filter-pageedits-description": "Ännerungen um Wikiinhalt, an Diskussiounen, a Beschreiwunge vu Kategorien, ...",
        "rcfilters-filter-newpages-label": "Ugeluechte Säiten",
        "rcfilters-view-advanced-filters-label": "Erweidert Filteren",
        "rcfilters-view-tags": "Markéiert Ännerungen",
        "rcfilters-view-namespaces-tooltip": "Resultater no Nummraum filteren",
+       "rcfilters-view-return-to-default-tooltip": "Zréck op den Haaptmenü vum Filteren",
        "rcfilters-liveupdates-button": "Live-Aktualiséierungen",
+       "rcfilters-liveupdates-button-title-on": "Live-Aktualiséierungen ausschalten",
        "rcfilters-liveupdates-button-title-off": "Nei Ännerunge weisen esoubal wéi se gemaach ginn",
-       "rcfilters-watchlist-markSeen-button": "All Ännerungen als gesi markéieren",
+       "rcfilters-watchlist-markseen-button": "All Ännerungen als gesi markéieren",
+       "rcfilters-watchlist-edit-watchlist-button": "Ännert Är Lëscht vun iwwerwaachte säiten",
        "rcnotefrom": "Hei drënner {{PLURAL:$5|gëtt d'Ännerung|ginn d'Ännerungen}} zanter <strong>$3, $4</strong> (maximal <strong>$1</strong> Ännerunge gi gewisen).",
        "rclistfrom": "Nei Ännerunge vum $3 $2 u weisen",
        "rcshowhideminor": "Kleng Ännerunge $1",
        "unwatchthispage": "Net méi iwwerwaachen",
        "notanarticle": "Keng Säit",
        "notvisiblerev": "Versioun gouf geläscht",
-       "watchlist-details": "{{PLURAL:$1|1 Säit|$1 Säite}} sinn op Ärer Iwwerwaachungslëscht, d'Diskussiounssäiten net matgezielt.",
+       "watchlist-details": "{{PLURAL:$1|1 Säit|$1 Säite}} sinn op Ärer Iwwerwaachungslëscht, (plus Diskussiounssäiten).",
        "wlheader-enotif": "E-Mail-Notifikatioun ass ageschalt.",
        "wlheader-showupdated": "Säiten déi zanter Ärer leschter Visite geännert goufen, si '''fett''' geschriwwen",
        "wlnote": "Hei {{PLURAL:$1|ass déi lescht Ännerung|sinn déi lescht <strong>$1</strong> Ännerunge}} vun {{PLURAL:$2|der leschter Stonn|de leschte(n) <strong>$2</strong> Stonnen}}, Stand: $3 ëm $4 Auer.",
index 0b5e469..f61d797 100644 (file)
        "page_first": "pirm",
        "page_last": "pask",
        "histlegend": "Skirtumai tarp versijų: pažymėkite lyginamas versijas ir spustelkite ''Enter'' klavišą arba mygtuką apačioje.<br />\nŽymėjimai: (dab) = palyginimas su naujausia versija,\n(pask) = palyginimas su prieš tai buvusia versija, S = smulkus keitimas.",
-       "history-fieldset-title": "Ieškoti istorijoje",
+       "history-fieldset-title": "Ieškoti versijų",
        "history-show-deleted": "Tik ištrinti",
        "histfirst": "seniausi",
        "histlast": "paskutiniai",
        "rcfilters-highlightmenu-help": "Pasirinkite spalvą šio elemento paryškinimui",
        "rcfilters-filterlist-noresults": "Nerastas toks filtras",
        "rcfilters-noresults-conflict": "Nerasta jokių rezultatų, nes paieškos kriterijai konfliktuoja",
-       "rcfilters-filtergroup-registration": "Vartotojo registracija",
-       "rcfilters-filter-registered-label": "Registruoti",
-       "rcfilters-filter-registered-description": "Prisijungę redaktoriai.",
-       "rcfilters-filter-unregistered-label": "Neregistruoti",
-       "rcfilters-filter-unregistered-description": "Redaktoriai, kurie nėra prisijungę.",
        "rcfilters-filter-editsbyself-label": "Jūsų keitimai",
        "rcfilters-filter-editsbyself-description": "Jūsų keitimai.",
        "rcfilters-filter-editsbyother-label": "Kitų keitimai",
        "rcfilters-filter-editsbyother-description": "Visi keitimai, išskyrus jūsų.",
        "rcfilters-filtergroup-userExpLevel": "Patirties lygis (tik registruotiems vartotojams)",
+       "rcfilters-filter-user-experience-level-registered-label": "Registruoti",
+       "rcfilters-filter-user-experience-level-registered-description": "Prisijungę redaktoriai.",
+       "rcfilters-filter-user-experience-level-unregistered-label": "Neregistruoti",
+       "rcfilters-filter-user-experience-level-unregistered-description": "Redaktoriai, kurie nėra prisijungę.",
        "rcfilters-filter-user-experience-level-newcomer-label": "Naujokai",
        "rcfilters-filter-user-experience-level-newcomer-description": "Mažiau nei 10 keitimų ir 4 dienų aktyvumo.",
        "rcfilters-filter-user-experience-level-learner-label": "Mokiniai",
        "fileduplicatesearch-noresults": "Nėra failo pavadinimu \"$1\".",
        "specialpages": "Specialieji puslapiai",
        "specialpages-note-top": "Paaiškinimai",
-       "specialpages-note": "* Įprasti specialieji puslapiai.\n* <span class=\"mw-specialpagerestricted\">Apriboto pasiekiamumo specialieji puslapiai.</span>",
        "specialpages-group-maintenance": "Sistemos palaikymo pranešimai",
        "specialpages-group-other": "Kiti specialieji puslapiai",
        "specialpages-group-login": "Prisijungti / sukurti paskyrą",
        "compare-invalid-title": "Jūsų nurodytas pavadinimas neleistinas.",
        "compare-title-not-exists": "Pavadinimas, kurį nurodėte, neegzistuoja.",
        "compare-revision-not-exists": "Keitimas, kurį nurodėte, neegzistuoja.",
+       "diff-form": "'''forma'''",
        "dberr-problems": "Atsiprašome! Svetainei iškilo techninių problemų.",
        "dberr-again": "Palaukite kelias minutes ir perkraukite puslapį.",
        "dberr-info": "(Nepavyksta pasiekti duomenų bazės: $1)",
        "logentry-delete-delete_redir": "$1 pervadindamas {{GENDER:$2|ištrynė}} buvusį nukreipimą $3",
        "logentry-delete-restore": "$1 atkūrė puslapį $3 ($4)",
        "logentry-delete-restore-nocount": "$1 atkūrė puslapį $3",
+       "restore-count-revisions": "{{PLURAL:$1|1 versija|versijų: $1}}",
        "restore-count-files": "{{PLURAL:$1|1 failas|$1 failai}}",
        "logentry-delete-event": "$1 {{GENDER:$2|pakeitė}} matomumą {{PLURAL:$5|žurnalo įvykio|$5 žurnalo įvykių}} $3: $4",
        "logentry-delete-revision": "$1 {{GENDER:$2|pakeitė}} matomumą {{PLURAL:$5|versijos|$5 versijų}} puslapyje $3: $4",
index 8bbb835..5237062 100644 (file)
        "right-deletechangetags": "Dzēst [[Special:Tags|iezīmes]] no datubāzes",
        "grant-generic": "\"$1\" tiesību paka",
        "grant-group-page-interaction": "Darboties ar lapām",
+       "grant-group-file-interaction": "Darboties ar multimediju failiem",
        "grant-group-email": "Sūtīt e-pastu",
        "grant-group-high-volume": "Veikt liela apjoma aktivitātes",
        "grant-group-administration": "Veikt administratīvās darbības",
        "grant-patrol": "Patrulēt lapu izmaiņas",
        "grant-privateinfo": "Piekļūt privātai informācijai",
        "grant-sendemail": "Sūtīt e-pastu citiem dalībniekiem",
-       "grant-uploadeditmovefile": "Augšupielādēt, aizvieto un pārvietot failus",
+       "grant-uploadeditmovefile": "Augšupielādēt, aizvietot un pārvietot failus",
        "grant-uploadfile": "Augšupielādēt jaunus failus",
        "grant-basic": "Pamattiesības",
        "grant-viewdeleted": "Skatīt dzēstos failus un lapas",
        "exif-sensingmethod-2": "Vienas mikroshēmas krāsu zonas sensors",
        "exif-sensingmethod-3": "Divu mikroshēmu krāsu zonas sensors",
        "exif-sensingmethod-4": "Trīs mikroshēmu krāsu zonas sensors",
+       "exif-filesource-3": "Digitālā kamera",
+       "exif-scenetype-1": "Tieši fotografēts attēls",
        "exif-customrendered-0": "Normāls process",
        "exif-customrendered-1": "Dažādots process",
        "exif-exposuremode-0": "Automātiskā ekspozīcija",
index 974f267..c95f930 100644 (file)
        "poolcounter-usage-error": "用誤:$1",
        "aboutsite": "{{SITENAME}}自序",
        "aboutpage": "Project:述",
-       "copyright": "若無側,諸文皆奉$1以行。",
+       "copyright": "若無側,諸文皆奉$1以行。",
        "copyrightpage": "{{ns:project}}:版權",
        "currentevents": "世事",
        "currentevents-url": "Wikipedia:世事",
        "recentchanges-summary": "共筆揮新,悉列於此。",
        "recentchanges-noresult": "無易。",
        "recentchanges-feed-description": "跟wiki源之近易。",
-       "recentchanges-label-newpage": "此纂開新頁",
+       "recentchanges-label-newpage": "立新文",
        "recentchanges-label-minor": "此乃細纂",
        "recentchanges-label-bot": "此乃機纂",
        "recentchanges-label-unpatrolled": "是纂未巡",
index d49b715..6815b8e 100644 (file)
        "rcfilters-empty-filter": "Нема активни филтри. Прикажани се сите придонеси.",
        "rcfilters-filterlist-title": "Филтри",
        "rcfilters-filterlist-whatsthis": "Како работи ова?",
-       "rcfilters-filterlist-feedbacklink": "Ð\94аÑ\98Ñ\82е Ð¼Ð¸Ñ\81леÑ\9aе Ð·Ð° Ð½Ð¾Ð²Ð¸Ñ\82е (беÑ\82а) Ñ\84илÑ\82Ñ\80и",
+       "rcfilters-filterlist-feedbacklink": "Ð\94аÑ\98Ñ\82е Ð½Ð¸ Ð²Ð°Ñ\88е Ð¼Ð¸Ñ\81леÑ\9aе Ð·Ð° Ð¾Ð²Ð¸Ðµ (нови) Ñ\84илÑ\82еÑ\80Ñ\81ки Ð°Ð»Ð°Ñ\82ки",
        "rcfilters-highlightbutton-title": "Истакнување на исход",
        "rcfilters-highlightmenu-title": "Изберете боја",
        "rcfilters-highlightmenu-help": "Изберете боја за да го истакнете ова својство",
        "rcfilters-liveupdates-button": "Поднови во живо",
        "rcfilters-liveupdates-button-title-on": "Исклучи поднови во живо",
        "rcfilters-liveupdates-button-title-off": "Прикажува нови промени во живо",
-       "rcfilters-watchlist-markSeen-button": "Означи ги сите промени како видени",
+       "rcfilters-watchlist-markseen-button": "Означи ги сите промени како видени",
+       "rcfilters-watchlist-edit-watchlist-button": "Уреди набљудувани",
+       "rcfilters-watchlist-showupdated": "Промени во страниците што ги немате посетено откако се случиле се <strong>задебелени</strong>.",
        "rcnotefrom": "Подолу {{PLURAL:$5|е прикажана промената|се прикажани промените}} почнувајќи од <strong>$3, $4</strong>  (се прикажуваат до <b>$1</b>).",
        "rclistfromreset": "Нов избор на датуми",
        "rclistfrom": "Прикажи нови промени почнувајќи од $3 $2",
        "unwatchthispage": "Престани набљудување",
        "notanarticle": "Не е статија",
        "notvisiblerev": "Преработката била избришана",
-       "watchlist-details": "{{PLURAL:$1|$1 страница|$1 страници}} во вашиот список на набљудувања, не броејќи ги посебно страниците за разговор.",
+       "watchlist-details": "Во вашите набљудувани имате {{PLURAL:$1|$1 страница|$1 страници}} (не броејќи ги страниците за разговор).",
        "wlheader-enotif": "Известувањето по е-пошта е вклучено.",
        "wlheader-showupdated": "Страниците што се изменети од вашата последна посета се прикажани со '''задебелени''' букви",
        "wlnote": "Подолу {{PLURAL:$1|е прикажана последната промена|се прикажани последните <strong>$1</strong> промени}} во {{PLURAL:$2|последниов час|последниве <strong>$2</strong> часа}}, заклучно со $3, $4 ч.",
index ad1b6ec..53f0e54 100644 (file)
@@ -17,7 +17,7 @@
        "tog-newpageshidepatrolled": "Scunder  páiginas patrulhadas na lhista de páiginas nuobas",
        "tog-hidecategorization": "Scunder la catadorizaçon de las páiginas",
        "tog-extendwatchlist": "Lhistaige spandida de todas las altaraçones a las páiginas begiadas, nun solo de las redadeiras",
-       "tog-usenewrc": "Agrupar altaraçones por páigina nas mudanças recentes i páiginas bigiadas",
+       "tog-usenewrc": "Agrupar altaraçones por páigina nas altaraçones recentes i páiginas begiadas",
        "tog-numberheadings": "Outo-numerar cabeçalhos",
        "tog-showtoolbar": "Amostrar la barra d'eidiçon",
        "tog-editondblclick": "Eiditar páiginas quando houbir un clique duplo",
@@ -29,7 +29,7 @@
        "tog-minordefault": "Por oumisson, marcar todas las eidiçones cumo menores",
        "tog-previewontop": "Amostrar l'antebison antes de la caixa d'eidiçon",
        "tog-previewonfirst": "Amostrar l'antebison na purmeira eidiçon",
-       "tog-enotifwatchlistpages": "Notificar-me por correio eiletrónico quando ua páigina begiada fur altarada",
+       "tog-enotifwatchlistpages": "Abisar-me por correio eiletrónico quando ua páigina begiada fur altarada",
        "tog-enotifusertalkpages": "Abisar-me por correio eiletrónico quando la mie páigina de cumbersa ye eiditada",
        "tog-enotifminoredits": "Abisar-me por correio eiletrónico tamien quando las eidiçones fúren pequeinhas",
        "tog-enotifrevealaddr": "Rebelar l miu andereço de correio eiletrónico nas noteficaçones",
@@ -42,8 +42,8 @@
        "tog-watchlisthidebots": "Scunder eidiçones de robós al lhistar mudanças a las páiginas begiadas",
        "tog-watchlisthideminor": "Scunder eidiçones menores al lhistar mudanças a las páiginas begiadas",
        "tog-watchlisthideliu": "Scunder eidiçones d'outelizadores outenticados al lhistar mudanças a las páiginas begiadas",
-       "tog-watchlistreloadautomatically": "Recargar la lhista de páiginas bigiadas outomaticamente siempre que un filtro ye altarado (ye neçairo l JavaScript)",
-       "tog-watchlistunwatchlinks": "Adicionar lhigaçones diretas pa bigiar ó deixar de bigiar, a las antradas de la lhista de páiginas bigiadas (ye neçairo l JavaScript para altarnar antre ambas)",
+       "tog-watchlistreloadautomatically": "Recargar la lhista de páiginas begiadas outomaticamente siempre que un filtro ye altarado (ye neçairo l JavaScript)",
+       "tog-watchlistunwatchlinks": "Adicionar lhigaçones diretas pa begiar ó deixar de begiar, a las antradas de la lhista de páiginas begiadas (ye neçairo l JavaScript para altarnar antre ambas)",
        "tog-watchlisthideanons": "Scunder eidiçones d'outelizadores anónimos al lhistar mudanças a las páiginas begiadas",
        "tog-watchlisthidepatrolled": "Scunder  eidiçones patrulhadas al lhistar mudanças a las páiginas begiadas",
        "tog-watchlisthidecategorization": "Scunder la catadorizaçon de las páiginas",
        "templatepage": "Ber páigina de modelos",
        "viewhelppage": "Ber páigina de ajuda",
        "viewtalkpage": "Ber cumbersa",
-       "otherlanguages": "Outras lhénguas",
+       "otherlanguages": "Noutras lhénguas",
        "redirectedfrom": "(Ancaminamiento de $1)",
        "redirectpagesub": "Páigina de ancaminamiento",
        "lastmodifiedat": "Esta páigina fui eiditada pula redadeira beç a la(s) $2 de $1.",
        "page-atom-feed": "Feed Atom de \"$1\"",
        "red-link-title": "$1 (la páigina nun eisiste)",
        "nstab-main": "Páigina",
-       "nstab-user": "Páigina de l'{{GENDER:{{BASEPAGENAME}}|outelizador|outelizadora|outelizador(a)}}",
+       "nstab-user": "Páigina d{{GENDER:{{BASEPAGENAME}}|e l outelizador|e la outelizadora|e outelizador(a)}}",
        "nstab-media": "Páigina de média",
        "nstab-special": "Páigina special",
        "nstab-project": "Páigina de l porjeto",
        "changepassword": "Demudar palabra-chabe",
        "resetpass_header": "Demudar palabra-chabe de la cuonta",
        "retypenew": "Pon outra beç la nuoba palabra chabe:",
+       "botpasswords": "Palabras-chabe de robós",
+       "botpasswords-label-resetpassword": "Redefenir palabra-chabe",
        "resetpass-submit-loggedin": "Demudar palabra-chabe",
+       "passwordreset": "Redefenir palabra-chabe",
        "changeemail": "Altarar ó remober l'andereço de correio eiletrónico",
+       "resettokens": "Redefenir chabes",
        "bold_sample": "Testo a negrito",
        "bold_tip": "Testo a negrito",
        "italic_sample": "Testo an eitálico",
        "summary": "Resumo:",
        "subject": "Assunto/cabeçailho:",
        "minoredit": "Marcar cumo eidiçon pequerrixa",
-       "watchthis": "Bigiar esta páigina",
+       "watchthis": "Begiar esta páigina",
        "savearticle": "Grabar páigina",
+       "publishchanges": "Publicar altaraçones",
        "preview": "Ber cumo queda",
        "showpreview": "Ber cumo queda",
        "showdiff": "Amostrar altaraçones",
-       "anoneditwarning": "<strong>Abiso</strong>: Tu nun stás outenticado. L tou IP será registrado ne l stórico de las eidiçones desta páigina. Se <strong>[$1 ampeçar sesson]</strong> ó <strong>[$2 criar ua cunta]</strong>, las sues eidiçones seran registradas cul sou nome d'outelizador(a), an cunjunto cun outros benefícios.",
+       "anoneditwarning": "<strong>Abiso</strong>: Tu nun stás outenticado(a). L tou IP será registrado ne l stórico de las eidiçones desta páigina. Se <strong>[$1 ampeçar sesson]</strong> ó <strong>[$2 criar ua cuonta]</strong>, las sues eidiçones seran registradas cul sou nome d'outelizador(a), an cunjunto cun outros benefícios.",
        "summary-preview": "Amostra de l sumário:",
        "blockedtext": "<strong>L tou nome d'outelizador ó morada de IP foi bloquiado.</strong>\n\nL bloqueio fui feito por $1.\nLa rezon fui <em>$2</em>.\n\n* Ampeço de l bloqueio: $8\n* Balidade de l bloqueio: $6\n* Çtino de l bloqueio: $7\n\nTu puodes cuntatar $1 ó outro [[{{MediaWiki:Grouppage-sysop}}|admenistrador]] pa çcutir subre l bloqueio.\nBei que nun poderás outelizar la funcionalidade \"Cuntatar outelizador\" se nun tubires ua counta cun ua morada eiletrónica bálida andicada an las tues [[Special:Preferences|preferéncias d'outelizador]] i se tubires sido bloquiado de outelizar essa ferramienta.\nLa tue morada de IP atual ye $3 i la eidantificaçon (ID) de l bloqueio ye #$5.\nPor fabor, anclui un deilhes (ó dambos ls dous) dados an qualquier tentatibas de sclarecimentos.",
        "autoblockedtext": "La sue morada de IP foi bloquiada de forma outomática porque fui outelizado recentemente por outro outelizador, l qual fui bloquiado por $1.\nLa rezon fui:\n\n:<em>$2</em>\n\n* Ampeço de l bloqueio: $8\n* Balidade de l bloqueio: $6\n* Çtino de l bloqueio: $7\n\nTu puodes cuntatar $1 ó outro [[{{MediaWiki:Grouppage-sysop}}|admenistrador]] pa çcutir subre l bloqueio.\n\nBei que nun poderás outelizar la funcionalidade \"Cuntatar outelizador\" se nun tubires ua counta cun ua morada eiletrónica bálida andicada an las tues [[Special:Preferences|preferéncias d'outelizador]] i se tubires sido bloquiado de outelizar essa ferramienta.\n\nLa tue morada de IP atual ye $3 i la eidantificaçon (ID) de l bloqueio ye #$5.\nPor fabor, anclui un deilhes (ó dambos ls dous) dados an qualquier tentatibas de sclarecimentos.",
        "template-protected": "(portegida)",
        "template-semiprotected": "(semi-protegida)",
        "hiddencategories": "Esta páigina faç parte {{PLURAL:$1|dua catadorie scundida|$1 duas catadories scundidas}}:",
-       "nocreatetext": "{{SITENAME}} tem restringida la possibilidade de criar nuobas páginas.\nPode boltar atrás i editar unha página yá eisistente, o [[Special:UserLogin|autenticar-se o criar unha cuonta]].",
+       "nocreatetext": "{{SITENAME}} restringe la possibilidade de criar nuobas páiginas.\nPuode buoltar atrás i eiditar ua páigina yá eisistente, ó [[Special:UserLogin|outenticar-se ó criar ua cuonta]].",
        "permissionserrorstext-withaction": "Tu nun tenes premisson pa $2, {{PLURAL:$1|pula seguinte rezon|pulas seguintes rezones}}:",
        "recreate-moveddeleted-warn": "<strong>Abiso: Tu stás a criar ua páigina que yá fui d'atrás botada fuora.</strong>\n\nBei bien se ye própio cuntinar a eiditar esta páigina.\nL registro de la eileminaçon i de l arrastrar ye amostrado eiqui por cumbeniéncia:",
        "moveddeleted-notice": "Esta páigina fui apagada.\nL registro de la eileminaçon, proteçon i arrastrar desta páigina stá ambaixo pa refréncia.",
        "search-interwiki-default": "Resultados de $1:",
        "search-interwiki-more": "(mais)",
        "searchall": "todos",
+       "showingresultsinrange": "Apersenta-se ambaixo {{PLURAL:$1|<strong>1</strong> resultado|anté <strong>$1</strong> resultados}} ne l'anterbalo #<strong>$2</strong> a #<strong>$3</strong>.",
        "search-nonefound": "La percura nun porduziu resultados.",
        "powersearch-legend": "Percura abançada",
        "powersearch-ns": "Percurar ne ls spácios nominales:",
-       "powersearch-remember": "Lhembrar seleçon pa las pesquisas feturas",
+       "powersearch-remember": "Lhembrar seleçon pa las percuras feturas",
        "preferences": "Perfréncias",
        "mypreferences": "Las mies perfréncias",
        "prefs-edits": "Númaro d'eidiçones:",
        "prefs-skin": "Maçcarilha",
        "skin-preview": "amostrar",
-       "datedefault": "Sin preferéncia",
+       "datedefault": "Sin perfréncia",
        "prefs-personal": "Calantriç",
        "prefs-rc": "Redadeiras altaraçones",
        "prefs-watchlist": "Páiginas begiadas",
-       "prefs-editwatchlist": "Eiditar lhista de páiginas bigiadas",
-       "prefs-editwatchlist-label": "Eiditar antradas na sue lhista de páiginas bigiadas:",
-       "prefs-editwatchlist-edit": "Ber i remober títalos de la sue lhista de páiginas bigiadas",
-       "prefs-editwatchlist-raw": "Eiditar lhista de páiginas bigiadas an forma de testo",
-       "prefs-editwatchlist-clear": "Lhimpar lhista de páiginas bigiadas",
-       "prefs-watchlist-days": "Dies a amostrar nas mudanças a las páiginas bigiadas:",
+       "prefs-editwatchlist": "Eiditar la lhista de páiginas begiadas",
+       "prefs-editwatchlist-label": "Eiditar antradas na sue lhista de páiginas begiadas:",
+       "prefs-editwatchlist-edit": "Ber i remober títalos de la sue lhista de páiginas begiadas",
+       "prefs-editwatchlist-raw": "Eiditar lhista de páiginas begiadas an forma de testo",
+       "prefs-editwatchlist-clear": "Lhimpar la sue lhista de páiginas begiadas",
+       "prefs-watchlist-days": "Dies a amostrar nas altaraçones a las páiginas begiadas:",
        "prefs-watchlist-days-max": "Mássimo: $1 {{PLURAL:$1|die|dies}}",
-       "prefs-watchlist-edits": "Númaro mássimo d'eidiçones a amostrar na lhista de bigiadas:",
+       "prefs-watchlist-edits": "Númaro mássimo d'eidiçones a amostrar na lhista de begiadas:",
        "prefs-watchlist-edits-max": "Númaro mássimo: 1000",
-       "prefs-watchlist-token": "Chabe secreta de la lhista de páiginas bigiadas:",
+       "prefs-watchlist-token": "Chabe secreta de la lhista de páiginas begiadas:",
        "prefs-resetpass": "Altarar palabra-chabe",
        "prefs-changeemail": "Altarar ó remober correio eiletrónico",
        "prefs-email": "Oupçones de l correio eiletrónico",
        "recentchangesdays-max": "Mássimo: $1 {{PLURAL:$1|die|dies}}",
        "recentchangescount": "Númaro d'eidiçones a apersentar por omisson:",
        "prefs-help-recentchangescount": "Anclui mudanças recentes, stórico de páiginas i registros.",
-       "prefs-help-watchlist-token2": "Esta ye la chabe secreta pa l ''feed'' RSS de la sue lhista de páiginas bigiadas.\nQualquiera pessona que coinça la chabe será capaç de lher la sue lhista de páiginas bigiadas, por esso nun la dibulgue.\n[[Special:ResetTokens|Clique eiqui pa redefenir eilha]].",
+       "prefs-help-watchlist-token2": "Esta ye la chabe secreta pa l ''feed'' RSS de la sue lhista de páiginas begiadas.\nQualquiera pessona que coinça la chabe será capaç de lher la sue lhista de páiginas begiadas, por esso nun la dibulgue.\n[[Special:ResetTokens|Clique eiqui pa redefenir eilha]].",
        "timezonelegend": "Fuso hourário:",
        "localtime": "Hora lhocal:",
        "timezoneuseoffset": "Outro (specificar defréncia)",
        "timezoneregion-indian": "Ouceano Índico",
        "timezoneregion-pacific": "Ouceano Pacífico",
        "allowemail": "Aceitar correio eiletrónico d'outros outelizadores",
+       "prefs-searchoptions": "Percura",
        "default": "padron",
        "prefs-files": "Fexeiros",
        "prefs-custom-css": "CSS personalizada",
        "gender-unknown": "Al fazer mençon a la sue pessona, l software eirá outelizar palabras de l género neutro siempre que possible",
        "gender-male": "El ye un outelizador",
        "gender-female": "Eilha ye ua outelizadora",
-       "prefs-help-gender": "Esta preferéncia ye oupcional.\nL software outeliza l sou balor pa l'andereçar i pa l mencionar a outros outelizando l género gramatical apropiado.\nEsta anformaçon será pública.",
-       "email": "Morada Eiletrónica",
+       "prefs-help-gender": "Esta perfréncia ye oupcional.\nL software outeliza l sou balor pa l'andereçar i pa l mencionar a outros outelizando l género gramatical apropiado.\nEsta anformaçon será pública.",
+       "email": "Morada eiletrónica",
        "prefs-help-realname": "L nome berdadeiro ye oupcional.\nCauso l çponiblizes, este será outelizado pa te dar crédito pul tou trabalho.",
        "prefs-help-email": "Oupcional: l'andereço de correio eiletrónico ye oupcional, mas será necessairo pa redefenir la palabra-chabe causo squeça l'antiga.",
        "prefs-help-email-others": "Tamien puode ouptar por permitir que outros antren an cuntato cunsigo por correio eiletrónico, atrabeç dua lhigaçon nas sues páiginas de outelizador ó de cumbersa, sin rebelar l sou andereço de correio eiletrónico.",
        "prefs-displaywatchlist": "Oupçones de bisualizaçon",
        "prefs-tokenwatchlist": "Chabe",
        "prefs-diffs": "Defréncias",
+       "userrights": "Prebilégios {{GENDER:{{BASEPAGENAME}}|de l outelizador|de la outelizadora|de outelizador(a)}}",
        "editusergroup": "Cargar grupos de outelizadores",
        "userrights-groupsmember": "Nembro de:",
        "group": "Grupo:",
        "action-move": "arrastrar esta páigina",
        "action-movefile": "arrastrar este fexeiro",
        "action-delete": "apagar esta páigina",
+       "action-purge": "recargar esta páigina",
        "nchanges": "$1 {{PLURAL:$1|altaraçon|altaraçones}}",
        "recentchanges": "Redadeiras altaraçones",
        "recentchanges-legend": "Oupçones de las redadeiras altaraçones",
        "statistics-articles": "Páiginas de cuntenido",
        "statistics-pages": "Páiginas",
        "statistics-users-active": "Outelizadores atibos",
+       "pageswithprop": "Páiginas que outelizan ua propiadade",
+       "pageswithprop-legend": "Páiginas que outelizan ua propiadade",
        "doubleredirects": "Ancaminamientos duplos",
        "brokenredirects": "Ancaminamientos scachados",
        "brokenredirects-edit": "eiditar",
        "unusedimages": "Fexeiros nun outelizados",
        "wantedcategories": "Catadories pedidas",
        "wantedpages": "Páiginas pedidas",
+       "wantedfiles": "Fexeiros zeiados",
+       "wantedtemplates": "Modelos zeiados",
        "mostlinked": "Páiginas mais lhigadas",
        "mostlinkedcategories": "Catadories cun mais nembros",
        "mostlinkedtemplates": "Páiginas mais transcluídas",
        "shortpages": "Páiginas pequeinhas",
        "longpages": "Páiginas cumpridas",
        "deadendpages": "Páiginas sin salida",
-       "protectedpages": "Páginas protegidas",
+       "protectedpages": "Páiginas protegidas",
+       "protectedtitles": "Títalos portegidos",
        "listusers": "Lhista de outelizadores",
        "newpages": "Páiginas nuobas",
        "ancientpages": "Páiginas mais antigas",
        "booksources-search-legend": "Percurar por fuontes de lhibros",
        "booksources-search": "Percurar",
        "booksources-text": "Ye apersentada ambaixo ua lhista de lhigaçones para outros sítios na Anternete que benden lhibros nuobos i ousados i talbeç possuan anformaçones adicionales subre ls lhibros que percura:",
-       "booksources-invalid-isbn": "L númaro ISBN apersentado nun parece ser bálido; berifique l'eisisténcia de ls erros al copiar de la fuonte ouriginal.",
+       "booksources-invalid-isbn": "L númaro ISBN apersentado nun parece ser bálido; berifique la eisisténcia de ls erros al copiar de la fuonte oureginal.",
        "magiclink-tracking-rfc": "Páiginas que outelizan lhigaçones mágicas RFC",
        "magiclink-tracking-rfc-desc": "Esta páigina outeliza lhigaçones mágicas RFC. Cunsulte la [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Magic_links mediawiki.org] para saber cumo migrar.",
        "magiclink-tracking-pmid": "Páiginas que outelizan lhigaçones mágicas PMID",
        "linksearch-ok": "Percurar",
        "listusers-submit": "Amostrar",
        "activeusers": "Lhista de outelizadores atibos",
+       "listgrouprights": "Prebilégios de ls grupos de outelizadores",
        "listgrouprights-rights": "Dreitos",
        "listgrouprights-members": "(lista de nembros)",
+       "listgrants": "Cuncessones de permissones a las aplicaçones lhigadas",
+       "trackingcategories": "Catadories de monitorizaçon",
        "emailuser": "Ambiar carta eiletrónica a {{GENDER:{{BASEPAGENAME}}|este outelizador|esta outelizadora|este(a) outelizador(a)}}",
        "emailfrom": "De:",
        "emailto": "Para:",
        "watch": "Begiar",
        "watchthispage": "Begiar esta páigina",
        "unwatch": "Zantressar-se",
-       "watchlist-details": "{{PLURAL:$1|Eisiste $1 páigina|Eisisten $1 páiginas}} na sue lhista de páiginas bigiadas, scluindo las páiginas de cumbersa.",
+       "watchlist-details": "{{PLURAL:$1|Eisiste $1 páigina|Eisisten $1 páiginas}} na sue lhista de páiginas begiadas, scluindo las páiginas de cumbersa.",
+       "wlheader-enotif": "La notificaçon por correio eiletrónico stá atiba.",
+       "wlheader-showupdated": "Las páiginas altaradas zde la redadeira beç que las besitou aparecen çtacadas an <strong>negrito</strong>.",
        "wlshowlast": "Ber redadeiras $1 horas $2 dies",
-       "watchlist-options": "Oupçones de la lista de begiados",
+       "watchlist-options": "Oupçones de la lhista de páiginas begiadas",
        "watching": "A begiar...",
        "unwatching": "A deixar de begiar...",
+       "enotif_reset": "Marcar todas las páiginas cumo bejitadas",
        "created": "criada",
        "changed": "demudada",
        "deletepage": "Botar fuora páigina",
        "protectlogpage": "Registro de porteçon",
        "protectedarticle": "porteger \"[[$1]]\"",
        "modifiedarticleprotection": "demudeste l nible de porteçon pa \"[[$1]]\"",
-       "prot_1movedto2": "[[$1]] foi movido para [[$2]]",
+       "prot_1movedto2": "arrastrou [[$1]] pa [[$2]]",
        "protect-legend": "Confirmar protecçon",
        "protectcomment": "Rezon:",
        "protectexpiry": "Data de balidade:",
        "whatlinkshere-filters": "Filtros",
        "blockip": "Bloquiar {{GENDER:$1|outelizador|outelizadora|outelizador(a)}}",
        "ipboptions": "2 horas:2 hours,1 die:1 day,3 dias:3 days,1 sumana:1 week,2 sumanas:2 weeks,1 més:1 month,3 meses:3 months,6 meses:6 months,1 anho:1 year,anfenito:infinite",
+       "blocklist": "Outelizadores bloquiados",
+       "autoblocklist": "Bloqueios outomáticos",
        "ipblocklist": "Outelizadores bloquiados",
        "blocklink": "bloquiar",
        "unblocklink": "zbloquiar",
        "tooltip-ca-edit": "Eiditar esta páigina",
        "tooltip-ca-addsection": "Ampeçar un cacho nuobo",
        "tooltip-ca-viewsource": "Esta páigina stá portegida.\nInda assi, tu puodes ber l sou código.",
-       "tooltip-ca-history": "Eidiçones mais antigas deste páigina.",
+       "tooltip-ca-history": "Eidiçones mais antigas desta páigina.",
        "tooltip-ca-protect": "Porteger esta páigina",
        "tooltip-ca-delete": "Botar fuora esta páigina",
        "tooltip-ca-move": "Arrastrar esta páigina",
        "tooltip-search": "Percurar an {{SITENAME}}",
        "tooltip-search-go": "Ir pa ua páigina cun este nome, causo eisista",
        "tooltip-search-fulltext": "Percurar por páiginas cun este testo",
+       "tooltip-p-logo": "Bejitar la páigina percipal",
        "tooltip-n-mainpage": "Besitar la páigina percipal",
        "tooltip-n-mainpage-description": "Besitar la páigina percipal",
        "tooltip-n-portal": "Subre l porjeto, l que puodes fazer, i adonde ancuntrar las cousas",
        "tooltip-t-print": "Berson pa ampremir desta páigina",
        "tooltip-t-permalink": "Lhigaçon pa siempre desta berson desta páigina",
        "tooltip-ca-nstab-main": "Ber la páigina de l cuntenido",
-       "tooltip-ca-nstab-user": "Ber la páigina de outelizador",
+       "tooltip-ca-nstab-user": "Ber la páigina de outelizador",
        "tooltip-ca-nstab-special": "Esta ye ua páigina special, i nun puode ser eiditada.",
        "tooltip-ca-nstab-project": "Ber la páigina de l porjeto",
        "tooltip-ca-nstab-image": "Ber la páigina de l fexeiro",
        "tooltip-ca-nstab-category": "Ber la páigina de la catadorie",
        "tooltip-minoredit": "Marcar cumo eidiçon pequerrixa",
        "tooltip-save": "Grabar las tues altaraçones",
+       "tooltip-publish": "Publicar las sues altaraçones",
        "tooltip-preview": "Bei purmeiro las altaraçones, por fabor outeliza esto antes de grabar!",
        "tooltip-diff": "Amostrar altaraçones que faziste neste testo.",
        "tooltip-compareselectedversions": "Ber las defréncias antre las dues bersones marcadas desta páigina.",
        "exif-subjectdistancerange-0": "Çcoincido",
        "namespacesall": "todos",
        "monthsall": "todos",
+       "confirm-purge-title": "Purgar esta páigina",
        "confirm_purge_button": "Stá bien",
+       "confirm-purge-top": "Lhimpar a mimória cache desta páigina?",
+       "confirm-purge-bottom": "Recargar ua páigina lhimpa la mimória cache i fuorça la sue berson mais reciente a aparecer.",
        "imgmultipageprev": "← páigina atrasada",
        "imgmultipagenext": "páigina seguinte →",
        "imgmultigo": "Bota!",
        "table_pager_limit": "Amostrar $1 antradas por páigina",
        "table_pager_empty": "Sien resultados",
        "autoredircomment": "Ancaminamiento pa [[$1]]",
-       "watchlistedit-normal-title": "Eiditar lhista de páiginas bigiadas",
+       "watchlistedit-normal-title": "Eiditar la lhista de páiginas begiadas",
        "watchlistedit-raw-titles": "Títalos",
-       "watchlistedit-clear-title": "Lhimpar lhista de páiginas bigiadas",
-       "watchlistedit-clear-legend": "Lhimpar lhista de páiginas bigiadas",
-       "watchlisttools-clear": "Lhimpar lhista de páiginas bigiadas",
+       "watchlistedit-clear-title": "Lhimpar la lhista de páiginas begiadas",
+       "watchlistedit-clear-legend": "Lhimpar la lhista de páiginas begiadas",
+       "watchlisttools-clear": "Lhimpar la lhista de páiginas begiadas",
        "watchlisttools-view": "Ber altaraçones amportantes",
-       "watchlisttools-edit": "Ber i eiditar ls mius begiados",
-       "watchlisttools-raw": "Ediçon bruta da lhista de ls bigiados",
+       "watchlisttools-edit": "Ber i eiditar la mie lhista de páiginas begiadas",
+       "watchlisttools-raw": "Eiditar la lhista de páiginas begiadas an forma de testo",
        "signature": "[[{{ns:user}}:$1|$2]] ([[{{ns:user_talk}}:$1|cumbersa]])",
        "version": "Berson",
-       "version-specialpages": "Páiginas Speciales",
+       "version-specialpages": "Páiginas speciales",
        "version-variables": "Bariables",
        "version-other": "Outro",
        "version-license": "Lhicença de l MediaWiki",
        "version-ext-colheader-description": "Çcriçon",
        "version-software-product": "Perduto",
        "version-software-version": "Berson",
+       "redirect-lookup": "Percurar:",
        "fileduplicatesearch-filename": "Nome de l fexeiro",
        "fileduplicatesearch-submit": "Percurar",
        "specialpages": "Páiginas speciales",
+       "specialpages-note-top": "Lhegenda",
+       "specialpages-note-restricted": "* Páiginas speciales normales.\n* <span class=\"mw-specialpagerestricted\">Páiginas speciales restritas.</span>",
+       "specialpages-group-maintenance": "Relatórios de manutençon",
+       "specialpages-group-other": "Outras páiginas speciales",
        "specialpages-group-login": "Antrar / criar ua cuonta",
+       "specialpages-group-changes": "Altaraçones i registros recentes",
+       "specialpages-group-media": "Lhistas i cargadura de fexeiros",
+       "specialpages-group-users": "Outelizadores i prebilégios",
+       "specialpages-group-highuse": "Páiginas mui outelizadas",
        "specialpages-group-pages": "Lhistas de páiginas",
        "specialpages-group-pagetools": "Ferramienta de páiginas",
+       "specialpages-group-wiki": "Dados i ferramientas",
+       "specialpages-group-redirects": "Páiginas speciales de ancaminamientos",
        "tags-title": "Eitiquetas",
        "tags-edit": "eiditar",
        "tags-activate": "atibar",
        "tags-deactivate": "zatibar",
        "tags-activate-submit": "Atibar",
        "diff-form": "Defréncias",
+       "logentry-move-move": "$1 {{GENDER:$2|arrastrou}} $3 pa $4",
+       "logentry-move-move-noredirect": "$1 {{GENDER:$2|arrastrou}} $3 pa $4 sin deixar un ancaminamiento",
+       "logentry-move-move_redir": "$1 {{GENDER:$2|arrastrou}} $3 pa l sou ancaminamiento $4",
        "rightsnone": "(nanhun)",
        "mediastatistics-header-multimedia": "Média anriquecida",
+       "authmanager-email-label": "Correio eiletrónico",
+       "changecredentials": "Altarar credenciales",
+       "changecredentials-submit": "Altarar credenciales",
+       "removecredentials": "Remober credenciales",
+       "removecredentials-submit": "Remober credenciales",
        "gotointerwiki": "Salindo de {{SITENAME}}"
 }
index 1a0dc94..8c67a7c 100644 (file)
        "all-logs-page": "အများနှင့်ဆိုင်သောမှတ်တမ်းအားလုံး",
        "alllogstext": "{{SITENAME}}၏ ရရှိနိုင်သော မှတ်တမ်းများအားလုံး ပေါင်းစည်းပြသခြင်း ဖြစ်သည်။\nမှတ်တမ်းအမျိုးအစား၊ အသုံးပြုသူအမည် (စာလုံးအကြီးအသေး)၊ သို့မဟုတ် သက်ဆိုင်ရာ စာမျက်နှာ (စာလုံးအကြီးအသေး) ကို ရွေးချယ်ခြင်းဖြင့် ကြည့်ရှုမှုကို အကျဉ်းချုံးနိုင်ပါသည်။",
        "logempty": "မှတ်တမ်းထဲတွင် ကိုက်ညီသော အရာများ မရှိပါ။",
+       "showhideselectedlogentries": "ရွေးချယ်ထားသော မှတ်တမ်းများ၏ မြင်နိုင်မှုကို ပြောင်းလဲရန်",
        "checkbox-all": "အားလုံး",
        "allpages": "စာမျက်နှာအားလုံး",
        "nextpage": "နောက်ထပ်စာမျက်နှာ ($1)",
        "markedaspatrolledtext": "[[:$1]] ၏ ရွေးချယ်ထားသော တည်းဖြတ်မူကို စောင့်ကြပ်စစ်ဆေးပြီးကြောင်း မှတ်သားပြီးပါပြီ။",
        "markedaspatrollednotify": "$1 သို့ ဤပြောင်းလဲမှုအား စောင့်ကြပ်စစ်ဆေးပြီးကြောင်း မှတ်သားပြီးပါပြီ။",
        "patrol-log-page": "စောင့်ကြပ်စစ်ဆေးမှု မှတ်တမ်း",
+       "log-show-hide-patrol": "စောင့်ကြပ်စစ်ဆေးမှု မှတ်တမ်း $1",
        "filedeleteerror-short": "ဖိုင်ဖျက်ရာတွင် အမှားအယွင်း - $1",
        "previousdiff": "← တည်းဖြတ်မူ အဟောင်း",
        "nextdiff": "ပိုသစ်သော တည်းဖြတ်မှု",
        "logentry-patrol-patrol-auto": "စာမျက်နှာ $3 ၏ တည်းဖြတ်မူ $4 အား $1 က စောင့်ကြပ်စစ်ဆေးပြီးကြောင်း အလိုအလျောက် {{GENDER:$2|မှတ်သားခဲ့သည်}}",
        "logentry-newusers-create": "အသုံးပြုသူအကောင့် $1 ကို {{GENDER:$2|ဖန်တီးခဲ့သည်}}",
        "logentry-newusers-autocreate": "အသုံးပြုသူအကောင့် $1 ကို အလိုအလျောက် {{GENDER:$2|ဖန်တီးခဲ့သည်}}",
+       "logentry-protect-protect": "$1 က  $3 ကို {{GENDER:$2|ကာကွယ်ခဲ့သည်}} $4",
        "logentry-protect-modify": "$3 အတွက် ကာကွယ်မှုအဆင့်ကို $1 {{GENDER:$2|က ပြောင်းလဲခဲ့သည်}} $4",
        "logentry-upload-upload": "$1 သည် $3 ကို {{GENDER:$2|upload တင်ခဲ့သည်}}",
        "logentry-upload-overwrite": "$3 ၏ ဗားရှင်းအသစ်ကို $1 {{GENDER:$2|upload တင်ခဲ့သည်}}",
index f98e7f6..3f350c2 100644 (file)
        "showpreview": "Seng khoàⁿ-māi",
        "showdiff": "Khòaⁿ kái-piàn ê pō·-hūn",
        "anoneditwarning": "'''thê-chhíⁿ:''' Lí bô teng-ji̍p. Lí nā ū kái mi̍h-kiāⁿ, lí ê IP ē hô͘ lâng khoàⁿ tio̍h. Lí nā <strong>[$1 teng-ji̍p]</strong> iah-sī <strong>[$2 khui chi̍t-ê kháu-chō]</strong>; lí kái ê mi̍h-kiāⁿ ē kái kì lí ê kháu-chō-miâ. Mā ū kî-thaⁿ ê hó-chhù.",
+       "anonpreviewwarning": "<em>Lí bô teng-ji̍p. Nā-sī lí beh pó-chûn, lí--ê IP ūi-chí ē kì-lo̍k tī i--ê siu-kái le̍k-sú lāi-bīn.</em>",
        "summary-preview": "Khài-iàu ê preview:",
        "subject-preview": "Ū-lám tê-bo̍k/piau-tê:",
        "blockednoreason": "無寫理由",
        "userjspreview": "'''Sè-jī! Lí hiān-chú-sî chhì khoàⁿ--ê sī lí ka-kī ê javascript; che iáu-bōe pó-chûn--khí-lâi!'''",
        "note": "'''Chù-ì:'''",
        "previewnote": "'''Thê-chhéⁿ lí che sī 1 bīn kiám-cha chho͘-phe ēng--ê \"seng-khoàⁿ-ia̍h\", iáu-bōe pó-chûn--khí-lâi!'''",
+       "continue-editing": "Kè-sio̍k siu-kái",
        "session_fail_preview": "'''Pháiⁿ-sè! Gún chiām-sî bô hoat-tō͘ chhú-lí lí ê pian-chi̍p (goân-in: \"phàng-kiàn sú-iōng kî-kan ê chu-liāu\"). Lô-hoân têng chhì khoàⁿ-māi. Ká-sú iû-goân bô-hāu, ē-sái teng-chhut koh-chài teng-ji̍p hoān-sè tō ē-tit kái-koat.'''",
        "editing": "Siu-kái $1",
        "creating": "Chhòng-kiàn $1",
index 309a992..7c60994 100644 (file)
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (se også [[Special:NewPages|liste over nye sider]])",
        "recentchanges-legend-plusminus": "«(±123)»",
        "recentchanges-submit": "Vis",
+       "rcfilters-tag-remove": "Fjern «$1»",
        "rcfilters-legend-heading": "<strong>Liste over forkortelser:</strong>",
        "rcfilters-other-review-tools": "<strong>Andre gjennomgangsverktøy</strong>",
        "rcfilters-group-results-by-page": "Grupper resultater etter side",
        "rcfilters-hours-title": "De siste timene",
        "rcfilters-days-show-days": "{{PLURAL:$1|Én dag|$1 dager}}",
        "rcfilters-days-show-hours": "{{PLURAL:$1|Én time|$1 timer}}",
+       "rcfilters-highlighted-filters-list": "Fremhevet: $1",
        "rcfilters-quickfilters": "Lagrede filtre",
        "rcfilters-quickfilters-placeholder-title": "Ingen lenker lagret enda",
        "rcfilters-quickfilters-placeholder-description": "For å lagre filterinnstillingene og gjenbruk dem senere, klikk på bokmerkeikonet i området Aktive Filtre under.",
        "rcfilters-liveupdates-button": "Live-oppdateringer",
        "rcfilters-liveupdates-button-title-on": "Slå av live-oppdateringer",
        "rcfilters-liveupdates-button-title-off": "Vis nye endringer når de skjer",
-       "rcfilters-watchlist-markSeen-button": "Merk alle endringer som sett.",
+       "rcfilters-watchlist-markseen-button": "Merk alle endringer som sett.",
        "rcnotefrom": "Nedenfor er vist {{PLURAL:$5|endringen|endringene}} som er gjort siden <strong>$3, $4</strong> (frem til <strong>$1</strong>).",
        "rclistfromreset": "Nullstill datovalg",
        "rclistfrom": "Vis nye endringer fra og med $3 $2",
index c2722ac..cf25286 100644 (file)
        "jumptonavigation": "अन्वेषण",
        "jumptosearch": "खोज्नुहोस्",
        "view-pool-error": "माफ गर्नुहोस् , यस समयमा सर्भरहरूमा कार्यभार उच्च रहेको छ ।\nअति धेरै प्रयोगकर्ताहरू यो पृष्ट हेर्ने प्रयास गरी रहनु भएको छ।\nकृपया यो पृष्ठ पुन: हेर्नु अगाडि केही समय पर्खिदिनुहोस् ।\n\n$1",
-       "generic-pool-error": "माफ à¤\97रà¥\8dनà¥\81हà¥\8bसà¥\8d , à¤¯à¤¸ à¤¸à¤®à¤¯à¤®à¤¾ à¤¸à¤°à¥\8dभरहरà¥\81मा कार्यभार उच्च रहेको छ।\nअति धेरै प्रयोगकर्ताहरू यो पृष्ट हेर्ने प्रयास गरी रहनु भएको छ।\nकृपया यो सामग्री  हेर्नु अगाडि केही समय पर्खिदिनुहोस् ।",
+       "generic-pool-error": "माफ à¤\97रà¥\8dनà¥\81हà¥\8bसà¥\8d , à¤¯à¤¸ à¤¸à¤®à¤¯à¤®à¤¾ à¤¸à¤°à¥\8dभरहरà¥\82मा कार्यभार उच्च रहेको छ।\nअति धेरै प्रयोगकर्ताहरू यो पृष्ट हेर्ने प्रयास गरी रहनु भएको छ।\nकृपया यो सामग्री  हेर्नु अगाडि केही समय पर्खिदिनुहोस् ।",
        "pool-timeout": "समय सकियो बन्द गर्ने प्रतीक्षामा",
        "pool-queuefull": "प्रतीक्षा पङ्क्ति भरियो",
        "pool-errorunknown": "अज्ञात त्रुटि",
        "passwordremindertext": "कसैले (सायद तपाईं, IP ठेगाना $1 बाट), {{SITENAME}}($4) को लागि नयाँ प्रवेशशब्द अनुरोध गर्नुभएको छ । प्रयोगकर्ता \"$2\" को लागि नयाँ अस्थायी प्रवेशशब्द \"$3\"तयार पारिएको छ । यदि यो तपाईंको इच्छामा भएको भए अहिले तपाईँले प्रवेशगरी नयाँ प्रवेशशब्द छान्नु पर्ने हुन्छ ।\nतपाईंको अस्थायी प्रवेशशब्द  {{PLURAL:$5|एक दिन|$5 दिनहरू पछि}} अमान्य हुनेछ ।\n\nयदि कोही अरुले नै अनुरोध गरेको हो भने , या तपाईंले आफ्नो प्रवेशशब्द सम्झिनु भयो भने, अथवा\nत्यसलाई परिवर्तन गर्न चाहनुहुन्न भने, तपाईंले यो सन्देशको वेवास्ता गर्नसक्नुहुन्छ र पुरानै प्रवेशशब्द प्रयोग गरिरहन सक्नुहुन्छ ।",
        "noemail": "प्रयोगकर्ता  \"$1\"को लागि कुनै पनि इ-मेल दर्ता गरिएको छैन ।",
        "noemailcreate": "तपाईंले सही ई-मेल ठेगाना दिनुपर्छ",
-       "passwordsent": "\"$1\" को लागि दर्ता गरिएको ई-मेल ठेगानामा एक प्रवेशशव्द पठाइएको छ।\nकृपया त्यसलाई प्राप्त गरेपछि प्रवेश गर्नुहोला ।",
+       "passwordsent": "\"$1\" को लागि दर्ता गरिएको ई-मेल ठेगानामा एक प्रवेश शब्द पठाइएको छ।\nकृपया त्यसलाई प्राप्त गरेपछि प्रवेश गर्नुहोला ।",
        "blocked-mailpassword": "तपाईंको IP ठेगानालाई सम्पादनगर्नबाट रोक लगाइएको छ, र त्यसैले दुरुपयोग रोक्नको लागि प्रवेसशब्द पुनर्लाभ प्रक्रिया प्रयोग गर्न अनुमति छैन ।",
        "eauthentsent": "दिइएको इमेल ठेगानामा इमेल पठाइएको छ ।\nतपाईंको खातामा अरु इमेल पठउनु अघि , इमेलमा लेखिएको मार्गदर्शन अनुसार , त्यो खाता तपाईंकै हो भनेर निश्चित गर्नु पर्नेछ ।",
        "throttled-mailpassword": "बितेको {{PLURAL:$1|घण्टा|$1 घण्टाहरु}} भित्र एउटा पासवर्ड अनुस्मारक पठाई सकिएको छ।\nदुरुपयोगबाट बचाउकोलागि प्रत्येक {{PLURAL:$1|घण्टा|$1 घण्टाहरु}}मा केवल एउटा पासवर्ड अनुस्मारक पठाइन्छ।",
        "passwordreset-domain": "डोमेन",
        "passwordreset-email": "इमेल ठेगाना:",
        "passwordreset-emailtitle": "{{SITENAME}}मा खाता विवरण",
-       "passwordreset-emailtext-ip": "à¤\95सà¥\88लà¥\87 (सायद à¤¤à¤ªà¤¾à¤\88à¤\82लà¥\87, $1 à¤\86à¤\88पि à¤ à¥\87à¤\97ानाबाà¤\9f) {{SITENAME}} ($4)मा à¤¤à¤ªà¤¾à¤\88à¤\82à¤\95à¥\8b à¤\96ाता à¤µà¤¿à¤µà¤°à¤£à¤\95à¥\8b à¤¨à¤¿à¤®à¥\8dति à¤\8fà¤\89à¤\9fा à¤\85नà¥\81सà¥\8dमारà¤\95à¤\95à¥\8b à¤\85नà¥\81रà¥\8bध à¤\97रà¥\87à¤\95à¥\8b à¤\9b। à¤¨à¤¿à¤®à¥\8dन à¤ªà¥\8dरयà¥\8bà¤\97à¤\95रà¥\8dता {{PLURAL:$3|à¤\96ाता à¤¯à¤¸ à¤\87मà¥\87ल à¤ à¥\87à¤\97ानासित à¤¸à¤®à¥\8dबनà¥\8dधित à¤\9b|à¤\96ाताहरà¥\82 à¤¯à¤¸ à¤\87मà¥\87ल à¤ à¥\87à¤\97ानासित à¤¸à¤®à¥\8dबनà¥\8dधित à¤\9bनà¥\8d}}:\n\n$2\n\n{{PLURAL:$3|यà¥\8b à¤\85सà¥\8dथाà¤\88 à¤ªà¤¾à¤¸à¤µà¤°à¥\8dडà¤\95à¥\8b|यà¥\80 à¤\85सà¥\8dथाà¤\88 à¤ªà¤¾à¤¸à¤µà¤°à¥\8dडहरà¥\81को}} समय {{PLURAL:$5|एक दिन|$5 दिन}}मा सकिनेछ।\nतपाईंले प्रवेश गरेर अहिले नैं नयाँ पासवर्ड छान्नुहोस्। यदि अरु कसैले अनुरोध गरेको भए अथवा यदि तपाईंलाई मूल पासवर्ड याद भए अनि यसलाई परिवर्तन गर्न चाहनुहुन्न भने, तपाईंले यस सन्देशलाई अनदेखा गर्नुहोस् र पुरानै पासवर्डलाई चालू राख्नुहोस्।",
+       "passwordreset-emailtext-ip": "à¤\95सà¥\88लà¥\87 (सायद à¤¤à¤ªà¤¾à¤\88à¤\82लà¥\87, $1 à¤\86à¤\88पि à¤ à¥\87à¤\97ानाबाà¤\9f) {{SITENAME}} ($4)मा à¤¤à¤ªà¤¾à¤\88à¤\82à¤\95à¥\8b à¤\96ाता à¤µà¤¿à¤µà¤°à¤£à¤\95à¥\8b à¤¨à¤¿à¤®à¥\8dति à¤\8fà¤\89à¤\9fा à¤\85नà¥\81सà¥\8dमारà¤\95à¤\95à¥\8b à¤\85नà¥\81रà¥\8bध à¤\97रà¥\87à¤\95à¥\8b à¤\9b। à¤¨à¤¿à¤®à¥\8dन à¤ªà¥\8dरयà¥\8bà¤\97à¤\95रà¥\8dता {{PLURAL:$3|à¤\96ाता à¤¯à¤¸ à¤\87मà¥\87ल à¤ à¥\87à¤\97ानासित à¤¸à¤®à¥\8dबनà¥\8dधित à¤\9b|à¤\96ाताहरà¥\82 à¤¯à¤¸ à¤\87मà¥\87ल à¤ à¥\87à¤\97ानासित à¤¸à¤®à¥\8dबनà¥\8dधित à¤\9bनà¥\8d}}:\n\n$2\n\n{{PLURAL:$3|यà¥\8b à¤\85सà¥\8dथाà¤\88 à¤ªà¤¾à¤¸à¤µà¤°à¥\8dडà¤\95à¥\8b|यà¥\80 à¤\85सà¥\8dथाà¤\88 à¤ªà¤¾à¤¸à¤µà¤°à¥\8dडहरà¥\82को}} समय {{PLURAL:$5|एक दिन|$5 दिन}}मा सकिनेछ।\nतपाईंले प्रवेश गरेर अहिले नैं नयाँ पासवर्ड छान्नुहोस्। यदि अरु कसैले अनुरोध गरेको भए अथवा यदि तपाईंलाई मूल पासवर्ड याद भए अनि यसलाई परिवर्तन गर्न चाहनुहुन्न भने, तपाईंले यस सन्देशलाई अनदेखा गर्नुहोस् र पुरानै पासवर्डलाई चालू राख्नुहोस्।",
        "passwordreset-emailtext-user": "{{SITENAME}} को $1 प्रयोगकर्ताले  {{SITENAME}} ($4)को लागि खाता विवरणको निम्ति एउटा अनुस्मारकको अनुरोध गरेको छ । निम्न प्रयोगकर्ता {{PLURAL:$3|खाता यस इमेल ठेगानासित सम्बन्धित छ|खाताहरू यस इमेल ठेगानासित सम्बन्धित छन् ।}}:\n\n$2\n\n{{PLURAL:$3|यो अस्थाई पासवर्डको|यी अस्थाई पासवर्डहरूको}} समय {{PLURAL:$5|एक दिन|$5 दिन}}मा सकिनेछ ।\nतपाईंले प्रवेश गरेर अहिले नैं नयाँ पासवर्ड छान्नुहोस्। यदि अरु कसैले अनुरोध गरेको भए अथवा यदि तपाईंलाई मूल पासवर्ड याद भए अनि यसलाई परिवर्तन गर्न चाहनुहुन्न भने, तपाईंले यस सन्देशलाई अनदेखा गर्नुहोस् र पुरानै पासवर्डलाई चालू राख्नुहोस् ।",
        "passwordreset-emailelement": "प्रयोगकर्ताको नाम: \n$1\n\nअस्थाई पासवर्ड: \n$2",
        "passwordreset-emailsentemail": "पासवर्ड परिवर्तनको लागि इमेल पठाइएको छ।",
        "changeemail-submit": "इमेल परिवर्तन गर्ने",
        "changeemail-throttled": "तपाईंले भर्खरै धेरै पल्ट प्रवेशको निम्ति प्रयास गर्नुभएको छ।\nकृपया $1 पर्खेर मात्र प्रयास गर्नुहोस्।",
        "resettokens": "टोकन पूर्वरुपमा फर्काउने",
-       "resettokens-text": "जुन टोकन तपाईंको खातासँग सम्बद्ध केहि विशिष्ट व्यक्तिगत जानकारी प्रदान गर्छन, तपाईं त्यसलाई यहाँ रिसेट गर्न सक्नुहुन्छ।\n\nयदि तपाईंले तिनलाई भुलवस कसैलाई देखाईदिनु भएको छ वा तपाईंको खाता ह्याक भइसकेको छ भने तपाईं यसलाई रिसेट गर्नुहोला।",
+       "resettokens-text": "जुन टोकनले तपाईंको खातासँग सम्बद्ध केहि विशिष्ट व्यक्तिगत जानकारी प्रदान गर्छन्, तपाईं त्यसलाई यहाँ रिसेट गर्न सक्नुहुन्छ।\n\nयदि तपाईंले तिनलाई भुलवस कसैलाई देखाउनु भएको छ वा तपाईंको खाता ह्याक भइसकेको छ भने तपाईं यसलाई रिसेट गर्नुहोला।",
        "resettokens-no-tokens": "पूर्वरुपमा फर्काउन कुनै पनि टोकन छैन ।",
        "resettokens-tokens": "टोकनहरू:",
        "resettokens-token-label": "$1 (वर्तमान मूल्यः $2)",
        "continue-editing": "सम्पादन क्षेत्रमा जानुहोस",
        "previewconflict": "यस पूर्वावलोकनले सम्पादन क्षेत्र को माथिल्लो भागको पाठ परिवर्तन गर्ने ठाउँको पाठलाइ देखाउँछ अनि तपाईंले यसलाई सेभ गरेपछि देखापर्छ।",
        "session_fail_preview": "'''माफ गर्नुहोस्! सत्र-आँकड़ा (session data) हराउनाले हामीले तपाईंको सम्पादन प्रक्रिया अघि बढाउन सकेनौं।.'''\nकृपया पुनः प्रयास गर्नुहोस्।\nयदि फेरि पनि काम भएन भनें, [[Special:UserLogout|बाहिर गई(लग आउट गरी)]]  फेरि प्रवेश गर्नुहोस्।",
-       "session_fail_preview_html": "माफ à¤\97रà¥\8dनà¥\81हà¥\8bला ! à¤¸à¥\87शन à¤¡à¤¾à¤\9fा à¤¨à¤·à¥\8dà¤\9f à¤­à¤\8fà¤\95à¥\8b à¤\95ारण à¤¤à¤ªà¤¾à¤\88à¤\82à¤\95à¥\8b à¤ªà¤°à¤¿à¤µà¤°à¥\8dतन à¤¶à¥\81रà¤\95à¥\8dषित à¤\97रà¥\8dन à¤¸à¤\95िà¤\8fन à¥¤\n\n<em>à¤\95िनà¤\95à¥\80 {{SITENAME}}मा raw HTML à¤¸à¤\95à¥\8dषम à¤\9b, à¤\9cावासà¥\8dà¤\95à¥\8dरिपà¥\8dà¤\9f à¤¹à¤®à¤¹à¤°à¥\82बाà¤\9f à¤¬à¤\9aाà¤\89नà¤\95à¥\8b à¤²à¤¾à¤\97ि à¤\9dलà¤\95 à¤¨à¤¹à¥\80à¤\82 à¤¦à¥\87à¤\96ाà¤\87à¤\8fà¤\95à¥\8b à¤\9bà¥\88न à¥¤</em>\n\n<strong>यदà¥\80 à¤¯à¥\8b à¤¤à¤ªà¤¾à¤\88à¤\82à¤\95à¥\8b à¤µà¥\88ध à¤¸à¤®à¥\8dपादन à¤¯à¤¤à¥\8dन à¤¥à¤¿à¤¯à¥\8b à¤­à¤¨à¥\87 à¤\95à¥\83पया à¤ªà¥\81नà¤\83 à¤ªà¥\8dरयास à¤\97रà¥\8dनà¥\81हà¥\8bसà¥\8d à¥¤</strong>\nयदà¥\80 à¤¯à¤¸ पनि यस्तै भयो भने कृपया [[Special:UserLogout|लग आउट]] गरेर पुनः लग इन गर्नुहोस् तथा तपाईंको ब्राउजरले यस साइटसँग कुकीजको अनुमति दिन्छ दिन्न जाँच गर्नुहोस् ।",
+       "session_fail_preview_html": "माफ à¤\97रà¥\8dनà¥\81हà¥\8bला ! à¤¸à¥\87शन à¤¡à¤¾à¤\9fा à¤¨à¤·à¥\8dà¤\9f à¤­à¤\8fà¤\95à¥\8b à¤\95ारण à¤¤à¤ªà¤¾à¤\88à¤\82à¤\95à¥\8b à¤ªà¤°à¤¿à¤µà¤°à¥\8dतन à¤¶à¥\81रà¤\95à¥\8dषित à¤\97रà¥\8dन à¤¸à¤\95िà¤\8fन à¥¤\n\n<em>à¤\95िनà¤\95à¥\80 {{SITENAME}}मा raw HTML à¤¸à¤\95à¥\8dषम à¤\9b, à¤\9cावासà¥\8dà¤\95à¥\8dरिपà¥\8dà¤\9f à¤¹à¤®à¤²à¤¾à¤¹à¤°à¥\82बाà¤\9f à¤¬à¤\9aाà¤\89नà¤\95à¥\8b à¤²à¤¾à¤\97ि à¤\9dलà¤\95 à¤¦à¥\87à¤\96ाà¤\87à¤\8fà¤\95à¥\8b à¤\9bà¥\88न à¥¤</em>\n\n<strong>यदà¥\80 à¤¯à¥\8b à¤¤à¤ªà¤¾à¤\88à¤\82à¤\95à¥\8b à¤µà¥\88ध à¤¸à¤®à¥\8dपादन à¤¯à¤¤à¥\8dन à¤¥à¤¿à¤¯à¥\8b à¤­à¤¨à¥\87 à¤\95à¥\83पया à¤ªà¥\81नà¤\83 à¤ªà¥\8dरयास à¤\97रà¥\8dनà¥\81हà¥\8bसà¥\8d à¥¤</strong>\nयदà¥\80 à¤«à¥\87रà¥\80 पनि यस्तै भयो भने कृपया [[Special:UserLogout|लग आउट]] गरेर पुनः लग इन गर्नुहोस् तथा तपाईंको ब्राउजरले यस साइटसँग कुकीजको अनुमति दिन्छ दिन्न जाँच गर्नुहोस् ।",
        "token_suffix_mismatch": "'''सम्पादन टोकनमा विराम चिह्न र वर्ण सम्बन्धित गड़बड़ीको कारण तपाईंको सम्पादन अस्वीकार गरिएको छ'''\nपृष्ठको पाठ बचाउन सम्पादन अस्वीकार गरिएको हो।\nयस्तो त्यसबेला हुन्छ जब तपाईंले बगी वेवमा आधारित अज्ञात प्रोक्सी सेवा प्रयोग गर्नुहुन्छ।",
        "edit_form_incomplete": "'''सम्पादनको केहि भाग सर्वरसम्म पुग्न सकेन, दुइपल्ट जाँच गर्नुहोस्, तपाईंको सम्पादन यथावत रहे पुनः प्रयास गर्नुहोस्'''",
        "editing": "$1 सम्पादन गरिदै",
        "editingsection": "$1 (खण्ड) सम्पादन गरिदै",
        "editingcomment": "$1 सम्पादन गर्दै(नयाँ खण्ड)",
        "editconflict": "सम्पादन बाँझियो: $1",
-       "explainconflict": "तपाईंले सम्पादन कार्य सुरु गरेपछि कसैले यस पृष्टलाई परिवर्तन गरेकोछ।\nमाथिल्लो पाठक्षेत्रमा पृष्ठको वर्तमान पाठ छ।\nतपाईंको परिवर्तन तल्लो भागमा दर्शाइएकोछ। \nतपाईंले गर्नुभएको परिवर्तनलाई वर्तमान पाठसित मिसाउनु पर्नेछ, यदि तपाईंले \"$1\" थिच्नु भयो भनें पाठको माथिल्लो भाग '''मात्र''' संग्रह गरिनेछ।",
+       "explainconflict": "तपाईंले सम्पादन कार्य सुरु गरेपछि कसैले यस पृष्टलाई परिवर्तन गरेकोछ।\nमाथिल्लो पाठक्षेत्रमा पृष्ठको वर्तमान पाठ छ।\nतपाईंको परिवर्तन तल्लो भागमा दर्शाइएकोछ। \nतपाईंले गर्नुभएको परिवर्तनलाई वर्तमान पाठसित मिसाउनु पर्नेछ, यदि तपाईंले \"$1\" थिच्नु भयो भने पाठको माथिल्लो भाग '''मात्र''' सङ्ग्रह गरिनेछ।",
        "yourtext": "तपाईंका पाठहरु",
        "storedversion": "संग्रहित पुनरावलोकन",
        "nonunicodebrowser": "<strong>चेतावनी: तपाईंको ब्राउजर युनिकोडलाई स्वीकार गर्दैन।</strong> \nतपाईंद्वारा सहि रुपले पृष्ठ सम्पादनको लागि: गैर-एयससिआइआइ क्यारेक्टर हेक्जाडेसिमल कोड (hexadecimal) मा देखाइनेछ।",
        "page_first": "पहिलो",
        "page_last": "अन्तिम",
        "histlegend": "अन्तर चयन:संशोधनहरूको तुलनाको लागि रेडियो बाकसमा क्लिक गरेर इण्टर गर्नुहोस् अथवा तल दिएको बटनमा थिच्नुहोस् <br />\nलिजेंड: (चालू): '''({{int:cur}})''' = अवतरणको बीचमा अन्तर, '''({{int:last}})''' = पहिलाका अवतरणको बीचमा अन्तर, '''{{int:minoreditletter}}''' = सानो परिवर्तन।",
-       "history-fieldset-title": "à¤\87तिहासà¤\95à¥\8b à¤µà¤¿à¤\9aरण à¤\97रà¥\8dनà¥\87",
+       "history-fieldset-title": "सà¤\82शà¥\8bधनà¤\95ा à¤²à¤¾à¤\97ि à¤\96à¥\8bà¤\9cà¥\80 à¤\97रà¥\8dनà¥\81हà¥\8bसà¥\8d",
        "history-show-deleted": "मेटिएका मात्र",
        "histfirst": "पुरानो",
        "histlast": "नयाँ",
        "rev-deleted-user-contribs": "[प्रयोगकर्ताको नाम अथवा IP ठेगाना हटाइयो - योगदानहरुबाट सम्पादन लुकाइयो]",
        "rev-deleted-text-permission": "यस पृष्ठको पुनरावलोकन '''मेटिएकोछ'''।\nयसको पूर्ण विवरण [{{fullurl:{{#Special:Log}}/delete|पृष्ठ={{FULLPAGENAMEE}}}}को मेटिएको लगमा पाउन सकिन्छ]।",
        "rev-suppressed-text-permission": "यो पृष्ठ संशोधनलाई <strong>दमन</strong> गरिएको छ । \nविस्तृत जानकारी [{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGENAMEE}}}} दमन लग]मा पाउन सकिन्छ ।",
-       "rev-deleted-text-unhide": "यस पृष्ठको संशोधन '''मेटिएकोछ'''।\nयसको पूर्ण विवरण [{{fullurl:{{#Special:Log}}/delete|पृष्ठ={{FULLPAGENAMEE}}}} को मेटिएको लगमा पाउन सकिन्छ].\nयदि चाहनु भयो भने [$1 संशोधन हेर्न] सक्नुहुन्छ।",
+       "rev-deleted-text-unhide": "यस पृष्ठको संशोधन '''मेटिएकोछ'''।\nयसको पूर्ण विवरण [{{fullurl:{{#Special:Log}}/delete|पृष्ठ={{FULLPAGENAMEE}}}} को मेटिएको लगमा पाउन सकिन्छ].\nयदि चाहनु भयो भने [$1 संशोधन हेर्न] सक्नुहुन्छ।",
        "rev-suppressed-text-unhide": "यस पृष्ठको पुनरावलोकन '''दमन''' गरिएको छ ।\nविस्तृत जानकारी [{{fullurl:{{#Special:Log}}/delete|पृष्ठ={{FULLPAGENAMEE}}}} दमन लग] पाउन सकिन्छ ।\nयदि तपाईं अगाडि बढ्न चाहनु हुन्छ भने पनि तपाईंले  [$1 यि संशोधनहरू हेर्न] पाउनु हुनेछ ।",
        "rev-deleted-text-view": "यस पृष्ठको संशोधन '''मेटिएकोछ'''।\nतपाईंले हेर्न सक्नुहुन्छ; [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} मेटिएको लगमा विवरण पाउन सकिन्छ]।",
        "rev-suppressed-text-view": "यस पृष्ठको पुनरावलोकन <strong>थिचिएको छ</strong>।\nप्रबन्धकको हैसियतले हेर्न सक्नुहुन्छ; [{{fullurl:{{#Special:Log}}/delete|पृष्ठ={{FULLPAGENAMEE}}}}को थिचिएको लगमा विवरण पाउन सकिन्छ]",
        "rev-suppressed-no-diff": "तपाईं यसको भिन्नता हेर्न सक्नुहुन्न किनभने यसको एउटा संशोधन <strong>मेटाइएको</strong>छ।",
        "rev-deleted-unhide-diff": "यस पृष्ठका पुनरावलोकनहरू मध्ये एउटा भिन्नता <strong>मेटाइएकोछ</strong>।\nयसको पूर्ण विवरण [{{fullurl:{{#Special:Log}}/delete|पृष्ठ={{FULLPAGENAMEE}}}}को मेटाइएको लगमा पाउन सकिन्छ]।\nयदि चाहनु भयो भने प्रवन्धकको हैसियतले [यो भिन्नता $1] हेर्न सक्नुहुन्छ।",
        "rev-suppressed-unhide-diff": "यस पृष्ठको पुनरावलोकनहरू मध्ये एउटा भिन्नता <strong>थिचिएको छ</strong>।\nयसको पूर्ण विवरण [{{fullurl:{{#Special:Log}}/suppress|पृष्ठ={{FULLPAGENAMEE}}}}को थिचिएको लगमा पाउन सकिन्छ]।\nयदि चाहनु भयो भने प्रबन्धकको हैसियतमा [यो भिन्नता $1] हेर्न सक्नुहुन्छ।",
-       "rev-deleted-diff-view": "यस à¤­à¤¿à¤¨à¥\8dनताà¤\95ा à¤¸à¤\82शà¥\8bधनहरà¥\81मध्येको एउटा चाहिं <strong>मेटियो।<strong> \nतपाईंले यस भिन्नतालाई हेर्न सक्नुहुन्छ; सबै विवरण  [{{fullurl:{{#Special:Log}}/delete|पृष्ठ={{FULLPAGENAMEE}}}} मेटाइएको लग]मा पाउन सकिनेछ।",
-       "rev-suppressed-diff-view": "यस à¤­à¤¿à¤¨à¥\8dनताà¤\95ा à¤¸à¤\82शà¥\8bधनहरà¥\81मध्येको एउटा चाहिं  <strong>दबाइयो।<strong> \nतपाईंले यस भिन्नतालाई हेर्न सक्नुहुन्छ; सबै विवरण  [{{fullurl:{{#Special:Log}}/delete|पृष्ठ={{FULLPAGENAMEE}}}} दबाइएको लग]मा पाउन सकिनेछ।",
+       "rev-deleted-diff-view": "यस à¤­à¤¿à¤¨à¥\8dनताà¤\95ा à¤¸à¤\82शà¥\8bधनहरà¥\82 मध्येको एउटा चाहिं <strong>मेटियो।<strong> \nतपाईंले यस भिन्नतालाई हेर्न सक्नुहुन्छ; सबै विवरण  [{{fullurl:{{#Special:Log}}/delete|पृष्ठ={{FULLPAGENAMEE}}}} मेटाइएको लग]मा पाउन सकिनेछ।",
+       "rev-suppressed-diff-view": "यस à¤­à¤¿à¤¨à¥\8dनताà¤\95ा à¤¸à¤\82शà¥\8bधनहरà¥\82 मध्येको एउटा चाहिं  <strong>दबाइयो।<strong> \nतपाईंले यस भिन्नतालाई हेर्न सक्नुहुन्छ; सबै विवरण  [{{fullurl:{{#Special:Log}}/delete|पृष्ठ={{FULLPAGENAMEE}}}} दबाइएको लग]मा पाउन सकिनेछ।",
        "rev-delundel": "दृश्यता परिवर्तन गर्ने",
        "rev-showdeleted": "देखाउनुहोस्",
        "revisiondelete": "मेटाउने/मेटाएको रद्दगर्ने  पुनरावलोकनहरू",
        "revdelete-edit-reasonlist": "मेट्ने कार्यहरु सम्पादन गर्ने",
        "revdelete-offender": "संशोधन कर्ता:",
        "suppressionlog": "कमगरेको लग",
-       "suppressionlogtext": "मà¥\87à¤\9fà¥\8dन à¤° à¤°à¥\8bà¤\95à¥\8dनà¤\95ा à¤¨à¤¿à¤®à¤¿à¤¤à¥\8dत à¤¨à¤¿à¤®à¥\8dन à¤¸à¥\81à¤\9aà¥\80 à¤°à¤¹à¥\87à¤\95à¥\8b à¤\9b à¤\9cसमा à¤ªà¥\8dरवनà¥\8dधà¤\95बाà¤\9f à¤²à¥\81à¤\95ाà¤\87à¤\8fà¤\95ा à¤¸à¤¾à¤®à¤\97à¥\8dरà¥\80 à¤¸à¤®à¥\87त à¤°à¤¹à¥\87à¤\95ा à¤\9bन।\nà¤\95à¥\83पया à¤¹à¤¾à¤² à¤ªà¥\8dरयà¥\8bà¤\97मा à¤°à¤¹à¥\87à¤\95ा à¤°à¥\8bà¤\95 à¤° à¤°à¥\8bà¤\95ावà¤\9fà¤\95à¥\8b à¤¸à¥\81à¤\9aà¥\80à¤\95ा à¤²à¤¾à¤\97ि [[Special:BlockList|रà¥\8bà¤\95 à¤¸à¥\81ची]] हेर्नुहोला।",
+       "suppressionlogtext": "मà¥\87à¤\9fà¥\8dन à¤° à¤°à¥\8bà¤\95à¥\8dनà¤\95ा à¤¨à¤¿à¤®à¤¿à¤¤à¥\8dत à¤¨à¤¿à¤®à¥\8dन à¤¸à¥\82à¤\9aà¥\80 à¤°à¤¹à¥\87à¤\95à¥\8b à¤\9b à¤\9cसमा à¤ªà¥\8dरवनà¥\8dधà¤\95बाà¤\9f à¤²à¥\81à¤\95ाà¤\87à¤\8fà¤\95ा à¤¸à¤¾à¤®à¤\97à¥\8dरà¥\80 à¤¸à¤®à¥\87त à¤°à¤¹à¥\87à¤\95ा à¤\9bनà¥\8d।\nà¤\95à¥\83पया à¤¹à¤¾à¤² à¤ªà¥\8dरयà¥\8bà¤\97मा à¤°à¤¹à¥\87à¤\95ा à¤°à¥\8bà¤\95 à¤° à¤°à¥\8bà¤\95ावà¤\9fà¤\95à¥\8b à¤¸à¥\82à¤\9aà¥\80à¤\95ा à¤²à¤¾à¤\97ि [[Special:BlockList|रà¥\8bà¤\95 à¤¸à¥\82ची]] हेर्नुहोला।",
        "mergehistory": "पृष्ठ इतिहासहरु मिसाउने",
        "mergehistory-header": "यो पृष्ठ एक स्रोत पृष्ठको इतिहास कुनै अन्य पृष्ठमा मिलाउनको लागि हो।\nसुनिश्चित गर्नुस कि यो परिवर्तन पृष्ठ इतिहासमा निरन्तरता प्रदान गर्न सकोस।",
        "mergehistory-box": "दुई पृष्ठहरूको पुनरावलोकन जोड्नुहोस् :",
        "action-userrights-interwiki": "अरु विकिका प्रयोगकर्ताहरूको प्रयोगकर्ता अधिकारलाई सम्पादन गर्ने",
        "action-siteadmin": "डेटाबेस बन्दगर्ने वा खोल्ने",
        "action-sendemail": "इमेलहरु पठाउने",
-       "action-editmywatchlist": "तपाईंको निगरानी सूची सम्पादन गर्नुहोस",
+       "action-editmywatchlist": "तपाईंको निगरानी सूची सम्पादन गर्नुहोस",
        "action-viewmywatchlist": "तपाईंको निगरानी सूची हेर्नुहोस्",
        "action-viewmyprivateinfo": "तपाईंको व्यक्तिगत जानकारी हेर्नुहोस",
-       "action-editmyprivateinfo": "तपाईंको व्यक्तिगत जानकारी सम्पादन गर्नुहोस",
+       "action-editmyprivateinfo": "तपाईंको व्यक्तिगत जानकारी सम्पादन गर्नुहोस",
        "action-editcontentmodel": "पृष्ठको सामग्री नमुना सम्पादन",
        "action-managechangetags": "डाटाबेसबाट ट्यागहरू बनाउने र मेटाउने",
        "action-applychangetags": "तपाईंको परिवर्तनसँगै ट्यागहरू लागु गर्ने",
        "rcshowhidemine-hide": "लुकाउनुहोस्",
        "rcshowhidecategorization-show": "देखाउनुहोस्",
        "rcshowhidecategorization-hide": "लुकाउनुहोस्",
-       "rclinks": "पछिल्ला $1 परिवर्तनहरू पछिल्ला $2 दिनहरूमा",
+       "rclinks": "पछिल्ला $2 दिनहरूमा भएका पछिल्ला $1 परिवर्तनहरू देखाउनुहोस्",
        "diff": "भिन्न",
        "hist": "इतिहास",
        "hide": "लुकाउनुहोस्",
        "badfilename": "फाइलको नाम \"$1\"मा सारियो।",
        "filetype-mime-mismatch": "\".$1\" फाइल विस्तार  पाइएको फाइल ($2)को MIME प्रकारसित मेल खाँदैन।",
        "filetype-badmime": "MIME \"$1\" प्रकारको फाइल उर्ध्वभरण गर्ने अनुमति छैन।",
-       "filetype-bad-ie-mime": "यो फाइल उर्ध्वभरण गर्न सकिएन किनभनें '''इण्टरनेट एक्स्प्लोरर'''ले यस फाइललाई \"$1\" बतायो जसलाई संभावित खतरनाक प्रकारको फाइल मानियो।",
+       "filetype-bad-ie-mime": "यो फाइल उर्ध्वभरण गर्न सकिएन किन भने '''इण्टरनेट एक्स्प्लोरर'''ले यस फाइललाई \"$1\" बतायो जसलाई सम्भावित खतरनाक प्रकारको फाइल मानियो।",
        "filetype-unwanted-type": "<strong>\".$1\"</strong> फाइल नचाहिने प्रकारको फाइल हो।\nमुख्यतया {{PLURAL:$3|फाइलको प्रकार हो|फाइलका प्रकार हुन्}} $2।",
        "filetype-banned-type": "<strong>\".$1\"</strong> फाइल {{PLURAL:$4|प्रकार|प्रकारहरू}} को अनुमति छैन।\nफाइल प्रकार {{PLURAL:$3|जसको|जुनको}} अनुमति छ: $2।",
        "filetype-missing": "फाइलको एक्स्टेन्शन छैन (उदा- \".jpg\")।",
        "randompage-nopages": "{{PLURAL:$2| $1 नाम भएको कुनै पृष्ट छैन|$1 नाम भएका कुनै पृष्टहरु छैनन्}}",
        "randomincategory": "श्रेणीमा रहेको अनियमित पृष्ठ",
        "randomincategory-invalidcategory": "''$1'' वैध श्रेणी नाम होइन ।",
-       "randomincategory-nopages": "यस [[:Category:$1|$1]] श्रेणीमा कुनै पनि पृष्ठ छैन ।",
+       "randomincategory-nopages": "यस [[:Category:$1|$1]] श्रेणीमा कुनै पनि पृष्ठ छैन ।",
        "randomincategory-category": "श्रेणी:",
        "randomincategory-legend": "श्रेणीमा अनियमित पृष्ठ",
        "randomincategory-submit": "जाउ",
        "statistics-header-pages": "पृष्ठहरूको तथ्याङ्क",
        "statistics-header-edits": "सम्पादनहरूको तथ्याङ्क",
        "statistics-header-users": "प्रयोगकर्ता तथ्याङ्कहरू",
-       "statistics-header-hooks": "à¤\85नà¥\8dय à¤¤à¤¥à¥\8dयाà¤\99à¥\8dà¤\95हरà¥\81",
+       "statistics-header-hooks": "à¤\85नà¥\8dय à¤¤à¤¥à¥\8dयाà¤\99à¥\8dà¤\95हरà¥\82",
        "statistics-articles": "सामग्री पृष्ठहरू",
        "statistics-pages": "पृष्ठहरू",
        "statistics-pages-desc": "विकिका सबै पृष्ठहरू, वार्तापका पृष्ठहरूसमेत, रिडाइरेक्ट, इत्यादि ।",
        "booksources-text": "तल दिइएको सूची नयाँ तथा पूराना किताब बेच्ने लगायत तपाईंले खोज्नु भएको किताबका बारेमा थप जानकारी भएका अन्य साइटका लिंकहरू हुन् ।",
        "booksources-invalid-isbn": "यो आइएसबीएन सहि छैन; मूल स्रोतबाट नक्कल गर्दा भएको त्रुटिको जाँच गर्नुहोस।",
        "specialloguserlabel": "निष्पादक:",
-       "speciallogtitlelabel": "लक्ष्य (शीर्षक वा प्रयोगकर्ता)",
+       "speciallogtitlelabel": "लक्ष्य (शीर्षक वा {{ns:user}}:प्रयोगकर्ताका लागि प्रयोगकर्ता नाम)",
        "log": "लगहरू",
        "logeventslist-submit": "देखाउनुहोस्",
        "all-logs-page": "सबै सार्वजनिक लगहरू",
        "revertpage-nouser": "(सदस्य नाम हटाइएको छ) को सम्पादनहरूलाई हटाएर {{GENDER:$1|[[User:$1|$1]]}} ले अन्तिम अवतरणमा पूर्ववत गर्यो।",
        "rollback-success": "$1द्वारा उल्टाइएका सम्पादनहरू;\nपछिल्लो संशोधनमा $2द्वारा परिवर्तन गरि पुनः फर्काइएको।",
        "sessionfailure-title": "सत्र त्रुटी",
-       "sessionfailure": "यसà¥\8dतà¥\8b à¤²à¤¾à¤\97दà¥\88à¤\9b à¤\95ि à¤¤à¤ªà¤¾à¤\88à¤\82à¤\95à¥\8b à¤²à¤\97à¤\87न à¤¸à¤¤à¥\8dरसà¤\81à¤\97 à¤\95à¥\81नà¥\88 à¤¸à¤®à¤¸à¥\8dया à¤\9b। à¤¸à¤¤à¥\8dर à¤\85पहरणबाà¤\9f à¤¬à¤\9aाà¤\89न à¤\95à¥\8b à¤²à¤¾à¤\97ि à¤¸à¤¾à¤µà¤§à¤¾à¤¨à¥\80à¤\95à¥\8b à¤°à¥\82पमा à¤¤à¤ªà¤¾à¤\88à¤\82à¤\95à¥\8b à¤¯à¥\8b à¤\95à¥\8dरियाà¤\95लाप à¤°à¤¦à¥\8dद à¤\97रिà¤\8fà¤\95à¥\8b à¤\9b। à¤\95à¥\83पया à¤ªà¤\9bाडà¥\80 à¤\9cानà¥\81हà¥\8bस à¤° à¤ªà¥\83षà¥\8dठलाà¤\88 à¤ªà¥\81नà¤\83 à¤²à¥\8bड à¤\97रà¥\8dनà¥\81हà¥\8bस, अनि फेरी प्रयास गर्नुहोला।",
+       "sessionfailure": "यसà¥\8dतà¥\8b à¤²à¤¾à¤\97à¥\8dदà¥\88à¤\9b à¤\95ि à¤¤à¤ªà¤¾à¤\88à¤\82à¤\95à¥\8b à¤²à¤\97à¤\87न à¤¸à¤¤à¥\8dरसà¤\81à¤\97 à¤\95à¥\81नà¥\88 à¤¸à¤®à¤¸à¥\8dया à¤\9b। à¤¸à¤¤à¥\8dर à¤\85पहरणबाà¤\9f à¤¬à¤\9aाà¤\89न à¤\95à¥\8b à¤²à¤¾à¤\97ि à¤¸à¤¾à¤µà¤§à¤¾à¤¨à¥\80à¤\95à¥\8b à¤°à¥\82पमा à¤¤à¤ªà¤¾à¤\88à¤\82à¤\95à¥\8b à¤¯à¥\8b à¤\95à¥\8dरियाà¤\95लाप à¤°à¤¦à¥\8dद à¤\97रिà¤\8fà¤\95à¥\8b à¤\9b। à¤\95à¥\83पया à¤ªà¤\9bाडà¥\80 à¤\9cानà¥\81हà¥\8bस à¤° à¤ªà¥\83षà¥\8dठलाà¤\88 à¤ªà¥\81नà¤\83 à¤²à¥\8bड à¤\97रà¥\8dनà¥\81हà¥\8bसà¥\8d, अनि फेरी प्रयास गर्नुहोला।",
        "changecontentmodel-title-label": "पाना शीर्षक",
        "changecontentmodel-reason-label": "कारण:",
        "logentry-contentmodel-change-revertlink": "पहिलेको रुपमा फर्काउने",
        "ipbother": "अरु समय:",
        "ipboptions": "२ घण्टाहरू:2 hours,१ दिन :1 day,३ दिनहरू:3 days,१ हप्ता:1 week,२ हप्ताहरू:2 weeks,१ महिना:1 month,३ महिनाहरू:3 months,६ महिनाहरू:6 months,१ वर्ष:1 year,अनगिन्ती:infinite",
        "ipbhidename": "प्रयोगकर्ताको नाम सम्पादनबाट र सूचीबाट हटाउने",
-       "ipbwatchuser": "यो प्रयोगकर्ताको  प्रयपोगकर्ता र वार्तलाप पृष्ठ हेर्नुहोस्",
+       "ipbwatchuser": "यो प्रयोगकर्ताको प्रयपोगकर्ता पृष्ठ र वार्तालाप पृष्ठ हेर्नुहोस्",
        "ipb-disableusertalk": "यस प्रयोगकर्तालाई निषेधित समयमा आफ्नै वार्तालाप पृष्ठ सम्पादन गर्न नदिने",
        "ipb-change-block": "निम्म स्थितीमा प्रयोगकर्तालाई पुन: निषेध गर्ने",
        "ipb-confirm": "रोक सुनिश्चित गर्ने",
        "blocklist-reason": "कारण",
        "ipblocklist-submit": "खोज्ने",
        "ipblocklist-localblock": "स्थानीय रोक",
-       "ipblocklist-otherblocks": "à¤\85नà¥\8dय {{PLURAL:$1|रà¥\8bà¤\95|रà¥\8bà¤\95हरà¥\81}}",
+       "ipblocklist-otherblocks": "à¤\85नà¥\8dय {{PLURAL:$1|रà¥\8bà¤\95|रà¥\8bà¤\95हरà¥\82}}",
        "infiniteblock": "अनिश्चित काल",
        "expiringblock": "$1 को दिन  $2 मा सकिनेछ",
        "anononlyblock": "अज्ञातहरु मात्र",
        "blocklog-showsuppresslog": "यो प्रयोगकर्तालाई पहिला रोक लगाइएको र लुकेको थियो ।\nलु्काइएको लग सन्दर्भको निम्ति तल दिइन्छ:",
        "blocklogentry": " [[$1]]लाई $2 $3 समयसम्म को लागि निषेध गरिएको छ",
        "reblock-logentry": "$2 $3 मा सकिने गरि  [[$1]] को निषेध स्थिति परिवर्तन गरिएको छ ।",
-       "blocklogtext": "यà¥\8b à¤²à¤\97 à¤ªà¥\8dरयà¥\8bà¤\97à¤\95रà¥\8dताà¤\95à¥\8b à¤°à¥\8bà¤\95ावà¤\9f à¤° à¤«à¥\81à¤\95à¥\81वा à¤\95ारà¥\8dयहरà¥\81को हो।\nस्वतः रोकिएका आईपी ठेगानाहरू सूचीमा छैनन्।\nवर्तमानका चालू रोक र प्रतिबन्धहरूको सूचीकोलागि हेर्नुहोस् [[Special:BlockList|आईपी निषेध सूची]]।",
+       "blocklogtext": "यà¥\8b à¤²à¤\97 à¤ªà¥\8dरयà¥\8bà¤\97à¤\95रà¥\8dताà¤\95à¥\8b à¤°à¥\8bà¤\95ावà¤\9f à¤° à¤«à¥\81à¤\95à¥\81वा à¤\95ारà¥\8dयहरà¥\82को हो।\nस्वतः रोकिएका आईपी ठेगानाहरू सूचीमा छैनन्।\nवर्तमानका चालू रोक र प्रतिबन्धहरूको सूचीकोलागि हेर्नुहोस् [[Special:BlockList|आईपी निषेध सूची]]।",
        "unblocklogentry": "$1 लाई अनिषेधित गरियो",
        "block-log-flags-anononly": "अज्ञात प्रयोगकर्ताहरू मात्र",
        "block-log-flags-nocreate": "खाता खोल्न निस्क्रिय पारिएको",
        "ipb_hide_invalid": "यो खातालाई दबाउन सकिने छैन; किन कि यसका धेरै {{PLURAL:$1|एक सम्पादन|$1 सम्पादनहरू}} छन्।",
        "ipb_already_blocked": "\"$1\"लाई पहिले नै रोक लगाइएको छ",
        "ipb-needreblock": "$1लाई अघिबाट नैं प्रतिबन्ध लगाइएकोछ।\nके तपाईं यसको व्यवस्थालाई परिवर्तन गर्न चाहनुहुन्छ?",
-       "ipb-otherblocks-header": "à¤\85रà¥\81 {{PLURAL:$1|रà¥\8bà¤\95|रà¥\8bà¤\95हरà¥\81}}",
+       "ipb-otherblocks-header": "à¤\85रà¥\81 {{PLURAL:$1|रà¥\8bà¤\95|रà¥\8bà¤\95हरà¥\82}}",
        "unblock-hideuser": "यस प्रयोगकर्तालाई रोक फुकुवा गर्न सक्नु हुन्न, यस प्रयोगकर्ताको नाम लुकेको छ।",
        "ipb_cant_unblock": "त्रुटी: रोक आइडी $1 भेटिएन। या यो पहिले नै खोलिइसकेको हुनसक्छ ।",
        "ipb_blocked_as_range": "त्रुटी:  IP ठेगाना $1 is लाई सिधै रोकलगाइएको छैन र यस रोकलाई खोल्न मिल्दैन\nयो एक रेन्ज रोक $2, को अन्तर्गत रहेको छ जसलाई रोक खोल्न मिल्छ ।",
        "ipbnounblockself": "तपाईं आफैले आफैलाई रोक खुलाउन सक्नुहुन्न ।",
        "lockdb": "डेटाबेस ताल्चामार्ने",
        "unlockdb": "डेटाबेसको ताल्चा खोल्ने",
-       "lockdbtext": "डà¥\87à¤\9fाबà¥\87समा à¤¤à¤¾à¤²à¤¾ à¤²à¤\97ाà¤\89नालà¥\87 à¤¸à¤¬à¥\88 à¤ªà¥\8dरयà¥\8bà¤\97à¤\95रà¥\8dता à¤ªà¥\83षà¥\8dठ à¤¸à¤®à¥\8dपादन, à¤\86फà¥\8dनà¥\8b à¤\85भिरà¥\82à¤\9aà¥\80मा à¤ªà¤°à¤¿à¤µà¤°à¥\8dतन, à¤\86फà¥\8dनà¥\8b à¤§à¥\8dयानसà¥\82à¤\9aà¥\80मा à¤¸à¤®à¥\8dपादन, à¤° à¤\85नà¥\8dय à¤µà¤¸à¥\8dतà¥\81 à¤\9cसà¤\95à¥\8b à¤²à¤¾à¤\97ि à¤¡à¥\87à¤\9fाबà¥\87समा à¤ªà¤°à¤¿à¤µà¤°à¥\8dतन à¤\97रà¥\87à¤\82 हुन्छ, त्यसबाट वन्चित हुनेछ। कृपया यो सुनिश्चित गर्नुहोस् कि तपाईं यो गर्न चाहनुहुन्छ, र तपाईं रक्षण पश्चात ताला खोल्नुहुन्छ ।",
+       "lockdbtext": "डà¥\87à¤\9fाबà¥\87समा à¤¤à¤¾à¤²à¤¾ à¤²à¤\97ाà¤\89नालà¥\87 à¤¸à¤¬à¥\88 à¤ªà¥\8dरयà¥\8bà¤\97à¤\95रà¥\8dता à¤ªà¥\83षà¥\8dठ à¤¸à¤®à¥\8dपादन, à¤\86फà¥\8dनà¥\8b à¤\85भिरà¥\82à¤\9aà¥\80मा à¤ªà¤°à¤¿à¤µà¤°à¥\8dतन, à¤\86फà¥\8dनà¥\8b à¤§à¥\8dयानसà¥\82à¤\9aà¥\80मा à¤¸à¤®à¥\8dपादन, à¤° à¤\85नà¥\8dय à¤µà¤¸à¥\8dतà¥\81 à¤\9cसà¤\95à¥\8b à¤²à¤¾à¤\97ि à¤¡à¥\87à¤\9fाबà¥\87समा à¤ªà¤°à¤¿à¤µà¤°à¥\8dतन à¤\97रà¥\8dनà¥\81 à¤ªà¤°à¥\8dनà¥\87 हुन्छ, त्यसबाट वन्चित हुनेछ। कृपया यो सुनिश्चित गर्नुहोस् कि तपाईं यो गर्न चाहनुहुन्छ, र तपाईं रक्षण पश्चात ताला खोल्नुहुन्छ ।",
        "unlockdbtext": "डेटाबेसको ताला खोल्नका लागि सबै प्रयोगकर्ता पृष्ठ सम्पादन, आफ्नो अभिरूचीहरूमा परिवर्तन, आफ्नो ध्यानसूचीमा सम्पादन, र अन्य वस्तु जसको लागि डेटाबेसमा परिवर्तन गर्नु पर्छ, को सक्षमतालाई पुनर्स्थापित गर्नछ। कृपया यो सुनिश्चित गर्नुस कि तपाईं यो गर्न चाहनुहुन्छ।",
        "lockconfirm": "हो, म साँच्चिकै डेटाबेस थुन्न चाहन्छु।",
        "unlockconfirm": "हो , म साँच्चै  डेटाबेसको ताल्चा खोल्न चाहन्छु ।",
        "import-error-special": "पृष्ठ \"$1\" आयात गर्न सकिएन किनभने यो एउटा यस्तो विशेष नामस्थान अन्तर्गत आउँछ जसमा पृष्ठ बनाउन सकिंदैन।",
        "import-error-invalid": "पृष्ठ \"$1\" आयात गर्न सकिएन किनभने यसको आयात पश्चात जुन नाम हुन्थ्यो त्यो यस विकिमा मान्य छैन।",
        "import-error-unserialize": "पृष्ठ \"$1\" को संशोधन $2 लाई क्रमबाट हटाउन सकिएन। संशोधनको बारेमा भनिएको छ कि सामग्री नमूना $3 लाई क्रम $4 को रूप प्रयोगमा ल्याइएको थियो।",
-       "import-error-bad-location": "संशोधन $2 जसमा सामग्री नमूनाहरू $3 मा प्रयोग गरिएको छ, लाई यस विकिमा \"$1\" मा सङ्ग्रह गर्न सकिंदैन, किनकि त्यो नमूना यस पृष्ठको नमूनहरू भन्दा भिन्न छ।",
+       "import-error-bad-location": "सà¤\82शà¥\8bधन $2 à¤\9cसमा à¤¸à¤¾à¤®à¤\97à¥\8dरà¥\80 à¤¨à¤®à¥\82नाहरà¥\82 $3 à¤®à¤¾ à¤ªà¥\8dरयà¥\8bà¤\97 à¤\97रिà¤\8fà¤\95à¥\8b à¤\9b, à¤²à¤¾à¤\88 à¤¯à¤¸ à¤µà¤¿à¤\95िमा \"$1\" à¤®à¤¾ à¤¸à¤\99à¥\8dà¤\97à¥\8dरह à¤\97रà¥\8dन à¤¸à¤\95िà¤\82दà¥\88न, à¤\95िनà¤\95ि à¤¤à¥\8dयà¥\8b à¤¨à¤®à¥\82ना à¤¯à¤¸ à¤ªà¥\83षà¥\8dठà¤\95à¥\8b à¤¨à¤®à¥\82नाहरà¥\82 à¤­à¤¨à¥\8dदा à¤­à¤¿à¤¨à¥\8dन à¤\9b।",
        "import-options-wrong": "गलत {{PLURAL:$2|विकल्प|विकल्पहरू}}: <nowiki>$1</nowiki>",
        "import-rootpage-invalid": "दिइएको उपसर्ग पृष्ठ शीर्षक अमान्य छ।",
        "import-rootpage-nosubpage": "दिइएको उपसर्ग पृष्ठ \"$1\" को नामस्थानमा उप-पृष्ठ बनाउन सकिंदैन।",
        "tooltip-feed-rss": "यो पृष्ठको लागि RSS फिड",
        "tooltip-feed-atom": "यो पृष्ठको लागि एटम फिड",
        "tooltip-t-contributions": "{{GENDER:$1|यस प्रयोगकर्ता}}का योगदानहरूको सूची हेर्नुहोस्",
-       "tooltip-t-emailuser": "यो प्रयोगकर्तालाई इमेल पठाउनुहोस्",
+       "tooltip-t-emailuser": "{{GENDER:$1|यस प्रयोगकर्ता}}लाई इमेल पठाउनुहोस्",
        "tooltip-t-info": "यस पृष्ठको बारेमा थप जानकारी",
        "tooltip-t-upload": "फाइल अपलोड गर्ने",
        "tooltip-t-specialpages": "सबै विशेष पृष्ठहरूको सूची",
        "creditspage": "क्रेडिट पृष्ठ",
        "nocredits": "यो पृष्ठको लागि कुनै श्रेय उपलब्ध छैन ।",
        "spamprotectiontitle": "स्प्याम सुरक्षा फिल्टर",
-       "spamprotectiontext": "तपाà¤\88à¤\82लà¥\87 à¤\9cà¥\81न à¤ªà¤¨à¥\8dना à¤²à¤¾à¤\87 à¤¸à¥\87भ à¤\97रà¥\8dन à¤\9aाहनà¥\81हà¥\81नà¥\8dथà¥\8dयà¥\8b à¤¤à¥\8dयसलाà¤\88 à¤°à¤¦à¥\8dदà¥\80 à¤\9bननà¥\80 à¤\95ारà¥\8dयà¤\95à¥\8dरमलà¥\87 à¤°à¥\8bà¤\95 à¤²à¤\97ाà¤\8fà¤\95à¥\8b à¤\9b।\nयà¥\8b à¤¸à¤\82भवतà¤\83 à¤\95à¥\81नà¥\88 à¤\95रà¥\8dपसà¥\82à¤\9aित à¤¬à¤¾à¤¹à¤¿à¤°à¥\80 à¤¸à¥\8dथल à¤¸à¤\82à¤\97 à¤¸à¤®à¥\8dबनà¥\8dधित à¤\95डà¥\80 को कारणले भएको हुन सक्छ।",
+       "spamprotectiontext": "तपाà¤\88à¤\82लà¥\87 à¤\9cà¥\81न à¤ªà¥\83षà¥\8dठलाà¤\88 à¤¸à¥\87भ à¤\97रà¥\8dन à¤\9aाहनà¥\81हà¥\81नà¥\8dथà¥\8dयà¥\8b à¤¤à¥\8dयसलाà¤\88 à¤°à¤¦à¥\8dदà¥\80 à¤\9bननà¥\80 à¤\95ारà¥\8dयà¤\95à¥\8dरमलà¥\87 à¤°à¥\8bà¤\95 à¤²à¤\97ाà¤\8fà¤\95à¥\8b à¤\9b।\nयà¥\8b à¤¸à¤\82भवतà¤\83 à¤\95à¥\81नà¥\88 à¤\95रà¥\8dपसà¥\82à¤\9aित à¤¬à¤¾à¤¹à¤¿à¤°à¥\80 à¤¸à¥\8dथलसà¤\81à¤\97 à¤¸à¤®à¥\8dबनà¥\8dधित à¤²à¤¿à¤\99à¥\8dà¤\95को कारणले भएको हुन सक्छ।",
        "spamprotectionmatch": "निम्न पाठले हाम्रो स्प्प्याम फिल्टर : $1 घच्घच्यायो",
        "spambot_username": "MediaWiki स्पाम सर-सफाइ",
        "spam_reverting": "$1 मा कडीहरू  नभएका पुरानो अवतरणमा पुनर्स्थापित गर्दै",
        "confirmemail_loggedin": "तपाईंको इमेल ठेगाना प्रमाणित भएको छ।",
        "confirmemail_subject": "{{SITENAME}} ई मेलl ठेगानाको पुष्टि",
        "confirmemail_body": "कसैले, सायद तपाईंले, आई पी ठेगाना $1बाट,\n{{SITENAME}}मा एउटा  खाता  \"$2\"को नाममा यस ई मेल ठेगानामा  पञ्जीकरण गरेकोछ।\n\nयो खाता साँच्ची नैं तपाईंको हो भनेर पुष्टि गर्न र {{SITENAME}}मा यो ई मेलका सुविधाहरु  सक्रिय गर्न तपाईंको ब्राउजरमा यो लिंक खोल्नुहोस्:\n\n$3 \n\nयदि त्यो खाता तपाईंले पञ्जीकरण गर्नु भएको *होइन* भनें, ई मेलको पुष्टिकरण रद्द गर्न यो लिंक पहिल्याउनुहोस्:\n\n$5\n\nयो पुष्टिकरणको समय  $4 मा सकिनेछ।",
-       "confirmemail_body_changed": "à¤\95सà¥\88लà¥\87, à¤¸à¤¾à¤¯à¤¦ à¤¤à¤ªà¤¾à¤\88à¤\82लà¥\87, à¤\86à¤\88 à¤ªà¥\80 à¤ à¥\87à¤\97ाना $1बाà¤\9f,\n{{SITENAME}}मा \"$2\" à¤¨à¤¾à¤®à¤\95à¥\8b à¤\96ाताà¤\95à¥\8b  à¤\88 à¤®à¥\87ल à¤ à¥\87à¤\97ाना à¤¯à¤¸ à¤ à¥\87à¤\97ानामा  à¤ªà¤°à¤¿à¤µà¤°à¥\8dतन à¤\97रà¥\87à¤\95à¥\8bà¤\9b।\n\nयà¥\8b à¤\96ाता à¤¸à¤¾à¤\81à¤\9aà¥\8dà¤\9aà¥\80 à¤¨à¥\88à¤\82 à¤¤à¤ªà¤¾à¤\88à¤\82à¤\95à¥\8b à¤¹à¥\8b à¤­à¤¨à¥\87र à¤ªà¥\81षà¥\8dà¤\9fि à¤\97रà¥\8dन à¤° {{SITENAME}}मा à¤¯à¥\8b à¤\88 à¤®à¥\87लà¤\95ा à¤¸à¥\81विधाहरà¥\81  à¤ªà¥\81नà¤\83 à¤¸à¤\95à¥\8dरिय à¤\97रà¥\8dन à¤¤à¤ªà¤¾à¤\88à¤\82à¤\95à¥\8b à¤¬à¥\8dराà¤\89à¤\9cरमा à¤¯à¥\8b à¤²à¤¿à¤\82à¤\95 à¤\96à¥\8bलà¥\8dनà¥\81हà¥\8bसà¥\8d:\n\n$3 \n\nयदि à¤¤à¥\8dयà¥\8b à¤\96ाता à¤¤à¤ªà¤¾à¤\88à¤\82à¤\95à¥\8b *हà¥\8bà¤\87न* à¤­à¤¨à¥\87à¤\82, ई मेल ठेगानाको पुष्टिकरण रद्द गर्न यो लिंक पहिल्याउनुहोस्:\n\n$5\n\nयो पुष्टिकरणको समय  $4 मा सकिनेछ।",
-       "confirmemail_body_set": "à¤\95सà¥\88लà¥\87, à¤¸à¤¾à¤¯à¤¦ à¤¤à¤ªà¤¾à¤\88à¤\82लà¥\87, à¤\86à¤\88पà¥\80 à¤ à¥\87à¤\97ाना $1बाà¤\9f,\n{{SITENAME}}मा \"$2\" à¤¨à¤¾à¤®à¤\95à¥\8b à¤\96ाताà¤\95à¥\8b à¤\88मà¥\87ल à¤ à¥\87à¤\97ाना à¤¯à¤¸ à¤ à¥\87à¤\97ानासित à¤\9cà¥\8bडà¥\87à¤\95à¥\8b à¤\9b।\n\nयà¥\8b à¤\96ाता à¤¸à¤¾à¤\81à¤\9aà¥\8dà¤\9aà¥\80 à¤¨à¥\88à¤\82 à¤¤à¤ªà¤¾à¤\88à¤\82à¤\95à¥\8b à¤¹à¥\8b à¤­à¤¨à¥\87र à¤ªà¥\81षà¥\8dà¤\9fि à¤\97रà¥\8dन à¤° {{SITENAME}}मा à¤¯à¥\8b à¤\88मà¥\87लà¤\95ा à¤¸à¥\81विधाहरà¥\81 à¤ªà¥\81नà¤\83 à¤¸à¤\95à¥\8dरिय à¤\97रà¥\8dन à¤¤à¤ªà¤¾à¤\88à¤\82à¤\95à¥\8b à¤¬à¥\8dराà¤\89à¤\9cरमा à¤¯à¥\8b à¤²à¤¿à¤\99à¥\8dà¤\95 à¤\96à¥\8bलà¥\8dनà¥\81हà¥\8bसà¥\8d:\n\n$3 \n\nयदि à¤¤à¥\8dयà¥\8b à¤\96ाता à¤¤à¤ªà¤¾à¤\88à¤\82à¤\95à¥\8b *हà¥\8bà¤\87न* à¤­à¤¨à¥\87à¤\82, ईमेल ठेगानाको पुष्टिकरण रद्द गर्न यो लिङ्क पहिल्याउनुहोस्:\n\n$5\n\nयो पुष्टिकरणको समय  $4 मा सकिनेछ।",
+       "confirmemail_body_changed": "à¤\95सà¥\88लà¥\87, à¤¸à¤¾à¤¯à¤¦ à¤¤à¤ªà¤¾à¤\88à¤\82लà¥\87, à¤\86à¤\88 à¤ªà¥\80 à¤ à¥\87à¤\97ाना $1बाà¤\9f,\n{{SITENAME}}मा \"$2\" à¤¨à¤¾à¤®à¤\95à¥\8b à¤\96ाताà¤\95à¥\8b  à¤\88 à¤®à¥\87ल à¤ à¥\87à¤\97ाना à¤¯à¤¸ à¤ à¥\87à¤\97ानामा  à¤ªà¤°à¤¿à¤µà¤°à¥\8dतन à¤\97रà¥\87à¤\95à¥\8bà¤\9b।\n\nयà¥\8b à¤\96ाता à¤¸à¤¾à¤\81à¤\9aà¥\8dà¤\9aà¥\80 à¤¨à¥\88à¤\82 à¤¤à¤ªà¤¾à¤\88à¤\82à¤\95à¥\8b à¤¹à¥\8b à¤­à¤¨à¥\87र à¤ªà¥\81षà¥\8dà¤\9fि à¤\97रà¥\8dन à¤° {{SITENAME}}मा à¤¯à¥\8b à¤\88 à¤®à¥\87लà¤\95ा à¤¸à¥\81विधाहरà¥\82  à¤ªà¥\81नà¤\83 à¤¸à¤\95à¥\8dरिय à¤\97रà¥\8dन à¤¤à¤ªà¤¾à¤\88à¤\82à¤\95à¥\8b à¤¬à¥\8dराà¤\89à¤\9cरमा à¤¯à¥\8b à¤²à¤¿à¤\82à¤\95 à¤\96à¥\8bलà¥\8dनà¥\81हà¥\8bसà¥\8d:\n\n$3 \n\nयदि à¤¤à¥\8dयà¥\8b à¤\96ाता à¤¤à¤ªà¤¾à¤\88à¤\82à¤\95à¥\8b *हà¥\8bà¤\87न* à¤­à¤¨à¥\87, ई मेल ठेगानाको पुष्टिकरण रद्द गर्न यो लिंक पहिल्याउनुहोस्:\n\n$5\n\nयो पुष्टिकरणको समय  $4 मा सकिनेछ।",
+       "confirmemail_body_set": "à¤\95सà¥\88लà¥\87, à¤¸à¤¾à¤¯à¤¦ à¤¤à¤ªà¤¾à¤\88à¤\82लà¥\87, à¤\86à¤\88पà¥\80 à¤ à¥\87à¤\97ाना $1बाà¤\9f,\n{{SITENAME}}मा \"$2\" à¤¨à¤¾à¤®à¤\95à¥\8b à¤\96ाताà¤\95à¥\8b à¤\88मà¥\87ल à¤ à¥\87à¤\97ाना à¤¯à¤¸ à¤ à¥\87à¤\97ानासित à¤\9cà¥\8bडà¥\87à¤\95à¥\8b à¤\9b।\n\nयà¥\8b à¤\96ाता à¤¸à¤¾à¤\81à¤\9aà¥\8dà¤\9aà¥\80 à¤¨à¥\88à¤\82 à¤¤à¤ªà¤¾à¤\88à¤\82à¤\95à¥\8b à¤¹à¥\8b à¤­à¤¨à¥\87र à¤ªà¥\81षà¥\8dà¤\9fि à¤\97रà¥\8dन à¤° {{SITENAME}}मा à¤¯à¥\8b à¤\88मà¥\87लà¤\95ा à¤¸à¥\81विधाहरà¥\82 à¤ªà¥\81नà¤\83 à¤¸à¤\95à¥\8dरिय à¤\97रà¥\8dन à¤¤à¤ªà¤¾à¤\88à¤\82à¤\95à¥\8b à¤¬à¥\8dराà¤\89à¤\9cरमा à¤¯à¥\8b à¤²à¤¿à¤\99à¥\8dà¤\95 à¤\96à¥\8bलà¥\8dनà¥\81हà¥\8bसà¥\8d:\n\n$3 \n\nयदि à¤¤à¥\8dयà¥\8b à¤\96ाता à¤¤à¤ªà¤¾à¤\88à¤\82à¤\95à¥\8b *हà¥\8bà¤\87न* à¤­à¤¨à¥\87, ईमेल ठेगानाको पुष्टिकरण रद्द गर्न यो लिङ्क पहिल्याउनुहोस्:\n\n$5\n\nयो पुष्टिकरणको समय  $4 मा सकिनेछ।",
        "confirmemail_invalidated": "ई मेल ठेगाना रद्द भएको पुष्टिकरण",
        "invalidateemail": "इमेल यकिन कार्य रद्द गर्नुहोस्",
        "scarytranscludedisabled": "[अन्तरविकि दस्तावेज अन्तरकरण निस्क्रिय]",
        "tag-filter-submit": "फिल्टर",
        "tag-list-wrapper": "([[Special:Tags|{{PLURAL:$1|ट्याग|ट्यागहरू}}]]: $2)",
        "tags-title": "ट्यागहरु",
-       "tags-intro": "यà¥\8b à¤ªà¥\83षà¥\8dठलà¥\87 à¤ªà¥\81à¤\9aà¥\8dà¤\9bरहरà¥\81 à¤¸à¥\81à¤\9aà¥\80à¤\95à¥\83त à¤\97रà¥\8dà¤\9b à¤\9cससà¤\81à¤\97 à¤¯à¥\8b à¤¸à¤«à¥\8dà¤\9fवà¥\87यरलà¥\87 à¤\9aिनà¥\8b à¤²à¤\97ाà¤\89न à¤° à¤¸à¤®à¥\8dपादन à¤\97रà¥\8dन à¤¸à¤\95à¥\8dà¤\9b à¤° à¤¤à¤¿à¤¨à¤\95ा à¤\85रà¥\8dथहरà¥\81 ।",
+       "tags-intro": "यà¥\8b à¤ªà¥\83षà¥\8dठलà¥\87 à¤\9fà¥\8dयाà¤\97हरà¥\82 à¤¸à¥\82à¤\9aà¥\80à¤\95à¥\83त à¤\97रà¥\8dà¤\9b à¤\9cससà¤\81à¤\97 à¤¯à¥\8b à¤¸à¤«à¥\8dà¤\9fवà¥\87यरलà¥\87 à¤\9aिनà¥\8b à¤²à¤\97ाà¤\89न à¤° à¤¸à¤®à¥\8dपादन à¤\97रà¥\8dन à¤¸à¤\95à¥\8dà¤\9b à¤° à¤¤à¤¿à¤¨à¤\95ा à¤\85रà¥\8dथहरà¥\82 ।",
        "tags-tag": "आन्तरिक ट्याग नाम",
        "tags-display-header": "परिवर्तन सूचीहरूमाथि झलक",
        "tags-description-header": "पूर्ण अर्थको वर्णन",
        "htmlform-cloner-delete": "हटाउने",
        "htmlform-cloner-required": "कम्तिमा एउटामा आवश्यक छ ।",
        "logentry-delete-delete": "$1 द्वारा पृष्ठ $3 {{GENDER:$2|मेटाइयो}}",
-       "logentry-delete-restore": "$3 पृष्ठ $1ले {{GENDER:$2|पुनर्स्थापित}} गरेको हो",
+       "logentry-delete-restore": "$1 {{GENDER:$2|पुनर्स्थापित}} पृष्ठ $3 ($4)",
        "logentry-delete-event": "$1 ले $3 पृष्ठको लग {{PLURAL:$5|प्रविष्टि|प्रविष्टिहरू}}को दृश्यता {{GENDER:$2|परिवर्तन गर्यो}}: $4",
        "logentry-delete-revision": "$1 ले $3 पृष्ठको {{PLURAL:$5|एक अवतरण|$5 अवतरणहरू}}को दृश्यता {{GENDER:$2|परिवर्तन गर्यो}}: $4",
        "logentry-delete-event-legacy": "$1 ले $3 पृष्ठमा लग क्रियाहरूको दृश्यता {{GENDER:$2|परिवर्तन गर्यो}}",
        "special-characters-title-emdash": "इएम ड्यास",
        "special-characters-title-minus": "घटाउने चिन्ह",
        "mw-widgets-titleinput-description-new-page": "हालसम्म पृष्ठ उपलब्ध छैन्",
-       "mw-widgets-titleinput-description-redirect": "$1 मा जाने"
+       "mw-widgets-titleinput-description-redirect": "$1 मा जाने",
+       "randomrootpage": "यादृच्छिक शीर्ष पृष्ठ"
 }
index fe275cc..56b0a91 100644 (file)
        "rcfilters-empty-filter": "Geen actieve filters. Alle bijdragen worden weergeven.",
        "rcfilters-filterlist-title": "Filters",
        "rcfilters-filterlist-whatsthis": "Hoe werkt dit?",
-       "rcfilters-filterlist-feedbacklink": "Geef terugkoppeling op de nieuwe (beta)filters",
+       "rcfilters-filterlist-feedbacklink": "Laat ons weten wat u denkt over deze (nieuwe) filterhulpmiddelen",
        "rcfilters-highlightbutton-title": "Resultaten markeren",
        "rcfilters-highlightmenu-title": "Kies een kleur",
        "rcfilters-highlightmenu-help": "Selecteer een kleur om deze eigenschap uit te lichten",
        "rcfilters-liveupdates-button": "Liveupdates",
        "rcfilters-liveupdates-button-title-on": "Live updates uitschakelen",
        "rcfilters-liveupdates-button-title-off": "Toon nieuwe wijzigingen op het moment dat ze gebeuren",
-       "rcfilters-watchlist-markSeen-button": "Alle wijzigingen markeren als bezocht.",
+       "rcfilters-watchlist-markseen-button": "Alle wijzigingen markeren als bezocht.",
+       "rcfilters-watchlist-edit-watchlist-button": "Bewerk uw volglijst",
        "rcnotefrom": "Wijzigingen sinds <strong>$3 om $4</strong> (maximaal <strong>$1</strong> {{PLURAL:$1|wijziging|wijzigingen}}).",
        "rclistfromreset": "Datum selectie opnieuw instellen",
        "rclistfrom": "Wijzigingen bekijken vanaf $3 $2",
        "unwatchthispage": "Niet meer volgen",
        "notanarticle": "Is geen pagina",
        "notvisiblerev": "De laatste versie van een andere gebruiker is verwijderd",
-       "watchlist-details": "Er {{PLURAL:$1|staat één pagina|staan $1 pagina's}} op uw volglijst. Overlegpagina's worden niet meegeteld.",
+       "watchlist-details": "Er {{PLURAL:$1|staat één pagina|staan $1 pagina's}} op uw volglijst (inclusief overlegpagina's).",
        "wlheader-enotif": "U wordt per e-mail gewaarschuwd.",
        "wlheader-showupdated": "Pagina's die zijn bewerkt sinds uw laatste bezoek worden '''vet''' weergegeven.",
        "wlnote": "Hieronder {{PLURAL:$1|staat de laaste wijziging|staan de laatste $1 wijzigingen}} in {{PLURAL:$2|het laatste uur|de laatste $2 uur}} per $3 om $4.",
index 77e9f5d..e2bb178 100644 (file)
        "newpassword": "Nytt passord",
        "retypenew": "Nytt passord om att",
        "resetpass_submit": "Oppgje passord og logg inn",
-       "changepassword-success": "Passordet ditt er no nullstilt! Loggar inn...",
+       "changepassword-success": "Passordet ditt er no endra!",
        "resetpass_forbidden": "Passord kan ikkje endrast",
        "resetpass-no-info": "Du må vera innlogga for å få direktetilgang til denne sida.",
        "resetpass-submit-loggedin": "Endra passord",
        "passwordreset-emailtext-user": "Brukaren $1 på {{SITENAME}} bad om ei påminning for kontodetaljane dine for {{SITENAME}} ($4). {{PLURAL:$3|Den fylgjande brukarkontoen|Dei fylgjande brukarkontoane}} er assosierte med denne e-postadressa:\n\n$2\n\n{{PLURAL:$3|Dette mellombels passordet|Desse mellombels passorda}} vil verta ugilde om {{PLURAL:$5|éin dag|$5 dagar}}.\nDu bør logga inn og velja eit nytt passord no. Om nokon andre enn deg bad om denne påminninga, eller du har kome i hug det opphavlege passordet og ikkje lenger ynskjer å endra det, kan du sjå bort frå denne meldinga og halda fram med å nytta det gamle passordet ditt.",
        "passwordreset-emailelement": "↓Brukarnamn: \n$1\n\nMellombels passord: \n$2",
        "passwordreset-emailsentemail": "Ein e-post for attendestilling av passord er vorten send",
-       "changeemail": "↓Endre e-postadresse",
+       "changeemail": "Endre eller fjern e-postadresse",
        "changeemail-header": "↓Endre kontoen si e-postadresse",
        "changeemail-no-info": "↓Du må vera pålogga for å få tilgang direkte til denne sida.",
        "changeemail-oldemail": "↓Noverande e-postadresse:",
        "sig_tip": "Signaturen din med tidsstempel",
        "hr_tip": "Vassrett line",
        "summary": "Samandrag:",
-       "subject": "Emne/overskrift:",
+       "subject": "Emne:",
        "minoredit": "Småplukk",
        "watchthis": "Overvak sida",
        "savearticle": "Lagra sida",
        "page_last": "siste",
        "histlegend": "Merk av for dei versjonane du vil samanlikne og trykk [Enter] eller klikk på knappen nedst på sida.<br />Forklaring: (no) = skilnad frå den noverande versjonen, (førre) = skilnad frå den førre versjonen, <b>s</b> = småplukk",
        "history-fieldset-title": "Søk etter versjonar",
-       "history-show-deleted": "Berre sletta",
+       "history-show-deleted": "Berre sletta versjonar",
        "histfirst": "eldste",
        "histlast": "nyaste",
        "historysize": "({{PLURAL:$1|1 byte|$1 byte}})",
        "lineno": "Line $1:",
        "compareselectedversions": "Samanlikn valde versjonar",
        "showhideselectedversions": "Vis/løyn valde versjonar",
-       "editundo": "fjern endringa",
+       "editundo": "fjern",
        "diff-empty": "(Ingen skilnad)",
        "diff-multi-sameuser": "({{PLURAL:$1|Éin mellomversjon|$1 mellomversjonar}} av den same brukaren er ikkje {{PLURAL:$1|vist|viste}})",
        "diff-multi-otherusers": "({{PLURAL:$1|Éin mellomliggjande versjon|$1 mellomliggjande versjonar}} av {{PLURAL:$2|éin annan brukar|$2 brukarar}} er ikkje {{PLURAL:$1|vist|viste}})",
        "prefs-watchlist-days-max": "Høgst {{PLURAL:$1|éin dag|$1 dagar}}",
        "prefs-watchlist-edits": "Talet på endringar som viser i den utvida overvakingslista:",
        "prefs-watchlist-edits-max": "Høgst 1000",
-       "prefs-watchlist-token": "Emne på overvakingslista:",
+       "prefs-watchlist-token": "Nykel for overvakingslista:",
        "prefs-misc": "Andre",
        "prefs-resetpass": "Endra passord",
        "prefs-changeemail": "↓Endre e-postadresse",
        "badsig": "Ugyldig råsignatur, sjekk HTML-kodinga.",
        "badsiglength": "Signaturen din er for lang. Han må vere under {{PLURAL:$1|eitt teikn|$1 teikn}}.",
        "yourgender": "Korleis ynskjer du å skildrast?",
-       "gender-unknown": "Eg ynskjer ikkje å spesifisera",
+       "gender-unknown": "Programvara vil omtala deg med med kjønnsnøytrale ord der relevant og mogeleg",
        "gender-male": "Han endrar wikisider",
        "gender-female": "Ho endrar wikisider",
        "prefs-help-gender": "Det er valfritt å oppgje dette.\nProgramvara brukar denne verdien for å bruka rett grammatisk kjønn når ho rettar seg til deg eller nemner deg for andre.\nDenne informasjonen vil vera offentleg.",
        "userrights-nodatabase": "Databasen $1 finst ikkje eller er ikkje lokal.",
        "userrights-changeable-col": "Grupper du kan endre",
        "userrights-unchangeable-col": "Grupper du ikkje kan endre",
+       "userrights-expiry-current": "Endar $1",
+       "userrights-expiry-none": "Aldri",
+       "userrights-expiry-othertime": "Anna tid:",
+       "userrights-expiry-options": "1 dag:1 day,1 veke:1 week,1 månad:1 month,3 månader:3 months,6 månader:6 months,1 år:1 year",
        "group": "Gruppe:",
        "group-user": "Brukarar",
        "group-autoconfirmed": "Automatisk godkjende brukarar",
        "rcfilters-savedqueries-apply-label": "Lagra innstillingar",
        "rcfilters-savedqueries-add-new-title": "Lagra gjeldande filterinnstillingar",
        "rcfilters-clear-all-filters": "Fjern alle filter",
+       "rcfilters-show-new-changes": "Sjå dei nyaste endringane",
        "rcfilters-search-placeholder": "Filtrer siste endringar (gå gjennom liste eller skriv filternamn)",
        "rcfilters-invalid-filter": "Ugyldig filter",
        "rcfilters-empty-filter": "Ingen aktive filter. Alle bidrag er viste.",
        "rcfilters-view-namespaces-tooltip": "Filtrer resultat etter namnerom",
        "rcfilters-view-tags-tooltip": "Filtrer resultat etter endringsmerke",
        "rcnotefrom": "Nedanfor er endringane gjorde sidan <strong>$2</strong> viste (opp til <strong>$1</strong> stykke)",
+       "rclistfromreset": "Nullstill datoval",
        "rclistfrom": "Vis nye endringar sidan $3 $2",
        "rcshowhideminor": "$1 småplukk",
        "rcshowhideminor-show": "Vis",
        "log-title-wildcard": "Søk i titlar som byrjar med denne teksten",
        "showhideselectedlogentries": "Vis/gøym valde loggoppføringar",
        "log-edit-tags": "Endra merka til valde loggoppføringar",
+       "checkbox-select": "Vel: $1",
        "checkbox-all": "Alle",
        "checkbox-none": "Ingen",
        "checkbox-invert": "Vreng",
        "mw-widgets-dateinput-placeholder-day": "ÅÅÅÅ-MM-DD",
        "mw-widgets-dateinput-placeholder-month": "ÅÅÅÅ-MM",
        "mw-widgets-titleinput-description-new-page": "sida finst ikkje enno",
-       "mw-widgets-titleinput-description-redirect": "omdiriger til $1",
+       "mw-widgets-titleinput-description-redirect": "omdirigering til $1",
        "date-range-from": "Frå dato:",
        "date-range-to": "Til dato:",
        "randomrootpage": "Tilfeldig rotsida",
index 9c862ad..90b49a3 100644 (file)
        "anontalk": "ଆଲୋଚନା",
        "navigation": "ଦିଗବାରେଣି",
        "and": "&#32;ଓ",
-       "qbfind": "ଖୋଜନ୍ତୁ",
-       "qbbrowse": "ଦେଖିବେ",
-       "qbedit": "ସମ୍ପାଦନା (Edit)",
-       "qbpageoptions": "ଏହି ପୃଷ୍ଠାଟି",
-       "qbmyoptions": "ମୋ ପୃଷ୍ଠାଗୁଡ଼ିକ",
        "faq": "ବାରମ୍ବାର ପଚରାଯାଉଥିବା ପ୍ରଶ୍ନ",
-       "faqpage": "Project:ବାରମ୍ବାର ପଚରାଯାଉଥିବା ପ୍ରଶ୍ନ",
        "actions": "କାର୍ଯ୍ୟକ୍ରମ",
        "namespaces": "ନେମସ୍ପେସ",
        "variants": "ନିଆରା",
        "edit-local": "ସ୍ଥାନୀୟ ବିବରଣ ସମ୍ପାଦନା କରନ୍ତୁ",
        "create": "ତିଆରି କରନ୍ତୁ",
        "create-local": "ନିଜର ସ୍ଥାନୀୟ ବିବରଣ ଯୋଡ଼ନ୍ତୁ",
-       "editthispage": "ଏହି ପୃଷ୍ଠାଟିକୁ ବଦଳାଇବେ",
-       "create-this-page": "ଏହି ପୃଷ୍ଠା ତିଆରି କରିବେ",
        "delete": "ଲିଭାଇବେ",
-       "deletethispage": "ଏହି ପୃଷ୍ଠାଟି ଲିଭାଇବେ",
-       "undeletethispage": "ଏହି ପୃଷ୍ଠାଟିକୁ ଲିଭାଇବେ ନାହିଁ",
        "undelete_short": "{{PLURAL:$1|ଗୋଟିଏ ବଦଳ|$1ଟି ବଦଳ}} ଯାହା ଲିଭାସରିଛି ତାହାକୁ ପଛକୁ ଫେରାଇଦେବା",
        "viewdeleted_short": "{{PLURAL:$1|ଗୋଟିଏ ଲିଭାଯାଇଥିବା ବଦଳ|$1ଟି ଲିଭାଯାଇଥିବା ବଦଳ}} ଦେଖାଇବେ",
        "protect": "କିଳିବେ",
        "protect_change": "ବଦଳାଇବା",
-       "protectthispage": "ଏହି ପୃଷ୍ଠାଟିକୁ କିଳିବେ",
        "unprotect": "ସୁରକ୍ଷା ସ୍ତରକୁ ବଦଳାଇବେ",
-       "unprotectthispage": "ଏହି ପୃଷ୍ଠା ପାଇଁ ସୁରକ୍ଷାର ପ୍ରକାର ବଦଳାଇବେ",
        "newpage": "ନୂଆ ପୃଷ୍ଠା",
-       "talkpage": "ପୃଷ୍ଠାକୁ ଆଲୋଚନା କରନ୍ତୁ",
        "talkpagelinktext": "ଆଲୋଚନା",
        "specialpage": "ବିଶେଷ ପୃଷ୍ଠା",
        "personaltools": "ନିଜର ଟୁଲ",
-       "articlepage": "ସୂଚୀ ପୃଷ୍ଠାଟି ଦେଖାଇବେ",
        "talk": "ଆଲୋଚନା",
        "views": "ଦେଖା",
        "toolbox": "ଉପକରଣ",
        "tool-link-emailuser": "{{GENDER:$1|user}}ଙ୍କୁ ଇ-ମେଲ କରନ୍ତୁ",
-       "userpage": "ବ୍ୟବହାରକାରୀଙ୍କ ପୃଷ୍ଠା ଦେଖନ୍ତୁ",
-       "projectpage": "ପ୍ରକଳ୍ପ ପୃଷ୍ଠାଟି ଦେଖାଇବା",
        "imagepage": "ଫାଇଲ ପୃଷ୍ଠାଗୁଡ଼ିକ ଦେଖନ୍ତୁ",
        "mediawikipage": "ମେସେଜ ପୃଷ୍ଠାଟି ଦେଖାଇବେ",
        "templatepage": "ଛାଞ୍ଚ ପୃଷ୍ଠାଗୁଡ଼ିକ ଦେଖନ୍ତୁ",
        "nonunicodebrowser": "'''ଚେତାବନୀ: ଆପଣଙ୍କ ବ୍ରାଉଜରରେ ଇଉନିକୋଡ଼ ସଚଳ କରାଯାଇନାହିଁ ।'''\nଏକ ୱର୍କାଆରାଉଣ୍ଡ ଏକ ଏହିପରି ଜାଗା ଯାହା ଆପଣଙ୍କୁ ନିରାପଦ ଭାବରେ ପୃଷ୍ଠା ସମ୍ପାଦନ କରିବାରେ ସାହାଯ୍ୟ କରିଥାଏ: ଅଣ-ASCII ଅକ୍ଷରସମୂହ ସମ୍ପାଦନା ଘରେ ହେକ୍ସାଡେସିମାଲ କୋଡ଼ ରୂପେ ଦେଖାଯିବ ।",
        "editingold": "'''ଚେତାବନୀ: ଆପଣ ଏହି ପୃଷ୍ଠାର ଏକ ଅଚଳ ପୁରାତନ ସଙ୍କଳନକୁ ବଦଳାଉଛନ୍ତି ।'''\nଯଦି ଆପଣ ଏହାକୁ ସାଇତିବେ, ନୂଆ ସଙ୍କଳନ ଯାଏଁ କରାଯାଇଥିବା ସବୁ ବଦଳ ନଷ୍ଟ ହୋଇଯିବ ।",
        "yourdiff": "ତଫାତ",
-       "copyrightwarning": "ଦୟାକରି ଜାଣିରଖନ୍ତୁ ଯେ {{SITENAME}}କୁ ସବୁଯାକ ଅବଦାନ $2 ଅଧିନରେ ପ୍ରକାଶ କରାଯିବ । (ଅଧିକ ଜାଣିବା ପାଇଁ $1 ଦେଖନ୍ତୁ)\nଯଦି ଆପଣ ନିଜର ଲେଖା ନିର୍ଦୟ ଭାବେ ସମ୍ପାଦିତ ହେଉ ବୋଲି ଚାହୁଁନାହାନ୍ତି ବା ବଣ୍ଟନ କରାଯାଉ ବୋଲି ଚାହୁଁ ନାହାନ୍ତି ତେବେ ତାହା ଏଠାରେ ଦିଅନ୍ତୁ ନାହିଁ ।<br />\nଆପଣ ଆମପକ୍ଷେ ମଧ୍ୟ ପ୍ରତିଜ୍ଞା କରୁଛନ୍ତି ଯେ ଏହା ଆପଣ ନିଜେ ଲେଖିଛନ୍ତି, କିମ୍ବା ଏକ ପବ୍ଲିକ ଡୋମେନରୁ ବା ମାଗଣା ଓ ଖୋଲା ଲାଇସେନ୍ସ ଥିବା ସାଇଟରୁ ନକଲ କରି ଆଣିଛନ୍ତି ।\n'''ଅନୁମତି ବିନା ସତ୍ଵାଧିକାର ଥିବା କାମ ଏଠାରେ ଦିଅନ୍ତୁ ନାହିଁ !'''",
+       "copyrightwarning": "ଦà­\9fାà¬\95ରି à¬\9cାଣିରà¬\96ନà­\8dତà­\81 à¬¯à­\87 {{SITENAME}}à¬\95à­\81 à¬¸à¬¬à­\81ଯାà¬\95 à¬\85ବଦାନ $2 à¬\85ଧିନରà­\87 à¬ªà­\8dରà¬\95ାଶ à¬\95ରାଯିବ à¥¤ (à¬\85ଧିà¬\95 à¬\9cାଣିବା à¬ªà¬¾à¬\87à¬\81 $1 à¬¦à­\87à¬\96ନà­\8dତà­\81)\nଯଦି à¬\86ପଣ à¬¨à¬¿à¬\9cର à¬²à­\87à¬\96ା à¬¨à¬¿à¬°à­\8dଦà­\9f à¬­à¬¾à¬¬à­\87 à¬¸à¬®à­\8dପାଦିତ à¬¹à­\87à¬\89 à¬¬à­\8bଲି à¬\9aାହà­\81à¬\81ନାହାନà­\8dତି à¬¬à¬¾ à¬¬à¬£à­\8dà¬\9fନ à¬\95ରାଯାà¬\89 à¬¬à­\8bଲି à¬\9aାହà­\81à¬\81 à¬¨à¬¾à¬¹à¬¾à¬¨à­\8dତି à¬¤à­\87ବà­\87 à¬¤à¬¾à¬¹à¬¾ à¬\8fଠାରà­\87 à¬¦à¬¿à¬\85ନà­\8dତà­\81 à¬¨à¬¾à¬¹à¬¿à¬\81 à¥¤<br />\nà¬\86ପଣ à¬\86ମପà¬\95à­\8dଷà­\87 à¬®à¬§à­\8dà­\9f à¬ªà­\8dରତିà¬\9cà­\8dà¬\9eା à¬\95ରà­\81à¬\9bନà­\8dତି à¬¯à­\87 à¬\8fହା à¬\86ପଣ à¬¨à¬¿à¬\9cà­\87 à¬²à­\87à¬\96ିà¬\9bନà­\8dତି, à¬\95ିମà­\8dବା à¬\8fà¬\95 à¬ªà¬¬à­\8dଲିà¬\95 à¬¡à­\8bମà­\87ନରà­\81 à¬¬à¬¾ à¬®à¬¾à¬\97ଣା à¬\93 à¬\96à­\8bଲା à¬²à¬¾à¬\87ସà­\87ନà­\8dସ à¬¥à¬¿à¬¬à¬¾ à¬¸à¬¾à¬\87à¬\9fରà­\81 à¬¨à¬\95ଲ à¬\95ରି à¬\86ଣିà¬\9bନà­\8dତି à¥¤\n'''à¬\85ନà­\81ମତି à¬¬à¬¿à¬¨à¬¾ à¬¸à­\8dଵତà­\8dତà­\8dଵାଧିà¬\95ାର à¬¥à¬¿à¬¬à¬¾ à¬\95ାମ à¬\8fଠାରà­\87 à¬¦à¬¿à¬\85ନà­\8dତà­\81 à¬¨à¬¾à¬¹à¬¿à¬\81 !'''",
        "copyrightwarning2": "ଦୟାକରି ଜାଣିରଖନ୍ତୁ ଯେ {{SITENAME}} ସବୁଯାକ ଅବଦାନ ସମ୍ପାଦିତ ହୋଇପାରିବ, ବଦଳାଯାଇପାରିବ କିମ୍ବା ବାକି ଅବଦାନକାରୀଙ୍କ ଦେଇ କଢ଼ାଯାଇପାରିବ ।\nଯଦି ଆପଣ ନିଜର ଲେଖା ନିର୍ଦୟ ଭାବେ ସମ୍ପାଦିତ ହେଉ ବୋଲି ଚାହୁଁନାହାନ୍ତି ବା ବଣ୍ଟନ କରାଯାଉ ବୋଲି ଚାହୁଁ ନାହାନ୍ତି ତେବେ ତାହା ଏଠାରେ ଦିଅନ୍ତୁ ନାହିଁ ।<br />\nଆପଣ ଆମପକ୍ଷେ ମଧ୍ୟ ପ୍ରତିଜ୍ଞା କରୁଛନ୍ତି ଯେ ଏହା ଆପଣ ନିଜେ ଲେଖିଛନ୍ତି, କିମ୍ବା ଏକ ପବ୍ଲିକ ଡୋମେନରୁ ବା ମାଗଣା ଓ ଖୋଲା ଲାଇସେନ୍ସ ଥିବା ସାଇଟରୁ ନକଲ କରି ଆଣିଛନ୍ତି । (ଦୟାକରି ସବିଶେଷ ପାଇଁ $1 ଦେଖନ୍ତୁ) ।\n'''ଅନୁମତି ବିନା ସତ୍ଵାଧିକାର ଥିବା କାମ ଏଠାରେ ଦିଅନ୍ତୁ ନାହିଁ !'''",
        "longpageerror": "'''ଭୁଲ: ଆପଣ ଦେଇଥିବା ଲେଖାଟି {{PLURAL:$1|କିଲୋବାଇଟ|$1 କିଲୋବାଇଟ}} ଲମ୍ବା, ଯାହାକି ସବୁଠାରୁ ଅଧିକ {{PLURAL:$2|କିଲୋବାଇଟ|$2 କିଲୋବାଇଟ}} ଠାରୁ ବି ଅଧିକ ।'''\nଏହା ସାଇତାଯାଇପାରିବ ନାହିଁ ।",
        "readonlywarning": "ସୂଚନା: ଏହି ଡାଟାବେସଟି ରକ୍ଷଣାବେକ୍ଷଣା ପାଇଁ କିଳାଯାଇଛି । ତେଣୁ ଆପଣ ଆପଣା ସମ୍ପାଦନା ଏବେ ସାଇତି ପାରିବେ ନାହିଁ ।'''\nଆପଣ ଲେଖାସବୁ ଏକ ଟେକ୍ସଟ ଫାଇଲରେ ନକଲ ଏବଂ ପେଷ୍ଟ କରି ଆଗକୁ ବ୍ୟବହାର କରିବା ପାଇଁ ସାଇତି ପାରିବେ ।\n\nଏହାକୁ କିଳିଥିବା ପରିଛା ଏହି କଇଫତ ଦେଇଛନ୍ତି: $1",
        "exif-compression-2": "CCITT ଗୋଠ ୩ ୧-ବିମିୟ ବଦଳାଯାଇଥିବା ହଫମାନ ରନ ଲମ୍ବ ଏନକୋଡ଼ିଙ୍ଗ",
        "exif-compression-3": "CCITT ଗୋଠ ୩ ଫାକ୍ସ ଏନକୋଡ଼ିଙ୍ଗ",
        "exif-compression-4": "CCITT ଗୋଠ ୪ ଫାକ୍ସ ଏନକୋଡ଼ିଙ୍ଗ",
-       "exif-copyrighted-true": "ସତ୍ଵାଧିକାର ଥିବା",
+       "exif-copyrighted-true": "ସà­\8dଵତà­\8dତà­\8dଵାଧିà¬\95ାର à¬¥à¬¿à¬¬à¬¾",
        "exif-copyrighted-false": "କପିରାଇଟ ତଥ୍ୟ ଦିଆଯାଇନାହିଁ",
        "exif-unknowndate": "ଅଜଣା ତାରିଖ",
        "exif-orientation-1": "ସାଧାରଣ",
        "fileduplicatesearch-noresults": "\"$1\" ନାମରେ ଗୋଟିଏ ବି ଫାଇଲ ମିଳିଲା ନାହିଁ ।",
        "specialpages": "ବିଶେଷ ପୃଷ୍ଠା",
        "specialpages-note-top": "ଲିଜେଣ୍ଡ",
-       "specialpages-note": "* ସାଧାରଣ ବିଶେଷ ପୃଷ୍ଠାମାନ ।\n* <span class=\"mw-specialpagerestricted\">କିଳାଯାଇଥିବା ବିଶେଷ ପୃଷ୍ଠାମାନ ।</span>",
        "specialpages-group-maintenance": "ରକ୍ଷଣାବେକ୍ଷଣା ବିବରଣୀ",
        "specialpages-group-other": "ବାକି ବିଶେଷ ପୃଷ୍ଠା",
        "specialpages-group-login": "ଲଗ-ଇନ (Log in)/ ନୂଆ ଖାତା ଖୋଲିବେ (Sign up)",
index a97428c..8fcd2b7 100644 (file)
        "rcfilters-empty-filter": "Brak aktywnych filtrów. Wyświetlane są wszystkie zmiany.",
        "rcfilters-filterlist-title": "Filtry",
        "rcfilters-filterlist-whatsthis": "Jak działają?",
-       "rcfilters-filterlist-feedbacklink": "Podziel się swoją opinią na temat tych nowych (beta) filtrów",
+       "rcfilters-filterlist-feedbacklink": "Napisz co sądzisz o tych nowych narzędziach filtrowania",
        "rcfilters-highlightbutton-title": "Podświetl wyniki",
        "rcfilters-highlightmenu-title": "Wybierz kolor",
        "rcfilters-highlightmenu-help": "Wybierz kolor, aby podświetlić tę właściwość",
        "rcfilters-liveupdates-button": "Aktualizacje na bieżąco",
        "rcfilters-liveupdates-button-title-on": "Wyłącz aktualizacje na bieżąco",
        "rcfilters-liveupdates-button-title-off": "Wyświetlaj nowe zmiany zaraz po tym jak nastąpią",
-       "rcfilters-watchlist-markSeen-button": "Oznacz wszystkie zmiany jako obejrzane",
+       "rcfilters-watchlist-markseen-button": "Oznacz wszystkie zmiany jako obejrzane",
+       "rcfilters-watchlist-edit-watchlist-button": "Edytuj swoją listę obserwowanych stron",
        "rcnotefrom": "Poniżej {{PLURAL:$5|pokazano zmianę|pokazano zmiany}} {{PLURAL:$5|wykonaną|wykonane}} po <strong>$3, $4</strong> (nie więcej niż '''$1''' pozycji).",
        "rclistfromreset": "Zresetuj wybór daty",
        "rclistfrom": "Pokaż nowe zmiany od $3 $2",
index 844971b..d1c9de9 100644 (file)
                        "Felipe L. Ewald",
                        "WikiUser22222",
                        "BarbaraAckles",
-                       "Trigonometria87"
+                       "Trigonometria87",
+                       "RadiX"
                ]
        },
        "tog-underline": "Link sublinhado:",
        "rcfilters-empty-filter": "Nenhum filtro ativo. Todas as contribuições são mostradas.",
        "rcfilters-filterlist-title": "Filtros",
        "rcfilters-filterlist-whatsthis": "Como funcionam estes?",
-       "rcfilters-filterlist-feedbacklink": "Forneça feedback sobre os novos filtros (beta)",
+       "rcfilters-filterlist-feedbacklink": "Diga-nos o que você pensa sobre estas (novas) ferramentas de filtragem",
        "rcfilters-highlightbutton-title": "Realçar os resultados",
        "rcfilters-highlightmenu-title": "Selecione uma cor",
        "rcfilters-highlightmenu-help": "Selecione uma cor para realçar esta propriedade",
        "rcfilters-liveupdates-button": "Atualizações instantâneas",
        "rcfilters-liveupdates-button-title-on": "Desativar as atualizações ao vivo",
        "rcfilters-liveupdates-button-title-off": "Exibir novas mudanças à medida que elas acontecem",
-       "rcfilters-watchlist-markSeen-button": "Marque todas as mudanças como visto",
+       "rcfilters-watchlist-markseen-button": "Marque todas as mudanças como visto",
+       "rcfilters-watchlist-edit-watchlist-button": "Edite sua lista de páginas vigiadas",
+       "rcfilters-watchlist-showupdated": "As alterações nas páginas que você não visitou desde as mudanças ocorridas estão em <strong>negrito</strong>, com marcadores sólidos.",
        "rcnotefrom": "Abaixo {{PLURAL:$5|é a mudança|são as mudanças}} desde <strong>$3, $4</strong> (up to <strong>$1</strong> shown).",
        "rclistfromreset": "Redefinir seleção da data",
        "rclistfrom": "Mostrar as novas alterações a partir das $2 de $3",
        "unwatchthispage": "Parar de vigiar esta página",
        "notanarticle": "Não é uma página de conteúdo",
        "notvisiblerev": "Edição eliminada",
-       "watchlist-details": "{{PLURAL:$1|$1 página|$1 páginas}} na sua lista de páginas vigiadas, excluindo as páginas de discussão.",
+       "watchlist-details": "{{PLURAL:$1|$1 página está|$1 páginas estão}} na sua lista de páginas vigiadas (incluindo páginas de discussão).",
        "wlheader-enotif": "A notificação por email encontra-se ativada.",
        "wlheader-showupdated": "As páginas modificadas desde a sua última visita são mostradas em <strong>negrito</strong>.",
        "wlnote": "A seguir {{PLURAL:$1|está a última alteração ocorrida|estão as últimas <strong>$1</strong> alterações ocorridas}} {{PLURAL:$2|na última hora|nas últimas <strong>$2</strong> horas}} até $3, $4.",
        "logentry-protect-protect-cascade": "$1 {{GENDER:$2|protegeu}} $3 $4 [em cascata]",
        "logentry-protect-modify": "$1 {{GENDER:$2|alterou}} o nível de proteção para $3 $4",
        "logentry-protect-modify-cascade": "$1 {{GENDER:$2|alterou}} o nível de proteção para $3 $4 [em cascata]",
-       "logentry-rights-rights": "$1 {{GENDER:$2|mudou}} membros do grupo para {{GENDER:$6|$3}} de $4 para $5",
+       "logentry-rights-rights": "$1 {{GENDER:$2|alterou}} os grupos de usuário de {{GENDER:$6|$3}} de $4 para $5",
        "logentry-rights-rights-legacy": "$1 alterou os grupos de $3",
        "logentry-rights-autopromote": "$1 foi promovido automaticamente de $4 para $5",
        "logentry-upload-upload": "$1 {{GENDER:$2|carregou}} $3",
index d8cad9a..1839dfd 100644 (file)
@@ -73,7 +73,8 @@
                        "Gato Preto",
                        "Jdforrester",
                        "Mansil",
-                       "Ngl2016"
+                       "Ngl2016",
+                       "RadiX"
                ]
        },
        "tog-underline": "Sublinhar ligações:",
        "prefs-tabs-navigation-hint": "Dica: Pode usar as setas direita e esquerda do teclado para navegar entre os separadores.",
        "userrights": "Privilégios de utilizador",
        "userrights-lookup-user": "Selecionar um utilizador",
-       "userrights-user-editname": "Introduza um nome de utilizador(a):",
+       "userrights-user-editname": "Forneça um nome de utilizador(a):",
        "editusergroup": "Carregar grupos do utilizador",
        "editinguser": "A modificar os privilégios {{GENDER:$1|do utilizador|da utilizadora|do(a) utilizador(a)}}  <strong>[[User:$1|$1]]</strong> $2",
        "viewinguserrights": "A ver os privilégios {{GENDER:$1|do utilizador|da utilizadora}} <strong>[[User:$1|$1]]</strong> $2",
        "rcfilters-liveupdates-button": "Atualizações instantâneas",
        "rcfilters-liveupdates-button-title-on": "Desligar atualizações ao vivo",
        "rcfilters-liveupdates-button-title-off": "Apresentar mudanças novas à medida que acontecem",
-       "rcfilters-watchlist-markSeen-button": "Marcar todas as modificações como já vistas",
+       "rcfilters-watchlist-markseen-button": "Marcar todas as modificações como já vistas",
        "rcnotefrom": "Abaixo {{PLURAL:$5|está a mudança|estão as mudanças}} desde <strong>$2</strong> (mostradas até <strong>$1</strong>).",
        "rclistfromreset": "Reiniciar a seleção da data",
        "rclistfrom": "Mostrar as novas mudanças a partir das $2 de $3",
index 036a941..c30ac2d 100644 (file)
        "rcfilters-limit-shownum": "Title for the button that opens the operation to control how many results are shown. \n\nParameters: $1 - Number of results shown",
        "rcfilters-days-title": "Title for the options to change the number of days for the results shown.",
        "rcfilters-hours-title": "Title for the options to change the number of hours for the results shown.",
-       "rcfilters-days-show-days": "Title for the button that opens the operation to control the day range for the results. \n\nParameters: $1 - Number of days shown",
-       "rcfilters-days-show-hours": "Title for the button that opens the operation to control the hour range for the results. \n\nParameters: $1 - Number of hours shown",
+       "rcfilters-days-show-days": "Title for the button that opens the operation to control the day range for the results. \n\nParameters: $1 - Number of days shown\n{{Identical|Day}}",
+       "rcfilters-days-show-hours": "Title for the button that opens the operation to control the hour range for the results. \n\nParameters: $1 - Number of hours shown\n{{Identical|Hour}}",
        "rcfilters-highlighted-filters-list": "Text for the tooltip that is displayed over highlighted results, specifying which filters the result matches in [[Special:RecentChanges]] when RCFilters are enabled. \n\nParameters: $1 - A comma separated list of matching filter names.",
        "rcfilters-quickfilters": "Label for the button that opens the saved filter settings menu in [[Special:RecentChanges]]",
        "rcfilters-quickfilters-placeholder-title": "Title for the text shown in the quick filters menu on [[Special:RecentChanges]] if the user has not saved any quick filters.",
        "rcfilters-liveupdates-button": "Label for the button to enable or disable live updates on [[Special:RecentChanges]]",
        "rcfilters-liveupdates-button-title-on": "Title for the button to enable or disable live updates on [[Special:RecentChanges]] when the feature is ON.",
        "rcfilters-liveupdates-button-title-off": "Title for the button to enable or disable live updates on [[Special:RecentChanges]] when the feature is OFF.",
-       "rcfilters-watchlist-markSeen-button": "Label for the button to mark all changes as seen on [[Special:Watchlist]] when using the structured filters interface.",
+       "rcfilters-watchlist-markseen-button": "Label for the button to mark all changes as seen on [[Special:Watchlist]] when using the structured filters interface.",
+       "rcfilters-watchlist-edit-watchlist-button": "Label for the button to edit the watched pages on [[Special:Watchlist]] when using the structured filters interface.\n\nCf. {{msg-mw|watchlisttools-edit}}.",
+       "rcfilters-watchlist-showupdated": "Message at the top of [[Special:Watchlist]] when the Structured filters are enabled that describes what unseen changes look like.\n\nCf. {{msg-mw|wlheader-showupdated}}",
        "rcnotefrom": "This message is displayed at [[Special:RecentChanges]] when viewing recentchanges from some specific time.\n\nThe corresponding message is {{msg-mw|Rclistfrom}}.\n\nParameters:\n* $1 - the maximum number of changes that are displayed\n* $2 - (Optional) a date and time\n* $3 - a date\n* $4 - a time\n* $5 - Number of changes are displayed, for use with PLURAL",
        "rclistfromreset": "Used on [[Special:RecentChanges]] to reset a selection of a certain date range.",
        "rclistfrom": "Used on [[Special:RecentChanges]]. Parameters:\n* $1 - (Currently not use) date and time. The date and the time adds to the rclistfrom description.\n* $2 - time. The time adds to the rclistfrom link description (with split of date and time).\n* $3 - date. The date adds to the rclistfrom link description (with split of date and time).\n\nThe corresponding message is {{msg-mw|Rcnotefrom}}.",
index c752011..aa31bdb 100644 (file)
        "unwatchthispage": "No condrollà cchiù 'a pàgene",
        "notanarticle": "Non g'è 'na vosce",
        "notvisiblerev": "'A revisione ha state scangellete",
-       "watchlist-details": "{{PLURAL:$1|$1 pàgene|$1 pàggene}} jndr'à l'elenghe de le pàggene condrollate, scartanne le pàggene de le 'ngazzaminde.",
+       "watchlist-details": "{{PLURAL:$1|$1 pàgene jè|$1 pàggene stonne}} jndr'à l'elenghe de le pàggene condrollate (cchiù le pàggene de le 'ngazzaminde).",
        "wlheader-enotif": "* Notifiche pe email abbilitate.",
        "wlheader-showupdated": "* Le pàggene ca onne state cangiate da l'urtema visite avènene fatte vedè in '''grascette'''",
        "wlnote": "Aqquà sotte {{PLURAL:$1|ste l'urteme cangiamende|stonne l'urteme <strong>$1</strong> cangiaminde}} jndr'à {{PLURAL:$2|l'urtema ore|l'urteme <strong>$2</strong> ore}}, jndr'à $3, $4.",
index 7496cf2..c34cec3 100644 (file)
        "pool-errorunknown": "Неизвестная ошибка",
        "pool-servererror": "Служба счётчика пула недоступна ($1).",
        "poolcounter-usage-error": "Ошибка использования: $1",
-       "aboutsite": "Описание {{GRAMMAR:prepositional|{{SITENAME}}}}",
+       "aboutsite": "О {{GRAMMAR:prepositional|{{SITENAME}}}}",
        "aboutpage": "Project:Описание",
        "copyright": "Содержание доступно по лицензии $1 (если не указано иное).",
        "copyrightpage": "{{ns:project}}:Авторские права",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (см. также [[Special:NewPages|список новых страниц]])",
        "recentchanges-legend-plusminus": "(''±123'')",
        "recentchanges-submit": "Показать",
+       "rcfilters-tag-remove": "Удалить '$1'",
        "rcfilters-legend-heading": "<strong>Список сокращений:</strong>",
        "rcfilters-other-review-tools": "<strong>Другие инструменты проверки</strong>",
        "rcfilters-group-results-by-page": "Группировать результаты по странице",
        "rcfilters-hours-title": "Последние часы",
        "rcfilters-days-show-days": "$1 {{PLURAL:$1|день|дня|дней}}",
        "rcfilters-days-show-hours": "$1 {{PLURAL:$1|час|часа|часов}}",
+       "rcfilters-highlighted-filters-list": "Подсвечено: $1",
        "rcfilters-quickfilters": "Сохранённые фильтры",
        "rcfilters-quickfilters-placeholder-title": "Сохраненных ссылок еще нет",
        "rcfilters-quickfilters-placeholder-description": "Чтобы сохранить настройки фильтра и повторно использовать их позже, щелкните значок закладки в области «Активный фильтр» ниже.",
        "rcfilters-empty-filter": "Нет активных фильтров. Показываются все правки.",
        "rcfilters-filterlist-title": "Фильтры",
        "rcfilters-filterlist-whatsthis": "Как это работает?",
-       "rcfilters-filterlist-feedbacklink": "Ð\9eÑ\81Ñ\82авиÑ\82Ñ\8c Ð¾Ñ\82зÑ\8bв Ð¾ Ð½Ð¾Ð²Ñ\8bÑ\85 (беÑ\82а) Ñ\84илÑ\8cÑ\82Ñ\80аÑ\85",
+       "rcfilters-filterlist-feedbacklink": "РаÑ\81Ñ\81кажиÑ\82е Ð½Ð°Ð¼, Ñ\87Ñ\82о Ð²Ñ\8b Ð´Ñ\83маеÑ\82е Ð¾Ð± Ñ\8dÑ\82иÑ\85 (новÑ\8bÑ\85) Ð¸Ð½Ñ\81Ñ\82Ñ\80Ñ\83менÑ\82аÑ\85 Ñ\84илÑ\8cÑ\82Ñ\80аÑ\86ии",
        "rcfilters-highlightbutton-title": "Выделить результаты",
        "rcfilters-highlightmenu-title": "Выберите цвет",
        "rcfilters-highlightmenu-help": "Выберите цвет, чтобы подсветить это свойство",
        "rcfilters-liveupdates-button": "Обновлять автоматически",
        "rcfilters-liveupdates-button-title-on": "Отключить автоматические обновления",
        "rcfilters-liveupdates-button-title-off": "Показывать новые изменения сразу после их появления",
-       "rcfilters-watchlist-markSeen-button": "Отметить все изменения как просмотренные",
+       "rcfilters-watchlist-markseen-button": "Отметить все изменения как просмотренные",
+       "rcfilters-watchlist-edit-watchlist-button": "Редактировать ваш список просмотренных страниц",
+       "rcfilters-watchlist-showupdated": "Изменения страниц, которые вы не посещали с того момента, как они изменились, выделены <strong>жирным</strong> и отмечены полным маркером.",
        "rcnotefrom": "Ниже {{PLURAL:$5|указано изменение|перечислены изменения}} с <strong>$3, $4</strong> (показано не более <strong>$1</strong>).",
        "rclistfromreset": "Сбросить выбор даты",
        "rclistfrom": "Показать изменения с $3 $2.",
        "unwatchthispage": "Прекратить наблюдение",
        "notanarticle": "Не статья",
        "notvisiblerev": "Версия была удалена",
-       "watchlist-details": "В вашем списке наблюдения $1 {{PLURAL:$1|страница|страницы|страниц}}, не считая страниц обсуждений.",
+       "watchlist-details": "В вашем Списке наблюдения $1 {{PLURAL:$1|страница|страницы|страниц}} (а также страницы обсуждений).",
        "wlheader-enotif": "Уведомления по эл. почте включены.",
        "wlheader-showupdated": "Страницы, изменившиеся с вашего последнего их посещения, выделены '''полужирным''' шрифтом.",
        "wlnote": "Ниже {{PLURAL:$1|показано последнее изменение|показаны <strong>$1</strong> последние изменения|показаны <strong>$1</strong> последних изменений}} за {{PLURAL:$2|последний час|последние <strong>$2</strong> часа|последние <strong>$2</strong> часов}}, по состоянию на $3 $4.",
index 97de6d4..047d508 100644 (file)
        "show-big-image-preview": "هن پيش نگاھ جي ماپ: $1",
        "show-big-image-other": "ٻيا {{PLURAL:$2|تحلل}}:$1",
        "show-big-image-size": "$1*$2 پڪزلس",
+       "file-info-gif-frames": "$1 {{PLURAL:$1|فريم|فريمَ}}",
        "newimages": "نون فائيلن جي گيلري",
        "noimages": "ڏسڻ لاءِ ڪجھہ ناهي.",
        "ilsubmit": "ڳوليو",
        "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": "عربي توسيعي",
        "special-characters-group-hebrew": "ابراني",
        "special-characters-group-bangla": "بنگالي",
        "special-characters-group-tamil": "تامل",
        "special-characters-group-gujarati": "گجراتي",
        "special-characters-group-devanagari": "ديوناگري",
        "special-characters-group-thai": "ٿائي",
+       "special-characters-group-lao": "لائو",
        "mw-widgets-dateinput-no-date": "ڪا بہ تاريخ نہ چونڊيل",
        "mw-widgets-titleinput-description-new-page": "اڃا اهو صفحو وجود نہ ٿو رکي",
        "mw-widgets-titleinput-description-redirect": "$1 ڏانهن چوريل",
index 4eaee8e..576cb17 100644 (file)
        "hidden-category-category": "ⵜⴰⴳⴳⴰⵢⵉⵏ ⵏⵜⵍⵏⵉⵏ",
        "category-subcat-count": "{{PLURAL:$2|ⵜⴰⴳⴳⴰⵢⵜ ⴰⴷ ⵓⵔ ⵜⵓⵎⵢ ⴰⴱⵍⴰ ⵜⴰⴷⵓⴳⴳⴰⵢⵜ ⴰⴷ ⵉⵍⵍⴰⵏ ⴷⴷⴰⵡ ⴰⵙ.|ⵜⴰⴳⴳⴰⵢⵜ ⴰⴷ ⵜⵓⵎⵢ $2 ⵜⴷⵓⴳⴳⴰⵢⵉⵏ, ⴳⵉⵙ {{PLURAL:$1|ⵜⴰⴷⵓⴳⴳⴰⵢⵜ ⴰⴷ ⵉⵍⵍⴰⵏ|ⵜⵉⴷⵓⴳⴳⴰⵢⵉⵏ ⴰⴷ ⵙ $1 ⵍⵍⴰⵏⵉⵏ}} ⴷⴷⴰⵡ ⴰⵙ.}}",
        "category-subcat-count-limited": "ⵜⴰⴳⴳⴰⵢⵜ ⴰⴷ ⵢⵓⵎⵢ {{PLURAL:$1|ⵜⴰⴷⵓⴳⴳⴰⵢⵜ|$1 ⵜⴰⴷⵓⴳⴳⴰⵢⵉⵏ}} ⴰⴷ ⴷⴷⴰⵡ ⴰⵙ.",
-       "category-article-count": "Taggayt ad gis {{PLURAL:$2|tasna d yuckan|$2 tisniwin, lliɣ llant {{PLURAL:$1|ɣta|ɣti $1}} ɣid ɣu uzddar}}.",
+       "category-article-count": "ⵜⴰⴳⴳⴰⵢⵜ ⴰⴷ {{PLURAL:$2|ⵓⵔ ⵜⵓⵎⵢ ⴰⴱⵍⴰ ⵜⴰⵙⵏⴰ ⴰⴷ ⵉⴹⴼⴰⵔⵏ.|ⵜⵓⵎⵢ $2 ⵜⴰⵙⵏⵉⵡⵉⵏ, ⴳⵉⵙⵏⵜ {{PLURAL:$1|ⵜⴰⵙⵏⴰ ⴰⴷ ⵉⴹⴼⴰⵔⵏ|ⵜⴰⵙⵏⵉⵡⵉⵏ ⴰⴷ ⴹⴼⴰⵔⵏⵉⵏ}}.}}",
        "category-article-count-limited": "{{PLURAL:$1|Tasna d yuckan tlla|Tisniwin $1 llid yuckan llant}} ɣ taggayt ad",
-       "category-file-count": "Taggayt ad gis {{PLURAL:$2|asdaw ad yuckan|$2 isdawn ad, lliɣ llant {{PLURAL:$1|ɣta|ɣti $1}} ɣid ɣ uzddar}}.",
+       "category-file-count": "ⵜⴰⴳⴳⴰⵢⵜ ⴰⴷ {{PLURAL:$2|ⵓⵔ ⵜⵓⵎⵢ ⴰⴱⵍⴰ ⴰⴼⴰⵢⵍⵓ ⴰⴷ ⵏⵏⴰ ⵉⴹⴼⴰⵔⵏ.|ⵜⵓⵎⵢ $2 ⵉⴼⴰⵢⵍⵓⵜⵏ, ⴳⵉⵙⵏ {{PLURAL:$1|ⴰⴼⴰⵢⵍⵓ ⴰⴷ ⵏⵏⴰ ⵉⴹⴼⴰⵔⵏ|$1 ⵉⴼⴰⵢⵍⵓⵜⵏ ⴰⴷ ⵏⵏⴰ ⴹⴼⴰⵔⵏⵉⵏ}} ⴷⴷⴰⵡ ⴰⵙ.}}",
        "category-file-count-limited": "{{PLURAL:$1|Asdaw ad yuckan illa|isdawn ad $1 llid yuckan llan}} ɣ taggayt ad",
        "listingcontinuesabbrev": "Attfr",
        "index-category": "ⵜⴰⵙⵡⵏⵉⵡⵉⵏ ⵜⵜⵡⴰⵏⴷⵉⴽⵙⴰⵏⵉⵏ",
        "whitelistedittext": "ⵉ ⵕⴱⴱⵉ $1 ⵉⵖ ⵜⵔⵉⵜ ⴰⴷ ⵜⵙⵏⴼⵍⵜ ⵜⴰⵙⵏⵉⵡⵉⵏ.",
        "confirmedittext": "Illa fllak ad talst i tansa nk tbratin urta tsbadalt tisniwin.\nKcm zwar tft tansan nk tbratin ɣ [[Special:Preferences|Timssusmin n umqdac]].",
        "nosuchsectiontitle": "Ur as tufit ad taft ayyaw ad.",
-       "nosuchsectiontext": "Turmt ad tsbadlt yan w-ayyaw lli ur illin.\nḤaqqan is immutti s mani niɣt ittuykkas s mad tɣrit tasnayad.",
+       "nosuchsectiontext": "ⵜⵓⵔⵎⵜ ⴰⴷ ⵜⵙⵏⴼⵍⵜ ⵢⴰⵜ ⵜⴳⵣⵎⵉ ⵓⵔ ⵉⵍⵍⵉⵏ.\nⵉⵥⴹⴰⵔ ⴰⴷ ⵜⵉⵍⵉ ⵜⴻⵜⵜⵢⴰⵡⵙⵎⴰⵜⵜⵉ ⵏⵖ ⵜⴻⵜⵜⵡⴰⴽⴽⵙ ⵍⵍⵉⵖ ⴰⵔ ⵜⴻⵜⵜⴰⵏⵏⴰⵢⵜ ⵜⴰⵙⵏⴰ.",
        "loginreqtitle": "ⵍⴰⴱⵓⴷⴷ ⵏ ⵓⵣⴷⴰⵢ",
        "loginreqlink": "ⴽⵛⵎ",
        "loginreqpagetext": "ⵉ ⵕⴱⴱⵉ $1 ⵉⵖ ⵜⵔⵉⵜ ⴰⴷ ⵜⴰⵏⵏⴰⵢⵜ ⵜⴰⵙⵏⵉⵡⵉⵏ ⵢⴰⴹⵏ.",
        "accmailtitle": "ⵜⴻⵜⵜⵢⵓⵣⵏ ⵜⴳⵓⵔⵉ ⵏ ⵓⵣⵔⴰⵢ",
        "newarticle": "(ⴰⵎⴰⵢⵏⵓ)",
-       "newarticletext": "Tfrt yan uzday s yat tasna lli ur ta jju illan [{{fullurl:Special:Log|type=delete&page={{FULLPAGENAMEE}}}} ttuykkas].\nIɣ rast daɣ tskrt skcm atṛiṣ nk ɣ tanaka  yad (Tẓḍaṛt an taggt γi [$1 tasna u usaws] iɣ trit inɣmisn yaḍn).\nIvd tlkmt {{GENDER:||e|(e)}} ɣis bla trit, klikki f tajrrayt n '''urrir''' n iminig nk (navigateur).",
+       "newarticletext": "ⵜⵎⴰⵏⵜ ⴷ ⵢⴰⵏ ⵓⵍⵉⵏⴽ ⵙ ⵢⴰⵜ ⵜⴰⵙⵏⴰ ⵓⵔ ⵜⴰ ⵉⵍⵍⵉⵏ.\nⴱⴰⵛ ⴰⴷ ⵜⵙⵏⵓⵍⴼⵓⵜ ⵜⴰⵙⵏⴰ, start typing in the box below (ⵥⵔ [$1 ⵜⴰⵙⵏⴰ ⵏ ⵜⵡⵉⵙⵉ] for more info).\nIf you are here by mistake, click your browser's <strong>back</strong> button.",
        "noarticletext": "ⵓⵔ ⵖⵉⵍⴰⴷ ⵉⵍⵍⵉ ⴽⵔⴰ ⵏ ⵓⴹⵔⵉⵙ ⵖ ⵜⴰⵙⵏⴰ ⴰⴷ.\nⵜⵥⴹⴰⵔⵜ [[Special:Search/{{PAGENAME}}|ⴰⴷ ⵜⵙⵉⴳⴳⵍⵜ ⴰⵣⵡⵍ ⴰⴷ]] ⵖ ⵜⴰⵙⵏⵉⵡⵉⵏ ⵢⴰⴹⵏ,\n<span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} search the related logs],\nⵏⵖ [{{fullurl:{{FULLPAGENAME}}|action=edit}} ⴰⴷ ⵜⵙⵏⵓⵍⴼⵓⵜ ⵜⴰⵙⵏⴰ ⴰⴷ]</span>.",
        "noarticletext-nopermission": "Ur illa may itt yuran ɣ tasna tad.\nẒr [[Special:Search/{{PAGENAME}}|search for this page title]] ɣ tisnatin yaḍnin,\nulla <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}}search the related logs]</span>.",
        "updated": "(mohdata)",
        "creating": "ⴰⵙⵏⵓⵍⴼⵓ ⵏ $1",
        "editingsection": "ⴰⵙⵏⴼⵍ ⵏ $1 (ⵜⵉⴳⵣⵎⵉ)",
        "yourtext": "ⴰⴹⵔⵉⵙ ⵏⵏⴽ/ⵎ",
-       "storedversion": "noskha ityawsjaln",
+       "storedversion": "ⵜⵓⵏⵖⵉⵍⵜ ⵉⵜⵜⵢⵓⵃⴹⴰⵏ",
        "yourdiff": "ⵉⵎⵣⴰⵔⴰⵢⵏ",
        "copyrightwarning": "ikhssak atst izd kolchi tikkin noun ɣ {{SITENAME}} llan ɣdo $2 (zr $1 iɣ trit ztsnt uggar).\niɣ ortrit ayg ɣayli torit ḥor artisbadal wnna ka-iran, attid ortgt ɣid.<br />\nikhssak ola kiyi ador tnqilt ɣtamani yadni.\n'''ador tgat ɣid ɣayli origan ḥor iɣzark orilli lidn nbab-ns!'''",
        "templatesused": "{{PLURAL:$1|Tamuḍimt lli nsxdm|Timuḍimin}} ɣ tasna yad:",
        "hiddencategories": "ⵜⵍⵍⴰ ⵜⴰⵙⵏⴰ ⴰⴷ ⵖ {{PLURAL:$1|1 ⵜⴰⴳⴳⴰⵢⵜ ⵉⵏⵜⵍⵏ|$1 ⵜⴰⴳⴳⴰⵢⵉⵏ ⵏⵜⵍⵏⵉⵏ}}:",
        "permissionserrors": "ⵜⴰⵣⴳⵍⵜ ⵖ ⵜⵓⵔⴰⴳⵜ",
        "permissionserrorstext-withaction": "Urak ittuyskar  {{IGGUT:||e|(e)}} s $2, bac {{PLURAL:$1|s wacku yad|iwackutn ad}} :",
-       "recreate-moveddeleted-warn": "\"Balak z ɣin: tmmaɣt addaɣ tskrt tasna lli yad ittuykkasn.\"\nẒr zwar is ifulki ad tfrt imbddln ɣ tasna yad. Tanɣmast n mad ittuykkasn d mad ibddln ttla ɣid ɣ uzddar.",
+       "recreate-moveddeleted-warn": "<strong>ⵔⴰⵔ ⵜⴰⵖⴹⴼⵜ: ⵀⴰ ⵜ ⴰⵔ ⴷⴰⵖ ⵜⵙⵏⵓⵍⴼⵓⵜ ⵢⴰⵜ ⵜⴰⵙⵏⴰ ⵢⴰⴷ ⵉⵜⵜⵡⴰⴽⴽⵙⵏ.</strong>\n\nYou should consider whether it is appropriate to continue editing this page.\nⴰⵍⵓⴳ ⵏ ⵡⵓⴽⵓⵙ ⴷ ⵓⵙⵎⵓⵜⵜⵉ ⵏ ⵜⴰⵙⵏⴰ ⴰⴷ ⵜⵜⵢⴰⵡⴼⵙⵔⵏ ⴷⴷⴰⵡ ⴰⵙ for convenience:",
        "moveddeleted-notice": "ⵜⴻⵜⵜⵡⴰⴽⴽⵙ ⵜⴰⵙⵏⴰ ⴰⴷ.\nⵜⵓⴽⴽⵙⴰ, ⴰⴼⵔⴰⴳ, ⴷ ⵓⵙⵎⵓⵜⵜⵉ ⵏ ⵜⴰⵙⵏⴰ ⵍⵍⴰⵏ ⴷⴷⴰⵡ‒ⴰⵙ for reference.",
        "log-fulllog": "Zṛ anɣmas izun (usmmid)",
        "edit-hook-aborted": "Imbddln ur ttuyskarnin.. Ur ittuyssan maɣ",
        "currentrev-asof": "Amseggar amǧuru  n $1",
        "revisionasof": "Askttay yaḍn f $1",
        "revision-info": "Imsurritn n $1 s $2",
-       "previousrevision": "Iẓṛi daɣ aqbur",
-       "nextrevision": "Amẓr amaynu",
+       "previousrevision": "← ⵜⵓⵏⵖⵉⵍⵜ ⵉⵣⵡⴰⵔⵏ",
+       "nextrevision": "ⵜⵓⵏⵖⵉⵍⵜ ⵉⴹⴼⴰⵔⵏ →",
        "currentrevisionlink": "Amcggr amggaṛu",
        "cur": "ⵎⵔⵏ",
        "next": "ⵓⴹⴼⵉⵔ",
        "history-show-deleted": "Tḥiyd hlli",
        "histfirst": "ⴰⵇⴷⵉⵎ ⴰⴽⴽⵯ",
        "histlast": "ⴰⵎⴰⵢⵏⵓ ⴰⴽⴽⵯ",
-       "historyempty": "(âµ¢âµ\93â´³ⴰ)",
+       "historyempty": "(âµ\89âµ\85ⵡⴰ)",
        "history-feed-item-nocomment": "$1 ⵖ $2",
        "rev-delundel": "Mel/ĥbu",
        "rev-showdeleted": "ⵎⵍ",
        "search-external": "ⴰⵔⵣⵣⵓ ⴰⴱⵕⵕⴰⵏ",
        "searchdisabled": "ⵉⵏⵙⴰ ⵓⵔⵣⵣⵓ ⵖ {{SITENAME}}.\nⵜⵥⴹⴰⵔⵜ ⴰⴷ ⵜⵙⵉⴳⴳⵍⵜ ⵖ ⴳⵓⴳⵍ ⵙ ⵉⵖ ⴷ ⵢⵓⵔⵔⵉ.\nIzdar ad urtili ɣ isbidn n mayllan ɣ {{SITENAME}} .",
        "preferences": "Timssusmin",
-       "mypreferences": "âµ\89âµ\99âµ\8fâµ¢âµ\89â´¼âµ\8f",
+       "mypreferences": "âµ\9câµ\89âµ\99âµ\96â´°âµ\8d",
        "prefs-edits": "ⵓⵟⵟⵓⵏ ⵏ ⵉⵙⵏⴼⵉⵍⵏ:",
        "prefs-skin": "ⵜⵉⵎⵍⵙⵉⵜ",
-       "skin-preview": "Ammal",
+       "skin-preview": "ⴱⵔⵉⴱⵢⵓ",
        "datedefault": "Timssusmin",
        "prefs-personal": "milf n umsxdam",
        "prefs-rc": "ⵉⵙⵏⴼⵉⵍⵏ ⴳⴳⵯⵔⴰⵏⵉⵏ",
        "guesstimezone": "skchm twqit gh lmotasaffih",
        "timezoneregion-africa": "ⵜⴰⴼⵔⵉⴽⵜ",
        "timezoneregion-america": "ⵜⴰⵎⵔⵉⴽⵜ",
-       "timezoneregion-antarctica": "ⴰⵏⵜⴰⵔⴽⵜⵉⴽ",
+       "timezoneregion-antarctica": "ⴰⵏⵜⴰⵔⴽⵜⵉⴽ",
        "timezoneregion-arctic": "ⴰⵔⴽⵜⵉⴽ",
        "timezoneregion-asia": "ⴰⵙⵢⴰ",
        "timezoneregion-atlantic": "ⴰⴳⴰⵔⴰⵡ ⴰⵏⴰⵟⵍⴰⵙ",
        "filedelete-submit": "ⴽⴽⵙ",
        "randompage": "ⵜⴰⵙⵏⴰ ⵜⴰⴷⵀⵎⴰⵙⵜ",
        "randomincategory-category": "ⴰⵙⵎⵉⵍ:",
-       "statistics": "ⵉⵙⵉⴹⵏⴻⵏ",
+       "statistics": "ⵜⵉⵙⵉⴹⴰⵏ",
+       "statistics-header-edits": "ⵜⵉⵙⵉⴹⴰⵏ ⵏ ⵉⵙⵏⴼⵉⵍⵏ",
+       "statistics-header-hooks": "ⵜⵉⵙⵉⴹⴰⵏ ⵢⴰⴹⵏ",
        "statistics-articles": "ⵜⴰⵙⵏⵉⵡⵉⵏ ⵏ ⵜⵓⵎⴰⵢⵜ",
        "statistics-pages": "ⵜⴰⵙⵏⵉⵡⵉⵏ",
        "brokenredirects-edit": "ⵙⵏⴼⵍ",
        "actioncomplete": "tigawt tummidt",
        "actionfailed": "Tawwuri i xsrn",
        "deletedtext": "\"$1\"  ttuykkas.\nẒṛ $2 inɣmas imggura n ma ittuykkasn",
-       "dellogpage": "Qqiyd akkas ad",
+       "dellogpage": "ⴰⵍⵓⴳ ⵏ ⵡⵓⴽⵓⵙ",
        "deletecomment": "ⵜⴰⵎⵏⵜⵉⵍⵜ:",
        "deleteotherreason": "ⵜⴰⵎⵏⵜⵉⵍⵜ ⵢⴰⴹⵏ/:",
        "deletereasonotherlist": "ⵜⴰⵎⵏⵜⵉⵍⵜ ⵢⴰⴹⵏ",
        "tooltip-pt-userpage": "Tasna n umsqdac",
        "tooltip-pt-mytalk": "ⵜⴰⵙⵏⴰ {{GENDER:|ⵏⵏⴽ|ⵏⵏⵎ}} ⵏ ⵓⵎⵙⴰⵡⴰⵍ",
        "tooltip-pt-anontalk": "Amsgdal f imbddeln n tansa n IP yad",
-       "tooltip-pt-preferences": "âµ\89âµ\99âµ\8fâµ¢âµ\89â´¼âµ\8f {{GENDER:|ⵏⵏⴽ|ⵏⵏⵎ}}",
+       "tooltip-pt-preferences": "âµ\9câµ\89âµ\99âµ\96â´°âµ\8d {{GENDER:|ⵏⵏⴽ|ⵏⵏⵎ}}",
        "tooltip-pt-watchlist": "Tifilit n tisnatin li itsaggan imdddeln li gisnt ittyskarn..",
        "tooltip-pt-mycontris": "ⵜⴰⵍⴳⴰⵎⵜ ⵏ ⵜⵓⵎⵓⵜⵉⵏ {{GENDER:|ⵏⵏⴽ|ⵏⵏⵎ}}",
        "tooltip-pt-login": "Yufak at qiyt akcum nek, mach ur fllak ibziz .",
index b2281ae..c033af2 100644 (file)
@@ -11,6 +11,7 @@
        "tog-numberheadings": "سرخیاں کوں خود کار نمبر ݙیوو",
        "tog-showtoolbar": "آلات ترمیم ݙکھاؤ",
        "tog-editondblclick": "ڈبل کلک نال ورقے وچ تبدیلیاں کرو",
+       "tog-previewonfirst": "پہلی تبدیلی تے پری ویویو ݙکھاؤ",
        "tog-oldsig": "تہاݙے موجودہ دستخط:",
        "tog-uselivepreview": "ورقہ ولدا لوڈ کیتے ٻاجھوں نمائش ݙکھاؤ",
        "tog-watchlisthideminor": "چھوٹیاں تبدیلیاں اکھیں ہیٹھ فہرست وچوں لکاؤ",
        "mypage": "ورقہ",
        "mytalk": "ڳالھ مہاڑ",
        "anontalk": "ڳالھ مہاڑ",
-       "navigation": "رہنمائی",
+       "navigation": "نیوی ڳیشݨ",
        "and": "&#32;تے",
        "faq": "عام طور تے پچھے ونڄݨ آلے سوال",
        "actions": "کم",
        "namespaces": "ناں جاہیں",
        "variants": "قسماں",
-       "navigation-heading": "Ù\81Û\81رست Ø±Û\81Ù\86Ù\85ائÛ\8c",
+       "navigation-heading": "Ù\86Û\8cÙ\88Û\8c Ú³Û\8cشݨ Ù\81Û\81رست",
        "errorpagetitle": "نقص",
        "returnto": "واپس $1 چلو",
        "tagline": " {{SITENAME}} توں",
        "edit": "لکھو",
        "edit-local": "مقامی تفصیل درج کرو",
        "create": "بݨاؤ",
-       "create-local": "آپنی لکھت رلاؤ",
+       "create-local": "آپݨی لکھت رَلاؤ",
        "delete": "مٹاؤ",
        "protect": "حفاظت کرو",
        "protect_change": "تبدیل کرو",
        "lastmodifiedat": "ایہ ورقہ چھیکڑی واری  $1 کوں $2 تے تبدیل تھیا ہائی۔",
        "protectedpage": "آم شام ورقہ",
        "jumpto": "ٹپ مارو",
-       "jumptonavigation": "رہنمائی",
+       "jumptonavigation": "نیوی ڳیشݨ",
        "jumptosearch": "ڳولو",
        "pool-errorunknown": "نامعلوم غلطی",
        "poolcounter-usage-error": "استعمال وچ خامی: $1",
        "ok": "ٹھیک ہے",
        "retrievedfrom": "\"$1\" توں گھدا",
        "youhavenewmessages": "{{PLURAL:$3| تہاݙے کیتے}} $1 ($2).",
+       "youhavenewmessagesfromusers": "{{PLURAL:$4|تہاݙے کیتے}} {{PLURAL:$3|کہیں ٻئے صارف|$3 صارفین}} دی طرفوں $1 ($2)۔",
        "newmessageslinkplural": "{{PLURAL:$1|نواں سنیہا|999=نویں سنیہے}}",
        "newmessagesdifflinkplural": "چھیکڑی {{PLURAL:$1|تبدیلی|تبدیلیاں}}",
        "editsection": "لکھو",
        "viewsource": "ماخذ ݙیکھو",
        "viewsource-title": "$1 دا مسودہ ݙیکھو",
        "viewsourcetext": "تساں ایں ورقے کوں صرف ݙیکھ تے ماخز نقل کر سڳدے ہو لیکن تبدیلی نہوے کر سڳدے",
+       "ns-specialprotected": "خاص ورقیاں وچ تبدیلی نی تھی سڳدی",
        "exception-nologin": "لاگ ان نہوے تھئے",
+       "virus-scanfailed": "سکین نی تھی سڳیا(کوڈ$1)",
+       "virus-unknownscanner": "ان ڄاݨ اینٹی وائرس",
        "cannotlogoutnow-title": "ہݨ لاگ ان نہوے تھی سڳدے",
        "welcomeuser": "خوش آمدید، $1!",
        "yourname": "صارف دا ناں",
        "createacct-error": "کھاتہ بݨاوݨ وچ غلطی",
        "loginsuccesstitle": "لاگ ان تھی ڳیا",
        "mailmypassword": "نواں پاس ورڈ بݨاؤ",
+       "mailerror": "ای میل بھیجݨ وچ غلطی: $1",
        "emailconfirmlink": "آپݨے ای میل پتے دی تصدیق کرو",
        "emaildisabled": "ایہ سائٹ ای میل نی بھیج سڳدی۔",
        "accountcreated": "کھاتہ کھل ڳیا",
        "oldpassword": "پراݨا پاس ورڈ",
        "newpassword": "نواں پاس ورڈ",
        "retypenew": "نواں پاس ورڈ ولدا لکھو",
+       "resetpass_submit": "پاس ورڈ بݨاؤ تے لاگ ان تھیوو",
+       "changepassword-success": "تہاݙا پاس ورڈ تبدیل تھی ڳیا!",
        "botpasswords": "بوٹ پاس ورڈ",
        "botpasswords-label-appid": "بوٹ ناں:",
        "botpasswords-label-create": "بݨاؤ",
        "preview": "نمائش",
        "showpreview": "نمائش",
        "showdiff": "تبدیلیاں ݙکھاؤ",
-       "subject-preview": "موضوع دی نمائش:",
+       "subject-preview": "موضوع دا ݙکھالا:",
        "blockedtitle": "ورتݨ آلا بلاک ہے",
        "blockednoreason": "کوئی وجہ نی ݙتی ڳئی",
        "loginreqtitle": "لاگ ان ضروری ہے",
        "template-semiprotected": "(نیم محفوظ)",
        "hiddencategories": "ایہ ورقہ {{PLURAL:$1|1 لُکے زمریاں|$1 لکا زمرہ }} وچ شامل ہے:",
        "permissionserrors": "خطائے اجازت",
+       "permissionserrorstext-withaction": "انہاں {{PLURAL:$1|وجہ|وجوہات}} پاروں تہاکوں$2 دی اجازت کائنی",
        "moveddeleted-notice": "ایہ ورقہ مٹایا ڳیا ہے۔ مٹاوݨ دا لاگ،حفاظت دا لاگ تے ورقہ ٹورݨ دا لاگ  حوالے کیتے ہیٹھاں ݙتے ہوئے ہن۔",
        "log-fulllog": "پورا لاگ ݙیکھو",
+       "postedit-confirmation-created": "ورقہ بݨ ڳیا ہے۔",
+       "postedit-confirmation-restored": "ورقہ بحال تھی ڳئے",
+       "postedit-confirmation-saved": "تہاݙی تبدیلی محفوظ تھی ڳئی ہے۔",
        "content-model-wikitext": "ویکی متن",
        "content-model-text": "سادہ متن",
        "content-model-javascript": "جاوا  سکرپٹ",
        "revdelete-radio-set": "پوشیدہ",
        "revdelete-radio-unset": "ظاہر",
        "revdelete-log": "سبب:",
+       "pagehist": "ورقے دی تاریخ",
        "deletedhist": "مٹایا ہویا تاریخچہ",
        "revdelete-reasonotherlist": "ہور وجہ",
        "revdelete-edit-reasonlist": "مٹاوݨ دی وجہ لکھو",
        "prefs-personal": "پروفائل",
        "prefs-rc": "نویاں تبدیلیاں",
        "prefs-watchlist": "نظریں ہیٹھ فہرست",
+       "prefs-resetpass": "پاس ورڈ تبدیل کرو",
        "prefs-rendering": "شکل و صورت",
        "saveprefs": "بچاؤ",
        "searchresultshead": "ڳولو",
        "prefs-advancedrendering": "اعلیٰ اختیارات",
        "prefs-advancedsearchoptions": "اعلیٰ اختیارات",
        "prefs-advancedwatchlist": "اعلیٰ اختیارات",
+       "prefs-displayrc": "ݙکھاوݨ دے اختیارات",
+       "prefs-displaywatchlist": "ݙکھاوݨ دے اختیارات",
        "prefs-tokenwatchlist": "ٹوکن",
        "prefs-diffs": "فرق",
        "userrights-user-editname": "ورتݨ آلا ناں درج کرو:",
        "group-user-member": "{{GENDER:$1|ورتݨ آلا}}",
        "grouppage-bot": "{{ns:project}}:بوٹ",
        "grouppage-sysop": "{{ns:project}}:ایڈمنسٹریٹر",
+       "right-move": "ورقے ٹورو",
+       "right-movefile": "فائلاں ٹورو",
        "right-upload": "فائلاں چڑھاؤ",
        "right-writeapi": "اے پی آئی تحریر دا استعمال",
        "right-delete": "ورقے مٹاؤ",
        "grant-group-email": "ای میل بھیجو",
        "grant-createaccount": "کھاتے کھولو",
        "grant-basic": "بنیادی حقوق",
-       "newuserlogpage": "یوزر بنݨاوݨ آلی لاگ",
+       "newuserlogpage": "کھاتہ بݨاوݨ آلی لاگ",
        "rightslog": "ورتݨ والے دے حقاں دی لاگ",
        "action-read": "ایہ ورقہ پڑھو",
        "action-edit": "ایں ورقے تے لکھو",
        "rcfilters-filter-minor-label": "معمولی تبدیلیاں",
        "rcfilters-filtergroup-lastRevision": "موجودہ حالت",
        "rcfilters-filter-lastrevision-label": "موجودہ حالت",
-       "rclistfrom": "$3 $2 توں ہونے آلیاں نویاں تبدیلیاں ݙکھاؤ",
+       "rclistfrom": "$3 $2 توں تھیوݨ آلیاں نویاں تبدیلیاں ݙکھاؤ",
        "rcshowhideminor": "$1 معمولی تبدیلیاں",
        "rcshowhideminor-show": "ݙیکھاؤ",
        "rcshowhideminor-hide": "لُکاؤ",
        "recentchangeslinked-feed": "رلدیاں ملدیاں تبدیلیاں",
        "recentchangeslinked-toolbox": "رلدیاں ملدیاں تبدیلیاں",
        "recentchangeslinked-title": "\"$1\" دے متعلقہ تبدیلیاں",
+       "recentchangeslinked-summary": "ایہ انہاں نویاں تبدیلیاں دی لسٹ ہے جہڑیاں خاص ورقے نال جُڑے ہوئے ورقیاں( یا خاص قسم دے ممبراں) وچ تھیاں ہن۔\nتہاݙی [[Special:Watchlist|اکھیں ہیٹھ ورقے]] <strong>موٹے</strong> نظر آسن۔",
        "recentchangeslinked-page": "ورقے دا ناں",
        "recentchangeslinked-to": "کھلے ہوئے ورقے دی بجائے ایندے نال جُڑے ہوئے ورقے دیاں تبدیلیاں ݙکھاؤ",
        "upload": "فائل چڑھاؤ",
        "newpages": "نویں ورقے",
        "newpages-submit": "ݙِکھاؤ",
        "newpages-username": "ورتݨ آلا ناں:",
-       "move": "ٹرو",
+       "move": "ٹورو",
        "pager-newer-n": "{{PLURAL:$1|newer 1|زیادہ نواں $1}}",
        "pager-older-n": "{{PLURAL:$1|قدیم}} $1",
        "apisandbox-unfullscreen": "ورقہ ݙکھاؤ",
        "watchlistfor2": "$1 تے $2 کیتے",
        "watch": "اکھ تلے رکھو",
        "unwatch": "اکھ ہیٹھوں ہٹاؤ",
+       "watchlist-details": "{{PLURAL:$1|$1 ورقہ ہے|$1 ورقے ہن}} تہاݙیاں نظراں ہیٹھ (تے ڳالھ مہاڑ آلے ورقے).",
        "wlshowlast": "ݙیکھاؤ چھیکڑی $1 گھنٹے $2 ݙینہ",
        "watchlist-hide": "لُکاؤ",
        "watchlist-submit": "ݙِکھاؤ",
        "logentry-delete-restore": "$1 {{GENDER:$2|بحال تھی ڳیوہے}} page $3 ($4)",
        "revdelete-content-hid": "مواد لکیا",
        "logentry-move-move": "$1 {{جنس:$2|پلٹی}} ورقہ $3 توں $4",
+       "logentry-move-move-noredirect": "$1 نے $3 کوں $4 آلے پاسے ریڈائرکٹ کیتے ٻاڄھ{{GENDER:$2|منتقل کیتے}}",
        "logentry-move-move_redir": "$1 نے رجوع مکرر ہٹا تے ورقہ $3 کوں $4 آلے پاسے {{GENDER:$2|منتقل کیتا}}",
+       "logentry-patrol-patrol-auto": "$1 نے ورقہ $3 دے نسخہ $4 کوں خودکار طور تے گشت کیتا ہویا {{GENDER:$2|نشان زد کیتا}}",
        "logentry-newusers-create": "صارف کھاتہ $1 {{GENDER:$2|بݨایا ڳیا}}",
        "logentry-newusers-autocreate": "صارف کھاتہ $1 خودکار طور  {{GENDER:$2|تخلیق تھیا}}",
        "logentry-upload-upload": "$1 {{GENDER:$2|اپلوڈ}} $3",
index e99c7ad..3997ac7 100644 (file)
        "rcfilters-empty-filter": "Ni dejavnih filtrov. Prikazani so vsi prispevki.",
        "rcfilters-filterlist-title": "Filtri",
        "rcfilters-filterlist-whatsthis": "Kako to deluje?",
-       "rcfilters-filterlist-feedbacklink": "Podajte povratne informacije o novih (preizkusnih) filtrih",
+       "rcfilters-filterlist-feedbacklink": "Povejte nam, kaj menite o teh (novih) orodjih za filtriranje",
        "rcfilters-highlightbutton-title": "Označi rezultate",
        "rcfilters-highlightmenu-title": "Izberite barvo",
        "rcfilters-highlightmenu-help": "Izberite barvo za označitev te lastnosti",
        "rcfilters-liveupdates-button": "Posodobitve v živo",
        "rcfilters-liveupdates-button-title-on": "Izklopi posodobitve v živo",
        "rcfilters-liveupdates-button-title-off": "Prikaži nove spremembe, ko se zgodijo",
-       "rcfilters-watchlist-markSeen-button": "Označi vse spremembe kot pregledane",
+       "rcfilters-watchlist-markseen-button": "Označi vse spremembe kot pregledane",
+       "rcfilters-watchlist-edit-watchlist-button": "Uredite svoj seznam nadzorovanih strani",
+       "rcfilters-watchlist-showupdated": "Spremembe strani, ki jih niste obiskali od zadnje spremembe, so prikazane <strong>krepko</strong>, z močnimi oznakami.",
        "rcnotefrom": "{{PLURAL:$5|Navedena je sprememba|Navedeni sta spremembi|Navedene so spremembe}} od <strong>$3 $4</strong> dalje (prikazujem jih do <strong>$1</strong>).",
        "rclistfromreset": "Ponastavi izbiro datuma",
        "rclistfrom": "Prikaži spremembe od $3 $2 naprej",
        "unwatchthispage": "Prenehaj opazovati stran",
        "notanarticle": "Ni članek",
        "notvisiblerev": "Redakcija je bila izbrisana",
-       "watchlist-details": "Na vašem spisku nadzorov {{PLURAL:$1|je $1 stran|sta $1 strani|so $1 strani|je $1 strani}}; pogovorne strani niso štete posebej.",
+       "watchlist-details": "Na vašem spisku nadzorov {{PLURAL:$1|je $1 stran|sta $1 strani|so $1 strani|je $1 strani}} (plus pogovorne strani).",
        "wlheader-enotif": "Obveščanje po elektronski pošti je omogočeno.",
        "wlheader-showupdated": "Strani, spremenjene od vašega zadnjega ogleda, so prikazane '''krepko'''.",
        "wlnote": "{{PLURAL:$1|Navedena je zadnja|Navedeni sta zadnji|Navedene so zadnje|Navedenih je zadnjih}} <strong>$1</strong> {{PLURAL:$1|sprememba|spremembi|spremembe|sprememb}} v {{PLURAL:$2|zadnji <strong>$2</strong> uri|zadnjih <strong>$2</strong> urah}}, od $3, $4.",
index 2593dad..4940ba8 100644 (file)
        "cannotlogin-title": "Пријава није могућа",
        "cannotlogin-text": "Пријава није могућа",
        "cannotloginnow-title": "Пријава тренутно није могућа",
-       "cannotloginnow-text": "Ð\9fÑ\80иÑ\98ава Ð½Ð¸Ñ\98е Ð¼Ð¾Ð³Ñ\83Ñ\9bа ÐºÐ¾Ñ\80иÑ\88Ñ\9bеÑ\9aем $1",
+       "cannotloginnow-text": "Ð\9fÑ\80иÑ\98ава Ð½Ð¸Ñ\98е Ð¼Ð¾Ð³Ñ\83Ñ\9bа ÐºÐ°Ð´Ð° Ñ\81е ÐºÐ¾Ñ\80иÑ\81Ñ\82и $1.",
        "cannotcreateaccount-title": "Отварање налога није могуће",
        "yourdomainname": "Домен:",
        "password-change-forbidden": "Не можете да промените лозинку на овом викију.",
        "botpasswords-label-delete": "Обриши",
        "botpasswords-label-resetpassword": "Ресетуј лозинку",
        "botpasswords-label-grants-column": "Одобрено",
-       "botpasswords-bad-appid": "\"$1\" није валидан назив бота",
+       "botpasswords-bad-appid": "„$1” није валидан назив бота.",
        "botpasswords-insert-failed": "Неуспешно додавање бота \"$1\". Да ли је већ додат?",
+       "botpasswords-update-failed": "Није могуће ажурирати бота \"$1\". Да ли је обрисан?",
        "botpasswords-created-title": "Направљена лозинка бота",
        "botpasswords-created-body": "Лозинка за бота \"$1\" корисника \"$2\" је направљена.",
        "botpasswords-updated-title": "Лозинка бота промењена",
+       "botpasswords-updated-body": "Лозинка за бота \"$1\" корисника \"$2\" је ажурирана.",
        "botpasswords-deleted-title": "Обрисана лозинка бота",
+       "botpasswords-deleted-body": "Лозинка за бота \"$1\" корисника \"$2\" је обрисана.",
+       "botpasswords-no-provider": "BotPasswordsSessionProvider није доступан.",
        "resetpass_forbidden": "Лозинка не може бити промењена",
        "resetpass_forbidden-reason": "Лозинке није могуће променити: $1",
        "resetpass-no-info": "Морате бити пријављени да бисте приступили овој страници.",
        "content-model-css": "CSS",
        "content-json-empty-object": "Празан објекат",
        "content-json-empty-array": "Празан низ",
+       "deprecated-self-close-category": "Странице које користе невалидан самозатварајући HTML таг.",
        "duplicate-args-warning": "<strong>Упозорење:</strong> [[:$1]] позива [[:$2]] са више од једне вредности за параметар „$3“. Само последња наведена вредност ће бити коришћена.",
        "duplicate-args-category": "Странице с дуплираним аргументима код позива шаблона",
        "duplicate-args-category-desc": "Страница садржи позиве шаблона који користе двоструке аргументе, као што су <code><nowiki>{{foo|bar=1|bar=2}}</nowiki></code> или <code><nowiki>{{foo|bar|1=baz}}</nowiki></code>.",
        "grant-group-file-interaction": "Уређивање датотека",
        "grant-group-watchlist-interaction": "Уређивање вашег списка надгледања",
        "grant-group-email": "Пошаљи имејл",
+       "grant-group-other": "Разне активности",
        "grant-blockusers": "Блокирање и деблокирање корисника",
        "grant-createaccount": "Отварање налога",
        "grant-createeditmovepage": "Прављење, уређивање и премештање страница",
        "grant-editprotected": "Уређивање заштићених страница",
        "grant-highvolume": "Масовно уређивање",
        "grant-patrol": "Патролирање измена",
+       "grant-privateinfo": "Приступи приватним информацијама",
        "grant-protect": "Закључавање и откључавање страница",
        "grant-rollback": "Враћање измена",
        "grant-sendemail": "Слање имејлова другим корисницима",
        "action-userrights-interwiki": "уређивање корисничких права на другим викијима",
        "action-siteadmin": "закључавање или откључавање базе података",
        "action-sendemail": "слање имејлова",
+       "action-editmyoptions": "уређивање ваших подешавања",
        "action-editmywatchlist": "измену сопственог списак надгледања",
        "action-viewmywatchlist": "преглед вашег списак надгледања",
        "action-viewmyprivateinfo": "прегледање ваших личних података",
        "action-managechangetags": "прављење и (де)активирање ознака",
        "action-applychangetags": "додавање ознака на ваше измене",
        "action-changetags": "додавање и уклањање разних ознака на појединачним изменама и уносима у дневницима",
+       "action-deletechangetags": "Обриши ознаке из базе података",
        "action-purge": "чишћење привремене меморије ове странице",
        "nchanges": "$1 {{PLURAL:$1|измена|измене|измена}}",
        "enhancedrc-since-last-visit": "$1 {{PLURAL:$1|измена од ваше последње посете}}",
        "enhancedrc-history": "историја",
        "recentchanges": "Скорашње измене",
-       "recentchanges-legend": "Ð\9fоÑ\81Ñ\82авке скорашњих измена",
+       "recentchanges-legend": "Ð\9eпÑ\86иÑ\98е скорашњих измена",
        "recentchanges-summary": "Пратите скорашње измене на овој страници.",
        "recentchanges-noresult": "Нема промена у задатом времену за задате критеријуме.",
        "recentchanges-feed-description": "Пратите скорашње измене уз помоћ овог довода.",
        "rcfilters-tag-remove": "Обриши $1",
        "rcfilters-legend-heading": "<strong>Списак скраћеница:</strong>",
        "rcfilters-other-review-tools": "<strong>Остали алати за преглед</strong>",
+       "rcfilters-group-results-by-page": "Групиши резултате по страницама",
        "rcfilters-grouping-title": "Груписање",
        "rcfilters-activefilters": "Активни филтери",
        "rcfilters-advancedfilters": "Напредни филтери",
        "rcfilters-hours-title": "Претходних неколико сати",
        "rcfilters-days-show-days": "$1 {{PLURAL:$1|дан|дана}}",
        "rcfilters-days-show-hours": "$1 {{PLURAL:$1|сат|сата}}",
+       "rcfilters-highlighted-filters-list": "Истакнуто: $1",
        "rcfilters-quickfilters": "Сачувани филтери",
+       "rcfilters-quickfilters-placeholder-title": "Везе још увек нису упамћене",
        "rcfilters-savedqueries-defaultlabel": "Сачувани филтери",
        "rcfilters-savedqueries-rename": "Преименуј",
        "rcfilters-savedqueries-setdefault": "Постави као подразумевано",
        "rcfilters-savedqueries-unsetdefault": "Уклони као подразумевано",
        "rcfilters-savedqueries-remove": "Уклони",
        "rcfilters-savedqueries-new-name-label": "Име",
+       "rcfilters-savedqueries-new-name-placeholder": "Опиши сврху филтера",
        "rcfilters-savedqueries-apply-label": "Направи филтер",
+       "rcfilters-savedqueries-apply-and-setdefault-label": "Направи подразумевани филтер",
        "rcfilters-savedqueries-cancel-label": "Откажи",
        "rcfilters-savedqueries-add-new-title": "Сачувај тренутне поставке филтера",
        "rcfilters-restore-default-filters": "Враћање подразумеваних филтера",
        "rcfilters-clear-all-filters": "Уклони све филтере",
        "rcfilters-show-new-changes": "Погледајте најновије измене",
        "rcfilters-search-placeholder": "Филтер скорашњих измјена (претражите или почните куцати)",
+       "rcfilters-invalid-filter": "Невалидан филтер",
        "rcfilters-empty-filter": "Нема активних филтера. Сви доприноси су приказани.",
        "rcfilters-filterlist-title": "Филтери",
        "rcfilters-filterlist-whatsthis": "Како ово функционише?",
        "rcfilters-filter-editsbyself-description": "Ваши доприноси.",
        "rcfilters-filter-editsbyother-label": "Измене других",
        "rcfilters-filter-editsbyother-description": "Све измене осим Ваших.",
+       "rcfilters-filtergroup-userExpLevel": "Корисничка регистрација и искуство",
        "rcfilters-filter-user-experience-level-registered-label": "Регистровани",
        "rcfilters-filter-user-experience-level-registered-description": "Пријављени уредници.",
        "rcfilters-filter-user-experience-level-unregistered-label": "Нерегистровани",
        "rcfilters-filter-humans-label": "Човјек (није бот)",
        "rcfilters-filter-patrolled-label": "Патролирано",
        "rcfilters-filter-unpatrolled-label": "Непатролирано",
+       "rcfilters-filtergroup-significance": "Значај",
        "rcfilters-filter-minor-label": "Мање измјене",
+       "rcfilters-filter-major-label": "Значајне промене",
+       "rcfilters-filter-major-description": "Промене означене као значајне.",
        "rcfilters-filtergroup-watchlist": "Странице на списку надгледања",
        "rcfilters-filter-watchlist-watched-label": "На списку надгледања",
        "rcfilters-filter-watchlist-watched-description": "Измене страница на Вашем списку надгледања",
        "rcfilters-filter-lastrevision-description": "Само најновија измена на страници.",
        "rcfilters-filter-previousrevision-label": "Раније измене",
        "rcfilters-filter-previousrevision-description": "Све измене које нису најскорашњије измене странице.",
+       "rcfilters-filter-excluded": "Изостављено",
+       "rcfilters-tag-prefix-namespace-inverted": "<strong>:није</strong> $1",
+       "rcfilters-exclude-button-off": "Изостави означено",
        "rcfilters-view-advanced-filters-label": "Напредни филтери",
        "rcfilters-view-namespaces-tooltip": "Филтер резултата према именском простору",
-       "rcfilters-view-tags-tooltip": "Филтер резултата према ознаци измјене",
+       "rcfilters-view-tags-tooltip": "Филтер резултата према ознаци измене",
        "rcnotefrom": "Испод {{PLURAL:$5|је измена|су измене}} од <strong>$3, $4</strong> (до <strong>$1</strong> приказано).",
        "rclistfromreset": "Ресетуј одабир датума",
        "rclistfrom": "Прикажи нове измене почев од $2 $3",
index 8f103a9..64a7353 100644 (file)
        "enhancedrc-since-last-visit": "$1 {{PLURAL:$1|izmena od vaše poslednje posete}}",
        "enhancedrc-history": "istorija",
        "recentchanges": "Skorašnje izmene",
-       "recentchanges-legend": "Postavke skorašnjih izmena",
+       "recentchanges-legend": "Opcije skorašnjih izmena",
        "recentchanges-summary": "Pratite skorašnje izmene na ovoj stranici.",
        "recentchanges-noresult": "Nema promena u zadatom vremenu za zadate kriterijume.",
        "recentchanges-feed-description": "Pratite skorašnje izmene uz pomoć ovog dovoda.",
index e3d0271..54e4498 100644 (file)
        "laggedslavemode": "Awas: kandungan kaca bisa baé teu mutahir.",
        "readonly": "pangkalan data dikonci",
        "enterlockreason": "Asupkeun alesan pikeun ngonci, kaasup kira-kira iraha konci ieu rék dibuka",
-       "readonlytext": "pangkalan data kiwar keur di konci pikeun éntri anyar sarta parobahan séjénna, meureun pikeun pangropéa pangkalan datarutin, nu satutasna mah bakal normal deui. Kuncén nu ngonci ngécéskeun kieu:\n\n$1",
+       "readonlytext": "pangkalan data kiwar keur di konci pikeun éntri anyar sarta parobahan séjénna, meureun pikeun pangropéa pangkalan datarutin, nu satutasna mah bakal normal deui. Sistim kuncén nu ngonci ngécéskeun kieu:\n\n$1",
        "missing-article": "Pangkalan data teu manggihan téks tina kaca nu sakuduna aya, nyaéta \"$1\" $2.\n\nHal ieu biasana disababkeun ku ayana tutumbu béda atawa jujutan heubeul ka hiji kaca nu geus dihapus.\n\nLamun lain ieu sababna, Anjeun meureun geus manggihan bug dina pakakas lemes.\nMangga laporkeun ha ieu ka salasaurang [[Special:ListUsers/sysop|Kuncén]], bari jeung nyebutkeun alamat URL nu dituju.",
        "missingarticle-rev": "(révisi#: $1)",
        "missingarticle-diff": "(Béda: $1, $2)",
        "protectedinterface": "Ieu kaca nyadiakeun téks antarmuka pikeun sopwér di ieu wiki, ku kkituna dikonci pikeun nyingkahan \nanu ngaruksak.\nPikeun nambahkeun atawa ngarobah tarjamahan pikeun sakabéh wiki, buka [https://translatewiki.net/ translatewiki.net], proyék lokalisasi MediaWiki.",
        "editinginterface": "<strong>Awas:</strong> Anjeun keur ngédit kaca nu dipaké pikeun nyadiakeun téks antarmuka pikeun sopwérna.\nParobahan kana ieu kaca bakal mangaruhan pidangan antarmuka pikeun pamaké séjén di ieu wiki.",
        "translateinterface": "Pikeun nambahkeun atawa ngarobah tarjamah keur sakabéh wiki, paké [https://translatewiki.net/ translatewiki.net], proyék lokalisasi MediaWiki.",
-       "cascadeprotected": "Kaca ieu geus dikonci ti éditan alatan disartakeun di {{PLURAL:$1|kaca|kaca-kaca}} katut anu geus dikonci kalawan pilihan \"runtun\": $2",
+       "cascadeprotected": "Kaca ieu geus dikonci ti éditan alatan ditransklusikeun dina {{PLURAL:$1|kaca|kaca-kaca}} katut anu geus dikonci kalawan pilihan \"runtun\": $2",
        "namespaceprotected": "Anjeun teu ngabogaan hak pikeun ngédit kaca di ngaranspasi '''$1'''.",
        "customcssprotected": "Anjeun teu teu diwenangkeun pikeun ngédit ieu kaca CSS, sabab ngandung setélan pribadi kontributor séjén.",
        "customjsprotected": "Anjeun teu teu diwenangkeun pikeun ngédit ieu kaca JavaScript, sabab ngandung setélan pribadi kontributor séjén.",
        "mypreferencesprotected": "Anjeun teu boga kawenangan pikeun ngédit préferénsi anjeun.",
        "ns-specialprotected": "Kaca dina ngaranspasi {{ns:special}} teu bisa di édit.",
        "titleprotected": "Ieu judul dikonci ku [[User:$1|$1]] kalawan alesan <em>$2</em>.",
-       "filereadonlyerror": "Berkas \"$1\" teu bisa dirobah kusabab répositori \"$2\" keur dina mode ukur-maca.\n\nKuncén anu ngonci méré alesan: \"$3\".",
+       "filereadonlyerror": "Berkas \"$1\" teu bisa dirobah kusabab répositori \"$2\" keur dina mode ukur-maca.\n\nSistim kuncén anu ngonci méré alesan: \"$3\".",
        "invalidtitle-knownnamespace": "Judul henteu sah kusabab ngandung ngaranspasi \"$2\" jeung téks \"$3\"",
        "invalidtitle-unknownnamespace": "Judul henteu sah kusabab ngandung angka ngaranspasi $1 jeung tulisan \"$2\"",
        "exception-nologin": "Henteu asup log",
        "cannotloginnow-title": "Teu bisa asup log ayeuna",
        "cannotloginnow-text": "Kaluar log teu mungkin bisa nalika keur ngagunakeun $1.",
        "cannotcreateaccount-title": "Teu bisa nyieun akun",
+       "cannotcreateaccount-text": "Nangtukeun akun langsung teu aktif di ieu wiki.",
        "yourdomainname": "Domain anjeun",
        "password-change-forbidden": "Anjeun teu bisa ngarobah kecap sandi dina ieu wiki.",
        "externaldberror": "Aya kasalahan dina pangkalan data oténtikasi luar, atawa anjeun mémang teu diwenangkeun pikeun ngaropéa akun luar anjeun.",
        "userlogin-resetpassword-link": "Poho kecap sandi?",
        "userlogin-helplink2": "Pitulung asup log",
        "userlogin-loggedin": "Anjeun geus asup log salaku {{GENDER:$1|$1}}.\nPaké pormulir di handap pikeun asup log salaku pamaké séjén.",
+       "userlogin-reauth": "Anjeun kudu asup log deui pikeun mariksa yén anjeun téh {{GENDER:$1|$1}}",
        "userlogin-createanother": "Jieun akun séjén",
        "createacct-emailrequired": "Alamat surélék:",
        "createacct-emailoptional": "Alamat surélék (teu wajib)",
        "createacct-email-ph": "Asupkeun alamat surélék anjeun",
        "createacct-another-email-ph": "Asupkeun alamat surélék",
        "createaccountmail": "Paké kecap sandi acak sarta kirim ka alamat surélék",
+       "createaccountmail-help": "Bisa dipaké pikeun nyieun akun jang batur tanpa kudu nyaho kecap sandina.",
        "createacct-realname": "Ngaran asli (teu wajib)",
        "createacct-reason": "Alesan",
        "createacct-reason-ph": "Naha bet nyieun akun séjén",
        "nocookiesnew": "Akun pamaké geus dijieun, tapi anjeun can asup log. {{SITENAME}} maké ''cookies'' pikeun ngalog pamaké. Anjeun boga ''cookies'' nu ditumpurkeun. Mangga fungsikeun, teras asup log migunakeun sandiasma sarta kecap sandi anu anyar.",
        "nocookieslogin": "{{SITENAME}} migunakeun ''cookies'' pikeun ngasupkeun pamaké kana log. Anjeun boga ''cookies'' nu ditumpurkeun. Mangga pungsikeun sarta cobian deui.",
        "nocookiesfornew": "Akun pamaké teu bisa dijieun, kusabab sumberna teu bisa dipastikeun.\nPariksa kukisna bisi tumpur, terus cobaan muat ulang ieu kaca.",
+       "createacct-loginerror": "Akun anjeun geu dijieun, ngan anjeun teu bisa langsung asup log sacara otomatis. Pék tuluykeun kana [[Special:UserLogin|asup log manual]].",
        "noname": "Anjeun teu nuliskeun ngaran pamaké nu sah.",
        "loginsuccesstitle": "Geus asup log",
        "loginsuccess": "Anjeun ayeuna geus asup log ka {{SITENAME}} salaku \"$1\".",
        "wrongpasswordempty": "Sandina can kaeusian. Cobaan deui!",
        "passwordtooshort": "Sandina kudu diwangun ku sahanteuna {{PLURAL:$1|1 karakter|$1 karakter}}.",
        "passwordtoolong": "Kecap sandi teu bisa leuwih ti {{PLURAL:$1|1 karakter|$1 karakter}}.",
+       "passwordtoopopular": "Kecap sandi nu guyub teu bisa dipaké. Mangga pilih kecap sandi nu béda.",
        "password-name-match": "Kecap sandi anjeun kudu béda ti sandiasma.",
        "password-login-forbidden": "Sandiasma jeung sandina teu bisa dipaké.",
        "mailmypassword": "Setél ulang kecap sandi",
        "changepassword-success": "Kecap sandi Anjeun geus laksana dirobah!",
        "changepassword-throttled": "Anjeun geus loba teuing nyobaan asup log.\nTungguan $1 méméh nyobaan deui.",
        "botpasswords": "Kecap sandi bot",
+       "botpasswords-summary": "<em>Kecap sandi bot</em> ngamumkinkeun aksés kana akun pamaké ngagunakeun API tanpa maké krédensial asup log utama éta akun. Hak pamaké nu nyangkaruk nalika asup log kalawn kecap sandi bot meureun bakal diwatesan.\n\nUpama anjeun teu apal kunaon anjeun mikahayang ieu lalampahan, alusna mah ulah dilakonan. Saenyana euweuh jalma lian nu digaékeun pikeun nyieun sarta nyumerahkeun kecap sandi ieu bot ka manéhna.",
        "botpasswords-disabled": "Kecap sandi bot dipareuman.",
        "botpasswords-no-central-id": "Pikeun migunakeun kecap sandi bot, anjeun kudu asup log ka akun museur heula.",
        "botpasswords-existing": "Kecap sandi bot sayaga",
        "botpasswords-label-grants": "Aksés nu dibikeun:",
        "botpasswords-label-grants-column": "Diwidian",
        "botpasswords-bad-appid": "Ngaran bot \"$1\" teu sah.",
+       "botpasswords-insert-failed": "Gagal nambahkeun ngaran bot \"$1\". Éta geus pernah ditambahkeun sugah?",
        "botpasswords-update-failed": "Gagal nganyarkeun ngaran bot \"$1\". Baheula pernah dipupus kitu?",
        "botpasswords-created-title": "Kecap sandi bot dijieun",
        "botpasswords-created-body": "Kecap sandi pikeun ngaran bot \"$1\" ti pamaké \"$2\" geus dijieun.",
        "botpasswords-updated-body": "Kecap sandi pikeun ngaran bot \"$1\" ti pamaké \"$2\" geus dianyarkeun.",
        "botpasswords-deleted-title": "Kecap sandi bot dihapus",
        "botpasswords-deleted-body": "Kecap sandi pikeun ngaran bot \"$1\" ti pamaké \"$2\" geus dipupus.",
+       "botpasswords-no-provider": "BotPasswordsSessionProvider teu sayaga.",
+       "botpasswords-restriction-failed": "Wates kecap sandi ngahalangan ieu asup log.",
+       "botpasswords-invalid-name": "Ngaran pamaké nu dibikeun teu ngandung pamisah kecap sandi bot (\"$1\").",
+       "botpasswords-not-exist": "Pamaké \"$1\" teu miboga kecap sandi bot nu ngaranna \"$2\".",
        "resetpass_forbidden": "Sandi henteu bisa dirobah",
        "resetpass_forbidden-reason": "Kecap sandi teu bisa diganti: $1",
        "resetpass-no-info": "Anjeun kudu asup log pkeun bisa muka ieu kaca sacara langsung.",
        "passwordreset-emailtext-user": "Pamaké $1 di {{SITENAME}} ménta nyetél ulang sandi anjeun di {{SITENAME}} ($4). {{PLURAL:$3|Akun}} di handap tumali jeung alamat surélék ieu:\n\n$2\n\n{{PLURAL:$3|Ieu sandi saheulaanan}} bakal kadaluwarsa dina témpo {{PLURAL:$5|sapoé|$5 poé}}.\nAnjeun kudu asup sarta milih sandi anyar ayeuna. Lamun henteu rumasa nyieun ieu pamundut atawa lamun geus inget sandi asli sarta moal ngarobah deui, ieu talatah teu kudu dipaliré.",
        "passwordreset-emailelement": "Sandiasma: \n$1\n\nSandi saheulaanan: \n$2",
        "passwordreset-emailsentemail": "Mun ieu alamat surélék patalian jeung akun anjeun, mangka surélék pikeun nyetél ulang kecap sandi bakal dikirim.",
+       "passwordreset-emailsentusername": "Mun ieu alamat surélék patalian jeung akun anjeun, mangka surélék pikeun nyetél ulang kecap sandi bakal dikirim.",
        "passwordreset-nocaller": "Panggero kudu dibikeun",
        "passwordreset-nosuchcaller": "Panggero can aya: $1",
+       "passwordreset-ignored": "Pamulangan kecap sandi teu kasiwer. Sugan panyadia can diatur?",
        "passwordreset-invalidemail": "Alamat surélék teu sah",
        "passwordreset-nodata": "Boh ngaran pamaké, boh alamat surélék teu dibéré",
        "changeemail": "Ganti atawa pupus alamat surélék",
        "userpage-userdoesnotexist": "Akun pamaké \"<nowiki>$1</nowiki>\" tacan kadaptar. Mangga riksa lamun anjeun hoyong ngadamel/ngédit ieu kaca.",
        "userpage-userdoesnotexist-view": "Akun pamaké \"$1\" teu aya dina daptar.",
        "blocked-notice-logextract": "Ieu pamaké keur dipeungpeuk.\nPikeun rujukan, éntri log panungtung dipidangkeun di handap:",
-       "clearyourcache": "<strong>Catet:</strong> Sanggeus nyimpen, anjeun kudu narabas singgahan panyungsi anjeun pikeun nempo parobahanana.\n* <strong>Firefox/Safari:</strong> Tahan <em>Shift</em> bari ngaklik <em>Reload</em>, atawa pencét boh <em>Ctrl-F5</em> atawa <em>Ctrl-R</em> (<em>⌘-R</em> dina Mac)\n* <strong>Google Chrome:</strong> Pencét <em>Ctrl-Shift-R</em> (<em>⌘-Shift-R</em> dina Mac)\n* <strong>Internet Explorer:</strong> Tahan <em>Ctrl</em> bari ngaklik <em>Refresh</em>, atawa pencét <em>Ctrl-F5</em>\n* <strong>Opera:</strong> Kosongkeun singgahan dina <em>Tools → Preferences</em>",
+       "clearyourcache": "<strong>Catet:</strong> Sanggeus nyimpen, anjeun kudu narabas singgahan panyungsi anjeun pikeun nempo parobahanana.\n* <strong>Firefox/Safari:</strong> Tahan <em>Shift</em> bari ngaklik <em>Reload</em>, atawa pencét boh <em>Ctrl-F5</em> atawa <em>Ctrl-R</em> (<em>⌘-R</em> dina Mac)\n* <strong>Google Chrome:</strong> Pencét <em>Ctrl-Shift-R</em> (<em>⌘-Shift-R</em> dina Mac)\n* <strong>Internet Explorer:</strong> Tahan <em>Ctrl</em> bari ngaklik <em>Refresh</em>, atawa pencét <em>Ctrl-F5</em>\n* <strong>Opera:</strong> Indit ka <em>Menu → Settings </em> (<em>Opera → Preferences</em> di Mac) tuluy ka <em>Privacy & security → Clear browsing data → Cached images and files</em>.",
        "usercssyoucanpreview": "Tip:''' Paké tombol \"{{int:showpreview}}\" pikeun nyobaan CSS anyar anjeun méméh nyimpen.",
        "userjsyoucanpreview": "Tip:''' Paké tombol \"{{int:showpreview}}\" pikeun nyobaan JavaScript anyar anjeun méméh nyimpen.",
        "usercsspreview": "'''Inget yén anjeun ukur nyawang css pamaké anjeun, can disimpen!'''",
        "previewnote": "'''Inget yén ieu ukur pratayang, can disimpen.'''\nÉditan anjeun can disimpen!",
        "continue-editing": "Miang ka bagian ngédit",
        "previewconflict": "Sawangan ieu mangrupa eunteung pikeun téks na rohangan ngédit sakumaha bakal katémbong mun ku anjeun disimpen.",
-       "session_fail_preview": "'''Punten! Kami teu bisa ngolah éditan anjeun alatan leungitna data rintakan. Mangga cobian deui. Mun tetep teu bisa, cobi kaluar log lajeng lebet deui.'''",
+       "session_fail_preview": "Hampura, kami teu bisa ngolah éditan anjeun alatan kapupusna data sési.\n\nAjeun meureun geus kaluar log. '''Wayahna riksakeun yén anjeun téh masih asup log kénéh atawa henteu sarta coba sakali deui.'''\nMun masih kénéh teu ngahasil, cobaan [[Special:UserLogout|kaluar log]] tuluy asup log deui, sarta riksakeun yén panyungsi wéb anjeun ngawidian panyimpenan kuki tina ieu situs.",
        "session_fail_preview_html": "Hampura! Kami teu bisa ngolah éditan anjeun lantaran leungitna data rintakan.\n\n<em>Kusabab {{SITENAME}} ngawenangkeun dipakéna HTML atah, pramidangna disumputkeun pikeun nyegah panarajang JavaScript.''</em>\n\n<strong>Mun ieu éditan bener, mangga cobian deui. Mun tetep teu metu, coba [[Special:UserLogout|kaluar log]] heula, terus asup deui.</strong>",
        "token_suffix_mismatch": "'''Éditan anjeun ditolak sabab aplikasi klien Anjeun ngarobah karakter tanda baca dina éditan. Éditan kasebut ditolak keur nyegah kasalahan dina artikel téks. Hal ieu kadang-kadang kajadian lamun Anjeun maké proksi anonim basis web nu masalah.'''",
        "edit_form_incomplete": "'''Sawatara bagian tina wangun éditan teu nepi ka sérver; pariksa deui naha éditan Anjeun tetep gembleng sarta cobaan deui.'''",
        "copyrightwarning2": "Catet yén sadaya kontribusi ka {{SITENAME}} bisa diédit, dirobah, atawa dihapus ku kontributor séjén. Mun anjeun teu miharep tulisan anjeun dirobah, ulah ngintunkeun ka dieu.<br />\nAnjeun ogé mastikeun yén ieu téh pituin tulisan anjeun, atawa salinan ti domain umum atawa sumberdaya bébas séjénna (tempo $1 pikeun écésna).\n'''ULAH NGINTUNKEUN KARYA NU MIBANDA HAK CIPTA TANPA WIDI!'''",
        "editpage-cannot-use-custom-model": "Modél kontén ieu kaca teu bisa dirobah.",
        "longpageerror": "<strong>Éror: téks anu dikirimkeun panjangna {{PLURAL:$1|hiji kilobit|$1 kilobit}}, leuwih ti maksimum {{PLURAL:$2|hiji kilobit|$2 kilobit}}.</strong>\nTeu bisa disimpen.",
-       "readonlywarning": "<strong>Awas: pangkalan data dikonci pikeun diropéa, anjeun moal bisa nyimpen éditan anjeun ayeuna.</strong>\nMun perlu, simpen heula téksna kana berkas téks pikeun diasupkeun deui séjén mangsa.\n\nKuncén anu ngonci pangkalan data méré katerangan: $1",
+       "readonlywarning": "<strong>Awas: pangkalan data dikonci pikeun diropéa, anjeun moal bisa nyimpen éditan anjeun ayeuna.</strong>\nMun perlu, simpen heula téksna kana berkas téks pikeun diasupkeun deui séjén mangsa.\n\nSistim kuncén anu ngonci pangkalan data méré katerangan: $1",
        "protectedpagewarning": "'''AWAS: ieu kaca dikonci sarta ngan bisa dirobah ku pamaké nu statusna kuncén.'''\nÉntri log panungtungan ditémbongkeun di handap:",
        "semiprotectedpagewarning": "'''Catetan''': ieu kaca dikonci sarta ukur bisa dirobah ku pamaké nu geus kadaptar.\nÉntri log panungtung dibéréndélkeun di handap:",
-       "cascadeprotectedwarning": "'''Awas''': ieu kaca dikonci sahingga ukur bisa dirobah ku kuncén, sabab kaasup {{PLURAL:$1|kaca|kaca}} dina panyalindungan-ngaruntuy di handap ieu:",
+       "cascadeprotectedwarning": "<strong>Mangkahadé:</strong> Ieu kaca geus ditangtayungan sangkan bisa diédit ku pamaké kalawan [[Special:ListGroupRights|hak aksés tinangtu]] wungkul lantaran ditransklusikeun dina {{PLURAL:$1|kaca|kaca-kaca}} nu ditangtayungan runtuy:",
        "titleprotectedwarning": "'''Awas: ieu kaca dikonci sarta ngan bisa dijieun ku pamaké anu boga [[Special:ListGroupRights|kawenangan husus]].'''\nÉntri log panungtung dibéréndélkeun di handap:",
        "templatesused": "{{PLURAL:$1|Citakan|Citakan}} nu dipaké dina ieu kaca:",
        "templatesusedpreview": "{{PLURAL:$1|Citakan|Citakan}} nu dipaké dina ieu pramidang:",
        "permissionserrorstext": "Anjeung teu boga kawenangan pikeun peta kitu, kalawan {{PLURAL:$1|alesan|alesan}} di handap ieu:",
        "permissionserrorstext-withaction": "Anjeun teu ngabogaan hak keur $2, kusabab {{PLURAL:$1|alesan|alesan}} katut:",
        "recreate-moveddeleted-warn": "'''Awas: anjeun keur nyieun deui kaca nu geus kungsi dihapus.'''\n\nMangga émutan deui perlu/henteuna nyieun deui ieu artikel.\nPikeun leuwih écés, di handap dibéréndélkeun logna:",
-       "moveddeleted-notice": "Ieu kaca geus dihapus.\nPikeun rujukan, logna tiasa ditingal di handap ieu.",
+       "moveddeleted-notice": "Ieu kaca geus dipupus.\nLog pamupusan, panangtayungan, sarta alihan ti éta kaca nyangkaruk di handap ieu minangka rujukan.",
        "log-fulllog": "Tempo log sakabéhna",
        "edit-hook-aborted": "Éditan dibolaykeun tanpa pedaran.",
        "edit-gone-missing": "Kaca teu bisa dianyarkeun,\nsigana kusabab geus dihapus.",
        "content-not-allowed-here": "Eusi \"$1\" teu diijinan di kaca [[$2]]",
        "editwarning-warning": "Ninggalkeun ieu kaca bakal ngaleungitkeun parobahan anu tas dijieun.\nUpama anjeun geus asup log, anjeun bisa numpurkeun ieu talatah dina bagian \"{{int:prefs-editing}}\" préferénsi anjeun.",
        "editpage-invalidcontentmodel-title": "Modél kontén teu dirojong",
+       "editpage-invalidcontentmodel-text": "Modél kontén \"$1\" teu dirojong.",
        "editpage-notsupportedcontentformat-title": "Format eusi teu dirojong",
        "editpage-notsupportedcontentformat-text": "Format eusi $1 teu dirojong ku modél eusi $2.",
        "content-model-wikitext": "wikitéks",
        "template-loop-category": "Kaca kawalan citakan bulak-balik",
        "parser-template-recursion-depth-warning": "Citakan patumpang tindih ngaleuwihan wates($1)",
        "language-converter-depth-warning": "Parobah basa ngaleuwihan wates jerona ($1)",
+       "node-count-exceeded-category": "Kaca di mana itungan-node kalampau",
+       "node-count-exceeded-category-desc": "Ieu kaca ngaleuwihan node maksimum.",
+       "node-count-exceeded-warning": "Kaca nu ngaleuwihan jumlah node",
        "expansion-depth-exceeded-category": "Kaca-kaca anu jero ékspansina leuwih ti wates",
        "expansion-depth-exceeded-category-desc": "Kacana ngaleuwihan wates jero ékspansina.",
        "expansion-depth-exceeded-warning": "Kaca ngaleuwihan jero ékspansi",
        "mergehistory-fail-bad-timestamp": "Stémpel waktu teu sah.",
        "mergehistory-fail-invalid-source": "Kaca sumber teu sah.",
        "mergehistory-fail-invalid-dest": "Kaca tujuan teu sah.",
+       "mergehistory-fail-permission": "Izin panggabungan jujutan kaca teu nyumponana.",
+       "mergehistory-fail-self-merge": "Kaca asal jeung tujulna sarua.",
+       "mergehistory-fail-timestamps-overlap": "Révisi asal tumpang tindih atawa leuwih anyar batan révisi tujul.",
        "mergehistory-no-source": "Sumber kaca $1 teu aya.",
        "mergehistory-no-destination": "Kaca nu dituju ($1) teu aya.",
        "mergehistory-invalid-source": "Kaca sumber kudu sohéh judulna.",
        "search-category": "(kategori $1)",
        "search-file-match": "(cocog jeung eusi berkas)",
        "search-suggest": "Meureun maksud Anjeun nyaéta: $1",
-       "search-interwiki-caption": "Proyék sawargi",
+       "search-rewritten": "Némbongkeun hasil pikeun $1. Paluruh lain pikeun $2.",
+       "search-interwiki-caption": "Hasil ti proyék sawargi",
        "search-interwiki-default": "Hasil ti $1:",
        "search-interwiki-more": "(saterusna)",
        "search-interwiki-more-results": "hasil lianna",
        "showingresultsinrange": "Di handap dipidangkeun nepi ka {{PLURAL:$1|<strong>1</strong> hasil}} ti #<strong>$2</strong> nepi ka #<strong>$3</strong>.",
        "search-showingresults": "{{PLURAL:$4|Hasil <strong>$1</strong> ti <strong>$3</strong>|Hasil <strong>$1 - $2</strong> ti <strong>$3</strong>}}",
        "search-nonefound": "Euweuh hasil nu cocog jeung kueri.",
+       "search-nonefound-thiswiki": "Euweuh hasil nu cocog jeung pamundutan di ieu situs.",
        "powersearch-legend": "Panéangan tuluy",
        "powersearch-ns": "Téangan di ngaranspasi:",
        "powersearch-togglelabel": "Pariksa:",
        "powersearch-toggleall": "Kabéh",
        "powersearch-togglenone": "Henteu aya",
+       "powersearch-remember": "Inget pilihan pikeun pamaluruhan satuluyna",
        "search-external": "Panéangan luar",
        "searchdisabled": "Punten! Néangan téks lengkep di {{SITENAME}} kanggo samentawis ditumpurkeun pikeun alesan kinerja. Jalaran kitu, saheulaanan anjeun bisa nyungsi di Google di handap ieu. Catet yén indéxna ngeunaan eusi {{SITENAME}} bisa jadi teu mutahir.",
+       "search-error": "Aya kesalahan nalika maluruh: $1",
+       "search-warning": "Aya panginget nalika maluruh: $1",
        "preferences": "Préferénsi",
        "mypreferences": "Préferénsi",
        "prefs-edits": "Jumlah éditan:",
        "prefs-watchlist": "Awaskeuneun",
        "prefs-editwatchlist": "Ropéa awaskeuneun",
        "prefs-editwatchlist-label": "Ropéa éntri anu aya dina awaskeuneun:",
+       "prefs-editwatchlist-edit": "Tempo jeung pupus judul di daptar awaskeuneun anjeun",
+       "prefs-editwatchlist-raw": "Édit daptar awaskeuneun atah",
        "prefs-editwatchlist-clear": "Bersihan aawaseun anjeun",
        "prefs-watchlist-days": "Jumlah poé anu ditémbongkeun dina daptar awaskeuneun:",
        "prefs-watchlist-days-max": "Panglilana $1 {{PLURAL:$1|poé|poé}}",
-       "prefs-watchlist-edits": "Jumlah parobahan maksimum nu ditémbongkeun dina daptar panjang awaskeuneun:",
+       "prefs-watchlist-edits": "Jumlah maksimum parobahan nu ditémbongkeun dina daptar awaskeuneun:",
        "prefs-watchlist-edits-max": "Panglobana: 1000",
        "prefs-watchlist-token": "Token awaskeuneun:",
        "prefs-misc": "Pangaturan rupa-rupa",
        "prefs-help-signature": "Pamanggih dina kaca sawala/obrolan kudu ditandaan \"<nowiki>~~~~</nowiki>\" nu bakal robah jadi tanda tangan anjeun jeung titimangsana.",
        "badsig": "Parafna teu valid; pariksa tag HTML-na geura.",
        "badsiglength": "Tawis leungeun panjang teuing. Kuduna kurang ti $1 {{PLURAL:$1|karaktér|karaktér}}.",
-       "yourgender": "Jenis kelamin:",
-       "gender-unknown": "Moal béja-béja",
+       "yourgender": "Anjeun leuwih resep didéskripsikeunna kumaha?",
+       "gender-unknown": "Nalika nyebut anjeun, pakakas lemes bakal ngagunakeun kekecapan nu nétral waktu diperlukeun",
        "gender-male": "Manéhna ngédit kaca wiki",
        "gender-female": "Manéhna ngédit kaca wiki",
        "email": "Surélék",
-       "prefs-help-realname": "* Ngaran asli (pilihan): mun anjeun milih ngeusian, bakal dipaké pikeun nandaan kontribusi anjeun.",
+       "prefs-help-realname": "Ngaran asli miwatek opsional.\nMun disayagakeun, ieu ngaran bisa dipaké pikeun méré atribusi kana karya anjeun.",
        "prefs-help-email": "Surélék sipatna pilihan, tapi diperlukeun pikeun nyetél ulang sandi lamun anjeun poho.",
        "prefs-help-email-others": "Anjeun ogé bisa milih sangkan bisa disuratan ngaliwatan kaca pamaké atawa obrolan tanpa kudu ngedalkeun saha anjeun sabenerna.",
        "prefs-help-email-required": "Alamat surélék dibutuhkeun.",
        "prefs-displaywatchlist": "Pilihan pidangan",
        "prefs-tokenwatchlist": "Token",
        "prefs-diffs": "Béda",
-       "userrights": "Manajemén hak pamaké",
-       "userrights-lookup-user": "Atur gorombolan pamaké",
+       "userrights": "Hak pamaké",
+       "userrights-lookup-user": "Pilih saurang pamaké",
        "userrights-user-editname": "Asupkeun sandiasma:",
        "editusergroup": "Muat gorombolan pamaké",
-       "editinguser": "Ngarobah hak kontributor '''[[User:$1|$1]]''' $2",
-       "userrights-editusergroup": "Édit gorombolan pamaké",
-       "saveusergroups": "Simpen Grup Pamaké",
+       "editinguser": "Ngarobah hak pamaké pikeun {{GENDER:$1|pamaké}} <strong>[[User:$1|$1]]</strong> $2",
+       "userrights-editusergroup": "Édit gorombolan {{GENDER:$1|pamaké}}",
+       "userrights-viewusergroup": "Témbong gorombolan {{GENDER:$1|pamaké}}",
+       "saveusergroups": "Simpen gorombolan {{GENDER:$1|pamaké}}",
        "userrights-groupsmember": "Anggota ti:",
        "userrights-groupsmember-auto": "Anggota implisit ti:",
-       "userrights-groups-help": "Anjeun bisa ngarobah jumplukan pamaké ieu:\n* Kotak jeung tanda cék mangrupa jumplukan pamaké anu dimaksud\n* Kotak tanpa tanda cék hartosna pamaké ieu lain anggota jumplukan kasebut\n* Tanda * nandakeun yén Anjeun henteu bisa ngabolaykeun jumplukan kasebut lamun Anjeun geus nambahanana, atawa sabalikna.",
+       "userrights-groups-help": "Anjeun bisa ngarobah jumplukan pamaké ieu:\n* Kotak jeung tanda cék mangrupa jumplukan pamaké anu dimaksud\n* Kotak tanpa tanda cék hartosna pamaké ieu lain anggota jumplukan kasebut\n* Tanda * nandakeun yén Anjeun henteu bisa ngabolaykeun jumplukan kasebut lamun Anjeun geus nambahanana, atawa sabalikna.\n* Tanda # nandakeun yén anjeun ngan ukur bisa malikkeun waktu kadaluwarsa kaanggotaan ini gorombolan, tapi anjeun teu bisa majukeun waktu kadaluwarsana.",
        "userrights-reason": "Alesan:",
        "userrights-no-interwiki": "Anjeung teu diwenangkeun ngarobah hak pamaké dina wiki séjén.",
        "userrights-nodatabase": "Pangkalan data $1 euweuh atawa henteu lokal.",
        "userrights-expiry-current": "Kadaluwarsa $1",
        "userrights-expiry-none": "Teu kadaluwarsa",
        "userrights-expiry": "Kadaluwarsa:",
+       "userrights-expiry-existing": "Waktu kadaluwarsa kiwari: $3, $2",
        "userrights-expiry-othertime": "Séjén waktu:",
        "group": "Gorombolan:",
        "group-user": "Pamaké",
        "right-reupload-shared": "Nampik gambar-gambar dina média lokal babarengan",
        "right-upload_by_url": "Unjal berkas tina alamat URL",
        "right-purge": "Ngahapus sindangan tina kaca tanpa kaca konfirmasi",
-       "right-autoconfirmed": "Ngédit kaca nu semi dikonci",
+       "right-autoconfirmed": "Teu dipangaruhan rate limit nu basis IP",
        "right-bot": "Anggap salaku prosés otomatis",
        "right-apihighlimits": "Maké wates leuwih luhur dina kueri API",
        "right-writeapi": "Maké nulis API",
        "right-unblockself": "buka peungpeuk sorangan",
        "right-protect": "Ngarobah hambalan protéksi jeung édit kaca anu dikonci",
        "right-editprotected": "Edit kaca anu dikonci salaku \"{{int:protect-level-sysop}}\"",
+       "right-editcontentmodel": "Édit modél kontén kaca",
        "right-editinterface": "Édit antarbenget pamaké",
        "right-editusercss": "Édit berkas CSS pamaké séjén",
        "right-edituserjs": "Ngédit berkas JS pamaké séjén",
+       "right-editmyusercss": "Édit berkas CSS pamaké anjeun",
+       "right-editmyuserjs": "Édit berkas JavaScript pamaké anjeun",
        "right-viewmywatchlist": "Tempo awaskeuneun anjeun",
        "right-viewmyprivateinfo": "Tempo data pribadi anjeun (alamat surélék, ngaran asli)",
        "right-editmyprivateinfo": "Robah data pribadi anjeun (alamat surélék, ngaran asli)",
        "right-editmyoptions": "Robah préferénsi anjeun",
+       "right-markbotedits": "Nandaan pamalikan révisi minangka éditan bot",
+       "right-noratelimit": "Teu dipangaruhan ku wawatesan jumlah éditan",
        "right-import": "Ngimpor kaca ti wiki séjén",
        "right-importupload": "Ngimpor kaca tina hiji koropak nu dimuat",
        "right-patrol": "Nandaan éditan pamaké séjén minangka geus dipatroli",
        "right-autopatrol": "Ngédit kalayan status éditan sacara otomatis ditandaan geus dipatroli",
        "right-patrolmarks": "Tempo panandaan patroli nuanyar robah",
+       "right-unwatchedpages": "Tempo daptar kaca-kaca nu teu dipariksa",
        "right-mergehistory": "Ngagabungkeun jujutan kaca",
        "right-userrights": "Édit kabeh hak pamaké",
        "right-userrights-interwiki": "Ngédit hak kontributor di wiki lianna",
        "right-siteadmin": "Ngonci jeung muka konci databés",
+       "right-override-export-depth": "Ékspor kaca kaasup kaca-kaca patalian nepi ka kalaputan 5",
        "right-sendemail": "Kirim surélék ka pamaké séjén",
+       "right-managechangetags": "Jieun sarta pareuman [[Special:Tags|tag]]",
+       "right-applychangetags": "Tapelkeun [[Special:Tags|tag]] bareng jeun parobahan pamaké",
+       "right-changetags": "Tambah sarta pupus [[Special:Tags|tag]] arbitrari dina révisi masing-masing jeung éntri log",
+       "right-deletechangetags": "Pupus [[Special:Tags|tag]] tina basisdata",
        "grant-generic": "\"$1\" buntel hak aksés",
        "grant-group-page-interaction": "Interaksi jeung kaca",
        "grant-group-file-interaction": "Interaksi jeung média",
        "grant-group-watchlist-interaction": "Interaksi jeung aawaseun anjeun",
        "grant-group-email": "Kirim surélék",
+       "grant-group-high-volume": "Ngalampahan aktivitas nu loba pisan",
+       "grant-group-customization": "Kustomisasi jeung préférénsi",
+       "grant-group-administration": "Ngalakokan tarékah administratif",
        "grant-group-private-information": "Aksés data pribadi ngeunaan anjeun",
        "grant-group-other": "Lalampahan macem-macem",
        "grant-blockusers": "Peungpeuk sarta teu meungpeuk pamaké",
        "grant-createaccount": "Jieun akun",
        "grant-createeditmovepage": "Jieun, édit, jeung alihkeun kaca",
        "grant-delete": "Pupus kaca, révisi, jeung éntri log",
+       "grant-editinterface": "Ngédit ngaranspasi MediaWiki sarta CSS/JavaScript pamaké",
        "grant-editmycssjs": "Édit CSS/JavaScript pamaké anjeun",
        "grant-editmyoptions": "Édit préférénsi pamaké anjeun",
        "grant-editmywatchlist": "Édit awaskeuneun anjeun",
        "grant-basic": "Aksés dasar",
        "grant-viewdeleted": "Tempo berkas jeung kaca nu dihapus",
        "grant-viewmywatchlist": "Tempo aawaseun anjeun",
+       "grant-viewrestrictedlogs": "Tempo éntri log kawates",
        "newuserlogpage": "Log akun anyar",
        "newuserlogpagetext": "Di handap ieu béréndélan log pamaké anyar.",
        "rightslog": "Log hak pamaké",
        "rightslogtext": "Ieu mangrupa log parobahan hak-hak pamaké.",
        "action-read": "maca ieu kaca",
        "action-edit": "édit kaca ieu",
-       "action-createpage": "mitembeyan kaca anyar",
-       "action-createtalk": "mitembeyan kaca obrolan",
+       "action-createpage": "jieun ieu kaca",
+       "action-createtalk": "jieun ieu kaca sawala",
        "action-createaccount": "jieun ieu akun pamaké",
+       "action-autocreateaccount": "jieun otomatis akun pamaké luar",
        "action-history": "tempo jujutan ieu kaca",
        "action-minoredit": "nandaan ieu éditan salaku minor",
        "action-move": "mindahkeun ieu kaca",
        "action-delete": "ngahapus ieu kaca",
        "action-deleterevision": "mupus révisi",
        "action-deletelogentry": "pupus éntri log",
-       "action-deletedhistory": "nempo jujutan anu geus dihapus ti ieu kaca",
+       "action-deletedhistory": "nempo jujutan kaca anu geus dihapus",
+       "action-deletedtext": "témbong téks révisi anu dihapus",
        "action-browsearchive": "milari kaca nu geus dihapus",
-       "action-undelete": "ngabolaykeun hapusan ieu kaca",
-       "action-suppressrevision": "mariksa jeung nyimpen deui ieu révisi nyumput",
+       "action-undelete": "bolaykeun pamupusan kaca",
+       "action-suppressrevision": "riksa sarta balikkeun révisi nu disamunikeun",
        "action-suppressionlog": "nempo ieu log pribadi",
        "action-block": "meungpeuk ieu pamaké tina ngédit",
        "action-protect": "ngarobah hambalan konci ieu kaca",
+       "action-rollback": "geuwat malikkeun éditan-éditan pamaké panungtung nu ngédit kaca tinangtu",
        "action-import": "impor kaca ti wiki séjén",
+       "action-importupload": "ngimpor ieu kaca tina pamuatan berkas",
        "action-patrol": "Nandaan éditan séjén minangka geus diroris",
        "action-autopatrol": "tandaan éditan anjeun salaku geus diroris",
        "action-unwatchedpages": "témbongkeun béréndélan kaca nu teu diawaskeun",
        "action-userrights-interwiki": "ngarobah hak pamaké di wiki lianna",
        "action-siteadmin": "ngonci atawa muka konci databés",
        "action-sendemail": "ngirim surélék",
+       "action-editmyoptions": "édit préférénsi anjeun",
        "action-editmywatchlist": "robah awaskeuneun anjeun",
+       "action-viewmywatchlist": "Tempo aawaseun anjeun",
        "action-viewmyprivateinfo": "tempo émbaran pribadi anjeun",
        "action-editmyprivateinfo": "robah émbaran pribadi anjeun",
+       "action-editcontentmodel": "ngédit modél kontén hiji kaca",
+       "action-managechangetags": "jieun sarta pareuman tag",
+       "action-applychangetags": "larapkeun tag bareng jeung parobahan anjeun",
+       "action-deletechangetags": "pupus tag tina basis data",
        "action-purge": "hapus sindangan ieu kaca",
        "nchanges": "$1 {{PLURAL:$1|parobahan|parobahan}}",
+       "enhancedrc-since-last-visit": "$1 {{PLURAL:$1|saprak sorang panungtung}}",
        "enhancedrc-history": "jujutan",
        "recentchanges": "Anyar robah",
        "recentchanges-legend": "Pilihan parobahan anyar",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (tempo ogé [[Special:NewPages|béréndélan kaca anyar]])",
        "recentchanges-submit": "Témbongkeun",
        "rcfilters-tag-remove": "Pupus '$1'",
+       "rcfilters-legend-heading": "<strong>Daptar singgetan:</strong>",
+       "rcfilters-other-review-tools": "<strong>Pakakas paninjauan lianna</strong>",
+       "rcfilters-group-results-by-page": "Gorombolkeun hasil dumasar kaca",
+       "rcfilters-grouping-title": "Gorombolkeun",
        "rcfilters-activefilters": "Panyaringan aktif",
+       "rcfilters-advancedfilters": "Panyaringan leuwih jero",
+       "rcfilters-limit-title": "Parobahan pidangkeuneun",
+       "rcfilters-limit-shownum": "Pidangkeun {{PLURAL:$1|parobahan|$1 parobahan}} panungtung",
+       "rcfilters-days-title": "Poé-poé panungtung",
+       "rcfilters-hours-title": "Jam-jam panungtung",
+       "rcfilters-days-show-days": "$1 {{PLURAL:$1|sapoé|poé}}",
+       "rcfilters-days-show-hours": "$1 {{PLURAL:$1|sajam|jam}}",
+       "rcfilters-highlighted-filters-list": "Disorot: $1",
+       "rcfilters-quickfilters": "Saringan kasimpen",
+       "rcfilters-quickfilters-placeholder-title": "Can aya tutumbu kasimpen",
+       "rcfilters-savedqueries-defaultlabel": "Saringan kasimpen",
        "rcfilters-savedqueries-rename": "Robah ngaran",
+       "rcfilters-savedqueries-setdefault": "Atur minangka baku",
+       "rcfilters-savedqueries-unsetdefault": "Pupus minangka baku",
        "rcfilters-savedqueries-remove": "Hapus",
        "rcfilters-savedqueries-new-name-label": "Ngaran",
+       "rcfilters-savedqueries-new-name-placeholder": "Émbarkeun tujuan ieu panyaringan",
+       "rcfilters-savedqueries-apply-label": "Nyieun panyaringan",
+       "rcfilters-savedqueries-apply-and-setdefault-label": "Jieun panyaringan baku",
        "rcfilters-savedqueries-cancel-label": "Bolay",
+       "rcfilters-savedqueries-add-new-title": "Simpen pangaturan ieu saringan",
        "rcfilters-restore-default-filters": "Balikeun panyaringan bawaan",
        "rcfilters-clear-all-filters": "Pupus sakumna panyaringan",
-       "rcfilters-search-placeholder": "Sarinh parobahan panganyarna (langlang atawa mimitian ngetik)",
+       "rcfilters-show-new-changes": "Témbongkeun parobahan panganyarna",
+       "rcfilters-search-placeholder": "Saring parobahan panganyarna (langlang atawa mimitian ngetik)",
        "rcfilters-invalid-filter": "Panyaringan teu sah",
+       "rcfilters-empty-filter": "Euweuh filter aktif. Sakumna kontribusi ditémbongkeun.",
        "rcfilters-filterlist-title": "Saringan",
-       "rcfilters-filterlist-whatsthis": "Naon ieu téh?",
+       "rcfilters-filterlist-whatsthis": "Kumaha bet bisa kieu?",
+       "rcfilters-filterlist-feedbacklink": "Béré eupan balik pikeun saringan uji coba anyar",
        "rcfilters-highlightbutton-title": "Hasil sorotan",
        "rcfilters-highlightmenu-title": "Pilih warna",
        "rcfilters-highlightmenu-help": "Pilih warna pikeun nyorot ieu properti",
        "rcfilters-filter-editsbyself-description": "Kontribusi anjeun.",
        "rcfilters-filter-editsbyother-label": "Éditan ku batur",
        "rcfilters-filter-editsbyother-description": "Sakumna éditan iwal nu kuring.",
-       "rcfilters-filtergroup-userExpLevel": "Undakan mahér (pikeun pamaké kadaptar hungkul)",
+       "rcfilters-filtergroup-userExpLevel": "Padaptaran sarta pangalaman pamaké",
        "rcfilters-filter-user-experience-level-registered-label": "Kadaptar",
-       "rcfilters-filter-user-experience-level-registered-description": "Éditor asup log",
+       "rcfilters-filter-user-experience-level-registered-description": "Éditor asup log.",
        "rcfilters-filter-user-experience-level-unregistered-label": "Teu kadaptar",
        "rcfilters-filter-user-experience-level-unregistered-description": "Éditor nu teu asup log.",
        "rcfilters-filter-user-experience-level-newcomer-label": "Padatang anyar",
+       "rcfilters-filter-user-experience-level-newcomer-description": "Éditor kadaptar nu miboga éditan kurang ti 10 éditan sarta aktivitas salila 4 poé.",
        "rcfilters-filter-user-experience-level-learner-label": "Palajar",
+       "rcfilters-filter-user-experience-level-learner-description": "Éditor kadaptar nu pangalamanna aya di antara \"padatang anyar\" jeung \"pamaké pangpangalaman\".",
        "rcfilters-filter-user-experience-level-experienced-label": "Pamaké pangpangalaman",
-       "rcfilters-filter-user-experience-level-experienced-description": "Leuwih ti 30 poé tina aktivitas jeung 500 éditan.",
+       "rcfilters-filter-user-experience-level-experienced-description": "Éditor kadaptar nu leuwih ti 500 éditan sarta aktivitas salila 30 poé.",
        "rcfilters-filtergroup-automated": "Kontribusi otomatis",
        "rcfilters-filter-bots-label": "Bot",
        "rcfilters-filter-bots-description": "Éditan dipigawé ku parabot otomatis.",
        "rcfilters-filter-patrolled-label": "Diaawas",
        "rcfilters-filter-patrolled-description": "Éditan ditandaan geus diaawas.",
        "rcfilters-filter-unpatrolled-label": "Teu kaawaskeun",
-       "rcfilters-filter-unpatrolled-description": "Éditan teu ditandaan geus diawaskeun.",
+       "rcfilters-filter-unpatrolled-description": "Éditan teu ditandaan geus diaawas.",
        "rcfilters-filtergroup-significance": "Kapentingan",
        "rcfilters-filter-minor-label": "Éditan minor",
+       "rcfilters-filter-minor-description": "Éditan nu ditandaan éditor minangka éditan minor.",
        "rcfilters-filter-major-label": "Lain éditan minor",
        "rcfilters-filter-major-description": "Éditan teu ditandaan minangka minor.",
+       "rcfilters-filtergroup-watchlist": "Kaca kaawas",
+       "rcfilters-filter-watchlist-watched-label": "Dina aawas",
+       "rcfilters-filter-watchlist-watched-description": "Parobahan kana kaca dina aawaseun anjeun",
+       "rcfilters-filter-watchlist-watchednew-label": "Parobahan Daptar awaseun anyar.",
+       "rcfilters-filter-watchlist-notwatched-label": "Teu dina daptar awaseun",
+       "rcfilters-filter-watchlist-notwatched-description": "Sakabéhna iwal parobahan kana kaca nu diaawas.",
+       "rcfilters-filtergroup-watchlistactivity": "Aktivitas daptar awaseun",
+       "rcfilters-filter-watchlistactivity-unseen-label": "Parobahan nu can ditempo",
+       "rcfilters-filter-watchlistactivity-seen-label": "Parobahan nu geus ditempo",
+       "rcfilters-filter-watchlistactivity-seen-description": "Parobahan kana kaca-kaca nu geus disorang ku anjeun saprak kajadianna parobahan.",
        "rcfilters-filtergroup-changetype": "Jinis parobahan",
        "rcfilters-filter-pageedits-label": "Éditan kaca",
+       "rcfilters-filter-pageedits-description": "Éditan kana kontén wiki, sawala, déskripsi kategori...",
        "rcfilters-filter-newpages-label": "Panyieunan kaca",
        "rcfilters-filter-newpages-description": "Éditan nu nyieun kaca anyar.",
        "rcfilters-filter-categorization-label": "Parobahan kategori",
        "rcfilters-filter-logactions-label": "Tarékah kacatet",
-       "rcfilters-filtergroup-lastRevision": "Révisi kiwari",
-       "rcfilters-filter-lastrevision-label": "Révisi kiwari",
-       "rcnotefrom": "Di handap ieu {{PLURAL:$5|parobahan|parobahan}} ti <strong>$3, $4</strong> (nepi ka <strong>$1</strong> ditémbongkeun).",
+       "rcfilters-filtergroup-lastRevision": "Révisi panganyarna",
+       "rcfilters-filter-lastrevision-label": "Révisi panganyarna",
+       "rcfilters-filter-lastrevision-description": "Ngan parobahan panganyarna di ieu kaca.",
+       "rcfilters-filter-previousrevision-label": "Lain révisi panganyarna",
+       "rcfilters-filter-previousrevision-description": "Sakabéh parobahan nu lain mangrupa \"révisi panganyarna\".",
+       "rcfilters-filter-excluded": "Diiwalkeun",
+       "rcfilters-tag-prefix-namespace-inverted": "<strong>:lain</strong> $1",
+       "rcfilters-exclude-button-off": "Iwalkeun nu dipilih",
+       "rcfilters-exclude-button-on": "Teu kaasup nu dipilih",
+       "rcfilters-view-advanced-filters-label": "Panyaringan leuwih jero",
+       "rcfilters-view-tags": "Éditan ditandaan",
+       "rcfilters-view-namespaces-tooltip": "Saring hasil dumasar ngarangspasi",
+       "rcfilters-view-tags-tooltip": "Saring hasil maké tag éditan",
+       "rcfilters-view-return-to-default-tooltip": "Balik ka menu panyaringan utama",
+       "rcfilters-liveupdates-button": "Parobahan langsung",
+       "rcfilters-liveupdates-button-title-on": "Pareuman parobahan langsung",
+       "rcfilters-liveupdates-button-title-off": "Témbongkeun parobahan anyar nalika éta parobahan prung",
+       "rcfilters-watchlist-markseen-button": "Tandaan sakumna parobahan minangka katémbong",
+       "rcfilters-watchlist-edit-watchlist-button": "Édit daptar kaca awaskeuneun anjeun",
+       "rcnotefrom": "Di handap ieu {{PLURAL:$5|parobahan}} ti <strong>$3, $4</strong> (nepi ka <strong>$1</strong> ditémbongkeun).",
        "rclistfromreset": "Rését pilihan kaping",
        "rclistfrom": "Témbongkeun nu anyar robah nepi ka $3 $2",
        "rcshowhideminor": "$1 éditan minor",
        "uploaderror": "Kasalahan muat",
        "upload-recreate-warning": "'''Awas: berkas nu ngaranna kitu geus kungsi dihapus atawa dipindahkeun.'''\n\nLog hahapus jeung pipindah pikeun ieu kaca dipidangkeun di handap:",
        "uploadtext": "Gunakeun formulir di handap pikeun ngunjal berkas.\nPikeun midangkeun atawa maluruh berkas anu saméméhna diunjal, sorang [[Special:FileList|daptar berkas]]. Unjalan (ulang) ogé kacatet kana [[Special:Log/upload|log unjalan]], sedengkeun pamupusan mah kacatetna dina [[Special:Log/delete|log pamupusan]].\n\nPikeun midangkeun atawa nerapkeun berkas kana kaca mah migunakeun tutumbu salah sahiji format di handap:\n* '''<code><nowiki>[[</nowiki>{{ns:file}}<nowiki>:Berkas.jpg]]</nowiki></code>''' pikeun midangkeun berkas dina ukuran aslina\n* '''<code><nowiki>[[</nowiki>{{ns:file}}<nowiki>:Berkas.png|200px|thumb|left|téks alternatif]]</nowiki></code>''' pikeun midangkeun berkas nu rubakna 200px na jero kotak, nitih di kéncaeun kaca bari aya tulisan 'téks alternatif' minangka kamandang gambar\n* '''<code><nowiki>[[</nowiki>{{ns:media}}<nowiki>:Berkas.ogg]]</nowiki></code>''' minangka tutumbu langsung kana berkas anu dimaksud tanpa kudu midangkeun éta berkas liwat wiki",
-       "upload-permitted": "Tipeu koropak nu diwidian: $1.",
+       "upload-permitted": "{{PLURAL:$2|Jinis}} berkas nu diheugbaékeun: $1.",
        "upload-preferred": "Tipeu koropak nu dianjurkeun: $1.",
-       "upload-prohibited": "Tipeu koropak nu dicaram: $1.",
+       "upload-prohibited": "{{PLURAL:$2|Jinis}} berkas nu dilarang: $1.",
        "uploadlogpage": "Log unggahan",
        "uploadlogpagetext": "Di handap mangrupa daptar muatan koropak nu panganyarna. Titimangsa nu katémbong dumasar titimangsa server.",
        "filename": "Ngaran koropak",
        "empty-file": "Berkas nu dikirim kosong.",
        "file-too-large": "Berkas nu dikirim gedé teuing.",
        "filename-tooshort": "Ngaran berkas pondok teuing.",
-       "filetype-banned": "Jenis berkas ieu dipahing.",
+       "filetype-banned": "Jinis berkas ieu dipahing.",
        "verification-error": "Ieu berkas teu lulus vérifikasi.",
+       "hookaborted": "Modifikasi nu coba dipilampah ku anjeun dibolaykeun ku hiji kaitan éksténsi.",
        "illegal-filename": "Ngaran berkas dipahing.",
+       "overwrite": "Teu diidinan pikeun ngalandih berkas nu geus aya.",
        "unknown-error": "Aya kasalahan anu teu dikanyahoankeun.",
        "tmp-create-error": "Teu bisa nyieun berkas sementara.",
        "tmp-write-error": "Éror nulis berkas sementara.",
        "copyuploaddisabled": "Unggahan dumasar URL ditumpurkeun.",
        "uploaddisabledtext": "Fungsi ngamuat koropak ditumpurkeun.",
        "uploadscripted": "Koropak ieu ngandung kode HTML atawa skrip nu bisa dibaca ngaco ku panyungsi ramat (''web browser'').",
+       "uploaded-setting-href-svg": "Maké tag \"sét\" pikeun nambahkeun atribut \"href\" kana élemén utama dipeungpeuk.",
        "uploadinvalidxml": "XML na berkas nu diunjal teu bisa didadarkeun.",
        "uploadvirus": "Koropakna ngandung virus! Katrangan: $1",
        "upload-source": "Koropak sumber",
        "upload-proto-error": "Salah protokol",
        "upload-file-error": "Kasalahan internal",
        "upload-misc-error": "Kasalahan muat anu teu kanyahoan",
+       "upload-too-many-redirects": "URL ngandung loba teuing alihan",
        "upload-http-error": "Aya galat HTTP: $1",
+       "upload-copy-upload-invalid-domain": "Unjalan téplakan teu sayaga ti ieu domain.",
+       "upload-foreign-cant-upload": "Ieu wiki teu diatur pikeun ngunjal berkas ka gudang panyindangan asing.",
        "upload-dialog-title": "Unjal berkas",
        "upload-dialog-button-cancel": "Bolay",
        "upload-dialog-button-back": "Balik deui",
        "backend-fail-stream": "Teu bisa malidkeun berkas \"$1\"",
        "backend-fail-backup": "Teu bisa nyadangkeun berkas \"$1\".",
        "backend-fail-notexists": "Berkas $1 euweuh.",
+       "backend-fail-hashes": "Teu bisa meunang hash berkas minangka babandingan.",
        "backend-fail-notsame": "Berkas anu teu-identik geus aya di $1.",
        "backend-fail-invalidpath": "$1 perenahna henteu absah.",
        "backend-fail-delete": "Teu bisa ngahapus berkas $1.",
        "backend-fail-read": "Teu bisa maca berkas $1.",
        "backend-fail-create": "Teu bisa nulis berkas \"$1\".",
        "backend-fail-maxsize": "Teu bisa nulis berkas \"$1\" kusabab leuwih ti {{PLURAL:$2|hiji bit|$2 bit}}.",
+       "backend-fail-connect": "Teu bisa nyambungkeun kana panyimpenan backend \"$1\".",
+       "backend-fail-internal": "Aya kasalahan nu teu dipikawanoh di backend panyimpenan \"$1\".",
        "backend-fail-contenttype": "Teu bisa nangtukeun tipeu eusi berkas anu badé disimpen di \"$1\".",
        "lockmanager-notlocked": "Teu bisa muka konci \"$1\" kusabab teu dikonci.",
        "lockmanager-fail-closelock": "Teu bisa nutup berkas konci pikeun \"$1\".",
        "lockmanager-fail-deletelock": "Teu bisa ngahapus berkas konci pikeun \"$1\".",
+       "lockmanager-fail-acquirelock": "Teu bisa meunang pangoncian pikeun \"$1\"",
        "lockmanager-fail-openlock": "Teu bisa muka berkas konci pikeun \"$1\".",
        "lockmanager-fail-releaselock": "Teu bisa ngaleupaskeun konci pikeun \"$1\".",
        "lockmanager-fail-db-release": "Teu bisa ngaleupaskeun konci dina databés $1.",
+       "lockmanager-fail-svr-acquire": "Gagal nyokot konci di servér $1.",
        "lockmanager-fail-svr-release": "Teu bisa ngaleupaskeun konci dina server $1.",
        "zip-wrong-format": "Berkas anu dipilih lain berkas ZIP.",
        "uploadstash": "Unjal engkeunan",
        "img-auth-streaming": "Palidan \"$1\".",
        "img-auth-noread": "Pamaké teu boga kawenangan maca \"$1\".",
        "http-invalid-url": "URL teu bener: $1",
-       "http-invalid-scheme": "URL anu skémana \"$1\" teu karojong",
+       "http-invalid-scheme": "URL kalawan skéma \"$1\" teu dirojong.",
        "http-read-error": "Kasalahan maca HTTP.",
        "http-timed-out": "Pamundutan HTTP béakeun waktu.",
        "http-curl-error": "Kasalahan keur nyokot URL: $1",
        "nolicense": "Taya nu dipilih",
        "licenses-edit": "Robah pilihan lisénsi",
        "license-nopreview": "(euweuh pramidang)",
-       "upload_source_url": "(URL nu sohéh sarta bisa dibuka ku umum)",
-       "upload_source_file": " (koropak dina komputer salira)",
+       "upload_source_url": "(Anjeun milih berkas ti URL valid nu bisa diaksés publik)",
+       "upload_source_file": "(berkas pinilih anjeun tina komputer anjeun)",
        "listfiles-delete": "hapus",
        "listfiles-summary": "Ieu kaca husus némbongkeun sakabéh berkas anu geus diunggah.",
        "listfiles_search_for": "Paluruh ngaran média:",
        "listfiles_size": "Badagna",
        "listfiles_description": "Pedaran",
        "listfiles_count": "Vérsi",
+       "listfiles-show-all": "Kaasup vérsi heubeul gambar",
        "listfiles-latestversion": "Vérsi ayeuna",
        "listfiles-latestversion-yes": "Enya",
        "listfiles-latestversion-no": "Henteu",
        "imagelinks": "Pamakéan berkas",
        "linkstoimage": "Kaca ieu  {{PLURAL:$1|numbu|$1 numbu}} ka gambar ieu :",
        "nolinkstoimage": "Teu aya kaca anu nutumbu ka ieu berkas.",
+       "linkstoimage-redirect": "$1 (pangalihan berkas) $2",
        "sharedupload": "Ieu koropak téh ti $1 nu bisa jadi dipaké ku proyék-proyék lianna.",
        "sharedupload-desc-here": "Ieu berkas asalna ti $1 anu bisa jadi dipaké ku proyék séjén. \nPedaran ti [$2 kaca pedaranana] dipidangkeun di handap.",
        "filepage-nofile": "Taya berkas nu ngaranna kieu.",
        "uploadnewversion-linktext": "ngamuatkeun vérsi anyar koropak ieu",
        "shared-repo-from": "ti $1",
+       "shared-repo": "hiji répositori réréongan",
        "upload-disallowed-here": "Anjeun teu bisa nimpah ieu berkas.",
        "filerevert": "balikkeun $1",
        "filerevert-legend": "Balikkeun gambar",
        "unwatchedpages": "Kaca nu teu diawaskeun",
        "listredirects": "Daptar alihan",
        "listduplicatedfiles": "Daptar berkas duplikat.",
+       "listduplicatedfiles-summary": "Ieu téh daptar berkas nu mana vérsi panganyarna tina éta berkas mangrupa duplikat tina vérsi panganyarna ti sawatara berkas lian. Ngan berkas lokal nu dianggap mah.",
        "unusedtemplates": "Citakan nu teu kapaké",
        "unusedtemplatestext": "Ieu kaca ngabéréndélkeun sakabéh kaca dina rohang ngaran {{ns:template}} anu teu diwengku ku kaca séjén.\nSaméméh ngahapus, pariksa heula bisi aya tumbu ka ieu citakan.",
        "unusedtemplateswlh": "tutumbu lianna",
        "randompage": "Kaca acak",
-       "randompage-nopages": "Euweuh kaca dina ieu spasi ngaran \"$1\".",
+       "randompage-nopages": "Euweuh kaca dina {{PLURAL:$2|ngaranspasi}} di handap: $1.",
+       "randomincategory": "Kaca acak dina kategori",
+       "randomincategory-invalidcategory": "\"$1\" lain ngaran kategori nu lumaku.",
+       "randomincategory-nopages": "Euweuh kaca dina [[:Category:$1]].",
        "randomincategory-category": "Kategori:",
        "randomincategory-legend": "Kaca acak dina kategori",
        "randomincategory-submit": "Jung",
        "statistics-users-active": "Pamaké getol",
        "statistics-users-active-desc": "Kontributor nu ngoprék salila {{PLURAL:$1|poé|$1 poé}} panungtung",
        "pageswithprop": "Kaca ku kaca properti",
+       "pageswithprop-legend": "Kaca kalawan kaca properti",
+       "pageswithprop-text": "Ieu kaca eusina daptar kaca nu ngagunakeun properti kaca tinangtu.",
        "pageswithprop-prop": "Ngarab properti:",
+       "pageswithprop-reverse": "Susunkeun dina susunan tibalik",
+       "pageswithprop-sortbyvalue": "Susunkeun sumasar eusi properti",
        "pageswithprop-submit": "Jung",
+       "pageswithprop-prophidden-long": "eusi properti téks panjang nyamuni ($1)",
+       "pageswithprop-prophidden-binary": "eusi properti binér nyamuni ($1)",
        "doubleredirects": "Alihan ganda",
        "doubleredirectstext": "Ieu kaca ngabéréndélkeun kaca-kaca alihan ka kaca alihan lianna. Unggal baris ngandung tutumbu ka alihan kahiji jeung kadua, ogé tujul alihan kadua anu biasana tujul kaca anu \"bener\", anu sakuduna dituju ku alihan kahiji. Ëntri nu <del>dicorét</del> geus diropéa.",
-       "double-redirect-fixed-move": "[[$1]] geus pindah, dialihkeun ka [[$2]].",
-       "double-redirect-fixed-maintenance": "Ngoméan alihan ganda ti [[$1]] ka [[$2]].",
+       "double-redirect-fixed-move": "[[$1]] geus dipindahkeun.\nKami geus nganyarkeunna sacara otomatis jeung deuih kiwari mah jadi kaca alihan ka [[$2]].",
+       "double-redirect-fixed-maintenance": "Ngomékeun alihan ganda ti [[$1]] ka [[$2]] dina hiji pamulasaraan.",
        "double-redirect-fixer": "Pangomé alihan",
        "brokenredirects": "Alihan buntu",
        "brokenredirectstext": "Alihan di handap numbu ka kaca nu teu aya:",
        "wantedpages": "Kaca nu dipikabutuh",
        "wantedpages-badtitle": "Judul teu sah dina kumpulan hasil: $1",
        "wantedfiles": "Berkas nu dipikabutuh",
+       "wantedfiletext-nocat-noforeign": "Berkas-berkas di handap téh dipaké, ngan euweuh.",
        "wantedtemplates": "Citakan nu dipikabutuh",
        "mostlinked": "Nu panglobana numbu ka kaca séjén",
        "mostlinkedcategories": "Paling loba ditumbukeun ka kategori",
-       "mostlinkedtemplates": "Citakan nu panglobana ditumbu",
+       "mostlinkedtemplates": "Citakan nu panglobana dipaké (ditransklusikeun)",
        "mostcategories": "Artikel nu paling loba ngandung kategori",
        "mostimages": "Berkas anu panglobana ditumbukeun",
+       "mostinterwikis": "Kaca kalawan interwiki panglobana",
        "mostrevisions": "Artikel nu pangmindengna dirévisi",
        "prefixindex": "Kabeh kaca maké awalan",
+       "prefixindex-namespace": "Sakum kaca kalawan awalan (ngaranspasi $1)",
        "prefixindex-submit": "Témbongkeun",
+       "prefixindex-strip": "Strip awalan dina daptar",
        "shortpages": "Kaca-kaca parondok",
        "longpages": "Kaca-kaca paranjang",
        "deadendpages": "Kaca buntu",
        "deadendpagestext": "Kaca-kaca di handap ieu teu numbu ka kaca séjén di {{SITENAME}}:",
        "protectedpages": "Kaca-kaca nu dikonci",
        "protectedpages-indef": "Ngan pikeun panangtayungan kalawan waktu nuteu kawates",
+       "protectedpages-cascade": "Ngan raksaan runtuy",
        "protectedpages-noredirect": "Sumputkeun pangalihan",
        "protectedpagesempty": "Dina danget ieu, teu aya kaca nu dikonci dumasar kana ieu paraméter.",
        "protectedpages-timestamp": "Cap titimangsa",
        "apihelp": "Pitulung API",
        "apihelp-no-such-module": "Modul \"$1\" teu kapanggih.",
        "apisandbox": "Kotrétan API",
+       "apisandbox-jsonly": "JavaScript diperlukeun pikeun maké kotrétan API.",
+       "apisandbox-api-disabled": "API dipareuman dina ieu situs.",
        "apisandbox-fullscreen": "Mekarkeun panél",
+       "apisandbox-fullscreen-tooltip": "Kembangkeun panel kotrétan pikeun ngeusian jandéla panyungsi.",
        "apisandbox-unfullscreen": "Témbongkeun kaca",
        "apisandbox-submit": "Jieun pundutan",
        "apisandbox-reset": "Bersihan",
        "apisandbox-retry": "Cobaan deui",
        "apisandbox-loading": "Muatkeun info pikeun modul API \"$1\"...",
+       "apisandbox-no-parameters": "Ieu Modul API teu mibanda paraméter.",
        "apisandbox-helpurls": "Tutumbu pitulung",
        "apisandbox-examples": "Conto",
+       "apisandbox-dynamic-parameters": "Paraméter tatambah",
        "apisandbox-dynamic-parameters-add-label": "Tambah paraméter:",
        "apisandbox-dynamic-parameters-add-placeholder": "Ngaran paraméter",
+       "apisandbox-dynamic-error-exists": "Parametér nu ngaranna \"$1\" geus sayaga.",
        "apisandbox-deprecated-parameters": "Paraméter basi",
        "apisandbox-fetch-token": "Eusi token kalayan otomatis",
        "apisandbox-submit-invalid-fields-title": "Sawatara kolom teu sah",
+       "apisandbox-submit-invalid-fields-message": "Mangga oméan kolom nu ditandaan sarta coba deui.",
        "apisandbox-results": "Hasil",
        "apisandbox-sending-request": "Ngirim pundutan API...",
        "apisandbox-loading-results": "Nampa hasil API...",
        "apisandbox-request-selectformat-label": "Témbongkeun pundutan data minangka:",
+       "apisandbox-request-format-url-label": "String kuéri URL",
        "apisandbox-request-url-label": "URL pundutan:",
        "apisandbox-request-json-label": "Pundut JSON:",
+       "apisandbox-request-time": "Wayah pamundutan: {{PLURAL:$1|$1 ms}}",
+       "apisandbox-results-fixtoken": "Oméan token sarta kirim deui",
+       "apisandbox-results-fixtoken-fail": "Gagal meunangkeun token \"$1\".",
+       "apisandbox-alert-page": "Kolom jeung ieu kaca téh teu valid.",
+       "apisandbox-alert-field": "Niléy dina ieu kolom téh teu valid.",
        "apisandbox-continue": "Tuluykeun",
        "apisandbox-continue-clear": "Bersihan",
+       "apisandbox-param-limit": "Asupkeun <kbd>max</kbd> pikeun ngagunakeun wates maksimum.",
+       "apisandbox-multivalue-all-namespaces": "$1 (Sakum ngaranspasi)",
        "apisandbox-multivalue-all-values": "$1 (Kabéh ajén)",
        "booksources": "Sumber pustaka",
        "booksources-search-legend": "Paluruh sumber buku",
        "booksources-search": "Paluruh",
        "booksources-text": "Di handap ieu ngabéréndélkeun tutumbu ka loka-loka nu ngical buku, boh nu anyar atawa loakan, nu sugan uninga kana buku anu nuju dipilari:",
        "booksources-invalid-isbn": "Sigana ISBN-na teu bener; pariksa deui bisi aya salah téplak ti sumber aslina.",
+       "magiclink-tracking-rfc": "Kaca ngagunakeun tutumbu magis RFC",
+       "magiclink-tracking-pmid": "Kaca ngagunakeun tutumbu magis PMID",
+       "magiclink-tracking-isbn": "Kaca ngagunakeun tutumbu magis ISBN",
        "specialloguserlabel": "Palaku:",
        "speciallogtitlelabel": "Sasaran (judul atawa {{ns:user}}:sandiasma pikeun pamaké):",
        "log": "Log",
        "alllogstext": "Béréndélan sakabéh log nu aya di {{SITENAME}}.\nBisa dipondokkeun ku cara milih tipe log, ngaran pamaké, atawa kaca nu dimaksud.",
        "logempty": "Taya item nu cocog dina log.",
        "log-title-wildcard": "Téangan judul nu dimimitian ku tulisan ieu",
+       "showhideselectedlogentries": "Robah katempo henteuna éntri log pinilih",
+       "log-edit-tags": "Édit tag tina éntri log pinilih",
        "checkbox-select": "Pilih: $1",
        "checkbox-all": "Sakumna",
        "checkbox-none": "Kosong",
        "allpagesbadtitle": "Judul kaca nu dibikeun teu bener atawa mibanda awalan antarbasa atawa antarwiki, nu ngandung karakter nu teu bisa dipaké dina judul.",
        "allpages-bad-ns": "{{SITENAME}} teu boga spasi ngaran \"$1\".",
        "allpages-hide-redirects": "Sumputkeun pangalihan",
+       "cachedspecial-viewing-cached-ttl": "Anjeun nempo vérsi kés ieu kaca, nya meureun geus lilana $1.",
+       "cachedspecial-viewing-cached-ts": "Anjeun nempo vérsi kés ieu kaca, nya meureun moal bener-bener aktual.",
        "cachedspecial-refresh-now": "Tempo nu panganyarna.",
        "categories": "Kategori",
        "categories-submit": "Témbongkeun",
        "linksearch-pat": "Pola pamaluruhan:",
        "linksearch-ns": "Spasi ngaran:",
        "linksearch-ok": "Paluruh",
-       "linksearch-text": "''Wildcard'' sarupaning \"*.wikipedia.org\" bisa dipaké.<br />Protokol nu dirojong: $1",
+       "linksearch-text": "Tanda béntang kayaning \"*.wikipedia.org\" bisa dipaké.\nPerlu saeutikna hiji domain undak luhur, misalna \"*.org\".<br />\n{{PLURAL:$2|Protokol}} anu dirojong: $1 (ngagunakeun http:// mun protokol teu ditangtukeun)",
        "linksearch-line": "$1 ditumbu ti $2",
        "linksearch-error": "''Wildcard'' ngan bisa némbongan dina awal ngaran indung (''host'').",
        "listusersfrom": "Témbongkeun kontributor dimimitian ku:",
        "listusers-blocked": "(diblokir)",
        "activeusers": "Béréndélan pamaké nu getol",
        "activeusers-intro": "Ieu béréndélan kontributor anu geus ngoprék $1 {{PLURAL:$1|poé|poé}} panungtung.",
-       "activeusers-count": "$1 {{PLURAL:$1|édit|édit}}an salila {{PLURAL:$3|poé|$3 poé}} panungtung",
+       "activeusers-count": "$1 {{PLURAL:$1|aktivitas}} dina {{PLURAL:$3|1 hari|$3 hari}} panungtung",
        "activeusers-from": "Témbongkeun kontributor dimimitian ku:",
+       "activeusers-groups": "Témbongkeun pamaké nu kaasup gorombolan:",
+       "activeusers-excludegroups": "Samunikeun pamaké nu kaasup gorombolan:",
        "activeusers-noresult": "Teu kapendak.",
+       "activeusers-submit": "Témbongkun pamaké aktif",
        "listgrouprights": "Hak-hak grup pamaké",
        "listgrouprights-summary": "Ieu mangrupa daptar jumplukan pamaké anu aya di wiki ieu, kalawan daptar hak aksés maranéhanana.\nÉmbaran leuwih luyu ngeunaan hak pamaké bisa ditingali di [[{{MediaWiki:Listgrouprights-helppage}}|dieu]].",
-       "listgrouprights-key": "* <span class=\"listgrouprights-granted\">Hak anu dipimilik</span>\n* <span class=\"listgrouprights-revoked\">Hak anu dicabut</span>",
+       "listgrouprights-key": "Jujutan:\n* <span class=\"listgrouprights-granted\">Hak anu dipimilik</span>\n* <span class=\"listgrouprights-revoked\">Hak anu dicabut</span>",
        "listgrouprights-group": "Jumplukan",
        "listgrouprights-rights": "Hak",
        "listgrouprights-helppage": "Help:Hak Jumplukan",
        "listgrouprights-removegroup-self": "Piceun {{PLURAL:$2|grup|grups}} ti akun sorangan: $1",
        "listgrouprights-addgroup-self-all": "Tambahkeun sakabéh grup ka akun sorangan",
        "listgrouprights-removegroup-self-all": "Piceun sakabéh grup ti akun sorangan",
+       "listgrouprights-namespaceprotection-header": "Watesan ngaranspasi",
+       "listgrouprights-namespaceprotection-namespace": "Ngaranspasi",
+       "listgrouprights-namespaceprotection-restrictedto": "Hak nu ngawidian pamaké pikeun ngédit",
        "listgrants": "Idin",
        "listgrants-grant": "Idin",
        "listgrants-rights": "Hak",
        "trackingcategories-msg": "Kategori palacak",
        "trackingcategories-name": "Ngaran talatah",
        "trackingcategories-desc": "Kritéria inklusi kategori",
+       "restricted-displaytitle-ignored": "Kaca-kaca kalawan pangantepan pidangan judul",
        "trackingcategories-nodesc": "Taya pedaran nu sayaga",
        "trackingcategories-disabled": "Kategori dipareuman",
        "mailnologin": "Euweuh alamat ngirim",
        "emailsent": "Surélék geus dikirim",
        "emailsenttext": "Surélék anjeun geus dikirim.",
        "emailuserfooter": "Ieu surélék dikirim ku $1 ka $2 migunakeun fungsi \"Surélékan pamaké ieu\" di {{SITENAME}}.",
-       "usermessage-summary": "Ninggalkeun talatah sistem.",
+       "usermessage-summary": "Ninggalkeun talatah sistim.",
        "usermessage-editor": "Talatah sistim",
        "watchlist": "Awaskeuneun",
        "mywatchlist": "Awaskeuneun",
        "watchnologin": "Can asup log",
        "addwatch": "Tambahkeun ka aawaseun",
        "addedwatchtext": "Kaca \"[[:$1]]\" geus ditambahkeun ka [[Special:Watchlist|awaskeuneun]] anjeun.\nJaga, parobahan na kaca ieu katut kaca obrolanana bakal dibéréndélkeun di dinya, sarta kacana bakal katémbong '''dikandelan''' dina kaca [[Special:RecentChanges|Nu anyar robah]] sangkan leuwih gampang ngawaskeunana.\n\n<p>Mun jaga anjeun moal deui ngawaskeun parobahan na kaca éta, klik tumbu \"Eureun ngawaskeun\" na lajursisi.",
+       "addedwatchtext-short": "Kaca \"$1\" geus ditambahkeun kana daptar aawaseun anjeun.",
        "removewatch": "Piceun tina béréndélan awaskeuneun",
        "removedwatchtext": "Kaca \"[[:$1]]\" geus dikaluarkeun tina [[Special:Watchlist|daptar awaskeuneun]] anjeun.",
        "removedwatchtext-short": "Kaca \"$1\" geus dipiceun tina béréndélan awaskeuneun.",
        "notanarticle": "Sanés kaca eusi",
        "notvisiblerev": "Révisi geus dihapus",
        "watchlist-details": "Aya {{PLURAL:$1|$1 kaca|$1 kaca}} dina béréndélan awaskeuneun, teu kaasup kaca obrolan/sawala.",
-       "wlheader-enotif": "Pangémbar surélék difungsikeun.",
+       "wlheader-enotif": "Iber surélék diaktifkeun.",
        "wlheader-showupdated": "Kaca nu robah ti panungtungan anjeun sindang ditémbongkeun kalawan '''kandel'''",
        "wlnote": "Di handap ieu mangrupa $1 {{PLURAL:$1|robahan|robahan}} ahir salila '''$2''' jam.",
-       "wlshowlast": "Témbongkeun $1 jam $2 poé  ahir",
+       "wlshowlast": "Témbongkeun $1 jam $2 poé panungtung",
        "watchlist-hide": "Sumputkeun",
        "watchlist-submit": "Témbongkeun",
        "wlshowtime": "Periodeu waktu ajang dipidangkeun:",
        "enotif_lastdiff": "Pikeun nempo parobahan, ilikan $1",
        "enotif_anon_editor": "pamaké anonim $1",
        "enotif_body": "Sadérék $WATCHINGUSERNAME,\n\nKaca $PAGETITLE na {{SITENAME}} geus $CHANGEDORCREATED tanggal $PAGEEDITDATE ku $PAGEEDITOR. Mangga tingal {{SERVER}}{{localurl:$PAGETITLE}} pikeun vérsi kiwari.\n\n$NEWPAGE\n\nRingkesan éditor: $PAGESUMMARY $PAGEMINOREDIT\n\nKontak éditor:\nsurat {{SERVER}}{{localurl:Husus:Emailuser|target=$PAGEEDITOR}}\nwiki {{SERVER}}{{localurl:Pamaké:$PAGEEDITOR}}\n\nMun anjeun teu sindang deui ka ieu kaca, parobahan salajengna moal diémbarkeun. Anjeun bisa ogé nyetél deui umbul-umbul pikeun sadaya kaca nu aya na daptar awaseun anjeun.\n\n             Sistim émbaran {{SITENAME}} pikeun anjeun\n\n--\nPikeun ngarobah setélan dabtar awaseun anjeun, sindang ka {{SERVER}}{{localurl:Husus:Watchlist|edit=yes}}\n\nAsupan jeung bantuan salajengna:\n$HELPPAGE",
+       "enotif_minoredit": "Ieu mah éditan minor",
        "created": "geus dijieun",
        "changed": "geus robah",
        "deletepage": "Hapus kaca",
        "confirm": "Konfirmasi",
        "excontent": "eusina nu heubeul: '$1'",
-       "excontentauthor": "eusina: \"$1\" (nu ditulis ku \"[[Special:Contributions/$2|$2]]\" wungkul)",
+       "excontentauthor": "eusina ngan mangrupa: \"$1\", sarta hiji-hijina kontributor téh nyaéta \"[[Special:Contributions/$2|$2]]\" ([[User talk:$2|obrolan]])",
        "exbeforeblank": "eusi méméh dikosongkeun nyéta: '$1'",
        "delete-confirm": "Hapus \"$1\"",
        "delete-legend": "Hapus",
        "delete-edit-reasonlist": "Alesan ngahapus éditan",
        "delete-toobig": "Jujutan édit ieu kaca panjang pisan, leuwih ti {{PLURAL:$1|révisi|révisi}}.\nHal ieu teu diwenangkeun pikeun nyegah karuksakan {{SITENAME}} nu teu dihaja.",
        "delete-warning-toobig": "Jujutan ieu kaca panjang pisan, leuwih ti{{PLURAL:$1|révisi|révisi}}. Dihapusna ieu kaca bisa ngaruksak jalanna pangkalan data {{SITENAME}}; sing ati-ati.",
+       "deleteprotected": "Anjeun teu bisa mupus ieu kaca lantaran geus ditangtayungan.",
        "rollback": "Balikkeun éditan",
        "rollbacklink": "balikkeun",
        "rollbacklinkcount": "balikkeun $1 {{PLURAL:$1|éditan}}",
+       "rollbacklinkcount-morethan": "balikkeun leuwih ti $1 {{PLURAL:$1|saéditan|éditan}}",
        "rollbackfailed": "Gagal malikkeun",
+       "rollback-missingparam": "Paraméter diperlukeun nalika dupundut teu sayaga.",
        "rollback-missingrevision": "Teu bisa muatkeun révisi data.",
        "cantrollback": "Éditan teu bisa dibalikkeun; kontribusi panungtung ngarupakeun hiji-hijina panulis kaca ieu.",
        "alreadyrolled": "Teu bisa mulangkeun édit ahir [[$1]] ku [[User:$2|$2]] ([[User talk:$2|Obrolan]]{{int:pipe-separator}}[[Special:Contributions/$2|{{int:contribslink}}]]); geus aya nu ngédit atawa mulangkeun kacana.\n\nÉdit ahir ku [[User:$3|$3]] ([[User talk:$3|Obrolan]]{{int:pipe-separator}}[[Special:Contributions/$3|{{int:contribslink}}]]).",
        "rollback-success": "Mulangkeun éditan $1; balik deui ka vérsi panungtung ku $2.",
        "sessionfailure-title": "Kagagalan sési",
        "sessionfailure": "Sigana aya masalah jeung termin log anjeun; peta ieu geus dibolaykeun salaku pépéling pikeun ngalawan ayana pangbajak. Mangga pencét \"back\" jeung muat ulang ti kaca asal anjeun, lajeng cobaan deui.",
+       "changecontentmodel": "Robah modél kontén hiji kaca",
        "changecontentmodel-legend": "Robah modél kontén",
        "changecontentmodel-title-label": "Judul kaca",
        "changecontentmodel-model-label": "Modél kontén anyar",
        "changecontentmodel-reason-label": "Alesan:",
        "changecontentmodel-submit": "Parobahan",
        "changecontentmodel-success-title": "Modél ieu kontén geus dirobah",
+       "changecontentmodel-success-text": "Jinis kontén [[:$1]] geus dirobah",
+       "changecontentmodel-nodirectediting": "Modél kontén $1 teu ngarojong éditan langsung",
        "changecontentmodel-emptymodels-title": "Taya modél kontén nu sayaga",
+       "changecontentmodel-emptymodels-text": "Kontén dina [[:$1]] teu bisa dirobah kana jinis lian.",
        "log-name-contentmodel": "Log parobahan modél kontén",
        "logentry-contentmodel-change-revertlink": "balikkeun",
        "logentry-contentmodel-change-revert": "balikkeun",
        "unprotectedarticle": "muka konci tina \"[[$1]]\"",
        "protectedarticle-comment": "{{GENDER:$2|Nangtayungan}} \"[[$1]]\"",
        "protect-title": "Ngonci \"$1\"",
+       "protect-title-notallowed": "Tempo undak panangtayungan ti \"$1\"",
        "prot_1movedto2": "mindahkeun [[$1]] ka [[$2]]",
+       "protect-badnamespace-title": "Ngaranspasi nu teu bisa ditangtayungan",
        "protect-norestrictiontypes-title": "Kaca nu teu karaksa",
        "protect-legend": "Konfirmasi ngonci",
        "protectcomment": "Alesan:",
        "protectexpiry": "Kadaluwarsa",
        "protect_expiry_invalid": "Waktu kadaluwarsa teu sah.",
        "protect_expiry_old": "Waktu kadaluwarsa geus kaliwat.",
+       "protect-unchain-permissions": "Aktifkeun opsi panangtayungan lanjutan",
        "protect-text": "Di dieu anjeun bisa nempo sarta ngarobah hambalan pangonci pikeun kaca '''$1'''.",
        "protect-locked-blocked": "Anjeun teu bisa ngarobah hambalan koncian sabab keur dipeungpeuk. Setélan ayeuna pikeun kaca '''$1''' nyaéta:",
        "protect-locked-access": "Akun anjeun teu wenang ngarobah hambalan pangonci kaca.\nSetélan kiwari pikeun kaca <strong>$1</strong>:",
        "protect-default": "Bisa ku sakabeh pamaké",
        "protect-fallback": "Ngan pikeun pamaké kalawan idin \"$1\"",
        "protect-level-autoconfirmed": "Peungpeuk pamaké anyar jeung nu teu daptar",
-       "protect-level-sysop": "Ngan bisa ku kuncén",
+       "protect-level-sysop": "Ngan pikeun kuncén",
        "protect-summary-cascade": "ngaruntuykeun",
        "protect-expiring": "kadaluwarsa $1",
        "protect-expiring-local": "kadaluwarsa $1",
        "undelete-search-title": "Paluruh kaca kahapus",
        "undelete-search-box": "Téang kaca nu dihapus",
        "undelete-search-prefix": "Témbongkeun kaca dimimitian ku",
+       "undelete-search-full": "Témbongkeun judul kaca nu ngandung:",
        "undelete-search-submit": "Téang",
        "undelete-no-results": "Euweuh kaca nu cocog dina arsip hapusan.",
        "undelete-filename-mismatch": "Hanteu bisa ngabolaykeun hapusan révisi berkas titimangsa $1: ngaran berkas teu cocog.",
        "ipb-unblock-addr": "Buka peungpeuk $1",
        "ipb-unblock": "Nyabut peungpeuk pamaké atawa alamat IP",
        "ipb-blocklist": "Tempo peungpeuk nu diteurapkeun",
-       "ipb-blocklist-contribs": "Ilubiung $1",
+       "ipb-blocklist-contribs": "Kontribusi pikeun {{GENDER:$1|$1}}",
        "ipb-blocklist-duration-left": "Nyésa $1",
        "unblockip": "Buka peungpeuk pamaké",
        "unblockiptext": "Paké formulir di handap pikeun mulangkeun aksés nulis ka alamat IP atawa ngaran pamaké nu saméméhna dipeungpeuk.",
-       "ipusubmit": "Buka peungpeuk pikeun pamaké ieu",
+       "ipusubmit": "Pupus ieu peungpeukan",
        "unblocked": "peungpeuk ka [[User:$1|$1]] geus dicabut",
        "unblocked-range": "$1 geus teu dipeungpeuk",
        "unblocked-id": "peungpeuk $1 geus dicabut",
+       "unblocked-ip": "Pameungpeukan [[Special:Contributions/$1|$1]] geus dicabut.",
        "blocklist": "Kontributor nu dipeungpeuk",
        "autoblocklist": "Otomatis peungpeuk",
        "autoblocklist-submit": "Paluruh",
        "autoblocklist-legend": "Daptar otomatis peungpeuk",
        "autoblocklist-localblocks": "{{PLURAL:$1|Otomatis peungpeuk}} lokal",
+       "autoblocklist-total-autoblocks": "Total peungeukan otomatis: $1",
+       "autoblocklist-empty": "Daptar peungpeukan otomatis kosong.",
+       "autoblocklist-otherblocks": "{{PLURAL:$1|Sapeungpeukan otomatis|Peungpeukan otomatis}} lianna",
        "ipblocklist": "Pamaké nu dipeungpeuk",
        "ipblocklist-legend": "Téang pamaké nu dipeungpeuk",
        "blocklist-userblocks": "Sumputkeun peungpeukan akun",
        "blocklist-tempblocks": "Sumputkeun peungpeukan saheulaanan",
+       "blocklist-addressblocks": "Sumputkeun pameungpeukan IP tunggal",
        "blocklist-timestamp": "Cap titimangsa",
        "blocklist-target": "Udagan",
        "blocklist-expiry": "Kadaluwarsa",
        "block-log-flags-noautoblock": "meungpeuk otomatis dipaéhan",
        "block-log-flags-noemail": "surélek di peungpeuk",
        "block-log-flags-nousertalk": "teu bisa ngédit kaca obrolan sorangan",
+       "block-log-flags-angry-autoblock": "ronjatan sistim pameungpeukan otomatis geus dihurungkeun",
        "block-log-flags-hiddenname": "sandiasma disumputkeun",
        "range_block_disabled": "Pangabisa kuncén pikeun nyieun sarupaning peungpeuk geus ditumpurkeun.",
        "ipb_expiry_invalid": "Wanci daluwarsa teu bener.",
+       "ipb_expiry_old": "Waktu kadaluwarsana mah baheula.",
        "ipb_already_blocked": "\"$1\" geus dipeungpeuk",
        "ipb-needreblock": "$1 geus dipeungpeuk. Rék dirobah sétinganana?",
        "ipb-otherblocks-header": "{{PLURAL:$1|Peungpeuk|Peungpeuk}} lianna",
        "unblock-hideuser": "Anjeun teu bisa muka peungpeuk ieu pamaké, kusabab landihanan keur disumputkeun.",
        "ipb_cant_unblock": "Éror: ID peungpeuk $1 teu kapanggih. Sigana mah geus dibuka.",
        "ip_range_invalid": "Angka IP teu bener.",
+       "ip_range_toolarge": "Panteng blok leuwih badag tibatan /$1 teu diheugbaékeun.",
        "proxyblocker": "Pameungpeuk proxy",
        "proxyblockreason": "Alamat IP anjeun dipeungpeuk sabab mangrupa proxy muka. Mangga tepungan ''Internet service provider'' atanapi ''tech support'' anjeun, béjakeun masalah serius ieu.",
        "sorbsreason": "Alamat IP anjeun kadaptar salaku ''open proxy'' dina DNSBL anu dipaké ku {{SITENAME}}.",
        "sorbs_create_account_reason": "Alamat IP anjeun kadaptar salaku ''open proxy'' dina DNSBL. Anjeun teu bisa nyieun akun",
        "ipbblocked": "Anjeun teu bisa meungpeuk atawa muka peungpeuk séjén kontributor ku sabab anjeun sorangan keur dipeungpeuk",
+       "ipbnounblockself": "Anjeun teu diidinan pikeun muka peungpeukan sorangan.",
        "lockdb": "Konci pangkalan data",
        "unlockdb": "Buka konci pangkalan data",
        "lockdbtext": "Ngonci gudang data bakal numpurkeun kabisa sakabéh pamaké pikeun ngédit kaca, ngarobah préferénsina, ngédit awaskeuneunana, sarta hal séjén nu merlukeun parobahan na gudang data. Konfirmasikeun yén ieu nu dimaksud ku anjeun, sarta anjeun bakal muka konci gudang data nalika pangropéa anjeun geus réngsé.",
        "movenologintext": "Anjeun kudu jadi pamaké nu kadaptar tur [[Special:UserLogin|asup log]] pikeun mindahkeun kaca.",
        "movenotallowed": "Anjeung teu boga kawenangan mindahkeun kaca.",
        "movenotallowedfile": "Anjeung teu boga kawenangan mindahkeun kaca.",
+       "cant-move-user-page": "Anjeun teu miboga hak aksés pikeun ngalihkeun kaca pamaké (misah ti subkaca).",
+       "cant-move-to-user-page": "Anjeun teu miboga hak aksés pikeun ngalihkeun kaca ka hiji kaca pamaké (iwal ka subkaca pamaké).",
+       "cant-move-category-page": "Anjeun teu miboga hak aksés pikeun ngalihkeun kaca kategori.",
+       "cant-move-to-category-page": "Anjeun teu miboga hak aksés pikeun ngalihkeun kaca ka kaca kategori.",
+       "cant-move-subpages": "Anjeun teu miboga hak aksés pikeun ngalihkeun subkaca.",
+       "namespace-nosubpages": "Ngaranspasi \"$1\" teu ngidinan subkaca.",
        "newtitle": "Judul anyar:",
        "move-watch": "Awaskeuneun kaca ieu",
        "movepagebtn": "Pindahkeun kaca",
        "pagemovedsub": "Mindahkeun geus hasil!",
        "movepage-moved": "'''\"$1\" geus dipindahkeun ka \"$2\"'''",
        "movepage-moved-redirect": "Alihan geus dijieunkeun.",
+       "movepage-moved-noredirect": "Panyieunan alihan geus diteken.",
        "articleexists": "Kaca nu ngaranna kitu geus aya, atawa ngaran nu dipilih ku anjeun teu sah. Mangga pilih ngaran séjén.",
        "cantmove-titleprotected": "Anjeun teu bisa mindahkeun kaca ka dieu, sabab éta judul dikonci",
        "movetalk": "Mun bisa, kaca \"obrolan\" ogé pindahkeun.",
        "immobile-source-page": "Ieu kaca teu bisa dipindahkeun.",
        "immobile-target-page": "Teu bisa mindahkeun ka judul nu ditujul.",
        "imagenocrossnamespace": "Teu bisa mindahkeun gambar ka rohangan ngaran nu lain gambar",
+       "nonfile-cannot-move-to-file": "Teu bisa ngalihkeun non-berkas ka ngaranspasi",
        "imagetypemismatch": "Éksténsi berkas anyar teu cocog jeung tipena",
        "imageinvalidfilename": "Ngaran berkas tujuan teu sah",
        "fix-double-redirects": "Hadéan sakabéh alihan ganda nu mungkin kajadian",
        "export-submit": "Ékspor",
        "export-addcattext": "Tambahkeun kaca tina kategori:",
        "export-addcat": "Tambahkeun",
+       "export-addnstext": "Tambahkeun kaca ti ngaranspasi:",
        "export-addns": "Tambahkeun",
        "export-download": "Simpen salaku berkas",
        "export-templates": "Kaasup citakan",
+       "export-pagelinks": "Sartakeun kaca patali nepi ka kajeroan:",
        "export-manual": "Tambahkeun kaca manual:",
        "allmessages": "Talatah sistim",
        "allmessagesname": "Ngaran",
        "allmessagestext": "Ieu mangrupa daptar talatah sistim nu aya na spasi ngaran MediaWiki:.",
        "allmessagesnotsupportedDB": "Kaca ieu teu dirojong sabab '''$wgUseDatabaseMessages''' pareum.",
        "allmessages-filter-legend": "Ayakan",
+       "allmessages-filter": "Saring ku kaayaan kustomisasi:",
        "allmessages-filter-unmodified": "Teu diropéa",
        "allmessages-filter-all": "Kabéh",
        "allmessages-filter-modified": "Diropéa",
        "thumbnail-more": "Gedéan",
        "filemissing": "Berkas leungit",
        "thumbnail_error": "Kasalahan sawaktu nyieun gambar leutik (thumbnail): $1",
+       "thumbnail_error_remote": "Talatah kasalahan ti $1:\n$2",
        "djvu_page_error": "Kaca DjVu teu kawadahan",
        "djvu_no_xml": "Hanteu bisa nyokot XML pikeun berkas DjVu",
+       "thumbnail-temp-create": "Teu bisa nyieun berkas leutik témporer",
        "thumbnail_invalid_params": "Kasalahan paraméter miniatur",
+       "thumbnail_toobigimagearea": "Berkas kalawan diménsi leuwih badag batan $1",
        "thumbnail_dest_directory": "Diréktori nu dituju teu bisa dijieun",
-       "thumbnail_image-type": "Jenis gambar teu dirojong",
+       "thumbnail_image-type": "Jinis gambar teu dirojong",
        "thumbnail_image-missing": "Berkas anu sigana leungit: $1",
        "import": "Impor kaca",
-       "importinterwiki": "Impor transwiki",
+       "importinterwiki": "Impor tina wiki lianna",
        "import-interwiki-text": "Pilih wiki jeung judul kaca nu rék diimpor.\nTanggal révisi katut ngaran nu ngédit bakal dipertahankeun.\nSadaya aktivitas impor transwiki baris kacatet dina [[Special:Log/import|log impor]].",
        "import-interwiki-sourcewiki": "Wiki sumber:",
        "import-interwiki-sourcepage": "Kaca sumber:",
        "import-interwiki-history": "Téplak sakabéh vérsi jujutan pikeun ieu kaca",
        "import-interwiki-templates": "Kaasup sakabéh citakan",
        "import-interwiki-submit": "Impor",
+       "import-mapping-default": "Impor ka lokasi standar",
+       "import-mapping-namespace": "Impor ka ngaranspasi:",
        "import-upload-filename": "Ngaran berkas:",
        "import-comment": "Ringkesan:",
        "importtext": "Mangga ékspor koropakna ti sumber nu dipaké ku wiki migunakeun fungsi Special:Export, simpen na piringan anjeun, teras muatkeun di dieu.",
        "importuploaderrortemp": "Koropak impor gagal dimuat. Folder samentarana leungit.",
        "import-parse-failure": "Prosés impor XML teu hasil",
        "import-noarticle": "Euweuh kaca imporeun!",
-       "import-nonewrevisions": "Sakabéh révisi geus kungsi diimpor saméméhna.",
+       "import-nonewrevisions": "Euweuh révisi nu diimpor (sakum révisi geus aya atawa diliwatan lantaran kasalahan).",
        "xml-error-string": "$1 dina baris $2, kolom $3 (bit $4): $5",
        "import-upload": "Ngamuat data XML",
        "import-invalid-interwiki": "Teu bisa ngimpor ti wiki nu dipilih.",
        "import-rootpage-invalid": "Kaca turunan nu dibikeun judulna salah.",
        "importlogpage": "Log impor",
        "importlogpagetext": "Impor administratif kaca-kaca ti wiki séjén katut jujutanana.",
-       "import-logentry-upload-detail": "$1 {{PLURAL:$1|vérsi heubeul}}",
-       "import-logentry-interwiki-detail": "$1 {{PLURAL:$1|vérsi heubel}} ti $2",
+       "import-logentry-upload-detail": "$1 {{PLURAL:$1|sarévisi|révisi}} diimpor",
+       "import-logentry-interwiki-detail": "$1 {{PLURAL:$1|sarévisi|révisi}} diimpor ti $2",
        "javascripttest": "Nguji JavaScript",
        "javascripttest-pagetext-unknownaction": "Tarékah \"$1\" teu dipikanyaho.",
        "tooltip-pt-userpage": "Kaca {{GENDER:|pamaké anjeun}}",
        "tooltip-pt-preferences": "Préferénsi {{GENDER:|anjeun}}",
        "tooltip-pt-watchlist": "Daptar kaca nu diawaskeun ku anjeun parobahanana.",
        "tooltip-pt-mycontris": "Béréndélan kontribusi {{GENDER:|anjeun}}",
+       "tooltip-pt-anoncontribs": "Daptar éditan nu dijieun ti ieu alamat IP",
        "tooltip-pt-login": "Leuwih hadé asup log, sok sanajan teu wajib",
        "tooltip-pt-login-private": "Anjeun perlu asup log pikeun migunakeun ieu wiki",
        "tooltip-pt-logout": "Kaluar log",
        "tooltip-feed-atom": "Asupan atom pikeun kaca ieu",
        "tooltip-t-contributions": "Béréndélan kontribusi ti {{GENDER:$1|ieu pamaké}}",
        "tooltip-t-emailuser": "Kirim surélék ka {{GENDER:$1|ieu kontributor}}",
+       "tooltip-t-info": "Informasi leuwih jero ngeunaan ieu kaca",
        "tooltip-t-upload": "Unjal berkas",
        "tooltip-t-specialpages": "Daptar sadaya kaca husus",
        "tooltip-t-print": "Vérsi citakeun ieu kaca",
        "tooltip-watch": "Tambahkeun kaca ieu kana awaskeuneun kuring",
        "tooltip-watchlistedit-normal-submit": "Pupus judul",
        "tooltip-watchlistedit-raw-submit": "Anyarkeun aawaseun",
+       "tooltip-recreate": "Jieun deui kaca sanajan sabenerna mah geus dipupus",
        "tooltip-upload": "Prung unjalkeun",
        "tooltip-rollback": "Mulangkeun éditan ka panulis panungtung dina sakali klik",
        "tooltip-undo": "\"Bolay\" malikkeun ieu éditan sarta muka kotak édit dina modeu pramidang.\nCara kieu bisa nambahkeun alesan dina ringkesanana.",
        "lastmodifiedatby": "Kaca ieu panungtungan diédit $2, $1 ku $3.",
        "othercontribs": "Dumasar karya $1.",
        "others": "Séjénna",
-       "siteusers": "{{PLURAL:$2|Pamaké|Pamaké-pamaké}} {{SITENAME}} $1",
+       "siteusers": "{{PLURAL:$2|pamaké|para pamaké}} {{SITENAME}} $1",
+       "anonusers": "{{PLURAL:$2|pamaké|para pamaké}} anonim {{SITENAME}} $1",
        "creditspage": "Pangajén kaca",
        "nocredits": "Teu aya émbaran pangajén pikeun kaca ieu.",
        "spamprotectiontitle": "Saringan spam",
        "spamprotectiontext": "Kaca anu rék disimpen dipeungpeuk ku saringan spam.\nSigana mah ieu téh alatan tutumbu ka loka luar anu dibléklis.",
+       "spamprotectionmatch": "Teks di handap ieu mancing saringan spam kami: $1",
+       "spambot_username": "Pamersihan spam MediaWiki",
        "simpleantispam-label": "Pamariksaan anti-spam.\nAnu ieu <strong>ulah</strong> dieusian!",
        "pageinfo-title": "Émbaran pikeun \"$1\"",
        "pageinfo-header-basic": "Émbaran dasar",
        "pageinfo-header-restrictions": "Protéksi kaca",
        "pageinfo-header-properties": "Properti kaca",
        "pageinfo-display-title": "Judul pidangan",
+       "pageinfo-default-sort": "Konci susun baku",
        "pageinfo-length": "Panjang kaca (dina bit)",
        "pageinfo-article-id": "ID kaca",
        "pageinfo-language": "Basa eusi kaca",
        "pageinfo-robot-index": "Digaékeun",
        "pageinfo-robot-noindex": "Dicaram",
        "pageinfo-watchers": "Jumlah paroris kaca",
+       "pageinfo-visiting-watchers": "Jumlah pamariksa kaca nu nyorang éditan kiwari",
        "pageinfo-few-watchers": "Kurang ti $1 {{PLURAL:$1|pangawas}}",
+       "pageinfo-few-visiting-watchers": "Rék aya atawa henteuna pamariksa kaca nu nyorang éditan kiwari",
        "pageinfo-redirects-name": "Jumlah pindahan ka ieu kaca",
+       "pageinfo-subpages-name": "Nomor subkaca ieu kaca",
        "pageinfo-firstuser": "Panyieun kaca",
+       "pageinfo-firsttime": "Tanggal panyieunan kaca",
        "pageinfo-lastuser": "Pangédit panungtung",
+       "pageinfo-lasttime": "Tanggal éditan panungtung",
        "pageinfo-edits": "Jumlah éditan",
        "pageinfo-authors": "Jumlah kontributor nu béda",
+       "pageinfo-recent-edits": "Jumlah éditan kiwari (dina $1 panungtung)",
        "pageinfo-toolboxlink": "Émbaran kaca",
        "pageinfo-redirectsto": "Alihkeun ka",
        "pageinfo-redirectsto-info": "info",
        "filedelete-current-unregistered": "Koropak \"$1\" euweuh dina pangkalan data.",
        "previousdiff": "← Éditan saméméhna",
        "nextdiff": "Éditan salajengna →",
-       "imagemaxsize": "Watesan gambar na kaca dadaran gambar nepi ka:",
+       "imagemaxsize": "Wates ukuran gambar:<br />''(pikeun kaca déskripsi berkas)''",
        "thumbsize": "Ukuran miniatur:",
        "widthheightpage": "$1 × $2, $3 {{PLURAL:$3|kaca|kaca}}",
        "file-info": "ukuran koropak: $1, tipeu MIME: $2",
        "newimages-legend": "Saringan",
        "newimages-label": "Ngaran berkas (atawa sawaréh tina ngaranna):",
        "newimages-user": "Alamat IP atawa sandiasma",
+       "newimages-newbies": "Témbongkeun kontribusi ti akun anyar wungkul",
+       "newimages-showbots": "Témbongkeun unjalan ku bot",
+       "newimages-hidepatrolled": "Sumputkeun unjalan nu geus diriksa",
+       "newimages-mediatype": "Tipeu média:",
        "noimages": "Taya nanaon.",
        "gallery-slideshow-toggle": "''Toggle'' miniatur",
        "ilsubmit": "Paluruh",
        "exif-orientation": "Oriéntasi",
        "exif-samplesperpixel": "Jumlah komponén",
        "exif-planarconfiguration": "Susunan data",
+       "exif-ycbcrsubsampling": "Rasio subsampling Y ka C",
        "exif-ycbcrpositioning": "Perenah Y jeung C",
        "exif-xresolution": "Résolusi horizontal",
        "exif-yresolution": "Résolusi tangtung",
        "exif-stripoffsets": "Perenah data gambar",
+       "exif-rowsperstrip": "Jumlah baris per strip",
+       "exif-stripbytecounts": "Bita per strip komprési",
        "exif-jpeginterchangeformat": "Ofset ka JPEG SOI",
        "exif-jpeginterchangeformatlength": "Bit data JPEG",
+       "exif-whitepoint": "Kromatisitas titik bodas",
+       "exif-primarychromaticities": "Kromatisitas warna primér",
+       "exif-ycbcrcoefficients": "Koéfisién matriks transformasi rohang warna",
        "exif-referenceblackwhite": "Pasangan ajen rujukan hideung jeung bodas",
        "exif-datetime": "Wanci jeung titimangsa parobahan koropak",
        "exif-imagedescription": "Judul gambar",
        "exif-artist": "Pangarang",
        "exif-copyright": "Nu nyepeng hak cipta",
        "exif-exifversion": "Vérsi Exif",
+       "exif-flashpixversion": "Pangrojong vérsi Flashpix",
        "exif-colorspace": "Rohangan warna",
        "exif-componentsconfiguration": "Harti unggak komponén",
        "exif-compressedbitsperpixel": "Mode komprési gambar",
        "exif-pixelxdimension": "Lébar gambar",
        "exif-pixelydimension": "Jangkung gambar",
        "exif-usercomment": "Koméntar pamaké",
+       "exif-relatedsoundfile": "Berkas audio nu patali",
        "exif-datetimeoriginal": "Titimangsa jeung wanci dijieunna data",
        "exif-datetimedigitized": "Titimangsa jeung wanci digitisasi",
+       "exif-subsectime": "Subdetik DateTime",
+       "exif-subsectimeoriginal": "Subdetik DateTimeOriginal",
+       "exif-subsectimedigitized": "Subdetik DateTimeDigitized",
        "exif-exposuretime": "Waktu pajanan",
        "exif-exposuretime-format": "$1 detik ($2)",
        "exif-fnumber": "Nomer F",
        "exif-whitebalance": "Kasaimbangan bodas",
        "exif-digitalzoomratio": "Rasio zum digital",
        "exif-focallengthin35mmfilm": "Panjang fokus dina film 35 mm",
+       "exif-scenecapturetype": "Tipeu panéwakan",
+       "exif-gaincontrol": "Kontrol layar",
        "exif-contrast": "Kontras",
        "exif-saturation": "Saturasi",
        "exif-sharpness": "Seukeutna",
+       "exif-devicesettingdescription": "Déskripsi pangaturan alat",
+       "exif-subjectdistancerange": "Lolongkrang jarak subyék",
        "exif-imageuniqueid": "ID unik gambar",
        "exif-gpsversionid": "Vérsi tag GPS",
        "exif-gpslatituderef": "Gurat Kalér atawa Kidul",
        "exif-gpslatitude": "Gurat Lintang",
        "exif-gpslongituderef": "Gurat Wétan atawa Kulon",
        "exif-gpslongitude": "Gurat Bujur",
+       "exif-gpsaltituderef": "Référénsi jangkung",
+       "exif-gpsaltitude": "Jangkung",
        "exif-gpstimestamp": "Wanci GPS (jam atomik)",
+       "exif-gpssatellites": "Satelit pikeun pangukuran",
        "exif-gpsstatus": "Status panampa",
+       "exif-gpsmeasuremode": "Modeu pangukuran",
+       "exif-gpsdop": "Katepatan pangukuran",
        "exif-gpsspeedref": "Unit kecepatan",
+       "exif-gpsspeed": "Gancangna panarima GPS",
+       "exif-gpstrackref": "Référénsi arah obahan",
+       "exif-gpstrack": "Arah obahan",
+       "exif-gpsimgdirectionref": "Référénsi arah gambar",
+       "exif-gpsimgdirection": "Arah gambar",
+       "exif-gpsmapdatum": "Data survéi géodési",
+       "exif-gpsdestlatituderef": "Référénsi lintang ti tujuan",
+       "exif-gpsdestlatitude": "Lintang tujuan",
+       "exif-gpsdestlongituderef": "Référénsi bujur ti tujuan",
+       "exif-gpsdestlongitude": "Bujur tujuan",
+       "exif-gpsdestbearingref": "Référénsi bearing tujuan",
+       "exif-gpsdestbearing": "Bearing tujuan",
+       "exif-gpsdestdistanceref": "Référénsi jarak ti tujuan",
+       "exif-gpsdestdistance": "Jarak ti tujuan",
        "exif-gpsprocessingmethod": "Ngaran métodeu olah GPS",
        "exif-gpsareainformation": "Ngaran wewengkon GPS",
        "exif-gpsdatestamp": "Titimangsa GPS",
        "exif-gpsdifferential": "Koréksi diferensial GPS",
+       "exif-jpegfilecomment": "Koméntar berkas JPEG",
        "exif-keywords": "Kecap konci",
        "exif-worldregioncreated": "Wewengkon dunya tempat moto",
        "exif-countrycreated": "Nagara tempat moto",
        "exif-sublocationdest": "Sublokasi kota nu ditémbongkeun",
        "exif-objectname": "Judul pondok",
        "exif-specialinstructions": "Paréntah husus",
+       "exif-headline": "Lulugu",
+       "exif-credit": "Krédit/Panyadia",
        "exif-source": "Sumber",
        "exif-editstatus": "Status éditorial gambar",
        "exif-urgency": "Urgensi",
+       "exif-fixtureidentifier": "Ngaran fikstur",
        "exif-locationdest": "Lokasi nu digambarkeun",
        "exif-locationdestcode": "Kodeu lokasi nu digambarkeun",
        "exif-writer": "Nu nulis",
        "exif-disclaimer": "Bantahan",
        "exif-contentwarning": "Pépéling eusi",
        "exif-giffilecomment": "Koméntar berkas GIF",
-       "exif-intellectualgenre": "Jenis objék",
+       "exif-intellectualgenre": "Jinis objék",
        "exif-subjectnewscode": "Kodeu subjék",
        "exif-scenecode": "Sandi adegan IPTC",
        "exif-event": "Kajaadian anu ditémbongkan",
        "exif-originalimagewidth": "Lébar gambar saméméh diteukteuk",
        "exif-compression-1": "Teu kakompres",
        "exif-copyrighted-true": "Mihak cipta",
-       "exif-copyrighted-false": "Domain publik",
+       "exif-copyrighted-false": "Status hak cipta can diatur",
        "exif-unknowndate": "Titimangsa teu kanyahoan",
        "exif-orientation-1": "Normal",
        "exif-orientation-2": "Dibalikkeun horizontal",
        "exif-orientation-5": "Diputer 90° CCW jeung dibalikkeun vértikal",
        "exif-orientation-6": "Diputer 90° CCW",
        "exif-orientation-7": "Diputer 90° CW jeung dibalikkeun vértikal",
-       "exif-orientation-8": "Diputer 90° CCW",
+       "exif-orientation-8": "Diputer 90° CW",
+       "exif-planarconfiguration-1": "format chunky",
        "exif-planarconfiguration-2": "format datar",
+       "exif-colorspace-65535": "Teu dikalibrasi",
        "exif-componentsconfiguration-0": "euweuh",
+       "exif-exposureprogram-0": "Teu kadéfinisi",
        "exif-exposureprogram-1": "Manual",
        "exif-exposureprogram-2": "Program normal",
+       "exif-exposureprogram-3": "Prioritas bukaan",
+       "exif-exposureprogram-4": "Prioritas panutup",
+       "exif-exposureprogram-5": "Program kréatif (condong ka jejeroan ruang)",
+       "exif-exposureprogram-6": "Program aksi (condong ka gagancangna rana)",
        "exif-exposureprogram-7": "Modeu potrét (pikeun poto deukeut nu tukangna di luar fokus)",
        "exif-exposureprogram-8": "Modeu Lanskap (pikeun poto lanskap nu tukangna asup fokus)",
        "exif-subjectdistance-value": "$1 méter",
        "exif-gpsdirection-t": "Arah sajati",
        "exif-gpsdirection-m": "Arah magnétik",
        "exif-ycbcrpositioning-1": "Nengah",
+       "exif-ycbcrpositioning-2": "Atas (co-sited)",
        "exif-dc-contributor": "Kontributor",
        "exif-dc-date": "Titimangsa",
        "exif-dc-publisher": "Pamedal",
        "exif-dc-relation": "Média anu tumali",
        "exif-dc-rights": "Hak",
        "exif-dc-source": "Média sumber",
-       "exif-dc-type": "Jenis média",
+       "exif-dc-type": "Jinis média",
        "exif-rating-rejected": "Ditolak",
        "exif-isospeedratings-overflow": "Leuwih ti 65535",
        "exif-iimcategory-ace": "Seni, budaya, jeung hiburan",
        "exif-iimcategory-clj": "Hukum jeung kajahatan",
        "exif-iimcategory-dis": "Bencana jeung kacilakaan",
+       "exif-iimcategory-fin": "Ékonomi jeung bisnis",
        "exif-iimcategory-edu": "Atikan",
        "exif-iimcategory-evn": "Lingkungan",
        "exif-iimcategory-hth": "Kawaluyaan",
+       "exif-iimcategory-hum": "Minat jalma",
        "exif-iimcategory-lab": "Katanagakerjaan",
        "exif-iimcategory-lif": "Gaya hirup jeung rékréasi",
        "exif-iimcategory-pol": "Politik",
        "exif-iimcategory-sci": "Sayen jeung téknologi",
        "exif-iimcategory-soi": "Isu sosial",
        "exif-iimcategory-spo": "Olahraga",
+       "exif-iimcategory-war": "Perang, konflik, jeung karesahan",
        "exif-iimcategory-wea": "Cuaca",
        "exif-urgency-normal": "Normal ($1)",
        "exif-urgency-low": "Landeuh ($1)",
        "version-specialpages": "Kaca husus",
        "version-parserhooks": "Kait parser",
        "version-variables": "Variabel",
+       "version-antispam": "Panyegahan spam",
        "version-other": "Séjén",
+       "version-mediahandlers": "Pananganan média",
        "version-hooks": "Kait",
        "version-parser-extensiontags": "Tag éksténsi parser",
+       "version-parser-function-hooks": "Kait fungsi parser",
        "version-hook-name": "Ngaran kait",
        "version-hook-subscribedby": "Didaptarkeun ku",
        "version-version": "($1)",
+       "version-no-ext-name": "[tanpa ngaran]",
        "version-license": "Lisénsi MediaWiki",
        "version-ext-license": "Lisénsi",
        "version-ext-colheader-name": "Éksténsi",
        "version-software": "Sopwér nu geus diinstal",
        "version-software-product": "Produk",
        "version-software-version": "Vérsi",
+       "version-entrypoints": "URL titik éntri",
+       "version-entrypoints-header-entrypoint": "Titik éntri",
        "version-entrypoints-header-url": "URL",
        "version-libraries": "Pabukon kapasang",
        "version-libraries-library": "Pabukon",
        "fileduplicatesearch-info": "$1 × $2 piksel<br />Ukuran koropak: $3<br />Tipeu MIME: $4",
        "fileduplicatesearch-result-1": "Koropak \"$1\" teu boga duplikat idéntik.",
        "fileduplicatesearch-result-n": "Koropak \"$1\" mibanda {{PLURAL:$2|1 duplikat idéntik|$2 duplikat idéntik}}.",
+       "fileduplicatesearch-noresults": "Teu manggihan berkas nu ngaranna \"$1\".",
        "specialpages": "Kaca husus",
        "specialpages-note-top": "Kamandang",
        "specialpages-group-maintenance": "Laporan pigawéeun",
        "tags-tag": "Ngaran tag",
        "tags-source-header": "Sumber",
        "tags-active-header": "Hurung?",
+       "tags-hitcount-header": "Parobahan kalawan tag",
        "tags-actions-header": "Tarékah",
        "tags-active-yes": "Enya",
        "tags-active-no": "Teu",
+       "tags-source-extension": "Ditangtukeun ku pakakas lemes",
+       "tags-source-none": "Teu dipaké deui",
        "tags-edit": "édit",
+       "tags-delete": "pupus",
        "tags-activate": "hurungkeun",
        "tags-deactivate": "pareuman",
        "tags-hitcount": "$1 {{PLURAL:$1|parobahan|parobahan}}",
        "tags-create-tag-name": "Ngaran tag:",
        "tags-create-reason": "Alesan:",
        "tags-create-submit": "Jieun",
+       "tags-create-already-exists": "Tag \"$1\" geus aya.",
+       "tags-create-warnings-below": "Anjeun rék nuluykeun panyieunan ieu tag?",
        "tags-delete-title": "Pupus tag",
        "tags-delete-reason": "Alesan:",
        "tags-activate-title": "Hurungkeun tag",
        "tags-deactivate-reason": "Alesan:",
        "tags-deactivate-submit": "Pareuman",
        "tags-edit-title": "Édit tag",
+       "tags-edit-existing-tags": "Tag nu aya:",
        "tags-edit-existing-tags-none": "<em>Taya</em>",
        "tags-edit-new-tags": "Tag anyar:",
+       "tags-edit-add": "Tambahkeun ieu tag-tag:",
        "tags-edit-remove": "Pupus ieu tag-tag:",
+       "tags-edit-remove-all-tags": "(pupus sakum tag)",
+       "tags-edit-chosen-placeholder": "Pilih sawatara tag",
+       "tags-edit-chosen-no-results": "Euweuh tag nu luyu",
        "tags-edit-reason": "Alesan:",
+       "tags-edit-revision-submit": "Larapkeun parobahan kana {{PLURAL:$1|ieu révisi|$1 révisi}}",
        "comparepages": "Bandinkeun kaca",
        "compare-page1": "Kaca 1",
        "compare-page2": "Kaca 2",
        "compare-rev1": "Révisi 1",
        "compare-rev2": "Révisi 2",
        "compare-submit": "Bandingkeun",
+       "diff-form": "Béda",
+       "diff-form-oldid": "ID révisi heubeul (opsional)",
+       "diff-form-submit": "Témbongkeun bédana",
+       "permanentlink": "Tutumbu permanén",
+       "permanentlink-revid": "ID révisi",
+       "permanentlink-submit": "Tojo ka révisi",
        "dberr-problems": "Punten! Nuju aya gangguan téhnis.",
        "dberr-again": "Cobi antos sababaraha menit, lajeng dimuat ulang.",
-       "dberr-info": "(Teu bisa nyambung jeung server pangkalan data: $1)",
+       "dberr-info": "(Teu bisa ngaksés basis data: $1)",
+       "dberr-info-hidden": "(Teu bisa ngaksés basis data)",
        "dberr-usegoogle": "Kanggo samentawis, tiasa dicobi milari di Google.",
        "htmlform-select-badoption": "Niléy anu diasupkeun teu bener.",
        "htmlform-float-invalid": "Niléy anu diasupkeun lain angka.",
        "htmlform-no": "Henteu",
        "htmlform-yes": "Enya",
        "htmlform-chosen-placeholder": "Pilih opsi",
+       "htmlform-cloner-create": "Tambahkeun leuwih loba",
        "htmlform-cloner-delete": "Pupus",
+       "htmlform-cloner-required": "Saeutikna hiji niléy diperlukeun.",
        "htmlform-date-placeholder": "TTTT-BB-HH",
        "htmlform-time-placeholder": "JJ:MM:DD",
        "htmlform-datetime-placeholder": "TTTT-BB-HH JJ:MM:DD",
        "logentry-newusers-create": "Akun pamaké $1 geus {{GENDER:$2|dijieun}}",
        "logentry-newusers-autocreate": "Akun pamaké $1 {{GENDER:$2|dijieun}} otomatis",
        "logentry-upload-upload": "$1 {{GENDER:$2|ngamuat}} $3",
+       "log-name-tag": "Log tag",
        "rightsnone": "(euweuh)",
+       "feedback-adding": "Nambahkeun eupan balik kana kaca...",
        "feedback-back": "Balik deui",
        "feedback-cancel": "Bolay",
        "feedback-close": "Anggeus",
        "duration-decades": "$1 {{PLURAL:$1|dékadeu|dékadeu}}",
        "duration-centuries": "$1 {{PLURAL:$1|abad|abad}}",
        "duration-millennia": "$1 {{PLURAL:$1|milénium|milénium}}",
+       "limitreport-walltime": "Pamakéan waktu nyaan",
        "expandtemplates": "Mekarkeun citakan",
        "expand_templates_input": "Téks input:",
        "expand_templates_output": "Hasil:",
        "expand_templates_xml_output": "Output XML",
+       "expand_templates_html_output": "Kaluaran HTML atah",
        "expand_templates_ok": "Heug",
        "expand_templates_remove_comments": "Pupus koméntar",
+       "expand_templates_generate_xml": "Témbongkeun tangkal parser XML",
+       "expand_templates_generate_rawhtml": "Témbongkeun HTML atah",
        "expand_templates_preview": "Pramidang",
+       "pagelanguage": "Robah basa kaca",
        "pagelang-name": "Kaca",
        "pagelang-language": "Basa",
+       "pagelang-use-default": "Paké basa baku",
        "pagelang-select-lang": "Pilih basa",
        "pagelang-reason": "Alesan",
        "pagelang-submit": "Kirim",
        "pagelang-nonexistent-page": "Kaca $1 euweuh.",
+       "right-pagelang": "Robah basa kaca",
+       "action-pagelang": "ngarobah basa kaca",
+       "log-name-pagelang": "Log parobahan basa",
        "mediastatistics": "Statistik média",
        "mediastatistics-table-mimetype": "Tipeu MIME",
+       "mediastatistics-table-extensions": "Éksténsi ngamumkinkeun",
        "mediastatistics-table-count": "Jumlah berkas",
        "mediastatistics-table-totalbytes": "Ukuran gabungan",
        "mediastatistics-header-unknown": "Teu dipikanyaho",
        "mediastatistics-header-audio": "Audio",
        "mediastatistics-header-video": "Vidio",
        "mediastatistics-header-multimedia": "Média beunghar",
+       "mediastatistics-header-office": "Aplikasi Office",
        "mediastatistics-header-text": "Tékstual",
+       "mediastatistics-header-executable": "Program",
+       "mediastatistics-header-archive": "Format komprési",
        "mediastatistics-header-total": "Sakumna berkas",
+       "json-error-state-mismatch": "JSON teu sah atawa cacat",
+       "json-error-syntax": "Kasalahan sintaks",
+       "headline-anchor-title": "Tutumbu ka bagéan ieu",
        "special-characters-group-latin": "Latin",
+       "special-characters-group-latinextended": "Éksténsi Latin",
        "special-characters-group-ipa": "IPA",
        "special-characters-group-symbols": "Lambang",
        "special-characters-group-greek": "Yunani",
+       "special-characters-group-greekextended": "Éksténsi Yunani",
        "special-characters-group-cyrillic": "Sirilik",
        "special-characters-group-arabic": "Arab",
+       "special-characters-group-arabicextended": "Éksténsi Arab",
        "special-characters-group-persian": "Parsi",
        "special-characters-group-hebrew": "Ibrani",
        "special-characters-group-bangla": "Bangla",
+       "special-characters-group-tamil": "Tamil",
        "special-characters-group-telugu": "Telugu",
        "special-characters-group-sinhala": "Sinhala",
        "special-characters-group-gujarati": "Gujarati",
+       "special-characters-group-devanagari": "Dewanagari",
        "special-characters-group-thai": "Thai",
        "special-characters-group-lao": "Lao",
        "special-characters-group-khmer": "Khmer",
+       "special-characters-group-canadianaboriginal": "Aborigin Kanada",
+       "special-characters-title-endash": "gurat en",
+       "special-characters-title-emdash": "gurat em",
+       "special-characters-title-minus": "tanda kurang",
+       "mw-widgets-dateinput-no-date": "Euweuh tanggal pinilih",
+       "mw-widgets-mediasearch-input-placeholder": "Paluruh média",
+       "mw-widgets-mediasearch-noresults": "Euweuh hasil nu kapanggih.",
+       "mw-widgets-titleinput-description-new-page": "kaca can aya",
+       "mw-widgets-titleinput-description-redirect": "ngalihkeun ka $1",
+       "mw-widgets-categoryselector-add-category-placeholder": "Tambahkeun kategori...",
+       "mw-widgets-usersmultiselect-placeholder": "Tambahkeun leuwih loba...",
+       "date-range-from": "Ti ping:",
+       "date-range-to": "Nepi ping:",
+       "sessionprovider-generic": "sési $1",
+       "sessionprovider-mediawiki-session-cookiesessionprovider": "sési dumasar kuki",
+       "sessionprovider-nocookies": "Kuki meureun dipareuman. Pastikeun anjeun geus ngahurungkeun kuki sarta coba balikan deui.",
+       "randomrootpage": "Kaca dasar acak",
+       "log-action-filter-block": "Jinis pameungpeukan:",
+       "log-action-filter-contentmodel": "Jinis parobahan modél kontén:",
+       "log-action-filter-delete": "Jinis pamupusan:",
+       "log-action-filter-import": "Jinis impor:",
+       "log-action-filter-managetags": "Jinis tarékah ménéjemén tag:",
+       "log-action-filter-move": "Jinis alihan:",
+       "log-action-filter-newusers": "Jinis panyieunan akun:",
+       "log-action-filter-patrol": "Jinis riksaan:",
+       "log-action-filter-protect": "Jinis panangtayungan:",
+       "log-action-filter-rights": "Jinis parobahan hak aksés:",
+       "log-action-filter-suppress": "Jinis panyamunian:",
+       "log-action-filter-upload": "Jinis unjalan:",
        "log-action-filter-all": "Sakumna",
        "log-action-filter-block-block": "Peungpeuk",
+       "log-action-filter-block-reblock": "Modifikasi peungpeuk",
+       "log-action-filter-block-unblock": "Bolay peungpeukan",
+       "log-action-filter-contentmodel-change": "Robah modél kontén",
+       "log-action-filter-delete-delete": "Pamupusan kaca",
+       "log-action-filter-delete-delete_redir": "Ngalihkeun pangalihan",
+       "log-action-filter-delete-restore": "Bolayan pamupusan",
+       "log-action-filter-delete-event": "Log pamupusan",
+       "log-action-filter-delete-revision": "Pamupusan révisi",
+       "log-action-filter-import-interwiki": "Impor transwiki",
+       "log-action-filter-import-upload": "Impor kalawan unjalan XML",
+       "log-action-filter-managetags-create": "Panyieunan tag",
+       "log-action-filter-managetags-delete": "Pamupusan tag",
+       "log-action-filter-managetags-activate": "Pangaktifan tag",
+       "log-action-filter-managetags-deactivate": "Pamareuman tag",
+       "log-action-filter-move-move": "Alihkeun tanpa ngalandih pangalihan",
+       "log-action-filter-move-move_redir": "Alihkeun kalawan ngalandih pangalihan",
+       "log-action-filter-newusers-create": "Jijieunan ku pamaké anonim",
+       "log-action-filter-newusers-create2": "Jijieunan ku pamaké kadaptar",
+       "log-action-filter-newusers-autocreate": "Panyieunan otomatis",
+       "log-action-filter-newusers-byemail": "Panyieunan kalawan kecap sandi nu dikirimkeun liwat surélék",
+       "log-action-filter-patrol-patrol": "Riksaan manual",
+       "log-action-filter-patrol-autopatrol": "Riksaan otomatis",
+       "log-action-filter-protect-protect": "Panangtayungan",
+       "log-action-filter-protect-modify": "Modifikasi panangtayungan",
+       "log-action-filter-protect-unprotect": "Bolay panangtayungan",
+       "log-action-filter-protect-move_prot": "Pangalihan panangtayungan",
+       "log-action-filter-rights-rights": "Parobahan manual",
+       "log-action-filter-rights-autopromote": "Parobahan otomatis",
+       "log-action-filter-suppress-event": "Log samunian",
+       "log-action-filter-suppress-revision": "Panyamunian révisi",
+       "log-action-filter-suppress-delete": "Panyamunian kaca",
+       "log-action-filter-upload-upload": "Unjalan anyar",
+       "log-action-filter-upload-overwrite": "Unjal deui",
+       "authmanager-create-disabled": "Panyieunan akun ditumpurkeun",
+       "authmanager-authplugin-setpass-failed-title": "Parobahan kecap sandi gagal",
+       "authmanager-authplugin-setpass-bad-domain": "Domain teu sah.",
+       "authmanager-autocreate-noperm": "Panyieunan akun otomatis teu diidinan.",
+       "authmanager-userdoesnotexist": "Akun pamaké \"$1\" teu kadaptar.",
+       "authmanager-username-help": "Sandiasma pikeun oténtikasi.",
+       "authmanager-password-help": "Kecap sandi pikeun oténtikasi.",
+       "authmanager-domain-help": "Domain pikeun oténtikasi éksternal.",
+       "authmanager-retype-help": "Kecap sandi deui pikeun konfirmasi.",
+       "authmanager-email-label": "Surélék",
+       "authmanager-email-help": "Alamat surélék",
+       "authmanager-realname-label": "Ngaran asli",
+       "authmanager-realname-help": "Ngaran asli pamaké",
+       "authmanager-provider-password": "Oténtikasi dumasar kecap sandi",
+       "authprovider-resetpass-skip-label": "Liwatan",
+       "authprovider-resetpass-skip-help": "Liwatan pamulangan kecap sandi",
+       "authform-newtoken": "Token leungit. $1",
+       "authform-notoken": "Token leungit",
+       "authform-wrongtoken": "Token salah",
+       "specialpage-securitylevel-not-allowed-title": "Teu diidinan",
+       "specialpage-securitylevel-not-allowed": "Hampura, anjeun teu diidinan pikeun maké ieu kaca lantaran idéntitas anjeun teu bisa divérifikasi.",
+       "authpage-cannot-login": "Teu bisa ngamimitian asup log.",
+       "authpage-cannot-login-continue": "Teu bisa neruskeun asup log. Sési anjeun jigana geus kadaluwarsa.",
+       "authpage-cannot-create": "Teu bisa ngamimitian nyieun akun.",
+       "authpage-cannot-create-continue": "Teu bisa nuluykeun nyieun akun. Sési anjeun jigana geus kadaluwarsa.",
+       "authpage-cannot-link": "Teu bisa ngamimitian numbukeun akun.",
+       "authpage-cannot-link-continue": "Teu bisa nulurkeun numbukeun akun. Sési anjeun jigana geus kadaluwarsa.",
+       "cannotauth-not-allowed-title": "Idin ditolak",
+       "cannotauth-not-allowed": "Anjeun teu diidinan pikeun maké ieu kaca",
+       "changecredentials": "Robah krédensial",
+       "changecredentials-submit": "Robah krédensial",
        "removecredentials": "Pupus krédensial",
+       "removecredentials-submit": "Pupus krédensial",
        "removecredentials-success": "Krédensial Anda geus dipupus.",
+       "credentialsform-provider": "Jinis krédensial:",
+       "credentialsform-account": "Ngaran akun:",
+       "cannotlink-no-provider-title": "Euweuh akun nu bisa ditumbukeun",
+       "cannotlink-no-provider": "Euweuh akun nu bisa ditumbukeun",
+       "linkaccounts": "Tumbukeun akun",
+       "linkaccounts-success-text": "Akun geus ditumbukeun.",
+       "linkaccounts-submit": "Tumbukeun akun",
+       "unlinkaccounts": "Buka tumbuan akun",
+       "unlinkaccounts-success": "Akun geus teu ditumbukeun",
+       "restrictionsfield-badip": "Alamat IP atawa pantengan IP teu sah: $1",
+       "restrictionsfield-label": "Pantengan IP nu diheugbaékeun:",
+       "restrictionsfield-help": "Hiji alamat IP atawa pantengan CIDR per baris. Pikeun ngahurungkeun sakumna, paké:\n<pre>0.0.0.0/0\n::/0</pre>",
+       "revid": "révisi $1",
+       "pageid": "ID kaca $1",
        "gotointerwiki": "Ninggalkeun{{SITENAME}}",
-       "gotointerwiki-invalid": "Judul spésipik henteu valid"
+       "gotointerwiki-invalid": "Judul nu ditangtukeun teu sah.",
+       "undelete-cantedit": "Anjeun teu bisa ngabolaykeun pamupusan ieu kaca lantaran anjeun teu bisa ngédit ieu kaca.",
+       "pagedata-title": "Data kaca",
+       "pagedata-not-acceptable": "Teu kapanggih format nu luyu. Jinis MIME nu dirojong: $1",
+       "pagedata-bad-title": "Judul teu sah: $1."
 }
index 3650bec..909b2a6 100644 (file)
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (se även [[Special:NewPages|listan över nya sidor]])",
        "recentchanges-legend-plusminus": "(''±123'')",
        "recentchanges-submit": "Visa",
+       "rcfilters-tag-remove": "Ta bort \"$1\"",
        "rcfilters-legend-heading": "<strong>Lista över förkortningar:</strong>",
        "rcfilters-other-review-tools": "<strong>Andra granskningsverktyg</strong>",
        "rcfilters-group-results-by-page": "Gruppera resultat efter sida",
        "rcfilters-hours-title": "Senaste timmarna",
        "rcfilters-days-show-days": "$1 {{PLURAL:$1|dag|dagar}}",
        "rcfilters-days-show-hours": "$1 {{PLURAL:$1|timme|timmar}}",
+       "rcfilters-highlighted-filters-list": "Markerade: $1",
        "rcfilters-quickfilters": "Sparade filter",
        "rcfilters-quickfilters-placeholder-title": "Inga länkar har sparats ännu",
        "rcfilters-quickfilters-placeholder-description": "För att spara dina filterinställningar och återanvända dem senare, klicka på bokmärkesikonen under \"Aktiva filter\" nedan.",
        "rcfilters-empty-filter": "Inga aktiva filter. Alla bidrag visas.",
        "rcfilters-filterlist-title": "Filter",
        "rcfilters-filterlist-whatsthis": "Hur fungerar desse?",
-       "rcfilters-filterlist-feedbacklink": "Ge återkoppling på nya (beta)filter",
+       "rcfilters-filterlist-feedbacklink": "Berätta vad du tycker om dessa (nya) filtreringsverktyg",
        "rcfilters-highlightbutton-title": "Markera resultat",
        "rcfilters-highlightmenu-title": "Välj en färg",
        "rcfilters-highlightmenu-help": "Välj en färg att markera denna egenskap",
        "rcfilters-liveupdates-button": "Liveuppdateringar",
        "rcfilters-liveupdates-button-title-on": "Stäng av live-uppdateringar",
        "rcfilters-liveupdates-button-title-off": "Visa nya ändringar när de händer",
-       "rcfilters-watchlist-markSeen-button": "Markera alla ändringar som sedda",
+       "rcfilters-watchlist-markseen-button": "Markera alla ändringar som sedda",
+       "rcfilters-watchlist-edit-watchlist-button": "Redigera din lista över bevakade sidor",
+       "rcfilters-watchlist-showupdated": "Sidor som har ändrats sedan ditt senaste besök visas i <strong>fetstil</strong> med färgmarkering.",
        "rcnotefrom": "Nedan visas {{PLURAL:$5|ändringen|ändringar}} sedan <strong>$3, $4</strong> (upp till <strong>$1</strong> ändringar visas).",
        "rclistfromreset": "Återställ datumval",
        "rclistfrom": "Visa nya ändringar från och med $2 $3",
        "unwatchthispage": "Sluta bevaka",
        "notanarticle": "Inte en artikel",
        "notvisiblerev": "Sidversionen har raderats",
-       "watchlist-details": "Du har {{PLURAL:$1|en sida|$1 sidor}} på din bevakningslista (diskussionssidor är inte separat medräknade).",
+       "watchlist-details": "{{PLURAL:$1|$1 sida|$1 sidor}} är på din bevakningslista (inklusive diskussionssidor).",
        "wlheader-enotif": "E-postmeddelanden är aktiverade.",
        "wlheader-showupdated": "Sidor som har ändrats sedan ditt senaste besök visas i '''fetstil.'''",
        "wlnote": "Nedan finns {{PLURAL:$1|den senaste ändringen|de senaste <strong>$1</strong> ändringarna}} under {{PLURAL:$2|den senaste timmen|de senaste <strong>$2</strong> timmarna}} från den $3 kl. $4.",
        "modifiedarticleprotection": "ändrade skyddsnivån för \"[[$1]]\"",
        "unprotectedarticle": "tog bort skrivskydd från \"[[$1]]\"",
        "movedarticleprotection": "flyttade skrivskyddsinställningar från \"[[$2]]\" till \"[[$1]]\"",
-       "protectedarticle-comment": "{{GENDER:$2|Skyddad}} \"[[$1]]\"",
+       "protectedarticle-comment": "{{GENDER:$2|Skyddade}} \"[[$1]]\"",
        "modifiedarticleprotection-comment": "{{GENDER:$2|Ändrade skyddsnivå}} för \"[[$1]]\"",
        "unprotectedarticle-comment": "{{GENDER:$2|Tog bort skydd}} från \"[[$1]]\"",
        "protect-title": "Ändra skrivskyddsnivå för \"$1\"",
index 47214e0..b882534 100644 (file)
@@ -80,7 +80,7 @@
        "category-subcat-count": "{{PLURAL:$2|pintbcyan qaniy ga nanak yaquw qutux uzyuk na pintbcyan quw spgluw niya’.| pintbcyan qaniy ga kwara’ kin na $1 uzyuk na pintbcyan sawn niya uziy, $2 kwara’.}}",
        "category-article-count": "{{PLURAL:$2| pintbcyan qaniy ga ginkwara’ zngazyan tay suruw. | pintbcyan qaniy ga kwara’ kin $1 pintbcyan tay suruw, $2 kwara’.}}",
        "category-file-count": "{{PLURAL:$2|Pintbcyan niya’ qaniy ga nanak yaquw nyux niya’ sbiru’ sa hugal qaniy|Pintbcyan niya’ qaniy ga kwara’ kin na biru’ ka $1, psqunun kwara\nga $2 .}}",
-       "listingcontinuesabbrev": "pin’ubuy sa",
+       "listingcontinuesabbrev": "luhing",
        "about": "Nanu’ quw",
        "newwindow": "(gyahiy na giqas na kktan)",
        "cancel": "laxan",
        "history_small": "Pinhknyan sraral",
        "printableversion": "Kinbalay sa musa’ blaq sp’isat",
        "permalink": "Mrayrhuw na pin’ubuy",
+       "print": "Re’in",
        "view": "Psbaybzih minblaq mita’",
        "view-foreign": "Psbzih mita’ squ$1",
        "edit": "Smr’zyut miru’smr’zyut miru’",
        "nstab-template": "Mopan",
        "nstab-category": "Ps’anak sa mkgluw",
        "mainpage-nstab": "T’ringan na zzngayan",
+       "databaseerror-function": "Pptzyuwaw:$1",
        "missingarticle-diff": "(Kin’ini’ ptnaq:$1, $2)",
+       "internalerror": "pin’qwan tay qsahuy",
        "badtitle": "Ungat zyuwaw na lalu’ na spzyang kkayal",
        "badtitletext": "Sni’ su’ lalu’ na spzyang kkayal su’ qasa ga ungat zyuwaw niya’, ungat ana nanu’ qsahuy niya’, ini’ ga ini’ su’ ’nblayqiy p’ubuy quw pin’ubuy su’ squw bzinah na kay’, ini’ ga ’mubuy sa sni’ naha’ lalu’ sa Wiki’. \nKuna kya wal su’ syun ka biru’ qasa ga kya’a cyux ’magan sa biru’ na ini’ baqiy mita’ hazi’.",
        "viewsource": "Kta quw llpgan aring sa cin’ringan",
        "passwordreset": "T’aring lawziy smi’ mima’",
        "passwordreset-username": "Lalu’ na pptzyuwaw:",
        "passwordreset-email": "Zyusyo na e-meyo’:",
+       "changeemail-none": "(ungat)",
        "resettokens-tokens": "Niwan sawsu’:",
        "bold_sample": "Qthuy na biru’",
        "bold_tip": "Qthuy na biru’",
        "anoneditwarning": "<strong>Smrhuw kmal:</strong> Ini’ su’ kzyup na’. Maha iy wal su’ sbahun ana inu’ ga, nanu’ quw cyux ki’an na  IP su’ ga musa’ ktan kwara’ squliq. Maha iy <strong>[$1 wal mzyup]</strong> ini’ ga <strong>[$2 ps’rux Canghaw]</strong>,sinr’zyut su’ miru’ qaniy ga musa’ niya’ s’agal sa lalu’ su’ ka nyux mmiru’ qaniy smbbaq, ru musa’ magal sa kwara’ ka qqblayqan na hway naha’.",
        "loginreqlink": "mzyup",
        "noarticletext-nopermission": "Ungat ana cikuy knayal sa zyuwaw na qsahuy na lalu’ na kay’ squw nyux ktan sa zngayan qaniy.\nAna su’ s’usa’ sa zngayan tay bzinah \n[[Special:Search/{{PAGENAME}}|hmkangi’ sa puqing lalu’ na zngayan qaniy]], ini’ ga <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} hmkangi’ sa m’ubuy sa zyuwaw na bbrwan qutux qutux ryax]</span>,ga ungat kinri’ su’ ms’rux sa zngayan qaniy.",
+       "updated": "(Sinbahan)",
        "note": "<strong> pinkita’ niya’ sa pinzga’ :</strong>",
        "editing": "Nyuw smr’zyut miru’ $1",
        "editingsection": "smr’zyut miru’ $1 (gnaygay binrwan)",
        "moveddeleted-notice": "Wal pzyutan quw zngayan qaniy.\nNyux sbiru’ hugal quw wal pzyutan na zngazyan squw sinhzyuwan bniru’ sa qutux qutux ryax aki’ baqun sa ggalan pspngan mita’.",
        "content-model-wikitext": "Wikitext",
        "content-model-text": "biru’ mlmlux",
+       "content-json-empty-object": "Ungat ana nanu’ quw nnanu’ niya’",
+       "content-json-empty-array": "Ungat ana nanu’ sni’ binrwan naha’",
        "viewpagelogs": "Inblaq mita’ quw bniru’ sa zngazyan qaniy",
        "currentrev-asof": "Spzyang balay giqas sinbahan squw  $1",
        "revisionasof": "Gaga’ na pptzyuwaw sa qutux qutux binkgan gaga’",
        "nextrevision": "Ssbahun babaw nya’→",
        "currentrevisionlink": "Pzyang giqas na sinhzi’",
        "cur": "misuw qaniy ga",
+       "next": "tay suruw",
        "last": "tay glaing",
+       "page_first": "t’ringan balay na llpgan",
+       "page_last": "pucing balay llpgan",
        "histlast": "giqas balay",
        "historysize": "({{PLURAL:$1|$1 bzyaqan kkayal na llpgan}})",
        "rev-delundel": "Smbah sa musa’ slwan mita’",
        "search-showingresults": "{{PLURAL:$4|tay <strong>$1</strong>pucing niya’, psqunun lga <strong>$3</strong> |tay <strong>$1 - $2</strong> pucing nya’, psqunun lga <strong>$3</strong> pucing nya’}}",
        "search-nonefound": "Ktan qu bniru’ niya’ ga ungat quw musa’ mtnaq sa tthuzyay sa awsa’ hmkangi’.",
        "powersearch-toggleall": "Kwara’",
+       "powersearch-togglenone": "Ungat",
        "mypreferences": "Sni’ maku’",
        "prefs-skin": "Ktan na rawziq",
        "skin-preview": "Pnaynama’ mita’",
        "saveprefs": "Cucun",
        "prefs-editing": "Smr’zyut miru’",
        "searchresultshead": "Hhkangi’",
+       "timezonelegend": "Zikang na ini’ ptanaq rhzyal",
        "timezoneregion-africa": "Xweco",
        "timezoneregion-america": "Meco",
        "timezoneregion-antarctica": "Nancicow",
        "prefs-namespaces": "Kungcyen na sslalu’",
        "default": "pinnama’ smi’",
        "prefs-files": "biru’ na zayzyuwaw",
+       "prefs-custom-css": "Sinpung nanak CSS",
        "youremail": "e-meyo’:",
        "username": "{{GENDER:$1|Lalu’ na pptzyuwaw}}:",
        "yourlanguage": "Kay’:",
        "email": "e-meyo’",
        "prefs-i18n": "Koksayka",
+       "prefs-dateformat": "Ksu’ na ryax",
        "prefs-timeoffset": "Kinini’ ptnaq na zikang",
        "prefs-advancedediting": "Kwara’ hya’ g a syensyang",
        "prefs-preview": "Pnaynama’ mita’",
        "recentchanges-submit": "Pkaykita’",
        "rcfilters-filterlist-title": "Hhkangi’",
        "rcfilters-filter-user-experience-level-registered-label": "Pinbiru’",
+       "rcfilters-filter-user-experience-level-unregistered-label": "Iyat pinbiru’ na’",
        "rcfilters-filter-user-experience-level-learner-label": "Misan mqbaq",
        "rcfilters-filter-bots-label": "squliq na kikay",
+       "rcfilters-filter-unpatrolled-label": "Iyat gnawzyagan mita’ na’",
        "rcfilters-filtergroup-significance": "Spzyang krhun na zyuwaw",
+       "rcfilters-filter-categorization-label": "Pintbcyan na sinbahan",
        "rclistfrom": "Inkahul misan sinbahan sa $2, $3",
        "rcshowhideminor": "$1 mszik sa ssr’tun",
        "rcshowhideminor-show": "Pkaykita’",
        "filedesc": "Lalu’ na spzyang bbiru’ su’",
        "fileuploadsummary": "Lalu’ na spzyang bbiru’ su’:",
        "filesource": "Tkhulan:",
+       "upload-file-error": "pin’qwan tay qsahuy",
        "upload-dialog-button-back": "’bzinah",
+       "upload-dialog-button-done": "Tmasuq",
        "upload-dialog-button-save": "Cucun",
        "upload-form-label-infoform-description": "Miblaq pnqzyu’ sa zyuwaw",
+       "upload-form-label-usage-title": "Pptzyuwaw",
        "upload-form-label-infoform-date": "Ryax",
        "license": "Biru’ na gaga’ nqu snwayal hmriq sa kinri’:",
        "license-header": "Biru’ na gaga’ nqu snwayal hmriq sa kinri’",
        "filerevert-comment": "’ringan:",
        "filedelete-comment": "’ringan:",
        "filedelete-submit": "’muyut",
+       "download": "syacay",
        "randompage": "Random page",
        "randomincategory-submit": "Musa’",
        "statistics": "Sinqunan plpuw",
        "pageswithprop-submit": "Musa’",
        "brokenredirects-edit": "Smr’zyut miru’",
        "brokenredirects-delete": "’muyut",
+       "withoutinterwiki-legend": "T’ringan na biru’",
        "withoutinterwiki-submit": "Pkaykita’",
        "nbytes": "$1 {{PLURAL:$1|qutux llpgan na bzyaqan kkayal}}",
        "nmembers": "$1 {{PLURAL:$1|pinglgan}}",
        "prefixindex-submit": "Pkaykita’",
+       "protectedpages-timestamp": "Ryax zikang",
        "protectedpages-page": "Zzngayan",
        "protectedpages-expiry": "Sinpngan ryax",
        "protectedpages-reason": "’ringan",
        "newpages-submit": "Pkaykita’",
        "newpages-username": "Lalu’ na pptzyuwaw:",
        "move": "Smhzi’",
+       "notargettitle": "Ungat sinngusan niya’",
        "pager-older-n": "{{PLURAL:$1|smural hazi’ quw $1}}",
        "suppress": "Shtuy",
+       "apisandbox-retry": "Talam lawziy",
        "apisandbox-results": "Pcingan balay",
        "apisandbox-continue": "Siy lhingiy",
        "booksources": "Brbiru’ na inkhulan na pila’",
        "log": "Pinhknyan sraral",
        "logeventslist-submit": "Pkaykita’",
        "checkbox-all": "Kwara’",
+       "checkbox-none": "Ungat",
+       "checkbox-invert": "Pssyuk mwazyaw",
        "allpages": "Kwara’ biru’ na zngyan",
        "nextpage": "Llpgan tay suruw ($1)",
        "prevpage": "Llpgan tay glaing ($1)",
        "listgrants-rights": "Pcingan na sinpngan",
        "emailusername": "Lalu’ na pptzyuwaw:",
        "emailusernamesubmit": "Pawsun",
+       "emailto": "Sginbang a:",
        "emailsubject": "Spzyang na ptzyuwaw:",
        "emailmessage": "Pintkaykay’:",
        "watchlist": "Cyes’ cingtan",
        "restriction-move": "Smhzi’",
        "restriction-create": "Ps’rux",
        "undeletebtn": "Psbzih",
+       "undeleteinvert": "Pssyuk mwazyaw",
        "undeletecomment": "’ringan:",
        "undelete-search-submit": "Hhkangi’",
        "undelete-show-file-submit": "Aw’",
        "whatlinkshere-submit": "Musa’",
        "ipbreason": "’ringan:",
        "autoblocklist-submit": "Hhkangi’",
+       "blocklist-timestamp": "Ryax zikang",
+       "blocklist-target": "Sinpngan na sinngusan",
        "blocklist-expiry": "Sinpngan ryax",
        "blocklist-reason": "’ringan",
        "ipblocklist-submit": "Hhkangi’",
        "export": "Pawsa’ sa bzinah quwzngayan",
        "export-submit": "Pawsa’",
        "allmessages-filter-legend": "Hhkangi’",
+       "allmessages-filter-unmodified": "Iyat sinbah",
        "allmessages-filter-all": "Kwara’ biru’ na zngyan",
        "allmessages-language": "Kay’:",
        "allmessages-filter-submit": "Mtzyuwaw",
        "simpleantispam-label": "Kmyagal sa kana ptayqihiy na niwan saysyup na kay’ na nnanu.\n<strong>Laxiy</strong> brwaniy sa bbrwan qaniy!",
        "pageinfo-language-change": "smbah",
        "pageinfo-content-model-change": "smbah",
+       "pageinfo-robot-index": "Snwalan",
        "pageinfo-watchers": "Number of page watchers",
        "pageinfo-toolboxlink": "Zzngayan na ggalan qqbaqan",
        "pageinfo-contentpage-yes": "Aw’",
        "file-info-gif-looped": "syunxwan",
        "file-info-png-looped": "syunxwan",
        "newimages-legend": "Hhkangi’",
+       "gallery-slideshow-toggle": "Sbah mita' sa syasing bzinah",
        "ilsubmit": "Hhkangi’",
+       "bydate": "skahul sa ryax",
        "metadata": "Cyuens’cryaw",
        "metadata-help": "Taki’ sa biru’ na kwara’ zayzyuwaw qaniy ga kwara’ kin na zayzyuwaw bbzinah, kwara’ quw zyuwaw sqaniy ga hazi’ na kahul sa pins’rux na Suwe syangciy ini’ ga tmrang squw cyux ps’rux squw Sken ini’ ga cyux tmrang smr’zyut sa Suwe . \nMaha iy wal sbahun squw puqing balay na biru’ cyux syan squw ana nanu’ zyuwaw lga, iyat hazi’ baqun minblaq ppwah kruma’ quw wal minblayqun miru’ na wayal sbahun na zyuwaw hya’ la.",
        "metadata-fields": "maki’ squw bnaykgan na pintkaykay’ ka qsahuy na Cyens’cryaw EXIF ga, syun niya’ sa zzngazyan kwara’ kin na Syasing, nanu’ iy mhiriq quw binrwan niya’ Cyens’cryaw lga nanak yaquw nyux sbiru’ hugal ka pintkaykay’ qaniy msthay.\ncyuens’ cryaw bzinah hya’ lga skun niya’ sa llqingun qasa hya’. \n* make\n* model\n* datetimeoriginal\n* exposuretime\n* fnumber\n* isospeedratings\n* focallength\n* artist\n* copyright\n* imagedescription\n* gpslatitude\n* gpslongitude\n* gpsaltitude",
        "exif-orientation": "Ppiray sa iyat ptkkiy ktan quw syasing",
        "exif-xresolution": "Sweping Cyesitu’",
        "exif-yresolution": "Cwec’ Cyesitu’",
+       "exif-primarychromaticities": "Spzyang balay na iro’",
        "exif-datetime": "Ryax na sinbah Tang’an squw zikang na sinbahan Tang’an",
        "exif-make": "Squliq ka pkbalay squw Syasinki’",
        "exif-model": "Lalu’ na kinblayan Syasingki’",
        "exif-colorspace": "Hhalan mwazyaw sa qqlah sa ini’ ptnaq  kktan na bbiru’",
        "exif-datetimeoriginal": "Ryax na sni’ sa Craw squw zikang na sni’ sa Craw",
        "exif-datetimedigitized": "Ryax na minsuwexwa’ squw zikang na minsuwexwa’",
+       "exif-fnumber": "Kinsmyaxan na syasingki’",
+       "exif-subjectdistance": "Kintwahiq zyuwaw na sinngusan ppsingan",
+       "exif-lightsource": "Puqing na syax",
        "exif-flash": "Pnilaw na pyax pyax",
+       "exif-subjectarea": "Rhzyal cyux ki'an na spzyang kkayal",
+       "exif-subjectlocation": "Cyux ki'an na spzyang kkayal",
+       "exif-whitebalance": "Wayt belns",
        "exif-sharpness": "Srp nes",
        "exif-keywords": "Biru’ na Galan sa hhkangi qsahuy na tenaw",
        "exif-headline": "Lalu’",
        "exif-iimcategory": "Ps’anak sa mkgluw",
        "exif-identifier": "Biru’ na sinbbaq sa cyux naha’ ptcyuwagun",
        "exif-label": "Qinlah lalu’",
+       "exif-compression-1": "Ini’ aniy pkcikuy na’",
+       "exif-unknowndate": "Ini’ bqbaqiy ginlaylwan na ryax",
        "exif-orientation-1": "Mutuw galan sa puqing pspngan kwara’ na squliq",
+       "exif-orientation-2": "Ptbangun pssyuk",
+       "exif-exposureprogram-0": "Ini’ syaniy kay’ na’",
+       "exif-exposureprogram-1": "Szyuwi’ na qba’",
        "exif-meteringmode-0": "Ini’ bqbaqiy ginlaylwan",
+       "exif-meteringmode-1": "Pinqsugan",
+       "exif-meteringmode-4": "Multi-Spot",
        "exif-meteringmode-255": "Bzinah",
        "exif-lightsource-0": "Ini’ bqbaqiy ginlaylwan",
+       "exif-lightsource-1": "Snyaxan wagi’",
        "exif-lightsource-2": "Pnilaw na inkwang",
        "exif-lightsource-4": "Pnilaw na pyax pyax",
        "exif-lightsource-10": "Mzyulung",
+       "exif-lightsource-11": "Tay minkum",
        "exif-focalplaneresolutionunit-2": "incun",
+       "exif-sensingmethod-1": "Ini’ syaniy kay’ na’",
        "exif-customrendered-0": "Kwara’ hya’ ga  cngsyu’",
+       "exif-exposuremode-1": "Pinspsyax na squliq",
        "exif-scenecapturetype-0": "Galan pspngan",
+       "exif-scenecapturetype-2": "Syasing na squliq",
+       "exif-scenecapturetype-3": "Knita’ sa mlhngan na qlqalang",
+       "exif-gaincontrol-0": "Ungat",
+       "exif-gaincontrol-1": "Kcikuy cikay tmwang",
+       "exif-gaincontrol-2": "Kpzyux cikay tmwang",
+       "exif-gaincontrol-3": "Kcikuy cikay hmhuwi’",
+       "exif-gaincontrol-4": "Kpzyux cikay hmhuwi’",
        "exif-contrast-0": "Galan pspngan",
+       "exif-contrast-2": "lawkah/mhitu’",
        "exif-saturation-0": "Galan pspngan",
        "exif-sharpness-0": "Galan pspngan",
+       "exif-sharpness-2": "lawkah/mhitu’",
        "exif-subjectdistancerange-0": "Ini’ bqbaqiy ginlaylwan",
+       "exif-subjectdistancerange-1": "Mekro",
        "exif-gpslatitude-n": "Pewe’",
        "exif-gpslatitude-s": "Nanwe’",
+       "exif-gpslongitude-e": "Ist longzicyut",
        "exif-gpslongitude-w": "Sicing",
        "exif-gpsdestdistance-k": "Kirometa’",
        "exif-gpsdestdistance-m": "Inri’",
        "exif-dc-rights": "Pcingan na sinpngan",
        "exif-iimcategory-hth": "Blaq hi’",
        "exif-iimcategory-spo": "Tayyok",
+       "exif-iimcategory-wea": "Kayal",
        "exif-urgency-normal": "Galan pspngan ($1)",
        "namespacesall": "kwara’",
        "monthsall": "kwara’",
        "imgmultipagenext": "llpgan tay suruw →",
        "imgmultigo": "Aw’!",
        "img-lang-go": "Musa’",
+       "ascending_abbrev": "pskkrawn paybkuw",
        "table_pager_next": "Llpgan tay suruw",
        "table_pager_prev": "Llpgan tay glaing",
+       "table_pager_first": "T’ringan balay na llpgan",
+       "table_pager_last": "Pucing balay llpgan",
        "table_pager_limit_submit": "Pawsun",
        "watchlistedit-raw-titles": "Lalu’:",
        "watchlistedit-clear-titles": "Lalu’:",
        "redirect-lookup": "Hmkangi’:",
        "redirect-user": "Mning ID",
        "redirect-file": "Lalu’ na tang’an",
+       "redirect-not-exists": "Ini' ’luwiy biru’ na llpgan",
        "fileduplicatesearch-filename": "Lalu’ na tang’an:",
        "fileduplicatesearch-submit": "Hhkangi’",
        "specialpages": "Mnanak na zzngayan",
        "tags-delete-reason": "’ringan:",
        "tags-activate-reason": "’ringan:",
        "tags-deactivate-reason": "’ringan:",
+       "tags-edit-existing-tags-none": "<em>Ungat<em>",
        "tags-edit-reason": "’ringan:",
+       "comparepages": "Pspung sa zzngazyan",
        "compare-page2": "Zzngayan 2",
+       "compare-submit": "Pspngun",
        "diff-form": "Kin’ini’ ptnaq",
        "permanentlink": "Mrayrhuw na pin’ubuy",
        "htmlform-submit": "Pawsun",
        "logentry-move-move": "$1 {{GENDER:$2|wal shzyun}}zngyan $3 squw $4",
        "logentry-newusers-create": "Wayal tmasuq {{GENDER:$2|ps’rux sq }} quw cin canghaw $1",
        "logentry-upload-upload": "$1 {{GENDER:$2|wal pawsun }} $3",
+       "rightsnone": "(ungat)",
        "feedback-back": "’bzinah",
+       "feedback-close": "Tmasuq",
        "feedback-message": "Pintkaykay’:",
        "feedback-subject": "Spzyang na ptzyuwaw:",
        "feedback-submit": "Pawsun",
        "mediastatistics-header-text": "Biru’ mlmlux",
        "special-characters-group-latin": "Biru’ na lating",
        "special-characters-group-symbols": "Sni’ naha’ sa gaga’ na bbiru’",
+       "special-characters-group-greek": "Biru’ na Grisya’",
        "special-characters-group-persian": "Przn",
        "special-characters-group-bangla": "Biru’ na Bengr",
        "special-characters-group-thai": "Biru’ na Taykok",
+       "special-characters-group-khmer": "Biru' na Khmer",
        "mw-widgets-titleinput-description-new-page": "ungat zzngayan",
+       "mw-widgets-categoryselector-add-category-placeholder": "Twangiy sa pintbcyan...",
        "log-action-filter-all": "Kwara’ biru’ na zngyan",
        "log-action-filter-block-block": "Qmhut",
+       "log-action-filter-delete-event": "Pzyutan binrwan",
+       "log-action-filter-patrol-patrol": "hkangyun na qba’",
+       "log-action-filter-rights-rights": "Sbah na qba’",
        "authmanager-email-label": "e-meyo’",
        "authmanager-email-help": "Zyusyo na e-meyo’"
 }
index 37349a0..cf24b37 100644 (file)
        "search-showingresults": "{{PLURAL:$4|ผลลัพธ์ <strong>$1</strong> จากทั้งหมด <strong>$3</strong>|ผลลัพธ์ <strong>$1 - $2</strong> จากทั้งหมด <strong>$3</strong>}}",
        "search-nonefound": "ไม่มีผลลัพธ์ตรงกับคำค้น",
        "search-nonefound-thiswiki": "ไม่พบผลลัพธ์ตรงกับคำค้นในเว็บไซต์นี้",
-       "powersearch-legend": "ค้นหาขั้นสูง",
+       "powersearch-legend": "à¸\81ารà¸\84à¹\89à¸\99หาà¸\82ัà¹\89à¸\99สูà¸\87",
        "powersearch-ns": "ค้นหาในเนมสเปซ:",
        "powersearch-togglelabel": "เลือก:",
        "powersearch-toggleall": "ทั้งหมด",
index 83b4c1c..c4ffd62 100644 (file)
        "last": "попер.",
        "page_first": "перша",
        "page_last": "остання",
-       "histlegend": "Вибір версії: позначте у кружечках версії для порівняння і натисніть «Enter» або кнопку внизу.\n\nПояснення: (поточн.) = відмінності від поточної версії,\n(ост.) = відмінності від попередньої версії, '''м''' = незначне редагування",
+       "histlegend": "Вибір версії: позначте у кружечках версії для порівняння і натисніть «Enter» або кнопку внизу.\n\nПояснення: <strong>({{int:cur}})</strong> = відмінності від поточної версії,\n<strong>({{int:last}})</strong> = відмінності від попередньої версії, <strong>{{int:minoreditletter}}</strong> = незначне редагування",
        "history-fieldset-title": "Пошук версій",
        "history-show-deleted": "Лише вилучені версії",
        "histfirst": "найдавніші",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (див. також [[Special:NewPages|список нових сторінок]])",
        "recentchanges-legend-plusminus": "(''±123'')",
        "recentchanges-submit": "Показати",
+       "rcfilters-tag-remove": "Вилучити «$1»",
        "rcfilters-legend-heading": "<strong>Список скорочень:</strong>",
        "rcfilters-other-review-tools": "<strong>Інші інструменти перевірки</strong>",
        "rcfilters-group-results-by-page": "Групувати результати за сторінкою",
        "rcfilters-hours-title": "Останні години",
        "rcfilters-days-show-days": "$1 {{PLURAL:$1|день|дні|днів}}",
        "rcfilters-days-show-hours": "$1 {{PLURAL:$1|година|години|годин}}",
+       "rcfilters-highlighted-filters-list": "Виділено: $1",
        "rcfilters-quickfilters": "Збережені фільтри",
        "rcfilters-quickfilters-placeholder-title": "Ще немає збережених посилань",
        "rcfilters-quickfilters-placeholder-description": "Щоб зберегти Ваші налаштування фільтрів та використати їх пізніше, клацніть на іконку закладки в ділянці активних фільтрів нижче.",
        "rcfilters-empty-filter": "Без фільтрів. Показано всі зміни.",
        "rcfilters-filterlist-title": "Фільтри",
        "rcfilters-filterlist-whatsthis": "Як це працює?",
-       "rcfilters-filterlist-feedbacklink": "Ð\9dадайÑ\82е Ð²Ñ\96дгÑ\83к Ð¿Ñ\80о Ð½Ð¾Ð²Ñ\96 (беÑ\82а) Ñ\84Ñ\96лÑ\8cÑ\82Ñ\80и",
+       "rcfilters-filterlist-feedbacklink": "РозкажÑ\96Ñ\82Ñ\8c Ð½Ð°Ð¼, Ñ\89о Ð\92и Ð´Ñ\83маÑ\94Ñ\82е Ð¿Ñ\80о Ñ\86Ñ\96 (новÑ\96) Ñ\96нÑ\81Ñ\82Ñ\80Ñ\83менÑ\82и Ñ\84Ñ\96лÑ\8cÑ\82Ñ\80Ñ\83ваннÑ\8f",
        "rcfilters-highlightbutton-title": "Виділити результати",
        "rcfilters-highlightmenu-title": "Вибрати колір",
        "rcfilters-highlightmenu-help": "Вибрати колір, щоб виділити цю властивість",
        "rcfilters-filterlist-noresults": "Фільтри не знайдено",
        "rcfilters-noresults-conflict": "Результатів не знайдено через конфлікт у пошукових критеріях",
        "rcfilters-state-message-subset": "Цей фільтр не має впливу, оскільки його результати включені в результати {{PLURAL:$2|цього, ширшого, фільтра|цих, ширших, фільтрів}} (спробуйте увімкнути виділення, щоб вирізнити їх): $1",
-       "rcfilters-state-message-fullcoverage": "Ð\92ибÑ\96Ñ\80 Ñ\83Ñ\81Ñ\96Ñ\85 Ñ\84Ñ\96лÑ\8cÑ\82Ñ\80Ñ\96в Ñ\83 Ð³Ñ\80Ñ\83пÑ\96 â\80\94 Ñ\86е Ð²Ñ\81е Ð¾Ð´Ð½Ð¾, Ñ\89о Ð½Ðµ Ð²Ð¸Ð±Ð¸Ñ\80аÑ\82и Ð¶Ð¾Ð´Ð½Ð¾Ð³Ð¾ Ð· Ð½Ð¸Ñ\85, Ñ\82обÑ\82о Ñ\82аке Ñ\84Ñ\96лÑ\8cÑ\82Ñ\80Ñ\83ваннÑ\8f Ð½Ðµ Ð¼Ð°Ñ\94 Ð²Ð¿Ð»Ð¸Ð²Ñ\83. Ð\93упа містить: $1",
+       "rcfilters-state-message-fullcoverage": "Ð\92ибÑ\80аÑ\82и Ð²Ñ\81Ñ\96 Ñ\84Ñ\96лÑ\8cÑ\82Ñ\80и Ð² Ñ\86Ñ\96й Ð³Ñ\80Ñ\83пÑ\96 â\80\94 Ñ\86е Ð²Ñ\81е Ð¾Ð´Ð½Ð¾, Ñ\89о Ð½Ðµ Ð²Ð¸Ð±Ð¸Ñ\80аÑ\82и Ð¶Ð¾Ð´Ð½Ð¾Ð³Ð¾ Ð· Ð½Ð¸Ñ\85, Ñ\82обÑ\82о Ñ\82аке Ñ\84Ñ\96лÑ\8cÑ\82Ñ\80Ñ\83ваннÑ\8f Ð½Ðµ Ð¼Ð°Ñ\94 Ð²Ð¿Ð»Ð¸Ð²Ñ\83. Ð\93Ñ\80упа містить: $1",
        "rcfilters-filtergroup-authorship": "Авторство внеску",
        "rcfilters-filter-editsbyself-label": "Зміни, здійснені Вами",
        "rcfilters-filter-editsbyself-description": "Ваш власний внесок.",
        "rcfilters-filter-watchlist-watchednew-description": "Зміни до сторінок зі списку спостереження, які Ви не відвідували з моменту здійснення змін.",
        "rcfilters-filter-watchlist-notwatched-label": "Не в списку спостереження",
        "rcfilters-filter-watchlist-notwatched-description": "Усе, за винятком змін до сторінок з Вашого списку спостереження",
+       "rcfilters-filtergroup-watchlistactivity": "Активність у списку спостереження",
+       "rcfilters-filter-watchlistactivity-unseen-label": "Непереглянуті зміни",
+       "rcfilters-filter-watchlistactivity-unseen-description": "Зміни до сторінок, які Ви не відвідували з моменту здійснення цих змін.",
+       "rcfilters-filter-watchlistactivity-seen-label": "Переглянуті зміни",
+       "rcfilters-filter-watchlistactivity-seen-description": "Зміни до сторінок, які Ви відвідували з моменту здійснення цих змін.",
        "rcfilters-filtergroup-changetype": "Вид зміни",
        "rcfilters-filter-pageedits-label": "Редагування сторінок",
        "rcfilters-filter-pageedits-description": "Редагування вікі-вмісту, обговорень, опису категорій тощо.",
        "rcfilters-liveupdates-button": "Оновлення наживо",
        "rcfilters-liveupdates-button-title-on": "Вимкнути оновлення наживо",
        "rcfilters-liveupdates-button-title-off": "Показувати нові зміни одразу ж після їх здійснення",
+       "rcfilters-watchlist-markseen-button": "Позначити всі зміни як переглянуті",
+       "rcfilters-watchlist-edit-watchlist-button": "Редагувати Ваш список сторінок, за якими Ви спостерігаєте",
+       "rcfilters-watchlist-showupdated": "Зміни до сторінок, які Ви не відвідували з моменту здійснення змін, виділені <strong>жирним</strong>, із цілісними маркерами.",
        "rcnotefrom": "Нижче знаходяться {{PLURAL:$5|редагування}} з <strong>$3, $4</strong> (відображено до <strong>$1</strong>).",
        "rclistfromreset": "Скинути вибір дати",
        "rclistfrom": "Показати редагування починаючи з $3 $2.",
        "unwatchthispage": "Скасувати спостереження",
        "notanarticle": "Не стаття",
        "notvisiblerev": "Версія була вилучена",
-       "watchlist-details": "У Ð²Ð°Ñ\88омÑ\83 Ñ\81пиÑ\81кÑ\83 Ñ\81поÑ\81Ñ\82еÑ\80еженнÑ\8f $1 {{PLURAL:$1|Ñ\81Ñ\82оÑ\80Ñ\96нка|Ñ\81Ñ\82оÑ\80Ñ\96нки|Ñ\81Ñ\82оÑ\80Ñ\96нок}} (не Ð²Ñ\80аÑ\85овÑ\83Ñ\8eÑ\87и Ñ\81Ñ\82оÑ\80Ñ\96нок обговорення).",
+       "watchlist-details": "У Ð\92аÑ\88омÑ\83 Ñ\81пиÑ\81кÑ\83 Ñ\81поÑ\81Ñ\82еÑ\80еженнÑ\8f $1 {{PLURAL:$1|Ñ\81Ñ\82оÑ\80Ñ\96нка|Ñ\81Ñ\82оÑ\80Ñ\96нки|Ñ\81Ñ\82оÑ\80Ñ\96нок}} (плÑ\8eÑ\81 Ñ\81Ñ\82оÑ\80Ñ\96нки обговорення).",
        "wlheader-enotif": "Сповіщення електронною поштою ввімкнено.",
        "wlheader-showupdated": "Сторінки, що змінилися після Вашого останнього їх відвідування, виділені '''жирним''' шрифтом.",
        "wlnote": "Нижче наведено {{PLURAL:$1|останнє $1 редагування|останні $1 редагування|останні $1 редагувань}} за {{PLURAL:$2|останню|останні|останні}} <strong>$2</strong> {{PLURAL:$2|годину|години|годин}}, на час $3 $4.",
index d844fb8..6497dfa 100644 (file)
        "recentchanges-legend-heading": "<strong>اختصارات:</strong>",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (نیز [[Special:NewPages|جدید صفحات کی فہرست]]) ملاحظہ فرمائیں",
        "recentchanges-submit": "دکھائیں",
+       "rcfilters-filterlist-feedbacklink": "ہمیں بتایئے کہ آپ آپ ان (نئے) چھننی والے آلات کے بارے میں کیا سوچتے ہیں",
        "rcfilters-filter-user-experience-level-experienced-label": "تجربہ کار صارف",
+       "rcfilters-watchlist-edit-watchlist-button": "اپنی زیرنظر صفحات کی فہرست ترمیم کیجیے",
+       "rcfilters-watchlist-showupdated": "تبدیلیوں کے رونما ہونے کے بعد جن صفحات کا آپ دورہ نہیں کیے ہیں وہ <strong>جلی</strong> میں، ٹھوس مارکروں کے ساتھ ہیں۔",
        "rcnotefrom": "ذیل میں <strong>$2</strong> سے کی گئی {{PLURAL:$5|تبدیلی|تبدیلیاں}} <strong>$1</strong> تک دکھائی جا رہی ہیں۔",
        "rclistfrom": "$2، $3ء سے ہونے والی نئی تبدیلیاں دکھائیں",
        "rcshowhideminor": "معمولی ترامیم $1",
index 9ab3d48..2118541 100644 (file)
        "tog-shownumberswatching": "Hiển thị số người đang xem",
        "tog-oldsig": "Chữ ký hiện tại của bạn:",
        "tog-fancysig": "Xem chữ ký là mã wiki (không có liên kết tự động)",
-       "tog-uselivepreview": "Xem trước trực tiếp",
+       "tog-uselivepreview": "Tránh tải lại trang khi xem trước",
        "tog-forceeditsummary": "Nhắc tôi khi tôi quên tóm lược sửa đổi",
        "tog-watchlisthideown": "Ẩn các sửa đổi của tôi khỏi danh sách theo dõi",
        "tog-watchlisthidebots": "Ẩn các sửa đổi của robot khỏi danh sách theo dõi",
        "tog-watchlisthideminor": "Ẩn các sửa đổi nhỏ khỏi danh sách theo dõi",
        "tog-watchlisthideliu": "Ẩn sửa đổi của thành viên đã đăng nhập khỏi danh sách theo dõi",
        "tog-watchlistreloadautomatically": "Tự động tải lại danh sách theo dõi khi nào bộ lọc được thay đổi (cần JavaScript)",
+       "tog-watchlistunwatchlinks": "Thêm liên kết ngừng theo dõi/theo dõi trực tiếp vào mục trong danh sách theo dõi (cần JavaScript để bật/tắt)",
        "tog-watchlisthideanons": "Ẩn sửa đổi của người dùng vô danh khỏi danh sách theo dõi",
        "tog-watchlisthidepatrolled": "Ẩn sửa đổi đã tuần tra trong danh sách theo dõi",
        "tog-watchlisthidecategorization": "Ẩn việc xếp thể loại",
        "permissionserrorstext-withaction": "Bạn không được quyền $2, vì {{PLURAL:$1|lý do|các lý do}} sau:",
        "contentmodelediterror": "Bạn không thể sửa đổi phiên bản này vì kiểu nội dung của nó là <code>$1</code>, trong khi kiểu nội dung của trang là <code>$2</code>.",
        "recreate-moveddeleted-warn": "'''Cảnh báo: Bạn sắp tạo lại một trang từng bị xóa trước đây.'''\n\nBạn nên cân nhắc trong việc tiếp tục soạn thảo trang này.\nCác nhật trình xóa và di chuyển của trang được đưa ra dưới đây để tiện theo dõi:",
-       "moveddeleted-notice": "Trang này đã bị xóa.\nCác nhật trình xóa và di chuyển của trang được đưa ra dưới đây để tiện theo dõi.",
-       "moveddeleted-notice-recent": "Rất tiếc, trang này vừa bị xóa (trong vòng 24 giờ trước).\nCác nhật trình xóa và di chuyển của trang được đưa ra dưới đây để tiện theo dõi.",
+       "moveddeleted-notice": "Trang này đã bị xóa.\nCác nhật trình xóa, khóa, và di chuyển của trang được đưa ra dưới đây để tiện theo dõi.",
+       "moveddeleted-notice-recent": "Rất tiếc, trang này vừa bị xóa (trong vòng 24 giờ trước).\nCác nhật trình xóa, khóa, và di chuyển của trang được đưa ra dưới đây để tiện theo dõi.",
        "log-fulllog": "Xem nhật trình đầy đủ",
        "edit-hook-aborted": "Một phần bổ trợ phần mềm đã bỏ qua sửa đổi này.\nKhông có lý do nào được đưa ra.",
        "edit-gone-missing": "Không thể cập nhật trang.\nDường như trang này đã bị xóa.",
        "postedit-confirmation-saved": "Sửa đổi của bạn đã được lưu.",
        "edit-already-exists": "Không thể tạo trang mới.\nNó đã tồn tại.",
        "defaultmessagetext": "Nội dung mặc định",
-       "content-failed-to-parse": "Thất bại phân tích nội dung $2 cho mô hình $1: $3",
+       "content-failed-to-parse": "Thất bại phân tích nội dung $2 cho kiểu $1: $3",
        "invalid-content-data": "Dữ liệu nội dung không hợp lệ",
        "content-not-allowed-here": "Không cho phép đưa nội dung “$1” vào trang [[$2]]",
        "editwarning-warning": "Rời khỏi trang này sẽ khiến bạn mất các sửa đổi đã thực hiện.\nNếu đã đăng nhập, bạn có thể tắt cảnh báo này tại mục “{{int:prefs-editing}}” trong tùy chọn cá nhân.",
-       "editpage-invalidcontentmodel-title": "Không hỗ trợ mô hình nội dung",
-       "editpage-invalidcontentmodel-text": "Mô hình nội dung “$1” không được hỗ trợ.",
+       "editpage-invalidcontentmodel-title": "Không hỗ trợ kiểu nội dung",
+       "editpage-invalidcontentmodel-text": "Kiểu nội dung “$1” không được hỗ trợ.",
        "editpage-notsupportedcontentformat-title": "Không hỗ trợ định dạng nội dung",
        "editpage-notsupportedcontentformat-text": "Kiểu nội dung $2 không hỗ trợ định dạng nội dung $1.",
        "content-model-wikitext": "mã wiki",
        "prefs-help-prefershttps": "Đăng xuất và đăng nhập lại để áp dụng tùy chọn này.",
        "prefswarning-warning": "Bạn chưa lưu những thay đổi tùy chọn đã thực hiện.\nNếu bạn rời khỏi trang này mà không bấm “$1”, các tùy chọn của bạn sẽ không được cập nhật.",
        "prefs-tabs-navigation-hint": "Mẹo: Bạn có thể bấm các phím mũi tên trái phải để luân chuyển qua các thẻ trong danh sách thẻ.",
-       "userrights": "Quản lý quyền thành viên",
+       "userrights": "Quyền thành viên",
        "userrights-lookup-user": "Chọn thành viên",
        "userrights-user-editname": "Nhập tên thành viên:",
        "editusergroup": "Tải nhóm người dùng",
        "userrights-expiry-options": "1 ngày:1 day,1 tuần:1 week,1 tháng:1 month,3 tháng:3 months,6 tháng:6 months,1 năm:1 year",
        "userrights-invalid-expiry": "Thời hạn của nhóm “$1” không hợp lệ.",
        "userrights-expiry-in-past": "Thời hạn của nhóm “$1” đã xảy ra ở quá khứ.",
-       "userrights-cannot-shorten-expiry": "Bạn không thể đẩy sớm thời hạn của nhóm “$1”. Chỉ có những người dùng có quyền thêm hay xóa nhóm này có thể đẩy sớm thời hạn.",
+       "userrights-cannot-shorten-expiry": "Bạn không thể đẩy sớm thời hạn thuộc nhóm “$1”. Chỉ có những người dùng có quyền thêm hay xóa nhóm này có thể đẩy sớm thời hạn.",
        "userrights-conflict": "Mâu thuẫn thay đổi sửa nhóm thành viên! Xin vui lòng xem lại và xác nhận các thay đổi của bạn.",
        "group": "Nhóm:",
        "group-user": "Thành viên thông thường",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (xem thêm [[Special:NewPages|danh sách các trang mới]])",
        "recentchanges-legend-plusminus": "(''±123'')",
        "recentchanges-submit": "Xem",
+       "rcfilters-tag-remove": "Loại bỏ “$1”",
+       "rcfilters-legend-heading": "<strong>Danh sách chữ viết tắt:</strong>",
+       "rcfilters-other-review-tools": "<strong>Công cụ duyệt khác</strong>",
+       "rcfilters-group-results-by-page": "Nhóm kết quả theo trang",
+       "rcfilters-grouping-title": "Nhóm",
        "rcfilters-activefilters": "Bộ lọc hiện hành",
+       "rcfilters-advancedfilters": "Bộ lọc nâng cao",
+       "rcfilters-limit-title": "Số kết quả để hiển thị",
+       "rcfilters-limit-shownum": "Xem {{PLURAL:$1|thay đổi|$1 thay đổi}} cuối cùng",
        "rcfilters-days-title": "Những ngày gần đây",
+       "rcfilters-hours-title": "Số giờ gần đây",
+       "rcfilters-days-show-days": "$1 ngày",
+       "rcfilters-days-show-hours": "$1 giờ",
+       "rcfilters-highlighted-filters-list": "Tô màu: $1",
+       "rcfilters-quickfilters": "Bộ lọc đã lưu",
+       "rcfilters-quickfilters-placeholder-title": "Chưa lưu liên kết",
+       "rcfilters-quickfilters-placeholder-description": "Để lưu thiết lập bộ lọc để dùng lại sau, bấm hình dấu trang trong hộp “Bộ lọc hiện hành” bên dưới.",
+       "rcfilters-savedqueries-defaultlabel": "Bộ lọc đã lưu",
+       "rcfilters-savedqueries-rename": "Đổi tên",
        "rcfilters-savedqueries-setdefault": "Đặt làm mặc định",
        "rcfilters-savedqueries-unsetdefault": "Loại bỏ mặc định",
+       "rcfilters-savedqueries-remove": "Loại bỏ",
+       "rcfilters-savedqueries-new-name-label": "Tên",
+       "rcfilters-savedqueries-new-name-placeholder": "Miêu tả mục đích của bộ lọc",
+       "rcfilters-savedqueries-apply-label": "Tạo bộ lọc",
+       "rcfilters-savedqueries-apply-and-setdefault-label": "Tạo bộ lọc mặc định",
+       "rcfilters-savedqueries-cancel-label": "Hủy bỏ",
+       "rcfilters-savedqueries-add-new-title": "Lưu thiết lập bộ lọc hiện tại",
        "rcfilters-restore-default-filters": "Mặc định lại các bộ lọc",
        "rcfilters-clear-all-filters": "Xóa sạch các bộ lọc",
+       "rcfilters-show-new-changes": "Xem các thay đổi mới nhất",
        "rcfilters-search-placeholder": "Lọc các thay đổi gần đây (duyệt hoặc bắt đầu đánh chữ)",
        "rcfilters-invalid-filter": "Bộ lọc không hợp lệ",
        "rcfilters-empty-filter": "Không có bộ lọc hiện hành. Tất cả các đóng góp được hiển thị.",
        "rcfilters-filterlist-title": "Bộ lọc",
+       "rcfilters-filterlist-whatsthis": "Chúng hoạt động làm sao?",
+       "rcfilters-filterlist-feedbacklink": "Cho chúng tôi biết bạn cảm thấy sao về các công cụ bộ lọc mới này",
        "rcfilters-highlightbutton-title": "Làm nổi bật kết quả",
        "rcfilters-highlightmenu-title": "Chọn màu",
        "rcfilters-highlightmenu-help": "Chọn màu để làm nổi bật thuộc tính này",
        "rcfilters-filterlist-noresults": "Không tìm thấy bộ lọc",
        "rcfilters-noresults-conflict": "Không tìm thấy kết quả nào do tiêu chí tìm kiếm đang bị mâu thuẫn",
-       "rcfilters-filtergroup-authorship": "Người sửa đổi",
+       "rcfilters-state-message-subset": "Bộ lọc này không có hiệu lực vì kết quả của nó cũng có trong kết quả của {{PLURAL:$2|bộ lọc|các bộ lọc}} rộng hơn này (thử tô màu để phân biệt): $1",
+       "rcfilters-state-message-fullcoverage": "Chọn tất cả các bộ lọc trong nhóm này có cùng kết quả bằng không chọn gì, nên bộ lọc này không có hiệu lực. Nhóm này bao gồm: $1",
+       "rcfilters-filtergroup-authorship": "Người đóng góp",
        "rcfilters-filter-editsbyself-label": "Sửa đổi của bạn",
        "rcfilters-filter-editsbyself-description": "Các sửa đổi do bạn tạo ra.",
        "rcfilters-filter-editsbyother-label": "Sửa đổi của người khác",
        "rcfilters-filter-editsbyother-description": "Các sửa đổi của người khác.",
-       "rcfilters-filtergroup-userExpLevel": "Trình độ (chỉ người dùng đã đăng ký)",
+       "rcfilters-filtergroup-userExpLevel": "Trạng thái đăng nhập và trình độ của người dùng",
        "rcfilters-filter-user-experience-level-registered-label": "Đã đăng ký",
        "rcfilters-filter-user-experience-level-registered-description": "Người dùng đã đăng nhập.",
        "rcfilters-filter-user-experience-level-unregistered-label": "Vô danh",
        "rcfilters-filter-user-experience-level-unregistered-description": "Người dùng chưa đăng nhập.",
        "rcfilters-filter-user-experience-level-newcomer-label": "Người mới đến",
-       "rcfilters-filter-user-experience-level-newcomer-description": "Chưa tới 10 sửa đổi và 4 ngày hoạt động.",
+       "rcfilters-filter-user-experience-level-newcomer-description": "Người dùng đã đăng nhập có ít hơn 10 sửa đổi và 4 ngày hoạt động.",
        "rcfilters-filter-user-experience-level-learner-label": "Người đang tập",
-       "rcfilters-filter-user-experience-level-learner-description": "Nhiều ngày hoạt động và sửa đổi hơn “Người mới đến” mà ít hơn “Người có kinh nghiệm”.",
+       "rcfilters-filter-user-experience-level-learner-description": "Người dùng đã đăng nhập có nhiều kinh nghiệm hơn “Người mới đến” mà ít hơn “Người có kinh nghiệm”.",
        "rcfilters-filter-user-experience-level-experienced-label": "Người có kinh nghiệm",
-       "rcfilters-filter-user-experience-level-experienced-description": "Hơn 30 ngày hoạt động và 500 sửa đổi.",
+       "rcfilters-filter-user-experience-level-experienced-description": "Người dùng đã đăng nhập có hơn 500 sửa đổi và 30 ngày hoạt động.",
        "rcfilters-filtergroup-automated": "Đóng góp tự động",
        "rcfilters-filter-bots-label": "Bot",
        "rcfilters-filter-bots-description": "Các sửa đổi của công cụ tự động.",
        "rcfilters-filter-watchlist-watchednew-description": "Thay đổi mới trên các trang nằm trong danh sách theo dõi kể từ lần cuối bạn xem trang đó.",
        "rcfilters-filter-watchlist-notwatched-label": "Không trong danh sách theo dõi",
        "rcfilters-filter-watchlist-notwatched-description": "Sửa đổi trên các trang không nằm trong danh sách theo dõi của bạn.",
+       "rcfilters-filtergroup-watchlistactivity": "Hành động trong danh sách theo dõi",
+       "rcfilters-filter-watchlistactivity-unseen-label": "Thay đổi chưa xem",
+       "rcfilters-filter-watchlistactivity-unseen-description": "Thay đổi mới trên các trang kể từ lần cuối bạn xem trang đó.",
+       "rcfilters-filter-watchlistactivity-seen-label": "Thay đổi đã xem",
+       "rcfilters-filter-watchlistactivity-seen-description": "Thay đổi mới trên các trang mà bạn đã xem kể từ lần cuối trang được thay đổi.",
        "rcfilters-filtergroup-changetype": "Kiểu thay đổi",
        "rcfilters-filter-pageedits-label": "Sửa đổi trang",
        "rcfilters-filter-pageedits-description": "Các sửa đổi đối với nội dung wiki, các trang thảo luận, các miêu tả thể loại…",
        "rcfilters-typeofchange-conflicts-hideminor": "Bộ lọc Loại sửa đổi này mâu thuẫn với bộ lọc \"Các sửa đổi nhỏ\". Có một số loại sửa đổi không thể được đánh dấu là \"nhỏ\".",
        "rcfilters-filtergroup-lastRevision": "Phiên bản mới nhất",
        "rcfilters-filter-lastrevision-label": "Phiên bản mới nhất",
-       "rcfilters-filter-lastrevision-description": "Sửa đổi mới nhất trên một trang.",
-       "rcfilters-filter-previousrevision-label": "Các sửa đổi trước",
-       "rcfilters-filter-previousrevision-description": "Tất cả các sửa đổi không phải là sửa đổi mới nhất của trang.",
+       "rcfilters-filter-lastrevision-description": "Chỉ sửa đổi mới nhất trên một trang.",
+       "rcfilters-filter-previousrevision-label": "Không phải phiên bản mới nhất",
+       "rcfilters-filter-previousrevision-description": "Tất cả các sửa đổi không phải là “phiên bản mới nhất”.",
+       "rcfilters-filter-excluded": "Loại trừ",
+       "rcfilters-tag-prefix-namespace-inverted": "<strong>:không</strong> $1",
+       "rcfilters-exclude-button-off": "Loại trừ lựa chọn",
+       "rcfilters-exclude-button-on": "Đang trừ lựa chọn",
+       "rcfilters-view-advanced-filters-label": "Bộ lọc nâng cao",
+       "rcfilters-view-tags": "Sửa đổi được gắn thẻ",
+       "rcfilters-view-namespaces-tooltip": "Lọc kết quả theo không gian tên",
+       "rcfilters-view-tags-tooltip": "Lọc kết quả theo thẻ đánh dấu",
+       "rcfilters-view-return-to-default-tooltip": "Quay lại trình đơn bộ lọc chính",
+       "rcfilters-liveupdates-button": "Cập nhật trực tiếp",
+       "rcfilters-liveupdates-button-title-on": "Tắt cập nhật trực tiếp",
+       "rcfilters-liveupdates-button-title-off": "Hiển thị các thay đổi mới lúc khi xảy ra",
+       "rcfilters-watchlist-markseen-button": "Đánh dấu tất cả thay đổi là đã xem",
+       "rcfilters-watchlist-edit-watchlist-button": "Sửa danh sách trang theo dõi",
+       "rcfilters-watchlist-showupdated": "Thay đổi mới trên các trang kể lần cuối bạn xem trang được in <strong>đậm</strong> và có dấu tô màu.",
        "rcnotefrom": "Dưới đây là {{PLURAL:$5|thay đổi duy nhất|các thay đổi}} từ <strong>$3 $4</strong> (hiển thị tối đa <strong>$1</strong> thay đổi).",
        "rclistfromreset": "Đặt lại lựa chọn ngày",
        "rclistfrom": "Xem các thay đổi từ $2 $3 trở về sau",
        "pageswithprop-legend": "Các trang có thuộc tính trang",
        "pageswithprop-text": "Trang này liệt kê các trang sử dụng một thuộc tính trang nào đó.",
        "pageswithprop-prop": "Tên thuộc tính:",
+       "pageswithprop-reverse": "Sắp xếp chiều ngược",
+       "pageswithprop-sortbyvalue": "Sắp xếp theo giá trị thuộc tính",
        "pageswithprop-submit": "Xem",
        "pageswithprop-prophidden-long": "giá trị thuộc tính văn bản dài dòng bị ẩn ($1)",
        "pageswithprop-prophidden-binary": "giá trị thuộc tính nhị phân bị ẩn ($1)",
        "apisandbox-sending-request": "Đang gửi yêu cầu API...",
        "apisandbox-loading-results": "Nhận kết quả API...",
        "apisandbox-results-error": "Một lỗi xuất hiện khi tải các đáp ứng truy vấn API: $1.",
+       "apisandbox-results-login-suppressed": "Yêu cầu này đã được xử lý giống như thể người dùng chưa đăng nhập yêu cầu, nếu không thì có thể vượt qua chính sách bảo mật cùng gốc (Same-Origin) của trình duyệt. Lưu ý rằng chức năng tự động xử lý dấu hiệu của chỗ thử API không hoạt động tốt đối với những yêu cầu này, nên bạn phải điền thủ công.",
        "apisandbox-request-selectformat-label": "Hiển thị dữ liệu yêu cầu dưới dạng:",
        "apisandbox-request-format-url-label": "Chuỗi truy vấn URL",
        "apisandbox-request-url-label": "URL của yêu cầu:",
        "unwatchthispage": "Ngừng theo dõi",
        "notanarticle": "Không phải trang có nội dung",
        "notvisiblerev": "Phiên bản bị xóa",
-       "watchlist-details": "Bạn đang theo dõi {{PLURAL:$1}}$1 trang, không kể riêng các trang thảo luận.",
+       "watchlist-details": "Bạn đang theo dõi $1 trang, không kể các trang thảo luận.",
        "wlheader-enotif": "Đã bật thông báo qua thư điện tử.",
-       "wlheader-showupdated": "Các trang đã thay đổi kể từ lần cuối bạn xem chúng được in '''đậm'''",
+       "wlheader-showupdated": "Các trang đã thay đổi kể từ lần cuối bạn xem chúng được in <strong>đậm</strong>.",
        "wlnote": "Dưới đây là {{PLURAL:$1|thay đổi duy nhất|<strong>$1</strong> thay đổi gần nhất}} trong {{PLURAL:$2|giờ|<strong>$2</strong> giờ}} qua, tính tới $3 lúc $4.",
        "wlshowlast": "Hiển thị $1 giờ $2 ngày gần đây",
        "watchlist-hide": "Ẩn",
        "enotif_body_intro_moved": "Trang $1 tại {{SITENAME}} đã được $2 di chuyển vào $PAGEEDITDATE. Xem phiên bản hiện hành tại $3 .",
        "enotif_body_intro_restored": "Trang $1 tại {{SITENAME}} đã được $2 phục hồi vào $PAGEEDITDATE. Xem phiên bản hiện hành tại $3 .",
        "enotif_body_intro_changed": "Trang $1 tại {{SITENAME}} đã được $2 thay đổi vào $PAGEEDITDATE. Xem phiên bản hiện hành tại $3 .",
-       "enotif_lastvisited": "Xem $1 để biết các thay đổi diễn ra từ lần xem cuối cùng của bạn.",
-       "enotif_lastdiff": "Vào $1 để xem sự thay đổi này.",
+       "enotif_lastvisited": "Xem $1 để biết các thay đổi diễn ra từ lần xem cuối cùng của bạn",
+       "enotif_lastdiff": "Vào $1 để xem sự thay đổi này",
        "enotif_anon_editor": "người dùng vô danh $1",
        "enotif_body": "Xin chào $WATCHINGUSERNAME,\n\n$PAGEINTRO $NEWPAGE\n\nTóm lược sửa đổi: $PAGESUMMARY $PAGEMINOREDIT\n\nLiên lạc với người viết trang qua:\nthư: $PAGEEDITOR_EMAIL\nwiki: $PAGEEDITOR_WIKI\n\nSẽ không có thông báo nào khác nếu có sự thay đổi tiếp theo trừ khi bạn xem trang đó lúc khi đăng nhập. Bạn cũng có thể thiết lập lại việc nhắc nhở cho tất cả các trang nằm trong danh sách theo dõi của bạn.\n\nHệ thống báo tin {{SITENAME}} thân thiện của bạn\n\n--\nĐể thay đổi các thiết lập thư điện tử thông báo, mời xem:\n{{canonicalurl:{{#special:Preferences}}}}\n\nĐể thay đổi các thiết lập danh sách theo dõi, mời xem:\n{{canonicalurl:{{#special:EditWatchlist}}}}\n\nĐể xóa trang ra khỏi danh sách theo dõi của bạn, mời xem:\n$UNWATCHURL\n\nPhản hồi và cần sự hỗ trợ:\n$HELPPAGE",
+       "enotif_minoredit": "Sửa đổi nhỏ",
        "created": "viết mới",
        "changed": "thay đổi",
        "deletepage": "Xóa trang",
        "delete-warning-toobig": "Trang này có lịch sử sửa đổi lớn, đến hơn $1 lần sửa đổi.\nViệc xóa các trang có thể làm tổn hại đến hoạt động của cơ sở dữ liệu {{SITENAME}};\nhãy cẩn trọng khi thực hiện.",
        "deleteprotected": "Bạn không thể xóa trang này vì nó đã được khóa lại.",
        "deleting-backlinks-warning": "<strong>Cảnh báo:</strong> Có [[Special:WhatLinksHere/{{FULLPAGENAME}}|trang khác]] liên kết đến hoặc nhúng trang mà bạn sắp xóa.",
+       "deleting-subpages-warning": "<strong>Cảnh báo:</strong> Bạn sắp sửa xóa trang có [[Special:PrefixIndex/{{FULLPAGENAME}}/|{{PLURAL:$1|trang con|$1 trang con|51=hơn 50 trang con}}]].",
        "rollback": "Lùi tất cả sửa đổi",
        "rollbacklink": "lùi tất cả",
        "rollbacklinkcount": "lùi tất cả $1 sửa đổi",
        "editcomment": "Tóm lược sửa đổi: <em>$1</em>.",
        "revertpage": "Đã lùi lại sửa đổi của [[Special:Contributions/$2|$2]] ([[User talk:$2|Thảo luận]]) quay về phiên bản cuối của [[User:$1|$1]]",
        "revertpage-nouser": "Đã lùi lại sửa đổi của người dùng ẩn quay về phiên bản cuối của {{GENDER:$1}}[[User:$1|$1]]",
-       "rollback-success": "Đã hủy sửa đổi của $1;\nquay về phiên bản cuối của $2.",
+       "rollback-success": "Đã hủy sửa đổi của {{GENDER:$3}}$1;\nquay về phiên bản cuối của {{GENDER:$4}}$2.",
        "rollback-success-notify": "Đã hủy sửa đổi của $1;\nquay về phiên bản cuối của $2. [$3 Xem thay đổi]",
        "sessionfailure-title": "Phiên thất bại",
        "sessionfailure": "Dường như có trục trặc với phiên đăng nhập của bạn; thao tác này đã bị hủy để tránh việc cướp quyền đăng nhập. Xin hãy nhấn nút “Back”, tải lại trang đó, rồi thử lại.",
        "undelete-search-title": "Tìm kiếm trang đã bị xóa",
        "undelete-search-box": "Tìm kiếm trang đã bị xóa",
        "undelete-search-prefix": "Hiển thị trang có tiền tố:",
+       "undelete-search-full": "Hiển thị các tên trang chứa:",
        "undelete-search-submit": "Tìm kiếm",
        "undelete-no-results": "Không tìm thấy trang đã bị xóa nào khớp với từ khóa.",
        "undelete-filename-mismatch": "Không thể phục hồi phiên bản tập tin vào thời điểm $1: không có tập tin trùng tên",
        "sp-contributions-uploads": "tập tin tải lên",
        "sp-contributions-logs": "nhật trình",
        "sp-contributions-talk": "thảo luận",
-       "sp-contributions-userrights": "quản lý quyền thành viên",
+       "sp-contributions-userrights": "quản lý quyền {{GENDER:$1}}thành viên",
        "sp-contributions-blocked-notice": "Thành viên này hiện đang bị cấm sửa đổi. Nhật trình cấm gần nhất được ghi ở dưới để tiện theo dõi:",
        "sp-contributions-blocked-notice-anon": "Địa chỉ IP này đang bị cấm. Hãy tham khảo mục mới nhất trong nhật trình cấm IP này:",
        "sp-contributions-search": "Tìm kiếm đóng góp",
        "unblocked-id": "$1 đã hết bị cấm",
        "unblocked-ip": "[[Special:Contributions/$1|$1]] đã được bỏ cấm.",
        "blocklist": "Người dùng bị cấm",
-       "autoblocklist": "Các lệnh cấm tự động",
+       "autoblocklist": "Tác vụ cấm tự động",
        "autoblocklist-submit": "Tìm kiếm",
+       "autoblocklist-legend": "Xem danh sách các tác vụ cấm tự động",
+       "autoblocklist-localblocks": "{{PLURAL:$1}}Tác vụ cấm tự động cục bộ",
+       "autoblocklist-total-autoblocks": "Tổng số cấm tự động: $1",
+       "autoblocklist-empty": "Danh sách cấm tự động hiện đang trống.",
+       "autoblocklist-otherblocks": "{{PLURAL:$1}}Tác vụ cấm tự động khác",
        "ipblocklist": "Người dùng bị cấm",
        "ipblocklist-legend": "Tìm một thành viên bị cấm",
        "blocklist-userblocks": "Ẩn tác vụ cấm tài khoản",
        "import-nonewrevisions": "Không nhập phiên bản nào (tất cả các phiên bản đều đã có sẵn hoặc bị bỏ qua do lỗi).",
        "xml-error-string": "$1 tại dòng $2, cột $3 (byte $4): $5",
        "import-upload": "Tải lên dữ liệu XML",
-       "import-token-mismatch": "Mất dữ liệu phiên làm việc.\n\nCó thể bạn đã được đăng xuất. <strong>Xin hãy xác nhận rằng bạn vẫn được đăng nhập và thử lại.</strong>\nNếu vẫn không được, hãy thử [[Special:UserLogout|đăng xuất]] rồi đăng nhập lại, và kiểm tra rằng trình duyệt của bạn cho phép các cookie của trang Web này.",
+       "import-token-mismatch": "Mất dữ liệu phiên làm việc.\n\nCó thể bạn đã được đăng xuất. '''Xin hãy xác nhận rằng bạn vẫn được đăng nhập và thử lại.'''\nNếu vẫn không được, hãy thử [[Special:UserLogout|đăng xuất]] rồi đăng nhập lại, và kiểm tra rằng trình duyệt của bạn cho phép các cookie của trang Web này.",
        "import-invalid-interwiki": "Không thể nhập trang từ wiki được chỉ định.",
        "import-error-edit": "Trang “$1” không được nhập tại vì bạn không được phép sửa đổi nó.",
        "import-error-create": "Trang “$1” không được nhập tại vì bạn không được phép tạo ra nó.",
        "tooltip-pt-mycontris": "Danh sách các đóng góp của tôi",
        "tooltip-pt-anoncontribs": "Danh sách các sửa đổi được thực hiện qua địa chỉ  IP này",
        "tooltip-pt-login": "Đăng nhập sẽ có lợi hơn, tuy nhiên không bắt buộc.",
+       "tooltip-pt-login-private": "Bạn cần phải đăng nhập để sử dụng wiki này",
        "tooltip-pt-logout": "Đăng xuất",
        "tooltip-pt-createaccount": "Khuyến khích bạn mở tài khoản và đăng nhập; tuy nhiên, không phải bắt buộc phải có tài khoản",
        "tooltip-ca-talk": "Thảo luận về trang này",
        "tooltip-ca-nstab-category": "Xem trang thể loại",
        "tooltip-minoredit": "Đánh dấu đây là sửa đổi nhỏ",
        "tooltip-save": "Lưu lại những thay đổi của bạn",
-       "tooltip-publish": "Xuất bản các thay đổi của bạn",
+       "tooltip-publish": "Đăng các thay đổi của bạn",
        "tooltip-preview": "Xem trước những thay đổi, hãy dùng nó trước khi lưu!",
        "tooltip-diff": "Xem thay đổi bạn đã thực hiện.",
        "tooltip-compareselectedversions": "Xem khác biệt giữa hai phiên bản đã chọn của trang này.",
        "anonymous": "{{PLURAL:$1}}Người dùng vô danh của {{SITENAME}}",
        "siteuser": "thành viên $1 của {{SITENAME}}",
        "anonuser": "người dùng vô danh $1 tại {{SITENAME}}",
-       "lastmodifiedatby": "Trang này được $3 cập nhật lần cuối lúc $2 $1.",
+       "lastmodifiedatby": "Trang này được $3 sửa đổi lần cuối lúc $2 $1.",
        "othercontribs": "Dựa trên công trình của $1.",
        "others": "những người khác",
        "siteusers": "{{SITENAME}} {{PLURAL:$2|{{GENDER:$1|người dùng}}|users}} $1",
        "newimages-summary": "Trang đặc biệt này hiển thị các tập tin được tải lên gần đây nhất.",
        "newimages-legend": "Bộ lọc",
        "newimages-label": "Tên tập tin (hoặc một phần tên):",
+       "newimages-user": "Địa chỉ IP hoặc tên người dùng",
+       "newimages-newbies": "Chỉ hiển thị đóng góp của tài khoản mới",
        "newimages-showbots": "Xem các tập tin do bot tải lên",
        "newimages-hidepatrolled": "Ẩn tập tin tải lên đã tuần tra",
+       "newimages-mediatype": "Kiểu phương tiện:",
        "noimages": "Chưa có hình.",
        "gallery-slideshow-toggle": "Bật/tắt hình nhỏ",
        "ilsubmit": "Tìm kiếm",
        "fileduplicatesearch-noresults": "Không tìm thấy tập tin nào tên “$1”.",
        "specialpages": "Các trang đặc biệt",
        "specialpages-note-top": "Chú giải",
+       "specialpages-note-restricted": "* Trang đặc biệt thông thường.\n* <strong class=\"mw-specialpagerestricted\">Trang đặc biệt được hạn chế.</strong>",
        "specialpages-group-maintenance": "Báo cáo bảo quản",
        "specialpages-group-other": "Trang đặc biệt khác",
        "specialpages-group-login": "Đăng nhập / Mở tài khoản",
        "tag-filter": "Bộ lọc [[Special:Tags|thẻ]]:",
        "tag-filter-submit": "Bộ lọc",
        "tag-list-wrapper": "([[Special:Tags|{{PLURAL:$1}}Thẻ]]: $2)",
-       "tag-mw-contentmodelchange": "thay đổi mô hình nội dung",
-       "tag-mw-contentmodelchange-description": "Sửa đổi [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:ChangeContentModel thay đổi mô hình nội dung] của trang",
+       "tag-mw-contentmodelchange": "thay đổi kiểu nội dung",
+       "tag-mw-contentmodelchange-description": "Sửa đổi [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:ChangeContentModel thay đổi kiểu nội dung] của trang",
        "tags-title": "Thẻ đánh dấu",
        "tags-intro": "Trang này liệt kê các thẻ đánh dấu mà phần mềm dùng nó để đánh dấu một sửa đổi, và ý nghĩa của nó.",
        "tags-tag": "Tên thẻ",
        "tags-create-reason": "Lý do:",
        "tags-create-submit": "Tạo mới",
        "tags-create-no-name": "Bạn phải chỉ định một tên thẻ.",
-       "tags-create-invalid-chars": "Tên thẻ không được chứa dấu phẩy (<code>,</code>) hoặc dấu gạch chéo lên (<code>/</code>).",
+       "tags-create-invalid-chars": "Tên thẻ không được chứa dấu phẩy (<code>,</code>), dấu sổ (<code>|</code>), hoặc dấu gạch chéo lên (<code>/</code>).",
        "tags-create-invalid-title-chars": "Tên thẻ không được chứa các ký tự mà không thể được sử dụng trong tiêu đề của trang .",
        "tags-create-already-exists": "Các từ khóa “$1” đã tồn tại.",
        "tags-create-warnings-above": "{{PLURAL:$2|Cảnh báo|Các cảnh báo}} sau gặp phải khi cố gắng để tạo ra thẻ “$1”:",
        "compare-invalid-title": "Tên trang chỉ định không hợp lệ.",
        "compare-title-not-exists": "Tên trang chỉ định không tồn tại.",
        "compare-revision-not-exists": "Phiên bản chỉ định không tồn tại.",
-       "diff-form": "'''biểu mẫu'''",
+       "diff-form": "Khác biệt",
+       "diff-form-oldid": "Số phiên bản cũ (tùy chọn)",
+       "diff-form-revid": "Số phiên bản của khác biệt",
+       "diff-form-submit": "Trình bày khác biệt",
+       "permanentlink": "Liên kết thường trực",
+       "permanentlink-revid": "Số phiên bản",
+       "permanentlink-submit": "Đi đến phiên bản",
        "dberr-problems": "Xin lỗi! Trang này đang gặp phải những khó khăn về kỹ thuật.",
        "dberr-again": "Xin thử đợi vài phút rồi tải lại trang.",
        "dberr-info": "(Không thể liên lạc với máy chủ cơ sở dữ liệu: $1)",
        "logentry-delete-delete": "$1 {{GENDER:$2}}đã xóa trang “$3”",
        "logentry-delete-delete_redir": "$1 {{GENDER:$2}}đã xóa trang đổi hướng $3 bằng cách ghi đè",
        "logentry-delete-restore": "$1 {{GENDER:$2}}đã phục hồi trang $3 ($4)",
+       "logentry-delete-restore-nocount": "$1 {{GENDER:$2}}đã phục hồi trang $3",
+       "restore-count-revisions": "$1 phiên bản",
+       "restore-count-files": "$1 tập tin",
        "logentry-delete-event": "$1 {{GENDER:$2}}đã thay đổi mức hiển thị của {{PLURAL:$5|một mục nhật trình|$5 mục nhật trình}} về $3: $4",
        "logentry-delete-revision": "$1 {{GENDER:$2}}đã thay đổi mức hiển thị của {{PLURAL:$5|một phiên bản|$5 phiên bản}} trang $3: $4",
        "logentry-delete-event-legacy": "$1 {{GENDER:$2}}đã thay đổi mức hiển thị của các mục nhật trình về $3",
        "special-characters-group-thai": "Thái",
        "special-characters-group-lao": "Lào",
        "special-characters-group-khmer": "Khơ-me",
+       "special-characters-group-canadianaboriginal": "Thổ dân Canada",
        "special-characters-title-endash": "dấu gạch en",
        "special-characters-title-emdash": "dấu gạch em",
        "special-characters-title-minus": "dấu trừ",
        "restrictionsfield-help": "Mỗi dòng một địa chỉ IP hoặc dải CIDR. Để kích hoạt tất cả mọi địa chỉ IP, sử dụng:<pre>0.0.0.0/0\n::/0</pre>",
        "revid": "phiên bản $1",
        "pageid": "số trang $1",
+       "rawhtml-notallowed": "Không thể sử dụng thẻ &lt;html&gt; bên ngoài trang bình thường.",
        "gotointerwiki": "Rời khỏi {{SITENAME}}",
        "gotointerwiki-invalid": "Tên trang chỉ định không hợp lệ.",
+       "gotointerwiki-external": "Bạn sắp sửa thoát {{SITENAME}} để đi đến [[$2]], đó là trang Web riêng.\n\n'''[$1 Tiếp tục đi đến $1]'''",
+       "undelete-cantedit": "Bạn không thể phục hồi trang này vì bạn không có quyền sửa đổi trang.",
+       "undelete-cantcreate": "Bạn không thể phục hồi trang này vì không có trang nào với tên này và bạn không có quyền tạo ra trang này.",
        "pagedata-title": "Dữ liệu về trang",
+       "pagedata-text": "Trang này cung cấp giao diện dữ liệu cho các trang. Xin hãy cung cấp tên trang trong URL dùng cú pháp trang con.\n* Chế độ đàm phán nội dung được áp dụng tùy theo đầu đề Accept (chấp nhận) của trình khách của bạn. Điều này có nghĩa rằng dữ liệu trang được cung cấp dưới định dạng thích hợp nhất đối với trình khác của bạn.",
        "pagedata-not-acceptable": "Không tìm thấy định dạng phù hợp. Các kiểu MIME được hỗ trợ: $1",
        "pagedata-bad-title": "Tiêu đề không hợp lệ: $1."
 }
index 986f6d3..99699b5 100644 (file)
        "rcfilters-filter-previousrevision-label": "נישט די לעצטע ווערסיעס",
        "rcfilters-filter-excluded": "אויסגעשלאסן",
        "rcfilters-tag-prefix-namespace-inverted": "<strong>:נישט</strong> $1",
+       "rcfilters-view-advanced-filters-label": "פֿארגעשריטענע פֿילטערס",
        "rcfilters-liveupdates-button": "לעבעדיקע דערהיינטיקונגען",
        "rcnotefrom": "פֿאלגנד {{PLURAL:$5|איז די ענדערונג| זענען די ענדערונגען}} זײַט <strong>$3, $4</strong> (ביז <strong>$1</strong>).",
        "rclistfrom": "װײַזן נײַע ענדערונגען פֿון $3 $2",
index c26fca0..b34927e 100644 (file)
        "rcfilters-empty-filter": "没有激活的过滤器。已显示所有贡献。",
        "rcfilters-filterlist-title": "过滤器",
        "rcfilters-filterlist-whatsthis": "这些是怎样工作的?",
-       "rcfilters-filterlist-feedbacklink": "å\9c¨æ\96°ï¼\88æµ\8bè¯\95ç\89\88ï¼\89è¿\87滤å\99¨ä¸­æ\8f\90ä¾\9bå\8f\8dé¦\88",
+       "rcfilters-filterlist-feedbacklink": "å\91\8aè¯\89æ\88\91们æ\82¨å¯¹è¿\99äº\9bï¼\88æ\96°ï¼\89è¿\87滤工å\85·æ\9c\89ä»\80ä¹\88æ\83³æ³\95",
        "rcfilters-highlightbutton-title": "高亮结果",
        "rcfilters-highlightmenu-title": "选择颜色",
        "rcfilters-highlightmenu-help": "选择颜色来高亮该属性",
        "rcfilters-liveupdates-button": "实时更新",
        "rcfilters-liveupdates-button-title-on": "关闭实时更新",
        "rcfilters-liveupdates-button-title-off": "显示新更改(如有)",
-       "rcfilters-watchlist-markSeen-button": "标记所有更改为已查看",
+       "rcfilters-watchlist-markseen-button": "标记所有更改为已查看",
+       "rcfilters-watchlist-edit-watchlist-button": "编辑您的监视页面的列表",
+       "rcfilters-watchlist-showupdated": "自更改发生以来,对您尚未访问的页面做出的更改以<strong>粗体</strong>显示,并带有立体标记。",
        "rcnotefrom": "下面{{PLURAL:$5|是}}<strong>$3 $4</strong>之后的更改(最多显示<strong>$1</strong>个)。",
        "rclistfromreset": "重置时间选择",
        "rclistfrom": "显示$3 $2之后的新更改",
        "unwatchthispage": "停止监视",
        "notanarticle": "非内容页面",
        "notvisiblerev": "上次由不同用户所作的版本已经删除",
-       "watchlist-details": "不计讨论页,您的监视列表中有$1个页面。",
+       "watchlist-details": "您的监视列表中有{{PLURAL:$1|$1个页面}}(外加讨论页)。",
        "wlheader-enotif": "已启用电子邮件通知。",
        "wlheader-showupdated": "您上次访问后发生更改的页面<strong>加粗</strong>显示。",
        "wlnote": "下面是{{PLURAL:$2|过去<strong>$2</strong>小时}}的{{PLURAL:$1|最后<strong>$1</strong>个更改}},截至$3 $4。",
        "show-big-image-other": "其他{{PLURAL:$2|分辨率}}:$1。",
        "show-big-image-size": "$1×$2像素",
        "file-info-gif-looped": "循环",
-       "file-info-gif-frames": "$1",
+       "file-info-gif-frames": "$1{{PLURAL:$1|帧}}",
        "file-info-png-looped": "循环",
        "file-info-png-repeat": "已播放$1遍",
-       "file-info-png-frames": "$1",
+       "file-info-png-frames": "$1{{PLURAL:$1|帧}}",
        "file-no-thumb-animation": "'''注意:由于技术限制,该文件的缩略图无法进行动画处理。'''",
        "file-no-thumb-animation-gif": "'''注意:由于技术限制,高分辨率GIF图像的缩略图无法进行动画处理。'''",
        "newimages": "新文件图库",
index 2e0a247..46fdcf4 100644 (file)
        "compare-invalid-title": "您所指定的標題無效。",
        "compare-title-not-exists": "您所指定的標題不存在。",
        "compare-revision-not-exists": "您所指定的修訂不存在。",
-       "diff-form": "表",
+       "diff-form": "差異",
+       "diff-form-oldid": "舊修訂版本ID(可選)",
+       "diff-form-revid": "差異的修訂版本ID",
+       "permanentlink": "固定連結",
+       "permanentlink-revid": "修訂版本ID",
        "dberr-problems": "抱歉!這個網站出現了一些技術上的問題。",
        "dberr-again": "請稍後數分鐘後再試。",
        "dberr-info": "(無法存取資料庫:$1)",
diff --git a/languages/messages/MessagesTay.php b/languages/messages/MessagesTay.php
new file mode 100644 (file)
index 0000000..11b5b98
--- /dev/null
@@ -0,0 +1,10 @@
+<?php
+/** Atayal (Tayal)
+ *
+ * To improve a translation please visit https://translatewiki.net
+ *
+ * @ingroup Language
+ * @file
+ */
+
+$fallback = 'zh-hant';
diff --git a/maintenance/archives/patch-categorylinks-fix-pk.sql b/maintenance/archives/patch-categorylinks-fix-pk.sql
new file mode 100644 (file)
index 0000000..20bc716
--- /dev/null
@@ -0,0 +1 @@
+ALTER TABLE /*_*/categorylinks DROP KEY /*i*/cl_from, ADD PRIMARY KEY (cl_from,cl_to);
diff --git a/maintenance/archives/patch-comment-table.sql b/maintenance/archives/patch-comment-table.sql
new file mode 100644 (file)
index 0000000..c8bf958
--- /dev/null
@@ -0,0 +1,59 @@
+--
+-- patch-comment-table.sql
+--
+-- T166732. Add a `comment` table and various columns (and temporary tables) to reference it.
+
+CREATE TABLE /*_*/comment (
+  comment_id bigint unsigned NOT NULL PRIMARY KEY AUTO_INCREMENT,
+  comment_hash INT NOT NULL,
+  comment_text BLOB NOT NULL,
+  comment_data BLOB
+) /*$wgDBTableOptions*/;
+CREATE INDEX /*i*/comment_hash ON /*_*/comment (comment_hash);
+
+CREATE TABLE /*_*/revision_comment_temp (
+  revcomment_rev int unsigned NOT NULL,
+  revcomment_comment_id bigint unsigned NOT NULL,
+  PRIMARY KEY (revcomment_rev, revcomment_comment_id)
+) /*$wgDBTableOptions*/;
+CREATE UNIQUE INDEX /*i*/revcomment_rev ON /*_*/revision_comment_temp (revcomment_rev);
+
+CREATE TABLE /*_*/image_comment_temp (
+  imgcomment_name varchar(255) binary NOT NULL,
+  imgcomment_description_id bigint unsigned NOT NULL,
+  PRIMARY KEY (imgcomment_name, imgcomment_description_id)
+) /*$wgDBTableOptions*/;
+CREATE UNIQUE INDEX /*i*/imgcomment_name ON /*_*/image_comment_temp (imgcomment_name);
+
+ALTER TABLE /*_*/revision
+  ALTER COLUMN rev_comment SET DEFAULT '';
+
+ALTER TABLE /*_*/archive
+  ALTER COLUMN ar_comment SET DEFAULT '',
+  ADD COLUMN ar_comment_id bigint unsigned NOT NULL DEFAULT 0 AFTER ar_comment;
+
+ALTER TABLE /*_*/ipblocks
+  ALTER COLUMN ipb_reason SET DEFAULT '',
+  ADD COLUMN ipb_reason_id bigint unsigned NOT NULL DEFAULT 0 AFTER ipb_reason;
+
+ALTER TABLE /*_*/image
+  ALTER COLUMN img_description SET DEFAULT '';
+
+ALTER TABLE /*_*/oldimage
+  ALTER COLUMN oi_description SET DEFAULT '',
+  ADD COLUMN oi_description_id bigint unsigned NOT NULL DEFAULT 0 AFTER oi_description;
+
+ALTER TABLE /*_*/filearchive
+  ADD COLUMN fa_deleted_reason_id bigint unsigned NOT NULL DEFAULT 0 AFTER fa_deleted_reason,
+  ALTER COLUMN fa_description SET DEFAULT '',
+  ADD COLUMN fa_description_id bigint unsigned NOT NULL DEFAULT 0 AFTER fa_description;
+
+ALTER TABLE /*_*/recentchanges
+  ADD COLUMN rc_comment_id bigint unsigned NOT NULL DEFAULT 0 AFTER rc_comment;
+
+ALTER TABLE /*_*/logging
+  ADD COLUMN log_comment_id bigint unsigned NOT NULL DEFAULT 0 AFTER log_comment;
+
+ALTER TABLE /*_*/protected_titles
+  ALTER COLUMN pt_reason SET DEFAULT '',
+  ADD COLUMN pt_reason_id bigint unsigned NOT NULL DEFAULT 0 AFTER pt_reason;
diff --git a/maintenance/archives/patch-imagelinks-fix-pk.sql b/maintenance/archives/patch-imagelinks-fix-pk.sql
new file mode 100644 (file)
index 0000000..e66500f
--- /dev/null
@@ -0,0 +1 @@
+ALTER TABLE /*_*/imagelinks DROP KEY /*i*/il_from, ADD PRIMARY KEY (il_from,il_to);
diff --git a/maintenance/archives/patch-iwlinks-fix-pk.sql b/maintenance/archives/patch-iwlinks-fix-pk.sql
new file mode 100644 (file)
index 0000000..1dd5220
--- /dev/null
@@ -0,0 +1 @@
+ALTER TABLE /*_*/iwlinks DROP KEY /*i*/iwl_from, ADD PRIMARY KEY (iwl_from,iwl_prefix,iwl_title);
diff --git a/maintenance/archives/patch-langlinks-fix-pk.sql b/maintenance/archives/patch-langlinks-fix-pk.sql
new file mode 100644 (file)
index 0000000..e3ac312
--- /dev/null
@@ -0,0 +1 @@
+ALTER TABLE /*_*/langlinks DROP KEY /*i*/ll_from, ADD PRIMARY KEY (ll_from,ll_lang);
diff --git a/maintenance/archives/patch-log_search-fix-pk.sql b/maintenance/archives/patch-log_search-fix-pk.sql
new file mode 100644 (file)
index 0000000..51bfdf5
--- /dev/null
@@ -0,0 +1 @@
+ALTER TABLE /*_*/log_search DROP KEY /*i*/ls_field_val, ADD PRIMARY KEY (ls_field,ls_value,ls_log_id);
diff --git a/maintenance/archives/patch-log_search-rename-index.sql b/maintenance/archives/patch-log_search-rename-index.sql
deleted file mode 100644 (file)
index 7e1113e..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
--- Rename the primary unique index from PRIMARY to ls_field_val
--- This is for MySQL only and is necessary only for databases which were updated
--- between MW 1.16 development revisions r50567 and r51465.
-ALTER TABLE /*_*/log_search
-       DROP PRIMARY KEY,
-       ADD UNIQUE INDEX ls_field_val (ls_field,ls_value,ls_log_id);
-
diff --git a/maintenance/archives/patch-module_deps-fix-pk.sql b/maintenance/archives/patch-module_deps-fix-pk.sql
new file mode 100644 (file)
index 0000000..2338df0
--- /dev/null
@@ -0,0 +1 @@
+ALTER TABLE /*_*/module_deps DROP KEY /*i*/md_module_skin, ADD PRIMARY KEY (md_module,md_skin);
diff --git a/maintenance/archives/patch-objectcache-fix-pk.sql b/maintenance/archives/patch-objectcache-fix-pk.sql
new file mode 100644 (file)
index 0000000..cd55716
--- /dev/null
@@ -0,0 +1 @@
+ALTER TABLE /*_*/objectcache DROP KEY /*i*/keyname, ADD PRIMARY KEY (keyname);
diff --git a/maintenance/archives/patch-pagelinks-fix-pk.sql b/maintenance/archives/patch-pagelinks-fix-pk.sql
new file mode 100644 (file)
index 0000000..e269143
--- /dev/null
@@ -0,0 +1 @@
+ALTER TABLE /*_*/pagelinks DROP INDEX /*i*/pl_from, ADD PRIMARY KEY (pl_from,pl_namespace,pl_title);
diff --git a/maintenance/archives/patch-querycache_info-fix-pk.sql b/maintenance/archives/patch-querycache_info-fix-pk.sql
new file mode 100644 (file)
index 0000000..94f3c1d
--- /dev/null
@@ -0,0 +1 @@
+ALTER TABLE /*_*/querycache_info DROP KEY /*i*/qci_type, ADD PRIMARY KEY (qci_type);
diff --git a/maintenance/archives/patch-site_stats-fix-pk.sql b/maintenance/archives/patch-site_stats-fix-pk.sql
new file mode 100644 (file)
index 0000000..d32adf3
--- /dev/null
@@ -0,0 +1 @@
+ALTER TABLE /*_*/site_stats DROP KEY /*i*/ss_row_id, ADD PRIMARY KEY (ss_row_id);
diff --git a/maintenance/archives/patch-templatelinks-fix-pk.sql b/maintenance/archives/patch-templatelinks-fix-pk.sql
new file mode 100644 (file)
index 0000000..8aca510
--- /dev/null
@@ -0,0 +1 @@
+ALTER TABLE /*_*/templatelinks DROP INDEX /*i*/tl_from, ADD PRIMARY KEY (tl_from,tl_namespace,tl_title);
diff --git a/maintenance/archives/patch-text-fix-pk.sql b/maintenance/archives/patch-text-fix-pk.sql
new file mode 100644 (file)
index 0000000..b546333
--- /dev/null
@@ -0,0 +1 @@
+ALTER TABLE /*_*/text DROP KEY /*i*/old_id, ADD PRIMARY KEY (old_id);
diff --git a/maintenance/archives/patch-transcache-fix-pk.sql b/maintenance/archives/patch-transcache-fix-pk.sql
new file mode 100644 (file)
index 0000000..2e8fea1
--- /dev/null
@@ -0,0 +1 @@
+ALTER TABLE /*_*/transcache DROP KEY /*i*/tc_url_idx, ADD PRIMARY KEY (tc_url);
diff --git a/maintenance/archives/patch-user_former_groups-fix-pk.sql b/maintenance/archives/patch-user_former_groups-fix-pk.sql
new file mode 100644 (file)
index 0000000..9a776ca
--- /dev/null
@@ -0,0 +1 @@
+ALTER TABLE /*_*/user_former_groups DROP KEY /*i*/ufg_user_group, ADD PRIMARY KEY (ufg_user,ufg_group);
diff --git a/maintenance/archives/patch-user_properties-fix-pk.sql b/maintenance/archives/patch-user_properties-fix-pk.sql
new file mode 100644 (file)
index 0000000..5d51b78
--- /dev/null
@@ -0,0 +1 @@
+ALTER TABLE /*_*/user_properties DROP KEY /*i*/user_properties_user_property, ADD PRIMARY KEY (up_user,up_property);
diff --git a/maintenance/dumpCategoriesAsRdf.php b/maintenance/dumpCategoriesAsRdf.php
new file mode 100644 (file)
index 0000000..ff50498
--- /dev/null
@@ -0,0 +1,158 @@
+<?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
+ *
+ */
+use Wikimedia\Purtle\RdfWriter;
+use Wikimedia\Purtle\RdfWriterFactory;
+use Wikimedia\Rdbms\IDatabase;
+
+require_once __DIR__ . '/Maintenance.php';
+
+/**
+ * Maintenance script to provide RDF representation of the category tree.
+ *
+ * @ingroup Maintenance
+ * @since 1.30
+ */
+class DumpCategoriesAsRdf extends Maintenance {
+       /**
+        * @var RdfWriter
+        */
+       private $rdfWriter;
+       /**
+        * Categories RDF helper.
+        * @var CategoriesRdf
+        */
+       private $categoriesRdf;
+
+       public function __construct() {
+               parent::__construct();
+
+               $this->addDescription( "Generate RDF dump of categories in a wiki." );
+
+               $this->setBatchSize( 200 );
+               $this->addOption( 'output', "Output file (default is stdout). Will be overwritten.",
+                       false, true );
+               $this->addOption( 'format', "Set the dump format.", false, true );
+       }
+
+       /**
+        * Produce row iterator for categories.
+        * @param IDatabase $dbr Database connection
+        * @return RecursiveIterator
+        */
+       public function getCategoryIterator( IDatabase $dbr ) {
+               $it = new BatchRowIterator(
+                       $dbr,
+                       'page',
+                       [ 'page_title' ],
+                       $this->mBatchSize
+               );
+               $it->addConditions( [
+                       'page_namespace' => NS_CATEGORY,
+               ] );
+               $it->setFetchColumns( [ 'page_title', 'page_id' ] );
+               return $it;
+       }
+
+       /**
+        * Get iterator for links for categories.
+        * @param IDatabase $dbr
+        * @param array $ids List of page IDs
+        * @return Traversable
+        */
+       public function getCategoryLinksIterator( IDatabase $dbr, array $ids ) {
+               $it = new BatchRowIterator(
+                       $dbr,
+                       'categorylinks',
+                       [ 'cl_from', 'cl_to' ],
+                       $this->mBatchSize
+               );
+               $it->addConditions( [
+                       'cl_type' => 'subcat',
+                       'cl_from' => $ids
+               ] );
+               $it->setFetchColumns( [ 'cl_from', 'cl_to' ] );
+               return new RecursiveIteratorIterator( $it );
+       }
+
+       public function addDumpHeader( $timestamp ) {
+               global $wgRightsUrl;
+               $licenseUrl = $wgRightsUrl;
+               if ( substr( $licenseUrl, 0, 2 ) == '//' ) {
+                       $licenseUrl = 'https:' . $licenseUrl;
+               }
+               $this->rdfWriter->about( wfExpandUrl( '/categoriesDump', PROTO_CANONICAL ) )
+                       ->a( 'schema', 'Dataset' )
+                       ->a( 'owl', 'Ontology' )
+                       ->say( 'cc', 'license' )->is( $licenseUrl )
+                       ->say( 'schema', 'softwareVersion' )->value( CategoriesRdf::FORMAT_VERSION )
+                       ->say( 'schema', 'dateModified' )
+                               ->value( wfTimestamp( TS_ISO_8601, $timestamp ), 'xsd', 'dateTime' )
+                       ->say( 'schema', 'isPartOf' )->is( wfExpandUrl( '/', PROTO_CANONICAL ) )
+                       ->say( 'owl', 'imports' )->is( CategoriesRdf::OWL_URL );
+       }
+
+       public function execute() {
+               $outFile = $this->getOption( 'output', 'php://stdout' );
+
+               if ( $outFile === '-' ) {
+                       $outFile = 'php://stdout';
+               }
+
+               $output = fopen( $outFile, 'w' );
+               $this->rdfWriter = $this->createRdfWriter( $this->getOption( 'format', 'ttl' ) );
+               $this->categoriesRdf = new CategoriesRdf( $this->rdfWriter );
+
+               $this->categoriesRdf->setupPrefixes();
+               $this->rdfWriter->start();
+
+               $this->addDumpHeader( time() );
+               fwrite( $output, $this->rdfWriter->drain() );
+
+               $dbr = $this->getDB( DB_REPLICA, [ 'vslow' ] );
+
+               foreach ( $this->getCategoryIterator( $dbr ) as $batch ) {
+                       $pages = [];
+                       foreach ( $batch as $row ) {
+                               $this->categoriesRdf->writeCategoryData( $row->page_title );
+                               $pages[$row->page_id] = $row->page_title;
+                       }
+
+                       foreach ( $this->getCategoryLinksIterator( $dbr, array_keys( $pages ) ) as $row ) {
+                               $this->categoriesRdf->writeCategoryLinkData( $pages[$row->cl_from], $row->cl_to );
+                       }
+                       fwrite( $output, $this->rdfWriter->drain() );
+               }
+               fflush( $output );
+               if ( $outFile !== '-' ) {
+                       fclose( $output );
+               }
+       }
+
+       /**
+        * @param string $format Writer format
+        * @return RdfWriter
+        */
+       private function createRdfWriter( $format ) {
+               $factory = new RdfWriterFactory();
+               return $factory->getWriter( $factory->getFormatName( $format ) );
+       }
+}
+
+$maintClass = "DumpCategoriesAsRdf";
+require_once RUN_MAINTENANCE_IF_MAIN;
index 0fae63c..97cd37e 100644 (file)
@@ -68,13 +68,11 @@ class FixExtLinksProtocolRelative extends LoggedUpdateMaintenance {
                        $db->insert( 'externallinks',
                                [
                                        [
-                                               'el_id' => $db->nextSequenceValue( 'externallinks_el_id_seq' ),
                                                'el_from' => $row->el_from,
                                                'el_to' => $row->el_to,
                                                'el_index' => "http:{$row->el_index}",
                                        ],
                                        [
-                                               'el_id' => $db->nextSequenceValue( 'externallinks_el_id_seq' ),
                                                'el_from' => $row->el_from,
                                                'el_to' => $row->el_to,
                                                'el_index' => "https:{$row->el_index}",
index 802619e..206c7ee 100644 (file)
@@ -37,6 +37,7 @@ class BackupReader extends Maintenance {
        public $revCount = 0;
        public $dryRun = false;
        public $uploads = false;
+       protected $uploadCount = 0;
        public $imageBasePath = false;
        public $nsFilter = false;
 
diff --git a/maintenance/migrateComments.php b/maintenance/migrateComments.php
new file mode 100644 (file)
index 0000000..4313806
--- /dev/null
@@ -0,0 +1,291 @@
+<?php
+/**
+ * Migrate comments from pre-1.30 columns to the 'comment' table
+ *
+ * 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 Maintenance
+ */
+
+use Wikimedia\Rdbms\IDatabase;
+
+require_once __DIR__ . '/Maintenance.php';
+
+/**
+ * Maintenance script that migrates comments from pre-1.30 columns to the
+ * 'comment' table
+ *
+ * @ingroup Maintenance
+ */
+class MigrateComments extends LoggedUpdateMaintenance {
+       public function __construct() {
+               parent::__construct();
+               $this->addDescription( 'Migrates comments from pre-1.30 columns to the \'comment\' table' );
+               $this->setBatchSize( 100 );
+       }
+
+       protected function getUpdateKey() {
+               return __CLASS__;
+       }
+
+       protected function updateSkippedMessage() {
+               return 'comments already migrated.';
+       }
+
+       protected function doDBUpdates() {
+               global $wgCommentTableSchemaMigrationStage;
+
+               if ( $wgCommentTableSchemaMigrationStage < MIGRATION_WRITE_NEW ) {
+                       $this->output(
+                               "...cannot update while \$wgCommentTableSchemaMigrationStage < MIGRATION_WRITE_NEW\n"
+                       );
+                       return false;
+               }
+
+               $this->migrateToTemp(
+                       'revision', 'rev_id', 'rev_comment', 'revcomment_rev', 'revcomment_comment_id'
+               );
+               $this->migrate( 'archive', 'ar_id', 'ar_comment' );
+               $this->migrate( 'ipblocks', 'ipb_id', 'ipb_reason' );
+               $this->migrateToTemp(
+                       'image', 'img_name', 'img_description', 'imgcomment_name', 'imgcomment_description_id'
+               );
+               $this->migrate( 'oldimage', [ 'oi_name', 'oi_timestamp' ], 'oi_description' );
+               $this->migrate( 'filearchive', 'fa_id', 'fa_deleted_reason' );
+               $this->migrate( 'filearchive', 'fa_id', 'fa_description' );
+               $this->migrate( 'recentchanges', 'rc_id', 'rc_comment' );
+               $this->migrate( 'logging', 'log_id', 'log_comment' );
+               $this->migrate( 'protected_titles', [ 'pt_namespace', 'pt_title' ], 'pt_reason' );
+               return true;
+       }
+
+       /**
+        * Fetch comment IDs for a set of comments
+        * @param IDatabase $dbw
+        * @param array &$comments Keys are comment names, values will be set to IDs.
+        * @return int Count of added comments
+        */
+       private function loadCommentIDs( IDatabase $dbw, array &$comments ) {
+               $count = 0;
+               $needComments = $comments;
+
+               while ( true ) {
+                       $where = [];
+                       foreach ( $needComments as $need => $dummy ) {
+                               $where[] = $dbw->makeList(
+                                       [
+                                               'comment_hash' => CommentStore::hash( $need, null ),
+                                               'comment_text' => $need,
+                                       ],
+                                       LIST_AND
+                               );
+                       }
+
+                       $res = $dbw->select(
+                               'comment',
+                               [ 'comment_id', 'comment_text' ],
+                               [
+                                       $dbw->makeList( $where, LIST_OR ),
+                                       'comment_data' => null,
+                               ],
+                               __METHOD__
+                       );
+                       foreach ( $res as $row ) {
+                               $comments[$row->comment_text] = $row->comment_id;
+                               unset( $needComments[$row->comment_text] );
+                       }
+
+                       if ( !$needComments ) {
+                               break;
+                       }
+
+                       $dbw->insert(
+                               'comment',
+                               array_map( function ( $v ) {
+                                       return [
+                                               'comment_hash' => CommentStore::hash( $v, null ),
+                                               'comment_text' => $v,
+                                       ];
+                               }, array_keys( $needComments ) ),
+                               __METHOD__
+                       );
+                       $count += $dbw->affectedRows();
+               }
+               return $count;
+       }
+
+       /**
+        * Migrate comments in a table.
+        *
+        * Assumes any row with the ID field non-zero have already been migrated.
+        * Assumes the new field name is the same as the old with '_id' appended.
+        * Blanks the old fields while migrating.
+        *
+        * @param string $table Table to migrate
+        * @param string|string[] $primaryKey Primary key of the table.
+        * @param string $oldField Old comment field name
+        */
+       protected function migrate( $table, $primaryKey, $oldField ) {
+               $newField = $oldField . '_id';
+               $primaryKey = (array)$primaryKey;
+               $pkFilter = array_flip( $primaryKey );
+               $this->output( "Beginning migration of $table.$oldField to $table.$newField\n" );
+
+               $dbw = $this->getDB( DB_MASTER );
+               $next = '1=1';
+               $countUpdated = 0;
+               $countComments = 0;
+               while ( true ) {
+                       // Fetch the rows needing update
+                       $res = $dbw->select(
+                               $table,
+                               array_merge( $primaryKey, [ $oldField ] ),
+                               [
+                                       $newField => 0,
+                                       $next,
+                               ],
+                               __METHOD__,
+                               [
+                                       'ORDER BY' => $primaryKey,
+                                       'LIMIT' => $this->mBatchSize,
+                               ]
+                       );
+                       if ( !$res->numRows() ) {
+                               break;
+                       }
+
+                       // Collect the distinct comments from those rows
+                       $comments = [];
+                       foreach ( $res as $row ) {
+                               $comments[$row->$oldField] = 0;
+                       }
+                       $countComments += $this->loadCommentIDs( $dbw, $comments );
+
+                       // Update the existing rows
+                       foreach ( $res as $row ) {
+                               $dbw->update(
+                                       $table,
+                                       [
+                                               $newField => $comments[$row->$oldField],
+                                               $oldField => '',
+                                       ],
+                                       array_intersect_key( (array)$row, $pkFilter ) + [
+                                               $newField => 0
+                                       ],
+                                       __METHOD__
+                               );
+                               $countUpdated += $dbw->affectedRows();
+                       }
+
+                       // Calculate the "next" condition
+                       $next = '';
+                       $prompt = [];
+                       for ( $i = count( $primaryKey ) - 1; $i >= 0; $i-- ) {
+                               $field = $primaryKey[$i];
+                               $prompt[] = $row->$field;
+                               $value = $dbw->addQuotes( $row->$field );
+                               if ( $next === '' ) {
+                                       $next = "$field > $value";
+                               } else {
+                                       $next = "$field > $value OR $field = $value AND ($next)";
+                               }
+                       }
+                       $prompt = join( ' ', array_reverse( $prompt ) );
+                       $this->output( "... $prompt\n" );
+               }
+
+               $this->output(
+                       "Completed migration, updated $countUpdated row(s) with $countComments new comment(s)\n"
+               );
+       }
+
+       /**
+        * Migrate comments in a table to a temporary table.
+        *
+        * Assumes any row with the ID field non-zero have already been migrated.
+        * Assumes the new table is named "{$table}_comment_temp", and it has two
+        * columns, in order, being the primary key of the original table and the
+        * comment ID field.
+        * Blanks the old fields while migrating.
+        *
+        * @param string $oldTable Table to migrate
+        * @param string $primaryKey Primary key of the table.
+        * @param string $oldField Old comment field name
+        * @param string $newPrimaryKey Primary key of the new table.
+        * @param string $newField New comment field name
+        */
+       protected function migrateToTemp( $table, $primaryKey, $oldField, $newPrimaryKey, $newField ) {
+               $newTable = $table . '_comment_temp';
+               $this->output( "Beginning migration of $table.$oldField to $newTable.$newField\n" );
+
+               $dbw = $this->getDB( DB_MASTER );
+               $next = [];
+               $countUpdated = 0;
+               $countComments = 0;
+               while ( true ) {
+                       // Fetch the rows needing update
+                       $res = $dbw->select(
+                               [ $table, $newTable ],
+                               [ $primaryKey, $oldField ],
+                               [ $newPrimaryKey => null ] + $next,
+                               __METHOD__,
+                               [
+                                       'ORDER BY' => $primaryKey,
+                                       'LIMIT' => $this->mBatchSize,
+                               ],
+                               [ $newTable => [ 'LEFT JOIN', "{$primaryKey}={$newPrimaryKey}" ] ]
+                       );
+                       if ( !$res->numRows() ) {
+                               break;
+                       }
+
+                       // Collect the distinct comments from those rows
+                       $comments = [];
+                       foreach ( $res as $row ) {
+                               $comments[$row->$oldField] = 0;
+                       }
+                       $countComments += $this->loadCommentIDs( $dbw, $comments );
+
+                       // Update rows
+                       $inserts = [];
+                       $updates = [];
+                       foreach ( $res as $row ) {
+                               $inserts[] = [
+                                       $newPrimaryKey => $row->$primaryKey,
+                                       $newField => $comments[$row->$oldField]
+                               ];
+                               $updates[] = $row->$primaryKey;
+                       }
+                       $this->beginTransaction( $dbw, __METHOD__ );
+                       $dbw->insert( $newTable, $inserts, __METHOD__ );
+                       $dbw->update( $table, [ $oldField => '' ], [ $primaryKey => $updates ], __METHOD__ );
+                       $countUpdated += $dbw->affectedRows();
+                       $this->commitTransaction( $dbw, __METHOD__ );
+
+                       // Calculate the "next" condition
+                       $next = [ $primaryKey . ' > ' . $dbw->addQuotes( $row->$primaryKey ) ];
+                       $this->output( "... {$row->$primaryKey}\n" );
+               }
+
+               $this->output(
+                       "Completed migration, updated $countUpdated row(s) with $countComments new comment(s)\n"
+               );
+       }
+}
+
+$maintClass = "MigrateComments";
+require_once RUN_MAINTENANCE_IF_MAIN;
diff --git a/maintenance/oracle/archives/patch-auto_increment_triggers.sql b/maintenance/oracle/archives/patch-auto_increment_triggers.sql
new file mode 100644 (file)
index 0000000..6b471b0
--- /dev/null
@@ -0,0 +1,144 @@
+define mw_prefix='{$wgDBprefix}';
+
+-- Package to help with making Oracle more like other DBs with respect to
+-- auto-incrementing columns.
+/*$mw$*/
+CREATE PACKAGE &mw_prefix.lastval_pkg IS
+  lastval NUMBER;
+  PROCEDURE setLastval(val IN NUMBER, field OUT NUMBER);
+  FUNCTION getLastval RETURN NUMBER;
+END;
+/*$mw$*/
+
+/*$mw$*/
+CREATE PACKAGE BODY &mw_prefix.lastval_pkg IS
+  PROCEDURE setLastval(val IN NUMBER, field OUT NUMBER) IS BEGIN
+    lastval := val;
+    field := val;
+  END;
+
+  FUNCTION getLastval RETURN NUMBER IS BEGIN
+    RETURN lastval;
+  END;
+END;
+/*$mw$*/
+
+/*$mw$*/
+CREATE TRIGGER &mw_prefix.mwuser_default_user_id BEFORE INSERT ON &mw_prefix.mwuser
+       FOR EACH ROW WHEN (new.user_id IS NULL)
+BEGIN
+       &mw_prefix.lastval_pkg.setLastval(user_user_id_seq.nextval, :new.user_id);
+END;
+/*$mw$*/
+
+/*$mw$*/
+CREATE TRIGGER &mw_prefix.page_default_page_id BEFORE INSERT ON &mw_prefix.page
+       FOR EACH ROW WHEN (new.page_id IS NULL)
+BEGIN
+       &mw_prefix.lastval_pkg.setLastval(page_page_id_seq.nextval, :new.page_id);
+END;
+/*$mw$*/
+
+/*$mw$*/
+CREATE TRIGGER &mw_prefix.revision_default_rev_id BEFORE INSERT ON &mw_prefix.revision
+       FOR EACH ROW WHEN (new.rev_id IS NULL)
+BEGIN
+       &mw_prefix.lastval_pkg.setLastval(revision_rev_id_seq.nextval, :new.rev_id);
+END;
+/*$mw$*/
+
+/*$mw$*/
+CREATE TRIGGER &mw_prefix.text_default_old_id BEFORE INSERT ON &mw_prefix.text
+       FOR EACH ROW WHEN (new.old_id IS NULL)
+BEGIN
+       &mw_prefix.lastval_pkg.setLastval(text_old_id_seq.nextval, :new.old_id);
+END;
+/*$mw$*/
+
+/*$mw$*/
+CREATE TRIGGER &mw_prefix.archive_default_ar_id BEFORE INSERT ON &mw_prefix.archive
+       FOR EACH ROW WHEN (new.ar_id IS NULL)
+BEGIN
+       &mw_prefix.lastval_pkg.setLastval(archive_ar_id_seq.nextval, :new.ar_id);
+END;
+/*$mw$*/
+
+/*$mw$*/
+CREATE TRIGGER &mw_prefix.category_default_cat_id BEFORE INSERT ON &mw_prefix.category
+       FOR EACH ROW WHEN (new.cat_id IS NULL)
+BEGIN
+       &mw_prefix.lastval_pkg.setLastval(category_cat_id_seq.nextval, :new.cat_id);
+END;
+/*$mw$*/
+
+/*$mw$*/
+CREATE TRIGGER &mw_prefix.externallinks_default_el_id BEFORE INSERT ON &mw_prefix.externallinks
+       FOR EACH ROW WHEN (new.el_id IS NULL)
+BEGIN
+       &mw_prefix.lastval_pkg.setLastval(externallinks_el_id_seq.nextval, :new.el_id);
+END;
+/*$mw$*/
+
+/*$mw$*/
+CREATE TRIGGER &mw_prefix.ipblocks_default_ipb_id BEFORE INSERT ON &mw_prefix.ipblocks
+       FOR EACH ROW WHEN (new.ipb_id IS NULL)
+BEGIN
+       &mw_prefix.lastval_pkg.setLastval(ipblocks_ipb_id_seq.nextval, :new.ipb_id);
+END;
+/*$mw$*/
+
+/*$mw$*/
+CREATE TRIGGER &mw_prefix.filearchive_default_fa_id BEFORE INSERT ON &mw_prefix.filearchive
+       FOR EACH ROW WHEN (new.fa_id IS NULL)
+BEGIN
+       &mw_prefix.lastval_pkg.setLastval(filearchive_fa_id_seq.nextval, :new.fa_id);
+END;
+/*$mw$*/
+
+/*$mw$*/
+CREATE TRIGGER &mw_prefix.uploadstash_default_us_id BEFORE INSERT ON &mw_prefix.uploadstash
+       FOR EACH ROW WHEN (new.us_id IS NULL)
+BEGIN
+       &mw_prefix.lastval_pkg.setLastval(uploadstash_us_id_seq.nextval, :new.us_id);
+END;
+/*$mw$*/
+
+/*$mw$*/
+CREATE TRIGGER &mw_prefix.recentchanges_default_rc_id BEFORE INSERT ON &mw_prefix.recentchanges
+       FOR EACH ROW WHEN (new.rc_id IS NULL)
+BEGIN
+       &mw_prefix.lastval_pkg.setLastval(recentchanges_rc_id_seq.nextval, :new.rc_id);
+END;
+/*$mw$*/
+
+/*$mw$*/
+CREATE TRIGGER &mw_prefix.logging_default_log_id BEFORE INSERT ON &mw_prefix.logging
+       FOR EACH ROW WHEN (new.log_id IS NULL)
+BEGIN
+       &mw_prefix.lastval_pkg.setLastval(logging_log_id_seq.nextval, :new.log_id);
+END;
+/*$mw$*/
+
+/*$mw$*/
+CREATE TRIGGER &mw_prefix.job_default_job_id BEFORE INSERT ON &mw_prefix.job
+       FOR EACH ROW WHEN (new.job_id IS NULL)
+BEGIN
+       &mw_prefix.lastval_pkg.setLastval(job_job_id_seq.nextval, :new.job_id);
+END;
+/*$mw$*/
+
+/*$mw$*/
+CREATE TRIGGER &mw_prefix.page_restrictions_default_pr_id BEFORE INSERT ON &mw_prefix.page_restrictions
+       FOR EACH ROW WHEN (new.pr_id IS NULL)
+BEGIN
+       &mw_prefix.lastval_pkg.setLastval(page_restrictions_pr_id_seq.nextval, :new.pr_id);
+END;
+/*$mw$*/
+
+/*$mw$*/
+CREATE TRIGGER &mw_prefix.sites_default_site_id BEFORE INSERT ON &mw_prefix.sites
+       FOR EACH ROW WHEN (new.site_id IS NULL)
+BEGIN
+       &mw_prefix.lastval_pkg.setLastval(sites_site_id_seq.nextval, :new.site_id);
+END;
+/*$mw$*/
index fc3c696..44c907c 100644 (file)
@@ -1,6 +1,28 @@
 -- defines must comply with ^define\s*([^\s=]*)\s*=\s?'\{\$([^\}]*)\}';
 define mw_prefix='{$wgDBprefix}';
 
+-- Package to help with making Oracle more like other DBs with respect to
+-- auto-incrementing columns.
+/*$mw$*/
+CREATE PACKAGE &mw_prefix.lastval_pkg IS
+  lastval NUMBER;
+  PROCEDURE setLastval(val IN NUMBER, field OUT NUMBER);
+  FUNCTION getLastval RETURN NUMBER;
+END;
+/*$mw$*/
+
+/*$mw$*/
+CREATE PACKAGE BODY &mw_prefix.lastval_pkg IS
+  PROCEDURE setLastval(val IN NUMBER, field OUT NUMBER) IS BEGIN
+    lastval := val;
+    field := val;
+  END;
+
+  FUNCTION getLastval RETURN NUMBER IS BEGIN
+    RETURN lastval;
+  END;
+END;
+/*$mw$*/
 
 CREATE SEQUENCE user_user_id_seq;
 CREATE TABLE &mw_prefix.mwuser ( -- replace reserved word 'user'
@@ -25,6 +47,13 @@ ALTER TABLE &mw_prefix.mwuser ADD CONSTRAINT &mw_prefix.mwuser_pk PRIMARY KEY (u
 CREATE UNIQUE INDEX &mw_prefix.mwuser_u01 ON &mw_prefix.mwuser (user_name);
 CREATE INDEX &mw_prefix.mwuser_i01 ON &mw_prefix.mwuser (user_email_token);
 CREATE INDEX &mw_prefix.mwuser_i02 ON &mw_prefix.mwuser (user_email, user_name);
+/*$mw$*/
+CREATE TRIGGER &mw_prefix.mwuser_default_user_id BEFORE INSERT ON &mw_prefix.mwuser
+       FOR EACH ROW WHEN (new.user_id IS NULL)
+BEGIN
+       &mw_prefix.lastval_pkg.setLastval(user_user_id_seq.nextval, :new.user_id);
+END;
+/*$mw$*/
 
 -- Create a dummy user to satisfy fk contraints especially with revisions
 INSERT INTO &mw_prefix.mwuser
@@ -86,6 +115,13 @@ CREATE UNIQUE INDEX &mw_prefix.page_u01 ON &mw_prefix.page (page_namespace,page_
 CREATE INDEX &mw_prefix.page_i01 ON &mw_prefix.page (page_random);
 CREATE INDEX &mw_prefix.page_i02 ON &mw_prefix.page (page_len);
 CREATE INDEX &mw_prefix.page_i03 ON &mw_prefix.page (page_is_redirect, page_namespace, page_len);
+/*$mw$*/
+CREATE TRIGGER &mw_prefix.page_default_page_id BEFORE INSERT ON &mw_prefix.page
+       FOR EACH ROW WHEN (new.page_id IS NULL)
+BEGIN
+       &mw_prefix.lastval_pkg.setLastval(page_page_id_seq.nextval, :new.page_id);
+END;
+/*$mw$*/
 
 -- Create a dummy page to satisfy fk contraints especially with revisions
 INSERT INTO &mw_prefix.page
@@ -125,6 +161,13 @@ CREATE INDEX &mw_prefix.revision_i02 ON &mw_prefix.revision (rev_page,rev_timest
 CREATE INDEX &mw_prefix.revision_i03 ON &mw_prefix.revision (rev_user,rev_timestamp);
 CREATE INDEX &mw_prefix.revision_i04 ON &mw_prefix.revision (rev_user_text,rev_timestamp);
 CREATE INDEX &mw_prefix.revision_i05 ON &mw_prefix.revision (rev_page,rev_user,rev_timestamp);
+/*$mw$*/
+CREATE TRIGGER &mw_prefix.revision_default_rev_id BEFORE INSERT ON &mw_prefix.revision
+       FOR EACH ROW WHEN (new.rev_id IS NULL)
+BEGIN
+       &mw_prefix.lastval_pkg.setLastval(revision_rev_id_seq.nextval, :new.rev_id);
+END;
+/*$mw$*/
 
 CREATE SEQUENCE text_old_id_seq;
 CREATE TABLE &mw_prefix.pagecontent ( -- replaces reserved word 'text'
@@ -133,6 +176,13 @@ CREATE TABLE &mw_prefix.pagecontent ( -- replaces reserved word 'text'
   old_flags  VARCHAR2(255)
 );
 ALTER TABLE &mw_prefix.pagecontent ADD CONSTRAINT &mw_prefix.pagecontent_pk PRIMARY KEY (old_id);
+/*$mw$*/
+CREATE TRIGGER &mw_prefix.text_default_old_id BEFORE INSERT ON &mw_prefix.text
+       FOR EACH ROW WHEN (new.old_id IS NULL)
+BEGIN
+       &mw_prefix.lastval_pkg.setLastval(text_old_id_seq.nextval, :new.old_id);
+END;
+/*$mw$*/
 
 CREATE SEQUENCE archive_ar_id_seq;
 CREATE TABLE &mw_prefix.archive (
@@ -161,6 +211,13 @@ ALTER TABLE &mw_prefix.archive ADD CONSTRAINT &mw_prefix.archive_fk1 FOREIGN KEY
 CREATE INDEX &mw_prefix.archive_i01 ON &mw_prefix.archive (ar_namespace,ar_title,ar_timestamp);
 CREATE INDEX &mw_prefix.archive_i02 ON &mw_prefix.archive (ar_user_text,ar_timestamp);
 CREATE INDEX &mw_prefix.archive_i03 ON &mw_prefix.archive (ar_rev_id);
+/*$mw$*/
+CREATE TRIGGER &mw_prefix.archive_default_ar_id BEFORE INSERT ON &mw_prefix.archive
+       FOR EACH ROW WHEN (new.ar_id IS NULL)
+BEGIN
+       &mw_prefix.lastval_pkg.setLastval(archive_ar_id_seq.nextval, :new.ar_id);
+END;
+/*$mw$*/
 
 CREATE TABLE &mw_prefix.pagelinks (
   pl_from       NUMBER   NOT NULL,
@@ -215,6 +272,13 @@ CREATE TABLE &mw_prefix.category (
 ALTER TABLE &mw_prefix.category ADD CONSTRAINT &mw_prefix.category_pk PRIMARY KEY (cat_id);
 CREATE UNIQUE INDEX &mw_prefix.category_u01 ON &mw_prefix.category (cat_title);
 CREATE INDEX &mw_prefix.category_i01 ON &mw_prefix.category (cat_pages);
+/*$mw$*/
+CREATE TRIGGER &mw_prefix.category_default_cat_id BEFORE INSERT ON &mw_prefix.category
+       FOR EACH ROW WHEN (new.cat_id IS NULL)
+BEGIN
+       &mw_prefix.lastval_pkg.setLastval(category_cat_id_seq.nextval, :new.cat_id);
+END;
+/*$mw$*/
 
 CREATE SEQUENCE externallinks_el_id_seq;
 CREATE TABLE &mw_prefix.externallinks (
@@ -231,6 +295,13 @@ CREATE INDEX &mw_prefix.externallinks_i02 ON &mw_prefix.externallinks (el_to, el
 CREATE INDEX &mw_prefix.externallinks_i03 ON &mw_prefix.externallinks (el_index);
 CREATE INDEX &mw_prefix.externallinks_i04 ON &mw_prefix.externallinks (el_index_60, el_id);
 CREATE INDEX &mw_prefix.externallinks_i05 ON &mw_prefix.externallinks (el_from, el_index_60, el_id);
+/*$mw$*/
+CREATE TRIGGER &mw_prefix.externallinks_default_el_id BEFORE INSERT ON &mw_prefix.externallinks
+       FOR EACH ROW WHEN (new.el_id IS NULL)
+BEGIN
+       &mw_prefix.lastval_pkg.setLastval(externallinks_el_id_seq.nextval, :new.el_id);
+END;
+/*$mw$*/
 
 CREATE TABLE &mw_prefix.langlinks (
   ll_from    NUMBER  NOT NULL,
@@ -290,6 +361,13 @@ CREATE INDEX &mw_prefix.ipblocks_i02 ON &mw_prefix.ipblocks (ipb_range_start, ip
 CREATE INDEX &mw_prefix.ipblocks_i03 ON &mw_prefix.ipblocks (ipb_timestamp);
 CREATE INDEX &mw_prefix.ipblocks_i04 ON &mw_prefix.ipblocks (ipb_expiry);
 CREATE INDEX &mw_prefix.ipblocks_i05 ON &mw_prefix.ipblocks (ipb_parent_block_id);
+/*$mw$*/
+CREATE TRIGGER &mw_prefix.ipblocks_default_ipb_id BEFORE INSERT ON &mw_prefix.ipblocks
+       FOR EACH ROW WHEN (new.ipb_id IS NULL)
+BEGIN
+       &mw_prefix.lastval_pkg.setLastval(ipblocks_ipb_id_seq.nextval, :new.ipb_id);
+END;
+/*$mw$*/
 
 CREATE TABLE &mw_prefix.image (
   img_name         VARCHAR2(255)      NOT NULL,
@@ -374,6 +452,13 @@ CREATE INDEX &mw_prefix.filearchive_i02 ON &mw_prefix.filearchive (fa_storage_gr
 CREATE INDEX &mw_prefix.filearchive_i03 ON &mw_prefix.filearchive (fa_deleted_timestamp);
 CREATE INDEX &mw_prefix.filearchive_i04 ON &mw_prefix.filearchive (fa_user_text,fa_timestamp);
 CREATE INDEX &mw_prefix.filearchive_i05 ON &mw_prefix.filearchive (fa_sha1);
+/*$mw$*/
+CREATE TRIGGER &mw_prefix.filearchive_default_fa_id BEFORE INSERT ON &mw_prefix.filearchive
+       FOR EACH ROW WHEN (new.fa_id IS NULL)
+BEGIN
+       &mw_prefix.lastval_pkg.setLastval(filearchive_fa_id_seq.nextval, :new.fa_id);
+END;
+/*$mw$*/
 
 CREATE SEQUENCE uploadstash_us_id_seq;
 CREATE TABLE &mw_prefix.uploadstash (
@@ -400,6 +485,13 @@ ALTER TABLE &mw_prefix.uploadstash ADD CONSTRAINT &mw_prefix.uploadstash_fk1 FOR
 CREATE INDEX &mw_prefix.uploadstash_i01 ON &mw_prefix.uploadstash (us_user);
 CREATE INDEX &mw_prefix.uploadstash_i02 ON &mw_prefix.uploadstash (us_timestamp);
 CREATE UNIQUE INDEX &mw_prefix.uploadstash_u01 ON &mw_prefix.uploadstash (us_key);
+/*$mw$*/
+CREATE TRIGGER &mw_prefix.uploadstash_default_us_id BEFORE INSERT ON &mw_prefix.uploadstash
+       FOR EACH ROW WHEN (new.us_id IS NULL)
+BEGIN
+       &mw_prefix.lastval_pkg.setLastval(uploadstash_us_id_seq.nextval, :new.us_id);
+END;
+/*$mw$*/
 
 CREATE SEQUENCE recentchanges_rc_id_seq;
 CREATE TABLE &mw_prefix.recentchanges (
@@ -440,6 +532,13 @@ CREATE INDEX &mw_prefix.recentchanges_i05 ON &mw_prefix.recentchanges (rc_ip);
 CREATE INDEX &mw_prefix.recentchanges_i06 ON &mw_prefix.recentchanges (rc_namespace, rc_user_text);
 CREATE INDEX &mw_prefix.recentchanges_i07 ON &mw_prefix.recentchanges (rc_user_text, rc_timestamp);
 CREATE INDEX &mw_prefix.recentchanges_i08 ON &mw_prefix.recentchanges (rc_namespace, rc_type, rc_patrolled, rc_timestamp);
+/*$mw$*/
+CREATE TRIGGER &mw_prefix.recentchanges_default_rc_id BEFORE INSERT ON &mw_prefix.recentchanges
+       FOR EACH ROW WHEN (new.rc_id IS NULL)
+BEGIN
+       &mw_prefix.lastval_pkg.setLastval(recentchanges_rc_id_seq.nextval, :new.rc_id);
+END;
+/*$mw$*/
 
 CREATE TABLE &mw_prefix.watchlist (
   wl_id                     NUMBER     NOT NULL,
@@ -518,6 +617,13 @@ CREATE INDEX &mw_prefix.logging_i04 ON &mw_prefix.logging (log_timestamp);
 CREATE INDEX &mw_prefix.logging_i05 ON &mw_prefix.logging (log_type, log_action, log_timestamp);
 CREATE INDEX &mw_prefix.logging_i06 ON &mw_prefix.logging (log_user_text, log_type, log_timestamp);
 CREATE INDEX &mw_prefix.logging_i07 ON &mw_prefix.logging (log_user_text, log_timestamp);
+/*$mw$*/
+CREATE TRIGGER &mw_prefix.logging_default_log_id BEFORE INSERT ON &mw_prefix.logging
+       FOR EACH ROW WHEN (new.log_id IS NULL)
+BEGIN
+       &mw_prefix.lastval_pkg.setLastval(logging_log_id_seq.nextval, :new.log_id);
+END;
+/*$mw$*/
 
 CREATE TABLE &mw_prefix.log_search (
   ls_field VARCHAR2(32) NOT NULL,
@@ -548,6 +654,13 @@ CREATE INDEX &mw_prefix.job_i02 ON &mw_prefix.job (job_timestamp);
 CREATE INDEX &mw_prefix.job_i03 ON &mw_prefix.job (job_sha1);
 CREATE INDEX &mw_prefix.job_i04 ON &mw_prefix.job (job_cmd,job_token,job_random);
 CREATE INDEX &mw_prefix.job_i05 ON &mw_prefix.job (job_attempts);
+/*$mw$*/
+CREATE TRIGGER &mw_prefix.job_default_job_id BEFORE INSERT ON &mw_prefix.job
+       FOR EACH ROW WHEN (new.job_id IS NULL)
+BEGIN
+       &mw_prefix.lastval_pkg.setLastval(job_job_id_seq.nextval, :new.job_id);
+END;
+/*$mw$*/
 
 CREATE TABLE &mw_prefix.querycache_info (
   qci_type       VARCHAR2(32) NOT NULL,
@@ -593,6 +706,13 @@ CREATE UNIQUE INDEX &mw_prefix.page_restrictions_u01 ON &mw_prefix.page_restrict
 CREATE INDEX &mw_prefix.page_restrictions_i01 ON &mw_prefix.page_restrictions (pr_type,pr_level);
 CREATE INDEX &mw_prefix.page_restrictions_i02 ON &mw_prefix.page_restrictions (pr_level);
 CREATE INDEX &mw_prefix.page_restrictions_i03 ON &mw_prefix.page_restrictions (pr_cascade);
+/*$mw$*/
+CREATE TRIGGER &mw_prefix.page_restrictions_default_pr_id BEFORE INSERT ON &mw_prefix.page_restrictions
+       FOR EACH ROW WHEN (new.pr_id IS NULL)
+BEGIN
+       &mw_prefix.lastval_pkg.setLastval(page_restrictions_pr_id_seq.nextval, :new.pr_id);
+END;
+/*$mw$*/
 
 CREATE TABLE &mw_prefix.protected_titles (
   pt_namespace   NUMBER           DEFAULT 0 NOT NULL,
@@ -701,6 +821,13 @@ CREATE INDEX &mw_prefix.sites_i04 ON &mw_prefix.sites (site_language);
 CREATE INDEX &mw_prefix.sites_i05 ON &mw_prefix.sites (site_protocol);
 CREATE INDEX &mw_prefix.sites_i06 ON &mw_prefix.sites (site_domain);
 CREATE INDEX &mw_prefix.sites_i07 ON &mw_prefix.sites (site_forward);
+/*$mw$*/
+CREATE TRIGGER &mw_prefix.sites_default_site_id BEFORE INSERT ON &mw_prefix.sites
+       FOR EACH ROW WHEN (new.site_id IS NULL)
+BEGIN
+       &mw_prefix.lastval_pkg.setLastval(sites_site_id_seq.nextval, :new.site_id);
+END;
+/*$mw$*/
 
 CREATE TABLE &mw_prefix.site_identifiers (
   si_site NUMBER NOT NULL,
index e36c5b6..644fb95 100644 (file)
@@ -75,20 +75,24 @@ class Orphans extends Maintenance {
         */
        private function checkOrphans( $fix ) {
                $dbw = $this->getDB( DB_MASTER );
-               $page = $dbw->tableName( 'page' );
-               $revision = $dbw->tableName( 'revision' );
+               $commentStore = new CommentStore( 'rev_comment' );
 
                if ( $fix ) {
                        $this->lockTables( $dbw );
                }
 
+               $commentQuery = $commentStore->getJoin();
+
                $this->output( "Checking for orphan revision table entries... "
                        . "(this may take a while on a large wiki)\n" );
-               $result = $dbw->query( "
-                       SELECT *
-                       FROM $revision LEFT OUTER JOIN $page ON rev_page=page_id
-                       WHERE page_id IS NULL
-               " );
+               $result = $dbw->select(
+                       [ 'revision', 'page' ] + $commentQuery['tables'],
+                       [ 'rev_id', 'rev_page', 'rev_timestamp', 'rev_user_text' ] + $commentQuery['fields'],
+                       [ 'page_id' => null ],
+                       __METHOD__,
+                       [],
+                       [ 'page' => [ 'LEFT JOIN', [ 'rev_page=page_id' ] ] ] + $commentQuery['joins']
+               );
                $orphans = $result->numRows();
                if ( $orphans > 0 ) {
                        global $wgContLang;
@@ -100,9 +104,10 @@ class Orphans extends Maintenance {
                        ) );
 
                        foreach ( $result as $row ) {
-                               $comment = ( $row->rev_comment == '' )
-                                       ? ''
-                                       : '(' . $wgContLang->truncate( $row->rev_comment, 40 ) . ')';
+                               $comment = $commentStore->getComment( $row )->text;
+                               if ( $comment !== '' ) {
+                                       $comment = '(' . $wgContLang->truncate( $comment, 40 ) . ')';
+                               }
                                $this->output( sprintf( "%10d %10d %14s %20s %s\n",
                                        $row->rev_id,
                                        $row->rev_page,
diff --git a/maintenance/postgres/archives/patch-comment-table.sql b/maintenance/postgres/archives/patch-comment-table.sql
new file mode 100644 (file)
index 0000000..243a3b3
--- /dev/null
@@ -0,0 +1,27 @@
+--
+-- patch-comment-table.sql
+--
+-- T166732. Add a `comment` table, and temporary tables to reference it.
+
+CREATE SEQUENCE comment_comment_id_seq;
+CREATE TABLE comment (
+       comment_id   INTEGER NOT NULL PRIMARY KEY DEFAULT nextval('comment_comment_id_seq'),
+       comment_hash INTEGER NOT NULL,
+       comment_text TEXT    NOT NULL,
+       comment_data TEXT
+);
+CREATE INDEX comment_hash ON comment (comment_hash);
+
+CREATE TABLE revision_comment_temp (
+       revcomment_rev        INTEGER NOT NULL,
+       revcomment_comment_id INTEGER NOT NULL,
+       PRIMARY KEY (revcomment_rev, revcomment_comment_id)
+);
+CREATE UNIQUE INDEX revcomment_rev ON revision_comment_temp (revcomment_rev);
+
+CREATE TABLE image_comment_temp (
+       imgcomment_name       TEXT NOT NULL,
+       imgcomment_description_id INTEGER NOT NULL,
+       PRIMARY KEY (imgcomment_name, imgcomment_description_id)
+);
+CREATE UNIQUE INDEX imgcomment_name ON image_comment_temp (imgcomment_name);
index 03fd03a..eea9e68 100644 (file)
@@ -12,6 +12,7 @@ SET client_min_messages = 'ERROR';
 DROP SEQUENCE IF EXISTS user_user_id_seq CASCADE;
 DROP SEQUENCE IF EXISTS page_page_id_seq CASCADE;
 DROP SEQUENCE IF EXISTS revision_rev_id_seq CASCADE;
+DROP SEQUENCE IF EXISTS comment_comment_id_seq CASCADE;
 DROP SEQUENCE IF EXISTS text_old_id_seq CASCADE;
 DROP SEQUENCE IF EXISTS page_restrictions_pr_id_seq CASCADE;
 DROP SEQUENCE IF EXISTS ipblocks_ipb_id_seq CASCADE;
@@ -132,7 +133,7 @@ CREATE TABLE revision (
   rev_id             INTEGER      NOT NULL  UNIQUE DEFAULT nextval('revision_rev_id_seq'),
   rev_page           INTEGER          NULL  REFERENCES page (page_id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED,
   rev_text_id        INTEGER          NULL, -- FK
-  rev_comment        TEXT,
+  rev_comment        TEXT         NOT NULL DEFAULT '',
   rev_user           INTEGER      NOT NULL  REFERENCES mwuser(user_id) ON DELETE RESTRICT DEFERRABLE INITIALLY DEFERRED,
   rev_user_text      TEXT         NOT NULL,
   rev_timestamp      TIMESTAMPTZ  NOT NULL,
@@ -150,6 +151,12 @@ CREATE INDEX rev_timestamp_idx      ON revision (rev_timestamp);
 CREATE INDEX rev_user_idx           ON revision (rev_user);
 CREATE INDEX rev_user_text_idx      ON revision (rev_user_text);
 
+CREATE TABLE revision_comment_temp (
+       revcomment_rev        INTEGER NOT NULL,
+       revcomment_comment_id INTEGER NOT NULL,
+       PRIMARY KEY (revcomment_rev, revcomment_comment_id)
+);
+CREATE UNIQUE INDEX revcomment_rev ON revision_comment_temp (revcomment_rev);
 
 CREATE SEQUENCE text_old_id_seq;
 CREATE TABLE pagecontent ( -- replaces reserved word 'text'
@@ -159,6 +166,16 @@ CREATE TABLE pagecontent ( -- replaces reserved word 'text'
 );
 
 
+CREATE SEQUENCE comment_comment_id_seq;
+CREATE TABLE comment (
+  comment_id   INTEGER NOT NULL PRIMARY KEY DEFAULT nextval('comment_comment_id_seq'),
+  comment_hash INTEGER NOT NULL,
+  comment_text TEXT    NOT NULL,
+  comment_data TEXT
+);
+CREATE INDEX comment_hash ON comment (comment_hash);
+
+
 CREATE SEQUENCE page_restrictions_pr_id_seq;
 CREATE TABLE page_restrictions (
   pr_id      INTEGER      NOT NULL  UNIQUE DEFAULT nextval('page_restrictions_pr_id_seq'),
@@ -191,7 +208,8 @@ CREATE TABLE archive (
   ar_page_id        INTEGER          NULL,
   ar_parent_id      INTEGER          NULL,
   ar_sha1           TEXT         NOT NULL DEFAULT '',
-  ar_comment        TEXT,
+  ar_comment        TEXT         NOT NULL DEFAULT '',
+  ar_comment_id     INTEGER      NOT NULL DEFAULT 0,
   ar_user           INTEGER          NULL  REFERENCES mwuser(user_id) ON DELETE SET NULL DEFERRABLE INITIALLY DEFERRED,
   ar_user_text      TEXT         NOT NULL,
   ar_timestamp      TIMESTAMPTZ  NOT NULL,
@@ -296,7 +314,8 @@ CREATE TABLE ipblocks (
   ipb_user              INTEGER          NULL  REFERENCES mwuser(user_id) ON DELETE SET NULL DEFERRABLE INITIALLY DEFERRED,
   ipb_by                INTEGER      NOT NULL  REFERENCES mwuser(user_id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED,
   ipb_by_text           TEXT         NOT NULL  DEFAULT '',
-  ipb_reason            TEXT         NOT NULL,
+  ipb_reason            TEXT         NOT NULL  DEFAULT '',
+  ipb_reason_id         INTEGER      NOT NULL  DEFAULT 0,
   ipb_timestamp         TIMESTAMPTZ  NOT NULL,
   ipb_auto              SMALLINT     NOT NULL  DEFAULT 0,
   ipb_anon_only         SMALLINT     NOT NULL  DEFAULT 0,
@@ -327,7 +346,7 @@ CREATE TABLE image (
   img_media_type   TEXT,
   img_major_mime   TEXT                DEFAULT 'unknown',
   img_minor_mime   TEXT                DEFAULT 'unknown',
-  img_description  TEXT      NOT NULL,
+  img_description  TEXT      NOT NULL  DEFAULT '',
   img_user         INTEGER       NULL  REFERENCES mwuser(user_id) ON DELETE SET NULL DEFERRABLE INITIALLY DEFERRED,
   img_user_text    TEXT      NOT NULL,
   img_timestamp    TIMESTAMPTZ,
@@ -337,6 +356,13 @@ CREATE INDEX img_size_idx      ON image (img_size);
 CREATE INDEX img_timestamp_idx ON image (img_timestamp);
 CREATE INDEX img_sha1          ON image (img_sha1);
 
+CREATE TABLE image_comment_temp (
+       imgcomment_name       TEXT NOT NULL,
+       imgcomment_description_id INTEGER NOT NULL,
+       PRIMARY KEY (imgcomment_name, imgcomment_description_id)
+);
+CREATE UNIQUE INDEX imgcomment_name ON image_comment_temp (imgcomment_name);
+
 CREATE TABLE oldimage (
   oi_name          TEXT         NOT NULL,
   oi_archive_name  TEXT         NOT NULL,
@@ -344,7 +370,8 @@ CREATE TABLE oldimage (
   oi_width         INTEGER      NOT NULL,
   oi_height        INTEGER      NOT NULL,
   oi_bits          SMALLINT         NULL,
-  oi_description   TEXT,
+  oi_description   TEXT         NOT NULL DEFAULT '',
+  oi_description_id INTEGER     NOT NULL DEFAULT 0,
   oi_user          INTEGER          NULL  REFERENCES mwuser(user_id) ON DELETE SET NULL DEFERRABLE INITIALLY DEFERRED,
   oi_user_text     TEXT         NOT NULL,
   oi_timestamp     TIMESTAMPTZ      NULL,
@@ -370,7 +397,8 @@ CREATE TABLE filearchive (
   fa_storage_key        TEXT,
   fa_deleted_user       INTEGER          NULL  REFERENCES mwuser(user_id) ON DELETE SET NULL DEFERRABLE INITIALLY DEFERRED,
   fa_deleted_timestamp  TIMESTAMPTZ  NOT NULL,
-  fa_deleted_reason     TEXT,
+  fa_deleted_reason     TEXT         NOT NULL  DEFAULT '',
+  fa_deleted_reason_id  INTEGER      NOT NULL  DEFAULT 0,
   fa_size               INTEGER      NOT NULL,
   fa_width              INTEGER      NOT NULL,
   fa_height             INTEGER      NOT NULL,
@@ -379,7 +407,8 @@ CREATE TABLE filearchive (
   fa_media_type         TEXT,
   fa_major_mime         TEXT                   DEFAULT 'unknown',
   fa_minor_mime         TEXT                   DEFAULT 'unknown',
-  fa_description        TEXT         NOT NULL,
+  fa_description        TEXT         NOT NULL DEFAULT '',
+  fa_description_id     INTEGER      NOT NULL DEFAULT 0,
   fa_user               INTEGER          NULL  REFERENCES mwuser(user_id) ON DELETE SET NULL DEFERRABLE INITIALLY DEFERRED,
   fa_user_text          TEXT         NOT NULL,
   fa_timestamp          TIMESTAMPTZ,
@@ -429,7 +458,8 @@ CREATE TABLE recentchanges (
   rc_user_text       TEXT         NOT NULL,
   rc_namespace       SMALLINT     NOT NULL,
   rc_title           TEXT         NOT NULL,
-  rc_comment         TEXT,
+  rc_comment         TEXT         NOT NULL  DEFAULT '',
+  rc_comment_id      INTEGER      NOT NULL  DEFAULT 0,
   rc_minor           SMALLINT     NOT NULL  DEFAULT 0,
   rc_bot             SMALLINT     NOT NULL  DEFAULT 0,
   rc_new             SMALLINT     NOT NULL  DEFAULT 0,
@@ -528,7 +558,8 @@ CREATE TABLE logging (
   log_user        INTEGER                REFERENCES mwuser(user_id) ON DELETE SET NULL DEFERRABLE INITIALLY DEFERRED,
   log_namespace   SMALLINT     NOT NULL,
   log_title       TEXT         NOT NULL,
-  log_comment     TEXT,
+  log_comment     TEXT         NOT NULL DEFAULT '',
+  log_comment_id  INTEGER      NOT NULL DEFAULT 0,
   log_params      TEXT,
   log_deleted     SMALLINT     NOT NULL DEFAULT 0,
   log_user_text   TEXT         NOT NULL DEFAULT '',
@@ -635,7 +666,8 @@ CREATE TABLE protected_titles (
   pt_namespace   SMALLINT    NOT NULL,
   pt_title       TEXT        NOT NULL,
   pt_user        INTEGER         NULL  REFERENCES mwuser(user_id) ON DELETE SET NULL DEFERRABLE INITIALLY DEFERRED,
-  pt_reason      TEXT            NULL,
+  pt_reason      TEXT        NOT NULL DEFAULT '',
+  pt_reason_id   INTEGER     NOT NULL DEFAULT 0,
   pt_timestamp   TIMESTAMPTZ NOT NULL,
   pt_expiry      TIMESTAMPTZ     NULL,
   pt_create_perm TEXT        NOT NULL DEFAULT ''
index b93d112..a2cf3c5 100644 (file)
@@ -80,6 +80,8 @@ class RebuildRecentchanges extends Maintenance {
         */
        private function rebuildRecentChangesTablePass1() {
                $dbw = $this->getDB( DB_MASTER );
+               $revCommentStore = new CommentStore( 'rev_comment' );
+               $rcCommentStore = new CommentStore( 'rc_comment' );
 
                if ( $this->hasOption( 'from' ) && $this->hasOption( 'to' ) ) {
                        $this->cutoffFrom = wfTimestamp( TS_UNIX, $this->getOption( 'from' ) );
@@ -113,13 +115,14 @@ class RebuildRecentchanges extends Maintenance {
                }
 
                $this->output( "Loading from page and revision tables...\n" );
+
+               $commentQuery = $revCommentStore->getJoin();
                $res = $dbw->select(
-                       [ 'page', 'revision' ],
+                       [ 'revision', 'page' ] + $commentQuery['tables'],
                        [
                                'rev_timestamp',
                                'rev_user',
                                'rev_user_text',
-                               'rev_comment',
                                'rev_minor_edit',
                                'rev_id',
                                'rev_deleted',
@@ -127,19 +130,22 @@ class RebuildRecentchanges extends Maintenance {
                                'page_title',
                                'page_is_new',
                                'page_id'
-                       ],
+                       ] + $commentQuery['fields'],
                        [
                                'rev_timestamp > ' . $dbw->addQuotes( $dbw->timestamp( $this->cutoffFrom ) ),
-                               'rev_timestamp < ' . $dbw->addQuotes( $dbw->timestamp( $this->cutoffTo ) ),
-                               'rev_page=page_id'
+                               'rev_timestamp < ' . $dbw->addQuotes( $dbw->timestamp( $this->cutoffTo ) )
                        ],
                        __METHOD__,
-                       [ 'ORDER BY' => 'rev_timestamp DESC' ]
+                       [ 'ORDER BY' => 'rev_timestamp DESC' ],
+                       [
+                               'page' => [ 'JOIN', 'rev_page=page_id' ],
+                       ] + $commentQuery['joins']
                );
 
                $this->output( "Inserting from page and revision tables...\n" );
                $inserted = 0;
                foreach ( $res as $row ) {
+                       $comment = $revCommentStore->getComment( $row );
                        $dbw->insert(
                                'recentchanges',
                                [
@@ -148,7 +154,6 @@ class RebuildRecentchanges extends Maintenance {
                                        'rc_user_text' => $row->rev_user_text,
                                        'rc_namespace' => $row->page_namespace,
                                        'rc_title' => $row->page_title,
-                                       'rc_comment' => $row->rev_comment,
                                        'rc_minor' => $row->rev_minor_edit,
                                        'rc_bot' => 0,
                                        'rc_new' => $row->page_is_new,
@@ -156,10 +161,9 @@ class RebuildRecentchanges extends Maintenance {
                                        'rc_this_oldid' => $row->rev_id,
                                        'rc_last_oldid' => 0, // is this ok?
                                        'rc_type' => $row->page_is_new ? RC_NEW : RC_EDIT,
-                                       'rc_source' => $row->page_is_new ? RecentChange::SRC_NEW : RecentChange::SRC_EDIT
-                                       ,
+                                       'rc_source' => $row->page_is_new ? RecentChange::SRC_NEW : RecentChange::SRC_EDIT,
                                        'rc_deleted' => $row->rev_deleted
-                               ],
+                               ] + $rcCommentStore->insert( $dbw, $comment ),
                                __METHOD__
                        );
                        if ( ( ++$inserted % $this->mBatchSize ) == 0 ) {
@@ -266,25 +270,27 @@ class RebuildRecentchanges extends Maintenance {
                global $wgLogTypes, $wgLogRestrictions;
 
                $dbw = $this->getDB( DB_MASTER );
+               $logCommentStore = new CommentStore( 'log_comment' );
+               $rcCommentStore = new CommentStore( 'rc_comment' );
 
                $this->output( "Loading from user, page, and logging tables...\n" );
 
+               $commentQuery = $logCommentStore->getJoin();
                $res = $dbw->select(
-                       [ 'user', 'logging', 'page' ],
+                       [ 'user', 'logging', 'page' ] + $commentQuery['tables'],
                        [
                                'log_timestamp',
                                'log_user',
                                'user_name',
                                'log_namespace',
                                'log_title',
-                               'log_comment',
                                'page_id',
                                'log_type',
                                'log_action',
                                'log_id',
                                'log_params',
                                'log_deleted'
-                       ],
+                       ] + $commentQuery['fields'],
                        [
                                'log_timestamp > ' . $dbw->addQuotes( $dbw->timestamp( $this->cutoffFrom ) ),
                                'log_timestamp < ' . $dbw->addQuotes( $dbw->timestamp( $this->cutoffTo ) ),
@@ -298,13 +304,14 @@ class RebuildRecentchanges extends Maintenance {
                        [
                                'page' =>
                                        [ 'LEFT JOIN', [ 'log_namespace=page_namespace', 'log_title=page_title' ] ]
-                       ]
+                       ] + $commentQuery['joins']
                );
 
                $field = $dbw->fieldInfo( 'recentchanges', 'rc_cur_id' );
 
                $inserted = 0;
                foreach ( $res as $row ) {
+                       $comment = $logCommentStore->getComment( $row );
                        $dbw->insert(
                                'recentchanges',
                                [
@@ -313,7 +320,6 @@ class RebuildRecentchanges extends Maintenance {
                                        'rc_user_text' => $row->user_name,
                                        'rc_namespace' => $row->log_namespace,
                                        'rc_title' => $row->log_title,
-                                       'rc_comment' => $row->log_comment,
                                        'rc_minor' => 0,
                                        'rc_bot' => 0,
                                        'rc_patrolled' => 1,
@@ -330,7 +336,7 @@ class RebuildRecentchanges extends Maintenance {
                                        'rc_logid' => $row->log_id,
                                        'rc_params' => $row->log_params,
                                        'rc_deleted' => $row->log_deleted
-                               ],
+                               ] + $rcCommentStore->insert( $dbw, $comment ),
                                __METHOD__
                        );
 
diff --git a/maintenance/sqlite/archives/patch-categorylinks-fix-pk.sql b/maintenance/sqlite/archives/patch-categorylinks-fix-pk.sql
new file mode 100644 (file)
index 0000000..13a75a3
--- /dev/null
@@ -0,0 +1,60 @@
+CREATE TABLE /*_*/categorylinks_tmp (
+  -- Key to page_id of the page defined as a category member.
+  cl_from int unsigned NOT NULL default 0,
+
+  -- Name of the category.
+  -- This is also the page_title of the category's description page;
+  -- all such pages are in namespace 14 (NS_CATEGORY).
+  cl_to varchar(255) binary NOT NULL default '',
+
+  -- A binary string obtained by applying a sortkey generation algorithm
+  -- (Collation::getSortKey()) to page_title, or cl_sortkey_prefix . "\n"
+  -- . page_title if cl_sortkey_prefix is nonempty.
+  cl_sortkey varbinary(230) NOT NULL default '',
+
+  -- A prefix for the raw sortkey manually specified by the user, either via
+  -- [[Category:Foo|prefix]] or {{defaultsort:prefix}}.  If nonempty, it's
+  -- concatenated with a line break followed by the page title before the sortkey
+  -- conversion algorithm is run.  We store this so that we can update
+  -- collations without reparsing all pages.
+  -- Note: If you change the length of this field, you also need to change
+  -- code in LinksUpdate.php. See T27254.
+  cl_sortkey_prefix varchar(255) binary NOT NULL default '',
+
+  -- This isn't really used at present. Provided for an optional
+  -- sorting method by approximate addition time.
+  cl_timestamp timestamp NOT NULL,
+
+  -- Stores $wgCategoryCollation at the time cl_sortkey was generated.  This
+  -- can be used to install new collation versions, tracking which rows are not
+  -- yet updated.  '' means no collation, this is a legacy row that needs to be
+  -- updated by updateCollation.php.  In the future, it might be possible to
+  -- specify different collations per category.
+  cl_collation varbinary(32) NOT NULL default '',
+
+  -- Stores whether cl_from is a category, file, or other page, so we can
+  -- paginate the three categories separately.  This never has to be updated
+  -- after the page is created, since none of these page types can be moved to
+  -- any other.
+  cl_type ENUM('page', 'subcat', 'file') NOT NULL default 'page',
+  PRIMARY KEY (cl_from,cl_to)
+) /*$wgDBTableOptions*/;
+
+INSERT INTO /*_*/categorylinks_tmp
+       SELECT *
+               FROM /*_*/categorylinks;
+
+DROP TABLE /*_*/categorylinks;
+
+ALTER TABLE /*_*/categorylinks_tmp RENAME TO /*_*/categorylinks;
+
+-- We always sort within a given category, and within a given type.  FIXME:
+-- Formerly this index didn't cover cl_type (since that didn't exist), so old
+-- callers won't be using an index: fix this?
+CREATE INDEX /*i*/cl_sortkey ON /*_*/categorylinks (cl_to,cl_type,cl_sortkey,cl_from);
+
+-- Used by the API (and some extensions)
+CREATE INDEX /*i*/cl_timestamp ON /*_*/categorylinks (cl_to,cl_timestamp);
+
+-- Used when updating collation (e.g. updateCollation.php)
+CREATE INDEX /*i*/cl_collation_ext ON /*_*/categorylinks (cl_collation, cl_to, cl_type, cl_from);
\ No newline at end of file
diff --git a/maintenance/sqlite/archives/patch-comment-table.sql b/maintenance/sqlite/archives/patch-comment-table.sql
new file mode 100644 (file)
index 0000000..f743b55
--- /dev/null
@@ -0,0 +1,332 @@
+--
+-- patch-comment-table.sql
+--
+-- T166732. Add a `comment` table and various columns (and temporary tables) to reference it.
+-- Sigh, sqlite, such trouble just to change the default value of a column.
+
+CREATE TABLE /*_*/comment (
+  comment_id bigint unsigned NOT NULL PRIMARY KEY AUTO_INCREMENT,
+  comment_hash INT NOT NULL,
+  comment_text BLOB NOT NULL,
+  comment_data BLOB
+) /*$wgDBTableOptions*/;
+CREATE INDEX /*i*/comment_hash ON /*_*/comment (comment_hash);
+
+CREATE TABLE /*_*/revision_comment_temp (
+  revcomment_rev int unsigned NOT NULL,
+  revcomment_comment_id bigint unsigned NOT NULL,
+  PRIMARY KEY (revcomment_rev, revcomment_comment_id)
+) /*$wgDBTableOptions*/;
+CREATE UNIQUE INDEX /*i*/revcomment_rev ON /*_*/revision_comment_temp (revcomment_rev);
+
+CREATE TABLE /*_*/image_comment_temp (
+  imgcomment_name varchar(255) binary NOT NULL,
+  imgcomment_description_id bigint unsigned NOT NULL,
+  PRIMARY KEY (imgcomment_name, imgcomment_description_id)
+) /*$wgDBTableOptions*/;
+CREATE UNIQUE INDEX /*i*/imgcomment_name ON /*_*/image_comment_temp (imgcomment_name);
+
+ALTER TABLE /*_*/recentchanges
+  ADD COLUMN rc_comment_id bigint unsigned NOT NULL DEFAULT 0;
+
+ALTER TABLE /*_*/logging
+  ADD COLUMN log_comment_id bigint unsigned NOT NULL DEFAULT 0;
+
+BEGIN;
+
+DROP TABLE IF EXISTS /*_*/revision_tmp;
+CREATE TABLE /*_*/revision_tmp (
+  rev_id int unsigned NOT NULL PRIMARY KEY AUTO_INCREMENT,
+  rev_page int unsigned NOT NULL,
+  rev_text_id int unsigned NOT NULL,
+  rev_comment varbinary(767) NOT NULL default '',
+  rev_user int unsigned NOT NULL default 0,
+  rev_user_text varchar(255) binary NOT NULL default '',
+  rev_timestamp binary(14) NOT NULL default '',
+  rev_minor_edit tinyint unsigned NOT NULL default 0,
+  rev_deleted tinyint unsigned NOT NULL default 0,
+  rev_len int unsigned,
+  rev_parent_id int unsigned default NULL,
+  rev_sha1 varbinary(32) NOT NULL default '',
+  rev_content_model varbinary(32) DEFAULT NULL,
+  rev_content_format varbinary(64) DEFAULT NULL
+) /*$wgDBTableOptions*/ MAX_ROWS=10000000 AVG_ROW_LENGTH=1024;
+
+INSERT OR IGNORE INTO /*_*/revision_tmp (
+       rev_id, rev_page, rev_text_id, rev_comment, rev_user, rev_user_text,
+       rev_timestamp, rev_minor_edit, rev_deleted, rev_len, rev_parent_id,
+       rev_sha1, rev_content_model, rev_content_format)
+ SELECT
+       rev_id, rev_page, rev_text_id, rev_comment, rev_user, rev_user_text,
+       rev_timestamp, rev_minor_edit, rev_deleted, rev_len, rev_parent_id,
+       rev_sha1, rev_content_model, rev_content_format
+  FROM /*_*/revision;
+
+DROP TABLE /*_*/revision;
+ALTER TABLE /*_*/revision_tmp RENAME TO /*_*/revision;
+CREATE INDEX /*i*/rev_page_id ON /*_*/revision (rev_page, rev_id);
+CREATE INDEX /*i*/rev_timestamp ON /*_*/revision (rev_timestamp);
+CREATE INDEX /*i*/page_timestamp ON /*_*/revision (rev_page,rev_timestamp);
+CREATE INDEX /*i*/user_timestamp ON /*_*/revision (rev_user,rev_timestamp);
+CREATE INDEX /*i*/usertext_timestamp ON /*_*/revision (rev_user_text,rev_timestamp);
+CREATE INDEX /*i*/page_user_timestamp ON /*_*/revision (rev_page,rev_user,rev_timestamp);
+
+COMMIT;
+
+BEGIN;
+
+DROP TABLE IF EXISTS /*_*/archive_tmp;
+CREATE TABLE /*_*/archive_tmp (
+  ar_id int unsigned NOT NULL PRIMARY KEY AUTO_INCREMENT,
+  ar_namespace int NOT NULL default 0,
+  ar_title varchar(255) binary NOT NULL default '',
+  ar_text mediumblob NOT NULL,
+  ar_comment varbinary(767) NOT NULL default '',
+  ar_comment_id bigint unsigned NOT NULL DEFAULT 0,
+  ar_user int unsigned NOT NULL default 0,
+  ar_user_text varchar(255) binary NOT NULL,
+  ar_timestamp binary(14) NOT NULL default '',
+  ar_minor_edit tinyint NOT NULL default 0,
+  ar_flags tinyblob NOT NULL,
+  ar_rev_id int unsigned,
+  ar_text_id int unsigned,
+  ar_deleted tinyint unsigned NOT NULL default 0,
+  ar_len int unsigned,
+  ar_page_id int unsigned,
+  ar_parent_id int unsigned default NULL,
+  ar_sha1 varbinary(32) NOT NULL default '',
+  ar_content_model varbinary(32) DEFAULT NULL,
+  ar_content_format varbinary(64) DEFAULT NULL
+) /*$wgDBTableOptions*/;
+
+INSERT OR IGNORE INTO /*_*/archive_tmp (
+       ar_id, ar_namespace, ar_title, ar_text, ar_comment, ar_user, ar_user_text,
+       ar_timestamp, ar_minor_edit, ar_flags, ar_rev_id, ar_text_id, ar_deleted,
+       ar_len, ar_page_id, ar_parent_id, ar_sha1, ar_content_model,
+       ar_content_format)
+  SELECT
+       ar_id, ar_namespace, ar_title, ar_text, ar_comment, ar_user, ar_user_text,
+       ar_timestamp, ar_minor_edit, ar_flags, ar_rev_id, ar_text_id, ar_deleted,
+       ar_len, ar_page_id, ar_parent_id, ar_sha1, ar_content_model,
+       ar_content_format
+  FROM /*_*/archive;
+
+DROP TABLE /*_*/archive;
+ALTER TABLE /*_*/archive_tmp RENAME TO /*_*/archive;
+CREATE INDEX /*i*/name_title_timestamp ON /*_*/archive (ar_namespace,ar_title,ar_timestamp);
+CREATE INDEX /*i*/ar_usertext_timestamp ON /*_*/archive (ar_user_text,ar_timestamp);
+CREATE INDEX /*i*/ar_revid ON /*_*/archive (ar_rev_id);
+
+COMMIT;
+
+BEGIN;
+
+DROP TABLE IF EXISTS ipblocks_tmp;
+CREATE TABLE /*_*/ipblocks_tmp (
+  ipb_id int NOT NULL PRIMARY KEY AUTO_INCREMENT,
+  ipb_address tinyblob NOT NULL,
+  ipb_user int unsigned NOT NULL default 0,
+  ipb_by int unsigned NOT NULL default 0,
+  ipb_by_text varchar(255) binary NOT NULL default '',
+  ipb_reason varbinary(767) NOT NULL default '',
+  ipb_reason_id bigint unsigned NOT NULL DEFAULT 0,
+  ipb_timestamp binary(14) NOT NULL default '',
+  ipb_auto bool NOT NULL default 0,
+  ipb_anon_only bool NOT NULL default 0,
+  ipb_create_account bool NOT NULL default 1,
+  ipb_enable_autoblock bool NOT NULL default '1',
+  ipb_expiry varbinary(14) NOT NULL default '',
+  ipb_range_start tinyblob NOT NULL,
+  ipb_range_end tinyblob NOT NULL,
+  ipb_deleted bool NOT NULL default 0,
+  ipb_block_email bool NOT NULL default 0,
+  ipb_allow_usertalk bool NOT NULL default 0,
+  ipb_parent_block_id int default NULL
+) /*$wgDBTableOptions*/;
+
+INSERT OR IGNORE INTO /*_*/ipblocks_tmp (
+       ipb_id, ipb_address, ipb_user, ipb_by, ipb_by_text, ipb_reason,
+       ipb_timestamp, ipb_auto, ipb_anon_only, ipb_create_account,
+       ipb_enable_autoblock, ipb_expiry, ipb_range_start, ipb_range_end,
+       ipb_deleted, ipb_block_email, ipb_allow_usertalk, ipb_parent_block_id)
+  SELECT
+       ipb_id, ipb_address, ipb_user, ipb_by, ipb_by_text, ipb_reason,
+       ipb_timestamp, ipb_auto, ipb_anon_only, ipb_create_account,
+       ipb_enable_autoblock, ipb_expiry, ipb_range_start, ipb_range_end,
+       ipb_deleted, ipb_block_email, ipb_allow_usertalk, ipb_parent_block_id
+  FROM /*_*/ipblocks;
+
+DROP TABLE /*_*/ipblocks;
+ALTER TABLE /*_*/ipblocks_tmp RENAME TO /*_*/ipblocks;
+CREATE UNIQUE INDEX /*i*/ipb_address ON /*_*/ipblocks (ipb_address(255), ipb_user, ipb_auto, ipb_anon_only);
+CREATE INDEX /*i*/ipb_user ON /*_*/ipblocks (ipb_user);
+CREATE INDEX /*i*/ipb_range ON /*_*/ipblocks (ipb_range_start(8), ipb_range_end(8));
+CREATE INDEX /*i*/ipb_timestamp ON /*_*/ipblocks (ipb_timestamp);
+CREATE INDEX /*i*/ipb_expiry ON /*_*/ipblocks (ipb_expiry);
+CREATE INDEX /*i*/ipb_parent_block_id ON /*_*/ipblocks (ipb_parent_block_id);
+
+COMMIT;
+
+BEGIN;
+
+DROP TABLE IF EXISTS /*_*/image_tmp;
+CREATE TABLE /*_*/image_tmp (
+  img_name varchar(255) binary NOT NULL default '' PRIMARY KEY,
+  img_size int unsigned NOT NULL default 0,
+  img_width int NOT NULL default 0,
+  img_height int NOT NULL default 0,
+  img_metadata mediumblob NOT NULL,
+  img_bits int NOT NULL default 0,
+  img_media_type ENUM("UNKNOWN", "BITMAP", "DRAWING", "AUDIO", "VIDEO", "MULTIMEDIA", "OFFICE", "TEXT", "EXECUTABLE", "ARCHIVE") default NULL,
+  img_major_mime ENUM("unknown", "application", "audio", "image", "text", "video", "message", "model", "multipart", "chemical") NOT NULL default "unknown",
+  img_minor_mime varbinary(100) NOT NULL default "unknown",
+  img_description varbinary(767) NOT NULL default '',
+  img_user int unsigned NOT NULL default 0,
+  img_user_text varchar(255) binary NOT NULL,
+  img_timestamp varbinary(14) NOT NULL default '',
+  img_sha1 varbinary(32) NOT NULL default ''
+) /*$wgDBTableOptions*/;
+
+INSERT OR IGNORE INTO /*_*/image_tmp (
+       img_name, img_size, img_width, img_height, img_metadata, img_bits,
+       img_media_type, img_major_mime, img_minor_mime, img_description, img_user,
+       img_user_text, img_timestamp, img_sha1)
+  SELECT
+       img_name, img_size, img_width, img_height, img_metadata, img_bits,
+       img_media_type, img_major_mime, img_minor_mime, img_description, img_user,
+       img_user_text, img_timestamp, img_sha1
+  FROM /*_*/image;
+
+DROP TABLE /*_*/image;
+ALTER TABLE /*_*/image_tmp RENAME TO /*_*/image;
+CREATE INDEX /*i*/img_user_timestamp ON /*_*/image (img_user,img_timestamp);
+CREATE INDEX /*i*/img_usertext_timestamp ON /*_*/image (img_user_text,img_timestamp);
+CREATE INDEX /*i*/img_size ON /*_*/image (img_size);
+CREATE INDEX /*i*/img_timestamp ON /*_*/image (img_timestamp);
+CREATE INDEX /*i*/img_sha1 ON /*_*/image (img_sha1(10));
+CREATE INDEX /*i*/img_media_mime ON /*_*/image (img_media_type,img_major_mime,img_minor_mime);
+
+COMMIT;
+
+BEGIN;
+
+DROP TABLE IF EXISTS /*_*/oldimage_tmp;
+CREATE TABLE /*_*/oldimage_tmp (
+  oi_name varchar(255) binary NOT NULL default '',
+  oi_archive_name varchar(255) binary NOT NULL default '',
+  oi_size int unsigned NOT NULL default 0,
+  oi_width int NOT NULL default 0,
+  oi_height int NOT NULL default 0,
+  oi_bits int NOT NULL default 0,
+  oi_description varbinary(767) NOT NULL default '',
+  oi_description_id bigint unsigned NOT NULL DEFAULT 0,
+  oi_user int unsigned NOT NULL default 0,
+  oi_user_text varchar(255) binary NOT NULL,
+  oi_timestamp binary(14) NOT NULL default '',
+  oi_metadata mediumblob NOT NULL,
+  oi_media_type ENUM("UNKNOWN", "BITMAP", "DRAWING", "AUDIO", "VIDEO", "MULTIMEDIA", "OFFICE", "TEXT", "EXECUTABLE", "ARCHIVE") default NULL,
+  oi_major_mime ENUM("unknown", "application", "audio", "image", "text", "video", "message", "model", "multipart", "chemical") NOT NULL default "unknown",
+  oi_minor_mime varbinary(100) NOT NULL default "unknown",
+  oi_deleted tinyint unsigned NOT NULL default 0,
+  oi_sha1 varbinary(32) NOT NULL default ''
+) /*$wgDBTableOptions*/;
+
+INSERT OR IGNORE INTO /*_*/oldimage_tmp (
+       oi_name, oi_archive_name, oi_size, oi_width, oi_height, oi_bits,
+       oi_description, oi_user, oi_user_text, oi_timestamp, oi_metadata,
+       oi_media_type, oi_major_mime, oi_minor_mime, oi_deleted, oi_sha1)
+  SELECT
+       oi_name, oi_archive_name, oi_size, oi_width, oi_height, oi_bits,
+       oi_description, oi_user, oi_user_text, oi_timestamp, oi_metadata,
+       oi_media_type, oi_major_mime, oi_minor_mime, oi_deleted, oi_sha1
+  FROM /*_*/oldimage;
+
+DROP TABLE /*_*/oldimage;
+ALTER TABLE /*_*/oldimage_tmp RENAME TO /*_*/oldimage;
+CREATE INDEX /*i*/oi_usertext_timestamp ON /*_*/oldimage (oi_user_text,oi_timestamp);
+CREATE INDEX /*i*/oi_name_timestamp ON /*_*/oldimage (oi_name,oi_timestamp);
+CREATE INDEX /*i*/oi_name_archive_name ON /*_*/oldimage (oi_name,oi_archive_name(14));
+CREATE INDEX /*i*/oi_sha1 ON /*_*/oldimage (oi_sha1(10));
+
+COMMIT;
+
+BEGIN;
+
+DROP TABLE IF EXISTS /*_*/filearchive_tmp;
+CREATE TABLE /*_*/filearchive_tmp (
+  fa_id int NOT NULL PRIMARY KEY AUTO_INCREMENT,
+  fa_name varchar(255) binary NOT NULL default '',
+  fa_archive_name varchar(255) binary default '',
+  fa_storage_group varbinary(16),
+  fa_storage_key varbinary(64) default '',
+  fa_deleted_user int,
+  fa_deleted_timestamp binary(14) default '',
+  fa_deleted_reason varbinary(767) default '',
+  fa_deleted_reason_id bigint unsigned NOT NULL DEFAULT 0,
+  fa_size int unsigned default 0,
+  fa_width int default 0,
+  fa_height int default 0,
+  fa_metadata mediumblob,
+  fa_bits int default 0,
+  fa_media_type ENUM("UNKNOWN", "BITMAP", "DRAWING", "AUDIO", "VIDEO", "MULTIMEDIA", "OFFICE", "TEXT", "EXECUTABLE", "ARCHIVE") default NULL,
+  fa_major_mime ENUM("unknown", "application", "audio", "image", "text", "video", "message", "model", "multipart", "chemical") default "unknown",
+  fa_minor_mime varbinary(100) default "unknown",
+  fa_description varbinary(767) default '',
+  fa_description_id bigint unsigned NOT NULL DEFAULT 0,
+  fa_user int unsigned default 0,
+  fa_user_text varchar(255) binary,
+  fa_timestamp binary(14) default '',
+  fa_deleted tinyint unsigned NOT NULL default 0,
+  fa_sha1 varbinary(32) NOT NULL default ''
+) /*$wgDBTableOptions*/;
+
+INSERT OR IGNORE INTO /*_*/filearchive_tmp (
+       fa_id, fa_name, fa_archive_name, fa_storage_group, fa_storage_key,
+       fa_deleted_user, fa_deleted_timestamp, fa_deleted_reason, fa_size,
+       fa_width, fa_height, fa_metadata, fa_bits, fa_media_type, fa_major_mime,
+       fa_minor_mime, fa_description, fa_user, fa_user_text, fa_timestamp,
+       fa_deleted, fa_sha1)
+  SELECT
+       fa_id, fa_name, fa_archive_name, fa_storage_group, fa_storage_key,
+       fa_deleted_user, fa_deleted_timestamp, fa_deleted_reason, fa_size,
+       fa_width, fa_height, fa_metadata, fa_bits, fa_media_type, fa_major_mime,
+       fa_minor_mime, fa_description, fa_user, fa_user_text, fa_timestamp,
+       fa_deleted, fa_sha1
+  FROM /*_*/filearchive;
+
+DROP TABLE /*_*/filearchive;
+ALTER TABLE /*_*/filearchive_tmp RENAME TO /*_*/filearchive;
+CREATE INDEX /*i*/fa_name ON /*_*/filearchive (fa_name, fa_timestamp);
+CREATE INDEX /*i*/fa_storage_group ON /*_*/filearchive (fa_storage_group, fa_storage_key);
+CREATE INDEX /*i*/fa_deleted_timestamp ON /*_*/filearchive (fa_deleted_timestamp);
+CREATE INDEX /*i*/fa_user_timestamp ON /*_*/filearchive (fa_user_text,fa_timestamp);
+CREATE INDEX /*i*/fa_sha1 ON /*_*/filearchive (fa_sha1(10));
+
+COMMIT;
+
+BEGIN;
+
+DROP TABLE IF EXISTS /*_*/protected_titles_tmp;
+CREATE TABLE /*_*/protected_titles_tmp (
+  pt_namespace int NOT NULL,
+  pt_title varchar(255) binary NOT NULL,
+  pt_user int unsigned NOT NULL,
+  pt_reason varbinary(767) default '',
+  pt_reason_id bigint unsigned NOT NULL DEFAULT 0,
+  pt_timestamp binary(14) NOT NULL,
+  pt_expiry varbinary(14) NOT NULL default '',
+  pt_create_perm varbinary(60) NOT NULL
+) /*$wgDBTableOptions*/;
+
+INSERT OR IGNORE INTO /*_*/protected_titles_tmp (
+       pt_namespace, pt_title, pt_user, pt_reason, pt_timestamp, pt_expiry, pt_create_perm)
+  SELECT
+       pt_namespace, pt_title, pt_user, pt_reason, pt_timestamp, pt_expiry, pt_create_perm
+  FROM /*_*/protected_titles;
+
+DROP TABLE /*_*/protected_titles;
+ALTER TABLE /*_*/protected_titles_tmp RENAME TO /*_*/protected_titles;
+CREATE UNIQUE INDEX /*i*/pt_namespace_title ON /*_*/protected_titles (pt_namespace,pt_title);
+CREATE INDEX /*i*/pt_timestamp ON /*_*/protected_titles (pt_timestamp);
+
+COMMIT;
diff --git a/maintenance/sqlite/archives/patch-imagelinks-fix-pk.sql b/maintenance/sqlite/archives/patch-imagelinks-fix-pk.sql
new file mode 100644 (file)
index 0000000..b48bea5
--- /dev/null
@@ -0,0 +1,25 @@
+CREATE TABLE /*_*/imagelinks_tmp (
+  -- Key to page_id of the page containing the image / media link.
+  il_from int unsigned NOT NULL default 0,
+  -- Namespace for this page
+  il_from_namespace int NOT NULL default 0,
+
+  -- Filename of target image.
+  -- This is also the page_title of the file's description page;
+  -- all such pages are in namespace 6 (NS_FILE).
+  il_to varchar(255) binary NOT NULL default '',
+  PRIMARY KEY (il_from,il_to)
+) /*$wgDBTableOptions*/;
+
+INSERT INTO /*_*/imagelinks_tmp
+       SELECT * FROM /*_*/imagelinks;
+
+DROP TABLE /*_*/imagelinks;
+
+ALTER TABLE /*_*/imagelinks_tmp RENAME TO /*_*/imagelinks;
+
+-- Reverse index, for Special:Whatlinkshere and file description page local usage
+CREATE INDEX /*i*/il_to ON /*_*/imagelinks (il_to,il_from);
+
+-- Index for Special:Whatlinkshere with namespace filter
+CREATE INDEX /*i*/il_backlinks_namespace ON /*_*/imagelinks (il_from_namespace,il_to,il_from);
\ No newline at end of file
diff --git a/maintenance/sqlite/archives/patch-iwlinks-fix-pk.sql b/maintenance/sqlite/archives/patch-iwlinks-fix-pk.sql
new file mode 100644 (file)
index 0000000..91ce251
--- /dev/null
@@ -0,0 +1,24 @@
+CREATE TABLE /*_*/iwlinks_tmp (
+  -- page_id of the referring page
+  iwl_from int unsigned NOT NULL default 0,
+
+  -- Interwiki prefix code of the target
+  iwl_prefix varbinary(20) NOT NULL default '',
+
+  -- Title of the target, including namespace
+  iwl_title varchar(255) binary NOT NULL default '',
+  PRIMARY KEY (iwl_from,iwl_prefix,iwl_title)
+) /*$wgDBTableOptions*/;
+
+INSERT INTO /*_*/iwlinks_tmp
+       SELECT * FROM /*_*/iwlinks;
+
+DROP TABLE /*_*/iwlinks;
+
+ALTER TABLE /*_*/iwlinks_tmp RENAME TO /*_*/iwlinks;
+
+-- Index for ApiQueryIWBacklinks
+CREATE INDEX /*i*/iwl_prefix_title_from ON /*_*/iwlinks (iwl_prefix, iwl_title, iwl_from);
+
+-- Index for ApiQueryIWLinks
+CREATE INDEX /*i*/iwl_prefix_from_title ON /*_*/iwlinks (iwl_prefix, iwl_from, iwl_title);
\ No newline at end of file
diff --git a/maintenance/sqlite/archives/patch-langlinks-fix-pk.sql b/maintenance/sqlite/archives/patch-langlinks-fix-pk.sql
new file mode 100644 (file)
index 0000000..da096ac
--- /dev/null
@@ -0,0 +1,21 @@
+CREATE TABLE /*_*/langlinks_tmp (
+  -- page_id of the referring page
+  ll_from int unsigned NOT NULL default 0,
+
+  -- Language code of the target
+  ll_lang varbinary(20) NOT NULL default '',
+
+  -- Title of the target, including namespace
+  ll_title varchar(255) binary NOT NULL default '',
+  PRIMARY KEY (ll_from,ll_lang)
+) /*$wgDBTableOptions*/;
+
+INSERT INTO /*_*/langlinks_tmp
+       SELECT * FROM /*_*/langlinks;
+
+DROP TABLE /*_*/langlinks;
+
+ALTER TABLE /*_*/langlinks_tmp RENAME TO /*_*/langlinks;
+
+-- Index for ApiQueryLangbacklinks
+CREATE INDEX /*i*/ll_lang ON /*_*/langlinks (ll_lang, ll_title);
\ No newline at end of file
diff --git a/maintenance/sqlite/archives/patch-log_search-fix-pk.sql b/maintenance/sqlite/archives/patch-log_search-fix-pk.sql
new file mode 100644 (file)
index 0000000..153e415
--- /dev/null
@@ -0,0 +1,18 @@
+CREATE TABLE /*_*/log_search_tmp (
+  -- The type of ID (rev ID, log ID, rev timestamp, username)
+  ls_field varbinary(32) NOT NULL,
+  -- The value of the ID
+  ls_value varchar(255) NOT NULL,
+  -- Key to log_id
+  ls_log_id int unsigned NOT NULL default 0,
+  PRIMARY KEY (ls_field,ls_value,ls_log_id)
+) /*$wgDBTableOptions*/;
+
+INSERT INTO /*_*/log_search_tmp
+       SELECT * FROM /*_*/log_search;
+
+DROP TABLE /*_*/log_search;
+
+ALTER TABLE /*_*/log_search_tmp RENAME TO /*_*/log_search;
+
+CREATE INDEX /*i*/ls_log_id ON /*_*/log_search (ls_log_id);
\ No newline at end of file
diff --git a/maintenance/sqlite/archives/patch-log_search-rename-index.sql b/maintenance/sqlite/archives/patch-log_search-rename-index.sql
deleted file mode 100644 (file)
index 4b98a0f..0000000
+++ /dev/null
@@ -1 +0,0 @@
-CREATE UNIQUE INDEX ls_field_val ON /*_*/log_search (ls_field,ls_value,ls_log_id);
diff --git a/maintenance/sqlite/archives/patch-module_deps-fix-pk.sql b/maintenance/sqlite/archives/patch-module_deps-fix-pk.sql
new file mode 100644 (file)
index 0000000..73bcbe2
--- /dev/null
@@ -0,0 +1,16 @@
+CREATE TABLE /*_*/module_deps_tmp (
+  -- Module name
+  md_module varbinary(255) NOT NULL,
+  -- Module context vary (includes skin and language; called "md_skin" for legacy reasons)
+  md_skin varbinary(32) NOT NULL,
+  -- JSON blob with file dependencies
+  md_deps mediumblob NOT NULL,
+  PRIMARY KEY (md_module,md_skin)
+) /*$wgDBTableOptions*/;
+
+INSERT INTO /*_*/module_deps_tmp
+       SELECT * FROM /*_*/module_deps;
+
+DROP TABLE /*_*/module_deps;
+
+ALTER TABLE /*_*/module_deps_tmp RENAME TO /*_*/module_deps;
\ No newline at end of file
diff --git a/maintenance/sqlite/archives/patch-objectcache-fix-pk.sql b/maintenance/sqlite/archives/patch-objectcache-fix-pk.sql
new file mode 100644 (file)
index 0000000..f2bef58
--- /dev/null
@@ -0,0 +1,14 @@
+CREATE TABLE /*_*/objectcache_tmp (
+  keyname varbinary(255) NOT NULL default '' PRIMARY KEY,
+  value mediumblob,
+  exptime datetime
+) /*$wgDBTableOptions*/;
+
+INSERT INTO /*_*/objectcache_tmp
+       SELECT * FROM /*_*/objectcache;
+
+DROP TABLE /*_*/objectcache;
+
+ALTER TABLE /*_*/objectcache_tmp RENAME TO /*_*/objectcache;
+
+CREATE INDEX /*i*/exptime ON /*_*/objectcache (exptime);
\ No newline at end of file
diff --git a/maintenance/sqlite/archives/patch-pagelinks-fix-pk.sql b/maintenance/sqlite/archives/patch-pagelinks-fix-pk.sql
new file mode 100644 (file)
index 0000000..0e84586
--- /dev/null
@@ -0,0 +1,27 @@
+CREATE TABLE /*_*/pagelinks_tmp (
+  -- Key to the page_id of the page containing the link.
+  pl_from int unsigned NOT NULL default 0,
+  -- Namespace for this page
+  pl_from_namespace int NOT NULL default 0,
+
+  -- Key to page_namespace/page_title of the target page.
+  -- The target page may or may not exist, and due to renames
+  -- and deletions may refer to different page records as time
+  -- goes by.
+  pl_namespace int NOT NULL default 0,
+  pl_title varchar(255) binary NOT NULL default '',
+  PRIMARY KEY (pl_from,pl_namespace,pl_title)
+) /*$wgDBTableOptions*/;
+
+INSERT INTO /*_*/pagelinks_tmp
+       SELECT * FROM /*_*/pagelinks;
+
+DROP TABLE /*_*/pagelinks;
+
+ALTER TABLE /*_*/pagelinks_tmp RENAME TO /*_*/pagelinks;
+
+-- Reverse index, for Special:Whatlinkshere
+CREATE INDEX /*i*/pl_namespace ON /*_*/pagelinks (pl_namespace,pl_title,pl_from);
+
+-- Index for Special:Whatlinkshere with namespace filter
+CREATE INDEX /*i*/pl_backlinks_namespace ON /*_*/pagelinks (pl_from_namespace,pl_namespace,pl_title,pl_from);
diff --git a/maintenance/sqlite/archives/patch-querycache_info-fix-pk.sql b/maintenance/sqlite/archives/patch-querycache_info-fix-pk.sql
new file mode 100644 (file)
index 0000000..d9483be
--- /dev/null
@@ -0,0 +1,15 @@
+CREATE TABLE /*_*/querycache_info_tmp (
+  -- Special page name
+  -- Corresponds to a qc_type value
+  qci_type varbinary(32) NOT NULL default '' PRIMARY KEY,
+
+  -- Timestamp of last update
+  qci_timestamp binary(14) NOT NULL default '19700101000000'
+) /*$wgDBTableOptions*/;
+
+INSERT INTO /*_*/querycache_info_tmp
+       SELECT * FROM /*_*/querycache_info;
+
+DROP TABLE /*_*/querycache_info;
+
+ALTER TABLE /*_*/querycache_info_tmp RENAME TO /*_*/querycache_info;
\ No newline at end of file
diff --git a/maintenance/sqlite/archives/patch-site_stats-fix-pk.sql b/maintenance/sqlite/archives/patch-site_stats-fix-pk.sql
new file mode 100644 (file)
index 0000000..d785e98
--- /dev/null
@@ -0,0 +1,33 @@
+CREATE TABLE /*_*/site_stats_tmp (
+  -- The single row should contain 1 here.
+  ss_row_id int unsigned NOT NULL PRIMARY KEY,
+
+  -- Total number of edits performed.
+  ss_total_edits bigint unsigned default 0,
+
+  -- An approximate count of pages matching the following criteria:
+  -- * in namespace 0
+  -- * not a redirect
+  -- * contains the text '[['
+  -- See Article::isCountable() in includes/Article.php
+  ss_good_articles bigint unsigned default 0,
+
+  -- Total pages, theoretically equal to SELECT COUNT(*) FROM page; except faster
+  ss_total_pages bigint default '-1',
+
+  -- Number of users, theoretically equal to SELECT COUNT(*) FROM user;
+  ss_users bigint default '-1',
+
+  -- Number of users that still edit
+  ss_active_users bigint default '-1',
+
+  -- Number of images, equivalent to SELECT COUNT(*) FROM image
+  ss_images int default 0
+) /*$wgDBTableOptions*/;
+
+INSERT INTO /*_*/site_stats_tmp
+       SELECT * FROM /*_*/site_stats;
+
+DROP TABLE /*_*/site_stats;
+
+ALTER TABLE /*_*/site_stats_tmp RENAME TO /*_*/site_stats;
\ No newline at end of file
diff --git a/maintenance/sqlite/archives/patch-templatelinks-fix-pk.sql b/maintenance/sqlite/archives/patch-templatelinks-fix-pk.sql
new file mode 100644 (file)
index 0000000..5f09f60
--- /dev/null
@@ -0,0 +1,27 @@
+CREATE TABLE /*_*/templatelinks_tmp (
+  -- Key to the page_id of the page containing the link.
+  tl_from int unsigned NOT NULL default 0,
+  -- Namespace for this page
+  tl_from_namespace int NOT NULL default 0,
+
+  -- Key to page_namespace/page_title of the target page.
+  -- The target page may or may not exist, and due to renames
+  -- and deletions may refer to different page records as time
+  -- goes by.
+  tl_namespace int NOT NULL default 0,
+  tl_title varchar(255) binary NOT NULL default '',
+  PRIMARY KEY (tl_from,tl_namespace,tl_title)
+) /*$wgDBTableOptions*/;
+
+INSERT INTO /*_*/templatelinks_tmp
+       SELECT * FROM /*_*/templatelinks;
+
+DROP TABLE /*_*/templatelinks;
+
+ALTER TABLE /*_*/templatelinks_tmp RENAME TO /*_*/templatelinks;
+
+-- Reverse index, for Special:Whatlinkshere
+CREATE INDEX /*i*/tl_namespace ON /*_*/templatelinks (tl_namespace,tl_title,tl_from);
+
+-- Index for Special:Whatlinkshere with namespace filter
+CREATE INDEX /*i*/tl_backlinks_namespace ON /*_*/templatelinks (tl_from_namespace,tl_namespace,tl_title,tl_from);
diff --git a/maintenance/sqlite/archives/patch-text-fix-pk.sql b/maintenance/sqlite/archives/patch-text-fix-pk.sql
new file mode 100644 (file)
index 0000000..380887b
--- /dev/null
@@ -0,0 +1,37 @@
+CREATE TABLE /*_*/text_tmp (
+  -- Unique text storage key number.
+  -- Note that the 'oldid' parameter used in URLs does *not*
+  -- refer to this number anymore, but to rev_id.
+  --
+  -- revision.rev_text_id is a key to this column
+  old_id int unsigned NOT NULL PRIMARY KEY AUTO_INCREMENT,
+
+  -- Depending on the contents of the old_flags field, the text
+  -- may be convenient plain text, or it may be funkily encoded.
+  old_text mediumblob NOT NULL,
+
+  -- Comma-separated list of flags:
+  -- gzip: text is compressed with PHP's gzdeflate() function.
+  -- utf-8: text was stored as UTF-8.
+  --        If $wgLegacyEncoding option is on, rows *without* this flag
+  --        will be converted to UTF-8 transparently at load time. Note
+  --        that due to a bug in a maintenance script, this flag may
+  --        have been stored as 'utf8' in some cases (T18841).
+  -- object: text field contained a serialized PHP object.
+  --         The object either contains multiple versions compressed
+  --         together to achieve a better compression ratio, or it refers
+  --         to another row where the text can be found.
+  -- external: text was stored in an external location specified by old_text.
+  --           Any additional flags apply to the data stored at that URL, not
+  --           the URL itself. The 'object' flag is *not* set for URLs of the
+  --           form 'DB://cluster/id/itemid', because the external storage
+  --           system itself decompresses these.
+  old_flags tinyblob NOT NULL
+) /*$wgDBTableOptions*/ MAX_ROWS=10000000 AVG_ROW_LENGTH=10240;
+
+INSERT INTO /*_*/text_tmp
+       SELECT * FROM /*_*/text;
+
+DROP TABLE /*_*/text;
+
+ALTER TABLE /*_*/text_tmp RENAME TO /*_*/text;
\ No newline at end of file
diff --git a/maintenance/sqlite/archives/patch-transcache-fix-pk.sql b/maintenance/sqlite/archives/patch-transcache-fix-pk.sql
new file mode 100644 (file)
index 0000000..53f83e1
--- /dev/null
@@ -0,0 +1,12 @@
+CREATE TABLE /*_*/transcache_tmp (
+  tc_url varbinary(255) NOT NULL PRIMARY KEY,
+  tc_contents text,
+  tc_time binary(14) NOT NULL
+) /*$wgDBTableOptions*/;
+
+INSERT INTO /*_*/transcache_tmp
+       SELECT * FROM /*_*/transcache;
+
+DROP TABLE /*_*/transcache;
+
+ALTER TABLE /*_*/transcache_tmp RENAME TO /*_*/transcache;
\ No newline at end of file
diff --git a/maintenance/sqlite/archives/patch-user_former_groups-fix-pk.sql b/maintenance/sqlite/archives/patch-user_former_groups-fix-pk.sql
new file mode 100644 (file)
index 0000000..4f5d622
--- /dev/null
@@ -0,0 +1,13 @@
+CREATE TABLE /*_*/user_former_groups_tmp (
+  -- Key to user_id
+  ufg_user int unsigned NOT NULL default 0,
+  ufg_group varbinary(255) NOT NULL default '',
+  PRIMARY KEY (ufg_user,ufg_group)
+) /*$wgDBTableOptions*/;
+
+INSERT INTO /*_*/user_former_groups_tmp
+       SELECT * FROM /*_*/user_former_groups;
+
+DROP TABLE /*_*/user_former_groups;
+
+ALTER TABLE /*_*/user_former_groups_tmp RENAME TO /*_*/user_former_groups;
\ No newline at end of file
diff --git a/maintenance/sqlite/archives/patch-user_properties-fix-pk.sql b/maintenance/sqlite/archives/patch-user_properties-fix-pk.sql
new file mode 100644 (file)
index 0000000..8362d23
--- /dev/null
@@ -0,0 +1,20 @@
+CREATE TABLE /*_*/user_properties_tmp (
+  -- Foreign key to user.user_id
+  up_user int NOT NULL,
+
+  -- Name of the option being saved. This is indexed for bulk lookup.
+  up_property varbinary(255) NOT NULL,
+
+  -- Property value as a string.
+  up_value blob,
+  PRIMARY KEY (up_user,up_property)
+) /*$wgDBTableOptions*/;
+
+INSERT INTO /*_*/user_properties_tmp
+       SELECT * FROM /*_*/user_properties;
+
+DROP TABLE /*_*/user_properties;
+
+ALTER TABLE /*_*/user_properties_tmp RENAME TO /*_*/user_properties;
+
+CREATE INDEX /*i*/user_properties_property ON /*_*/user_properties (up_property);
\ No newline at end of file
index 1497d6f..d6ef40c 100644 (file)
@@ -178,11 +178,10 @@ CREATE INDEX /*i*/ug_expiry ON /*_*/user_groups (ug_expiry);
 CREATE TABLE /*_*/user_former_groups (
   -- Key to user_id
   ufg_user int unsigned NOT NULL default 0,
-  ufg_group varbinary(255) NOT NULL default ''
+  ufg_group varbinary(255) NOT NULL default '',
+  PRIMARY KEY (ufg_user,ufg_group)
 ) /*$wgDBTableOptions*/;
 
-CREATE UNIQUE INDEX /*i*/ufg_user_group ON /*_*/user_former_groups (ufg_user,ufg_group);
-
 --
 -- Stores notifications of user talk page changes, for the display
 -- of the "you have new messages" box
@@ -220,10 +219,10 @@ CREATE TABLE /*_*/user_properties (
   up_property varbinary(255) NOT NULL,
 
   -- Property value as a string.
-  up_value blob
+  up_value blob,
+  PRIMARY KEY (up_user,up_property)
 ) /*$wgDBTableOptions*/;
 
-CREATE UNIQUE INDEX /*i*/user_properties_user_property ON /*_*/user_properties (up_user,up_property);
 CREATE INDEX /*i*/user_properties_property ON /*_*/user_properties (up_property);
 
 --
@@ -346,10 +345,9 @@ CREATE TABLE /*_*/revision (
   -- or a rollback to a previous version.
   rev_text_id int unsigned NOT NULL,
 
-  -- Text comment summarizing the change.
-  -- This text is shown in the history and other changes lists,
-  -- rendered in a subset of wiki markup by Linker::formatComment()
-  rev_comment varbinary(767) NOT NULL,
+  -- Text comment summarizing the change. Deprecated in favor of
+  -- revision_comment_temp.revcomment_comment_id.
+  rev_comment varbinary(767) NOT NULL default '',
 
   -- Key to user.user_id of the user who made this edit.
   -- Stores 0 for anonymous edits and for some mass imports.
@@ -410,6 +408,23 @@ CREATE INDEX /*i*/usertext_timestamp ON /*_*/revision (rev_user_text,rev_timesta
 -- and is a logged-in user.
 CREATE INDEX /*i*/page_user_timestamp ON /*_*/revision (rev_page,rev_user,rev_timestamp);
 
+--
+-- Temporary table to avoid blocking on an alter of revision.
+--
+-- On large wikis like the English Wikipedia, altering the revision table is a
+-- months-long process. This table is being created to avoid such an alter, and
+-- will be merged back into revision in the future.
+--
+CREATE TABLE /*_*/revision_comment_temp (
+  -- Key to rev_id
+  revcomment_rev int unsigned NOT NULL,
+  -- Key to comment_id
+  revcomment_comment_id bigint unsigned NOT NULL,
+  PRIMARY KEY (revcomment_rev, revcomment_comment_id)
+) /*$wgDBTableOptions*/;
+-- Ensure uniqueness
+CREATE UNIQUE INDEX /*i*/revcomment_rev ON /*_*/revision_comment_temp (revcomment_rev);
+
 --
 -- Every time an edit by a logged out user is saved,
 -- a row is created in ip_changes. This stores
@@ -475,6 +490,40 @@ CREATE TABLE /*_*/text (
 -- In case tables are created as MyISAM, use row hints for MySQL <5.0 to avoid 4GB limit
 
 
+--
+-- Edits, blocks, and other actions typically have a textual comment describing
+-- the action. They are stored here to reduce the size of the main tables, and
+-- to allow for deduplication.
+--
+-- Deduplication is currently best-effort to avoid locking on inserts that
+-- would be required for strict deduplication. There MAY be multiple rows with
+-- the same comment_text and comment_data.
+--
+CREATE TABLE /*_*/comment (
+  -- Unique ID to identify each comment
+  comment_id bigint unsigned NOT NULL PRIMARY KEY AUTO_INCREMENT,
+
+  -- Hash of comment_text and comment_data, for deduplication
+  comment_hash INT NOT NULL,
+
+  -- Text comment summarizing the change.
+  -- This text is shown in the history and other changes lists,
+  -- rendered in a subset of wiki markup by Linker::formatComment()
+  -- Size limits are enforced at the application level, and should
+  -- take care to crop UTF-8 strings appropriately.
+  comment_text BLOB NOT NULL,
+
+  -- JSON data, intended for localizing auto-generated comments.
+  -- This holds structured data that is intended to be used to provide
+  -- localized versions of automatically-generated comments. When not empty,
+  -- comment_text should be the generated comment localized using the wiki's
+  -- content language.
+  comment_data BLOB
+) /*$wgDBTableOptions*/;
+-- Index used for deduplication.
+CREATE INDEX /*i*/comment_hash ON /*_*/comment (comment_hash);
+
+
 --
 -- Holding area for deleted articles, which may be viewed
 -- or restored by admins through the Special:Undelete interface.
@@ -496,7 +545,8 @@ CREATE TABLE /*_*/archive (
   ar_text mediumblob NOT NULL,
 
   -- Basic revision stuff...
-  ar_comment varbinary(767) NOT NULL,
+  ar_comment varbinary(767) NOT NULL default '', -- Deprecated in favor of ar_comment_id
+  ar_comment_id bigint unsigned NOT NULL DEFAULT 0, -- ("DEFAULT 0" is temporary, signaling that ar_comment should be used)
   ar_user int unsigned NOT NULL default 0,
   ar_user_text varchar(255) binary NOT NULL,
   ar_timestamp binary(14) NOT NULL default '',
@@ -576,12 +626,10 @@ CREATE TABLE /*_*/pagelinks (
   -- and deletions may refer to different page records as time
   -- goes by.
   pl_namespace int NOT NULL default 0,
-  pl_title varchar(255) binary NOT NULL default ''
+  pl_title varchar(255) binary NOT NULL default '',
+  PRIMARY KEY (pl_from,pl_namespace,pl_title)
 ) /*$wgDBTableOptions*/;
 
--- Forward index, for page edit, save
-CREATE UNIQUE INDEX /*i*/pl_from ON /*_*/pagelinks (pl_from,pl_namespace,pl_title);
-
 -- Reverse index, for Special:Whatlinkshere
 CREATE INDEX /*i*/pl_namespace ON /*_*/pagelinks (pl_namespace,pl_title,pl_from);
 
@@ -603,12 +651,10 @@ CREATE TABLE /*_*/templatelinks (
   -- and deletions may refer to different page records as time
   -- goes by.
   tl_namespace int NOT NULL default 0,
-  tl_title varchar(255) binary NOT NULL default ''
+  tl_title varchar(255) binary NOT NULL default '',
+  PRIMARY KEY (tl_from,tl_namespace,tl_title)
 ) /*$wgDBTableOptions*/;
 
--- Forward index, for page edit, save
-CREATE UNIQUE INDEX /*i*/tl_from ON /*_*/templatelinks (tl_from,tl_namespace,tl_title);
-
 -- Reverse index, for Special:Whatlinkshere
 CREATE INDEX /*i*/tl_namespace ON /*_*/templatelinks (tl_namespace,tl_title,tl_from);
 
@@ -630,12 +676,10 @@ CREATE TABLE /*_*/imagelinks (
   -- Filename of target image.
   -- This is also the page_title of the file's description page;
   -- all such pages are in namespace 6 (NS_FILE).
-  il_to varchar(255) binary NOT NULL default ''
+  il_to varchar(255) binary NOT NULL default '',
+  PRIMARY KEY (il_from,il_to)
 ) /*$wgDBTableOptions*/;
 
--- Forward index, for cache invalidation on file update, etc.
-CREATE UNIQUE INDEX /*i*/il_from ON /*_*/imagelinks (il_from,il_to);
-
 -- Reverse index, for Special:Whatlinkshere and file description page local usage
 CREATE INDEX /*i*/il_to ON /*_*/imagelinks (il_to,il_from);
 
@@ -685,10 +729,10 @@ CREATE TABLE /*_*/categorylinks (
   -- paginate the three categories separately.  This never has to be updated
   -- after the page is created, since none of these page types can be moved to
   -- any other.
-  cl_type ENUM('page', 'subcat', 'file') NOT NULL default 'page'
+  cl_type ENUM('page', 'subcat', 'file') NOT NULL default 'page',
+  PRIMARY KEY (cl_from,cl_to)
 ) /*$wgDBTableOptions*/;
 
-CREATE UNIQUE INDEX /*i*/cl_from ON /*_*/categorylinks (cl_from,cl_to);
 
 -- We always sort within a given category, and within a given type.  FIXME:
 -- Formerly this index didn't cover cl_type (since that didn't exist), so old
@@ -787,12 +831,10 @@ CREATE TABLE /*_*/langlinks (
   ll_lang varbinary(20) NOT NULL default '',
 
   -- Title of the target, including namespace
-  ll_title varchar(255) binary NOT NULL default ''
+  ll_title varchar(255) binary NOT NULL default '',
+  PRIMARY KEY (ll_from,ll_lang)
 ) /*$wgDBTableOptions*/;
 
--- Forward index, for page edit, save, ApiQueryLanglinks
-CREATE UNIQUE INDEX /*i*/ll_from ON /*_*/langlinks (ll_from, ll_lang);
-
 -- Index for ApiQueryLangbacklinks
 CREATE INDEX /*i*/ll_lang ON /*_*/langlinks (ll_lang, ll_title);
 
@@ -808,12 +850,10 @@ CREATE TABLE /*_*/iwlinks (
   iwl_prefix varbinary(20) NOT NULL default '',
 
   -- Title of the target, including namespace
-  iwl_title varchar(255) binary NOT NULL default ''
+  iwl_title varchar(255) binary NOT NULL default '',
+  PRIMARY KEY (iwl_from,iwl_prefix,iwl_title)
 ) /*$wgDBTableOptions*/;
 
--- Forward index, for page edit, save, ApiQueryIWLinks
-CREATE UNIQUE INDEX /*i*/iwl_from ON /*_*/iwlinks (iwl_from, iwl_prefix, iwl_title);
-
 -- Index for ApiQueryIWBacklinks
 CREATE INDEX /*i*/iwl_prefix_title_from ON /*_*/iwlinks (iwl_prefix, iwl_title, iwl_from);
 
@@ -827,7 +867,7 @@ CREATE INDEX /*i*/iwl_prefix_from_title ON /*_*/iwlinks (iwl_prefix, iwl_from, i
 --
 CREATE TABLE /*_*/site_stats (
   -- The single row should contain 1 here.
-  ss_row_id int unsigned NOT NULL,
+  ss_row_id int unsigned NOT NULL PRIMARY KEY,
 
   -- Total number of edits performed.
   ss_total_edits bigint unsigned default 0,
@@ -852,9 +892,6 @@ CREATE TABLE /*_*/site_stats (
   ss_images int default 0
 ) /*$wgDBTableOptions*/;
 
--- Pointless index to assuage developer superstitions
-CREATE UNIQUE INDEX /*i*/ss_row_id ON /*_*/site_stats (ss_row_id);
-
 --
 -- The internet is full of jerks, alas. Sometimes it's handy
 -- to block a vandal or troll account.
@@ -875,8 +912,12 @@ CREATE TABLE /*_*/ipblocks (
   -- User name of blocker
   ipb_by_text varchar(255) binary NOT NULL default '',
 
-  -- Text comment made by blocker.
-  ipb_reason varbinary(767) NOT NULL,
+  -- Text comment made by blocker. Deprecated in favor of ipb_reason_id
+  ipb_reason varbinary(767) NOT NULL default '',
+
+  -- Key to comment_id. Text comment made by blocker.
+  -- ("DEFAULT 0" is temporary, signaling that ipb_reason should be used)
+  ipb_reason_id bigint unsigned NOT NULL DEFAULT 0,
 
   -- Creation (or refresh) date in standard YMDHMS form.
   -- IP blocks expire automatically.
@@ -983,7 +1024,8 @@ CREATE TABLE /*_*/image (
 
   -- Description field as entered by the uploader.
   -- This is displayed in image upload history and logs.
-  img_description varbinary(767) NOT NULL,
+  -- Deprecated in favor of image_comment_temp.imgcomment_description_id.
+  img_description varbinary(767) NOT NULL default '',
 
   -- user_id and user_name of uploader.
   img_user int unsigned NOT NULL default 0,
@@ -1008,6 +1050,23 @@ CREATE INDEX /*i*/img_sha1 ON /*_*/image (img_sha1(10));
 -- Used to get media of one type
 CREATE INDEX /*i*/img_media_mime ON /*_*/image (img_media_type,img_major_mime,img_minor_mime);
 
+--
+-- Temporary table to avoid blocking on an alter of image.
+--
+-- On large wikis like Wikimedia Commons, altering the image table is a
+-- months-long process. This table is being created to avoid such an alter, and
+-- will be merged back into image in the future.
+--
+CREATE TABLE /*_*/image_comment_temp (
+  -- Key to img_name (ugh)
+  imgcomment_name varchar(255) binary NOT NULL,
+  -- Key to comment_id
+  imgcomment_description_id bigint unsigned NOT NULL,
+  PRIMARY KEY (imgcomment_name, imgcomment_description_id)
+) /*$wgDBTableOptions*/;
+-- Ensure uniqueness
+CREATE UNIQUE INDEX /*i*/imgcomment_name ON /*_*/image_comment_temp (imgcomment_name);
+
 
 --
 -- Previous revisions of uploaded files.
@@ -1027,7 +1086,8 @@ CREATE TABLE /*_*/oldimage (
   oi_width int NOT NULL default 0,
   oi_height int NOT NULL default 0,
   oi_bits int NOT NULL default 0,
-  oi_description varbinary(767) NOT NULL,
+  oi_description varbinary(767) NOT NULL default '', -- Deprecated.
+  oi_description_id bigint unsigned NOT NULL DEFAULT 0, -- ("DEFAULT 0" is temporary, signaling that oi_description should be used)
   oi_user int unsigned NOT NULL default 0,
   oi_user_text varchar(255) binary NOT NULL,
   oi_timestamp binary(14) NOT NULL default '',
@@ -1075,7 +1135,8 @@ CREATE TABLE /*_*/filearchive (
   -- Deletion information, if this file is deleted.
   fa_deleted_user int,
   fa_deleted_timestamp binary(14) default '',
-  fa_deleted_reason varbinary(767) default '',
+  fa_deleted_reason varbinary(767) default '', -- Deprecated
+  fa_deleted_reason_id bigint unsigned NOT NULL DEFAULT 0, -- ("DEFAULT 0" is temporary, signaling that fa_deleted_reason should be used)
 
   -- Duped fields from image
   fa_size int unsigned default 0,
@@ -1086,7 +1147,8 @@ CREATE TABLE /*_*/filearchive (
   fa_media_type ENUM("UNKNOWN", "BITMAP", "DRAWING", "AUDIO", "VIDEO", "MULTIMEDIA", "OFFICE", "TEXT", "EXECUTABLE", "ARCHIVE", "3D") default NULL,
   fa_major_mime ENUM("unknown", "application", "audio", "image", "text", "video", "message", "model", "multipart", "chemical") default "unknown",
   fa_minor_mime varbinary(100) default "unknown",
-  fa_description varbinary(767),
+  fa_description varbinary(767) default '', -- Deprecated
+  fa_description_id bigint unsigned NOT NULL DEFAULT 0, -- ("DEFAULT 0" is temporary, signaling that fa_description should be used)
   fa_user int unsigned default 0,
   fa_user_text varchar(255) binary,
   fa_timestamp binary(14) default '',
@@ -1184,7 +1246,8 @@ CREATE TABLE /*_*/recentchanges (
   rc_title varchar(255) binary NOT NULL default '',
 
   -- as in revision...
-  rc_comment varbinary(767) NOT NULL default '',
+  rc_comment varbinary(767) NOT NULL default '', -- Deprecated.
+  rc_comment_id bigint unsigned NOT NULL DEFAULT 0, -- ("DEFAULT 0" is temporary, signaling that rc_comment should be used)
   rc_minor tinyint unsigned NOT NULL default 0,
 
   -- Edits by user accounts with the 'bot' rights key are
@@ -1381,13 +1444,11 @@ CREATE INDEX /*i*/exptime ON /*_*/objectcache (exptime);
 -- Cache of interwiki transclusion
 --
 CREATE TABLE /*_*/transcache (
-  tc_url varbinary(255) NOT NULL,
+  tc_url varbinary(255) NOT NULL PRIMARY KEY,
   tc_contents text,
   tc_time binary(14) NOT NULL
 ) /*$wgDBTableOptions*/;
 
-CREATE UNIQUE INDEX /*i*/tc_url_idx ON /*_*/transcache (tc_url);
-
 
 CREATE TABLE /*_*/logging (
   -- Log ID, for referring to this specific log entry, probably for deletion and such.
@@ -1415,8 +1476,13 @@ CREATE TABLE /*_*/logging (
   log_page int unsigned NULL,
 
   -- Freeform text. Interpreted as edit history comments.
+  -- Deprecated in favor of log_comment_id.
   log_comment varbinary(767) NOT NULL default '',
 
+  -- Key to comment_id. Comment summarizing the change.
+  -- ("DEFAULT 0" is temporary, signaling that log_comment should be used)
+  log_comment_id bigint unsigned NOT NULL DEFAULT 0,
+
   -- miscellaneous parameters:
   -- LF separated list (old system) or serialized PHP array (new system)
   log_params blob NOT NULL,
@@ -1460,9 +1526,9 @@ CREATE TABLE /*_*/log_search (
   -- The value of the ID
   ls_value varchar(255) NOT NULL,
   -- Key to log_id
-  ls_log_id int unsigned NOT NULL default 0
+  ls_log_id int unsigned NOT NULL default 0,
+  PRIMARY KEY (ls_field,ls_value,ls_log_id)
 ) /*$wgDBTableOptions*/;
-CREATE UNIQUE INDEX /*i*/ls_field_val ON /*_*/log_search (ls_field,ls_value,ls_log_id);
 CREATE INDEX /*i*/ls_log_id ON /*_*/log_search (ls_log_id);
 
 
@@ -1514,14 +1580,12 @@ CREATE INDEX /*i*/job_timestamp ON /*_*/job (job_timestamp);
 CREATE TABLE /*_*/querycache_info (
   -- Special page name
   -- Corresponds to a qc_type value
-  qci_type varbinary(32) NOT NULL default '',
+  qci_type varbinary(32) NOT NULL default '' PRIMARY KEY,
 
   -- Timestamp of last update
   qci_timestamp binary(14) NOT NULL default '19700101000000'
 ) /*$wgDBTableOptions*/;
 
-CREATE UNIQUE INDEX /*i*/qci_type ON /*_*/querycache_info (qci_type);
-
 
 -- For each redirect, this table contains exactly one row defining its target
 CREATE TABLE /*_*/redirect (
@@ -1592,7 +1656,8 @@ CREATE TABLE /*_*/protected_titles (
   pt_namespace int NOT NULL,
   pt_title varchar(255) binary NOT NULL,
   pt_user int unsigned NOT NULL,
-  pt_reason varbinary(767),
+  pt_reason varbinary(767) default '', -- Deprecated.
+  pt_reason_id bigint unsigned NOT NULL DEFAULT 0, -- ("DEFAULT 0" is temporary, signaling that pt_reason should be used)
   pt_timestamp binary(14) NOT NULL,
   pt_expiry varbinary(14) NOT NULL default '',
   pt_create_perm varbinary(60) NOT NULL
@@ -1686,9 +1751,9 @@ CREATE TABLE /*_*/module_deps (
   -- Module context vary (includes skin and language; called "md_skin" for legacy reasons)
   md_skin varbinary(32) NOT NULL,
   -- JSON blob with file dependencies
-  md_deps mediumblob NOT NULL
+  md_deps mediumblob NOT NULL,
+  PRIMARY KEY (md_module,md_skin)
 ) /*$wgDBTableOptions*/;
-CREATE UNIQUE INDEX /*i*/md_module_skin ON /*_*/module_deps (md_module, md_skin);
 
 -- Holds all the sites known to the wiki.
 CREATE TABLE /*_*/sites (
index 4a7f3e4..3a5de66 100644 (file)
@@ -1056,6 +1056,7 @@ return [
                'targets' => [ 'desktop', 'mobile' ],
        ],
        'mediawiki.hlist' => [
+               'targets' => [ 'desktop', 'mobile' ],
                'styles' => [
                        'resources/src/mediawiki/mediawiki.hlist-allskins.less',
                ],
@@ -1428,7 +1429,7 @@ return [
        ],
        'mediawiki.action.edit.styles' => [
                'targets' => [ 'desktop', 'mobile' ],
-               'styles' => 'resources/src/mediawiki.action/mediawiki.action.edit.styles.css',
+               'styles' => 'resources/src/mediawiki.action/mediawiki.action.edit.styles.less',
        ],
        'mediawiki.action.edit.collapsibleFooter' => [
                'scripts' => 'resources/src/mediawiki.action/mediawiki.action.edit.collapsibleFooter.js',
@@ -1748,6 +1749,12 @@ return [
                        'resources/src/mediawiki.rcfilters/styles/mw.rcfilters.less',
                ],
        ],
+       'mediawiki.rcfilters.highlightCircles.seenunseen.styles' => [
+               'styles' => [
+                       'resources/src/mediawiki.rcfilters/' .
+                       'styles/mw.rcfilters.ui.ChangesListWrapperWidget.highlightCircles.seenunseen.less',
+               ],
+       ],
        'mediawiki.rcfilters.filters.dm' => [
                'scripts' => [
                        'resources/src/mediawiki.rcfilters/mw.rcfilters.js',
@@ -1796,6 +1803,8 @@ return [
                        'resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.HighlightColorPickerWidget.js',
                        'resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.LiveUpdateButtonWidget.js',
                        'resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.MarkSeenButtonWidget.js',
+                       'resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.RcTopSectionWidget.js',
+                       'resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.WatchlistTopSectionWidget.js',
                        'resources/src/mediawiki.rcfilters/mw.rcfilters.HighlightColors.js',
                        'resources/src/mediawiki.rcfilters/mw.rcfilters.init.js',
                ],
@@ -1823,6 +1832,8 @@ return [
                        'resources/src/mediawiki.rcfilters/styles/mw.rcfilters.ui.SavedLinksListItemWidget.less',
                        'resources/src/mediawiki.rcfilters/styles/mw.rcfilters.ui.SaveFiltersPopupButtonWidget.less',
                        'resources/src/mediawiki.rcfilters/styles/mw.rcfilters.ui.LiveUpdateButtonWidget.less',
+                       'resources/src/mediawiki.rcfilters/styles/mw.rcfilters.ui.RcTopSectionWidget.less',
+                       'resources/src/mediawiki.rcfilters/styles/mw.rcfilters.ui.WatchlistTopSectionWidget.less',
                ],
                'skinStyles' => [
                        'monobook' => [
@@ -1888,7 +1899,8 @@ return [
                        'rcfilters-liveupdates-button',
                        'rcfilters-liveupdates-button-title-on',
                        'rcfilters-liveupdates-button-title-off',
-                       'rcfilters-watchlist-markSeen-button',
+                       'rcfilters-watchlist-markseen-button',
+                       'rcfilters-watchlist-edit-watchlist-button',
                        'rcfilters-other-review-tools',
                        'blanknamespace',
                        'namespaces',
@@ -2180,8 +2192,9 @@ return [
                'styles' => 'resources/src/mediawiki.special/mediawiki.special.upload.styles.css',
        ],
        'mediawiki.special.userlogin.common.styles' => [
-               'styles' => [
-                       'resources/src/mediawiki.special/mediawiki.special.userlogin.common.css',
+               'targets' => [ 'desktop', 'mobile' ],
+               'skinStyles' => [
+                       'default' => 'resources/src/mediawiki.special/mediawiki.special.userlogin.common.css',
                ],
        ],
        'mediawiki.special.userlogin.login.styles' => [
index 922da31..ecd376a 100644 (file)
                                match = s.match( ts.rgx.isoDate[ 1 ] );
                        }
                        if ( !match ) {
-                               return 0;
+                               return -Infinity;
                        }
                        // Month and day
                        for ( i = 2; i <= 4; i += 2 ) {
diff --git a/resources/src/mediawiki.action/mediawiki.action.edit.styles.css b/resources/src/mediawiki.action/mediawiki.action.edit.styles.css
deleted file mode 100644 (file)
index 7b6aaa8..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-/*!
- * Styles for elements of the editing form.
- */
-
-/* General layout */
-#wpTextbox1 {
-       margin: 0;
-       display: block;
-       /* Ensure the textarea is not higher than browser's viewport on small screens */
-       max-height: 100vh;
-       /* But don't let it collapse into nothingness on really tiny screens */
-       min-height: 5em;
-}
-
-/*
- * Add a bit of margin space between the preview and the toolbar.
- * This replaces the ugly <p><br /></p> we used to insert into the page source
- */
-#wikiPreview.ontop {
-       margin-bottom: 1em;
-}
-
-/* Adjustments to edit form elements */
-#editpage-copywarn {
-       font-size: 0.9em;
-}
-
-.mw-editform-ooui #wpSummaryWidget {
-       display: block;
-       margin-bottom: 1em;
-       max-width: none;
-}
-
-.mw-editform-ooui #editpage-copywarn {
-       line-height: 1.26;
-}
-
-.mw-editform-ooui #wpSummaryLabel {
-       margin: 0;
-}
-
-.mw-editform-ooui .editCheckboxes .oo-ui-fieldLayout {
-       margin-right: 1em;
-}
-
-.mw-editform-ooui .editHelp {
-       margin-left: 0.5em;
-       vertical-align: middle;
-}
-
-.mw-editform-ooui .editHelp a {
-       font-weight: bold;
-}
-
-.mw-editform-ooui .editOptions {
-       border-radius: 0 0 2px 2px;
-}
diff --git a/resources/src/mediawiki.action/mediawiki.action.edit.styles.less b/resources/src/mediawiki.action/mediawiki.action.edit.styles.less
new file mode 100644 (file)
index 0000000..dc6a366
--- /dev/null
@@ -0,0 +1,56 @@
+/*!
+ * Styles for elements of the editing form.
+ */
+
+/*
+ * Add a bit of margin space between the preview and the toolbar.
+ * This replaces the ugly <p><br /></p> we used to insert into the page source
+ */
+#wikiPreview.ontop {
+       margin-bottom: 1em;
+}
+
+.mw-editform {
+       /* General layout */
+       #wpTextbox1 {
+               margin: 0;
+               display: block;
+               /* Ensure the textarea is not higher than browser's viewport on small screens */
+               max-height: 100vh;
+               /* But don't let it collapse into nothingness on really tiny screens */
+               min-height: 5em;
+       }
+
+       /* Adjustments to edit form elements */
+       #editpage-copywarn {
+               font-size: 0.9em;
+               line-height: 1.26;
+       }
+
+       #wpSummaryWidget {
+               display: block;
+               margin-bottom: 1em;
+               max-width: none;
+       }
+
+       #wpSummaryLabel {
+               margin: 0;
+       }
+
+       .editCheckboxes .oo-ui-fieldLayout {
+               margin-right: 1em;
+       }
+
+       .editHelp {
+               margin-left: 0.5em;
+               vertical-align: middle;
+
+               a {
+                       font-weight: bold;
+               }
+       }
+
+       .editOptions {
+               border-radius: 0 0 2px 2px;
+       }
+}
index e25c96a..e0ab45a 100644 (file)
                        $content.append( data.message );
                }
 
-               $popup = $( '<div>' ).addClass( 'postedit mw-notification' ).append(
-                       $content,
-                       $( '<a>' ).addClass( 'postedit-close' ).attr( 'href', '#' ).text( '×' )
-               ).on( 'click', function ( e ) {
-                       e.preventDefault();
-                       clearTimeout( timeoutId );
-                       fadeOutConfirmation();
-               } );
+               $popup = $( '<div>' ).addClass( 'postedit mw-notification' ).append( $content )
+                       .click( function () {
+                               clearTimeout( timeoutId );
+                               fadeOutConfirmation();
+                       } );
 
                $container = $( '<div>' ).addClass( 'postedit-container' ).append( $popup );
                timeoutId = setTimeout( fadeOutConfirmation, 3000 );
index 8094559..467928d 100644 (file)
@@ -8,10 +8,7 @@
        left: 50%;
        z-index: 1000;
        font-size: 13px;
-
-       &:hover {
-               cursor: pointer;
-       }
+       cursor: pointer;
 }
 
 .postedit {
@@ -50,7 +47,8 @@
        background-position: left;
 }
 
-.postedit-close {
+.postedit:after {
+       content: '×';
        position: absolute;
        padding: 0 0.8em;
        right: 0;
        font-size: 1.25em;
        font-weight: bold;
        line-height: 2.3em;
-       color: #000;
        text-shadow: 0 0.0625em 0 #fff;
-       text-decoration: none;
        opacity: 0.2;
+}
 
-       .postedit:hover & {
-               color: #000;
-               text-decoration: none;
-               opacity: 0.4;
-       }
+.postedit:hover:after {
+       opacity: 0.4;
 }
index a8ee06b..62ba002 100644 (file)
                return result;
        };
 
+       /**
+        * Get an array of currently applied highlight colors
+        *
+        * @return {string[]} Currently applied highlight colors
+        */
+       mw.rcfilters.dm.FiltersViewModel.prototype.getCurrentlyUsedHighlightColors = function () {
+               var result = [];
+
+               this.getHighlightedItems().forEach( function ( filterItem ) {
+                       var color = filterItem.getHighlightColor();
+
+                       if ( result.indexOf( color ) === -1 ) {
+                               result.push( color );
+                       }
+               } );
+
+               return result;
+       };
+
        /**
         * Sanitize value group of a string_option groups type
         * Remove duplicates and make sure to only use valid
index a7f3d23..d87ef73 100644 (file)
@@ -18,6 +18,7 @@
                OO.EmitterList.call( this );
 
                this.default = config.default;
+               this.baseState = {};
 
                // Events
                this.aggregate( { update: 'itemUpdate' } );
         * @return {mw.rcfilters.dm.SavedQueryItemModel} Matching item model
         */
        mw.rcfilters.dm.SavedQueriesModel.prototype.findMatchingQuery = function ( fullQueryComparison ) {
+               var model = this;
+
+               fullQueryComparison = this.getDifferenceFromBase( fullQueryComparison );
+
                return this.getItems().filter( function ( item ) {
+                       var comparedData = model.getDifferenceFromBase( item.getData() );
                        return OO.compare(
-                               item.getData(),
+                               comparedData,
                                fullQueryComparison
                        );
                } )[ 0 ];
        };
 
+       /**
+        * Get a minimal representation of the state for comparison
+        *
+        * @param {Object} state Given state
+        * @return {Object} Minimal state
+        */
+       mw.rcfilters.dm.SavedQueriesModel.prototype.getDifferenceFromBase = function ( state ) {
+               var result = { filters: {}, highlights: {}, invert: state.invert },
+                       baseState = this.baseState;
+
+               // XOR results
+               $.each( state.filters, function ( name, value ) {
+                       if ( baseState.filters !== undefined && baseState.filters[ name ] !== value ) {
+                               result.filters[ name ] = value;
+                       }
+               } );
+
+               $.each( state.highlights, function ( name, value ) {
+                       if ( baseState.highlights !== undefined && baseState.highlights[ name ] !== value && name !== 'highlight' ) {
+                               result.highlights[ name ] = value;
+                       }
+               } );
+
+               return result;
+       };
        /**
         * Get query by its identifier
         *
index a0e60d5..81bfb47 100644 (file)
@@ -40,7 +40,7 @@
         * @param {Object} [tagList] Tag definition
         */
        mw.rcfilters.Controller.prototype.initialize = function ( filterStructure, namespaceStructure, tagList ) {
-               var parsedSavedQueries, limitDefault,
+               var parsedSavedQueries,
                        displayConfig = mw.config.get( 'StructuredChangeFiltersDisplayConfig' ),
                        controller = this,
                        views = {},
                        };
                }
 
-               // Convert the default from the old preference
-               // since the limit preference actually affects more
-               // than just the RecentChanges page
-               limitDefault = Number( mw.user.options.get( 'rclimit', '50' ) );
-
                // Add parameter range operations
                views.range = {
                        groups: [
                                                max: 1000
                                        },
                                        sortFunc: function ( a, b ) { return Number( a.name ) - Number( b.name ); },
-                                       'default': String( limitDefault ),
+                                       'default': displayConfig.limitDefault,
                                        // Temporarily making this not sticky until we resolve the problem
                                        // with the misleading preference. Note that if this is to be permanent
                                        // we should remove all sticky behavior methods completely
                                                        ( Number( i ) * 24 ).toFixed( 2 ) :
                                                        Number( i );
                                        },
-                                       'default': mw.user.options.get( 'rcdays', '30' ),
+                                       'default': displayConfig.daysDefault,
                                        // Temporarily making this not sticky while limit is not sticky, see above
                                        // isSticky: true,
                                        excludedFromSavedQueries: true,
                                }
                        } );
 
-                       return $.extend( true, {}, savedParams, savedHighlights );
+                       return $.extend( true, {}, savedParams, savedHighlights, { invert: String( Number( data.invert || 0 ) ) } );
                }
 
                return this.filtersModel.getDefaultParams();
index a1ef981..1894b61 100644 (file)
                this.filtersModel.toggleInvertedNamespaces( !!Number( parameters.invert ) );
 
                // Update highlight state
-               this.filtersModel.toggleHighlight( !!Number( parameters.highlight ) );
                this.filtersModel.getItems().forEach( function ( filterItem ) {
                        var color = parameters[ filterItem.getName() + '_color' ];
                        if ( color ) {
                                filterItem.clearHighlightColor();
                        }
                } );
+               this.filtersModel.toggleHighlight( !!Number( parameters.highlight ) );
 
                // Check all filter interactions
                this.filtersModel.reassessFilterInteractions();
index a6bce14..0819351 100644 (file)
@@ -8,10 +8,10 @@
                 * @private
                 */
                init: function () {
-                       var toplinksTitle,
-                               topLinksCookieName = 'rcfilters-toplinks-collapsed-state',
-                               topLinksCookie = mw.cookie.get( topLinksCookieName ),
-                               topLinksCookieValue = topLinksCookie || 'collapsed',
+                       var $topLinks,
+                               rcTopSection,
+                               $watchlistDetails,
+                               wlTopSection,
                                savedQueriesPreferenceName = mw.config.get( 'wgStructuredChangeFiltersSavedQueriesPreferenceName' ),
                                filtersModel = new mw.rcfilters.dm.FiltersViewModel(),
                                changesListModel = new mw.rcfilters.dm.ChangesListViewModel(),
@@ -26,7 +26,9 @@
                                        .addClass( 'mw-rcfilters-ui-overlay' ),
                                filtersWidget = new mw.rcfilters.ui.FilterWrapperWidget(
                                        controller, filtersModel, savedQueriesModel, changesListModel, { $overlay: $overlay } ),
-                               markSeenButton,
+                               savedLinksListWidget = new mw.rcfilters.ui.SavedLinksListWidget(
+                                       controller, savedQueriesModel, { $overlay: $overlay }
+                               ),
                                currentPage = mw.config.get( 'wgCanonicalNamespace' ) +
                                        ':' +
                                        mw.config.get( 'wgCanonicalSpecialPageName' );
                        controller.replaceUrl();
 
                        if ( currentPage === 'Special:Recentchanges' ) {
-                               toplinksTitle = new OO.ui.ButtonWidget( {
-                                       framed: false,
-                                       indicator: topLinksCookieValue === 'collapsed' ? 'down' : 'up',
-                                       flags: [ 'progressive' ],
-                                       label: $( '<span>' ).append( mw.message( 'rcfilters-other-review-tools' ).parse() ).contents()
-                               } );
-                               $( '.mw-recentchanges-toplinks-title' ).replaceWith( toplinksTitle.$element );
-                               // Move the top links to a designated area so it's near the
-                               // 'saved filters' button and make it collapsible
-                               $( '.mw-recentchanges-toplinks' )
-                                       .addClass( 'mw-rcfilters-ui-ready' )
-                                       .makeCollapsible( {
-                                               collapsed: topLinksCookieValue === 'collapsed',
-                                               $customTogglers: toplinksTitle.$element
-                                       } )
-                                       .on( 'beforeExpand.mw-collapsible', function () {
-                                               mw.cookie.set( topLinksCookieName, 'expanded' );
-                                               toplinksTitle.setIndicator( 'up' );
-                                       } )
-                                       .on( 'beforeCollapse.mw-collapsible', function () {
-                                               mw.cookie.set( topLinksCookieName, 'collapsed' );
-                                               toplinksTitle.setIndicator( 'down' );
-                                       } )
-                                       .appendTo( '.mw-rcfilters-ui-filterWrapperWidget-top-placeholder' );
+                               $topLinks = $( '.mw-recentchanges-toplinks' ).detach();
+
+                               rcTopSection = new mw.rcfilters.ui.RcTopSectionWidget(
+                                       savedLinksListWidget, $topLinks
+                               );
+                               filtersWidget.setTopSection( rcTopSection.$element );
                        } // end Special:RC
 
                        if ( currentPage === 'Special:Watchlist' ) {
-                               markSeenButton = new mw.rcfilters.ui.MarkSeenButtonWidget( controller, changesListModel );
-                               $( 'form#mw-watchlist-resetbutton' ).detach();
-                               filtersWidget.prependToTopRow( markSeenButton );
+                               $( '#contentSub, form#mw-watchlist-resetbutton' ).detach();
+                               $watchlistDetails = $( '.watchlistDetails' ).detach().contents();
+
+                               wlTopSection = new mw.rcfilters.ui.WatchlistTopSectionWidget(
+                                       controller, changesListModel, savedLinksListWidget, $watchlistDetails
+                               );
+                               filtersWidget.setTopSection( wlTopSection.$element );
                        } // end Special:WL
                }
        };
index c667bac..e031552 100644 (file)
@@ -7,29 +7,6 @@
                border: 0;
        }
 
-       .mw-recentchanges-toplinks {
-               padding: 0 0.5em;
-
-               .oo-ui-widget-enabled.oo-ui-buttonElement.oo-ui-buttonElement-frameless .oo-ui-buttonElement-button {
-                       padding: 0 2.5em 0 0.5em;
-               }
-
-               &-title,
-               .mw-collapsible-text {
-                       // Same as the legend
-                       font-size: 0.85em;
-               }
-
-               &:not( .mw-collapsed ) {
-                       // Same as the legend
-                       border: 1px solid #ddd;
-               }
-
-               &:not( .mw-rcfilters-ui-ready ) {
-                       display: none;
-               }
-       }
-
        .rcfilters-head {
                min-height: 200px;
 
                        .animation-delay( 0s );
                }
        }
+
+       #contentSub,
+       p.watchlistDetails,
+       form#mw-watchlist-resetbutton {
+               display: none;
+       }
 }
 
 .mw-rcfilters-staticfilters-selected {
index 5a885ec..b4e3b0e 100644 (file)
@@ -8,8 +8,7 @@
 }
 
 // This is a general mixin for a color circle
-.mw-rcfilters-mixin-circle( @color: #fff, @diameter: 2em, @padding: 0.5em, @border: false ) {
-       background-color: @color;
+.mw-rcfilters-mixin-circle( @color: #fff, @diameter: 2em, @padding: 0.5em, @border: false, @borderColor: #54595d, @emptyBackground: false ) {
        .box-sizing( border-box );
        min-width: @diameter;
        width: @diameter;
        margin: @padding;
        border-radius: 50%;
 
+       & when ( @emptyBackground = false ) {
+               background-color: @color;
+       }
+       & when ( @emptyBackground = true ) {
+               background-color: @highlight-none;
+       }
+
        & when ( @border = true ) {
-               border: 1px solid #54595d;
+               border: 1px solid @borderColor;
        }
 }
 
        }
 }
 
+// A mixin just for changesListWrapperWidget page, to output the scope of the widget
+// so it is before the rest of the rule; we need the li& to be in
+// between the wrapper scope and the color-cX class, which doesn't
+// work if the rules are inside the above widget LESS scope
+.highlight-changesListWrapperWidget( @bgcolor ) {
+       .mw-rcfilters-ui-changesListWrapperWidget li&,
+               .mw-rcfilters-ui-changesListWrapperWidget & tr:first-child,
+               .mw-rcfilters-ui-changesListWrapperWidget tr&.mw-rcfilters-ui-changesListWrapperWidget-enhanced-toplevel:not(.mw-rcfilters-ui-changesListWrapperWidget-enhanced-grey) td:not( :nth-child( -n+2 ) ),
+               .mw-rcfilters-ui-changesListWrapperWidget tr&.mw-rcfilters-ui-changesListWrapperWidget-enhanced-nested:not(.mw-rcfilters-ui-changesListWrapperWidget-enhanced-grey) td:not( :nth-child( -n+3 ) ) {
+               background-color: @bgcolor;
+       }
+}
+
 // This mixin produces color mixes for two, three and four colors
 .highlight-color-mix( @color1, @color2, @color3: false, @color4: false ) {
        @highlight-color-class-var: ~'.mw-rcfilters-highlight-color-@{color1}.mw-rcfilters-highlight-color-@{color2}';
 
        // Two colors
        @{highlight-color-class-var} when ( @color3 = false ) and ( @color4 = false ) and not ( @color1 = false ), ( @color2 = false ) {
-               background-color: tint( average( @@c1var, @@c2var ), 50% );
+               .highlight-changesListWrapperWidget( tint( average( @@c1var, @@c2var ), 50% ) );
        }
        // Three colors
        @{highlight-color-class-var}.mw-rcfilters-highlight-color-@{color3} when ( @color4 = false ) and not ( @color3 = false ) {
                @c3var: ~'highlight-@{color3}';
-               background-color: tint( mix( @@c1var, average( @@c2var, @@c3var ), 33% ), 30% );
+               .highlight-changesListWrapperWidget( tint( mix( @@c1var, average( @@c2var, @@c3var ), 33% ), 30% ) );
        }
 
        // Four colors
        @{highlight-color-class-var}.mw-rcfilters-highlight-color-@{color3}.mw-rcfilters-highlight-color-@{color4} when not ( @color4 = false ) {
                @c3var: ~'highlight-@{color3}';
                @c4var: ~'highlight-@{color4}';
-               background-color: tint( mix( @@c1var, mix( @@c2var, average( @@c3var, @@c4var ), 25% ), 25% ), 25% );
+               .highlight-changesListWrapperWidget( tint( mix( @@c1var, mix( @@c2var, average( @@c3var, @@c4var ), 25% ), 25% ), 25% ) );
        }
 }
diff --git a/resources/src/mediawiki.rcfilters/styles/mw.rcfilters.ui.ChangesListWrapperWidget.highlightCircles.seenunseen.less b/resources/src/mediawiki.rcfilters/styles/mw.rcfilters.ui.ChangesListWrapperWidget.highlightCircles.seenunseen.less
new file mode 100644 (file)
index 0000000..f4ca717
--- /dev/null
@@ -0,0 +1,66 @@
+@import 'mw.rcfilters.mixins';
+
+.mw-rcfilters-ui-changesListWrapperWidget {
+       ul {
+               list-style: none;
+
+               li {
+                       list-style: none;
+               }
+       }
+
+       // Make more specific for the overrides
+       div&-highlights {
+               display: inline-block;
+
+               &-color {
+                       &-none {
+                               display: inline-block;
+                               li.mw-changeslist-watchedseen & {
+                                       .mw-rcfilters-ui-changesListWrapperWidget.mw-rcfilters-ui-changesListWrapperWidget-highlighted & {
+                                               .mw-rcfilters-mixin-circle( @highlight-none, @result-circle-diameter, 0, true, @highlight-grey, true );
+                                       }
+
+                                       .mw-rcfilters-ui-changesListWrapperWidget:not(.mw-rcfilters-ui-changesListWrapperWidget-highlighted) & {
+                                               .mw-rcfilters-mixin-circle( @highlight-none, @result-circle-diameter, 0, true, @highlight-bluedot, true );
+                                       }
+                               }
+
+                               li.mw-changeslist-watchedunseen & {
+                                       .mw-rcfilters-ui-changesListWrapperWidget.mw-rcfilters-ui-changesListWrapperWidget-highlighted & {
+                                               .mw-rcfilters-mixin-circle( @highlight-grey, @result-circle-diameter, 0, true, @highlight-grey );
+                                       }
+
+                                       .mw-rcfilters-ui-changesListWrapperWidget:not(.mw-rcfilters-ui-changesListWrapperWidget-highlighted) & {
+                                               .mw-rcfilters-mixin-circle( @highlight-bluedot, @result-circle-diameter, 0, true, @highlight-bluedot );
+                                       }
+                               }
+
+                       }
+
+                       // Watchlist unseen highlighted fixes
+                       // Seen (empty circle)
+                       // There's no need to correct 'unseen' because that would be
+                       // a filled colorful circle, which is the regular rendering
+                       .mw-changeslist-watchedseen &-c1 {
+                               .mw-rcfilters-mixin-circle( @highlight-c1, @result-circle-diameter, 0, true, @highlight-c1, true );
+                       }
+
+                       .mw-changeslist-watchedseen &-c2 {
+                               .mw-rcfilters-mixin-circle( @highlight-c2, @result-circle-diameter, 0, true, @highlight-c2, true );
+                       }
+
+                       .mw-changeslist-watchedseen &-c3 {
+                               .mw-rcfilters-mixin-circle( @highlight-c3, @result-circle-diameter, 0, true, @highlight-c3, true );
+                       }
+
+                       .mw-changeslist-watchedseen &-c4 {
+                               .mw-rcfilters-mixin-circle( @highlight-c4, @result-circle-diameter, 0, true, @highlight-c4, true );
+                       }
+
+                       .mw-changeslist-watchedseen &-c5 {
+                               .mw-rcfilters-mixin-circle( @highlight-c5, @result-circle-diameter, 0, true, @highlight-c5, true );
+                       }
+               }
+       }
+}
index dc7afab..5ef60e0 100644 (file)
                }
        }
 
+       // Rule needs to be specific
+       // We want the expand button to appear outside the color
+       // to match the way the general highlight background appears
+       &-enhanced-grey td:not( :nth-child( -n+2 ) ) {
+               background-color: #dee0e3;
+       }
+
        h4:first-of-type {
                margin-top: 0;
                padding-top: 0;
                // and then plus the general margin
                width: ~'calc( ( @{result-circle-diameter} + @{result-circle-margin} ) * 5 )';
                // And we want to shift the entire block to the left of the li
-               position: absolute;
-               left: 0;
+               position: relative;
+               // Negative left margin of width + padding
+               margin-left: ~'calc( ( @{result-circle-diameter} + @{result-circle-margin} ) * -5 - @{result-circle-general-margin} )';
 
                .mw-rcfilters-ui-changesListWrapperWidget-highlighted & {
                        display: inline-block;
                }
 
-               div {
+               // This needs to be very specific, since these are
+               // position rules that should apply to all overrides
+               .mw-rcfilters-ui-changesListWrapperWidget .mw-rcfilters-ui-changesListWrapperWidget-highlights > div&-circle {
                        .box-sizing( border-box );
                        margin-right: @result-circle-margin;
                        vertical-align: middle;
                        .result-circle( c5 );
                }
        }
+}
 
-       // One color
-       .mw-rcfilters-highlight-color-c1 {
-               background-color: tint( @highlight-c1, 70% );
-       }
+// One color
+.mw-rcfilters-highlight-color-c1 {
+       .highlight-changesListWrapperWidget( tint( @highlight-c1, 70% ); );
+}
 
-       .mw-rcfilters-highlight-color-c2 {
-               background-color: tint( @highlight-c2, 70% );
-       }
+.mw-rcfilters-highlight-color-c2 {
+       .highlight-changesListWrapperWidget( tint( @highlight-c2, 70% ); );
+}
 
-       .mw-rcfilters-highlight-color-c3 {
-               background-color: tint( @highlight-c3, 70% );
-       }
+.mw-rcfilters-highlight-color-c3 {
+       .highlight-changesListWrapperWidget( tint( @highlight-c3, 70% ); );
+}
 
-       .mw-rcfilters-highlight-color-c4 {
-               background-color: tint( @highlight-c4, 70% );
-       }
+.mw-rcfilters-highlight-color-c4 {
+       .highlight-changesListWrapperWidget( tint( @highlight-c4, 70% ); );
+}
 
-       .mw-rcfilters-highlight-color-c5 {
-               background-color: tint( @highlight-c5, 70% );
-       }
+.mw-rcfilters-highlight-color-c5 {
+       .highlight-changesListWrapperWidget( tint( @highlight-c5, 70% ); );
+}
 
-       // Two colors
-       .highlight-color-mix( c1, c2 );
-       // Overriding .highlight-color-mix( c1, c3 ); to produce
-       // a custom color rather than the computed tint
-       // see https://phabricator.wikimedia.org/T161267
-       .mw-rcfilters-highlight-color-c1.mw-rcfilters-highlight-color-c3 {
-               background-color: #ccdecc;
-       }
-       .highlight-color-mix( c1, c4 );
-       .highlight-color-mix( c1, c5 );
-       .highlight-color-mix( c2, c3 );
-       .highlight-color-mix( c2, c4 );
-       .highlight-color-mix( c2, c5 );
-       .highlight-color-mix( c3, c4 );
-       .highlight-color-mix( c3, c5 );
-       .highlight-color-mix( c4, c5 );
-
-       // Three colors
-       .highlight-color-mix( c1, c2, c3 );
-       .highlight-color-mix( c1, c2, c5 );
-       .highlight-color-mix( c1, c2, c4 );
-       .highlight-color-mix( c1, c3, c4 );
-       .highlight-color-mix( c1, c3, c5 );
-       .highlight-color-mix( c1, c4, c5 );
-       .highlight-color-mix( c2, c3, c4 );
-       .highlight-color-mix( c2, c3, c5 );
-       .highlight-color-mix( c2, c4, c5 );
-       .highlight-color-mix( c3, c4, c5 );
-
-       // Four colors
-       .highlight-color-mix( c1, c2, c3, c4 );
-       .highlight-color-mix( c1, c2, c3, c5 );
-       .highlight-color-mix( c1, c2, c4, c5 );
-       .highlight-color-mix( c1, c3, c4, c5 );
-       .highlight-color-mix( c2, c3, c4, c5 );
-
-       // Five colors:
-       .mw-rcfilters-highlight-color-c1.mw-rcfilters-highlight-color-c2.mw-rcfilters-highlight-color-c3.mw-rcfilters-highlight-color-c4.mw-rcfilters-highlight-color-c5 {
-               background-color: tint( mix( @highlight-c1, mix( @highlight-c2, mix( @highlight-c3, average( @highlight-c4, @highlight-c5 ), 20% ), 20% ), 20% ), 15% );
-       }
+// Two colors
+.highlight-color-mix( c1, c2 );
+// Overriding .highlight-color-mix( c1, c3 ); to produce
+// a custom color rather than the computed tint
+// see https://phabricator.wikimedia.org/T161267
+.mw-rcfilters-highlight-color-c1.mw-rcfilters-highlight-color-c3 {
+       .highlight-changesListWrapperWidget( #ccdecc );
+}
+.highlight-color-mix( c1, c4 );
+.highlight-color-mix( c1, c5 );
+.highlight-color-mix( c2, c3 );
+.highlight-color-mix( c2, c4 );
+.highlight-color-mix( c2, c5 );
+.highlight-color-mix( c3, c4 );
+.highlight-color-mix( c3, c5 );
+.highlight-color-mix( c4, c5 );
+
+// Three colors
+.highlight-color-mix( c1, c2, c3 );
+.highlight-color-mix( c1, c2, c5 );
+.highlight-color-mix( c1, c2, c4 );
+.highlight-color-mix( c1, c3, c4 );
+.highlight-color-mix( c1, c3, c5 );
+.highlight-color-mix( c1, c4, c5 );
+.highlight-color-mix( c2, c3, c4 );
+.highlight-color-mix( c2, c3, c5 );
+.highlight-color-mix( c2, c4, c5 );
+.highlight-color-mix( c3, c4, c5 );
+
+// Four colors
+.highlight-color-mix( c1, c2, c3, c4 );
+.highlight-color-mix( c1, c2, c3, c5 );
+.highlight-color-mix( c1, c2, c4, c5 );
+.highlight-color-mix( c1, c3, c4, c5 );
+.highlight-color-mix( c2, c3, c4, c5 );
+
+// Five colors:
+.mw-rcfilters-highlight-color-c1.mw-rcfilters-highlight-color-c2.mw-rcfilters-highlight-color-c3.mw-rcfilters-highlight-color-c4.mw-rcfilters-highlight-color-c5 {
+       .highlight-changesListWrapperWidget( tint( mix( @highlight-c1, mix( @highlight-c2, mix( @highlight-c3, average( @highlight-c4, @highlight-c5 ), 20% ), 20% ), 20% ), 15% ) );
 }
index a89b69c..bbd2c74 100644 (file)
@@ -7,17 +7,6 @@
                margin-top: 1em;
        }
 
-       &-top {
-               &-placeholder {
-                       width: 100%;
-               }
-
-               &-savedLinks {
-                       padding-left: 1em;
-                       vertical-align: bottom;
-               }
-       }
-
        &-bottom {
                margin-top: 1em;
 
diff --git a/resources/src/mediawiki.rcfilters/styles/mw.rcfilters.ui.RcTopSectionWidget.less b/resources/src/mediawiki.rcfilters/styles/mw.rcfilters.ui.RcTopSectionWidget.less
new file mode 100644 (file)
index 0000000..9d1cc23
--- /dev/null
@@ -0,0 +1,44 @@
+.mw-rcfilters-ui-rcTopSectionWidget {
+       &-topLinks {
+               &-table {
+                       width: 100%;
+               }
+
+               &-top {
+                       display: block;
+                       width: 100%;
+
+                       .mw-recentchanges-toplinks {
+                               margin-bottom: 0.5em;
+                       }
+               }
+       }
+
+       &-savedLinks {
+               vertical-align: bottom;
+               padding-left: 1em;
+       }
+
+       .mw-recentchanges-toplinks {
+               padding: 0 0.5em;
+
+               .oo-ui-widget-enabled.oo-ui-buttonElement.oo-ui-buttonElement-frameless .oo-ui-buttonElement-button {
+                       padding: 0 2.5em 0 0.5em;
+               }
+
+               &-title,
+               .mw-collapsible-text {
+                       // Same as the legend
+                       font-size: 0.85em;
+               }
+
+               &:not( .mw-collapsed ) {
+                       // Same as the legend
+                       border: 1px solid #ddd;
+               }
+
+               &:not( .mw-rcfilters-ui-ready ) {
+                       display: none;
+               }
+       }
+}
index e7433e2..9dccc24 100644 (file)
@@ -12,7 +12,7 @@
                vertical-align: middle;
        }
 
-       .oo-ui-iconElement-icon {
+       .mw-rcfilters-ui-savedLinksListItemWidget-icon .oo-ui-iconElement-icon {
                // Since we made the rows narrower (height smaller than usual)
                // then the icon needs to be slightly smaller as well, so that
                // when we toggle 'default' the icon doesn't bounce the option
diff --git a/resources/src/mediawiki.rcfilters/styles/mw.rcfilters.ui.WatchlistTopSectionWidget.less b/resources/src/mediawiki.rcfilters/styles/mw.rcfilters.ui.WatchlistTopSectionWidget.less
new file mode 100644 (file)
index 0000000..5e1e118
--- /dev/null
@@ -0,0 +1,27 @@
+.mw-rcfilters-ui-watchlistTopSectionWidget {
+       &-watchlistDetails {
+               width: 100%;
+       }
+
+       &-editWatchlistButton {
+               vertical-align: bottom;
+
+               // actual button
+               .oo-ui-buttonWidget {
+                       margin-left: 3em;
+               }
+       }
+
+       &-savedLinks {
+               float: right;
+       }
+
+       .mw-rcfilters-ui-table {
+               margin-top: 1em;
+       }
+
+       &-separator {
+               margin-top: 1em;
+               border-top: 2px solid #eaecf0; // Base80 AAA
+       }
+}
index 0bee2f1..f7081af 100644 (file)
@@ -2,6 +2,10 @@
        &-table {
                display: table;
                width: 100%;
+
+               &-placeholder {
+                       width: 100%;
+               }
        }
 
        &-row {
index 3060f25..fc8c9ef 100644 (file)
@@ -5,6 +5,8 @@
 @highlight-c3: #fc3;
 @highlight-c4: #ff6d22;
 @highlight-c5: #d33;
+@highlight-bluedot: #1d4aad; // Simulates the 'known' browser <li> blue dot
+@highlight-grey: #54595d; // The color of full dots on Watchlist when highlight is enabled
 
 // Muted state
 @muted-opacity: 0.5;
index a97ffe9..f331f75 100644 (file)
                this.filtersViewModel = filtersViewModel;
                this.changesListViewModel = changesListViewModel;
                this.controller = controller;
+               this.highlightClasses = null;
+               this.filtersModelInitialized = false;
 
                // Events
                this.filtersViewModel.connect( this, {
                        itemUpdate: 'onItemUpdate',
-                       highlightChange: 'onHighlightChange'
+                       highlightChange: 'onHighlightChange',
+                       initialize: 'onFiltersModelInitialize'
                } );
                this.changesListViewModel.connect( this, {
                        invalidate: 'onModelInvalidate',
@@ -45,9 +48,6 @@
                        // We handle our own display/hide of the empty results message
                        .removeClass( 'mw-changeslist-empty' );
 
-               // Set up highlight containers
-               this.setupHighlightContainers( this.$element );
-
                this.setupNewChangesButtonContainer( this.$element );
        };
 
 
        OO.inheritClass( mw.rcfilters.ui.ChangesListWrapperWidget, OO.ui.Widget );
 
+       /**
+        * Respond to filters model initialize event
+        */
+       mw.rcfilters.ui.ChangesListWrapperWidget.prototype.onFiltersModelInitialize = function () {
+               this.filtersModelInitialized = true;
+               // Set up highlight containers. We need to wait for the filters model
+               // to be initialized, so we can make sure we have all the css class definitions
+               // we get from the server with our filters
+               this.setupHighlightContainers( this.$element );
+       };
+
+       /**
+        * Get all available highlight classes
+        *
+        * @return {string[]} An array of available highlight class names
+        */
+       mw.rcfilters.ui.ChangesListWrapperWidget.prototype.getHighlightClasses = function () {
+               if ( !this.highlightClasses || !this.highlightClasses.length ) {
+                       this.highlightClasses = this.filtersViewModel.getItemsSupportingHighlights()
+                               .map( function ( filterItem ) {
+                                       return filterItem.getCssClass();
+                               } );
+               }
+
+               return this.highlightClasses;
+       };
+
        /**
         * Respond to the highlight feature being toggled on and off
         *
@@ -72,7 +99,7 @@
         * Respond to a filter item model update
         */
        mw.rcfilters.ui.ChangesListWrapperWidget.prototype.onItemUpdate = function () {
-               if ( this.filtersViewModel.isHighlightEnabled() ) {
+               if ( this.filtersModelInitialized && this.filtersViewModel.isHighlightEnabled() ) {
                        this.clearHighlight();
                        this.applyHighlight();
                }
         * @param {jQuery|string} $content The content of the updated changes list
         */
        mw.rcfilters.ui.ChangesListWrapperWidget.prototype.setupHighlightContainers = function ( $content ) {
-               var highlightClass = 'mw-rcfilters-ui-changesListWrapperWidget-highlights',
+               var $enhancedTopPageCell, $enhancedNestedPagesCell,
+                       widget = this,
+                       highlightClass = 'mw-rcfilters-ui-changesListWrapperWidget-highlights',
                        $highlights = $( '<div>' )
                                .addClass( highlightClass )
                                .append(
                                        $( '<div>' )
+                                               .addClass( 'mw-rcfilters-ui-changesListWrapperWidget-highlights-circle' )
                                                .addClass( 'mw-rcfilters-ui-changesListWrapperWidget-highlights-color-none' )
                                                .prop( 'data-color', 'none' )
                                );
                        $highlights.append(
                                $( '<div>' )
                                        .addClass( 'mw-rcfilters-ui-changesListWrapperWidget-highlights-color-' + color )
+                                       .addClass( 'mw-rcfilters-ui-changesListWrapperWidget-highlights-circle' )
                                        .prop( 'data-color', color )
                        );
                } );
 
                if ( this.inEnhancedMode() ) {
-                       // Enhanced RC
-                       $content.find( 'td.mw-enhanced-rc' )
-                               .parent()
+                       $enhancedTopPageCell = $content.find( 'table.mw-enhanced-rc.mw-collapsible' );
+                       $enhancedNestedPagesCell = $content.find( 'td.mw-enhanced-rc-nested' );
+
+                       // Enhanced RC highlight containers
+                       $content.find( 'table.mw-enhanced-rc tr:first-child' )
+                               .addClass( 'mw-rcfilters-ui-changesListWrapperWidget-enhanced-toplevel' )
                                .prepend(
                                        $( '<td>' )
                                                .append( $highlights.clone() )
                                );
+
+                       // We are adding and changing cells in a table that, despite having nested rows,
+                       // is actually all one big table. To do that right, we want to remove the 'placeholder'
+                       // cell from the top row, because we're actually adding that placeholder in the children
+                       // with the highlights.
+                       $content.find( 'table.mw-enhanced-rc tr:first-child td.mw-changeslist-line-prefix' )
+                               .detach();
+                       $content.find( 'table.mw-enhanced-rc tr:first-child td.mw-enhanced-rc' )
+                               .prop( 'colspan', '2' );
+
+                       $enhancedNestedPagesCell
+                               .before(
+                                       $( '<td>' )
+                                               .append( $highlights.clone().addClass( 'mw-enhanced-rc-nested' ) )
+                               );
+
+                       // We need to target the nested rows differently than the top rows so that the
+                       // LESS rules applies correctly. In top rows, the rule should highlight all but
+                       // the first 2 cells td:not( :nth-child( -n+2 ) and the nested rows, the rule
+                       // should highlight all but the first 3 cells td:not( :nth-child( -n+3 )
+                       $enhancedNestedPagesCell
+                               .closest( 'tr' )
+                               .addClass( 'mw-rcfilters-ui-changesListWrapperWidget-enhanced-nested' );
+
+                       // Go over pages that have sub results
+                       // HACK: We really only can collect those by targetting the collapsible class
+                       $enhancedTopPageCell.each( function () {
+                               var collectedClasses,
+                                       $table = $( this );
+
+                               // Go over <tr>s and pick up all recognized classes
+                               collectedClasses = widget.getHighlightClasses().filter( function ( className ) {
+                                       return $table.find( 'tr' ).hasClass( className );
+                               } );
+
+                               $table.find( 'tr:first-child' )
+                                       .addClass( collectedClasses.join( ' ' ) );
+                       } );
+
+                       $content.addClass( 'mw-rcfilters-ui-changesListWrapperWidget-enhancedView' );
                } else {
                        // Regular RC
                        $content.find( 'ul.special li' )
                }
        };
 
+       /**
+        * In enhanced mode, we need to check whether the grouped results all have the
+        * same active highlights in order to see whether the "parent" of the group should
+        * be grey or highlighted normally.
+        *
+        * This is called every time highlights are applied.
+        */
+       mw.rcfilters.ui.ChangesListWrapperWidget.prototype.updateEnhancedParentHighlight = function () {
+               var activeHighlightClasses,
+                       $enhancedTopPageCell = this.$element.find( 'table.mw-enhanced-rc.mw-collapsible' );
+
+               activeHighlightClasses = this.filtersViewModel.getCurrentlyUsedHighlightColors().map( function ( color ) {
+                       return 'mw-rcfilters-highlight-color-' + color;
+               } );
+
+               // Go over top pages and their children, and figure out if all sub-pages have the
+               // same highlights between themselves. If they do, the parent should be highlighted
+               // with all colors. If classes are different, the parent should receive a grey
+               // background
+               $enhancedTopPageCell.each( function () {
+                       var firstChildClasses, $rowsWithDifferentHighlights,
+                               $table = $( this );
+
+                       // Collect the relevant classes from the first nested child
+                       firstChildClasses = activeHighlightClasses.filter( function ( className ) {
+                               return $table.find( 'tr:nth-child(2)' ).hasClass( className );
+                       } );
+                       // Filter the non-head rows and see if they all have the same classes
+                       // to the first row
+                       $rowsWithDifferentHighlights = $table.find( 'tr:not(:first-child)' ).filter( function () {
+                               var classesInThisRow,
+                                       $this = $( this );
+
+                               classesInThisRow = activeHighlightClasses.filter( function ( className ) {
+                                       return $this.hasClass( className );
+                               } );
+
+                               return !OO.compare( firstChildClasses, classesInThisRow );
+                       } );
+
+                       // If classes are different, tag the row for using grey color
+                       $table.find( 'tr:first-child' )
+                               .toggleClass( 'mw-rcfilters-ui-changesListWrapperWidget-enhanced-grey', $rowsWithDifferentHighlights.length > 0 );
+               } );
+       };
+
        /**
         * @return {boolean} Whether the changes are grouped by page
         */
                        }
                } );
 
+               if ( this.inEnhancedMode() ) {
+                       this.updateEnhancedParentHighlight();
+               }
+
                // Turn on highlights
                this.$element.addClass( 'mw-rcfilters-ui-changesListWrapperWidget-highlighted' );
        };
                this.$element.find( '[data-highlightedFilters]' )
                        .removeAttr( 'title' )
                        .removeAttr( 'data-highlightedFilters' );
+
+               // Remove grey from enhanced rows
+               this.$element.find( '.mw-rcfilters-ui-changesListWrapperWidget-enhanced-grey' )
+                       .removeClass( 'mw-rcfilters-ui-changesListWrapperWidget-enhanced-grey' );
+
                // Turn off highlights
                this.$element.removeClass( 'mw-rcfilters-ui-changesListWrapperWidget-highlighted' );
        };
index b57f5d7..db7acaa 100644 (file)
@@ -17,7 +17,7 @@
        mw.rcfilters.ui.FilterWrapperWidget = function MwRcfiltersUiFilterWrapperWidget(
                controller, model, savedQueriesModel, changesListModel, config
        ) {
-               var $top, $bottom;
+               var $bottom;
                config = config || {};
 
                // Parent
                );
 
                // Initialize
-               this.$topRow = $( '<div>' )
-                       .addClass( 'mw-rcfilters-ui-row' )
-                       .append(
-                               $( '<div>' )
-                                       .addClass( 'mw-rcfilters-ui-cell' )
-                                       .addClass( 'mw-rcfilters-ui-filterWrapperWidget-top-placeholder' )
-                       );
-               $top = $( '<div>' )
-                       .addClass( 'mw-rcfilters-ui-filterWrapperWidget-top' )
-                       .addClass( 'mw-rcfilters-ui-table' )
-                       .append( this.$topRow );
+               this.$top = $( '<div>' )
+                       .addClass( 'mw-rcfilters-ui-filterWrapperWidget-top' );
 
                $bottom = $( '<div>' )
                        .addClass( 'mw-rcfilters-ui-filterWrapperWidget-bottom' )
                                this.dateWidget.$element
                        );
 
-               if ( !mw.user.isAnon() ) {
-                       this.savedLinksListWidget = new mw.rcfilters.ui.SavedLinksListWidget(
-                               this.controller,
-                               this.queriesModel,
-                               { $overlay: this.$overlay }
-                       );
-
-                       this.$topRow.append(
-                               $( '<div>' )
-                                       .addClass( 'mw-rcfilters-ui-cell' )
-                                       .addClass( 'mw-rcfilters-ui-filterWrapperWidget-top-savedLinks' )
-                                       .append( this.savedLinksListWidget.$element )
-                       );
-               }
-
                if ( mw.rcfilters.featureFlags.liveUpdate ) {
                        $bottom.append( this.liveUpdateButton.$element );
                }
                this.$element
                        .addClass( 'mw-rcfilters-ui-filterWrapperWidget' )
                        .append(
-                               $top,
+                               this.$top,
                                this.filterTagWidget.$element,
                                $bottom
                        );
        /* Methods */
 
        /**
-        * Add a widget at the beginning of the top row
+        * Set the content of the top section
         *
-        * @param {OO.ui.Widget} widget Any widget
+        * @param {jQuery} $topSectionElement
         */
-       mw.rcfilters.ui.FilterWrapperWidget.prototype.prependToTopRow = function ( widget ) {
-               this.$topRow.prepend(
-                       widget.$element
-                               .addClass( 'mw-rcfilters-ui-cell' )
-               );
+       mw.rcfilters.ui.FilterWrapperWidget.prototype.setTopSection = function ( $topSectionElement ) {
+               this.$top.append( $topSectionElement );
        };
-
 }( mediaWiki ) );
index ad99e22..cfcdf35 100644 (file)
                        this.$element.find( 'hr' ).detach();
                }
 
+               // Get rid of all <br>s, which are inside rcshowhide
+               // If we still have content in rcshowhide, the <br>s are
+               // gone. Instead, the CSS now has a rule to mark all <span>s
+               // inside .rcshowhide with display:block; to simulate newlines
+               // where they're actually needed.
+               this.$element.find( 'br' ).detach();
                if ( !this.$element.find( '.rcshowhide' ).contents().length ) {
                        this.$element.find( '.rcshowhide' ).detach();
-                       // If we're hiding rcshowhide, the '<br>'s are around it,
-                       // there's no need for them either.
-                       this.$element.find( 'br' ).detach();
                }
 
                if ( this.$element.find( '.cloption' ).text().trim() === '' ) {
                        '.rclistfrom, .rcnotefrom, .rcoptions-listfromreset'
                ).detach();
 
-               if ( this.$element.text().trim() === this.$element.find( 'legend' ).text() ) {
+               // Get rid of the legend
+               this.$element.find( 'legend' ).detach();
+
+               // Check if the element is essentially empty, and detach it if it is
+               if ( !this.$element.text().trim().length ) {
                        this.$element.detach();
                }
        };
index 073cd1e..56fe5b9 100644 (file)
@@ -14,7 +14,7 @@
 
                // Parent
                mw.rcfilters.ui.MarkSeenButtonWidget.parent.call( this, $.extend( {
-                       label: mw.message( 'rcfilters-watchlist-markSeen-button' ).text(),
+                       label: mw.message( 'rcfilters-watchlist-markseen-button' ).text(),
                        icon: 'doubleCheck'
                }, config ) );
 
diff --git a/resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.RcTopSectionWidget.js b/resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.RcTopSectionWidget.js
new file mode 100644 (file)
index 0000000..f0e1241
--- /dev/null
@@ -0,0 +1,110 @@
+( function ( mw ) {
+       /**
+        * Top section (between page title and filters) on Special:Recentchanges
+        *
+        * @extends OO.ui.Widget
+        *
+        * @constructor
+        * @param {mw.rcfilters.ui.SavedLinksListWidget} savedLinksListWidget
+        * @param {jQuery} $topLinks Content of the community-defined links
+        * @param {Object} [config] Configuration object
+        */
+       mw.rcfilters.ui.RcTopSectionWidget = function MwRcfiltersUiRcTopSectionWidget(
+               savedLinksListWidget, $topLinks, config
+       ) {
+               var toplinksTitle,
+                       topLinksCookieName = 'rcfilters-toplinks-collapsed-state',
+                       topLinksCookie = mw.cookie.get( topLinksCookieName ),
+                       topLinksCookieValue = topLinksCookie || 'collapsed',
+                       widget = this;
+
+               config = config || {};
+
+               // Parent
+               mw.rcfilters.ui.RcTopSectionWidget.parent.call( this, config );
+
+               this.$topLinks = $topLinks;
+
+               toplinksTitle = new OO.ui.ButtonWidget( {
+                       framed: false,
+                       indicator: topLinksCookieValue === 'collapsed' ? 'down' : 'up',
+                       flags: [ 'progressive' ],
+                       label: $( '<span>' ).append( mw.message( 'rcfilters-other-review-tools' ).parse() ).contents()
+               } );
+
+               this.$topLinks
+                       .addClass( 'mw-rcfilters-ui-ready' )
+                       .makeCollapsible( {
+                               collapsed: topLinksCookieValue === 'collapsed',
+                               $customTogglers: toplinksTitle.$element
+                       } )
+                       .on( 'beforeExpand.mw-collapsible', function () {
+                               mw.cookie.set( topLinksCookieName, 'expanded' );
+                               toplinksTitle.setIndicator( 'up' );
+                               widget.switchTopLinks( 'expanded' );
+                       } )
+                       .on( 'beforeCollapse.mw-collapsible', function () {
+                               mw.cookie.set( topLinksCookieName, 'collapsed' );
+                               toplinksTitle.setIndicator( 'down' );
+                               widget.switchTopLinks( 'collapsed' );
+                       } );
+
+               this.$topLinks.find( '.mw-recentchanges-toplinks-title' ).replaceWith( toplinksTitle.$element );
+
+               // Create two positions for the toplinks to toggle between
+               // in the table (first cell) or up above it
+               this.$top = $( '<div>' )
+                       .addClass( 'mw-rcfilters-ui-rcTopSectionWidget-topLinks-top' );
+               this.$tableTopLinks = $( '<div>' )
+                       .addClass( 'mw-rcfilters-ui-cell' )
+                       .addClass( 'mw-rcfilters-ui-rcTopSectionWidget-topLinks-table' );
+
+               // Initialize
+               this.$element
+                       .addClass( 'mw-rcfilters-ui-rcTopSectionWidget' )
+                       .append(
+                               this.$top,
+                               $( '<div>' )
+                                       .addClass( 'mw-rcfilters-ui-table' )
+                                       .append(
+                                               $( '<div>' )
+                                                       .addClass( 'mw-rcfilters-ui-row' )
+                                                       .append(
+                                                               this.$tableTopLinks,
+                                                               $( '<div>' )
+                                                                       .addClass( 'mw-rcfilters-ui-table-placeholder' )
+                                                                       .addClass( 'mw-rcfilters-ui-cell' ),
+                                                               !mw.user.isAnon() ?
+                                                                       $( '<div>' )
+                                                                               .addClass( 'mw-rcfilters-ui-cell' )
+                                                                               .addClass( 'mw-rcfilters-ui-rcTopSectionWidget-savedLinks' )
+                                                                               .append( savedLinksListWidget.$element ) :
+                                                                       null
+                                                       )
+                                       )
+                       );
+
+               // Initialize top links position
+               widget.switchTopLinks( topLinksCookieValue );
+       };
+
+       /* Initialization */
+
+       OO.inheritClass( mw.rcfilters.ui.RcTopSectionWidget, OO.ui.Widget );
+
+       /**
+        * Switch the top links widget from inside the table (when collapsed)
+        * to the 'top' (when open)
+        *
+        * @param {string} [state] The state of the top links widget: 'expanded' or 'collapsed'
+        */
+       mw.rcfilters.ui.RcTopSectionWidget.prototype.switchTopLinks = function ( state ) {
+               state = state || 'expanded';
+
+               if ( state === 'expanded' ) {
+                       this.$top.append( this.$topLinks );
+               } else {
+                       this.$tableTopLinks.append( this.$topLinks );
+               }
+       };
+}( mediaWiki ) );
diff --git a/resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.WatchlistTopSectionWidget.js b/resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.WatchlistTopSectionWidget.js
new file mode 100644 (file)
index 0000000..7d78565
--- /dev/null
@@ -0,0 +1,82 @@
+( function ( mw ) {
+       /**
+        * Top section (between page title and filters) on Special:Watchlist
+        *
+        * @extends OO.ui.Widget
+        *
+        * @constructor
+        * @param {mw.rcfilters.Controller} controller
+        * @param {mw.rcfilters.dm.ChangesListViewModel} changesListModel
+        * @param {mw.rcfilters.ui.SavedLinksListWidget} savedLinksListWidget
+        * @param {jQuery} $watchlistDetails Content of the 'details' section that includes watched pages count
+        * @param {Object} [config] Configuration object
+        */
+       mw.rcfilters.ui.WatchlistTopSectionWidget = function MwRcfiltersUiWatchlistTopSectionWidget(
+               controller, changesListModel, savedLinksListWidget, $watchlistDetails, config
+       ) {
+               var editWatchlistButton,
+                       markSeenButton,
+                       $topTable,
+                       $bottomTable,
+                       $separator;
+               config = config || {};
+
+               // Parent
+               mw.rcfilters.ui.WatchlistTopSectionWidget.parent.call( this, config );
+
+               editWatchlistButton = new OO.ui.ButtonWidget( {
+                       label: mw.msg( 'rcfilters-watchlist-edit-watchlist-button' ),
+                       icon: 'edit',
+                       href: mw.config.get( 'wgStructuredChangeFiltersEditWatchlistUrl' )
+               } );
+               markSeenButton = new mw.rcfilters.ui.MarkSeenButtonWidget( controller, changesListModel );
+
+               $topTable = $( '<div>' )
+                       .addClass( 'mw-rcfilters-ui-table' )
+                       .append(
+                               $( '<div>' )
+                                       .addClass( 'mw-rcfilters-ui-row' )
+                                       .append(
+                                               $( '<div>' )
+                                                       .addClass( 'mw-rcfilters-ui-cell' )
+                                                       .addClass( 'mw-rcfilters-ui-watchlistTopSectionWidget-watchlistDetails' )
+                                                       .append( $watchlistDetails )
+                                       )
+                                       .append(
+                                               $( '<div>' )
+                                                       .addClass( 'mw-rcfilters-ui-cell' )
+                                                       .addClass( 'mw-rcfilters-ui-watchlistTopSectionWidget-editWatchlistButton' )
+                                                       .append( editWatchlistButton.$element )
+                                       )
+                       );
+
+               $bottomTable = $( '<div>' )
+                       .addClass( 'mw-rcfilters-ui-table' )
+                       .append(
+                               $( '<div>' )
+                                       .addClass( 'mw-rcfilters-ui-row' )
+                                       .append(
+                                               $( '<div>' )
+                                                       .addClass( 'mw-rcfilters-ui-cell' )
+                                                       .append( markSeenButton.$element )
+                                       )
+                                       .append(
+                                               $( '<div>' )
+                                                       .addClass( 'mw-rcfilters-ui-cell' )
+                                                       .addClass( 'mw-rcfilters-ui-watchlistTopSectionWidget-savedLinks' )
+                                                       .append( savedLinksListWidget.$element )
+                                       )
+                       );
+
+               $separator = $( '<div>' )
+                       .addClass( 'mw-rcfilters-ui-watchlistTopSectionWidget-separator' );
+
+               this.$element
+                       .addClass( 'mw-rcfilters-ui-watchlistTopSectionWidget' )
+                       .append( $topTable, $separator, $bottomTable );
+       };
+
+       /* Initialization */
+
+       OO.inheritClass( mw.rcfilters.ui.WatchlistTopSectionWidget, OO.ui.Widget );
+}( mediaWiki ) );
index a991d36..0792762 100644 (file)
@@ -3,7 +3,7 @@
  */
 
 /* Remember the collapse state of the legend on recent changes and watchlist pages. */
-( function ( mw, $ ) {
+( function ( mw ) {
        var
                cookieName = 'changeslist-state',
                // Expanded by default
@@ -20,7 +20,5 @@
                                } );
                };
 
-       $( function () {
-               mw.hook( 'wikipage.content' ).add( doCollapsibleLegend );
-       } );
-}( mediaWiki, jQuery ) );
+       mw.hook( 'wikipage.content' ).add( doCollapsibleLegend );
+}( mediaWiki ) );
index 59464bd..8ec2735 100644 (file)
@@ -47,7 +47,6 @@
        }
        .iw-result__footer a {
                vertical-align: middle;
-               color: @colorGray7;
                font-style: italic;
        }
 
index 47ecfe4..640bbff 100644 (file)
@@ -1,7 +1,7 @@
 
 button_italic.png
 -------------------
-Source : http://commons.wikimedia.org/wiki/Image:Button_S_italic.png
+Source : https://commons.wikimedia.org/wiki/Image:Button_S_italic.png
 License: Public domain
-Author : Purodha Blissenbach, http://ksh.wikipedia.org/wiki/User:Purodha
+Author : Purodha Blissenbach, https://ksh.wikipedia.org/wiki/User:Purodha
 
index 2a47fa2..e0c3d5e 100644 (file)
@@ -16,7 +16,7 @@
 }
 
 .mw-widget-mediaResultWidget-error {
-       background-color: #f3f3f3;
+       background-color: #f8f9fa;
 }
 
 .mw-widget-mediaResultWidget-thumbnail {
        bottom: 0;
        left: 0;
        right: 0;
-       box-shadow: inset 0 0 0 1px #ccc;
+       box-shadow: inset 0 0 0 1px #c8ccd1;
 }
 
 .mw-widget-mediaResultWidget.oo-ui-optionWidget-highlighted,
 .mw-widget-mediaResultWidget.oo-ui-optionWidget-selected {
-       box-shadow: 0 0 0.3em #a7dcff, 0 0 0 #fff;
+       box-shadow: 0 0 2px #36c;
+}
+
+.mw-widget-mediaResultWidget.oo-ui-optionWidget-highlighted .mw-widget-mediaResultWidget-overlay,
+.mw-widget-mediaResultWidget.oo-ui-optionWidget-selected .mw-widget-mediaResultWidget-overlay {
+       box-shadow: inset 0 0 0 1px #36c;
 }
 
 .mw-widget-mediaResultWidget-error .mw-widget-mediaResultWidget-thumbnail {
index ea62075..8be1e86 100644 (file)
@@ -23,7 +23,7 @@
 .mw-widgets-stashedFileWidget-info {
        height: 2.4em;
        background-color: #fff;
-       border: 1px solid #ccc;
+       border: 1px solid #c8ccd1;
        border-radius: 2px;
        width: 100%;
        display: table-cell;
@@ -49,7 +49,7 @@
                        float: left;
                }
                > .mw-widgets-stashedFileWidget-fileType {
-                       color: #888;
+                       color: #72777d;
                        float: right;
                }
        }
 
        &.oo-ui-widget-disabled {
                .mw-widgets-stashedFileWidget-info {
-                       color: #ccc;
+                       background-color: #eaecf0;
+                       color: #72777d;
+                       border-color: #c8ccd1;
                        text-shadow: 0 1px 1px #fff;
-                       border-color: #ddd;
-                       background-color: #f3f3f3;
 
                        > .oo-ui-iconElement-icon,
                        > .oo-ui-indicatorElement-indicator {
-                               opacity: 0.2;
+                               opacity: 0.15;
                        }
                }
        }
@@ -93,7 +93,7 @@
        text-align: left;
        padding: 0;
        background-color: #fff;
-       border: 1px solid #ccc;
+       border: 1px solid #c8ccd1;
        margin-bottom: 0.5em;
        vertical-align: middle;
        overflow: hidden;
 
                > .mw-widgets-stashedFileWidget-noThumbnail-icon {
                        opacity: 0.4;
-                       background-color: #ccc;
+                       background-color: #c8ccd1;
                        height: 5.5em;
                        width: 5.5em;
                }
        }
 
        .mw-widgets-stashedFileWidget-label {
-               color: #ccc;
+               color: #c8ccd1;
                right: 0.5em;
        }
 
index 2ac5d45..deca71b 100644 (file)
@@ -11,7 +11,7 @@
                line-height: normal;
 
                &-description {
-                       color: #888;
+                       color: #72777d;
                }
        }
 
@@ -36,7 +36,7 @@
                                        height: 3.75em;
                                        left: 0;
                                        &:not( .mw-widget-titleOptionWidget-hasImage ) {
-                                               background-color: #ccc;
+                                               background-color: #c8ccd1;
                                                opacity: 0.4;
                                        }
                                        &.mw-widget-titleOptionWidget-hasImage {
index 97c3c05..0dab130 100644 (file)
@@ -182,13 +182,18 @@ class ParserTestRunner {
                        if ( !file_exists( $dir ) ) {
                                continue;
                        }
+                       $counter = 1;
                        $dirIterator = new RecursiveIteratorIterator(
                                new RecursiveDirectoryIterator( $dir )
                        );
                        foreach ( $dirIterator as $fileInfo ) {
                                /** @var SplFileInfo $fileInfo */
                                if ( substr( $fileInfo->getFilename(), -4 ) === '.txt' ) {
-                                       $files[] = $fileInfo->getPathname();
+                                       $name = $info['name'] . $counter;
+                                       while ( isset( $files[$name] ) ) {
+                                               $name = $info['name'] . '_' . $counter++;
+                                       }
+                                       $files[$name] = $fileInfo->getPathname();
                                }
                        }
                }
index 2fa3cb0..82d195a 100644 (file)
@@ -15807,26 +15807,6 @@ parsoid=wt2html
 <link rel="mw:PageProp/Category" href="./Category:Baz" data-parsoid='{"stx":"simple","a":{"href":"./Category:Baz"},"sa":{"href":"Category:Baz"}}'/>
 !! end
 
-!! test
-9. Categories and newlines: should behave properly with linkprefix (T87753)
-!! options
-language=ar
-!! wikitext
-foo bar
-foo bar
-[[تصنيف:Foo]]
-[[تصنيف:Bar]]
-!! html/php
-<p>foo bar
-foo bar
-</p>
-!! html/parsoid
-<p>foo bar
-foo bar</p>
-<link rel="mw:PageProp/Category" href="./تصنيف:Foo"/>
-<link rel="mw:PageProp/Category" href="./تصنيف:Bar"/>
-!! end
-
 !! test
 Category links with multiple namespaces
 !! wikitext
@@ -15874,20 +15854,6 @@ x[[Category:Foo]]y
 <p>x<link rel="mw:PageProp/Category" href="./Flokkur:Foo" data-parsoid=""/>y</p>
 !! end
 
-!! test
-Link prefix/suffixes aren't applied to language links
-!! options
-parsoid=wt2html
-language=is
-!! wikitext
-x[[es:Foo]]y
-!! html/php
-<p>xy
-</p>
-!! html/parsoid
-<p>x<link rel="mw:PageProp/Language" href="http://es.wikipedia.org/wiki/Foo" data-parsoid=""/>y</p>
-!! end
-
 !! test
 Parsoid: Serialize link to file page with colon escape
 !! options
@@ -28458,10 +28424,10 @@ wgFragmentMode=[ 'html5', 'legacy' ]
 
 <h2><span class="mw-headline" id="Foo_bar">Foo bar</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=1" title="Edit section: Foo bar">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
 <h2><span class="mw-headline" id="foo_Bar_2">foo Bar</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=2" title="Edit section: foo Bar">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
-<div id=".D0.A2.D0.B5.D1.81.D1.82"></div><h2><span class="mw-headline" id="Тест">Тест</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=3" title="Edit section: Тест">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
-<div id=".D0.A2.D0.B5.D1.81.D1.82_2"></div><h2><span class="mw-headline" id="Тест_2">Тест</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=4" title="Edit section: Тест">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
-<div id=".D1.82.D0.B5.D1.81.D1.82"></div><h2><span class="mw-headline" id="тест">тест</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=5" title="Edit section: тест">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
-<div id="Hey_.3C_.23_.22_.3E_.25_:_.27"></div><h2><span class="mw-headline" id="Hey_&lt;_#_&quot;_&gt;_%_:_'">Hey &lt; # " &gt;&#160;%&#160;: '</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=6" title="Edit section: Hey &lt; # &quot; &gt; % : '">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
+<h2><span id=".D0.A2.D0.B5.D1.81.D1.82"></span><span class="mw-headline" id="Тест">Тест</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=3" title="Edit section: Тест">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
+<h2><span id=".D0.A2.D0.B5.D1.81.D1.82_2"></span><span class="mw-headline" id="Тест_2">Тест</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=4" title="Edit section: Тест">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
+<h2><span id=".D1.82.D0.B5.D1.81.D1.82"></span><span class="mw-headline" id="тест">тест</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=5" title="Edit section: тест">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
+<h2><span id="Hey_.3C_.23_.22_.3E_.25_:_.27"></span><span class="mw-headline" id="Hey_&lt;_#_&quot;_&gt;_%_:_'">Hey &lt; # " &gt;&#160;%&#160;: '</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=6" title="Edit section: Hey &lt; # &quot; &gt; % : '">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
 <p><a href="#Foo_bar">#Foo bar</a> <a href="#foo_Bar">#foo Bar</a> <a href="#%D0%A2%D0%B5%D1%81%D1%82">#Тест</a> <a href="#%D1%82%D0%B5%D1%81%D1%82">#тест</a> <a href="#Hey_%3C_%23_%22_%3E_%25_:_%27">#Hey &lt; # " &gt;&#160;%&#160;: '</a>
 </p><p>%F0%9F%92%A9 <span id="%F0%9F%92%A9"></span>
 </p><p><a href="#%E5%95%A4%E9%85%92">#啤酒</a> <a href="#%E5%95%A4%E9%85%92">#啤酒</a>
@@ -28505,10 +28471,10 @@ wgFragmentMode=[ 'legacy', 'html5' ]
 
 <h2><span class="mw-headline" id="Foo_bar">Foo bar</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=1" title="Edit section: Foo bar">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
 <h2><span class="mw-headline" id="foo_Bar_2">foo Bar</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=2" title="Edit section: foo Bar">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
-<div id="Тест"></div><h2><span class="mw-headline" id=".D0.A2.D0.B5.D1.81.D1.82">Тест</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=3" title="Edit section: Тест">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
-<div id="Тест_2"></div><h2><span class="mw-headline" id=".D0.A2.D0.B5.D1.81.D1.82_2">Тест</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=4" title="Edit section: Тест">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
-<div id="тест"></div><h2><span class="mw-headline" id=".D1.82.D0.B5.D1.81.D1.82">тест</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=5" title="Edit section: тест">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
-<div id="Hey_&lt;_#_&quot;_&gt;_%_:_'"></div><h2><span class="mw-headline" id="Hey_.3C_.23_.22_.3E_.25_:_.27">Hey &lt; # " &gt;&#160;%&#160;: '</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=6" title="Edit section: Hey &lt; # &quot; &gt; % : '">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
+<h2><span id="Тест"></span><span class="mw-headline" id=".D0.A2.D0.B5.D1.81.D1.82">Тест</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=3" title="Edit section: Тест">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
+<h2><span id="Тест_2"></span><span class="mw-headline" id=".D0.A2.D0.B5.D1.81.D1.82_2">Тест</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=4" title="Edit section: Тест">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
+<h2><span id="тест"></span><span class="mw-headline" id=".D1.82.D0.B5.D1.81.D1.82">тест</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=5" title="Edit section: тест">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
+<h2><span id="Hey_&lt;_#_&quot;_&gt;_%_:_'"></span><span class="mw-headline" id="Hey_.3C_.23_.22_.3E_.25_:_.27">Hey &lt; # " &gt;&#160;%&#160;: '</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=6" title="Edit section: Hey &lt; # &quot; &gt; % : '">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
 <p><a href="#Foo_bar">#Foo bar</a> <a href="#foo_Bar">#foo Bar</a> <a href="#.D0.A2.D0.B5.D1.81.D1.82">#Тест</a> <a href="#.D1.82.D0.B5.D1.81.D1.82">#тест</a> <a href="#Hey_.3C_.23_.22_.3E_.25_:_.27">#Hey &lt; # " &gt;&#160;%&#160;: '</a>
 </p><p>.F0.9F.92.A9 <span id=".F0.9F.92.A9"></span>
 </p><p><a href="#.E5.95.A4.E9.85.92">#啤酒</a> <a href="#.E5.95.A4.E9.85.92">#啤酒</a>
index 6a1f4b5..c844e13 100644 (file)
@@ -1303,13 +1303,17 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase {
        private function resetDB( $db, $tablesUsed ) {
                if ( $db ) {
                        $userTables = [ 'user', 'user_groups', 'user_properties' ];
-                       $coreDBDataTables = array_merge( $userTables, [ 'page', 'revision' ] );
+                       $pageTables = [ 'page', 'revision', 'revision_comment_temp', 'comment' ];
+                       $coreDBDataTables = array_merge( $userTables, $pageTables );
 
-                       // If any of the user tables were marked as used, we should clear all of them.
+                       // If any of the user or page tables were marked as used, we should clear all of them.
                        if ( array_intersect( $tablesUsed, $userTables ) ) {
                                $tablesUsed = array_unique( array_merge( $tablesUsed, $userTables ) );
                                TestUserRegistry::clear();
                        }
+                       if ( array_intersect( $tablesUsed, $pageTables ) ) {
+                               $tablesUsed = array_unique( array_merge( $tablesUsed, $pageTables ) );
+                       }
 
                        $truncate = in_array( $db->getType(), [ 'oracle', 'mysql' ] );
                        foreach ( $tablesUsed as $tbl ) {
@@ -1845,4 +1849,29 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase {
                $this->mergeMwGlobalArrayValue( 'wgHooks', [ $hookName => [ $handler ] ] );
        }
 
+       /**
+        * Check whether file contains given data.
+        * @param string $fileName
+        * @param string $actualData
+        * @param bool $createIfMissing If true, and file does not exist, create it with given data
+        *                              and skip the test.
+        * @param string $msg
+        * @since 1.30
+        */
+       protected function assertFileContains(
+               $fileName,
+               $actualData,
+               $createIfMissing = true,
+               $msg = ''
+       ) {
+               if ( $createIfMissing ) {
+                       if ( !file_exists( $fileName ) ) {
+                               file_put_contents( $fileName, $actualData );
+                               $this->markTestSkipped( 'Data file $fileName does not exist' );
+                       }
+               } else {
+                       self::assertFileExists( $fileName );
+               }
+               self::assertEquals( file_get_contents( $fileName ), $actualData, $msg );
+       }
 }
diff --git a/tests/phpunit/data/categoriesrdf/categoriesRdf-out.nt b/tests/phpunit/data/categoriesrdf/categoriesRdf-out.nt
new file mode 100644 (file)
index 0000000..d2d7ea8
--- /dev/null
@@ -0,0 +1,16 @@
+<http://acme.test/categoriesDump> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://schema.org/Dataset> .
+<http://acme.test/categoriesDump> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.w3.org/2002/07/owl#Ontology> .
+<http://acme.test/categoriesDump> <http://creativecommons.org/ns#license> <https://creativecommons.org/licenses/by-sa/3.0/> .
+<http://acme.test/categoriesDump> <http://schema.org/softwareVersion> "1.0" .
+<http://acme.test/categoriesDump> <http://schema.org/dateModified> "{DATE}"^^<http://www.w3.org/2001/XMLSchema#dateTime> .
+<http://acme.test/categoriesDump> <http://schema.org/isPartOf> <http://acme.test/> .
+<http://acme.test/categoriesDump> <http://www.w3.org/2002/07/owl#imports> <https://www.mediawiki.org/ontology/ontology.owl> .
+<http://acme.test/wiki/Category:Category_One> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <https://www.mediawiki.org/ontology#Category> .
+<http://acme.test/wiki/Category:Category_One> <http://www.w3.org/2000/01/rdf-schema#label> "Category One" .
+<http://acme.test/wiki/Category:2_Category_Two> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <https://www.mediawiki.org/ontology#Category> .
+<http://acme.test/wiki/Category:2_Category_Two> <http://www.w3.org/2000/01/rdf-schema#label> "2 Category Two" .
+<http://acme.test/wiki/Category:Category_One> <https://www.mediawiki.org/ontology#isInCategory> <http://acme.test/wiki/Category:Parent_of_1> .
+<http://acme.test/wiki/Category:2_Category_Two> <https://www.mediawiki.org/ontology#isInCategory> <http://acme.test/wiki/Category:Parent_of_2> .
+<http://acme.test/wiki/Category:%D0%A2%D1%80%D0%B5%D1%82%D1%8C%D1%8F_%D0%BA%D0%B0%D1%82%D0%B5%D0%B3%D0%BE%D1%80%D0%B8%D1%8F> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <https://www.mediawiki.org/ontology#Category> .
+<http://acme.test/wiki/Category:%D0%A2%D1%80%D0%B5%D1%82%D1%8C%D1%8F_%D0%BA%D0%B0%D1%82%D0%B5%D0%B3%D0%BE%D1%80%D0%B8%D1%8F> <http://www.w3.org/2000/01/rdf-schema#label> "\u0422\u0440\u0435\u0442\u044C\u044F \u043A\u0430\u0442\u0435\u0433\u043E\u0440\u0438\u044F" .
+<http://acme.test/wiki/Category:%D0%A2%D1%80%D0%B5%D1%82%D1%8C%D1%8F_%D0%BA%D0%B0%D1%82%D0%B5%D0%B3%D0%BE%D1%80%D0%B8%D1%8F> <https://www.mediawiki.org/ontology#isInCategory> <http://acme.test/wiki/Category:Parent_of_3> .
diff --git a/tests/phpunit/includes/CommentStoreTest.php b/tests/phpunit/includes/CommentStoreTest.php
new file mode 100644 (file)
index 0000000..4e0210a
--- /dev/null
@@ -0,0 +1,622 @@
+<?php
+
+use Wikimedia\ScopedCallback;
+use Wikimedia\TestingAccessWrapper;
+
+/**
+ * @group Database
+ * @covers CommentStore
+ * @covers CommentStoreComment
+ */
+class CommentStoreTest extends MediaWikiLangTestCase {
+
+       protected $tablesUsed = [
+               'revision',
+               'revision_comment_temp',
+               'ipblocks',
+               'comment',
+       ];
+
+       /**
+        * Create a store for a particular stage
+        * @param int $stage
+        * @param string $key
+        * @return CommentStore
+        */
+       protected function makeStore( $stage, $key ) {
+               $store = new CommentStore( $key );
+               TestingAccessWrapper::newFromObject( $store )->stage = $stage;
+               return $store;
+       }
+
+       /**
+        * @dataProvider provideGetFields
+        * @param int $stage
+        * @param string $key
+        * @param array $expect
+        */
+       public function testGetFields( $stage, $key, $expect ) {
+               $store = $this->makeStore( $stage, $key );
+               $result = $store->getFields();
+               $this->assertEquals( $expect, $result );
+       }
+
+       public static function provideGetFields() {
+               return [
+                       'Simple table, old' => [
+                               MIGRATION_OLD, 'ipb_reason',
+                               [ 'ipb_reason_text' => 'ipb_reason', 'ipb_reason_data' => 'NULL', 'ipb_reason_cid' => 'NULL' ],
+                       ],
+                       'Simple table, write-both' => [
+                               MIGRATION_WRITE_BOTH, 'ipb_reason',
+                               [ 'ipb_reason_old' => 'ipb_reason', 'ipb_reason_id' => 'ipb_reason_id' ],
+                       ],
+                       'Simple table, write-new' => [
+                               MIGRATION_WRITE_NEW, 'ipb_reason',
+                               [ 'ipb_reason_old' => 'ipb_reason', 'ipb_reason_id' => 'ipb_reason_id' ],
+                       ],
+                       'Simple table, new' => [
+                               MIGRATION_NEW, 'ipb_reason',
+                               [ 'ipb_reason_id' => 'ipb_reason_id' ],
+                       ],
+
+                       'Revision, old' => [
+                               MIGRATION_OLD, 'rev_comment',
+                               [
+                                       'rev_comment_text' => 'rev_comment',
+                                       'rev_comment_data' => 'NULL',
+                                       'rev_comment_cid' => 'NULL',
+                               ],
+                       ],
+                       'Revision, write-both' => [
+                               MIGRATION_WRITE_BOTH, 'rev_comment',
+                               [ 'rev_comment_old' => 'rev_comment', 'rev_comment_pk' => 'rev_id' ],
+                       ],
+                       'Revision, write-new' => [
+                               MIGRATION_WRITE_NEW, 'rev_comment',
+                               [ 'rev_comment_old' => 'rev_comment', 'rev_comment_pk' => 'rev_id' ],
+                       ],
+                       'Revision, new' => [
+                               MIGRATION_NEW, 'rev_comment',
+                               [ 'rev_comment_pk' => 'rev_id' ],
+                       ],
+
+                       'Image, old' => [
+                               MIGRATION_OLD, 'img_description',
+                               [
+                                       'img_description_text' => 'img_description',
+                                       'img_description_data' => 'NULL',
+                                       'img_description_cid' => 'NULL',
+                               ],
+                       ],
+                       'Image, write-both' => [
+                               MIGRATION_WRITE_BOTH, 'img_description',
+                               [ 'img_description_old' => 'img_description', 'img_description_pk' => 'img_name' ],
+                       ],
+                       'Image, write-new' => [
+                               MIGRATION_WRITE_NEW, 'img_description',
+                               [ 'img_description_old' => 'img_description', 'img_description_pk' => 'img_name' ],
+                       ],
+                       'Image, new' => [
+                               MIGRATION_NEW, 'img_description',
+                               [ 'img_description_pk' => 'img_name' ],
+                       ],
+               ];
+       }
+
+       /**
+        * @dataProvider provideGetJoin
+        * @param int $stage
+        * @param string $key
+        * @param array $expect
+        */
+       public function testGetJoin( $stage, $key, $expect ) {
+               $store = $this->makeStore( $stage, $key );
+               $result = $store->getJoin();
+               $this->assertEquals( $expect, $result );
+       }
+
+       public static function provideGetJoin() {
+               return [
+                       'Simple table, old' => [
+                               MIGRATION_OLD, 'ipb_reason', [
+                                       'tables' => [],
+                                       'fields' => [
+                                               'ipb_reason_text' => 'ipb_reason',
+                                               'ipb_reason_data' => 'NULL',
+                                               'ipb_reason_cid' => 'NULL',
+                                       ],
+                                       'joins' => [],
+                               ],
+                       ],
+                       'Simple table, write-both' => [
+                               MIGRATION_WRITE_BOTH, 'ipb_reason', [
+                                       'tables' => [ 'comment_ipb_reason' => 'comment' ],
+                                       'fields' => [
+                                               'ipb_reason_text' => 'COALESCE( comment_ipb_reason.comment_text, ipb_reason )',
+                                               'ipb_reason_data' => 'comment_ipb_reason.comment_data',
+                                               'ipb_reason_cid' => 'comment_ipb_reason.comment_id',
+                                       ],
+                                       'joins' => [
+                                               'comment_ipb_reason' => [ 'LEFT JOIN', 'comment_ipb_reason.comment_id = ipb_reason_id' ],
+                                       ],
+                               ],
+                       ],
+                       'Simple table, write-new' => [
+                               MIGRATION_WRITE_NEW, 'ipb_reason', [
+                                       'tables' => [ 'comment_ipb_reason' => 'comment' ],
+                                       'fields' => [
+                                               'ipb_reason_text' => 'COALESCE( comment_ipb_reason.comment_text, ipb_reason )',
+                                               'ipb_reason_data' => 'comment_ipb_reason.comment_data',
+                                               'ipb_reason_cid' => 'comment_ipb_reason.comment_id',
+                                       ],
+                                       'joins' => [
+                                               'comment_ipb_reason' => [ 'LEFT JOIN', 'comment_ipb_reason.comment_id = ipb_reason_id' ],
+                                       ],
+                               ],
+                       ],
+                       'Simple table, new' => [
+                               MIGRATION_NEW, 'ipb_reason', [
+                                       'tables' => [ 'comment_ipb_reason' => 'comment' ],
+                                       'fields' => [
+                                               'ipb_reason_text' => 'comment_ipb_reason.comment_text',
+                                               'ipb_reason_data' => 'comment_ipb_reason.comment_data',
+                                               'ipb_reason_cid' => 'comment_ipb_reason.comment_id',
+                                       ],
+                                       'joins' => [
+                                               'comment_ipb_reason' => [ 'JOIN', 'comment_ipb_reason.comment_id = ipb_reason_id' ],
+                                       ],
+                               ],
+                       ],
+
+                       'Revision, old' => [
+                               MIGRATION_OLD, 'rev_comment', [
+                                       'tables' => [],
+                                       'fields' => [
+                                               'rev_comment_text' => 'rev_comment',
+                                               'rev_comment_data' => 'NULL',
+                                               'rev_comment_cid' => 'NULL',
+                                       ],
+                                       'joins' => [],
+                               ],
+                       ],
+                       'Revision, write-both' => [
+                               MIGRATION_WRITE_BOTH, 'rev_comment', [
+                                       'tables' => [
+                                               'temp_rev_comment' => 'revision_comment_temp',
+                                               'comment_rev_comment' => 'comment',
+                                       ],
+                                       'fields' => [
+                                               'rev_comment_text' => 'COALESCE( comment_rev_comment.comment_text, rev_comment )',
+                                               'rev_comment_data' => 'comment_rev_comment.comment_data',
+                                               'rev_comment_cid' => 'comment_rev_comment.comment_id',
+                                       ],
+                                       'joins' => [
+                                               'temp_rev_comment' => [ 'LEFT JOIN', 'temp_rev_comment.revcomment_rev = rev_id' ],
+                                               'comment_rev_comment' => [ 'LEFT JOIN',
+                                                       'comment_rev_comment.comment_id = temp_rev_comment.revcomment_comment_id' ],
+                                       ],
+                               ],
+                       ],
+                       'Revision, write-new' => [
+                               MIGRATION_WRITE_NEW, 'rev_comment', [
+                                       'tables' => [
+                                               'temp_rev_comment' => 'revision_comment_temp',
+                                               'comment_rev_comment' => 'comment',
+                                       ],
+                                       'fields' => [
+                                               'rev_comment_text' => 'COALESCE( comment_rev_comment.comment_text, rev_comment )',
+                                               'rev_comment_data' => 'comment_rev_comment.comment_data',
+                                               'rev_comment_cid' => 'comment_rev_comment.comment_id',
+                                       ],
+                                       'joins' => [
+                                               'temp_rev_comment' => [ 'LEFT JOIN', 'temp_rev_comment.revcomment_rev = rev_id' ],
+                                               'comment_rev_comment' => [ 'LEFT JOIN',
+                                                       'comment_rev_comment.comment_id = temp_rev_comment.revcomment_comment_id' ],
+                                       ],
+                               ],
+                       ],
+                       'Revision, new' => [
+                               MIGRATION_NEW, 'rev_comment', [
+                                       'tables' => [
+                                               'temp_rev_comment' => 'revision_comment_temp',
+                                               'comment_rev_comment' => 'comment',
+                                       ],
+                                       'fields' => [
+                                               'rev_comment_text' => 'comment_rev_comment.comment_text',
+                                               'rev_comment_data' => 'comment_rev_comment.comment_data',
+                                               'rev_comment_cid' => 'comment_rev_comment.comment_id',
+                                       ],
+                                       'joins' => [
+                                               'temp_rev_comment' => [ 'JOIN', 'temp_rev_comment.revcomment_rev = rev_id' ],
+                                               'comment_rev_comment' => [ 'JOIN',
+                                                       'comment_rev_comment.comment_id = temp_rev_comment.revcomment_comment_id' ],
+                                       ],
+                               ],
+                       ],
+
+                       'Image, old' => [
+                               MIGRATION_OLD, 'img_description', [
+                                       'tables' => [],
+                                       'fields' => [
+                                               'img_description_text' => 'img_description',
+                                               'img_description_data' => 'NULL',
+                                               'img_description_cid' => 'NULL',
+                                       ],
+                                       'joins' => [],
+                               ],
+                       ],
+                       'Image, write-both' => [
+                               MIGRATION_WRITE_BOTH, 'img_description', [
+                                       'tables' => [
+                                               'temp_img_description' => 'image_comment_temp',
+                                               'comment_img_description' => 'comment',
+                                       ],
+                                       'fields' => [
+                                               'img_description_text' => 'COALESCE( comment_img_description.comment_text, img_description )',
+                                               'img_description_data' => 'comment_img_description.comment_data',
+                                               'img_description_cid' => 'comment_img_description.comment_id',
+                                       ],
+                                       'joins' => [
+                                               'temp_img_description' => [ 'LEFT JOIN', 'temp_img_description.imgcomment_name = img_name' ],
+                                               'comment_img_description' => [ 'LEFT JOIN',
+                                                       'comment_img_description.comment_id = temp_img_description.imgcomment_description_id' ],
+                                       ],
+                               ],
+                       ],
+                       'Image, write-new' => [
+                               MIGRATION_WRITE_NEW, 'img_description', [
+                                       'tables' => [
+                                               'temp_img_description' => 'image_comment_temp',
+                                               'comment_img_description' => 'comment',
+                                       ],
+                                       'fields' => [
+                                               'img_description_text' => 'COALESCE( comment_img_description.comment_text, img_description )',
+                                               'img_description_data' => 'comment_img_description.comment_data',
+                                               'img_description_cid' => 'comment_img_description.comment_id',
+                                       ],
+                                       'joins' => [
+                                               'temp_img_description' => [ 'LEFT JOIN', 'temp_img_description.imgcomment_name = img_name' ],
+                                               'comment_img_description' => [ 'LEFT JOIN',
+                                                       'comment_img_description.comment_id = temp_img_description.imgcomment_description_id' ],
+                                       ],
+                               ],
+                       ],
+                       'Image, new' => [
+                               MIGRATION_NEW, 'img_description', [
+                                       'tables' => [
+                                               'temp_img_description' => 'image_comment_temp',
+                                               'comment_img_description' => 'comment',
+                                       ],
+                                       'fields' => [
+                                               'img_description_text' => 'comment_img_description.comment_text',
+                                               'img_description_data' => 'comment_img_description.comment_data',
+                                               'img_description_cid' => 'comment_img_description.comment_id',
+                                       ],
+                                       'joins' => [
+                                               'temp_img_description' => [ 'JOIN', 'temp_img_description.imgcomment_name = img_name' ],
+                                               'comment_img_description' => [ 'JOIN',
+                                                       'comment_img_description.comment_id = temp_img_description.imgcomment_description_id' ],
+                                       ],
+                               ],
+                       ],
+               ];
+       }
+
+       private function assertComment( $expect, $actual, $from ) {
+               $this->assertSame( $expect['text'], $actual->text, "text $from" );
+               $this->assertInstanceOf( get_class( $expect['message'] ), $actual->message,
+                       "message class $from" );
+               $this->assertSame( $expect['message']->getKeysToTry(), $actual->message->getKeysToTry(),
+                       "message keys $from" );
+               $this->assertEquals( $expect['message']->text(), $actual->message->text(),
+                       "message rendering $from" );
+               $this->assertEquals( $expect['data'], $actual->data, "data $from" );
+       }
+
+       /**
+        * @dataProvider provideInsertRoundTrip
+        * @param string $table
+        * @param string $key
+        * @param string $pk
+        * @param string $extraFields
+        * @param string|Message $comment
+        * @param array|null $data
+        * @param array $expect
+        */
+       public function testInsertRoundTrip( $table, $key, $pk, $extraFields, $comment, $data, $expect ) {
+               $expectOld = [
+                       'text' => $expect['text'],
+                       'message' => new RawMessage( '$1', [ $expect['text'] ] ),
+                       'data' => null,
+               ];
+
+               $stages = [
+                       MIGRATION_OLD => [ MIGRATION_OLD, MIGRATION_WRITE_NEW ],
+                       MIGRATION_WRITE_BOTH => [ MIGRATION_OLD, MIGRATION_NEW ],
+                       MIGRATION_WRITE_NEW => [ MIGRATION_WRITE_BOTH, MIGRATION_NEW ],
+                       MIGRATION_NEW => [ MIGRATION_WRITE_BOTH, MIGRATION_NEW ],
+               ];
+
+               foreach ( $stages as $writeStage => $readRange ) {
+                       if ( $key === 'ipb_reason' ) {
+                               $extraFields['ipb_address'] = __CLASS__ . "#$writeStage";
+                       }
+
+                       $wstore = $this->makeStore( $writeStage, $key );
+                       $usesTemp = $key === 'rev_comment';
+
+                       if ( $usesTemp ) {
+                               list( $fields, $callback ) = $wstore->insertWithTempTable( $this->db, $comment, $data );
+                       } else {
+                               $fields = $wstore->insert( $this->db, $comment, $data );
+                       }
+
+                       if ( $writeStage <= MIGRATION_WRITE_BOTH ) {
+                               $this->assertSame( $expect['text'], $fields[$key], "old field, stage=$writeStage" );
+                       } else {
+                               $this->assertArrayNotHasKey( $key, $fields, "old field, stage=$writeStage" );
+                       }
+                       if ( $writeStage >= MIGRATION_WRITE_BOTH && !$usesTemp ) {
+                               $this->assertArrayHasKey( "{$key}_id", $fields, "new field, stage=$writeStage" );
+                       } else {
+                               $this->assertArrayNotHasKey( "{$key}_id", $fields, "new field, stage=$writeStage" );
+                       }
+
+                       $this->db->insert( $table, $extraFields + $fields, __METHOD__ );
+                       $id = $this->db->insertId();
+                       if ( $usesTemp ) {
+                               $callback( $id );
+                       }
+
+                       for ( $readStage = $readRange[0]; $readStage <= $readRange[1]; $readStage++ ) {
+                               $rstore = $this->makeStore( $readStage, $key );
+
+                               $fieldRow = $this->db->selectRow(
+                                       $table,
+                                       $rstore->getFields(),
+                                       [ $pk => $id ],
+                                       __METHOD__
+                               );
+
+                               $queryInfo = $rstore->getJoin();
+                               $joinRow = $this->db->selectRow(
+                                       [ $table ] + $queryInfo['tables'],
+                                       $queryInfo['fields'],
+                                       [ $pk => $id ],
+                                       __METHOD__,
+                                       [],
+                                       $queryInfo['joins']
+                               );
+
+                               $this->assertComment(
+                                       $writeStage === MIGRATION_OLD || $readStage === MIGRATION_OLD ? $expectOld : $expect,
+                                       $rstore->getCommentLegacy( $this->db, $fieldRow ),
+                                       "w=$writeStage, r=$readStage, from getFields()"
+                               );
+                               $this->assertComment(
+                                       $writeStage === MIGRATION_OLD || $readStage === MIGRATION_OLD ? $expectOld : $expect,
+                                       $rstore->getComment( $joinRow ),
+                                       "w=$writeStage, r=$readStage, from getJoin()"
+                               );
+                       }
+               }
+       }
+
+       public static function provideInsertRoundTrip() {
+               $db = wfGetDB( DB_REPLICA ); // for timestamps
+
+               $msgComment = new Message( 'parentheses', [ 'message comment' ] );
+               $textCommentMsg = new RawMessage( '$1', [ 'text comment' ] );
+               $nestedMsgComment = new Message( [ 'parentheses', 'rawmessage' ], [ new Message( 'mainpage' ) ] );
+               $ipbfields = [
+                       'ipb_range_start' => '',
+                       'ipb_range_end' => '',
+                       'ipb_by' => 0,
+                       'ipb_timestamp' => $db->timestamp(),
+                       'ipb_expiry' => $db->getInfinity(),
+               ];
+               $revfields = [
+                       'rev_page' => 42,
+                       'rev_text_id' => 42,
+                       'rev_len' => 0,
+                       'rev_user' => 0,
+                       'rev_user_text' => '',
+                       'rev_timestamp' => $db->timestamp(),
+               ];
+               $comStoreComment = new CommentStoreComment(
+                       null, 'comment store comment', null, [ 'foo' => 'bar' ]
+               );
+
+               return [
+                       'Simple table, text comment' => [
+                               'ipblocks', 'ipb_reason', 'ipb_id', $ipbfields, 'text comment', null, [
+                                       'text' => 'text comment',
+                                       'message' => $textCommentMsg,
+                                       'data' => null,
+                               ]
+                       ],
+                       'Simple table, text comment with data' => [
+                               'ipblocks', 'ipb_reason', 'ipb_id', $ipbfields, 'text comment', [ 'message' => 42 ], [
+                                       'text' => 'text comment',
+                                       'message' => $textCommentMsg,
+                                       'data' => [ 'message' => 42 ],
+                               ]
+                       ],
+                       'Simple table, message comment' => [
+                               'ipblocks', 'ipb_reason', 'ipb_id', $ipbfields, $msgComment, null, [
+                                       'text' => '(message comment)',
+                                       'message' => $msgComment,
+                                       'data' => null,
+                               ]
+                       ],
+                       'Simple table, message comment with data' => [
+                               'ipblocks', 'ipb_reason', 'ipb_id', $ipbfields, $msgComment, [ 'message' => 42 ], [
+                                       'text' => '(message comment)',
+                                       'message' => $msgComment,
+                                       'data' => [ 'message' => 42 ],
+                               ]
+                       ],
+                       'Simple table, nested message comment' => [
+                               'ipblocks', 'ipb_reason', 'ipb_id', $ipbfields, $nestedMsgComment, null, [
+                                       'text' => '(Main Page)',
+                                       'message' => $nestedMsgComment,
+                                       'data' => null,
+                               ]
+                       ],
+                       'Simple table, CommentStoreComment' => [
+                               'ipblocks', 'ipb_reason', 'ipb_id', $ipbfields, clone $comStoreComment, [ 'baz' => 'baz' ], [
+                                       'text' => 'comment store comment',
+                                       'message' => $comStoreComment->message,
+                                       'data' => [ 'foo' => 'bar' ],
+                               ]
+                       ],
+
+                       'Revision, text comment' => [
+                               'revision', 'rev_comment', 'rev_id', $revfields, 'text comment', null, [
+                                       'text' => 'text comment',
+                                       'message' => $textCommentMsg,
+                                       'data' => null,
+                               ]
+                       ],
+                       'Revision, text comment with data' => [
+                               'revision', 'rev_comment', 'rev_id', $revfields, 'text comment', [ 'message' => 42 ], [
+                                       'text' => 'text comment',
+                                       'message' => $textCommentMsg,
+                                       'data' => [ 'message' => 42 ],
+                               ]
+                       ],
+                       'Revision, message comment' => [
+                               'revision', 'rev_comment', 'rev_id', $revfields, $msgComment, null, [
+                                       'text' => '(message comment)',
+                                       'message' => $msgComment,
+                                       'data' => null,
+                               ]
+                       ],
+                       'Revision, message comment with data' => [
+                               'revision', 'rev_comment', 'rev_id', $revfields, $msgComment, [ 'message' => 42 ], [
+                                       'text' => '(message comment)',
+                                       'message' => $msgComment,
+                                       'data' => [ 'message' => 42 ],
+                               ]
+                       ],
+                       'Revision, nested message comment' => [
+                               'revision', 'rev_comment', 'rev_id', $revfields, $nestedMsgComment, null, [
+                                       'text' => '(Main Page)',
+                                       'message' => $nestedMsgComment,
+                                       'data' => null,
+                               ]
+                       ],
+                       'Revision, CommentStoreComment' => [
+                               'revision', 'rev_comment', 'rev_id', $revfields, clone $comStoreComment, [ 'baz' => 'baz' ], [
+                                       'text' => 'comment store comment',
+                                       'message' => $comStoreComment->message,
+                                       'data' => [ 'foo' => 'bar' ],
+                               ]
+                       ],
+               ];
+       }
+
+       public function testGetCommentErrors() {
+               MediaWiki\suppressWarnings();
+               $reset = new ScopedCallback( 'MediaWiki\restoreWarnings' );
+
+               $store = $this->makeStore( MIGRATION_OLD, 'dummy' );
+               $res = $store->getComment( [ 'dummy' => 'comment' ] );
+               $this->assertSame( '', $res->text );
+               $res = $store->getComment( [ 'dummy' => 'comment' ], true );
+               $this->assertSame( 'comment', $res->text );
+
+               $store = $this->makeStore( MIGRATION_NEW, 'dummy' );
+               try {
+                       $store->getComment( [ 'dummy' => 'comment' ] );
+                       $this->fail( 'Expected exception not thrown' );
+               } catch ( InvalidArgumentException $ex ) {
+                       $this->assertSame( '$row does not contain fields needed for comment dummy', $ex->getMessage() );
+               }
+               $res = $store->getComment( [ 'dummy' => 'comment' ], true );
+               $this->assertSame( 'comment', $res->text );
+               try {
+                       $store->getComment( [ 'dummy_id' => 1 ] );
+                       $this->fail( 'Expected exception not thrown' );
+               } catch ( InvalidArgumentException $ex ) {
+                       $this->assertSame(
+                               '$row does not contain fields needed for comment dummy and getComment(), '
+                               . 'but does have fields for getCommentLegacy()',
+                               $ex->getMessage()
+                       );
+               }
+
+               $store = $this->makeStore( MIGRATION_NEW, 'rev_comment' );
+               try {
+                       $store->getComment( [ 'rev_comment' => 'comment' ] );
+                       $this->fail( 'Expected exception not thrown' );
+               } catch ( InvalidArgumentException $ex ) {
+                       $this->assertSame(
+                               '$row does not contain fields needed for comment rev_comment', $ex->getMessage()
+                       );
+               }
+               $res = $store->getComment( [ 'rev_comment' => 'comment' ], true );
+               $this->assertSame( 'comment', $res->text );
+               try {
+                       $store->getComment( [ 'rev_comment_pk' => 1 ] );
+                       $this->fail( 'Expected exception not thrown' );
+               } catch ( InvalidArgumentException $ex ) {
+                       $this->assertSame(
+                               '$row does not contain fields needed for comment rev_comment and getComment(), '
+                               . 'but does have fields for getCommentLegacy()',
+                               $ex->getMessage()
+                       );
+               }
+       }
+
+       public static function provideStages() {
+               return [
+                       'MIGRATION_OLD' => [ MIGRATION_OLD ],
+                       'MIGRATION_WRITE_BOTH' => [ MIGRATION_WRITE_BOTH ],
+                       'MIGRATION_WRITE_NEW' => [ MIGRATION_WRITE_NEW ],
+                       'MIGRATION_NEW' => [ MIGRATION_NEW ],
+               ];
+       }
+
+       /**
+        * @dataProvider provideStages
+        * @param int $stage
+        * @expectedException InvalidArgumentException
+        * @expectedExceptionMessage Must use insertWithTempTable() for rev_comment
+        */
+       public function testInsertWrong( $stage ) {
+               $store = $this->makeStore( $stage, 'rev_comment' );
+               $store->insert( $this->db, 'foo' );
+       }
+
+       /**
+        * @dataProvider provideStages
+        * @param int $stage
+        * @expectedException InvalidArgumentException
+        * @expectedExceptionMessage Must use insert() for ipb_reason
+        */
+       public function testInsertWithTempTableWrong( $stage ) {
+               $store = $this->makeStore( $stage, 'ipb_reason' );
+               $store->insertWithTempTable( $this->db, 'foo' );
+       }
+
+       /**
+        * @dataProvider provideStages
+        * @param int $stage
+        */
+       public function testInsertWithTempTableDeprecated( $stage ) {
+               $wrap = TestingAccessWrapper::newFromClass( CommentStore::class );
+               $wrap->formerTempTables += [ 'ipb_reason' => '1.30' ];
+
+               $this->hideDeprecated( 'CommentStore::insertWithTempTable for ipb_reason' );
+               $store = $this->makeStore( $stage, 'ipb_reason' );
+               list( $fields, $callback ) = $store->insertWithTempTable( $this->db, 'foo' );
+               $this->assertTrue( is_callable( $callback ) );
+       }
+
+       public function testConstructor() {
+               $this->assertInstanceOf( CommentStore::class, CommentStore::newKey( 'dummy' ) );
+       }
+
+}
index 3ba82a6..b207e06 100644 (file)
@@ -146,7 +146,7 @@ class RevisionStorageTest extends MediaWikiTestCase {
                $orig = $this->makeRevision();
 
                $dbr = wfGetDB( DB_REPLICA );
-               $res = $dbr->select( 'revision', '*', [ 'rev_id' => $orig->getId() ] );
+               $res = $dbr->select( 'revision', Revision::selectFields(), [ 'rev_id' => $orig->getId() ] );
                $this->assertTrue( is_object( $res ), 'query failed' );
 
                $row = $res->fetchObject();
@@ -164,7 +164,7 @@ class RevisionStorageTest extends MediaWikiTestCase {
                $orig = $this->makeRevision();
 
                $dbr = wfGetDB( DB_REPLICA );
-               $res = $dbr->select( 'revision', '*', [ 'rev_id' => $orig->getId() ] );
+               $res = $dbr->select( 'revision', Revision::selectFields(), [ 'rev_id' => $orig->getId() ] );
                $this->assertTrue( is_object( $res ), 'query failed' );
 
                $row = $res->fetchObject();
@@ -188,7 +188,9 @@ class RevisionStorageTest extends MediaWikiTestCase {
                $page->doDeleteArticle( 'test Revision::newFromArchiveRow' );
 
                $dbr = wfGetDB( DB_REPLICA );
-               $res = $dbr->select( 'archive', '*', [ 'ar_rev_id' => $orig->getId() ] );
+               $res = $dbr->select(
+                       'archive', Revision::selectArchiveFields(), [ 'ar_rev_id' => $orig->getId() ]
+               );
                $this->assertTrue( is_object( $res ), 'query failed' );
 
                $row = $res->fetchObject();
index 4744875..62ba5f6 100644 (file)
@@ -1,5 +1,6 @@
 <?php
 
+use Wikimedia\ScopedCallback;
 use Wikimedia\TestingAccessWrapper;
 
 /**
@@ -447,100 +448,175 @@ class WatchedItemQueryServiceUnitTest extends PHPUnit_Framework_TestCase {
                        [
                                [ 'includeFields' => [ WatchedItemQueryService::INCLUDE_FLAGS ] ],
                                null,
+                               [],
                                [ 'rc_type', 'rc_minor', 'rc_bot' ],
                                [],
                                [],
+                               [],
                        ],
                        [
                                [ 'includeFields' => [ WatchedItemQueryService::INCLUDE_USER ] ],
                                null,
+                               [],
                                [ 'rc_user_text' ],
                                [],
                                [],
+                               [],
                        ],
                        [
                                [ 'includeFields' => [ WatchedItemQueryService::INCLUDE_USER_ID ] ],
                                null,
+                               [],
                                [ 'rc_user' ],
                                [],
                                [],
+                               [],
+                       ],
+                       [
+                               [ 'includeFields' => [ WatchedItemQueryService::INCLUDE_COMMENT ] ],
+                               null,
+                               [],
+                               [
+                                       'rc_comment_text' => 'rc_comment',
+                                       'rc_comment_data' => 'NULL',
+                                       'rc_comment_cid' => 'NULL',
+                               ],
+                               [],
+                               [],
+                               [],
+                               [ 'wgCommentTableSchemaMigrationStage' => MIGRATION_OLD ],
+                       ],
+                       [
+                               [ 'includeFields' => [ WatchedItemQueryService::INCLUDE_COMMENT ] ],
+                               null,
+                               [ 'comment_rc_comment' => 'comment' ],
+                               [
+                                       'rc_comment_text' => 'COALESCE( comment_rc_comment.comment_text, rc_comment )',
+                                       'rc_comment_data' => 'comment_rc_comment.comment_data',
+                                       'rc_comment_cid' => 'comment_rc_comment.comment_id',
+                               ],
+                               [],
+                               [],
+                               [ 'comment_rc_comment' => [ 'LEFT JOIN', 'comment_rc_comment.comment_id = rc_comment_id' ] ],
+                               [ 'wgCommentTableSchemaMigrationStage' => MIGRATION_WRITE_BOTH ],
+                       ],
+                       [
+                               [ 'includeFields' => [ WatchedItemQueryService::INCLUDE_COMMENT ] ],
+                               null,
+                               [ 'comment_rc_comment' => 'comment' ],
+                               [
+                                       'rc_comment_text' => 'COALESCE( comment_rc_comment.comment_text, rc_comment )',
+                                       'rc_comment_data' => 'comment_rc_comment.comment_data',
+                                       'rc_comment_cid' => 'comment_rc_comment.comment_id',
+                               ],
+                               [],
+                               [],
+                               [ 'comment_rc_comment' => [ 'LEFT JOIN', 'comment_rc_comment.comment_id = rc_comment_id' ] ],
+                               [ 'wgCommentTableSchemaMigrationStage' => MIGRATION_WRITE_NEW ],
                        ],
                        [
                                [ 'includeFields' => [ WatchedItemQueryService::INCLUDE_COMMENT ] ],
                                null,
-                               [ 'rc_comment' ],
+                               [ 'comment_rc_comment' => 'comment' ],
+                               [
+                                       'rc_comment_text' => 'comment_rc_comment.comment_text',
+                                       'rc_comment_data' => 'comment_rc_comment.comment_data',
+                                       'rc_comment_cid' => 'comment_rc_comment.comment_id',
+                               ],
                                [],
                                [],
+                               [ 'comment_rc_comment' => [ 'JOIN', 'comment_rc_comment.comment_id = rc_comment_id' ] ],
+                               [ 'wgCommentTableSchemaMigrationStage' => MIGRATION_NEW ],
                        ],
                        [
                                [ 'includeFields' => [ WatchedItemQueryService::INCLUDE_PATROL_INFO ] ],
                                null,
+                               [],
                                [ 'rc_patrolled', 'rc_log_type' ],
                                [],
                                [],
+                               [],
                        ],
                        [
                                [ 'includeFields' => [ WatchedItemQueryService::INCLUDE_SIZES ] ],
                                null,
+                               [],
                                [ 'rc_old_len', 'rc_new_len' ],
                                [],
                                [],
+                               [],
                        ],
                        [
                                [ 'includeFields' => [ WatchedItemQueryService::INCLUDE_LOG_INFO ] ],
                                null,
+                               [],
                                [ 'rc_logid', 'rc_log_type', 'rc_log_action', 'rc_params' ],
                                [],
                                [],
+                               [],
                        ],
                        [
                                [ 'namespaceIds' => [ 0, 1 ] ],
                                null,
                                [],
+                               [],
                                [ 'wl_namespace' => [ 0, 1 ] ],
                                [],
+                               [],
                        ],
                        [
                                [ 'namespaceIds' => [ 0, "1; DROP TABLE watchlist;\n--" ] ],
                                null,
                                [],
+                               [],
                                [ 'wl_namespace' => [ 0, 1 ] ],
                                [],
+                               [],
                        ],
                        [
                                [ 'rcTypes' => [ RC_EDIT, RC_NEW ] ],
                                null,
                                [],
+                               [],
                                [ 'rc_type' => [ RC_EDIT, RC_NEW ] ],
                                [],
+                               [],
                        ],
                        [
                                [ 'dir' => WatchedItemQueryService::DIR_OLDER ],
                                null,
                                [],
                                [],
-                               [ 'ORDER BY' => [ 'rc_timestamp DESC', 'rc_id DESC' ] ]
+                               [],
+                               [ 'ORDER BY' => [ 'rc_timestamp DESC', 'rc_id DESC' ] ],
+                               [],
                        ],
                        [
                                [ 'dir' => WatchedItemQueryService::DIR_NEWER ],
                                null,
                                [],
                                [],
-                               [ 'ORDER BY' => [ 'rc_timestamp', 'rc_id' ] ]
+                               [],
+                               [ 'ORDER BY' => [ 'rc_timestamp', 'rc_id' ] ],
+                               [],
                        ],
                        [
                                [ 'dir' => WatchedItemQueryService::DIR_OLDER, 'start' => '20151212010101' ],
                                null,
                                [],
+                               [],
                                [ "rc_timestamp <= '20151212010101'" ],
-                               [ 'ORDER BY' => [ 'rc_timestamp DESC', 'rc_id DESC' ] ]
+                               [ 'ORDER BY' => [ 'rc_timestamp DESC', 'rc_id DESC' ] ],
+                               [],
                        ],
                        [
                                [ 'dir' => WatchedItemQueryService::DIR_OLDER, 'end' => '20151212010101' ],
                                null,
                                [],
+                               [],
                                [ "rc_timestamp >= '20151212010101'" ],
-                               [ 'ORDER BY' => [ 'rc_timestamp DESC', 'rc_id DESC' ] ]
+                               [ 'ORDER BY' => [ 'rc_timestamp DESC', 'rc_id DESC' ] ],
+                               [],
                        ],
                        [
                                [
@@ -550,22 +626,28 @@ class WatchedItemQueryServiceUnitTest extends PHPUnit_Framework_TestCase {
                                ],
                                null,
                                [],
+                               [],
                                [ "rc_timestamp <= '20151212020101'", "rc_timestamp >= '20151212010101'" ],
-                               [ 'ORDER BY' => [ 'rc_timestamp DESC', 'rc_id DESC' ] ]
+                               [ 'ORDER BY' => [ 'rc_timestamp DESC', 'rc_id DESC' ] ],
+                               [],
                        ],
                        [
                                [ 'dir' => WatchedItemQueryService::DIR_NEWER, 'start' => '20151212010101' ],
                                null,
                                [],
+                               [],
                                [ "rc_timestamp >= '20151212010101'" ],
-                               [ 'ORDER BY' => [ 'rc_timestamp', 'rc_id' ] ]
+                               [ 'ORDER BY' => [ 'rc_timestamp', 'rc_id' ] ],
+                               [],
                        ],
                        [
                                [ 'dir' => WatchedItemQueryService::DIR_NEWER, 'end' => '20151212010101' ],
                                null,
                                [],
+                               [],
                                [ "rc_timestamp <= '20151212010101'" ],
-                               [ 'ORDER BY' => [ 'rc_timestamp', 'rc_id' ] ]
+                               [ 'ORDER BY' => [ 'rc_timestamp', 'rc_id' ] ],
+                               [],
                        ],
                        [
                                [
@@ -575,133 +657,169 @@ class WatchedItemQueryServiceUnitTest extends PHPUnit_Framework_TestCase {
                                ],
                                null,
                                [],
+                               [],
                                [ "rc_timestamp >= '20151212010101'", "rc_timestamp <= '20151212020101'" ],
-                               [ 'ORDER BY' => [ 'rc_timestamp', 'rc_id' ] ]
+                               [ 'ORDER BY' => [ 'rc_timestamp', 'rc_id' ] ],
+                               [],
                        ],
                        [
                                [ 'limit' => 10 ],
                                null,
                                [],
                                [],
+                               [],
                                [ 'LIMIT' => 11 ],
+                               [],
                        ],
                        [
                                [ 'limit' => "10; DROP TABLE watchlist;\n--" ],
                                null,
                                [],
                                [],
+                               [],
                                [ 'LIMIT' => 11 ],
+                               [],
                        ],
                        [
                                [ 'filters' => [ WatchedItemQueryService::FILTER_MINOR ] ],
                                null,
                                [],
+                               [],
                                [ 'rc_minor != 0' ],
                                [],
+                               [],
                        ],
                        [
                                [ 'filters' => [ WatchedItemQueryService::FILTER_NOT_MINOR ] ],
                                null,
                                [],
+                               [],
                                [ 'rc_minor = 0' ],
                                [],
+                               [],
                        ],
                        [
                                [ 'filters' => [ WatchedItemQueryService::FILTER_BOT ] ],
                                null,
                                [],
+                               [],
                                [ 'rc_bot != 0' ],
                                [],
+                               [],
                        ],
                        [
                                [ 'filters' => [ WatchedItemQueryService::FILTER_NOT_BOT ] ],
                                null,
                                [],
+                               [],
                                [ 'rc_bot = 0' ],
                                [],
+                               [],
                        ],
                        [
                                [ 'filters' => [ WatchedItemQueryService::FILTER_ANON ] ],
                                null,
                                [],
+                               [],
                                [ 'rc_user = 0' ],
                                [],
+                               [],
                        ],
                        [
                                [ 'filters' => [ WatchedItemQueryService::FILTER_NOT_ANON ] ],
                                null,
                                [],
+                               [],
                                [ 'rc_user != 0' ],
                                [],
+                               [],
                        ],
                        [
                                [ 'filters' => [ WatchedItemQueryService::FILTER_PATROLLED ] ],
                                null,
                                [],
+                               [],
                                [ 'rc_patrolled != 0' ],
                                [],
+                               [],
                        ],
                        [
                                [ 'filters' => [ WatchedItemQueryService::FILTER_NOT_PATROLLED ] ],
                                null,
                                [],
+                               [],
                                [ 'rc_patrolled = 0' ],
                                [],
+                               [],
                        ],
                        [
                                [ 'filters' => [ WatchedItemQueryService::FILTER_UNREAD ] ],
                                null,
                                [],
+                               [],
                                [ 'rc_timestamp >= wl_notificationtimestamp' ],
                                [],
+                               [],
                        ],
                        [
                                [ 'filters' => [ WatchedItemQueryService::FILTER_NOT_UNREAD ] ],
                                null,
                                [],
+                               [],
                                [ 'wl_notificationtimestamp IS NULL OR rc_timestamp < wl_notificationtimestamp' ],
                                [],
+                               [],
                        ],
                        [
                                [ 'onlyByUser' => 'SomeOtherUser' ],
                                null,
                                [],
+                               [],
                                [ 'rc_user_text' => 'SomeOtherUser' ],
                                [],
+                               [],
                        ],
                        [
                                [ 'notByUser' => 'SomeOtherUser' ],
                                null,
                                [],
+                               [],
                                [ "rc_user_text != 'SomeOtherUser'" ],
                                [],
+                               [],
                        ],
                        [
                                [ 'dir' => WatchedItemQueryService::DIR_OLDER ],
                                [ '20151212010101', 123 ],
                                [],
+                               [],
                                [
                                        "(rc_timestamp < '20151212010101') OR ((rc_timestamp = '20151212010101') AND (rc_id <= 123))"
                                ],
                                [ 'ORDER BY' => [ 'rc_timestamp DESC', 'rc_id DESC' ] ],
+                               [],
                        ],
                        [
                                [ 'dir' => WatchedItemQueryService::DIR_NEWER ],
                                [ '20151212010101', 123 ],
                                [],
+                               [],
                                [
                                        "(rc_timestamp > '20151212010101') OR ((rc_timestamp = '20151212010101') AND (rc_id >= 123))"
                                ],
                                [ 'ORDER BY' => [ 'rc_timestamp', 'rc_id' ] ],
+                               [],
                        ],
                        [
                                [ 'dir' => WatchedItemQueryService::DIR_OLDER ],
                                [ '20151212010101', "123; DROP TABLE watchlist;\n--" ],
                                [],
+                               [],
                                [
                                        "(rc_timestamp < '20151212010101') OR ((rc_timestamp = '20151212010101') AND (rc_id <= 123))"
                                ],
                                [ 'ORDER BY' => [ 'rc_timestamp DESC', 'rc_id DESC' ] ],
+                               [],
                        ],
                ];
        }
@@ -712,10 +830,28 @@ class WatchedItemQueryServiceUnitTest extends PHPUnit_Framework_TestCase {
        public function testGetWatchedItemsWithRecentChangeInfo_optionsAndEmptyResult(
                array $options,
                $startFrom,
+               array $expectedExtraTables,
                array $expectedExtraFields,
                array $expectedExtraConds,
-               array $expectedDbOptions
+               array $expectedDbOptions,
+               array $expectedExtraJoinConds,
+               array $globals = []
        ) {
+               // Sigh. This test class doesn't extend MediaWikiTestCase, so we have to reinvent setMwGlobals().
+               if ( $globals ) {
+                       $resetGlobals = [];
+                       foreach ( $globals as $k => $v ) {
+                               $resetGlobals[$k] = $GLOBALS[$k];
+                               $GLOBALS[$k] = $v;
+                       }
+                       $reset = new ScopedCallback( function () use ( $resetGlobals ) {
+                               foreach ( $resetGlobals as $k => $v ) {
+                                       $GLOBALS[$k] = $v;
+                               }
+                       } );
+               }
+
+               $expectedTables = array_merge( [ 'recentchanges', 'watchlist', 'page' ], $expectedExtraTables );
                $expectedFields = array_merge(
                        [
                                'rc_id',
@@ -736,29 +872,33 @@ class WatchedItemQueryServiceUnitTest extends PHPUnit_Framework_TestCase {
                        [ 'wl_user' => 1, '(rc_this_oldid=page_latest) OR (rc_type=3)', ],
                        $expectedExtraConds
                );
+               $expectedJoinConds = array_merge(
+                       [
+                               'watchlist' => [
+                                       'INNER JOIN',
+                                       [
+                                               'wl_namespace=rc_namespace',
+                                               'wl_title=rc_title'
+                                       ]
+                               ],
+                               'page' => [
+                                       'LEFT JOIN',
+                                       'rc_cur_id=page_id',
+                               ],
+                       ],
+                       $expectedExtraJoinConds
+               );
 
                $mockDb = $this->getMockDb();
                $mockDb->expects( $this->once() )
                        ->method( 'select' )
                        ->with(
-                               [ 'recentchanges', 'watchlist', 'page' ],
+                               $expectedTables,
                                $expectedFields,
                                $expectedConds,
                                $this->isType( 'string' ),
                                $expectedDbOptions,
-                               [
-                                       'watchlist' => [
-                                               'INNER JOIN',
-                                               [
-                                                       'wl_namespace=rc_namespace',
-                                                       'wl_title=rc_title'
-                                               ]
-                                       ],
-                                       'page' => [
-                                               'LEFT JOIN',
-                                               'rc_cur_id=page_id',
-                                       ],
-                               ]
+                               $expectedJoinConds
                        )
                        ->will( $this->returnValue( [] ) );
 
index 12878b3..186ffdb 100644 (file)
@@ -16,6 +16,7 @@ class WikiMapTest extends MediaWikiLangTestCase {
                                'enwiki' => 'http://en.example.org',
                                'ruwiki' => '//ru.example.org',
                                'nopathwiki' => '//nopath.example.org',
+                               'thiswiki' => '//this.wiki.org'
                        ],
                        'wgArticlePath' => [
                                'enwiki' => '/w/$1',
@@ -25,6 +26,10 @@ class WikiMapTest extends MediaWikiLangTestCase {
                $conf->suffixes = [ 'wiki' ];
                $this->setMwGlobals( [
                        'wgConf' => $conf,
+                       'wgLocalDatabases' => [ 'enwiki', 'ruwiki', 'nopathwiki' ],
+                       'wgCanonicalServer' => '//this.wiki.org',
+                       'wgDBname' => 'thiswiki',
+                       'wgDBprefix' => ''
                ] );
 
                TestSites::insertIntoDb();
@@ -175,4 +180,57 @@ class WikiMapTest extends MediaWikiLangTestCase {
                $this->assertEquals( $expected, WikiMap::getForeignURL( $wikiId, $page, $fragment ) );
        }
 
+       /**
+        * @covers WikiMap::getCanonicalServerInfoForAllWikis()
+        */
+       public function testGetCanonicalServerInfoForAllWikis() {
+               $expected = [
+                       'thiswiki' => [
+                               'url' => '//this.wiki.org',
+                               'parts' => [ 'scheme' => '', 'host' => 'this.wiki.org', 'delimiter' => '//' ]
+                       ],
+                       'enwiki' => [
+                               'url' => 'http://en.example.org',
+                               'parts' => [
+                                       'scheme' => 'http', 'host' => 'en.example.org', 'delimiter' => '://' ]
+                       ],
+                       'ruwiki' => [
+                               'url' => '//ru.example.org',
+                               'parts' => [ 'scheme' => '', 'host' => 'ru.example.org', 'delimiter' => '//' ]
+                       ]
+               ];
+
+               $this->assertArrayEquals(
+                       $expected,
+                       WikiMap::getCanonicalServerInfoForAllWikis(),
+                       true,
+                       true
+               );
+       }
+
+       public function provideGetWikiFromUrl() {
+               return [
+                       [ 'http://this.wiki.org', 'thiswiki' ],
+                       [ 'https://this.wiki.org', 'thiswiki' ],
+                       [ 'http://this.wiki.org/$1', 'thiswiki' ],
+                       [ 'https://this.wiki.org/$2', 'thiswiki' ],
+                       [ 'http://en.example.org', 'enwiki' ],
+                       [ 'https://en.example.org', 'enwiki' ],
+                       [ 'http://en.example.org/$1', 'enwiki' ],
+                       [ 'https://en.example.org/$2', 'enwiki' ],
+                       [ 'http://ru.example.org', 'ruwiki' ],
+                       [ 'https://ru.example.org', 'ruwiki' ],
+                       [ 'http://ru.example.org/$1', 'ruwiki' ],
+                       [ 'https://ru.example.org/$2', 'ruwiki' ],
+                       [ 'http://not.defined.org', false ]
+               ];
+       }
+
+       /**
+        * @dataProvider provideGetWikiFromUrl
+        * @covers WikiMap::getWikiFromUrl()
+        */
+       public function testGetWikiFromUrl( $url, $wiki ) {
+               $this->assertEquals( $wiki, WikiMap::getWikiFromUrl( $url ) );
+       }
 }
index 4f4453f..fdbeded 100644 (file)
@@ -1074,6 +1074,8 @@ class ApiQueryWatchlistIntegrationTest extends ApiTestCase {
                        'rc_user' => 0,
                        'rc_user_text' => 'External User',
                        'rc_comment' => '',
+                       'rc_comment_text' => '',
+                       'rc_comment_data' => null,
                        'rc_this_oldid' => $title->getLatestRevID(),
                        'rc_last_oldid' => $title->getLatestRevID(),
                        'rc_bot' => 0,
index a840599..c18af8b 100644 (file)
@@ -1408,7 +1408,7 @@ class AuthManagerTest extends \MediaWikiTestCase {
                $readOnlyMode = \MediaWiki\MediaWikiServices::getInstance()->getReadOnlyMode();
                $readOnlyMode->setReason( 'Because' );
                $this->assertEquals(
-                       \Status::newFatal( 'readonlytext', 'Because' ),
+                       \Status::newFatal( wfMessage( 'readonlytext', 'Because' ) ),
                        $this->manager->checkAccountCreatePermissions( new \User )
                );
                $readOnlyMode->setReason( false );
@@ -2478,7 +2478,7 @@ class AuthManagerTest extends \MediaWikiTestCase {
                $this->hook( 'LocalUserCreated', $this->never() );
                $ret = $this->manager->autoCreateUser( $user, AuthManager::AUTOCREATE_SOURCE_SESSION, true );
                $this->unhook( 'LocalUserCreated' );
-               $this->assertEquals( \Status::newFatal( 'readonlytext', 'Because' ), $ret );
+               $this->assertEquals( \Status::newFatal( wfMessage( 'readonlytext', 'Because' ) ), $ret );
                $this->assertEquals( 0, $user->getId() );
                $this->assertNotEquals( $username, $user->getName() );
                $this->assertEquals( 0, $session->getUser()->getId() );
index 04b7ee0..4f917e9 100644 (file)
@@ -40,8 +40,6 @@ class ChangesListStringOptionsFilterGroupTest extends MediaWikiTestCase {
         * @dataProvider provideModifyQuery
         */
        public function testModifyQuery( $filterDefinitions, $expectedValues, $input ) {
-               $self = $this;
-
                $queryCallable = function (
                        $className,
                        $ctx,
@@ -52,8 +50,8 @@ class ChangesListStringOptionsFilterGroupTest extends MediaWikiTestCase {
                        &$query_options,
                        &$join_conds,
                        $actualSelectedValues
-               ) use ( $self, $expectedValues ) {
-                       $self->assertSame(
+               ) use ( $expectedValues ) {
+                       $this->assertSame(
                                $expectedValues,
                                $actualSelectedValues
                        );
index 68f9079..d638d0f 100644 (file)
@@ -31,6 +31,8 @@ class RecentChangeTest extends MediaWikiTestCase {
                $row->rc_foo = 'AAA';
                $row->rc_timestamp = '20150921134808';
                $row->rc_deleted = 'bar';
+               $row->rc_comment_text = 'comment';
+               $row->rc_comment_data = null;
 
                $rc = RecentChange::newFromRow( $row );
 
@@ -38,6 +40,29 @@ class RecentChangeTest extends MediaWikiTestCase {
                        'rc_foo' => 'AAA',
                        'rc_timestamp' => '20150921134808',
                        'rc_deleted' => 'bar',
+                       'rc_comment' => 'comment',
+                       'rc_comment_text' => 'comment',
+                       'rc_comment_data' => null,
+               ];
+               $this->assertEquals( $expected, $rc->getAttributes() );
+
+               $row = new stdClass();
+               $row->rc_foo = 'AAA';
+               $row->rc_timestamp = '20150921134808';
+               $row->rc_deleted = 'bar';
+               $row->rc_comment = 'comment';
+
+               MediaWiki\suppressWarnings();
+               $rc = RecentChange::newFromRow( $row );
+               MediaWiki\restoreWarnings();
+
+               $expected = [
+                       'rc_foo' => 'AAA',
+                       'rc_timestamp' => '20150921134808',
+                       'rc_deleted' => 'bar',
+                       'rc_comment' => 'comment',
+                       'rc_comment_text' => 'comment',
+                       'rc_comment_data' => null,
                ];
                $this->assertEquals( $expected, $rc->getAttributes() );
        }
index 4da09d8..2c30948 100644 (file)
@@ -119,6 +119,8 @@ class TestRecentChangesHelper {
                                'rc_last_oldid' => $lastid,
                                'rc_cur_id' => $curid,
                                'rc_comment' => '[[:Testpage]] added to category',
+                               'rc_comment_text' => '[[:Testpage]] added to category',
+                               'rc_comment_data' => null,
                                'rc_old_len' => 0,
                                'rc_new_len' => 0,
                        ]
@@ -139,6 +141,8 @@ class TestRecentChangesHelper {
                        'rc_old_len' => 212,
                        'rc_new_len' => 188,
                        'rc_comment' => '',
+                       'rc_comment_text' => '',
+                       'rc_comment_data' => null,
                        'rc_minor' => 0,
                        'rc_bot' => 0,
                        'rc_type' => 0,
index c13cf25..ebe1972 100644 (file)
@@ -383,7 +383,7 @@ class EtcConfigTest extends PHPUnit_Framework_TestCase {
                                        false // retry
                                ],
                        ],
-                       '200 OK - Skip dir' => [
+                       '200 OK - Empty dir' => [
                                'http' => [
                                        'code' => 200,
                                        'reason' => 'OK',
@@ -395,7 +395,8 @@ class EtcConfigTest extends PHPUnit_Framework_TestCase {
                                                ],
                                                [
                                                        'key' => '/example/sub',
-                                                       'dir' => true
+                                                       'dir' => true,
+                                                       'nodes' => [],
                                                ],
                                                [
                                                        'key' => '/example/bar',
@@ -410,6 +411,68 @@ class EtcConfigTest extends PHPUnit_Framework_TestCase {
                                        false // retry
                                ],
                        ],
+                       '200 OK - Recursive' => [
+                               'http' => [
+                                       'code' => 200,
+                                       'reason' => 'OK',
+                                       'headers' => [],
+                                       'body' => json_encode( [ 'node' => [ 'nodes' => [
+                                               [
+                                                       'key' => '/example/a',
+                                                       'dir' => true,
+                                                       'nodes' => [
+                                                               [
+                                                                       'key' => 'b',
+                                                                       'value' => json_encode( [ 'val' => true ] ),
+                                                               ],
+                                                               [
+                                                                       'key' => 'c',
+                                                                       'value' => json_encode( [ 'val' => false ] ),
+                                                               ],
+                                                       ],
+                                               ],
+                                       ] ] ] ),
+                                       'error' => '',
+                               ],
+                               'expect' => [
+                                       [ 'a/b' => true, 'a/c' => false ], // data
+                                       null,
+                                       false // retry
+                               ],
+                       ],
+                       '200 OK - Missing nodes at second level' => [
+                               'http' => [
+                                       'code' => 200,
+                                       'reason' => 'OK',
+                                       'headers' => [],
+                                       'body' => json_encode( [ 'node' => [ 'nodes' => [
+                                               [
+                                                       'key' => '/example/a',
+                                                       'dir' => true,
+                                               ],
+                                       ] ] ] ),
+                                       'error' => '',
+                               ],
+                               'expect' => [
+                                       null,
+                                       "Unexpected JSON response in dir 'a'; missing 'nodes' list.",
+                                       false // retry
+                               ],
+                       ],
+                       '200 OK - Correctly encoded garbage response' => [
+                               'http' => [
+                                       'code' => 200,
+                                       'reason' => 'OK',
+                                       'headers' => [],
+                                       'body' => json_encode( [ 'foo' => 'bar' ] ),
+                                       'error' => '',
+                               ],
+                               'expect' => [
+                                       null,
+                                       "Unexpected JSON response: Missing or invalid node at top level.",
+                                       false // retry
+                               ],
+                       ],
                        '200 OK - Bad value' => [
                                'http' => [
                                        'code' => 200,
@@ -453,7 +516,7 @@ class EtcConfigTest extends PHPUnit_Framework_TestCase {
                                ],
                                'expect' => [
                                        null, // data
-                                       "Unexpected JSON response; missing 'nodes' list.",
+                                       "Error unserializing JSON response.",
                                        false // retry
                                ],
                        ],
@@ -491,6 +554,9 @@ class EtcConfigTest extends PHPUnit_Framework_TestCase {
        /**
         * @covers EtcdConfig::fetchAllFromEtcdServer
         * @covers EtcdConfig::unserialize
+        * @covers EtcdConfig::parseResponse
+        * @covers EtcdConfig::parseDirectory
+        * @covers EtcdConfigParseError
         * @dataProvider provideFetchFromServer
         */
        public function testFetchFromServer( array $httpResponse, array $expected ) {
index 639c323..4c0a5fa 100644 (file)
@@ -378,16 +378,33 @@ class LinksUpdateTest extends MediaWikiLangTestCase {
        protected function assertRecentChangeByCategorization(
                Title $pageTitle, ParserOutput $parserOutput, Title $categoryTitle, $expectedRows
        ) {
-               $this->assertSelect(
-                       'recentchanges',
-                       'rc_title, rc_comment',
-                       [
-                               'rc_type' => RC_CATEGORIZE,
-                               'rc_namespace' => NS_CATEGORY,
-                               'rc_title' => $categoryTitle->getDBkey()
-                       ],
-                       $expectedRows
-               );
+               global $wgCommentTableSchemaMigrationStage;
+
+               if ( $wgCommentTableSchemaMigrationStage <= MIGRATION_WRITE_BOTH ) {
+                       $this->assertSelect(
+                               'recentchanges',
+                               'rc_title, rc_comment',
+                               [
+                                       'rc_type' => RC_CATEGORIZE,
+                                       'rc_namespace' => NS_CATEGORY,
+                                       'rc_title' => $categoryTitle->getDBkey()
+                               ],
+                               $expectedRows
+                       );
+               }
+               if ( $wgCommentTableSchemaMigrationStage >= MIGRATION_WRITE_BOTH ) {
+                       $this->assertSelect(
+                               [ 'recentchanges', 'comment' ],
+                               'rc_title, comment_text',
+                               [
+                                       'rc_type' => RC_CATEGORIZE,
+                                       'rc_namespace' => NS_CATEGORY,
+                                       'rc_title' => $categoryTitle->getDBkey(),
+                                       'comment_id = rc_comment_id',
+                               ],
+                               $expectedRows
+                       );
+               }
        }
 
        private function runAllRelatedJobs() {
index 307652d..e47c4ba 100644 (file)
@@ -237,7 +237,7 @@ class IPTest extends PHPUnit_Framework_TestCase {
                ];
                foreach ( $ipCIDRs as $i ) {
                        $this->assertFalse( IP::isValid( $i ),
-                               "$i is an invalid IP address because it is a block" );
+                               "$i is an invalid IP address because it is a range" );
                }
                // Incomplete/garbage
                $invalid = [
@@ -254,9 +254,9 @@ class IPTest extends PHPUnit_Framework_TestCase {
        }
 
        /**
-        * Provide some valid IP blocks
+        * Provide some valid IP ranges
         */
-       public function provideValidBlocks() {
+       public function provideValidRanges() {
                return [
                        [ '116.17.184.5/32' ],
                        [ '0.17.184.5/30' ],
@@ -274,22 +274,22 @@ class IPTest extends PHPUnit_Framework_TestCase {
        }
 
        /**
-        * @covers IP::isValidBlock
-        * @dataProvider provideValidBlocks
+        * @covers IP::isValidRange
+        * @dataProvider provideValidRanges
         */
-       public function testValidBlocks( $block ) {
-               $this->assertTrue( IP::isValidBlock( $block ), "$block is a valid IP block" );
+       public function testValidRanges( $range ) {
+               $this->assertTrue( IP::isValidRange( $range ), "$range is a valid IP range" );
        }
 
        /**
-        * @covers IP::isValidBlock
-        * @dataProvider provideInvalidBlocks
+        * @covers IP::isValidRange
+        * @dataProvider provideInvalidRanges
         */
-       public function testInvalidBlocks( $invalid ) {
-               $this->assertFalse( IP::isValidBlock( $invalid ), "$invalid is not a valid IP block" );
+       public function testInvalidRanges( $invalid ) {
+               $this->assertFalse( IP::isValidRange( $invalid ), "$invalid is not a valid IP range" );
        }
 
-       public function provideInvalidBlocks() {
+       public function provideInvalidRanges() {
                return [
                        [ '116.17.184.5/33' ],
                        [ '0.17.184.5/130' ],
index c289839..2dc9a2c 100644 (file)
@@ -39,7 +39,8 @@ abstract class LogFormatterTestCase extends MediaWikiLangTestCase {
                        'log_namespace' => isset( $data['namespace'] ) ? $data['namespace'] : NS_MAIN,
                        'log_title' => isset( $data['title'] ) ? $data['title'] : 'Main_Page',
                        'log_page' => isset( $data['page'] ) ? $data['page'] : 0,
-                       'log_comment' => isset( $data['comment'] ) ? $data['comment'] : '',
+                       'log_comment_text' => isset( $data['comment'] ) ? $data['comment'] : '',
+                       'log_comment_data' => null,
                        'log_params' => $legacy
                                ? LogPage::makeParamBlob( $data['params'] )
                                : LogEntryBase::makeParamBlob( $data['params'] ),
index a9f74b6..d0fefde 100644 (file)
@@ -17,6 +17,7 @@ class WikiPageTest extends MediaWikiLangTestCase {
                        $this->tablesUsed,
                        [ 'page',
                                'revision',
+                               'archive',
                                'text',
 
                                'recentchanges',
@@ -1123,4 +1124,84 @@ more stuff
                $page = WikiPage::factory( $title );
                $this->assertEquals( 'WikiPage', get_class( $page ) );
        }
+
+       /**
+        * @dataProvider provideCommentMigrationOnDeletion
+        * @param int $wstage
+        * @param int $rstage
+        */
+       public function testCommentMigrationOnDeletion( $wstage, $rstage ) {
+               $this->setMwGlobals( 'wgCommentTableSchemaMigrationStage', $wstage );
+               $dbr = wfGetDB( DB_REPLICA );
+
+               $page = $this->createPage(
+                       "WikiPageTest_testCommentMigrationOnDeletion",
+                       "foo",
+                       CONTENT_MODEL_WIKITEXT
+               );
+               $revid = $page->getLatest();
+               if ( $wstage > MIGRATION_OLD ) {
+                       $comment_id = $dbr->selectField(
+                               'revision_comment_temp',
+                               'revcomment_comment_id',
+                               [ 'revcomment_rev' => $revid ],
+                               __METHOD__
+                       );
+               }
+
+               $this->setMwGlobals( 'wgCommentTableSchemaMigrationStage', $rstage );
+
+               $page->doDeleteArticle( "testing deletion" );
+
+               if ( $rstage > MIGRATION_OLD ) {
+                       // Didn't leave behind any 'revision_comment_temp' rows
+                       $n = $dbr->selectField(
+                               'revision_comment_temp', 'COUNT(*)', [ 'revcomment_rev' => $revid ], __METHOD__
+                       );
+                       $this->assertEquals( 0, $n, 'no entry in revision_comment_temp after deletion' );
+
+                       // Copied or upgraded the comment_id, as applicable
+                       $ar_comment_id = $dbr->selectField(
+                               'archive',
+                               'ar_comment_id',
+                               [ 'ar_rev_id' => $revid ],
+                               __METHOD__
+                       );
+                       if ( $wstage > MIGRATION_OLD ) {
+                               $this->assertSame( $comment_id, $ar_comment_id );
+                       } else {
+                               $this->assertNotEquals( 0, $ar_comment_id );
+                       }
+               }
+
+               // Copied rev_comment, if applicable
+               if ( $rstage <= MIGRATION_WRITE_BOTH && $wstage <= MIGRATION_WRITE_BOTH ) {
+                       $ar_comment = $dbr->selectField(
+                               'archive',
+                               'ar_comment',
+                               [ 'ar_rev_id' => $revid ],
+                               __METHOD__
+                       );
+                       $this->assertSame( 'testing', $ar_comment );
+               }
+       }
+
+       public static function provideCommentMigrationOnDeletion() {
+               return [
+                       [ MIGRATION_OLD, MIGRATION_OLD ],
+                       [ MIGRATION_OLD, MIGRATION_WRITE_BOTH ],
+                       [ MIGRATION_OLD, MIGRATION_WRITE_NEW ],
+                       [ MIGRATION_WRITE_BOTH, MIGRATION_OLD ],
+                       [ MIGRATION_WRITE_BOTH, MIGRATION_WRITE_BOTH ],
+                       [ MIGRATION_WRITE_BOTH, MIGRATION_WRITE_NEW ],
+                       [ MIGRATION_WRITE_BOTH, MIGRATION_NEW ],
+                       [ MIGRATION_WRITE_NEW, MIGRATION_WRITE_BOTH ],
+                       [ MIGRATION_WRITE_NEW, MIGRATION_WRITE_NEW ],
+                       [ MIGRATION_WRITE_NEW, MIGRATION_NEW ],
+                       [ MIGRATION_NEW, MIGRATION_WRITE_BOTH ],
+                       [ MIGRATION_NEW, MIGRATION_WRITE_NEW ],
+                       [ MIGRATION_NEW, MIGRATION_NEW ],
+               ];
+       }
+
 }
index c93fe47..3d0d344 100644 (file)
@@ -140,7 +140,7 @@ class SpecialPageDataTest extends SpecialPageTestBase {
                list( $output, ) = $this->executeSpecialPage( '', $request );
 
                $this->assertContains(
-                       "Content negotiation applies based on you client's Accept header.",
+                       "Content negotiation applies based on your client's Accept header.",
                        $output,
                        "output"
                );
diff --git a/tests/phpunit/maintenance/categoriesRdfTest.php b/tests/phpunit/maintenance/categoriesRdfTest.php
new file mode 100644 (file)
index 0000000..ec2746e
--- /dev/null
@@ -0,0 +1,72 @@
+<?php
+
+class CategoriesRdfTest extends MediaWikiLangTestCase {
+       public function getCategoryIterator() {
+               return [
+                       // batch 1
+                       [
+                               (object)[ 'page_title' => 'Category One', 'page_id' => 1 ],
+                               (object)[ 'page_title' => '2 Category Two', 'page_id' => 2 ],
+                       ],
+                       // batch 2
+                       [
+                               (object)[ 'page_title' => 'Третья категория', 'page_id' => 3 ],
+                       ]
+               ];
+       }
+
+       public function getCategoryLinksIterator( $dbr, array $ids ) {
+               $res = [];
+               foreach ( $ids as $pageid ) {
+                       $res[] = (object)[ 'cl_from' => $pageid, 'cl_to' => "Parent of $pageid" ];
+               }
+               return $res;
+       }
+
+       public function testCategoriesDump() {
+               $this->setMwGlobals( [
+                       'wgServer' => 'http://acme.test',
+                       'wgCanonicalServer' => 'http://acme.test',
+                       'wgArticlePath' => '/wiki/$1',
+                       'wgRightsUrl' => '//creativecommons.org/licenses/by-sa/3.0/',
+               ] );
+
+               $dumpScript =
+                       $this->getMockBuilder( DumpCategoriesAsRdf::class )
+                               ->setMethods( [ 'getCategoryIterator', 'getCategoryLinksIterator' ] )
+                               ->getMock();
+
+               $dumpScript->expects( $this->once() )
+                       ->method( 'getCategoryIterator' )
+                       ->willReturn( $this->getCategoryIterator() );
+
+               $dumpScript->expects( $this->any() )
+                       ->method( 'getCategoryLinksIterator' )
+                       ->willReturnCallback( [ $this, 'getCategoryLinksIterator' ] );
+
+               /** @var DumpCategoriesAsRdf  $dumpScript */
+               $logFileName = tempnam( sys_get_temp_dir(), "Categories-DumpRdfTest" );
+               $outFileName = tempnam( sys_get_temp_dir(), "Categories-DumpRdfTest" );
+
+               $dumpScript->loadParamsAndArgs(
+                       null,
+                       [
+                               'log' => $logFileName,
+                               'output' => $outFileName,
+                               'format' => 'nt',
+                       ]
+               );
+
+               $dumpScript->execute();
+               $actualOut = file_get_contents( $outFileName );
+               $actualOut = preg_replace(
+                       '|<http://acme.test/categoriesDump> <http://schema.org/dateModified> "[^"]+?"|',
+                       '<http://acme.test/categoriesDump> <http://schema.org/dateModified> "{DATE}"',
+                       $actualOut
+               );
+
+               $outFile = __DIR__ . '/../data/categoriesrdf/categoriesRdf-out.nt';
+               $this->assertFileContains( $outFile, $actualOut );
+       }
+
+}
index 09052f3..4ea1090 100644 (file)
@@ -82,15 +82,15 @@ class ParserTestTopLevelSuite extends PHPUnit_Framework_TestSuite {
 
                # Filter out .txt files
                $files = ParserTestRunner::getParserTestFiles();
-               foreach ( $files as $parserTestFile ) {
+               foreach ( $files as $extName => $parserTestFile ) {
                        $isCore = ( 0 === strpos( $parserTestFile, $mwTestDir ) );
 
                        if ( $isCore && $wantsCore ) {
                                self::debug( "included core parser tests: $parserTestFile" );
-                               $filesToTest[] = $parserTestFile;
+                               $filesToTest[$extName] = $parserTestFile;
                        } elseif ( !$isCore && $wantsRest ) {
                                self::debug( "included non core parser tests: $parserTestFile" );
-                               $filesToTest[] = $parserTestFile;
+                               $filesToTest[$extName] = $parserTestFile;
                        } else {
                                self::debug( "skipped parser tests: $parserTestFile" );
                        }
@@ -100,12 +100,13 @@ class ParserTestTopLevelSuite extends PHPUnit_Framework_TestSuite {
 
                $testList = [];
                $counter = 0;
-               foreach ( $filesToTest as $fileName ) {
-                       // Call the highest level directory the extension name.
-                       // It may or may not actually be, but it should be close
-                       // enough to cause there to be separate names for different
-                       // things, which is good enough for our purposes.
-                       $extensionName = basename( dirname( $fileName ) );
+               foreach ( $filesToTest as $extensionName => $fileName ) {
+                       if ( is_int( $extensionName ) ) {
+                               // If there's no extension name because this is coming
+                               // from the legacy global, then assume the next level directory
+                               // is the extension name (e.g. extensions/FooBar/parserTests.txt).
+                               $extensionName = basename( dirname( $fileName ) );
+                       }
                        $testsName = $extensionName . '__' . basename( $fileName, '.txt' );
                        $parserTestClassName = ucfirst( $testsName );
 
index 257699a..01589c3 100644 (file)
        parserTest( 'Y Dates', 'date', YDates );
 
        ISODates = [
-               [ '2000',               false,  946684800000, 'Plain 4-digit year' ],
+               [ '',           false,  -Infinity, 'Not a date' ],
+               [ '2000',       false,  946684800000, 'Plain 4-digit year' ],
                [ '2000-01',    true,   946684800000, 'Year with month' ],
                [ '2000-01-01', true,   946684800000, 'Year with month and day' ],
                [ '2000-13-01', false,  978307200000, 'Non existant month' ],
index f3e4877..32a7712 100644 (file)
@@ -48,7 +48,8 @@ exports.config = {
        specs: [
                relPath( './tests/selenium/specs/**/*.js' ),
                relPath( './extensions/*/tests/selenium/specs/**/*.js' ),
-               relPath( './extensions/VisualEditor/modules/ve-mw/tests/selenium/specs/**/*.js' )
+               relPath( './extensions/VisualEditor/modules/ve-mw/tests/selenium/specs/**/*.js' ),
+               relPath( './skins/*/tests/selenium/specs/**/*.js' ),
        ],
        // Patterns to exclude.
        exclude: [