Merge "Allow callback functions for creating jobs"
authorjenkins-bot <jenkins-bot@gerrit.wikimedia.org>
Tue, 9 May 2017 18:38:57 +0000 (18:38 +0000)
committerGerrit Code Review <gerrit@wikimedia.org>
Tue, 9 May 2017 18:38:57 +0000 (18:38 +0000)
198 files changed:
.mailmap
CREDITS
HISTORY
RELEASE-NOTES-1.30
autoload.php
composer.json
docs/hooks.txt
includes/DefaultSettings.php
includes/EditPage.php
includes/GlobalFunctions.php
includes/Preferences.php
includes/SiteStats.php
includes/Title.php
includes/api/ApiParse.php
includes/api/ApiQueryAllImages.php
includes/api/ApiQueryAllUsers.php
includes/api/ApiQueryContributors.php
includes/api/ApiQueryRevisions.php
includes/api/ApiQueryTags.php
includes/api/ApiQueryUsers.php
includes/api/ApiUserrights.php
includes/api/i18n/de.json
includes/api/i18n/en.json
includes/api/i18n/es.json
includes/api/i18n/fr.json
includes/api/i18n/he.json
includes/api/i18n/hu.json
includes/api/i18n/it.json
includes/api/i18n/qqq.json
includes/api/i18n/zh-hans.json
includes/cache/MessageCache.php
includes/changetags/ChangeTags.php
includes/config/EtcdConfig.php
includes/content/FileContentHandler.php
includes/installer/DatabaseUpdater.php
includes/installer/LocalSettingsGenerator.php
includes/installer/MssqlUpdater.php
includes/installer/i18n/hi.json
includes/installer/i18n/nl.json
includes/interwiki/Interwiki.php
includes/interwiki/InterwikiLookup.php
includes/interwiki/InterwikiLookupAdapter.php
includes/jobqueue/jobs/RecentChangesUpdateJob.php
includes/libs/CSSMin.php
includes/libs/IEUrlExtension.php
includes/libs/mime/IEContentAnalyzer.php
includes/libs/mime/MimeAnalyzer.php
includes/libs/rdbms/database/DBConnRef.php
includes/libs/rdbms/database/Database.php
includes/libs/rdbms/loadmonitor/LoadMonitorNull.php
includes/libs/stats/SamplingStatsdClient.php
includes/libs/xmp/XMP.php
includes/page/Article.php
includes/parser/Parser.php
includes/parser/ParserDiffTest.php
includes/parser/ParserOptions.php
includes/search/SearchEngine.php
includes/services/ServiceContainer.php
includes/specialpage/ChangesListSpecialPage.php
includes/specials/SpecialRecentchanges.php
includes/specials/SpecialSearch.php
includes/specials/SpecialUserrights.php
includes/specials/pagers/ActiveUsersPager.php
includes/specials/pagers/ContribsPager.php
includes/specials/pagers/NewFilesPager.php
includes/specials/pagers/UsersPager.php
includes/user/User.php
includes/user/UserGroupMembership.php
includes/utils/AutoloadGenerator.php
includes/utils/BatchRowIterator.php
includes/widget/search/InterwikiSearchResultSetWidget.php
includes/widget/search/InterwikiSearchResultWidget.php
includes/widget/search/SimpleSearchResultSetWidget.php
languages/FakeConverter.php
languages/i18n/ar.json
languages/i18n/arz.json
languages/i18n/atj.json
languages/i18n/be-tarask.json
languages/i18n/bn.json
languages/i18n/bs.json
languages/i18n/ca.json
languages/i18n/cs.json
languages/i18n/da.json
languages/i18n/en.json
languages/i18n/es.json
languages/i18n/et.json
languages/i18n/eu.json
languages/i18n/fi.json
languages/i18n/fr.json
languages/i18n/gl.json
languages/i18n/he.json
languages/i18n/hi.json
languages/i18n/hr.json
languages/i18n/hu.json
languages/i18n/ia.json
languages/i18n/ja.json
languages/i18n/ka.json
languages/i18n/kn.json
languages/i18n/ko.json
languages/i18n/lb.json
languages/i18n/lv.json
languages/i18n/mk.json
languages/i18n/nb.json
languages/i18n/ne.json
languages/i18n/nl.json
languages/i18n/pl.json
languages/i18n/pms.json
languages/i18n/qqq.json
languages/i18n/ru.json
languages/i18n/sd.json
languages/i18n/sr-ec.json
languages/i18n/sr-el.json
languages/i18n/su.json
languages/i18n/sv.json
languages/i18n/zh-hans.json
maintenance/benchmarks/benchmarkCSSMin.php [new file with mode: 0644]
maintenance/benchmarks/cssmin/circle.svg [new file with mode: 0644]
maintenance/benchmarks/cssmin/styles.css [new file with mode: 0644]
maintenance/benchmarks/cssmin/wiki.png [new file with mode: 0644]
maintenance/cleanupInvalidDbKeys.php
maintenance/updateCredits.php
package.json
phpcs.xml
resources/Resources.php
resources/lib/jquery.ui/PATCHES
resources/lib/jquery.ui/jquery.ui.core.js
resources/lib/jquery.ui/jquery.ui.widget.js
resources/src/mediawiki.action/mediawiki.action.edit.preview.js
resources/src/mediawiki.action/mediawiki.action.view.postEdit.js
resources/src/mediawiki.language/specialcharacters.json
resources/src/mediawiki.less/mediawiki.mixins.less
resources/src/mediawiki.rcfilters/dm/mw.rcfilters.dm.FilterGroup.js
resources/src/mediawiki.rcfilters/dm/mw.rcfilters.dm.FiltersViewModel.js
resources/src/mediawiki.rcfilters/dm/mw.rcfilters.dm.SavedQueriesModel.js [new file with mode: 0644]
resources/src/mediawiki.rcfilters/dm/mw.rcfilters.dm.SavedQueryItemModel.js [new file with mode: 0644]
resources/src/mediawiki.rcfilters/images/clip.svg [new file with mode: 0644]
resources/src/mediawiki.rcfilters/images/pushPin.svg [new file with mode: 0644]
resources/src/mediawiki.rcfilters/images/unClip.svg [new file with mode: 0644]
resources/src/mediawiki.rcfilters/mw.rcfilters.Controller.js
resources/src/mediawiki.rcfilters/mw.rcfilters.init.js
resources/src/mediawiki.rcfilters/styles/mw.rcfilters.ui.FilterTagMultiselectWidget.less
resources/src/mediawiki.rcfilters/styles/mw.rcfilters.ui.SaveFiltersPopupButtonWidget.less [new file with mode: 0644]
resources/src/mediawiki.rcfilters/styles/mw.rcfilters.ui.SavedLinksListItemWidget.less [new file with mode: 0644]
resources/src/mediawiki.rcfilters/styles/mw.rcfilters.ui.SavedLinksListWidget.less [new file with mode: 0644]
resources/src/mediawiki.rcfilters/styles/mw.rcfilters.ui.less
resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.FilterTagMultiselectWidget.js
resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.FilterWrapperWidget.js
resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.SaveFiltersPopupButtonWidget.js [new file with mode: 0644]
resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.SavedLinksListItemWidget.js [new file with mode: 0644]
resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.SavedLinksListWidget.js [new file with mode: 0644]
resources/src/mediawiki.special/images/special.search/book-icon.png [deleted file]
resources/src/mediawiki.special/images/special.search/book-icon.svg [deleted file]
resources/src/mediawiki.special/images/special.search/course-icon.png [deleted file]
resources/src/mediawiki.special/images/special.search/course-icon.svg [deleted file]
resources/src/mediawiki.special/images/special.search/definition-icon.png [deleted file]
resources/src/mediawiki.special/images/special.search/definition-icon.svg [deleted file]
resources/src/mediawiki.special/images/special.search/dna-icon.png [deleted file]
resources/src/mediawiki.special/images/special.search/dna-icon.svg [deleted file]
resources/src/mediawiki.special/images/special.search/image-icon.png [deleted file]
resources/src/mediawiki.special/images/special.search/image-icon.svg [deleted file]
resources/src/mediawiki.special/images/special.search/news-icon.png [deleted file]
resources/src/mediawiki.special/images/special.search/news-icon.svg [deleted file]
resources/src/mediawiki.special/images/special.search/quotation-icon.png [deleted file]
resources/src/mediawiki.special/images/special.search/quotation-icon.svg [deleted file]
resources/src/mediawiki.special/images/special.search/textbook-icon.png [deleted file]
resources/src/mediawiki.special/images/special.search/textbook-icon.svg [deleted file]
resources/src/mediawiki.special/images/special.search/travel-icon.png [deleted file]
resources/src/mediawiki.special/images/special.search/travel-icon.svg [deleted file]
resources/src/mediawiki.special/mediawiki.special.apisandbox.js
resources/src/mediawiki.special/mediawiki.special.search.commonsInterwikiWidget.js
resources/src/mediawiki.special/mediawiki.special.search.interwikiwidget.styles.less
resources/src/mediawiki.widgets/mw.widgets.UsersMultiselectWidget.js
resources/src/mediawiki/mediawiki.confirmCloseWindow.js
resources/src/mediawiki/mediawiki.inspect.js
tests/parser/ParserTestRunner.php
tests/parser/parserTests.txt
tests/phpunit/includes/ExtraParserTest.php
tests/phpunit/includes/changes/ChangesListFilterTest.php
tests/phpunit/includes/config/GlobalVarConfigTest.php
tests/phpunit/includes/config/MultiConfigTest.php
tests/phpunit/includes/content/WikitextContentTest.php
tests/phpunit/includes/db/DatabaseMysqlBaseTest.php
tests/phpunit/includes/deferred/DeferredUpdatesTest.php
tests/phpunit/includes/interwiki/InterwikiLookupAdapterTest.php
tests/phpunit/includes/libs/CSSMinTest.php
tests/phpunit/includes/libs/DnsSrvDiscovererTest.php
tests/phpunit/includes/media/JpegTest.php
tests/phpunit/includes/page/WikiPageTest.php
tests/phpunit/includes/parser/TagHooksTest.php
tests/phpunit/includes/resourceloader/ResourceLoaderWikiModuleTest.php
tests/phpunit/includes/search/SearchIndexFieldTest.php
tests/phpunit/includes/specialpage/AbstractChangesListSpecialPageTestCase.php
tests/phpunit/includes/specialpage/ChangesListSpecialPageTest.php
tests/phpunit/includes/specials/SpecialRecentchangesTest.php
tests/phpunit/includes/specials/SpecialWatchlistTest.php
tests/qunit/suites/resources/mediawiki.rcfilters/dm.FiltersViewModel.test.js
tests/qunit/suites/resources/mediawiki/mediawiki.loader.test.js
tests/selenium/.eslintrc.json

index f056219..ae18878 100644 (file)
--- a/.mailmap
+++ b/.mailmap
@@ -196,6 +196,7 @@ Jackmcbarn <jackmcbarn@gmail.com>
 Jackmcbarn <jackmcbarn@gmail.com> <jackmcbarn@users.noreply.github.com>
 jagori <jagori79@gmail.com>
 James Forrester <jforrester@wikimedia.org>
+Jaime Crespo <jcrespo@wikimedia.org>
 Jan Gerber <j@thing.net> <j@users.mediawiki.org>
 Jan Luca Naumann <jan@jans-seite.de>
 Jan Luca Naumann <jan@jans-seite.de> <jan@users.mediawiki.org>
@@ -409,9 +410,10 @@ Steven Walling <swalling@wikimedia.org>
 Subramanya Sastry <ssastry@wikimedia.org>
 Sucheta Ghoshal <sghoshal@wikimedia.org>
 Sumit Asthana <asthana.sumit23@gmail.com>
+TerraCodes <terracodes@tools.wmflabs.org>
 Thalia Chan <thalia@cantorion.org>
-Thiemo Mättig (WMDE) <thiemo.maettig@wikimedia.de>
-Thiemo Mättig (WMDE) <thiemo.maettig@wikimedia.de> <mr.heat@gmx.de>
+Thiemo Mättig <thiemo.maettig@wikimedia.de>
+Thiemo Mättig <thiemo.maettig@wikimedia.de> <mr.heat@gmx.de>
 This, that and the other <at.light@live.com.au>
 tholam <t.lam@lamsinfosystem.com>
 Thomas Bleher <ThomasBleher@gmx.de> <tbleher@users.mediawiki.org>
diff --git a/CREDITS b/CREDITS
index 80d4e0e..1530425 100644 (file)
--- a/CREDITS
+++ b/CREDITS
@@ -48,6 +48,7 @@ The following list can be found parsed under Special:Version/Credits -->
 * ananay
 * Anders Wegge Jakobsen
 * Andre Engels
+* Andre Klapper
 * Andrew Bogott
 * Andrew Dunbar
 * Andrew Garrett
@@ -200,6 +201,7 @@ The following list can be found parsed under Special:Version/Credits -->
 * Erik Moeller
 * Erwin Dokter
 * Étienne Beaulé
+* Eugene Gvozdetsky
 * Evan McIntire
 * Evan Prodromou
 * ExplosiveHippo
@@ -257,6 +259,7 @@ The following list can be found parsed under Special:Version/Credits -->
 * Jacob Block
 * Jacob Clark
 * jagori
+* Jaime Crespo
 * Jakub Vrana
 * James Earl Douglas
 * James Forrester
@@ -366,6 +369,7 @@ The following list can be found parsed under Special:Version/Credits -->
 * Madman
 * madurangasiriwardena
 * Magnus Manske
+* mainframe98
 * Manuel Menal
 * Manuel Schneider
 * Marc Ordinas i Llopis
@@ -421,6 +425,7 @@ The following list can be found parsed under Special:Version/Credits -->
 * Michał Roszka
 * Michał Zieliński
 * Mike Horvath
+* Mikhail Popov
 * Minh Nguyễn
 * MinuteElectron
 * Misza13
@@ -455,7 +460,6 @@ The following list can be found parsed under Special:Version/Credits -->
 * Nicolas Dumazet
 * Nicolas Weeger
 * Niharika Kohli
-* Nik
 * Nik Everett
 * Niklas Laxström
 * Nikola Kovacs
@@ -610,10 +614,10 @@ The following list can be found parsed under Special:Version/Credits -->
 * Subramanya Sastry
 * Sumit Asthana
 * svip
-* Swalling
 * Szymon Świerkosz
 * T.D. Corell
 * Tarquin
+* TerraCodes
 * The Discoverer
 * The Evil IP address
 * theopolisme
diff --git a/HISTORY b/HISTORY
index be90221..9259814 100644 (file)
--- a/HISTORY
+++ b/HISTORY
@@ -27,9 +27,6 @@ Change notes from older releases. For current info see RELEASE-NOTES-1.30.
   $wgNamespacesWithSubpages[NS_TEMPLATE] to false to keep the old behavior.
 * $wgRunJobsAsync is now false by default (T142751). This change only affects
   wikis with $wgJobRunRate > 0.
-* A temporary feature flag, $wgDisableUserGroupExpiry, is provided to disable
-  new features that rely on the schema changes to the user_groups table. This
-  feature flag will likely be removed before 1.29 is released.
 * (T158474) "Unknown user" has been added to $wgReservedUsernames.
 * (T156983) $wgRateLimitsExcludedIPs now accepts CIDR ranges as well as single IPs.
 * $wgDummyLanguageCodes is deprecated. Additional language code mappings may be
index 5370c6d..dd2841c 100644 (file)
@@ -19,7 +19,11 @@ production.
   to allow for proper dependency injection.
 
 === New features in 1.30 ===
-* …
+* (T37247) Output from Parser::parse() will now be wrapped in a div with
+  class="mw-parser-output" by default. This may be changed or disabled using
+  ParserOptions::setWrapOutputClass().
+* Added 'ChangeTagsAllowedAdd' hook, enabling extensions to allow software-
+  specific tags to be added by users.
 
 === External library changes in 1.30 ===
 
@@ -36,7 +40,9 @@ production.
 * …
 
 === Action API changes in 1.30 ===
-* …
+* (T37247) action=parse output will be wrapped in a div with
+  class="mw-parser-output" by default. This may be changed or disabled using
+  the new 'wrapoutputclass' parameter.
 
 === Action API internal changes in 1.30 ===
 * …
index 1141c39..e5161f1 100644 (file)
@@ -188,6 +188,7 @@ $wgAutoloadLocalClasses = [
        'BenchUtf8TitleCheck' => __DIR__ . '/maintenance/benchmarks/bench_utf8_title_check.php',
        'BenchWfIsWindows' => __DIR__ . '/maintenance/benchmarks/bench_wfIsWindows.php',
        'BenchWikimediaBaseConvert' => __DIR__ . '/maintenance/benchmarks/bench_Wikimedia_base_convert.php',
+       'BenchmarkCSSMin' => __DIR__ . '/maintenance/benchmarks/benchmarkCSSMin.php',
        'BenchmarkDeleteTruncate' => __DIR__ . '/maintenance/benchmarks/bench_delete_truncate.php',
        'BenchmarkHooks' => __DIR__ . '/maintenance/benchmarks/benchmarkHooks.php',
        'BenchmarkParse' => __DIR__ . '/maintenance/benchmarks/benchmarkParse.php',
index ed42b60..76ae28c 100644 (file)
@@ -53,7 +53,7 @@
                "jakub-onderka/php-parallel-lint": "0.9.2",
                "jetbrains/phpstorm-stubs": "dev-master#1b9906084d6635456fcf3f3a01f0d7d5b99a578a",
                "justinrainbow/json-schema": "~3.0",
-               "mediawiki/mediawiki-codesniffer": "0.7.2",
+               "mediawiki/mediawiki-codesniffer": "0.8.0",
                "monolog/monolog": "~1.22.1",
                "nikic/php-parser": "2.1.0",
                "nmred/kafka-php": "0.1.5",
index 7c09a55..d95e39b 100644 (file)
@@ -1070,6 +1070,13 @@ $params: tag params
 $rc: RecentChange being tagged when the tagging accompanies the action or null
 $user: User who performed the tagging when the tagging is subsequent to the action or null
 
+'ChangeTagsAllowedAdd': Called when checking if a user can add tags to a change.
+&$allowedTags: List of all the tags the user is allowed to add. Any tags the
+  user wants to add ($addTags) that are not in this array will cause it to fail.
+  You may add or remove tags to this array as required.
+$addTags: List of tags user intends to add.
+$user: User who is adding the tags.
+
 'ChangeUserGroups': Called before user groups are changed.
 $performer: The User who will perform the change
 $user: The User whose groups will be changed
index a6bc7e5..09a614c 100644 (file)
@@ -5912,15 +5912,6 @@ $wgBotPasswordsCluster = false;
  */
 $wgBotPasswordsDatabase = false;
 
-/**
- * Whether to disable user group expiry. This is a transitional feature flag
- * in accordance with WMF schema change policy, and will be removed later
- * (hopefully before MW 1.29 release).
- *
- * @since 1.29
- */
-$wgDisableUserGroupExpiry = false;
-
 /** @} */ # end of user rights settings
 
 /************************************************************************//**
index 6424ca6..b1f50f0 100644 (file)
@@ -1452,10 +1452,8 @@ class EditPage {
         * This uses a temporary cookie for each revision ID so separate saves will never
         * interfere with each other.
         *
-        * The cookie is deleted in the mediawiki.action.view.postEdit JS module after
-        * the redirect.  It must be clearable by JavaScript code, so it must not be
-        * marked HttpOnly. The JavaScript code converts the cookie to a wgPostEdit config
-        * variable.
+        * Article::view deletes the cookie on server-side after the redirect and
+        * converts the value to the global JavaScript variable wgPostEdit.
         *
         * If the variable were set on the server, it would be cached, which is unwanted
         * since the post-edit state should only apply to the load right after the save.
@@ -1474,9 +1472,7 @@ class EditPage {
                }
 
                $response = RequestContext::getMain()->getRequest()->response();
-               $response->setCookie( $postEditKey, $val, time() + self::POST_EDIT_COOKIE_DURATION, [
-                       'httpOnly' => false,
-               ] );
+               $response->setCookie( $postEditKey, $val, time() + self::POST_EDIT_COOKIE_DURATION );
        }
 
        /**
@@ -3170,7 +3166,6 @@ class EditPage {
                        );
                        $wgOut->addHTML( "{$label} {$input}" );
                }
-
        }
 
        /**
index c7f132a..d21cc1d 100644 (file)
@@ -1436,7 +1436,6 @@ function wfMsgReplaceArgs( $message, $args ) {
 function wfHostname() {
        static $host;
        if ( is_null( $host ) ) {
-
                # Hostname overriding
                global $wgOverrideHostname;
                if ( $wgOverrideHostname !== false ) {
index b428e87..4017619 100644 (file)
@@ -915,6 +915,9 @@ class Preferences {
                        'label-message' => 'tog-hideminor',
                        'section' => 'rc/advancedrc',
                ];
+               $defaultPreferences['rcfilters-saved-queries'] = [
+                       'type' => 'api',
+               ];
 
                if ( $config->get( 'RCWatchCategoryMembership' ) ) {
                        $defaultPreferences['hidecategorization'] = [
index ac5e49e..d253805 100644 (file)
@@ -194,7 +194,6 @@ class SiteStats {
                        wfMemcKey( 'SiteStats', 'groupcounts', $group ),
                        $cache::TTL_HOUR,
                        function ( $oldValue, &$ttl, array &$setOpts ) use ( $group ) {
-                               global $wgDisableUserGroupExpiry;
                                $dbr = wfGetDB( DB_REPLICA );
 
                                $setOpts += Database::getCacheSetOptions( $dbr );
@@ -204,9 +203,7 @@ class SiteStats {
                                        'COUNT(*)',
                                        [
                                                'ug_group' => $group,
-                                               $wgDisableUserGroupExpiry ?
-                                                       '1' :
-                                                       'ug_expiry IS NULL OR ug_expiry >= ' . $dbr->addQuotes( $dbr->timestamp() )
+                                               'ug_expiry IS NULL OR ug_expiry >= ' . $dbr->addQuotes( $dbr->timestamp() )
                                        ],
                                        __METHOD__
                                );
index e460cda..a8cfad8 100644 (file)
@@ -3994,29 +3994,52 @@ class Title implements LinkTarget {
        }
 
        /**
-        * Get the revision ID of the previous revision
-        *
+        * Get next/previous revision ID relative to another revision ID
         * @param int $revId Revision ID. Get the revision that was before this one.
         * @param int $flags Title::GAID_FOR_UPDATE
-        * @return int|bool Old revision ID, or false if none exists
-        */
-       public function getPreviousRevisionID( $revId, $flags = 0 ) {
-               /* This function and getNextRevisionID have bad performance when
-                  used on a page with many revisions on mysql. An explicit extended
-                  primary key may help in some cases, if the PRIMARY KEY is banned:
-                  T159319 */
+        * @param string $dir 'next' or 'prev'
+        * @return int|bool New revision ID, or false if none exists
+        */
+       private function getRelativeRevisionID( $revId, $flags, $dir ) {
+               $revId = (int)$revId;
+               if ( $dir === 'next' ) {
+                       $op = '>';
+                       $sort = 'ASC';
+               } elseif ( $dir === 'prev' ) {
+                       $op = '<';
+                       $sort = 'DESC';
+               } else {
+                       throw new InvalidArgumentException( '$dir must be "next" or "prev"' );
+               }
+
                if ( $flags & self::GAID_FOR_UPDATE ) {
                        $db = wfGetDB( DB_MASTER );
                } else {
                        $db = wfGetDB( DB_REPLICA, 'contributions' );
                }
+
+               // Intentionally not caring if the specified revision belongs to this
+               // page. We only care about the timestamp.
+               $ts = $db->selectField( 'revision', 'rev_timestamp', [ 'rev_id' => $revId ], __METHOD__ );
+               if ( $ts === false ) {
+                       $ts = $db->selectField( 'archive', 'ar_timestamp', [ 'ar_rev_id' => $revId ], __METHOD__ );
+                       if ( $ts === false ) {
+                               // Or should this throw an InvalidArgumentException or something?
+                               return false;
+                       }
+               }
+               $ts = $db->addQuotes( $ts );
+
                $revId = $db->selectField( 'revision', 'rev_id',
                        [
                                'rev_page' => $this->getArticleID( $flags ),
-                               'rev_id < ' . intval( $revId )
+                               "rev_timestamp $op $ts OR (rev_timestamp = $ts AND rev_id $op $revId)"
                        ],
                        __METHOD__,
-                       [ 'ORDER BY' => 'rev_id DESC', 'IGNORE INDEX' => 'PRIMARY' ]
+                       [
+                               'ORDER BY' => "rev_timestamp $sort, rev_id $sort",
+                               'IGNORE INDEX' => 'rev_timestamp', // Probably needed for T159319
+                       ]
                );
 
                if ( $revId === false ) {
@@ -4026,6 +4049,17 @@ class Title implements LinkTarget {
                }
        }
 
+       /**
+        * Get the revision ID of the previous revision
+        *
+        * @param int $revId Revision ID. Get the revision that was before this one.
+        * @param int $flags Title::GAID_FOR_UPDATE
+        * @return int|bool Old revision ID, or false if none exists
+        */
+       public function getPreviousRevisionID( $revId, $flags = 0 ) {
+               return $this->getRelativeRevisionID( $revId, $flags, 'prev' );
+       }
+
        /**
         * Get the revision ID of the next revision
         *
@@ -4034,25 +4068,7 @@ class Title implements LinkTarget {
         * @return int|bool Next revision ID, or false if none exists
         */
        public function getNextRevisionID( $revId, $flags = 0 ) {
-               if ( $flags & self::GAID_FOR_UPDATE ) {
-                       $db = wfGetDB( DB_MASTER );
-               } else {
-                       $db = wfGetDB( DB_REPLICA, 'contributions' );
-               }
-               $revId = $db->selectField( 'revision', 'rev_id',
-                       [
-                               'rev_page' => $this->getArticleID( $flags ),
-                               'rev_id > ' . intval( $revId )
-                       ],
-                       __METHOD__,
-                       [ 'ORDER BY' => 'rev_id', 'IGNORE INDEX' => 'PRIMARY' ]
-               );
-
-               if ( $revId === false ) {
-                       return false;
-               } else {
-                       return intval( $revId );
-               }
+               return $this->getRelativeRevisionID( $revId, $flags, 'next' );
        }
 
        /**
@@ -4069,8 +4085,8 @@ class Title implements LinkTarget {
                                [ 'rev_page' => $pageId ],
                                __METHOD__,
                                [
-                                       'ORDER BY' => 'rev_timestamp ASC',
-                                       'IGNORE INDEX' => 'rev_timestamp'
+                                       'ORDER BY' => 'rev_timestamp ASC, rev_id ASC',
+                                       'IGNORE INDEX' => 'rev_timestamp', // See T159319
                                ]
                        );
                        if ( $row ) {
index d648968..7d22d9c 100644 (file)
@@ -478,6 +478,9 @@ class ApiParse extends ApiBase {
                if ( $params['disabletidy'] ) {
                        $popts->setTidy( false );
                }
+               $popts->setWrapOutputClass(
+                       $params['wrapoutputclass'] === '' ? false : $params['wrapoutputclass']
+               );
 
                $reset = null;
                $suppressCache = false;
@@ -788,6 +791,7 @@ class ApiParse extends ApiBase {
                                        'parsetree' => [ 'apihelp-parse-paramvalue-prop-parsetree', CONTENT_MODEL_WIKITEXT ],
                                ],
                        ],
+                       'wrapoutputclass' => 'mw-parser-output',
                        'pst' => false,
                        'onlypst' => false,
                        'effectivelanglinks' => false,
index daeedbe..250bee6 100644 (file)
@@ -205,9 +205,7 @@ class ApiQueryAllImages extends ApiQueryGeneratorBase {
                                        [
                                                'ug_group' => User::getGroupsWithPermission( 'bot' ),
                                                'ug_user = img_user',
-                                               $this->getConfig()->get( 'DisableUserGroupExpiry' ) ?
-                                                       '1' :
-                                                       'ug_expiry IS NULL OR ug_expiry >= ' . $db->addQuotes( $db->timestamp() )
+                                               'ug_expiry IS NULL OR ug_expiry >= ' . $db->addQuotes( $db->timestamp() )
                                        ]
                                ] ] );
                                $groupCond = ( $params['filterbots'] == 'nobots' ? 'NULL' : 'NOT NULL' );
index 0f0b2af..fd95e17 100644 (file)
@@ -122,9 +122,7 @@ class ApiQueryAllUsers extends ApiQueryBase {
                                        [
                                                'ug1.ug_user=user_id',
                                                'ug1.ug_group' => $params['group'],
-                                               $this->getConfig()->get( 'DisableUserGroupExpiry' ) ?
-                                                       '1' :
-                                                       'ug1.ug_expiry IS NULL OR ug1.ug_expiry >= ' . $db->addQuotes( $db->timestamp() )
+                                               'ug1.ug_expiry IS NULL OR ug1.ug_expiry >= ' . $db->addQuotes( $db->timestamp() )
                                        ]
                                ]
                        ] );
@@ -147,9 +145,7 @@ class ApiQueryAllUsers extends ApiQueryBase {
                        $this->addJoinConds( [ 'ug1' => [ 'LEFT OUTER JOIN',
                                array_merge( [
                                        'ug1.ug_user=user_id',
-                                       $this->getConfig()->get( 'DisableUserGroupExpiry' ) ?
-                                               '1' :
-                                               'ug1.ug_expiry IS NULL OR ug1.ug_expiry >= ' . $db->addQuotes( $db->timestamp() )
+                                       'ug1.ug_expiry IS NULL OR ug1.ug_expiry >= ' . $db->addQuotes( $db->timestamp() )
                                ], $exclude )
                        ] ] );
                        $this->addWhere( 'ug1.ug_user IS NULL' );
@@ -165,9 +161,7 @@ class ApiQueryAllUsers extends ApiQueryBase {
                        $this->addFields( [ 'groups' =>
                                $db->buildGroupConcatField( '|', 'user_groups', 'ug_group', [
                                        'ug_user=user_id',
-                                       $this->getConfig()->get( 'DisableUserGroupExpiry' ) ?
-                                               '1' :
-                                               'ug_expiry IS NULL OR ug_expiry >= ' . $db->addQuotes( $db->timestamp() )
+                                       'ug_expiry IS NULL OR ug_expiry >= ' . $db->addQuotes( $db->timestamp() )
                                ] )
                        ] );
                }
index 183409d..693d954 100644 (file)
@@ -163,9 +163,7 @@ class ApiQueryContributors extends ApiQueryBase {
                                [
                                        'ug_user=rev_user',
                                        'ug_group' => $limitGroups,
-                                       $this->getConfig()->get( 'DisableUserGroupExpiry' ) ?
-                                               '1' :
-                                               'ug_expiry IS NULL OR ug_expiry >= ' . $db->addQuotes( $db->timestamp() )
+                                       'ug_expiry IS NULL OR ug_expiry >= ' . $db->addQuotes( $db->timestamp() )
                                ]
                        ] ] );
                        $this->addWhereIf( 'ug_user IS NULL', $excludeGroups );
index 7b8394f..b0a8468 100644 (file)
@@ -218,10 +218,75 @@ class ApiQueryRevisions extends ApiQueryRevisionsBase {
                                );
                        }
 
-                       $this->addTimestampWhereRange( 'rev_timestamp', $params['dir'],
-                               $params['start'], $params['end'] );
-                       $this->addWhereRange( 'rev_id', $params['dir'],
-                               $params['startid'], $params['endid'] );
+                       // Convert startid/endid to timestamps (T163532)
+                       if ( $params['startid'] !== null || $params['endid'] !== null ) {
+                               $ids = [
+                                       (int)$params['startid'] => true,
+                                       (int)$params['endid'] => true,
+                               ];
+                               unset( $ids[0] ); // null
+                               $ids = array_keys( $ids );
+
+                               $db = $this->getDB();
+                               $sql = $db->unionQueries( [
+                                       $db->selectSQLText(
+                                               'revision',
+                                               [ 'id' => 'rev_id', 'ts' => 'rev_timestamp' ],
+                                               [ 'rev_id' => $ids ],
+                                               __METHOD__
+                                       ),
+                                       $db->selectSQLText(
+                                               'archive',
+                                               [ 'id' => 'ar_rev_id', 'ts' => 'ar_timestamp' ],
+                                               [ 'ar_rev_id' => $ids ],
+                                               __METHOD__
+                                       ),
+                               ], false );
+                               $res = $db->query( $sql, __METHOD__ );
+                               foreach ( $res as $row ) {
+                                       if ( (int)$row->id === (int)$params['startid'] ) {
+                                               $params['start'] = $row->ts;
+                                       }
+                                       if ( (int)$row->id === (int)$params['endid'] ) {
+                                               $params['end'] = $row->ts;
+                                       }
+                               }
+                               if ( $params['startid'] !== null && $params['start'] === null ) {
+                                       $p = $this->encodeParamName( 'startid' );
+                                       $this->dieWithError( [ 'apierror-revisions-badid', $p ], "badid_$p" );
+                               }
+                               if ( $params['endid'] !== null && $params['end'] === null ) {
+                                       $p = $this->encodeParamName( 'endid' );
+                                       $this->dieWithError( [ 'apierror-revisions-badid', $p ], "badid_$p" );
+                               }
+
+                               if ( $params['start'] !== null ) {
+                                       $op = ( $params['dir'] === 'newer' ? '>' : '<' );
+                                       $ts = $db->addQuotes( $db->timestampOrNull( $params['start'] ) );
+                                       if ( $params['startid'] !== null ) {
+                                               $this->addWhere( "rev_timestamp $op $ts OR "
+                                                       . "rev_timestamp = $ts AND rev_id $op= " . intval( $params['startid'] ) );
+                                       } else {
+                                               $this->addWhere( "rev_timestamp $op= $ts" );
+                                       }
+                               }
+                               if ( $params['end'] !== null ) {
+                                       $op = ( $params['dir'] === 'newer' ? '<' : '>' ); // Yes, opposite of the above
+                                       $ts = $db->addQuotes( $db->timestampOrNull( $params['end'] ) );
+                                       if ( $params['endid'] !== null ) {
+                                               $this->addWhere( "rev_timestamp $op $ts OR "
+                                                       . "rev_timestamp = $ts AND rev_id $op= " . intval( $params['endid'] ) );
+                                       } else {
+                                               $this->addWhere( "rev_timestamp $op= $ts" );
+                                       }
+                               }
+                       } else {
+                               $this->addTimestampWhereRange( 'rev_timestamp', $params['dir'],
+                                       $params['start'], $params['end'] );
+                       }
+
+                       $sort = ( $params['dir'] === 'newer' ? '' : 'DESC' );
+                       $this->addOption( 'ORDER BY', [ "rev_timestamp $sort", "rev_id $sort" ] );
 
                        // There is only one ID, use it
                        $ids = array_keys( $pageSet->getGoodTitles() );
index be67dd2..1b154fa 100644 (file)
@@ -53,37 +53,24 @@ class ApiQueryTags extends ApiQueryBase {
                $softwareDefinedTags = array_fill_keys( ChangeTags::listSoftwareDefinedTags(), 0 );
                $explicitlyDefinedTags = array_fill_keys( ChangeTags::listExplicitlyDefinedTags(), 0 );
                $softwareActivatedTags = array_fill_keys( ChangeTags::listSoftwareActivatedTags(), 0 );
+               $tagStats = ChangeTags::tagUsageStatistics();
 
-               $definedTags = array_merge( $softwareDefinedTags, $explicitlyDefinedTags );
+               $tagHitcounts = array_merge( $softwareDefinedTags, $explicitlyDefinedTags, $tagStats );
+               $tags = array_keys( $tagHitcounts );
 
                # Fetch defined tags that aren't past the continuation
                if ( $params['continue'] !== null ) {
                        $cont = $params['continue'];
-                       $tags = array_filter( array_keys( $definedTags ), function ( $v ) use ( $cont ) {
+                       $tags = array_filter( $tags, function ( $v ) use ( $cont ) {
                                return $v >= $cont;
                        } );
-                       $tags = array_fill_keys( $tags, 0 );
-               } else {
-                       $tags = $definedTags;
-               }
-
-               # Merge in all used tags
-               $this->addTables( 'change_tag' );
-               $this->addFields( 'ct_tag' );
-               $this->addFields( [ 'hitcount' => $fld_hitcount ? 'COUNT(*)' : '0' ] );
-               $this->addOption( 'LIMIT', $limit + 1 );
-               $this->addOption( 'GROUP BY', 'ct_tag' );
-               $this->addWhereRange( 'ct_tag', 'newer', $params['continue'], null );
-               $res = $this->select( __METHOD__ );
-               foreach ( $res as $row ) {
-                       $tags[$row->ct_tag] = (int)$row->hitcount;
                }
 
                # Now make sure the array is sorted for proper continuation
-               ksort( $tags );
+               sort( $tags );
 
                $count = 0;
-               foreach ( $tags as $tagName => $hitcount ) {
+               foreach ( $tags as $tagName ) {
                        if ( ++$count > $limit ) {
                                $this->setContinueEnumParameter( 'continue', $tagName );
                                break;
@@ -102,7 +89,7 @@ class ApiQueryTags extends ApiQueryBase {
                        }
 
                        if ( $fld_hitcount ) {
-                               $tag['hitcount'] = $hitcount;
+                               $tag['hitcount'] = intval( $tagHitcounts[$tagName] );
                        }
 
                        $isSoftware = isset( $softwareDefinedTags[$tagName] );
index 4515f7f..a5d06c8 100644 (file)
@@ -172,10 +172,8 @@ class ApiQueryUsers extends ApiQueryBase {
                                $this->addJoinConds( [ 'user_groups' => [ 'INNER JOIN', 'ug_user=user_id' ] ] );
                                $this->addFields( [ 'user_name' ] );
                                $this->addFields( UserGroupMembership::selectFields() );
-                               if ( !$this->getConfig()->get( 'DisableUserGroupExpiry' ) ) {
-                                       $this->addWhere( 'ug_expiry IS NULL OR ug_expiry >= ' .
-                                               $db->addQuotes( $db->timestamp() ) );
-                               }
+                               $this->addWhere( 'ug_expiry IS NULL OR ug_expiry >= ' .
+                                       $db->addQuotes( $db->timestamp() ) );
                                $userGroupsRes = $this->select( __METHOD__ );
 
                                foreach ( $userGroupsRes as $row ) {
index d857e4a..2a364d9 100644 (file)
@@ -58,7 +58,7 @@ class ApiUserrights extends ApiBase {
                $params = $this->extractRequestParams();
 
                // Figure out expiry times from the input
-               // @todo Remove this isset check when removing $wgDisableUserGroupExpiry
+               // $params['expiry'] may not be set in subclasses
                if ( isset( $params['expiry'] ) ) {
                        $expiry = (array)$params['expiry'];
                } else {
index 074d69e..fee1fa3 100644 (file)
        "apihelp-parse-paramvalue-prop-wikitext": "Gibt den originalen Wikitext zurück, der geparst wurde.",
        "apihelp-parse-paramvalue-prop-properties": "Gibt verschiedene Eigenschaften zurück, die im geparsten Wikitext definiert sind.",
        "apihelp-parse-paramvalue-prop-parsewarnings": "Gibt die Warnungen aus, die beim Parsen des Inhalts aufgetreten sind.",
+       "apihelp-parse-param-wrapoutputclass": "Zu verwendende CSS-Klasse, in der die Parserausgabe verpackt werden soll.",
        "apihelp-parse-param-section": "Parst nur den Inhalt dieser Abschnittsnummer.\n\nFalls <kbd>new</kbd>, parst <var>$1text</var> und <var>$1sectiontitle</var>, als ob ein neuer Abschnitt der Seite hinzugefügt wird.\n\n<kbd>new</kbd> ist nur erlaubt mit der Angabe <var>text</var>.",
        "apihelp-parse-param-sectiontitle": "Überschrift des neuen Abschnittes, wenn <var>section</var> = <kbd>new</kbd> ist.\n\nAnders als beim Bearbeiten der Seite wird der Parameter nicht durch die <var>summary</var> ersetzt, wenn er weggelassen oder leer ist.",
        "apihelp-parse-param-disablepp": "Benutze <var>$1disablelimitreport</var> stattdessen.",
        "apierror-pagelang-disabled": "Das Ändern der Sprache von Seiten ist auf diesem Wiki nicht erlaubt.",
        "apierror-protect-invalidaction": "Ungültiger Schutztyp „$1“.",
        "apierror-readonly": "Das Wiki ist derzeit im schreibgeschützten Modus.",
+       "apierror-revisions-badid": "Für den Parameter <var>$1</var> wurde keine Version gefunden.",
        "apierror-revwrongpage": "Die Version $1 ist keine Version von $2.",
        "apierror-sectionreplacefailed": "Der aktualisierte Abschnitt konnte nicht zusammengeführt werden.",
        "apierror-stashinvalidfile": "Ungültige gespeicherte Datei.",
index 7a04caf..c3c7bd4 100644 (file)
        "apihelp-parse-paramvalue-prop-limitreporthtml": "Gives the HTML version of the limit report. Gives no data, when <var>$1disablelimitreport</var> is set.",
        "apihelp-parse-paramvalue-prop-parsetree": "The XML parse tree of revision content (requires content model <code>$1</code>)",
        "apihelp-parse-paramvalue-prop-parsewarnings": "Gives the warnings that occurred while parsing content.",
+       "apihelp-parse-param-wrapoutputclass": "CSS class to use to wrap the parser output.",
        "apihelp-parse-param-pst": "Do a pre-save transform on the input before parsing it. Only valid when used with text.",
        "apihelp-parse-param-onlypst": "Do a pre-save transform (PST) on the input, but don't parse it. Returns the same wikitext, after a PST has been applied. Only valid when used with <var>$1text</var>.",
        "apihelp-parse-param-effectivelanglinks": "Includes language links supplied by extensions (for use with <kbd>$1prop=langlinks</kbd>).",
 
        "apihelp-query+revisions-description": "Get revision information.\n\nMay be used in several ways:\n# Get data about a set of pages (last revision), by setting titles or pageids.\n# Get revisions for one given page, by using titles or pageids with start, end, or limit.\n# Get data about a set of revisions by setting their IDs with revids.",
        "apihelp-query+revisions-paraminfo-singlepageonly": "May only be used with a single page (mode #2).",
-       "apihelp-query+revisions-param-startid": "From which revision ID to start enumeration.",
-       "apihelp-query+revisions-param-endid": "Stop revision enumeration on this revision ID.",
+       "apihelp-query+revisions-param-startid": "Start enumeration from this revision's timestamp. The revision must exist, but need not belong to this page.",
+       "apihelp-query+revisions-param-endid": "Stop enumeration at this revision's timestamp. The revision must exist, but need not belong to this page.",
        "apihelp-query+revisions-param-start": "From which revision timestamp to start enumeration.",
        "apihelp-query+revisions-param-end": "Enumerate up to this timestamp.",
        "apihelp-query+revisions-param-user": "Only include revisions made by user.",
        "apierror-revdel-mutuallyexclusive": "The same field cannot be used in both <var>hide</var> and <var>show</var>.",
        "apierror-revdel-needtarget": "A target title is required for this RevDel type.",
        "apierror-revdel-paramneeded": "At least one value is required for <var>hide</var> and/or <var>show</var>.",
+       "apierror-revisions-badid": "No revision was found for parameter <var>$1</var>.",
        "apierror-revisions-norevids": "The <var>revids</var> parameter may not be used with the list options (<var>$1limit</var>, <var>$1startid</var>, <var>$1endid</var>, <kbd>$1dir=newer</kbd>, <var>$1user</var>, <var>$1excludeuser</var>, <var>$1start</var>, and <var>$1end</var>).",
        "apierror-revisions-singlepage": "<var>titles</var>, <var>pageids</var> or a generator was used to supply multiple pages, but the <var>$1limit</var>, <var>$1startid</var>, <var>$1endid</var>, <kbd>$1dir=newer</kbd>, <var>$1user</var>, <var>$1excludeuser</var>, <var>$1start</var>, and <var>$1end</var> parameters may only be used on a single page.",
        "apierror-revwrongpage": "r$1 is not a revision of $2.",
index bbd7c2d..8cb0e86 100644 (file)
        "apihelp-help-param-recursivesubmodules": "Incluir ayuda para submódulos recursivamente.",
        "apihelp-help-param-helpformat": "Formato de salida de la ayuda.",
        "apihelp-help-param-wrap": "Envolver el producto en una estructura de respuesta de la API estándar.",
-       "apihelp-help-param-toc": "Incluir una tabla de contenidos en la salida HTML.",
+       "apihelp-help-param-toc": "Incluir un sumario en la salida HTML.",
        "apihelp-help-example-main": "Ayuda del módulo principal",
        "apihelp-help-example-submodules": "Ayuda para <kbd>action=query</kbd> y todos sus submódulos.",
        "apihelp-help-example-recursive": "Toda la ayuda en una página",
        "apihelp-parse-param-generatexml": "Generar árbol de análisis sintáctico XML (requiere modelo de contenido <code>$1</code>; sustituido por <kbd>$2prop=parsetree</kbd>).",
        "apihelp-parse-param-preview": "Analizar en modo de vista previa.",
        "apihelp-parse-param-sectionpreview": "Analizar sección en modo de vista previa (también activa el modo de vista previa).",
-       "apihelp-parse-param-disabletoc": "Omitir la tabla de contenidos en la salida.",
+       "apihelp-parse-param-disabletoc": "Omitir el sumario en la salida.",
        "apihelp-parse-param-contentformat": "Formato de serialización de contenido utilizado para la introducción de texto. Sólo es válido cuando se utiliza con $1text.",
        "apihelp-parse-param-contentmodel": "Modelo de contenido del texto de entrada. Si se omite, se debe especificar $1title, y el valor por defecto será el modelo del título especificado. Solo es válido cuando se use junto con $1text.",
        "apihelp-parse-example-page": "Analizar una página.",
        "apihelp-query+imageinfo-param-urlwidth": "Si se establece $2prop=url, se devolverá una URL a una imagen escalada a este ancho.\nPor razones de rendimiento, si se utiliza esta opción, no se devolverán más de $1 imágenes escaladas.",
        "apihelp-query+imageinfo-param-urlheight": "Similar a $1urlwidth.",
        "apihelp-query+imageinfo-param-metadataversion": "Versión de los metadatos que se utilizará. Si se especifica <kbd>latest</kbd>, utilizará la última versión. El valor predeterminado es <kbd>1</kbd>, por motivo de retrocompatibilidad.",
-       "apihelp-query+imageinfo-param-extmetadatalanguage": "¿Qué idioma buscar  en extmetadata. Esto afecta a qué traducción buscar, si hay varias disponibles, así como la forma en que cosas como números y varios valores son formateados.",
+       "apihelp-query+imageinfo-param-extmetadatalanguage": "En qué idioma obtener «extmetadata». Esto afecta tanto la traducción que se obtendrá ―si hay varias― como el formato de elementos como los números y algunos valores.",
        "apihelp-query+imageinfo-param-extmetadatamultilang": "Si las traducciones para la propiedad extmetadata están disponibles, busque todas ellas.",
        "apihelp-query+imageinfo-param-extmetadatafilter": "Si se especifica y no vacío, sólo estas claves serán devueltos por $1prop=extmetadata.",
        "apihelp-query+imageinfo-param-urlparam": "Un controlador específico de la cadena de parámetro. Por ejemplo, los archivos Pdf pueden utilizar <kbd>page15-100px</kbd>. <var>$1urlwidth</var> debe ser utilizado y debe ser consistente con <var>$1urlparam</var>.",
index 3a47b63..35de672 100644 (file)
        "apihelp-parse-paramvalue-prop-limitreporthtml": "Fournit la version HTML du rapport de limite. Ne fournit aucune donnée, si <var>$1disablelimitreport</var> est positionné.",
        "apihelp-parse-paramvalue-prop-parsetree": "L’arbre d’analyse XML du contenu de la révision (nécessite le modèle de contenu <code>$1</code>)",
        "apihelp-parse-paramvalue-prop-parsewarnings": "Fournit les messages d'avertissement qui sont apparus lors de l'analyse de contenu.",
+       "apihelp-parse-param-wrapoutputclass": "classe CSS à utiliser pour formater la sortie de l'analyseur.",
        "apihelp-parse-param-pst": "Faire une transformation avant enregistrement de l’entrée avant de l’analyser. Valide uniquement quand utilisé avec du texte.",
        "apihelp-parse-param-onlypst": "Faire une transformation avant enregistrement (PST) de l’entrée, mais ne pas l’analyser. Renvoie le même wikitexte, après que la PST a été appliquée. Valide uniquement quand utilisé avec <var>$1text</var>.",
        "apihelp-parse-param-effectivelanglinks": "Inclut les liens de langue fournis par les extensions (à utiliser avec <kbd>$1prop=langlinks</kbd>).",
        "apihelp-query+redirects-example-generator": "Obtenir des informations sur toutes les redirections vers [[Main Page]]",
        "apihelp-query+revisions-description": "Obtenir des informations sur la révision.\n\nPeut être utilisé de différentes manières :\n# Obtenir des données sur un ensemble de pages (dernière révision), en mettant les titres ou les ids de page.\n# Obtenir les révisions d’une page donnée, en utilisant les titres ou les ids de page avec rvstart, rvend ou rvlimit.\n# Obtenir des données sur un ensemble de révisions en donnant leurs IDs avec revids.",
        "apihelp-query+revisions-paraminfo-singlepageonly": "Utilisable uniquement avec une seule page (mode #2).",
-       "apihelp-query+revisions-param-startid": "À quel ID de révision démarrer l’énumération.",
-       "apihelp-query+revisions-param-endid": "Arrêter l’énumération des révisions à cet ID.",
+       "apihelp-query+revisions-param-startid": "Commencer l'énumération à partir de la date de cette revue. La revue doit exister, mais ne concerne pas forcément cette page.",
+       "apihelp-query+revisions-param-endid": "Arrêter l’énumération à la date de cette revue. La revue doit exister mais ne concerne pas forcément cette page.",
        "apihelp-query+revisions-param-start": "À quel horodatage de révision démarrer l’énumération.",
        "apihelp-query+revisions-param-end": "Énumérer jusqu’à cet horodatage.",
        "apihelp-query+revisions-param-user": "Inclure uniquement les révisions faites par l’utilisateur.",
        "apierror-revdel-mutuallyexclusive": "Le même champ ne peut pas être utilisé à la fois en <var>hide</var> et <var>show</var>.",
        "apierror-revdel-needtarget": "Un titre cible est nécessaire pour ce type RevDel.",
        "apierror-revdel-paramneeded": "Au moins une valeur est nécessaire pour <var>hide</var> ou <var>show</var>.",
+       "apierror-revisions-badid": "Pas de correction trouvée pour le paramètre <var>$1</var>.",
        "apierror-revisions-norevids": "Le paramètre <var>revids</var> ne peut pas être utilisé avec les options de liste (<var>$1limit</var>, <var>$1startid</var>, <var>$1endid</var>, <kbd>$1dir=newer</kbd>, <var>$1user</var>, <var>$1excludeuser</var>, <var>$1start</var>, et <var>$1end</var>).",
        "apierror-revisions-singlepage": "<var>titles</var>, <var>pageids</var> ou un générateur a été utilisé pour fournir plusieurs pages, mais les paramètres <var>$1limit</var>, <var>$1startid</var>, <var>$1endid</var>, <kbd>$1dir=newer</kbd>, <var>$1user</var>, <var>$1excludeuser</var>, <var>$1start</var> et <var>$1end</var> ne peuvent être utilisés que sur une seule page.",
        "apierror-revwrongpage": "r$1 n'est pas une révision de $2.",
index a948c85..cc16214 100644 (file)
        "apihelp-parse-paramvalue-prop-limitreporthtml": "נותן את גרסת ה־HTML של דו\"ח ההגבלות. לא נותן שום נתונים כאשר מוגדר <var>$1disablelimitreport</var>.",
        "apihelp-parse-paramvalue-prop-parsetree": "עץ פענוח XML של תוכן הגרסה (דורש מודל תוכן <code>$1</code>)",
        "apihelp-parse-paramvalue-prop-parsewarnings": "נותן אזהרות שאירעו בזמן פענוח התוכן.",
+       "apihelp-parse-param-wrapoutputclass": "מחלקה של CSS שתשמש לעטיפת פלט המפענח.",
        "apihelp-parse-param-pst": "לעשות התמרה לפני שמירה על הקלט לפני פענוחו. תקין רק בשימוש עם טקסט.",
        "apihelp-parse-param-onlypst": "לעשות התמרה לפני שמירה (pre-save transform‏, PST) על הקלט, אבל לא לפענח אותו. מחזיר את אותו קוד הוויקי אחרי החלת PST. תקף רק בשימוש עם <var>$1text</var>.",
        "apihelp-parse-param-effectivelanglinks": "כולל קישור שפה שמספקות הרחבות (לשימוש עם <kbd>$1prop=langlinks</kbd>).",
        "apihelp-query+redirects-example-generator": "קבלת מידע על כל ההפניות ל־[[Main Page]].",
        "apihelp-query+revisions-description": "קבלת מידע על גרסה.\n\nיכול לשמש במספר דרכים:\n# קבלת נתונים על ערכת דפים (גרסה אחרונה), באמצעות כותרות או מזהי דף.\n# קבלת גרסאות עבור דף נתון אחד, באמצעות שימוש בכותרות או במזהי דף עם start‏, end או limit.\n# קבלת נתונים על ערכת גרסאות באמצעות הגדרת המזהים שלהם עם revid־ים.",
        "apihelp-query+revisions-paraminfo-singlepageonly": "יכול לשמש רק עם דף בודד (mode #2).",
-       "apihelp-query+revisions-param-startid": "×\9e×\90×\99×\96×\94 ×\9e×\96×\94×\94 ×\92רס×\94 ×\9c×\94ת×\97×\99×\9c ×\9c×\9e× ×\95ת.",
-       "apihelp-query+revisions-param-endid": "×\91×\90×\99×\96×\94 ×\9e×\96×\94×\94 ×\92רס×\94 ×\9c×\94פס×\99ק ×\90ת ×\9e× ×\99×\99ת ×\94×\92רס×\90×\95ת.",
+       "apihelp-query+revisions-param-startid": "×\9c×\94ת×\97×\99×\9c ×\9c×\9e× ×\95ת ×\9e×\97×\95ת×\9d ×\94×\96×\9e×\9f ×©×\9c ×\94×\92רס×\94 ×\94×\96×\90ת. ×\94×\92רס×\94 ×¦×¨×\99×\9b×\94 ×\9c×\94×\99×\95ת ×§×\99×\99×\9eת, ×\90×\91×\9c ×\9c×\90 ×\97×\99×\99×\91ת ×\9c×\94×\99×\95ת ×©×\99×\99×\9bת ×\9c×\93×£ ×\94×\96×\94.",
+       "apihelp-query+revisions-param-endid": "×\9c×\94פס×\99ק ×\9c×\9e× ×\95ת ×\9e×\97×\95ת×\9d ×\94×\96×\9e×\9f ×©×\9c ×\94×\92רס×\94 ×\94×\96×\90ת. ×\94×\92רס×\94 ×¦×¨×\99×\9b×\94 ×\9c×\94×\99×\95ת ×§×\99×\99×\9eת, ×\90×\91×\9c ×\9c×\90 ×\97×\99×\99×\91ת ×\9c×\94×\99×\95ת ×©×\99×\99×\9bת ×\9c×\93×£ ×\94×\96×\94.",
        "apihelp-query+revisions-param-start": "מאיזה חותם־זמן של גרסה להתחיל למנות.",
        "apihelp-query+revisions-param-end": "למנות עד חותם־הזמן הזה.",
        "apihelp-query+revisions-param-user": "לכלול רק גרסאות מאת משתמש.",
        "apierror-revdel-mutuallyexclusive": "אותו השדה אינו יכול לשמש עם <var>hide</var> ועם <var>show</var>.",
        "apierror-revdel-needtarget": "כותרת יעד נחוצה בשביל סוג ה־RevDel הזה.",
        "apierror-revdel-paramneeded": "לפחות ערך אחד נחוץ בשביל <var>hide</var> או <var>show</var>.",
+       "apierror-revisions-badid": "לא נמצאה גרסה לפרמטר <var>$1</var>.",
        "apierror-revisions-norevids": "הפרמטר <var>revids</var> אינו יכול לשמש עם אפשרויות הרשימה (<var>$1limit</var>‏, <var>$1startid</var>‏, <var>$1endid</var>‏, <kbd>$1dir=newer</kbd>‏, <var>$1user</var>‏, <var>$1excludeuser</var>‏, <var>$1start</var>, ו־<var>$1end</var>).",
        "apierror-revisions-singlepage": "<var>titles</var>‏, <var>pageids</var> או מחולל שימשו לאספקת דפים מרובים, אבל הפרמטרים <var>$1limit</var>‏, <var>$1startid</var>‏, <var>$1endid</var>‏, <kbd>$1dir=newer</kbd>‏, <var>$1user</var>‏, <var>$1excludeuser</var>‏, <var>$1start</var>, ו־<var>$1end</var> יכולים לשמש רק בדף בודד.",
        "apierror-revwrongpage": "הגרסה $1 אינה גרסה של $2.",
index 232386e..160bfa7 100644 (file)
                        "Dj"
                ]
        },
+       "apihelp-main-description": "<div class=\"hlist plainlinks api-main-links\">\n* [[mw:Special:MyLanguage/API:Main_page|Dokumentáció]]\n* [[mw:Special:MyLanguage/API:FAQ|GYIK]]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api Levelezőlista]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api-announce API-bejelentések]\n* [https://phabricator.wikimedia.org/maniphest/query/GebfyV4uCaLd/#R Hibabejelentések és kérések]\n</div>\n<strong>Státusz:</strong> Minden ezen a lapon látható funkciónak működnie kell, de az API jelenleg is aktív fejlesztés alatt áll, és bármikor változhat. Iratkozz fel a [https://lists.wikimedia.org/pipermail/mediawiki-api-announce/ mediawiki-api-announce levelezőlistára] a frissítések követéséhez.\n\n<strong>Hibás kérések:</strong> Ha az API hibás kérést kap, egy HTTP-fejlécet küld vissza „MediaWiki-API-Error” kulccsal, és a fejléc értéke és a visszaküldött hibakód ugyanarra az értékre lesz állítva. További információért lásd: [[mw:Special:MyLanguage/API:Errors_and_warnings|API: Hibák és figyelmeztetések]].\n\n<strong>Tesztelés:</strong> Az API-kérések könnyebb teszteléséhez használható az [[Special:ApiSandbox|API-homokozó]].",
        "apihelp-main-param-action": "Milyen műveletet hajtson végre.",
        "apihelp-main-param-format": "A kimenet formátuma.",
+       "apihelp-main-param-smaxage": "Az <code>s-maxage</code> gyorsítótár-vezérlő HTTP-fejléc beállítása ennyi másodpercre. A hibák soha nincsenek gyorsítótárazva.",
+       "apihelp-main-param-maxage": "Az <code>maxage</code> gyorsítótár-vezérlő HTTP-fejléc beállítása ennyi másodpercre. A hibák soha nincsenek gyorsítótárazva.",
+       "apihelp-main-param-assert": "Annak ellenőrzése, hogy a felhasználó be van-e jelentkezve <kbd>user</kbd> érték esetén, vagy botjog ellenőrzése <kbd>bot</kbd> érték esetén.",
+       "apihelp-main-param-assertuser": "Annak ellenőrzése, hogy a jelenlegi felhasználó a megadott-e.",
        "apihelp-main-param-requestid": "Az itt megadott bármilyen érték szerepelni fog a válaszban. Több kérés megkülönböztetésére használható.",
        "apihelp-main-param-servedby": "Tartalmazza a válasz kérést kiszolgáló gép nevét.",
        "apihelp-main-param-curtimestamp": "Tartalmazza a válasz az aktuális időbélyeget.",
+       "apihelp-main-param-responselanginfo": "A válasz tartalmazza <var>uselang</var> és <var>errorlang</var> paraméterekben használt nyelveket.",
+       "apihelp-main-param-uselang": "Az üzenetfordításokhoz használandó nyelv. A <kbd>[[Special:ApiHelp/query+siteinfo|action=query&meta=siteinfo]]</kbd> a <kbd>siprop=languages</kbd> paraméterrel visszaadja a lehetséges nyelvkódok listáját, vagy <kbd>user</kbd> az aktuális felhasználó, illetve <kbd>content</kbd> a wiki nyelvbeállításához.",
+       "apihelp-main-param-errorformat": "A figyelmeztetések és hibaüzenetek formátuma.\n; plaintext: Wikiszöveg eltávolított HTML-címkékkel és a HTML-entitások (pl. &amp;amp;) kicserélésével.\n; wikitext: Feldolgozatlan wikiszöveg.\n; html: HTML.\n; raw: Az üzenet azonosítója és paraméterei.\n; none: Szöveges kimenet mellőzése, csak hibakódok.\n; bc: A MediaWiki 1.29 előtti formátum. A <var>errorlang</var> és <var> erroruselocal</var> paraméterek figyelmen kívül lesznek hagyva.",
+       "apihelp-main-param-errorlang": "A figyelmeztetésekhez és hibaüzenetekhez használandó nyelv. A <kbd>[[Special:ApiHelp/query+siteinfo|action=query&meta=siteinfo]]</kbd> a <kbd>siprop=languages</kbd> paraméterrel visszaadja a lehetséges nyelvkódok listáját, vagy <kbd>content</kbd> a wiki nyelvbeállításához, illetve <kbd>uselang</kbd> a <var>uselang</var> paraméter értékéhez.",
+       "apihelp-main-param-errorsuselocal": "Ha meg van adva, a hibaüzenetek a helyileg testreszabott üzeneteket fogják használni a {{ns:MediaWiki}} névtérből.",
        "apihelp-block-description": "Szerkesztő blokkolása",
-       "apihelp-block-param-user": "Blokkolandó felhasználónév, IP-cím vagy IP-címtartomány.",
+       "apihelp-block-param-user": "Blokkolandó felhasználónév, IP-cím vagy IP-címtartomány. Nem használható együtt a <var>$1userid</var> paraméterrel.",
+       "apihelp-block-param-userid": "A blokkolandó felhasználó numerikus azonosítója. Nem használható a <var>$1user</var> paraméterrel együtt.",
        "apihelp-block-param-expiry": "Lejárat ideje. Lehet relatív (pl. <kbd>5 months</kbd>, <kbd>2 weeks</kbd>) vagy abszolút (pl. <kbd>2014-09-18T12:34:56Z</kbd>). Ha <kbd>infinite</kbd>-re, <kbd>indefinite</kbd>-re vagy <kbd>never</kbd>-re állítod, a blokk soha nem fog lejárni.",
        "apihelp-block-param-reason": "Blokkolás oka.",
+       "apihelp-block-param-anononly": "Csak anonim felhasználók blokkolása (anonim szerkesztések megakadályozása erről az IP-címről).",
        "apihelp-block-param-nocreate": "Új regisztráció megakadályozása",
+       "apihelp-block-param-autoblock": "Az utoljára használt IP-cím blokkolása, valamint bármilyen további IP-cím, amiről a felhasználó megpróbál bejelentkezni.",
+       "apihelp-block-param-noemail": "A wiki e-mail-küldő rendszerének letiltása a felhasználó számára (<code>blockemail</code> jogosultság szükséges hozzá).",
+       "apihelp-block-param-hidename": "A felhasználónév elrejtése a blokknaplóból (<code>hideuser</code> jog szükséges hozzá).",
+       "apihelp-block-param-allowusertalk": "A felhasználó szerkeszthesse a saját vitalapját (a <var>[[mw:Special:MyLanguage/Manual:$wgBlockAllowsUTEdit|$wgBlockAllowsUTEdit]]</var> beállítástól függ).",
+       "apihelp-block-param-reblock": "Jelenlegi blokk felülírása, ha a felhasználó már blokkolva van.",
        "apihelp-block-param-watchuser": "A szerkesztő vagy IP-cím szerkesztői- és vitalapjának figyelése.",
+       "apihelp-block-example-ip-simple": "A <kbd>192.0.2.5</kbd> IP-cím blokkolása három napra <kbd>First strike</kbd> indoklással.",
+       "apihelp-block-example-user-complex": "<kbd>Vandal</kbd> blokkolása határozatlan időre <kbd>Vandalism</kbd> indoklással, új fiók létrehozásának és e-mail küldésének megakadályozása.",
+       "apihelp-checktoken-description": "Egy <kbd>[[Special:ApiHelp/query+tokens|action=query&meta=tokens]]</kbd> kéréssel szerzett token érvényességének vizsgálata.",
+       "apihelp-checktoken-param-type": "A tesztelendő token típusa.",
+       "apihelp-checktoken-param-token": "A tesztelendő token.",
+       "apihelp-checktoken-param-maxtokenage": "A token megengedett legnagyobb kora másodpercekben.",
+       "apihelp-checktoken-example-simple": "Egy <kbd>csrf</kbd> token érvényességének vizsgálata.",
+       "apihelp-clearhasmsg-description": "A <code>hasmsg</code> jelzés törlése az aktuális felhasználónak.",
+       "apihelp-clearhasmsg-example-1": "A <code>hasmsg</code> jelzés törlése az aktuális felhasználónak.",
+       "apihelp-clientlogin-example-login": "A bejelentkezési folyamat elkezdése <kbd>Example</kbd> felhasználónévvel és <kbd>ExamplePassword</kbd> jelszóval.",
+       "apihelp-clientlogin-example-login2": "A bejelentkezés folytatása <samp>UI</samp> válasz után a kétlépcsős azonosításra, az <var>OATHToken</var> paraméternek <kbd>987654</kbd> értéket megadva.",
+       "apihelp-compare-description": "Két lap közötti különbség kiszámítása.\n\nMindkét laphoz kötelező megadni egy lapváltozat-azonosítót, címet vagy lapazonosítót.",
+       "apihelp-compare-param-fromtitle": "Az első összehasonlítandó lap címe.",
+       "apihelp-compare-param-fromid": "Az első összehasonlítandó lap lapazonosítója.",
+       "apihelp-compare-param-fromrev": "Az első összehasonlítandó lapváltozat azonosítója.",
+       "apihelp-compare-param-totitle": "A második összehasonlítandó lap címe.",
+       "apihelp-compare-param-toid": "A második összehasonlítandó lap lapazonosítója.",
+       "apihelp-compare-param-torev": "A második összehasonlítandó lapváltozat azonosítója.",
+       "apihelp-compare-example-1": "Az 1-es és 2-es lapváltozat összehasonlítása.",
+       "apihelp-createaccount-description": "Új felhasználói fiók létrehozása.",
+       "apihelp-createaccount-example-create": "<kbd>Example</kbd> felhasználói fiók létrehozásának elkezdése <kbd>ExamplePassword</kbd> jelszóval.",
        "apihelp-createaccount-param-name": "Felhasználónév.",
+       "apihelp-createaccount-param-password": "Jelszó (figyelmen kívül hagyva, ha a <var>$1mailpassword</var> be van állítva).",
+       "apihelp-createaccount-param-domain": "Tartomány külső hitelesítéshez (opcionális).",
+       "apihelp-createaccount-param-token": "Felhasználólétrehozási token az első kérésből",
        "apihelp-createaccount-param-email": "A szerkesztő e-mail-címe (nem kötelező).",
        "apihelp-createaccount-param-realname": "A szerkesztő valódi neve (nem kötelező).",
+       "apihelp-createaccount-param-mailpassword": "Ha bármilyen értéket kap, egy véletlenszerű jelszót kap a felhasználó e-mailben.",
+       "apihelp-createaccount-param-reason": "Opcionális indoklás a fióklétrehozáshoz a naplókba.",
+       "apihelp-createaccount-param-language": "A felhasználó alapértelmezett nyelvkódja (opcionális, alapértelmezetten a tartalom nyelve).",
+       "apihelp-createaccount-example-pass": "<kbd>testuser</kbd> felhasználó létrehozása <kbd>test123</kbd> jelszóval.",
+       "apihelp-createaccount-example-mail": "<kbd>testmailuser</kbd> felhasználó létrehozása, véletlenszerű jelszó elküldése e-mailben.",
        "apihelp-delete-description": "Lap törlése.",
+       "apihelp-delete-param-title": "A törlendő lap címe. Nem használható együtt a <var>$1pageid</var> paraméterrel.",
+       "apihelp-delete-param-pageid": "A törlendő lap lapazonosítója. Nem használható együtt a <var>$1title</var> paraméterrel.",
+       "apihelp-delete-param-reason": "A törlés indoka. Ha nincs beállítva, automatikusan generált indoklás helyettesíti.",
+       "apihelp-delete-param-watch": "A lap hozzáadása a felhasználó figyelőlistájához.",
+       "apihelp-delete-param-watchlist": "A lap hozzáadása a figyelőlistához vagy eltávolítása onnan feltétel nélkül, a beállítások használata vagy a figyelőlista érintetlenül hagyása.",
        "apihelp-delete-param-unwatch": "A lap törlése a szerkesztő figyelőlistájáról.",
+       "apihelp-delete-param-oldimage": "A törlendő régi kép neve az [[Special:ApiHelp/query+imageinfo|action=query&prop=imageinfo&iiprop=archivename]] által adott formátumban.",
        "apihelp-delete-example-simple": "<kbd>Main Page</kbd> törlése.",
+       "apihelp-delete-example-reason": "<kbd>Main Page</kbd> törlése <kbd>Preparing for move</kbd> indoklással.",
        "apihelp-disabled-description": "Ez a modul le lett tiltva.",
        "apihelp-edit-description": "Lapok létrehozása és szerkesztése.",
+       "apihelp-edit-param-title": "A szerkesztendő lap címe. Nem használható együtt a <var>$1pageid</var> paraméterrel.",
+       "apihelp-edit-param-pageid": "A szerkesztendő lap lapazonosítója. Nem használható együtt a <var>$1title</var> paraméterrel.",
+       "apihelp-edit-param-section": "A szerkesztendő szakasz száma. <kbd>0</kbd> a bevezetőhöz, <kbd>new</kbd> új szakaszhoz.",
        "apihelp-edit-param-sectiontitle": "Az új szakasz címe.",
+       "apihelp-edit-param-text": "A lap tartalma.",
+       "apihelp-edit-param-summary": "Szerkesztési összefoglaló. A szakasz címe is, ha $1section=new és a $1sectiontitle paraméter nincs beállítva.",
        "apihelp-edit-param-minor": "Apró változtatás.",
+       "apihelp-edit-param-notminor": "Nem apró változtatás.",
        "apihelp-edit-param-bot": "Szerkesztés megjelölése botszerkesztésként.",
+       "apihelp-edit-param-basetimestamp": "Az alapváltozat időbélyege, a szerkesztési ütközések felismerésére szolgál. Az [[Special:ApiHelp/query+revisions|action=query&prop=revisions&rvprop=timestamp]] kéréssel szerezhető meg.",
+       "apihelp-edit-param-starttimestamp": "A szerkesztési folyamat kezdetének időbélyege, a szerkesztési ütközések felismerésére szolgál. Egy megfelelő érték lekérhető a <var>[[Special:ApiHelp/main|curtimestamp]]</var> paraméterrel a folyamat kezdetén (pl. a szerkesztendő lap tartalmának letöltésekor).",
+       "apihelp-edit-param-recreate": "Bármilyen hiba felülírása arról, hogy a lapot a szerkesztés közben törölték.",
        "apihelp-edit-param-createonly": "Ne szerkeszd a lapot, ha már létezik.",
+       "apihelp-edit-param-watch": "A lap hozzáadása a felhasználó figyelőlistájához.",
+       "apihelp-edit-param-unwatch": "A lap törlése a szerkesztő figyelőlistájáról.",
+       "apihelp-edit-param-watchlist": "A lap hozzáadása a figyelőlistához vagy eltávolítása onnan feltétel nélkül, a beállítások használata vagy a figyelőlista érintetlenül hagyása.",
+       "apihelp-edit-param-prependtext": "Ezen szöveg hozzáadása a lap elejére. Felülírja a <var>$1text</var> paramétert.",
+       "apihelp-edit-param-appendtext": "Ezen szöveg hozzáadása a lap végére. Felülírja a <var>$1text</var> paramétert.\n\nHasználd a <kbd>$1section=new</kbd> paramétert új szakasz hozzáadásához ezen paraméter helyett.",
+       "apihelp-edit-param-undo": "Ezen változat visszavonása. Felülírja a <var>$1text</var>, <var>$1prependtext</var> és <var>$1appendtext</var> paramétereket.",
+       "apihelp-edit-param-undoafter": "Minden változtatás visszavonása az <var>$1undo</var> paraméterben szereplőtől eddig. Ha nincs megadva, csak egy változtatás visszavonása.",
+       "apihelp-edit-param-redirect": "Átirányítások automatikus feloldása.",
+       "apihelp-edit-param-contentmodel": "Az új tartalom tartalommodellje.",
+       "apihelp-edit-param-token": "A tokennek mindig az utolsó paraméternek, vagy legalább a <var>$1text</var> után kell lennie.",
        "apihelp-edit-example-edit": "Lap szerkesztése",
+       "apihelp-edit-example-prepend": "<kbd>_&#95;NOTOC_&#95;</kbd> hozzáadása a lap elejére.",
+       "apihelp-edit-example-undo": "Az 13579–13585. változatok visszavonása automatikus szerkesztési összefoglalóval.",
        "apihelp-emailuser-description": "E-mail küldése",
+       "apihelp-emailuser-param-target": "Az e-mail címzettje.",
+       "apihelp-emailuser-param-subject": "A levél tárgya.",
        "apihelp-emailuser-param-text": "Szövegtörzs.",
        "apihelp-emailuser-param-ccme": "Másolat küldése magamnak.",
+       "apihelp-emailuser-example-email": "E-mail küldése <kbd>WikiSysop</kbd> felhasználónak <kbd>Content</kbd> szöveggel.",
+       "apihelp-expandtemplates-description": "Minden sablon kibontása a wikiszövegben.",
        "apihelp-expandtemplates-param-title": "Lap címe.",
+       "apihelp-expandtemplates-param-text": "Az átalakítandó wikiszöveg.",
+       "apihelp-expandtemplates-param-revid": "Változatazonosító a <nowiki>{{REVISIONID}}</nowiki> és hasonló változók kibontásához.",
+       "apihelp-expandtemplates-param-prop": "A lekérendő információk.\n\nHa nincs megadva érték, a válasz tartalmazni fogja a wikiszöveget, de a kimenet elavult formátumú lesz.",
+       "apihelp-expandtemplates-paramvalue-prop-wikitext": "A kibontott wikiszöveg.",
+       "apihelp-expandtemplates-paramvalue-prop-categories": "Bármilyen, a bemenetben szereplő kategória, ami nem jelenik meg a wikiszöveges kimenetben.",
+       "apihelp-expandtemplates-paramvalue-prop-properties": "A wikiszövegben kibontott varázsszavak által meghatározott laptulajdonságok.",
+       "apihelp-expandtemplates-paramvalue-prop-ttl": "Maximális idő, ami után az eredmény gyorsítótárazása érvénytelenítendő.",
+       "apihelp-expandtemplates-paramvalue-prop-jsconfigvars": "A lapra vonatkozó JavaScript-változók.",
+       "apihelp-expandtemplates-param-includecomments": "A HTML-megjegyzések szerepeljenek-e a kimenetben.",
+       "apihelp-expandtemplates-example-simple": "A <kbd><nowiki>{{Project:Sandbox}}</nowiki></kbd> wikiszöveg kibontása.",
+       "apihelp-feedcontributions-description": "Egy felhasználó közreműködéseinek lekérése hírcsatornaként.",
+       "apihelp-feedcontributions-param-feedformat": "A hírcsatorna formátuma.",
+       "apihelp-feedcontributions-param-user": "A lekérendő felhasználók.",
+       "apihelp-feedcontributions-param-namespace": "A közreműködések szűrése ezen névtérre.",
+       "apihelp-feedcontributions-param-year": "Közreműködések lekérése eddig az évig.",
+       "apihelp-feedcontributions-param-month": "Közreműködések lekérése ennek a hónapnak a végéig.",
+       "apihelp-feedcontributions-param-tagfilter": "A közreműködések szűrése az ezen címkével ellátottakra.",
+       "apihelp-feedcontributions-param-deletedonly": "Csak a törölt szerkesztések lekérése.",
+       "apihelp-feedcontributions-param-toponly": "Csak a jelenleg utolsónak számító változtatások lekérése.",
+       "apihelp-feedcontributions-param-newonly": "Csak az új oldalt létrehozó szerkesztések lekérése.",
+       "apihelp-feedcontributions-param-hideminor": "Apró szerkesztések kihagyása.",
+       "apihelp-feedcontributions-param-showsizediff": "A változatok közötti méretkülönbség lekérése.",
+       "apihelp-feedcontributions-example-simple": "<kbd>Example</kbd> felhasználó közreműködéseinek lekérése.",
+       "apihelp-feedrecentchanges-description": "A friss változtatások lekérése hírcsatornaként.",
+       "apihelp-feedrecentchanges-param-feedformat": "A hírcsatorna formátuma.",
+       "apihelp-feedrecentchanges-param-namespace": "Az eredmények szűrése erre a névtérre.",
+       "apihelp-feedrecentchanges-param-invert": "Minden névtér a kiválasztott kivételével.",
+       "apihelp-feedrecentchanges-param-associated": "A kapcsolódó (vita- vagy tartalmi) névtér befoglalása.",
+       "apihelp-feedrecentchanges-param-days": "Az eredmények szűrése az elmúlt ennyi napra.",
+       "apihelp-feedrecentchanges-param-limit": "Találatok maximális száma.",
+       "apihelp-feedrecentchanges-param-from": "Szerkesztések megjelenítése ekkortól.",
        "apihelp-feedrecentchanges-param-hideminor": "Apró változtatások elrejtése.",
        "apihelp-feedrecentchanges-param-hidebots": "Botszerkesztések elrejtése.",
+       "apihelp-feedrecentchanges-param-hideanons": "Anonim felhasználók szerkesztéseinek elrejtése.",
+       "apihelp-feedrecentchanges-param-hideliu": "Bejelentkezett felhasználók szerkesztéseinek elrejtése.",
        "apihelp-feedrecentchanges-param-hidepatrolled": "Ellenőrzött változtatások elrejtése.",
+       "apihelp-feedrecentchanges-param-hidemyself": "A jelenlegi felhasználó szerkesztéseinek elrejtése.",
+       "apihelp-feedrecentchanges-param-hidecategorization": "Kategóriaváltoztatások elrejtése.",
+       "apihelp-feedrecentchanges-param-tagfilter": "Szűrés címke szerint.",
+       "apihelp-feedrecentchanges-param-target": "Csak a megadott lapról hivatkozott lapok szerkesztéseinek megjelenítése.",
+       "apihelp-feedrecentchanges-param-showlinkedto": "Inkább a megadott lap''ra'' hivatkozó lapok szerkesztéseinek megjelenítése.",
+       "apihelp-feedrecentchanges-param-categories": "Csak a megadott kategóriák mindegyikében szereplő lapok szerkesztéseinek megjelenítése.",
+       "apihelp-feedrecentchanges-param-categories_any": "Inkább a megadott kategóriák bármelyikében szereplő lapok szerkesztéseinek megjelenítése.",
+       "apihelp-feedrecentchanges-example-simple": "Friss változtatások megjelenítése.",
+       "apihelp-feedrecentchanges-example-30days": "Az elmúlt 30 nap friss változtatásainak megjelenítése.",
+       "apihelp-feedwatchlist-description": "A figyelőlista lekérése hírcsatornaként.",
+       "apihelp-feedwatchlist-param-feedformat": "A hírcsatorna formátuma.",
+       "apihelp-feedwatchlist-param-hours": "Az utóbbi ennyi órában szerkesztett lapok listázása.",
+       "apihelp-feedwatchlist-param-linktosections": "Hivatkozás közvetlenül a módosított szakaszra, ha lehetséges.",
+       "apihelp-feedwatchlist-example-default": "A figyelőlista-hírcsatorna megjelenítése.",
+       "apihelp-feedwatchlist-example-all6hrs": "A figyelt lapok összes változtatásának megjelenítése az elmúlt 6 órában.",
+       "apihelp-filerevert-description": "Egy fájl visszaállítása egy régebbi verzióra.",
+       "apihelp-filerevert-param-filename": "Célfájlnév, {{ns:6}}: (File:) előtag nélkül",
+       "apihelp-filerevert-param-comment": "Feltöltési összefoglaló.",
+       "apihelp-filerevert-param-archivename": "A visszaállítandó változat archív neve.",
+       "apihelp-filerevert-example-revert": "<kbd>Wiki.png</kbd> visszaállítása a <kbd>2011-03-05T15:27:40Z</kbd>-kori változatra.",
+       "apihelp-help-description": "Súgó megjelenítése a megadott modulokhoz.",
+       "apihelp-help-param-submodules": "Súgó megjelenítése a megadott modul almoduljaihoz is.",
+       "apihelp-help-param-recursivesubmodules": "Súgó megjelenítése az almodulokhoz rekurzívan.",
+       "apihelp-help-param-helpformat": "A súgó kimeneti formátuma.",
+       "apihelp-help-param-wrap": "Az eredmény visszaadása a szabványos API-válaszstruktúrában.",
+       "apihelp-help-param-toc": "A HTML-kimenet tartalmazzon egy tartalomjegyzéket.",
+       "apihelp-help-example-main": "Súgó megjelenítése a fő modulhoz.",
+       "apihelp-help-example-submodules": "Súgó az <kbd>action=query</kbd> modulhoz és összes almoduljához.",
+       "apihelp-help-example-recursive": "Minden súgó egy lapon.",
+       "apihelp-help-example-help": "Súgó magához a súgó modulhoz.",
+       "apihelp-help-example-query": "Súgó két lekérdező almodulhoz.",
+       "apihelp-imagerotate-description": "Egy vagy több kép elforgatása.",
+       "apihelp-imagerotate-param-rotation": "A kép forgatása ennyi fokkal az óramutató járásával megegyező irányban.",
+       "apihelp-imagerotate-example-simple": "<kbd>Example.png</kbd> elforgatása <kbd>90</kbd> fokkal.",
+       "apihelp-imagerotate-example-generator": "Az összes kép elforgatása a <kbd>Category:Flip</kbd> kategóriában <kbd>180</kbd> fokkal.",
+       "apihelp-import-description": "Egy lap importálása egy másik wikiből vagy XML-fájlból.\n\nA HTTP POST-kérést fájlfeltöltésként kell elküldeni (multipart/form-data használatával) a <var>xml</var> paraméter használatakor.",
+       "apihelp-import-param-xml": "Feltöltött XML-fájl.",
+       "apihelp-import-param-interwikisource": "Wikiközi importálásnál: forráswiki.",
+       "apihelp-import-param-interwikipage": "Wikiközi importálásnál: az importálandó lap.",
+       "apihelp-import-param-fullhistory": "Wikiközi importálásnál: teljes laptörténet importálása, nem csak az aktuális változat.",
+       "apihelp-import-param-templates": "Wikiközi importálásnál: importálás a lapon használt sablonokkal együtt.",
+       "apihelp-import-param-namespace": "Importálás ebbe a névtérbe. Nem használható együtt a <var>$1rootpage</var> paraméterrel.",
+       "apihelp-import-param-rootpage": "Importálás ennek a lapnak az allapjaként. Nem használható együtt a <var>$1namespace</var> paraméterrel.",
+       "apihelp-import-example-import": "[[meta:Help:ParserFunctions]] importálása a 100-as névtérbe teljes laptörténettel.",
+       "apihelp-linkaccount-description": "Egy harmadik fél szolgáltató fiókjának kapcsolása a jelenlegi felhasználóhoz.",
+       "apihelp-linkaccount-example-link": "Összekapcsolás elkezdése <kbd>Example</kbd> szolgáltató fiókjával.",
+       "apihelp-login-description": "Bejelentkezés és hitelesítő sütik lekérése.\n\nEz a művelet csak [[Special:BotPasswords|botjelszavakkal]] használandó; a fő fiókkal való használat elavult és figyelmeztetés nélkül sikertelen lehet. A fő fiókkal való biztonságos bejelentkezéshez használd az <kbd>[[Special:ApiHelp/clientlogin|action=clientlogin]]</kbd> paramétert.",
+       "apihelp-login-description-nobotpasswords": "Bejelentkezés és hitelesítő sütik lekérése.\n\nEz a művelet elavult és figyelmeztetés nélkül sikertelen lehet. A biztonságos bejelentkezéshez használd az <kbd>[[Special:ApiHelp/clientlogin|action=clientlogin]]</kbd> paramétert.",
        "apihelp-login-param-name": "Szerkesztőnév.",
        "apihelp-login-param-password": "Jelszó.",
        "apihelp-login-param-domain": "Tartomány (opcionális)",
+       "apihelp-login-param-token": "Az első kérésben megszerzett bejelentkezési token.",
+       "apihelp-login-example-gettoken": "Egy bejelentkezés token lekérése.",
        "apihelp-login-example-login": "Bejelentkezés.",
+       "apihelp-logout-description": "Kijelentkezés és munkamenetadatok törlése.",
        "apihelp-logout-example-logout": "Aktuális felhasználó kijelentkeztetése.",
+       "apihelp-managetags-description": "A változtatáscímkék kezelése.",
+       "apihelp-managetags-param-operation": "A végrehajtandó feladat:\n;create: Új változtatáscímke létrehozása kézi használatra.\n;delete: Egy változtatáscímke eltávolítása az adatbázisból, beleértve az eltávolítását minden lapváltozatról, frissváltoztatások-bejegyzésről és naplóbejegyzésről, ahol használatban van.\n;activate: Egy változtatáscímke aktiválása, lehetővé téve a felhasználóknak a kézi használatát.\n;deactivate: Egy változtatáscímke deaktiválása, a felhasználók megakadályozása a kézi használatban.",
+       "apihelp-managetags-param-tag": "A létrehozandó, törlendő, aktiválandó vagy deaktiválandó címke. Létrehozás esetén adott nevű címke nem létezhet. Törlés esetén a címkének léteznie kell. Aktiválás esetén a címkének léteznie kell, és nem használhatja más kiterjesztés. Deaktiválás esetén a címkének aktívnak és kézzel definiáltnak  kell lennie.",
+       "apihelp-managetags-param-reason": "Opcionális indoklás a címke létrehozásához, törléséhez, aktiválásához vagy deaktiválásához.",
+       "apihelp-managetags-param-ignorewarnings": "Figyelmeztetések figyelmen kívül hagyása a művelet közben.",
+       "apihelp-managetags-example-create": "<kbd>spam</kbd> címke létrehozása <kbd>For use in edit patrolling</kbd> indoklással",
+       "apihelp-managetags-example-delete": "<kbd>vandlaism</kbd> címke törlése <kbd>Misspelt</kbd> indoklással",
+       "apihelp-managetags-example-activate": "<kbd>spam</kbd> címke aktiválása <kbd>For use in edit patrolling</kbd> indoklással",
+       "apihelp-managetags-example-deactivate": "<kbd>spam</kbd> címke deaktiválása <kbd>No longer required</kbd> indoklással",
        "apihelp-mergehistory-description": "Laptörténetek egyesítése",
        "apihelp-mergehistory-param-reason": "Laptörténet egyesítésének oka.",
        "apihelp-move-description": "Egy lap átnevezése.",
+       "apihelp-move-param-from": "Az átnevezendő lap címe. Nem használható együtt a <var>$1fromid</var> paraméterrel.",
+       "apihelp-move-param-fromid": "Az átnevezendő lap lapazonosítója. Nem használható együtt a <var>$1from</var> paraméterrel.",
+       "apihelp-move-param-to": "A lap új címe.",
        "apihelp-move-param-reason": "Az átnevezés oka.",
        "apihelp-move-param-movetalk": "Nevezd át a vitalapot is, ha létezik.",
        "apihelp-move-param-movesubpages": "Nevezd át az allapokat is, ha lehetséges.",
        "apihelp-move-param-noredirect": "Ne készíts átirányítást.",
+       "apihelp-move-param-watch": "A lap és az átirányítás hozzáadása a jelenlegi felhasználó figyelőlistájához.",
+       "apihelp-move-param-unwatch": "A lap és az átirányítás eltávolítása a jelenlegi felhasználó figyelőlistájáról.",
+       "apihelp-move-param-watchlist": "A lap hozzáadása a figyelőlistához vagy eltávolítása onnan feltétel nélkül, a beállítások használata vagy a figyelőlista érintetlenül hagyása.",
        "apihelp-move-param-ignorewarnings": "Figyelmeztetések figyelmen kívül hagyása.",
+       "apihelp-move-example-move": "<kbd>Badtitle</kbd> átnevezése <kbd>Goodtitle</kbd> címre átirányítás készítése nélkül.",
+       "apihelp-opensearch-description": "Keresés a wikin az OpenSearch protokoll segítségével.",
+       "apihelp-opensearch-param-search": "A keresőkifejezés.",
        "apihelp-opensearch-param-limit": "Találatok maximális száma.",
+       "apihelp-opensearch-param-namespace": "A keresendő névterek.",
+       "apihelp-opensearch-param-suggest": "Ne csináljon semmit, ha a <var>[[mw:Special:MyLanguage/Manual:$wgEnableOpenSearchSuggest|$wgEnableOpenSearchSuggest]]</var> hamis.",
+       "apihelp-opensearch-param-redirects": "Hogyan kezelje az átirányításokat:\n;return: Magának az átirányításnak a visszaadása.\n;resolve: A céllap visszaadása. Lehet, hogy kevesebb mint <var>$1limit</var> találatot ad vissza.\nTörténeti okokból az alapértelmezés „return” <kbd>$1format=json</kbd> esetén és „resolve” más formátumoknál.",
+       "apihelp-opensearch-param-format": "A kimenet formátuma.",
+       "apihelp-opensearch-example-te": "<kbd>Te</kbd>-vel kezdődő lapok keresése.",
+       "apihelp-options-description": "A jelenlegi felhasználó beállításainak módosítása.\n\nCsak a MediaWiki vagy kiterjesztései által kínált, valamint a <code>userjs-</code> előtagú (felhasználói parancsfájloknak szánt) beállítások állíthatók be.",
+       "apihelp-options-param-reset": "Beállítások visszaállítása a wiki alapértelmezéseire.",
+       "apihelp-options-param-resetkinds": "A visszaállítandó beállítások típusa(i) a <var>$1reset</var> paraméter használatakor.",
+       "apihelp-options-param-change": "Változtatások listája név=érték formátumban (pl. <kbd>skin=vector</kbd>). Ha nincs érték megadva (egyenlőségjel sem szerepel – pl. <kbd>beállítás|másik|…</kbd>), a beállítások visszaállnak az alapértelmezett értékre. Ha bármilyen érték tartalmaz függőleges vonal karaktert (<kbd>|</kbd>), használd az [[Special:ApiHelp/main#main/datatypes|alternatív elválasztókaraktert]] a megfelelő működéshez.",
+       "apihelp-options-param-optionname": "Az <var>$1optionvalue</var> értékre állítandó beállítás neve.",
+       "apihelp-options-param-optionvalue": "Az <var>$1optionname</var> beállítás értéke.",
        "apihelp-options-example-reset": "Minden beállítás visszaállítása",
+       "apihelp-options-example-change": "A <kbd>skin</kbd> és a <kbd>hideminor</kbd> beállítások módosítása.",
+       "apihelp-options-example-complex": "Minden beállítás visszaállítása, majd a <kbd>skin</kbd> és a <kbd>nickname</kbd> beállítása.",
+       "apihelp-parse-paramvalue-prop-parsewarnings": "A tartalom feldolgozása közben előforduló hibák visszaadása.",
        "apihelp-protect-example-protect": "Lap levédése.",
        "apihelp-query+allcategories-param-dir": "A rendezés iránya.",
        "apihelp-query+deletedrevs-paraminfo-modes": "{{PLURAL:$1|Mód|Módok}}: $2",
        "api-help-param-type-boolean": "Típus: logikai ([[Special:ApiHelp/main#main/datatypes|részletek]])",
        "api-help-param-type-timestamp": "Típus: {{PLURAL:$1|1=időbélyeg|2=időbélyegek listája}} ([[Special:ApiHelp/main#main/datatypes|engedélyezett formátumok]])",
        "api-help-param-type-user": "Típus: {{PLURAL:$1|1=felhasználónév|2=felhasználónevek listája}}",
-       "api-help-param-list": "{{PLURAL:$1|1=A következő értékek egyike|2=Értékek (elválasztó: <kbd>{{!}}</kbd>)}}: $2",
+       "api-help-param-list": "{{PLURAL:$1|1=A következő értékek egyike|2=Értékek (elválasztó: <kbd>{{!}}</kbd> vagy [[Special:ApiHelp/main#main/datatypes|más]])}}: $2",
        "api-help-param-list-can-be-empty": "{{PLURAL:$1|0=Üresnek kell lennie|Lehet üres vagy $2}}",
        "api-help-param-limit": "Nem engedélyezett több mint $1.",
        "api-help-param-limit2": "Nem engedélyezett több mint $1 (botoknak $2).",
index 22b23f0..0cc154f 100644 (file)
        "apihelp-query+redirects-param-namespace": "Includi solo le pagine in questi namespace.",
        "apihelp-query+redirects-param-limit": "Quanti reindirizzamenti restituire.",
        "apihelp-query+redirects-example-simple": "Ottieni un elenco di redirect a [[Main Page]].",
-       "apihelp-query+revisions-param-startid": "L'ID versione da cui iniziare l'elenco.",
+       "apihelp-query+revisions-param-startid": "Inizia l'elenco dal timestamp di questa versione. La versione deve esistere, ma non necessariamente deve appartenere a questa pagina.",
        "apihelp-query+revisions-param-start": "Il timestamp della versione da cui iniziare l'elenco.",
        "apihelp-query+revisions-param-tag": "Elenca solo le versioni etichettate con questa etichetta.",
        "apihelp-query+revisions+base-paramvalue-prop-ids": "L'ID della versione.",
index 6e70653..da0b22d 100644 (file)
        "apihelp-parse-paramvalue-prop-limitreporthtml": "{{doc-apihelp-paramvalue|parse|prop|limitreporthtml}}",
        "apihelp-parse-paramvalue-prop-parsetree": "{{doc-apihelp-paramvalue|parse|prop|parsetree|params=* $1 - Value of the constant CONTENT_MODEL_WIKITEXT|paramstart=2}}",
        "apihelp-parse-paramvalue-prop-parsewarnings": "{{doc-apihelp-paramvalue|parse|prop|parsewarnings}}",
+       "apihelp-parse-param-wrapoutputclass": "{{doc-apihelp-param|parse|wrapoutputclass}}",
        "apihelp-parse-param-pst": "{{doc-apihelp-param|parse|pst}}",
        "apihelp-parse-param-onlypst": "{{doc-apihelp-param|parse|onlypst}}",
        "apihelp-parse-param-effectivelanglinks": "{{doc-apihelp-param|parse|effectivelanglinks}}",
        "apierror-revdel-mutuallyexclusive": "{{doc-apierror}}",
        "apierror-revdel-needtarget": "{{doc-apierror}}",
        "apierror-revdel-paramneeded": "{{doc-apierror}}",
+       "apierror-revisions-badid": "{{doc-apierror}}\n\nParameters:\n* $1 - Parameter in question, e.g. \"rvstartid\".",
        "apierror-revisions-norevids": "{{doc-apierror}}\n\nParameters:\n* $1 - Module parameter prefix, e.g. \"bl\".",
        "apierror-revisions-singlepage": "{{doc-apierror}}\n\nParameters:\n* $1 - Module parameter prefix, e.g. \"bl\".",
        "apierror-revwrongpage": "{{doc-apierror}}\n\nParameters:\n* $1 - Revision ID number.\n* $2 - Page title.",
index 152f1df..8c3c652 100644 (file)
        "apihelp-parse-paramvalue-prop-limitreporthtml": "提供限制报告的HTML版本。当<var>$1disablelimitreport</var>被设置时不会提供数据。",
        "apihelp-parse-paramvalue-prop-parsetree": "修订内容的XML解析树(需要内容模型<code>$1</code>)",
        "apihelp-parse-paramvalue-prop-parsewarnings": "在解析内容时提供发生的警告",
+       "apihelp-parse-param-wrapoutputclass": "要用于包裹解析输出的CSS类。",
        "apihelp-parse-param-pst": "在解析输入前,对输入做一次保存前变换处理。仅当使用文本时有效。",
        "apihelp-parse-param-onlypst": "在输入内容中执行预保存转换(PST),但不解析它。在PST被应用后返回相同的wiki文本。只当与<var>$1text</var>一起使用时有效。",
        "apihelp-parse-param-effectivelanglinks": "包含由扩展提供的语言链接(用于与<kbd>$1prop=langlinks</kbd>一起使用)。",
index 355aff4..8f88ee9 100644 (file)
@@ -193,6 +193,7 @@ class MessageCache {
                                $po = ParserOptions::newFromAnon();
                                $po->setEditSection( false );
                                $po->setAllowUnsafeRawHtml( false );
+                               $po->setWrapOutputClass( false );
                                return $po;
                        }
 
@@ -202,6 +203,11 @@ class MessageCache {
                        // from malicious sources. As a precaution, disable
                        // the <html> parser tag when parsing messages.
                        $this->mParserOptions->setAllowUnsafeRawHtml( false );
+                       // Wrapping messages in an extra <div> is probably not expected. If
+                       // they're outside the content area they probably shouldn't be
+                       // targeted by CSS that's targeting the parser output, and if
+                       // they're inside they already are from the outer div.
+                       $this->mParserOptions->setWrapOutputClass( false );
                }
 
                return $this->mParserOptions;
@@ -458,7 +464,11 @@ class MessageCache {
        protected function loadFromDB( $code, $mode = null ) {
                global $wgMaxMsgCacheEntrySize, $wgLanguageCode, $wgAdaptiveMessageCache;
 
-               $dbr = wfGetDB( ( $mode == self::FOR_UPDATE ) ? DB_MASTER : DB_REPLICA );
+               // (T164666) The query here performs really poorly on WMF's
+               // contributions replicas. We don't have a way to say "any group except
+               // contributions", so for the moment let's specify 'api'.
+               // @todo: Get rid of this hack.
+               $dbr = wfGetDB( ( $mode == self::FOR_UPDATE ) ? DB_MASTER : DB_REPLICA, 'api' );
 
                $cache = [];
 
@@ -509,15 +519,18 @@ class MessageCache {
 
                # Conditions to load the remaining pages with their contents
                $smallConds = $conds;
-               $smallConds[] = 'page_latest=rev_id';
-               $smallConds[] = 'rev_text_id=old_id';
                $smallConds[] = 'page_len <= ' . intval( $wgMaxMsgCacheEntrySize );
 
                $res = $dbr->select(
                        [ 'page', 'revision', 'text' ],
                        [ 'page_title', 'old_id', 'old_text', 'old_flags' ],
                        $smallConds,
-                       __METHOD__ . "($code)-small"
+                       __METHOD__ . "($code)-small",
+                       [],
+                       [
+                               'revision' => [ 'JOIN', 'page_latest=rev_id' ],
+                               'text' => [ 'JOIN', 'rev_text_id=old_id' ],
+                       ]
                );
 
                foreach ( $res as $row ) {
index 46cae8f..9bde056 100644 (file)
@@ -404,8 +404,8 @@ class ChangeTags {
                }
 
                // to be applied, a tag has to be explicitly defined
-               // @todo Allow extensions to define tags that can be applied by users...
                $allowedTags = self::listExplicitlyDefinedTags();
+               Hooks::run( 'ChangeTagsAllowedAdd', [ &$allowedTags, $tags, $user ] );
                $disallowedTags = array_diff( $tags, $allowedTags );
                if ( $disallowedTags ) {
                        return self::restrictedTagError( 'tags-apply-not-allowed-one',
@@ -660,7 +660,7 @@ class ChangeTags {
 
                        $tables[] = 'change_tag';
                        $join_conds['change_tag'] = [ 'INNER JOIN', $join_cond ];
-                       $conds['ct_tag'] = explode( ',', $filter_tag );
+                       $conds['ct_tag'] = explode( '|', $filter_tag );
                }
        }
 
@@ -947,9 +947,12 @@ class ChangeTags {
                        return Status::newFatal( 'tags-create-no-name' );
                }
 
-               // tags cannot contain commas (used as a delimiter in tag_summary table) or
-               // slashes (would break tag description messages in MediaWiki namespace)
-               if ( strpos( $tag, ',' ) !== false || strpos( $tag, '/' ) !== false ) {
+               // tags cannot contain commas (used as a delimiter in tag_summary table),
+               // pipe (used as a delimiter between multiple tags in
+               // modifyDisplayQuery), or slashes (would break tag description messages in
+               // MediaWiki namespace)
+               if ( strpos( $tag, ',' ) !== false || strpos( $tag, '|' ) !== false
+                       || strpos( $tag, '/' ) !== false ) {
                        return Status::newFatal( 'tags-create-invalid-chars' );
                }
 
index fd5c3f7..880cf9f 100644 (file)
@@ -73,7 +73,7 @@ class EtcdConfig implements Config, LoggerAwareInterface {
                        'encoding' => 'JSON',
                        'cacheTTL' => 10,
                        'skewTTL' => 1,
-                       'timeout' => 10
+                       'timeout' => 2
                ];
 
                $this->host = $params['host'];
@@ -215,7 +215,7 @@ class EtcdConfig implements Config, LoggerAwareInterface {
                        }
 
                        // Avoid the server next time if that failed
-                       $dsd->removeServer( $server, $servers );
+                       $servers = $dsd->removeServer( $server, $servers );
                } while ( $servers );
 
                return [ $config, $error, $retry ];
index 843d540..3028dfd 100644 (file)
@@ -6,7 +6,7 @@
  * but instead manually called by WikitextHandler.
  * This should be fixed in the future.
  */
-class FileContentHandler extends WikitextContentHandler  {
+class FileContentHandler extends WikitextContentHandler {
 
        public function getFieldsForSearchIndex( SearchEngine $engine ) {
                $fields['file_media_type'] =
index a4cb695..e5cbb7c 100644 (file)
@@ -926,11 +926,41 @@ abstract class DatabaseUpdater {
                } elseif ( $this->updateRowExists( $updateKey ) ) {
                        $this->output( "...$field in table $table already modified by patch $patch.\n" );
                } else {
-                       $this->insertUpdateRow( $updateKey );
+                       $apply = $this->applyPatch( $patch, $fullpath, "Modifying $field field of table $table" );
+                       if ( $apply ) {
+                               $this->insertUpdateRow( $updateKey );
+                       }
+                       return $apply;
+               }
+               return true;
+       }
 
-                       return $this->applyPatch( $patch, $fullpath, "Modifying $field field of table $table" );
+       /**
+        * Modify an existing table, similar to modifyField. Intended for changes that
+        *  touch more than one column on a table.
+        *
+        * @param string $table Name of the table to modify
+        * @param string $patch Name of the patch file to apply
+        * @param string $fullpath Whether to treat $patch path as relative or not, defaults to false
+        * @return bool False if this was skipped because of schema changes being skipped
+        */
+       public function modifyTable( $table, $patch,  $fullpath = false ) {
+               if ( !$this->doTable( $table ) ) {
+                       return true;
                }
 
+               $updateKey = "$table-$patch";
+               if ( !$this->db->tableExists( $table, __METHOD__ ) ) {
+                       $this->output( "...$table table does not exist, skipping modify table patch.\n" );
+               } elseif ( $this->updateRowExists( $updateKey ) ) {
+                       $this->output( "...table $table already modified by patch $patch.\n" );
+               } else {
+                       $apply = $this->applyPatch( $patch, $fullpath, "Modifying table $table" );
+                       if ( $apply ) {
+                               $this->insertUpdateRow( $updateKey );
+                       }
+                       return $apply;
+               }
                return true;
        }
 
index 7df1009..a9710eb 100644 (file)
@@ -69,7 +69,7 @@ class LocalSettingsGenerator {
                        $db->getGlobalNames()
                );
 
-               $unescaped = [ 'wgRightsIcon', 'wgLogo' ];
+               $unescaped = [ 'wgRightsIcon', 'wgLogo', '_Caches' ];
                $boolItems = [
                        'wgEnableEmail', 'wgEnableUserEmail', 'wgEnotifUserTalk',
                        'wgEnotifWatchlist', 'wgEmailAuthentication', 'wgEnableUploads', 'wgUseInstantCommons',
index dfe595e..1a9915d 100644 (file)
@@ -114,7 +114,9 @@ class MssqlUpdater extends DatabaseUpdater {
 
        /**
         * General schema update for a table that touches more than one field or requires
-        * destructive actions (such as dropping and recreating the table).
+        * destructive actions (such as dropping and recreating the table). NOTE: Usage of
+        * this function is highly discouraged, use it's successor DatabaseUpdater::modifyTable
+        * instead.
         *
         * @param string $table
         * @param string $updatekey
@@ -127,9 +129,11 @@ class MssqlUpdater extends DatabaseUpdater {
                } elseif ( $this->updateRowExists( $updatekey ) ) {
                        $this->output( "...$table already had schema updated by $patch.\n" );
                } else {
-                       $this->insertUpdateRow( $updatekey );
-
-                       return $this->applyPatch( $patch, $fullpath, "Updating schema of table $table" );
+                       $apply = $this->applyPatch( $patch, $fullpath, "Updating schema of table $table" );
+                       if ( $apply ) {
+                               $this->insertUpdateRow( $updatekey );
+                       }
+                       return $apply;
                }
 
                return true;
index 98af267..c12123d 100644 (file)
@@ -6,7 +6,8 @@
                        "Phoenix303",
                        "संजीव कुमार",
                        "Sahilrathod",
-                       "Shyamal"
+                       "Shyamal",
+                       "Sfic"
                ]
        },
        "config-desc": "साँचा लिए इंस्टॉलर",
        "config-localsettings-badkey": "आपकी दी गई कुंजी ग़लत है।",
        "config-your-language": "आपकी भाषा:",
        "config-your-language-help": "स्थापन के लिए भाषा चुनें",
-       "config-wiki-language": "विà¤\95à¥\80 भाषा:",
+       "config-wiki-language": "विà¤\95ि भाषा:",
        "config-wiki-language-help": "भाषा चुनें जिस  में अधिकतर लेख लिखा जाएगा",
        "config-back": "← वापस",
        "config-continue": "आगे बढ़ें →",
        "config-page-language": "भाषा",
-       "config-page-welcome": "मà¥\80डियाविà¤\95à¥\80 à¤ªà¤° आपका स्वागत है!",
-       "config-page-dbconnect": "डà¥\87à¤\9fाबà¥\87स à¤¸à¥\87 à¤\9cà¥\81ड़ें",
+       "config-page-welcome": "मà¥\80डियाविà¤\95ि à¤®à¥\87à¤\82 आपका स्वागत है!",
+       "config-page-dbconnect": "डà¥\87à¤\9fाबà¥\87स à¤¸à¥\87 à¤\9cà¥\8bड़ें",
        "config-page-upgrade": "मौजूदा स्थापना का नवीनीकरण",
-       "config-page-dbsettings": "डà¥\87à¤\9fाबà¥\87स à¤µà¤°à¤¿à¤¯à¤¤à¤¾à¤¯à¥\87à¤\82",
+       "config-page-dbsettings": "डà¥\87à¤\9fाबà¥\87स à¤¸à¥\87à¤\9fिà¤\82à¤\97 (पसà¤\82द)",
        "config-page-name": "नाम",
        "config-page-options": "विकल्प",
        "config-page-install": "स्थापित करें",
        "config-page-existingwiki": "मौजूदा विकि",
        "config-restart": "हाँ, इसे पुनः आरंभ करें",
        "config-env-php": "PHP $1 स्थापित किया गया है।",
+       "config-env-hhvm": "एचएचवीएम $1 स्थापित किया गया है।",
+       "config-memory-raised": "पीएचपी की <code>memory_limit</code> सीमा $1 है, जो $2 तक बढ़ गई है।",
+       "config-xcache": "[http://xcache.lighttpd.net/ एक्सकैश] स्थापित है।",
+       "config-apc": "[http://www.php.net/apc एपीसी] स्थापित है।",
+       "config-apcu": "[http://www.php.net/apcu एपीसीयू] स्थापित है।",
+       "config-wincache": "[http://www.iis.net/download/WinCacheForPhp विनकैश] स्थापित है।",
+       "config-db-type": "डेटाबेस प्रकार:",
+       "config-db-host": "डेटाबेस होस्ट:",
+       "config-db-host-oracle": "डेटाबेस टीएनएस:",
        "config-db-wiki-settings": "इस विकि को पहचानें",
-       "config-db-install-account": "इंस्टालेशन के लिए उपयोगकर्ता खाता",
+       "config-db-name": "डेटाबेस का नाम:",
+       "config-db-install-account": "इसे स्थापित करने हेतु सदस्य खाता",
+       "config-db-username": "डेटाबेस सदस्यनाम:",
+       "config-db-password": "डेटाबेस पासवर्ड:",
+       "config-db-port": "डेटाबेस पोर्ट:",
+       "config-type-mssql": "माइक्रोसॉफ़्ट एसक्यूएल सर्वर",
+       "config-invalid-db-type": "अमान्य डेटाबेस प्रकार",
+       "config-regenerate": "LocalSettings.php फिर से निर्मित करें →",
+       "config-db-web-account": "वेब पहुँच हेतु डेटाबेस खाता",
+       "config-mysql-innodb": "इनोडीबी",
+       "config-mysql-binary": "बाइनरी",
+       "config-mysql-utf8": "UTF-8",
        "config-mssql-auth": "प्रमाणन प्रकार:",
        "config-mssql-sqlauth": "SQL सर्वर प्रमाणन",
        "config-site-name": "विकि का नाम:",
@@ -53,6 +74,7 @@
        "config-admin-name": "आपका उपयोगकर्ता नाम:",
        "config-admin-password": "कूटशब्द:",
        "config-admin-password-confirm": "फिर से कूटशब्द:",
+       "config-admin-name-blank": "प्रबन्धक का सदस्य नाम लिखें।",
        "config-admin-email": "ईमेल पता:",
        "config-optional-continue": "मुझसे और सवाल पूछें।",
        "config-optional-skip": "मैं पहले से ही ऊब चुका हूँ, बस विकि स्थापित करें।",
        "config-profile-fishbowl": "केवल प्रमाषित संपादक ही",
        "config-profile-private": "निजी विकि",
        "config-license-cc-by": "क्रिएटिव कॉमन्स ऍट्रीब्यूशन",
+       "config-license-pd": "सार्वजनिक डोमैन",
        "config-email-watchlist": "ध्यानसूची अधिसूचना को सक्षम करें",
+       "config-upload-enable": "फ़ाइल अपलोड सक्रिय करें",
+       "config-upload-help": "यदि आप अपने सर्वर में फ़ाइल अपलोड की सेवा दे रहे हैं तो आपको सुरक्षा से समझौता करना पड़ सकता है।\n\nअधिक जानकारी के लिए मार्गदर्शक में [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Security सुरक्षा अनुभाग] देखें।\n\nयदि आप फ़ाइल अपलोड को सक्रिय करना चाहते हैं तो आपको मीडियाविकि के फोंल्डर के <code>images</code> फोंल्डर में जाने के बाद उसे सर्वर द्वारा लिखने लायक बनाना होगा।\nउसके बाद ही आप इस विकल्प को सक्रिय कर सकते हैं।",
+       "config-logo": "''लोगो'' का पता:",
+       "config-instantcommons": "''कॉमन्स'' सक्रिय करें",
+       "config-instantcommons-help": "[https://www.mediawiki.org/wiki/InstantCommons कॉमन्स] एक प्रकार की विशेषता प्रदान करता है, जिससे आप विकि में [https://commons.wikimedia.org/ विकिमीडिया कॉमन्स] साइट के किसी भी तस्वीर, आवाज या अन्य फ़ाइल का उपयोग अपने मीडियाविकि में कर सकते हैं। इसके लिए मीडियाविकि को इंटरनेट से जुड़ा होना चाहिए।\n\nइस विशेषता की अधिक जानकारी के लिए और इसे किस प्रकार आप अपने विकि में सक्रिय कर सकते हैं आदि जानने के लिए [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:$wgForeignFileRepos मार्गदर्शक] देखें।",
        "config-extensions": "एक्सटेंशन",
+       "config-skins": "त्वचा",
+       "config-install-step-done": "पूरा हुआ",
+       "config-install-step-failed": "विफल हुआ",
+       "config-install-user-alreadyexists": "सदस्य \"$1\" पहले से उपस्थित है।",
+       "config-install-user-create-failed": "सदस्य \"$1\" का निर्माण विफल हुआ: $2",
+       "config-install-keys": "गुप्त कुंजी बना रहा",
+       "config-install-sysop": "प्रबन्धक सदस्य खाता बना रहा",
+       "config-download-localsettings": "<code>LocalSettings.php</code> को डाउनलोड करें।",
        "config-help": "सहायता",
+       "config-help-tooltip": "विस्तार हेतु क्लिक करें",
        "config-nofile": "फ़ाइल \"$1\" नहीं पाई जा सकी। क्या इसे हटा दिया गया है?",
-       "mainpagetext": "'''मीडियाविकिका इन्स्टॉलेशन पूरा हो गया हैं ।'''",
-       "mainpagedocfooter": "विà¤\95ि à¤¸à¥\89फà¥\8dà¤\9fवà¥\87यरà¤\95à¥\87 à¤\87सà¥\8dतà¥\87माल à¤\95à¥\87 à¤²à¤¿à¤¯à¥\87 [https://meta.wikimedia.org/wiki/Help:Contents à¤\89पयà¥\8bà¤\97à¤\95रà¥\8dता à¤\97ाà¤\88ड] à¤¦à¥\87à¤\96à¥\87à¤\82 à¥¤\n\n== à¤¶à¥\81रà¥\81वात à¤\95रà¥\87à¤\82 ==\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Configuration_settings à¤\95à¥\89नà¥\8dफिà¤\97रà¥\87शन à¤¸à¥\87à¤\9fà¥\80à¤\82à¤\97à¤\95à¥\80 à¤¸à¥\82à¤\9aà¥\80]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ à¤®à¥\80डियाविà¤\95िà¤\95à¥\87 à¤¬à¤¾à¤°à¥\87 à¤®à¥\87à¤\82 à¤ªà¥\8dराय: à¤ªà¥\82à¤\9bà¥\87 à¤\9cानà¥\87 à¤µà¤¾à¤²à¥\87 à¤¸à¤µà¤¾à¤²]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce à¤®à¥\80डियाविà¤\95ि à¤®à¥\87लिà¤\82à¤\97 à¤²à¤¿à¤¸à¥\8dà¤\9f]"
+       "mainpagetext": "<strong>मीडियाविकि का अब स्थापित हो चुका है।</strong>",
+       "mainpagedocfooter": "à¤\87स à¤µà¤¿à¤\95ि à¤¸à¥\89फà¥\8dà¤\9fवà¥\87यर à¤\95ा à¤\95िस à¤ªà¥\8dरà¤\95ार à¤\86प à¤\87सà¥\8dतà¥\87माल à¤\95र à¤¸à¤\95तà¥\87 à¤¹à¥\88à¤\82, à¤\87सà¤\95à¥\80 à¤\9cानà¤\95ारà¥\80 à¤\95à¥\87 à¤²à¤¿à¤\8f [https://meta.wikimedia.org/wiki/Help:Contents à¤\89पयà¥\8bà¤\97 à¤®à¤¾à¤°à¥\8dà¤\97दरà¥\8dशà¤\95] à¤¦à¥\87à¤\96à¥\87à¤\82।\n== à¤¶à¥\81रà¥\81à¤\86त à¤\95रà¥\87à¤\82 ==\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Configuration_settings à¤µà¤¿à¤\95ि à¤®à¥\87à¤\82 à¤¬à¤¦à¤²à¤¾à¤µ à¤\95à¥\80 à¤¸à¥\82à¤\9aà¥\80]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ à¤®à¥\80डियाविà¤\95ि à¤\95à¥\87 à¤¬à¤¾à¤°à¥\87 à¤®à¥\87à¤\82 à¤ªà¥\8dराय: à¤ªà¥\82à¤\9bà¥\87 à¤\9cानà¥\87 à¤µà¤¾à¤²à¥\87 à¤¸à¤µà¤¾à¤²]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce à¤®à¥\80डियाविà¤\95ि à¤\95à¥\80 à¤®à¥\87ल à¤¸à¥\82à¤\9aà¥\80]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Localisation#Translation_resources à¤®à¥\80डियाविà¤\95ि à¤\95ा à¤\86पà¤\95à¥\87 à¤­à¤¾à¤·à¤¾ à¤®à¥\87à¤\82 à¤\85नà¥\81वाद]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Combating_spam à¤\85पनà¥\87 à¤µà¤¿à¤\95ि à¤\95à¥\8b à¤\95िस à¤ªà¥\8dरà¤\95ार à¤¸à¥\87 à¤µà¤¿à¤\9cà¥\8dà¤\9eापन à¤¡à¤¾à¤²à¤¨à¥\87 à¤µà¤¾à¤²à¥\87 à¤\94र à¤¬à¤°à¥\8dबरता à¤\95रनà¥\87 à¤µà¤¾à¤²à¥\8bà¤\82 à¤¸à¥\87 à¤¬à¤\9aा à¤¸à¤\95तà¥\87 à¤¹à¥\88à¤\82]"
 }
index a499553..ca02841 100644 (file)
        "config-unknown-collation": "'''Waarschuwing:''' de database gebruikt een collatie die niet wordt herkend.",
        "config-db-web-account": "Databaseaccount voor webtoegang",
        "config-db-web-help": "Selecteer de gebruikersnaam en het wachtwoord die de webserver gebruikt om verbinding te maken met de databaseserver na de installatie.",
-       "config-db-web-account-same": "Dezelfde account gebruiken als voor de installatie",
+       "config-db-web-account-same": "Hetzelfde account gebruiken als voor de installatie",
        "config-db-web-create": "Maak de gebruiker aan als deze nog niet bestaat",
        "config-db-web-no-create-privs": "De gebruiker die u hebt opgegeven voor de installatie heeft niet voldoende rechten om een gebruiker aan te maken.\nDe gebruiker die u hier opgeeft moet al bestaan.",
        "config-mysql-engine": "Opslagmethode:",
index 558e32c..8dd6193 100644 (file)
@@ -92,12 +92,12 @@ class Interwiki {
        }
 
        /**
-        * Returns all interwiki prefixes
+        * Returns all interwiki prefix definitions.
         *
         * @deprecated since 1.28, unused. Use InterwikiLookup instead.
         *
         * @param string|null $local If set, limits output to local/non-local interwikis
-        * @return array List of prefixes
+        * @return array[] List of interwiki rows
         * @since 1.19
         */
        public static function getAllPrefixes( $local = null ) {
index d0a7719..697e39d 100644 (file)
@@ -47,10 +47,21 @@ interface InterwikiLookup {
        public function fetch( $prefix );
 
        /**
-        * Returns all interwiki prefixes
+        * Returns information about all interwiki prefixes, in the form of rows
+        * of the interwiki table. Each row may have the following keys:
+        *
+        * - iw_prefix: the prefix. Always present.
+        * - iw_url: the URL to use for linking, with $1 as a placeholder for the target page.
+        *           Always present.
+        * - iw_api: the URL of the API. Optional.
+        * - iw_wikiid: the wiki ID (usually the database name for local wikis). Optional.
+        * - iw_local: whether the wiki is local, and the "magic redirect" mechanism should apply.
+        *             Defaults to false.
+        * - iw_trans: whether "scary transclusion" is allowed for this site.
+        *             Defaults to false.
         *
         * @param string|null $local If set, limits output to local/non-local interwikis
-        * @return string[] List of prefixes
+        * @return array[] interwiki rows.
         */
        public function getAllPrefixes( $local = null );
 
index 60d6f43..3baea1a 100644 (file)
@@ -87,16 +87,20 @@ class InterwikiLookupAdapter implements InterwikiLookup {
         * See InterwikiLookup::getAllPrefixes
         *
         * @param string|null $local If set, limits output to local/non-local interwikis
-        * @return string[] List of prefixes
+        * @return array[] interwiki rows
         */
        public function getAllPrefixes( $local = null ) {
-               if ( $local === null ) {
-                       return array_keys( $this->getInterwikiMap() );
-               }
                $res = [];
                foreach ( $this->getInterwikiMap() as $interwikiId => $interwiki ) {
-                       if ( $interwiki->isLocal() === $local ) {
-                               $res[] = $interwikiId;
+                       if ( $local === null || $interwiki->isLocal() === $local ) {
+                               $res[] = [
+                                       'iw_prefix' => $interwikiId,
+                                       'iw_url' => $interwiki->getURL(),
+                                       'iw_api' => $interwiki->getAPI(),
+                                       'iw_wikiid' => $interwiki->getWikiID(),
+                                       'iw_local' => $interwiki->isLocal(),
+                                       'iw_trans' => $interwiki->isTranscludable(),
+                               ];
                        }
                }
                return $res;
index c123619..eb367af 100644 (file)
@@ -231,7 +231,6 @@ class RecentChangesUpdateJob extends Job {
                                        ],
                                        __METHOD__
                                );
-
                        },
                        __METHOD__
                );
index bba07e2..c504f35 100644 (file)
@@ -38,7 +38,7 @@ class CSSMin {
         * Internet Explorer data URI length limit. See encodeImageAsDataURI().
         */
        const DATA_URI_SIZE_LIMIT = 32768;
-       const URL_REGEX = 'url\(\s*[\'"]?(?P<file>[^\?\)\'"]*?)(?P<query>\?[^\)\'"]*?|)[\'"]?\s*\)';
+
        const EMBED_REGEX = '\/\*\s*\@embed\s*\*\/';
        const COMMENT_REGEX = '\/\*.*?\*\/';
 
@@ -72,8 +72,9 @@ class CSSMin {
                $files = [];
 
                $rFlags = PREG_OFFSET_CAPTURE | PREG_SET_ORDER;
-               if ( preg_match_all( '/' . self::URL_REGEX . '/', $stripped, $matches, $rFlags ) ) {
+               if ( preg_match_all( '/' . self::getUrlRegex() . '/', $stripped, $matches, $rFlags ) ) {
                        foreach ( $matches as $match ) {
+                               self::processUrlMatch( $match, $rFlags );
                                $url = $match['file'][0];
 
                                // Skip fully-qualified and protocol-relative URLs and data URIs
@@ -266,7 +267,7 @@ class CSSMin {
                // appears in the rule itself, e.g. in a quoted string. You are advised
                // not to use such characters in file names. We also match start/end of
                // the string to be consistent in edge-cases ('@import url(…)').
-               $pattern = '/(?:^|[;{])\K[^;{}]*' . CSSMin::URL_REGEX . '[^;}]*(?=[;}]|$)/';
+               $pattern = '/(?:^|[;{])\K[^;{}]*' . self::getUrlRegex() . '[^;}]*(?=[;}]|$)/';
 
                $source = preg_replace_callback(
                        $pattern,
@@ -290,13 +291,14 @@ class CSSMin {
 
                                // Build two versions of current rule: with remapped URLs
                                // and with embedded data: URIs (where possible).
-                               $pattern = '/(?P<embed>' . CSSMin::EMBED_REGEX . '\s*|)' . CSSMin::URL_REGEX . '/';
+                               $pattern = '/(?P<embed>' . CSSMin::EMBED_REGEX . '\s*|)' . self::getUrlRegex() . '/';
 
                                $ruleWithRemapped = preg_replace_callback(
                                        $pattern,
                                        function ( $match ) use ( $local, $remote ) {
-                                               $remapped = CSSMin::remapOne( $match['file'], $match['query'], $local, $remote, false );
+                                               self::processUrlMatch( $match );
 
+                                               $remapped = CSSMin::remapOne( $match['file'], $match['query'], $local, $remote, false );
                                                return CSSMin::buildUrlValue( $remapped );
                                        },
                                        $rule
@@ -309,6 +311,8 @@ class CSSMin {
                                        $ruleWithEmbedded = preg_replace_callback(
                                                $pattern,
                                                function ( $match ) use ( $embedAll, $local, $remote, &$mimeTypes ) {
+                                                       self::processUrlMatch( $match );
+
                                                        $embed = $embedAll || $match['embed'];
                                                        $embedded = CSSMin::remapOne(
                                                                $match['file'],
@@ -385,6 +389,69 @@ class CSSMin {
                return false;
        }
 
+       private static function getUrlRegex() {
+               static $urlRegex;
+               if ( $urlRegex === null ) {
+                       // Match these three variants separately to avoid broken urls when
+                       // e.g. a double quoted url contains a parenthesis, or when a
+                       // single quoted url contains a double quote, etc.
+                       // Note: PCRE doesn't support multiple capture groups with the same name by default.
+                       // - PCRE 6.7 introduced the "J" modifier (PCRE_INFO_JCHANGED for PCRE_DUPNAMES).
+                       //   https://secure.php.net/manual/en/reference.pcre.pattern.modifiers.php
+                       //   However this isn't useful since it just ignores all but the first one.
+                       //   Also, while the modifier was introduced in PCRE 6.7 (PHP 5.2+) it was
+                       //   not exposed to public preg_* functions until PHP 5.6.0.
+                       // - PCRE 8.36 fixed this to work as expected (e.g. merge conceptually to
+                       //   only return the one matched in the part that actually matched).
+                       //   However MediaWiki supports 5.5.9, which has PCRE 8.32
+                       //   Per https://secure.php.net/manual/en/pcre.installation.php:
+                       //   - PCRE 8.32 (PHP 5.5.0)
+                       //   - PCRE 8.34 (PHP 5.5.10, PHP 5.6.0)
+                       //   - PCRE 8.37 (PHP 5.5.26, PHP 5.6.9, PHP 7.0.0)
+                       //   Workaround by using different groups and merge via processUrlMatch().
+                       // - Using string concatenation for class constant or member assignments
+                       //   is only supported in PHP 5.6. Use a getter method for now.
+                       $urlRegex = '(' .
+                               // Unquoted url
+                               'url\(\s*(?P<file0>[^\'"][^\?\)]*?)(?P<query0>\?[^\)]*?|)\s*\)' .
+                               // Single quoted url
+                               '|url\(\s*\'(?P<file1>[^\?\']*?)(?P<query1>\?[^\']*?|)\'\s*\)' .
+                               // Double quoted url
+                               '|url\(\s*"(?P<file2>[^\?"]*?)(?P<query2>\?[^"]*?|)"\s*\)' .
+                               ')';
+               }
+               return $urlRegex;
+       }
+
+       private static function processUrlMatch( array &$match, $flags = 0 ) {
+               if ( $flags & PREG_SET_ORDER ) {
+                       // preg_match_all with PREG_SET_ORDER will return each group in each
+                       // match array, and if it didn't match, instead of the sub array
+                       // being an empty array it is `[ '', -1 ]`...
+                       if ( isset( $match['file0'] ) && $match['file0'][1] !== -1 ) {
+                               $match['file'] = $match['file0'];
+                               $match['query'] = $match['query0'];
+                       } elseif ( isset( $match['file1'] ) && $match['file1'][1] !== -1 ) {
+                               $match['file'] = $match['file1'];
+                               $match['query'] = $match['query1'];
+                       } else {
+                               $match['file'] = $match['file2'];
+                               $match['query'] = $match['query2'];
+                       }
+               } else {
+                       if ( isset( $match['file0'] ) && $match['file0'] !== '' ) {
+                               $match['file'] = $match['file0'];
+                               $match['query'] = $match['query0'];
+                       } elseif ( isset( $match['file1'] ) && $match['file1'] !== '' ) {
+                               $match['file'] = $match['file1'];
+                               $match['query'] = $match['query1'];
+                       } else {
+                               $match['file'] = $match['file2'];
+                               $match['query'] = $match['query2'];
+                       }
+               }
+       }
+
        /**
         * Remap or embed a CSS URL path.
         *
index 4a6e3fb..e55bebc 100644 (file)
@@ -63,8 +63,8 @@ class IEUrlExtension {
                // Check QUERY_STRING or REQUEST_URI
                if ( isset( $vars['SERVER_SOFTWARE'] )
                        && isset( $vars['REQUEST_URI'] )
-                       && self::haveUndecodedRequestUri( $vars['SERVER_SOFTWARE'] ) )
-               {
+                       && self::haveUndecodedRequestUri( $vars['SERVER_SOFTWARE'] )
+               {
                        $urlPart = $vars['REQUEST_URI'];
                } elseif ( isset( $vars['QUERY_STRING'] ) ) {
                        $urlPart = $vars['QUERY_STRING'];
@@ -79,8 +79,8 @@ class IEUrlExtension {
                // Some servers have PATH_INFO but not REQUEST_URI, so we check both
                // to be on the safe side.
                if ( isset( $vars['PATH_INFO'] )
-                       && self::isUrlExtensionBad( $vars['PATH_INFO'], $extWhitelist ) )
-               {
+                       && self::isUrlExtensionBad( $vars['PATH_INFO'], $extWhitelist )
+               {
                        return true;
                }
 
@@ -223,8 +223,8 @@ class IEUrlExtension {
                                // If the extension is NOT exe, dll or cgi, return it
                                $extension = substr( $url, $pos, $nextPos - $pos );
                                if ( strcasecmp( $extension, 'exe' ) && strcasecmp( $extension, 'dll' ) &&
-                                       strcasecmp( $extension, 'cgi' ) )
-                               {
+                                       strcasecmp( $extension, 'cgi' )
+                               {
                                        return $extension;
                                }
                                // Else continue looking
index 0d1e527..badcb2b 100644 (file)
@@ -399,8 +399,8 @@ class IEContentAnalyzer {
                $proposedFormat = $this->getDataFormat( $version, $proposed );
                if ( $proposedFormat == 'unknown'
                        && $proposed != 'multipart/mixed'
-                       && $proposed != 'multipart/x-mixed-replace' )
-               {
+                       && $proposed != 'multipart/x-mixed-replace'
+               {
                        return $proposed;
                }
                if ( strval( $chunk ) === '' ) {
@@ -426,15 +426,15 @@ class IEContentAnalyzer {
                        return 'image/gif';
                }
                if ( ( $proposed == 'image/pjpeg' || $proposed == 'image/jpeg' )
-                       && $binaryType == 'image/pjpeg' )
-               {
+                       && $binaryType == 'image/pjpeg'
+               {
                        return $proposed;
                }
                // PNG check added in IE 7
                if ( $version >= 'ie07'
                        && ( $proposed == 'image/x-png' || $proposed == 'image/png' )
-                       && $binaryType == 'image/x-png' )
-               {
+                       && $binaryType == 'image/x-png'
+               {
                        return $proposed;
                }
 
@@ -450,8 +450,8 @@ class IEContentAnalyzer {
                }
                if ( isset( $sampleFound['rdf-tag'] )
                        && isset( $sampleFound['rdf-url'] )
-                       && isset( $sampleFound['rdf-purl'] ) )
-               {
+                       && isset( $sampleFound['rdf-purl'] )
+               {
                        return 'application/rss+xml';
                }
                if ( isset( $sampleFound['atom'] ) ) {
@@ -497,8 +497,8 @@ class IEContentAnalyzer {
                // Freaky heuristics to determine if the data is text or binary
                // The heuristic is of course broken for non-ASCII text
                if ( $counters['ctrl'] != 0 && ( $counters['ff'] + $counters['low'] )
-                       < ( $counters['ctrl'] + $counters['high'] ) * 16 )
-               {
+                       < ( $counters['ctrl'] + $counters['high'] ) * 16
+               {
                        $kindOfBinary = true;
                        $type = $binaryType ? $binaryType : $textType;
                        if ( $type === false ) {
@@ -599,13 +599,13 @@ class IEContentAnalyzer {
 
                if ( $chunk2 == 'BM'
                        && substr( $chunk, 6, 2 ) == "\000\000"
-                       && substr( $chunk, 8, 2 ) == "\000\000" )
-               {
+                       && substr( $chunk, 8, 2 ) == "\000\000"
+               {
                        return 'image/bmp'; // another non-standard MIME
                }
                if ( $chunk4 == 'RIFF'
-                       && substr( $chunk, 8, 4 ) == 'WAVE' )
-               {
+                       && substr( $chunk, 8, 4 ) == 'WAVE'
+               {
                        return 'audio/wav';
                }
                // These were integer literals in IE
@@ -613,8 +613,8 @@ class IEContentAnalyzer {
                if ( $chunk4 == ".sd\000"
                        || $chunk4 == ".snd"
                        || $chunk4 == "\000ds."
-                       || $chunk4 == "dns." )
-               {
+                       || $chunk4 == "dns."
+               {
                        return 'audio/basic';
                }
                if ( $chunk3 == "MM\000" ) {
@@ -648,8 +648,8 @@ class IEContentAnalyzer {
                        return 'video/mpeg';
                }
                if ( $chunk4 == "\001\000\000\000"
-                       && substr( $chunk, 40, 4 ) == ' EMF' )
-               {
+                       && substr( $chunk, 40, 4 ) == ' EMF'
+               {
                        return 'image/x-emf';
                }
                if ( $chunk4 == "\xd7\xcd\xc6\x9a" ) {
@@ -789,8 +789,8 @@ class IEContentAnalyzer {
                        if ( !strncasecmp( $remainder, $rdfUrl, strlen( $rdfUrl ) ) ) {
                                $found['rdf-url'] = true;
                                if ( isset( $found['rdf-tag'] )
-                                       && isset( $found['rdf-purl'] ) // [sic]
-                               {
+                                       && isset( $found['rdf-purl'] ) // [sic]
+                               {
                                        break;
                                }
                                continue;
@@ -798,8 +798,8 @@ class IEContentAnalyzer {
 
                        if ( !strncasecmp( $remainder, $rdfPurl, strlen( $rdfPurl ) ) ) {
                                if ( isset( $found['rdf-tag'] )
-                                       && isset( $found['rdf-url'] ) // [sic]
-                               {
+                                       && isset( $found['rdf-url'] ) // [sic]
+                               {
                                        break;
                                }
                                continue;
index 6ea3c21..d03bc48 100644 (file)
@@ -735,8 +735,8 @@ EOT;
                        ( strpos( $head, "<\x00?\x00 " ) !== false ) ||
                        ( strpos( $head, "<\x00?\x00\n" ) !== false ) ||
                        ( strpos( $head, "<\x00?\x00\t" ) !== false ) ||
-                       ( strpos( $head, "<\x00?\x00=" ) !== false ) ) {
-
+                       ( strpos( $head, "<\x00?\x00=" ) !== false )
+               ) {
                        $this->logger->info( __METHOD__ . ": recognized $file as application/x-php\n" );
                        return 'application/x-php';
                }
@@ -1035,7 +1035,6 @@ EOT;
                // Special code for ogg - detect if it's video (theora),
                // else label it as sound.
                if ( $mime == 'application/ogg' && file_exists( $path ) ) {
-
                        // Read a chunk of the file
                        $f = fopen( $path, "rt" );
                        if ( !$f ) {
index 6481c92..c15572c 100644 (file)
@@ -8,7 +8,7 @@ use InvalidArgumentException;
  * Helper class to handle automatically marking connections as reusable (via RAII pattern)
  * as well handling deferring the actual network connection until the handle is used
  *
- * @note: proxy methods are defined explicity to avoid interface errors
+ * @note: proxy methods are defined explicitly to avoid interface errors
  * @ingroup Database
  * @since 1.22
  */
index 88a883a..3bb7e6a 100644 (file)
@@ -833,9 +833,10 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                        $sql,
                        $matches
                ) ) {
+                       $isTemp = isset( $this->mSessionTempTables[$matches[1]] );
                        unset( $this->mSessionTempTables[$matches[1]] );
 
-                       return true;
+                       return $isTemp;
                } elseif ( preg_match(
                        '/^(?:INSERT\s+(?:\w+\s+)?INTO|UPDATE|DELETE\s+FROM)\s+[`"\']?(\w+)[`"\']?/i',
                        $sql,
index 613dac5..8bbf9e5 100644 (file)
@@ -28,14 +28,12 @@ class LoadMonitorNull implements ILoadMonitor {
        public function __construct(
                ILoadBalancer $lb, BagOStuff $sCache, BagOStuff $cCache, array $options = []
        ) {
-
        }
 
        public function setLogger( LoggerInterface $logger ) {
        }
 
        public function scaleLoads( array &$loads, $domain ) {
-
        }
 
        public function getLagTimes( array $serverIndexes, $domain ) {
@@ -43,6 +41,5 @@ class LoadMonitorNull implements ILoadMonitor {
        }
 
        public function clearCaches() {
-
        }
 }
index dd1976c..a8af714 100644 (file)
@@ -69,7 +69,7 @@ class SamplingStatsdClient extends StatsdClient {
                return $data;
        }
 
-       /*
+       /**
         * Send the metrics over UDP
         * Sample the metrics according to their sample rate and send the remaining ones.
         *
index f1df7f1..9d886bf 100644 (file)
@@ -272,7 +272,6 @@ class XMPReader implements LoggerAwareInterface {
                if ( isset( $data['xmp-exif']['GPSAltitudeRef'] )
                        && isset( $data['xmp-exif']['GPSAltitude'] )
                ) {
-
                        // Must convert to a real before multiplying by -1
                        // XMPValidate guarantees there will always be a '/' in this value.
                        list( $nom, $denom ) = explode( '/', $data['xmp-exif']['GPSAltitude'] );
@@ -1004,7 +1003,6 @@ class XMPReader implements LoggerAwareInterface {
         */
        private function startElementModeInitial( $ns, $tag, $attribs ) {
                if ( $ns !== self::NS_RDF ) {
-
                        if ( isset( $this->items[$ns][$tag] ) ) {
                                if ( isset( $this->items[$ns][$tag]['structPart'] ) ) {
                                        // If this element is supposed to appear only as
@@ -1066,7 +1064,6 @@ class XMPReader implements LoggerAwareInterface {
         */
        private function startElementModeStruct( $ns, $tag, $attribs ) {
                if ( $ns !== self::NS_RDF ) {
-
                        if ( isset( $this->items[$ns][$tag] ) ) {
                                if ( isset( $this->items[$ns][$this->ancestorStruct]['children'] )
                                        && !isset( $this->items[$ns][$this->ancestorStruct]['children'][$tag] )
index ee0ff22..3c767f5 100644 (file)
@@ -653,7 +653,17 @@ class Article implements Page {
                $this->showViewFooter();
                $this->mPage->doViewUpdates( $user, $oldid );
 
-               $outputPage->addModules( 'mediawiki.action.view.postEdit' );
+               # Load the postEdit module if the user just saved this revision
+               # See also EditPage::setPostEditCookie
+               $request = $this->getContext()->getRequest();
+               $cookieKey = EditPage::POST_EDIT_COOKIE_KEY_PREFIX . $this->getRevIdFetched();
+               $postEdit = $request->getCookie( $cookieKey );
+               if ( $postEdit ) {
+                       # Clear the cookie. This also prevents caching of the response.
+                       $request->response()->clearCookie( $cookieKey );
+                       $outputPage->addJsConfigVars( 'wgPostEdit', $postEdit );
+                       $outputPage->addModules( 'mediawiki.action.view.postEdit' );
+               }
        }
 
        /**
index 5b1e86d..ecee0e2 100644 (file)
@@ -589,6 +589,14 @@ class Parser {
                                        $this->mTitle->getPrefixedDBkey() );
                        }
                }
+
+               # Wrap non-interface parser output in a <div> so it can be targeted
+               # with CSS (T37247)
+               $class = $this->mOptions->getWrapOutputClass();
+               if ( $class !== false && !$this->mOptions->getInterfaceMessage() ) {
+                       $text = Html::rawElement( 'div', [ 'class' => $class ], $text );
+               }
+
                $this->mOutput->setText( $text );
 
                $this->mRevisionId = $oldRevisionId;
index d0b66f8..353825a 100644 (file)
@@ -24,8 +24,7 @@
 /**
  * @ingroup Parser
  */
-class ParserDiffTest
-{
+class ParserDiffTest {
        public $parsers;
        public $conf;
        public $shortOutput = false;
index 2cdd8c7..d4d1042 100644 (file)
@@ -258,6 +258,12 @@ class ParserOptions {
         */
        private $allowUnsafeRawHtml = true;
 
+       /**
+        * CSS class to use to wrap output from Parser::parse().
+        * @var string|false
+        */
+       private $wrapOutputClass = 'mw-parser-output';
+
        public function getInterwikiMagic() {
                return $this->mInterwikiMagic;
        }
@@ -481,6 +487,15 @@ class ParserOptions {
                return $this->allowUnsafeRawHtml;
        }
 
+       /**
+        * Class to use to wrap output from Parser::parse()
+        * @since 1.30
+        * @return string|bool
+        */
+       public function getWrapOutputClass() {
+               return $this->wrapOutputClass;
+       }
+
        public function setInterwikiMagic( $x ) {
                return wfSetVar( $this->mInterwikiMagic, $x );
        }
@@ -629,6 +644,19 @@ class ParserOptions {
                return wfSetVar( $this->allowUnsafeRawHtml, $x );
        }
 
+       /**
+        * CSS class to use to wrap output from Parser::parse()
+        * @since 1.30
+        * @param string|bool $className Set false to disable wrapping.
+        * @return string|bool Current value
+        */
+       public function setWrapOutputClass( $className ) {
+               if ( $className === true ) { // DWIM, they probably want the default class name
+                       $className = 'mw-parser-output';
+               }
+               return wfSetVar( $this->wrapOutputClass, $className );
+       }
+
        /**
         * Set the redirect target.
         *
index 6bb4e5a..4473bb2 100644 (file)
@@ -455,8 +455,8 @@ abstract class SearchEngine {
                        $title = Title::newFromText( $search . 'Dummy' );
                        if ( $title && $title->getText() == 'Dummy'
                                        && $title->getNamespace() != NS_MAIN
-                                       && !$title->isExternal() )
-                       {
+                                       && !$title->isExternal()
+                       {
                                $ns = [ $title->getNamespace() ];
                                $search = '';
                        } else {
index bad0ef9..633cfc9 100644 (file)
@@ -303,7 +303,7 @@ class ServiceContainer implements DestructibleService {
 
                $instance = $this->peekService( $name );
 
-               if ( $destroy && $instance instanceof DestructibleService )  {
+               if ( $destroy && $instance instanceof DestructibleService ) {
                        $instance->destroy();
                }
 
index 4d02ddc..6e3971f 100644 (file)
@@ -960,7 +960,90 @@ abstract class ChangesListSpecialPage extends SpecialPage {
         * @param FormOptions $opts
         */
        public function validateOptions( FormOptions $opts ) {
-               // nothing by default
+               if ( $this->fixContradictoryOptions( $opts ) ) {
+                       $query = wfArrayToCgi( $this->convertParamsForLink( $opts->getChangedValues() ) );
+                       $this->getOutput()->redirect( $this->getPageTitle()->getCanonicalURL( $query ) );
+               }
+       }
+
+       /**
+        * Fix invalid options by resetting pairs that should never appear together.
+        *
+        * @param FormOptions $opts
+        * @return bool True if any option was reset
+        */
+       private function fixContradictoryOptions( FormOptions $opts ) {
+               $fixed = $this->fixBackwardsCompatibilityOptions( $opts );
+
+               foreach ( $this->filterGroups as $filterGroup ) {
+                       if ( $filterGroup instanceof ChangesListBooleanFilterGroup ) {
+                               $filters = $filterGroup->getFilters();
+
+                               if ( count( $filters ) === 1 ) {
+                                       // legacy boolean filters should not be considered
+                                       continue;
+                               }
+
+                               $allInGroupEnabled = array_reduce(
+                                       $filters,
+                                       function ( $carry, $filter ) use ( $opts ) {
+                                               return $carry && $opts[ $filter->getName() ];
+                                       },
+                                       /* initialValue */ count( $filters ) > 0
+                               );
+
+                               if ( $allInGroupEnabled ) {
+                                       foreach ( $filters as $filter ) {
+                                               $opts[ $filter->getName() ] = false;
+                                       }
+
+                                       $fixed = true;
+                               }
+                       }
+               }
+
+               return $fixed;
+       }
+
+       /**
+        * Fix a special case (hideanons=1 and hideliu=1) in a special way, for backwards
+        * compatibility.
+        *
+        * This is deprecated and may be removed.
+        *
+        * @param FormOptions $opts
+        * @return bool True if this change was mode
+        */
+       private function fixBackwardsCompatibilityOptions( FormOptions $opts ) {
+               if ( $opts['hideanons'] && $opts['hideliu'] ) {
+                       $opts->reset( 'hideanons' );
+                       if ( !$opts['hidebots'] ) {
+                               $opts->reset( 'hideliu' );
+                               $opts['hidehumans'] = 1;
+                       }
+
+                       return true;
+               }
+
+               return false;
+       }
+
+       /**
+        * Convert parameters values from true/false to 1/0
+        * so they are not omitted by wfArrayToCgi()
+        * Bug 36524
+        *
+        * @param array $params
+        * @return array
+        */
+       protected function convertParamsForLink( $params ) {
+               foreach ( $params as &$value ) {
+                       if ( $value === false ) {
+                               $value = '0';
+                       }
+               }
+               unset( $value );
+               return $params;
        }
 
        /**
@@ -999,7 +1082,7 @@ abstract class ChangesListSpecialPage extends SpecialPage {
 
                // Namespace filtering
                if ( $opts[ 'namespace' ] !== '' ) {
-                       $namespaces = explode( ',', $opts[ 'namespace' ] );
+                       $namespaces = explode( ';', $opts[ 'namespace' ] );
 
                        if ( $opts[ 'associated' ] ) {
                                $associatedNamespaces = array_map(
@@ -1049,15 +1132,6 @@ abstract class ChangesListSpecialPage extends SpecialPage {
                        ''
                );
 
-               // It makes no sense to hide both anons and logged-in users. When this occurs, try a guess on
-               // what the user meant and either show only bots or force anons to be shown.
-
-               // -------
-
-               // XXX: We're no longer doing this handling.  To preserve back-compat, we need to complete
-               // T151873 (particularly the hideanons/hideliu/hidebots/hidehumans part) in conjunction
-               // with merging this.
-
                if ( !$this->runMainQueryHook( $tables, $fields, $conds, $query_options, $join_conds,
                        $opts )
                ) {
index a47d91b..5553218 100644 (file)
@@ -167,7 +167,7 @@ class SpecialRecentChanges extends ChangesListSpecialPage {
                        $jsData = $this->getStructuredFilterJsData();
 
                        $messages = [];
-                       foreach ( $jsData['messageKeys'] as $key ){
+                       foreach ( $jsData['messageKeys'] as $key ) {
                                $messages[$key] = $this->msg( $key )->plain();
                        }
 
@@ -291,7 +291,7 @@ class SpecialRecentChanges extends ChangesListSpecialPage {
                        if ( preg_match( '/^days=(\d+)$/', $bit, $m ) ) {
                                $opts['days'] = $m[1];
                        }
-                       if ( preg_match( '/^namespace=(\d+)$/', $bit, $m ) ) {
+                       if ( preg_match( '/^namespace=(.*)$/', $bit, $m ) ) {
                                $opts['namespace'] = $m[1];
                        }
                        if ( preg_match( '/^tagfilter=(.*)$/', $bit, $m ) ) {
@@ -619,7 +619,11 @@ class SpecialRecentChanges extends ChangesListSpecialPage {
                if ( !$message->isDisabled() ) {
                        $this->getOutput()->addWikiText(
                                Html::rawElement( 'div',
-                                       [ 'lang' => $wgContLang->getHtmlCode(), 'dir' => $wgContLang->getDir() ],
+                                       [
+                                               'class' => 'mw-recentchanges-toplinks',
+                                               'lang' => $wgContLang->getHtmlCode(),
+                                               'dir' => $wgContLang->getDir()
+                                       ],
                                        "\n" . $message->plain() . "\n"
                                ),
                                /* $lineStart */ true,
@@ -814,16 +818,7 @@ class SpecialRecentChanges extends ChangesListSpecialPage {
         * @return string
         */
        function makeOptionsLink( $title, $override, $options, $active = false ) {
-               $params = $override + $options;
-
-               // T38524: false values have be converted to "0" otherwise
-               // wfArrayToCgi() will omit it them.
-               foreach ( $params as &$value ) {
-                       if ( $value === false ) {
-                               $value = '0';
-                       }
-               }
-               unset( $value );
+               $params = $this->convertParamsForLink( $override + $options );
 
                if ( $active ) {
                        $title = new HtmlArmor( '<strong>' . htmlspecialchars( $title ) . '</strong>' );
index 3a93107..ceb6b7b 100644 (file)
@@ -352,12 +352,16 @@ class SpecialSearch extends SpecialPage {
                        $out->addHTML( $dymWidget->render( $term, $textMatches ) );
                }
 
-               $out->addHTML( "<div class='searchresults'>" );
-
                $hasErrors = $textStatus && $textStatus->getErrors();
                $hasOtherResults = $textMatches &&
                        $textMatches->hasInterwikiResults( SearchResultSet::INLINE_RESULTS );
 
+               if ( $textMatches->hasInterwikiResults( SearchResultSet::SECONDARY_RESULTS ) ) {
+                       $out->addHTML( '<div class="searchresults mw-searchresults-has-iw">' );
+               } else {
+                       $out->addHTML( '<div class="searchresults">' );
+               }
+
                if ( $hasErrors ) {
                        list( $error, $warning ) = $textStatus->splitByErrorType();
                        if ( $error->getErrors() ) {
index 127b530..002b47c 100644 (file)
@@ -215,7 +215,7 @@ class UserrightsPage extends SpecialPage {
         * @return bool
         */
        public function canProcessExpiries() {
-               return !$this->getConfig()->get( 'DisableUserGroupExpiry' );
+               return true;
        }
 
        /**
index 0d6f493..e2f4d4b 100644 (file)
@@ -101,9 +101,7 @@ class ActiveUsersPager extends UsersPager {
                        $tables[] = 'user_groups';
                        $conds[] = 'ug_user = user_id';
                        $conds['ug_group'] = $this->groups;
-                       if ( !$this->getConfig()->get( 'DisableUserGroupExpiry' ) ) {
-                               $conds[] = 'ug_expiry IS NULL OR ug_expiry >= ' . $dbr->addQuotes( $dbr->timestamp() );
-                       }
+                       $conds[] = 'ug_expiry IS NULL OR ug_expiry >= ' . $dbr->addQuotes( $dbr->timestamp() );
                }
                if ( $this->excludegroups !== [] ) {
                        foreach ( $this->excludegroups as $group ) {
@@ -111,9 +109,7 @@ class ActiveUsersPager extends UsersPager {
                                        'user_groups', '1', [
                                                'ug_user = user_id',
                                                'ug_group' => $group,
-                                               $this->getConfig()->get( 'DisableUserGroupExpiry' ) ?
-                                                       '1' :
-                                                       'ug_expiry IS NULL OR ug_expiry >= ' . $dbr->addQuotes( $dbr->timestamp() )
+                                               'ug_expiry IS NULL OR ug_expiry >= ' . $dbr->addQuotes( $dbr->timestamp() )
                                        ]
                                ) . ')';
                        }
index 1133625..7d303de 100644 (file)
@@ -228,10 +228,8 @@ class ContribsPager extends ReverseChronologicalPager {
                                        'LEFT JOIN', [
                                                'ug_user = rev_user',
                                                'ug_group' => $groupsWithBotPermission,
-                                               $this->getConfig()->get( 'DisableUserGroupExpiry' ) ?
-                                                       '1' :
-                                                       'ug_expiry IS NULL OR ug_expiry >= ' .
-                                                               $this->mDb->addQuotes( $this->mDb->timestamp() )
+                                               'ug_expiry IS NULL OR ug_expiry >= ' .
+                                                       $this->mDb->addQuotes( $this->mDb->timestamp() )
                                        ]
                                ];
                        }
index b781930..e2d9d42 100644 (file)
@@ -77,9 +77,7 @@ class NewFilesPager extends ReverseChronologicalPager {
                                        [
                                                'ug_group' => $groupsWithBotPermission,
                                                'ug_user = img_user',
-                                               $this->getConfig()->get( 'DisableUserGroupExpiry' ) ?
-                                                       '1' :
-                                                       'ug_expiry IS NULL OR ug_expiry >= ' . $dbr->addQuotes( $dbr->timestamp() )
+                                               'ug_expiry IS NULL OR ug_expiry >= ' . $dbr->addQuotes( $dbr->timestamp() )
                                        ]
                                ];
                        }
index d599599..9aef9ad 100644 (file)
@@ -112,9 +112,7 @@ class UsersPager extends AlphabeticPager {
 
                if ( $this->requestedGroup != '' ) {
                        $conds['ug_group'] = $this->requestedGroup;
-                       if ( !$this->getConfig()->get( 'DisableUserGroupExpiry' ) ) {
-                               $conds[] = 'ug_expiry IS NULL OR ug_expiry >= ' . $dbr->addQuotes( $dbr->timestamp() );
-                       }
+                       $conds[] = 'ug_expiry IS NULL OR ug_expiry >= ' . $dbr->addQuotes( $dbr->timestamp() );
                }
 
                if ( $this->requestedUser != '' ) {
index bb1e751..5dd4be1 100644 (file)
@@ -522,7 +522,6 @@ class User implements IDBAccessObject {
                                }
 
                                return $data;
-
                        },
                        [ 'pcTTL' => $cache::TTL_PROC_LONG, 'version' => self::VERSION ]
                );
index 81a4083..cf05df3 100644 (file)
@@ -49,11 +49,6 @@ class UserGroupMembership {
         * @param string|null $expiry Timestamp of expiry in TS_MW format, or null if no expiry
         */
        public function __construct( $userId = 0, $group = null, $expiry = null ) {
-               global $wgDisableUserGroupExpiry;
-               if ( $wgDisableUserGroupExpiry ) {
-                       $expiry = null;
-               }
-
                $this->userId = (int)$userId;
                $this->group = $group; // TODO throw on invalid group?
                $this->expiry = $expiry ?: null;
@@ -77,26 +72,15 @@ class UserGroupMembership {
         * @return string|null Timestamp of expiry in TS_MW format, or null if no expiry
         */
        public function getExpiry() {
-               global $wgDisableUserGroupExpiry;
-               if ( $wgDisableUserGroupExpiry ) {
-                       return null;
-               }
-
                return $this->expiry;
        }
 
        protected function initFromRow( $row ) {
-               global $wgDisableUserGroupExpiry;
-
                $this->userId = (int)$row->ug_user;
                $this->group = $row->ug_group;
-               if ( $wgDisableUserGroupExpiry ) {
-                       $this->expiry = null;
-               } else {
-                       $this->expiry = $row->ug_expiry === null ?
-                               null :
-                               wfTimestamp( TS_MW, $row->ug_expiry );
-               }
+               $this->expiry = $row->ug_expiry === null ?
+                       null :
+                       wfTimestamp( TS_MW, $row->ug_expiry );
        }
 
        /**
@@ -117,19 +101,11 @@ class UserGroupMembership {
         * @return array
         */
        public static function selectFields() {
-               global $wgDisableUserGroupExpiry;
-               if ( $wgDisableUserGroupExpiry ) {
-                       return [
-                               'ug_user',
-                               'ug_group',
-                       ];
-               } else {
-                       return [
-                               'ug_user',
-                               'ug_group',
-                               'ug_expiry',
-                       ];
-               }
+               return [
+                       'ug_user',
+                       'ug_group',
+                       'ug_expiry',
+               ];
        }
 
        /**
@@ -140,7 +116,6 @@ class UserGroupMembership {
         * @return bool Whether or not anything was deleted
         */
        public function delete( IDatabase $dbw = null ) {
-               global $wgDisableUserGroupExpiry;
                if ( wfReadOnly() ) {
                        return false;
                }
@@ -149,14 +124,10 @@ class UserGroupMembership {
                        $dbw = wfGetDB( DB_MASTER );
                }
 
-               if ( $wgDisableUserGroupExpiry ) {
-                       $dbw->delete( 'user_groups', $this->getDatabaseArray( $dbw ), __METHOD__ );
-               } else {
-                       $dbw->delete(
-                               'user_groups',
-                               [ 'ug_user' => $this->userId, 'ug_group' => $this->group ],
-                               __METHOD__ );
-               }
+               $dbw->delete(
+                       'user_groups',
+                       [ 'ug_user' => $this->userId, 'ug_group' => $this->group ],
+                       __METHOD__ );
                if ( !$dbw->affectedRows() ) {
                        return false;
                }
@@ -182,7 +153,6 @@ class UserGroupMembership {
         * @return bool Whether or not anything was inserted
         */
        public function insert( $allowUpdate = false, IDatabase $dbw = null ) {
-               global $wgDisableUserGroupExpiry;
                if ( $dbw === null ) {
                        $dbw = wfGetDB( DB_MASTER );
                }
@@ -206,7 +176,7 @@ class UserGroupMembership {
 
                // Don't collide with expired user group memberships
                // Do this after trying to insert, in order to avoid locking
-               if ( !$wgDisableUserGroupExpiry && !$affected ) {
+               if ( !$affected ) {
                        $conds = [
                                'ug_user' => $row['ug_user'],
                                'ug_group' => $row['ug_group'],
@@ -245,16 +215,11 @@ class UserGroupMembership {
         * @return array
         */
        protected function getDatabaseArray( IDatabase $db ) {
-               global $wgDisableUserGroupExpiry;
-
-               $a = [
+               return [
                        'ug_user' => $this->userId,
                        'ug_group' => $this->group,
+                       'ug_expiry' => $this->expiry ? $db->timestamp( $this->expiry ) : null,
                ];
-               if ( !$wgDisableUserGroupExpiry ) {
-                       $a['ug_expiry'] = $this->expiry ? $db->timestamp( $this->expiry ) : null;
-               }
-               return $a;
        }
 
        /**
@@ -262,8 +227,7 @@ class UserGroupMembership {
         * @return bool
         */
        public function isExpired() {
-               global $wgDisableUserGroupExpiry;
-               if ( $wgDisableUserGroupExpiry || !$this->expiry ) {
+               if ( !$this->expiry ) {
                        return false;
                } else {
                        return wfTimestampNow() > $this->expiry;
@@ -276,8 +240,7 @@ class UserGroupMembership {
         * @param IDatabase|null $dbw
         */
        public static function purgeExpired( IDatabase $dbw = null ) {
-               global $wgDisableUserGroupExpiry;
-               if ( $wgDisableUserGroupExpiry || wfReadOnly() ) {
+               if ( wfReadOnly() ) {
                        return;
                }
 
index 1dac0b1..54a8677 100644 (file)
@@ -212,7 +212,6 @@ global \${$this->variableName};
 ];
 
 EOD;
-
        }
 
        /**
index e107fb1..cab6a3d 100644 (file)
@@ -87,9 +87,9 @@ class BatchRowIterator implements RecursiveIterator {
 
        /**
         * @param IDatabase $db The database to read from
-        * @param string|array $table      The name or names of the table to read from
+        * @param string|array $table The name or names of the table to read from
         * @param string|array $primaryKey The name or names of the primary key columns
-        * @param integer      $batchSize  The number of rows to fetch per iteration
+        * @param integer $batchSize The number of rows to fetch per iteration
         * @throws InvalidArgumentException
         */
        public function __construct( IDatabase $db, $table, $primaryKey, $batchSize ) {
index 1911c79..3cdda02 100644 (file)
@@ -8,6 +8,7 @@ use SearchResultSet;
 use SpecialSearch;
 use Title;
 use Html;
+use OOUI;
 
 /**
  * Renders one or more SearchResultSets into a sidebar grouped by
@@ -27,8 +28,6 @@ class InterwikiSearchResultSetWidget implements SearchResultSetWidget {
        protected $iwLookup;
        /** @var $output */
        protected $output;
-       /** @var $iwPrefixDisplayTypes */
-       protected $iwPrefixDisplayTypes;
 
        public function __construct(
                SpecialSearch $specialSearch,
@@ -41,9 +40,6 @@ class InterwikiSearchResultSetWidget implements SearchResultSetWidget {
                $this->linkRenderer = $linkRenderer;
                $this->iwLookup = $iwLookup;
                $this->output = $specialSearch->getOutput();
-               $this->iwPrefixDisplayTypes = $specialSearch->getConfig()->get(
-                       'InterwikiPrefixDisplayTypes'
-               );
        }
        /**
         * @param string $term User provided search term
@@ -80,22 +76,17 @@ class InterwikiSearchResultSetWidget implements SearchResultSetWidget {
                        $position = 0;
                        $iwResultItemOutput = '';
 
-                       $iwDisplayType = isset( $this->iwPrefixDisplayTypes[$iwPrefix] )
-                               ? $this->iwPrefixDisplayTypes[$iwPrefix]
-                               : "";
-
                        foreach ( $results as $result ) {
                                $iwResultItemOutput .= $this->resultWidget->render( $result, $term, $position++ );
                        }
 
-                       $headerHtml = $this->headerHtml( $term, $iwPrefix );
                        $footerHtml = $this->footerHtml( $term, $iwPrefix );
                        $iwResultListOutput .= Html::rawElement( 'li',
                                [
-                                       'class' => 'iw-resultset iw-resultset--' . $iwDisplayType,
+                                       'class' => 'iw-resultset',
                                        'data-iw-resultset-pos' => $iwResultSetPos
                                ],
-                               $headerHtml .
+
                                $iwResultItemOutput .
                                $footerHtml
                        );
@@ -117,34 +108,6 @@ class InterwikiSearchResultSetWidget implements SearchResultSetWidget {
                );
        }
 
-       /**
-        * Generates an appropriate HTML header for the given interwiki prefix
-        *
-        * @param string $term User provided search term
-        * @param string $iwPrefix Interwiki prefix of wiki to show header for
-        * @return string HTML
-        */
-       protected function headerHtml( $term, $iwPrefix ) {
-
-               $iwDisplayType = isset( $this->iwPrefixDisplayTypes[$iwPrefix] )
-                       ? $this->iwPrefixDisplayTypes[$iwPrefix]
-                       : "";
-
-               if ( isset( $this->customCaptions[$iwPrefix] ) ) {
-                       /* customCaptions composed by loadCustomCaptions() with pre-escaped content. */
-                       $caption = $this->customCaptions[$iwPrefix];
-               } else {
-                       $interwiki = $this->iwLookup->fetch( $iwPrefix );
-                       $parsed = wfParseUrl( wfExpandUrl( $interwiki ? $interwiki->getURL() : '/' ) );
-                       $caption = $this->specialSearch->msg( 'search-interwiki-default', $parsed['host'] )->escaped();
-               }
-
-               return Html::rawElement( 'div', [ 'class' => 'iw-result__header' ],
-                       Html::rawElement( 'span', [ 'class' => 'iw-result__icon iw-result__icon--' . $iwDisplayType ] )
-                       . $caption
-               );
-       }
-
        /**
         * Generates an HTML footer for the given interwiki prefix
         *
@@ -158,13 +121,22 @@ class InterwikiSearchResultSetWidget implements SearchResultSetWidget {
                        [ 'search' => $term, 'fulltext' => 1 ]
                );
 
-               $searchLink = Html::rawElement(
-                       'a',
-                       [ 'href' => $href ],
-                       $this->specialSearch->msg( 'search-interwiki-more-results' )->escaped()
+               $interwiki = $this->iwLookup->fetch( $iwPrefix );
+               $parsed = wfParseUrl( wfExpandUrl( $interwiki ? $interwiki->getURL() : '/' ) );
+
+               if ( isset( $this->customCaptions[$iwPrefix] ) ) {
+                       $caption = $this->customCaptions[$iwPrefix];
+               } else {
+                       $caption = $this->specialSearch->msg( 'search-interwiki-default', $parsed['host'] )->escaped();
+               }
+
+               $searchLink = Html::rawElement( 'em', null,
+                       Html::rawElement( 'a', [ 'href' => $href, 'target' => '_blank' ], $caption )
                );
 
-               return Html::rawElement( 'div', [ 'class' => 'iw-result__footer' ], $searchLink );
+               return Html::rawElement( 'div',
+                       [ 'class' => 'iw-result__footer' ],
+                       $this->iwIcon( $iwPrefix ) . $searchLink );
        }
 
        protected function loadCustomCaptions() {
@@ -181,4 +153,33 @@ class InterwikiSearchResultSetWidget implements SearchResultSetWidget {
                        }
                }
        }
+
+       /**
+        * Generates a custom OOUI icon element with a favicon as the image.
+        * The favicon image URL is generated by parsing the interwiki URL
+        * and returning the default location of the favicon for that domain,
+        * which is assumed to be '/favicon.ico'.
+        *
+        * @param string $iwPrefix Interwiki prefix
+        * @return OOUI\IconWidget
+        **/
+       protected function iwIcon( $iwPrefix ) {
+
+               $interwiki = $this->iwLookup->fetch( $iwPrefix );
+               $parsed = wfParseUrl( wfExpandUrl( $interwiki ? $interwiki->getURL() : '/' ) );
+
+               $iwIconUrl = $parsed['scheme'] .
+                       $parsed['delimiter'] .
+                       $parsed['host'] .
+                       ( $parsed['port'] ? ':' . $parsed['port'] : '' ) .
+                       '/favicon.ico';
+
+               $iwIcon = new OOUI\IconWidget( [
+                       'icon' => 'favicon'
+                ] );
+
+                $iwIcon->setAttributes( [ 'style' => "background-image:url($iwIconUrl);" ] );
+
+               return $iwIcon;
+       }
 }
index 6b51db5..acd792d 100644 (file)
@@ -17,13 +17,10 @@ class InterwikiSearchResultWidget implements SearchResultWidget {
        protected $specialSearch;
        /** @var LinkRenderer */
        protected $linkRenderer;
-       /** @var $iwPrefixDisplayTypes */
-       protected $iwPrefixDisplayTypes;
 
        public function __construct( SpecialSearch $specialSearch, LinkRenderer $linkRenderer ) {
                $this->specialSearch = $specialSearch;
                $this->linkRenderer = $linkRenderer;
-               $this->iwPrefixDisplayTypes = $specialSearch->getConfig()->get( 'InterwikiPrefixDisplayTypes' );
        }
 
        /**
@@ -38,9 +35,6 @@ class InterwikiSearchResultWidget implements SearchResultWidget {
                $iwPrefix = $result->getTitle()->getInterwiki();
                $titleSnippet = $result->getTitleSnippet();
                $snippet = $result->getTextSnippet( $terms );
-               $displayType = isset( $this->iwPrefixDisplayTypes[$iwPrefix] )
-                       ? $this->iwPrefixDisplayTypes[$iwPrefix]
-                       : "";
 
                if ( $titleSnippet ) {
                        $titleSnippet = new HtmlArmor( $titleSnippet );
@@ -69,18 +63,7 @@ class InterwikiSearchResultWidget implements SearchResultWidget {
                        );
                }
 
-               switch ( $displayType ) {
-                       case 'definition':
-                               return "<div class='iw-result__content'>" .
-                                       "<span class='iw-result__title'>{$link} {$redirect}: </span>" .
-                                       $snippet .
-                               "</div>";
-                       case 'quotation':
-                               return "<div class='iw-result__content'>{$snippet}</div>" .
-                                       "<div class='iw-result__title'>{$link} {$redirect}</div>";
-                       default:
-                               return "<div class='iw-result__title'>{$link} {$redirect}</div>" .
-                                       "<div class='iw-result__content'>{$snippet}</div>";
-               }
+               return Html::rawElement( 'div', [ 'class' => 'iw-result__title' ], $link . ' ' . $redirect ) .
+                       Html::rawElement( 'div', [ 'class'=> 'iw-result__content' ], $snippet );
        }
 }
index 04e1e21..4df2eb5 100644 (file)
@@ -14,7 +14,7 @@ use Html;
  * interwiki prefix. Includes a per-wiki header indicating where
  * the results are from.
  */
-class SimpleSearchResultSetWidget implements SearchResultSetWidget{
+class SimpleSearchResultSetWidget implements SearchResultSetWidget {
        /** @var SpecialSearch */
        protected $specialSearch;
        /** @var SearchResultWidget */
index 6f2117c..0cddc99 100644 (file)
  */
 
 /**
- * A fake language converter
+ * A fake language variant converter. Languages which do not implement variant
+ * conversion, for example, English, should return a FakeConverter rather than a
+ * LanguageConverter when asked for their converter. The fake converter just
+ * returns text unchanged, i.e. it doesn't do any conversion.
+ *
+ * See https://www.mediawiki.org/wiki/Writing_systems#LanguageConverter.
  *
  * @ingroup Language
  */
index 4002e30..b82c5fc 100644 (file)
        "rcfilters-hideminor-conflicts-typeofchange-global": "مرشح \"التعديلات الطفيفة\" يتعارض مع مرشح واحد أو أكثر من مرشحات نوع التغيير، وذلك لأن بعض أنواع التغيير لا يمكن التعليم عليها ك\"طفيفة.\" المرشحات المتعارضة معلم عليها في مساحة المرشحات النشطة بالأعلى.",
        "rcfilters-hideminor-conflicts-typeofchange": "بعض أنواع التغييرات لا يمكن التعليم عليها ك\"طفيفة،\" لذا فهذا المرشح يتعارض مع مرشحات نوع التغيير التالية: $1",
        "rcfilters-typeofchange-conflicts-hideminor": "مرشح نوع التغيير هذا يتعارض مع مرشح \"التعديلات الطفيفة\". بعض أنواع التغييرات لا يمكن التعليم عليها ك\"طفيفة.\"",
+       "rcfilters-filter-lastrevision-description": "أخر تعديل للصفحة.",
+       "rcfilters-filter-previousrevision-label": "نسخ سابقة",
+       "rcfilters-filter-previousrevision-description": "كل تعديلات الصفحة ما عدا التعديل الأخير.",
        "rcnotefrom": "بالأسفل {{PLURAL:$5|التغيير|التغييرات}} منذ <strong>$2</strong> (إلى <strong>$1</strong> معروضة).",
        "rclistfromreset": "إعادة ضبط خيار التاريخ",
        "rclistfrom": "أظهر التغييرات بدء من $3 $2",
        "tooltip-t-recentchangeslinked": "أحدث التغييرات في الصفحات الموصولة من هذه الصفحة",
        "tooltip-feed-rss": "تلقيم أر إس إس لهذه الصفحة",
        "tooltip-feed-atom": "تلقيم أتوم لهذه الصفحة",
-       "tooltip-t-contributions": "رؤية قائمة مساهمات {{GENDER:$1|this user}}",
+       "tooltip-t-contributions": "رؤية قائمة مساهمات {{GENDER:$1|هذا المستخدم|هذه المستخدمة}}",
        "tooltip-t-emailuser": "أرسل رسالة {{GENDER:$1|لهذا المستخدم|لهذه المستخدمة}}",
        "tooltip-t-info": "المزيد من المعلومات عن هذه الصفحة",
        "tooltip-t-upload": "ارفع ملفات",
        "htmlform-user-not-valid": "اسم المستخدم <strong>$1</strong> غير صالح.",
        "logentry-delete-delete": "{{GENDER:$2|حذف|حذفت}} $1 صفحة $3",
        "logentry-delete-delete_redir": "$1 {{GENDER:$2|حذف|حذفت}} التحويلة $3 بواسطة إعادة الكتابة",
-       "logentry-delete-restore": "{{GENDER:$2|استرجع|استرجعت}} الصفحة $3 ($4)",
+       "logentry-delete-restore": "$1 {{GENDER:$2|استرجع|استرجعت}} الصفحة $3 ($4)",
        "logentry-delete-restore-nocount": "$1 {{GENDER:$2|استرجع|استرجعت}} الصفحة $3",
        "restore-count-revisions": "{{PLURAL:$1|1 مراجعة|$1 مراجعة}}",
        "restore-count-files": "{{PLURAL:$1|1 ملف|$1 ملف}}",
index 1c4b210..e10bd39 100644 (file)
        "anoneditwarning": "<strong>تحذير:'</strong> انت ما عملتش لوجين. عنوان الاى  بى  بتاعك هايتسجل ف تاريخ الصفحه. لو  <strong>[$1 عملت لوجين ]</strong> او <strong>[$2 فتحت حساب ]</strong>,   اليوزرنيم بتاعك هايتسجل ف تاريخ الصفحه.",
        "missingsummary": "'''خد بالك:''' انت ما كتبتش ملخص للتعديل.\nلو دوست على سييڤ الصفحه مرة تانية التعديل بتاعك ح يتحفظ من غير ملخص.",
        "missingcommenttext": "لو سمحت اكتب تعليق تحت.",
-       "missingcommentheader": "'''.خد بالك:''' انت ما كتبتش عنوان\\موضوع للتعليق دا\nلو دوست على $1 مرة تانيه، تعليقك ح يتحفظ من غير عنوان.",
+       "missingcommentheader": "<strong>خد بالك:</strong> انت ما كتبتش عنوان\\موضوع للتعليق دا\nلو دوست على $1 مرة تانيه، تعليقك ح يتحفظ من غير عنوان.",
        "summary-preview": "بروفه للملخص:",
        "subject-preview": "بروفة للعنوان/للموضوع",
        "blockedtitle": "اليوزر ممنوع",
index 7ec3a56..a8dd77c 100644 (file)
        "pagecategories": "{{PLURAL:$1|Ka ici arimotcikatek|Ka ici arimotcikateki}}",
        "category_header": "Masinahikana ka ici arimotcikateki \"$1\"",
        "subcategories": "Awocamec ke ici arimotcikateki",
+       "category-media-header": "Tipatcimoctakewin e ici actakaniwok$1",
        "hidden-categories": "{{PLURAL:$1|Ka katcictek|Ka katcicteki}}",
        "category-subcat-count": "Nohwe tipanictawin {{PLURAL:$2|0=nama takon e ki koski tipanictakaniwok|1=tepirak e ki koski tipanictakaniwok nta takon|takon $2 koski tipanictawina, nte {{PLURAL:$1|0=nama takon|1=nohwe|neki $1}}nta nitc}}.",
+       "category-article-count": "nohwe tipanictawin {{PLURAL:$2|0=nama takon paskickwemakan|1=Enkon nohwe tepirak paskickwemakan|takon $2 paskickwemakana,ohwe tca {{PLURAL:$1|0=nama takon|1=ohwi|nehi $1}} nihi nitc}}.",
+       "category-file-count": "Nohwe tipanictawin {{PLURAL:$2|0=nama takon mawtosinihikana|1= tec mawtosinihikan acotitin|acotitin $2 mawtosinihikana,  {{PLURAL:$1|0=nama takon|1=nohwe|nihi $1}} nta ka cekoctek}}.",
        "listingcontinuesabbrev": "minawatc",
        "about": "Taci we otciparik",
        "newwindow": "(cepita kotak ocki osapwakan)",
        "hidetoc": "Kata",
        "confirmable-yes": "Ehe",
        "confirmable-no": "Nama",
-       "site-atom-feed": "Flux Atom de $1",
+       "site-atom-feed": "Flux Atom $1",
        "page-atom-feed": "\"$1\" Atom feed",
        "red-link-title": "$1 (nama takon kekwcic)",
        "nstab-main": "Masinahikan",
        "createacct-yourpassword-ph": "Acta pitakesinihikan",
        "createacct-yourpasswordagain": "Naskamowicta pitakesinihikan",
        "createacct-yourpasswordagain-ph": "Minawatc acta pitakesinihikan",
+       "userlogin-remembermypassword": "Kitci cetik mekwact ka ici otamirohian",
        "login": "Posi",
        "logout": "Piskeapikenakan",
        "userlogout": "Piskeapikenakan",
        "createacct-email-ph": "Pitakesinaha ki pamikicikwepitcikan matcetcicihikan",
        "createacct-submit": "Masinahotiso",
        "createacct-benefit-heading": "{{SITENAME}} Iskwewok,iriniwok ka orisinihiketcik mitowi kir.",
+       "createacct-benefit-body1": "{{PLURAL:$1|ki meckotcitakiniwok|ki meckotcitakiniwoki}}",
        "createacct-benefit-body2": "{{PLURAL:$1|masinhikan|masinahikana}}",
+       "createacct-benefit-body3": "ocki {{PLURAL:$1|ka witcihietc|ka witcihietcik}}",
        "loginlanguagelabel": "arimwewin:$1",
        "pt-login": "Posi",
        "pt-login-button": "Posi",
        "extlink_sample": "http://www.example.com ka icinikatek takapikenikan",
        "extlink_tip": "Masinahikana ka ici tapitik kotakik masinahikanik",
        "headline_sample": "Atisokesinahikan ke aicinikatek",
+       "headline_tip": "Icinikatamowinicic 2 ka iteritakok",
        "nowiki_sample": "Acta atisokesinahikan aka moci ka ki otci nihipitcikatek ota",
        "nowiki_tip": "aka pamerita e itasinihak wiki",
        "image_tip": "E pitakesinahikatek masinahikaniwoc",
        "showdiff": "Kanawapata ka meckotcipitcikateki",
        "anoneditwarning": "<strong>Ekwa :</strong> nama kipitikeapikecinin. Nokon e tatosinatek kit irapitcikan ka pamikicikwakein kaskina wec ici nokon  kecpin e kweskisinihikein. Kecpin tca <strong>[$1wi pitikeapikecinine]</strong> ou <strong>[$2 ocita kata pitakesinasowin]</strong>,nohwe ka kweskisinihikein ki ka masinason e icinikatitisowin ,acit awacimec ki ka ici titamihikowin",
        "loginreqlink": "posi",
+       "newarticletext": "Ki nanosinehen ntowapikepatcikan aka  e takok nohwe paskickwemakan kiapatc.\nWi ocitaine nohwe paskickwemakan, nta ici masinaha pwetek kit atisokesinihikan minawatc\n (matci kika nta kanawapaten [$1 ka witciwemakak paskickwemakan] awacimec wi nanto kiskeritamone). \nKecpin ota ka pe icawone{{GENDER:||e}} e ki onipiriin, ohwe makona <strong>kiweckawin</strong> taci e ici pamikicikwepitcikein",
        "noarticletext": "Mekwatc nama takon atisokesinihikan nta paskickwemakanik.\nke ki totaman[[Special:Search/{{PAGENAME}}|nantowapaha ohwe icinikatamowin ]] kotakahikw paskickwemakanik,\n<span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|paskickwemakan={{FULLPAGENAMEE}}}} nantowapata ka ici  mikowapihikemikak]\nkekotc [{{fullurl:{{FULLPAGENAME}}|tota=orocowata}} ocita paskickwemakan]</span>.",
+       "noarticletext-nopermission": "Mekwatc nama takon atisokesinihikan nta paskickwemakanik.\nke ki totaman[[Special:Search/{{PAGENAME}}|nantowapaha ohwe icinikatamowin ]] kotakahikw paskickwemakanik,\n<span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|paskickwemakan={{FULLPAGENAMEE}}}} nantowapaha kotakihi wapatcikaniwoca ohwe ]</span>,nama aric ki mirikwin ohwe kata ocitain paskickwemakan.",
        "editing": "Meckotcita $1",
+       "creating": "$1 Wir tipirowe ka ki ocitatc",
+       "editingsection": "Ka ki meckotcitatc $1 (tipanitakiniwok)",
        "templatesused": "{{PLURAL:$1|tapapitcikan ka apatak |tapapitcikan ka apatak}} nta paskickwemakanik:",
        "template-protected": "(nakataweritcikatew)",
        "template-semiprotected": "(apita nakatoweritakon)",
+       "hiddencategories": "{{PLURAL:$1|tipanictawin katcitin|tipanictawina katcitano}} paskickwemakan tca nohwe nte ici actew :",
        "permissionserrorstext-withaction": "Nama ki ki toten $2 osam {{PLURAL:$1|}} nohwe ka witcikatek kekotc nihi ka wawitcikateki:",
        "moveddeleted-notice": "Paskickwemakan ka ki wepinikatek.\nOhwe wapatcikan nitc ici nokon paskickwemakanik ka ki wepinikateki acit ka ki atcipitcikateki.",
        "content-model-javascript": "JavaScript",
        "viewpagelogs": "Kinawapta kekwan kaki isparik ota masinhikanik",
+       "currentrev-asof": "Owe mekwatc ka icinakok ni apitc ka ocitakiniwokipan $1",
        "revisionasof": "Kiwe kanawapata $1",
        "revision-info": "E tato konekisitc ka koski kanawapatcikatek $1 nohwe {{GENDER:$6|$2}}$7",
        "previousrevision": "← Nictam ka ki masinatek",
        "revdelete-show-file-submit": "Ehe",
        "pagehist": "Ka ki pe icinakok owe masinhikan",
        "history-title": "Kotakihi e itatcitcikatekai $1",
+       "difference-title": "$1 E ci papitoc icinakok",
        "lineno": "E tatosinatek $1 :",
        "editundo": "nama ntwatc",
+       "diff-multi-sameuser": "({{PLURAL:$1|Nohwe ka ki koski kanawapatcikatek enkon nohwe peikon ka ki mockatcitatc nama aric nokon |$1 nohwe ka ki koski kanawapatcikateki enkon nohwe peikon ka mockatcitatc nama aric nokon }})",
        "searchresults": "Ka ki nta kiskeritakok",
        "searchresults-title": "Ka ki nta kiskeritakok \"$1\"",
        "prevn": "{{PLURAL:$1|nictamictew|nictamictewa $1}}",
        "nextn-title": "Minawa $1 {{PLURAL:$1|ke iti icinakok|ke iti icinakoki}}",
        "shown-title": "Akwaskoha $1 {{PLURAL:$1|ke iti icinakok|ke iti icinakoki}} tatwa e matce paskickwemikein",
        "viewprevnext": "Tapwatcike ($1 {{int:pipe-separator}} $2) ($3)",
+       "searchmenu-new": "<strong>Ocita paskickwemakan « [[:$1|$1]] »ohwe ota wiki !</strong> {{PLURAL:$2|0Kanawapata  kirika nohwe paskickwemakan ka ki nantowapahaman.|Kanawapata kirina kekwan ka ki miskowapahaman e nanto kiskeritaman .}}",
        "searchprofile-articles": "Masinahikana ka aicteki",
        "searchprofile-images": "Mitcetowina",
        "searchprofile-everything": "Kaskina",
        "search-section": "(ke arimotcikatek $1)",
        "search-suggest": "Ohwe kotcita e itasinatek:$1",
        "searchall": "kaskina",
+       "search-showingresults": "{{PLURAL:$4|E ici miskatek <strong>$1</strong> nta neki<strong>$3</strong>|E ici miskatek <strong>$1 à $2</strong>nta neki<strong>$3</strong>}}",
        "search-nonefound": "Nama miskwapahikatew ka nantowapahikatek.",
        "powersearch-legend": "Awocamec nantona",
        "powersearch-toggleall": "Kaskina",
        "recentchanges-label-unpatrolled": "Nama moci koski tapwatcikatew ka ki meckotcipirik",
        "recentchanges-label-plusminus": " Irikik e tacitcik bytes meckotcipirin e irikwak",
        "recentchanges-legend-heading": "<strong>itekesinihikan:</strong>",
+       "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (kirika kanawapata nohwe [[Special:NewPages|taci e ici masinihikatek ocki paskickwemakana]]).",
        "recentchanges-submit": "Wapata",
        "rclistfrom": "Nokota ka ki mameckotciparik nta e otci kitciparik $2$3",
        "rcshowhideminor": "$1 memantcic meckotcipirino",
        "recentchangeslinked-title": "E nosinehikatek paskickwemikana ka acotcictek\"$1\"",
        "recentchangeslinked-summary": " Enkon ohwe ka ki meckotcisinihikateki paskickwemikana  e ici natcipitcikatek nta paskickemakanik kekwan ka arimotcikatek mia kekotc ma neki ka mamowisinasotcik taci ka ki ici aritisotcik mia.\nPaskickwemikina [[Special:Watchlist|masinihikan ka nakatcitain]] nehi<strong>makatewasinikan</strong>",
        "recentchangeslinked-page": "Icinikatamowin Ickwemakinikan:",
+       "recentchangeslinked-to": "Kata nokok kaki kweskisinihikateki paskickwemikina ka acotcisinihikateki taci e ici ntowapekihikatek nohwe paskickwemakan patoc kweski e icinakok.",
        "upload": "Natcipata masinahikan",
        "filedesc": "Nosem",
        "fileuploadsummary": "Nosem:",
        "brokenredirects-delete": "wepina",
        "withoutinterwiki-submit": "Wapata",
        "nbytes": "$1 {{PLURAL:$1|irik}}",
+       "nmembers": "$1 {{PLURAL:$1|witciwetc|witciwetcik}}",
        "prefixindex-submit": "Wapata",
        "protectedpages-page": "Masinhikan",
        "newpages": "Ocki matcecikinakanik",
        "newpages-submit": "Wapata",
        "newpages-username": "Icinikasowin:",
+       "pager-older-n": "{{PLURAL:$1|1 mawtci weckat|$1 mawtci weckat}}",
        "booksources": "E otciparik",
        "booksources-search-legend": "Nantowapata nta kotakahi wapatcikana",
        "booksources-search": "Nanto kiskeritcikatek",
        "historyaction-submit": "Wapata",
        "dellogpage": " Nesitc ka wepinikatek kanaweritcikan",
        "rollbacklink": "e maninakatek",
+       "rollbacklinkcount": " nesitc wepina$1 {{PLURAL:$1|kweskisinikan|kweskisinihikana}}",
        "protectlogpage": "Nanakatisiwina wapatcikan",
        "restriction-edit": "Meckotcita",
        "undeleteviewlink": "tapwatcike",
        "namespace_association": "Taci e mamowisinasonaniwok",
        "tooltip-namespace_association": "Tcikisinaha nohwe kikesinahikan kata acotcisinatek kirika taci e mamowisinasinaniwok e aimihitonaniwok kekotc kekwan,taci ka ki orapitcikateki icinikatewina",
        "blanknamespace": "(Ka ici ocitakiniwok)",
+       "contributions": "Wir ka ki witcihietc {{GENDER:$1|User}}",
        "mycontris": "Witcihewin",
        "anoncontribs": "E ki witcihehin",
        "uctop": "(mekwatc)",
        "ipblocklist-submit": "Nantokaskeritcikatek",
        "blocklink": "nokipita",
        "contribslink": "Kaki witcihehin",
+       "movelogpage": "Tipatcimosanihikan ka ki meckotcicinikatcikateki",
        "movesubpagetalktext": "Neta ka arimotcikatek tipatcimosanikanik $1 {{PLURAL:$1|Nota paskickwemakan|Nota paskickwemakana}} kita masinatewa ota.",
        "export": "Matcetciciha masinahikana",
        "allmessages-filter-all": "Kaskina",
        "previousdiff": "Nictam meckotcisinihikan",
        "nextdiff": "Tec meckotcisinihikan",
        "file-info-size": "$1x$2pixels, e irikweckamikak mawtockwemikan:$3nohwe MIME:$4",
+       "file-nohires": "Nohwe e irikwactek nama takon kirowe e sokactek.",
+       "svg-long-desc": "SVG kinokewoc, erikokwactepirik $1 × $2 kawactecik, kinokewoc ehitakok: $3",
        "show-big-image": "E otciparik masinahikaniwoc",
        "show-big-image-preview": "E irikweckwemakisitc$1",
+       "show-big-image-other": "Kotak {{PLURAL:$2|erikokowactepirik|erikokowactepiriki}}: $1.",
        "show-big-image-size": "$1 x $2 pixels",
        "ilsubmit": "Nantokaskeritcikatek",
        "monday-at": "ockorkananiwon $1",
        "metadata-help": "Nohwe mawtockwemikan ekota acteki awacimec tipatcimowina,nohwe masinapiskipitcikan ka ki actakwen kekotc otitapiskipitcikan ka ki ocitarikwen. Kecpin ka meckotisinihikatekwen nictam ka icinakok, nama kaskina kata nokona ka wi icinakotakaniwok nohwe masinasowin.",
        "metadata-fields": "Nohwe e aitotwakaniwitc masinasowin nta kata ici actew paskickwemakanik ka ici tipatcimonaniwok ickwa atciwonikateke nta kitci tipatcimoniwocik. Minawatc kotakahi kata katcictakaniwona.\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": "Itactamictew",
+       "exif-xresolution": "E irikwactepirik mitaskosinihikan",
+       "exif-yresolution": "E irikwastepirik tcimiskisinihikan",
        "exif-datetime": "Apitc ka meckotcitakaniwok",
        "exif-make": "Ka ki ocitatatc masinapiskahikaniw",
        "exif-model": "E icinakok masinapiskohowewin",
        "redirect-submit": "Tapowata",
        "fileduplicatesearch-submit": "Nantokaskeritcikatek",
        "specialpages": "Ka ici wectakaniwok",
+       "tag-filter": "Nihipita nehi[[Special:Tags|balises]] :",
        "tag-list-wrapper": "([[Special:Tags|{{PLURAL:$1|Kicawatcikanicic|Kicawatcikanica}}]] : $2)",
        "tags-source-header": "Ite wetciparik",
        "tags-active-yes": "Ehe",
        "htmlform-yes": "Ehe",
        "htmlform-cloner-delete": "Manina",
        "logentry-delete-delete": "$1 {{GENDER:$2|ki maninam}} $3 ka arimotcikaterik",
+       "logentry-move-move": "$1 {{GENDER:$2| ki meckotcictaw}} paskickwemakan $3 nte itekera $4",
        "logentry-newusers-create": "Anahwe $1 aci {{GENDER:$2|ickwa ocitakiniwon}}",
+       "logentry-upload-upload": "$1 {{GENDER:$2|ki natapaham}} $3",
        "feedback-cancel": "Ponipita",
        "searchsuggest-search": "Nantona {{SITENAME}}",
        "expand_templates_ok": "OK",
index 4eb689e..7d69d1d 100644 (file)
        "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-filtergroup-changetype": "Тып зьмены",
        "rcfilters-filter-pageedits-label": "Рэдагаваньні старонкі",
        "rcfilters-filter-pageedits-description": "Рэдагаваньні вікізьместу, абмеркаваньняў, апісаньняў катэгорыяў…",
index d2529f2..996d234 100644 (file)
        "mergehistory-merge": "[[:$1]]-এর নিচের সংশোধনগুলি [[:$2]]-এর সাথে একত্র করা যাবে। রেডিও বোতাম কলামটি ব্যবহার করে কেবলমাত্র নির্দেশিত সময় ও তার আগের সমস্ত সংশোধন একত্র করুন। লক্ষ্য করুন, পরিভ্রমণ সংযোগ ব্যবহার করলে কলামটি আদি অবস্থায় ফেরত যাবে।",
        "mergehistory-go": "একত্রীকরণযোগ্য সম্পাদনাগুলি দেখানো হোক",
        "mergehistory-submit": "সংশোধনগুলি একত্রীত করুন",
-       "mergehistory-empty": "কোন সংশোধন একত্র করা যাবে না.",
+       "mergehistory-empty": "কোন সংশোধন একত্র করা যাবে না",
        "mergehistory-done": "$1-এর $3{{PLURAL:$3|টি সংশোধন}} [[:$2]]-এর সাথে একত্রিত করা হয়েছে।",
        "mergehistory-fail": "ইতিহাস একত্র করা গেল না। অনুগ্রহ করে পাতাটি ও সময়ের প্যারামিটারগুলি আবার পরীক্ষা করে দেখুন।",
        "mergehistory-fail-bad-timestamp": "সময়তারিখ অবৈধ।",
        "search-section": "($1 পরিচ্ছেদ)",
        "search-category": "($1 বিষয়শ্রেণী)",
        "search-file-match": "(ফাইলের বিষয়বস্তুর সাথে মিলে যায়)",
-       "search-suggest": "আপনি কি \"$1\" বোঝাতে চাচ্ছেন?",
+       "search-suggest": "আপনি কি বোঝাতে চাচ্ছেন: $1",
        "search-rewritten": "$1-এর জন্য অনুসন্ধানের ফলাফল দেখানো হচ্ছে। এর পরিবর্তে $2-এর জন্য অনুসন্ধান করুন।",
        "search-interwiki-caption": "সহপ্রকল্পসমূহ",
        "search-interwiki-default": "$1 থেকে প্রাপ্ত ফলাফলসমূহ:",
index dd7d921..4e2f7f0 100644 (file)
        "showpreview": "Prikaži izgled",
        "showdiff": "Prikaži izmjene",
        "blankarticle": "<strong>Upozorenje:</strong> Napravili ste praznu stranicu.\nAko ponovno kliknete \"$1\", napravit ćete praznu stranicu bez sadržaja.",
-       "anoneditwarning": "<strong>Upozorenje:</strong> Niste prijavljeni. \nVaša IP adresa će biti javno vidljiva ako napravite neku izmjenu. Ako se <strong>[$1 prijavite]</strong> ili <strong>[$2 napravite račun]</strong>, vaše izmjene će biti pripisane vašem korisničkom imenu, zajedno sa drugim pogodnostima.",
+       "anoneditwarning": "<strong>Upozorenje:</strong> Niste prijavljeni. Vaša IP-adresa bit će javno vidljiva ako napravite neku izmjenu. Ako se <strong>[$1 prijavite]</strong> ili <strong>[$2 napravite račun]</strong>, Vaše izmjene bit će pripisane Vašem korisničkom imenu, pored drugih pogodnosti.",
        "anonpreviewwarning": "''Niste prijavljeni. Nakon spremanja izmjena vaša IP adresa će biti zapisana u historiji uređivanja ove stranice.''",
        "missingsummary": "<strong>Napomena:</strong> Niste unijeli sažetak izmjene.\nAko ponovo kliknete na \"$1\", Vaša izmjena će biti sačuvana bez sažetka.",
        "selfredirect": "<strong>Upozorenje:</strong> Preusmjerili ste stranicu na samu sebe.\nMožda ste naveli pogrešan cilj preusmjeravanja ili ste uređivali pogrešnu stranicu.\nAko ponovno kliknete \"$1\", ipak će nastati preusmjerenje.",
        "rcfilters-filter-newpages-label": "Stvaranje stranica",
        "rcfilters-filter-newpages-description": "Izmjene kojima se stvaraju nove stranice.",
        "rcfilters-filter-categorization-label": "Izmjene kategorija",
-       "rcfilters-filter-categorization-description": "Izmjene kojima se dodavaju ili uklanjaju kategorije.",
+       "rcfilters-filter-categorization-description": "Izmjene kojima se dodavaju ili uklanjaju stranice iz kategorija.",
        "rcfilters-filter-logactions-label": "Zapisane radnje",
        "rcfilters-filter-logactions-description": "Administrativne radnje, pravljenje računa, brisanje stranica, postavljenje datoteka....",
        "rcfilters-typeofchange-conflicts-hideminor": "Ovaj filter za vrstu izmjene u sukobu je s filterom za \"manje izmjene\". Izvjesne vrste izmjena ne mogu se označiti kao \"manje\".",
        "blockip": "Blokiraj {{GENDER:$1|korisnika|korisnicu}}",
        "blockip-legend": "Blokiranje korisnika",
        "blockiptext": "Koristite donji obrazac da biste uklonili prava pisanja određenoj IP-adresi ili korisničkom imenu.\nOvo bi se trebalo raditi samo da bi se spriječio vandalizam, i u skladu sa [[{{MediaWiki:Policy-url}}|smjernicama]].\nIspod upišite konkretan razlog (naprimjer, navedite koje su stranice vandalizirane).\nMožete blokirati IP-opsege koristeći sintaksu [https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing CIDR-a]; najveći dozvoljeni opseg za IPv4 je /$1, a za IPv6 /$2.",
-       "ipaddressorusername": "IP adresa ili korisničko ime:",
+       "ipaddressorusername": "IP-adresa ili korisničko ime:",
        "ipbexpiry": "Ističe:",
        "ipbreason": "Razlog:",
        "ipbreason-dropdown": "*Najčešći razlozi blokiranja\n**Netačne informacije\n**Uklanjanje sadržaja stranica\n**Postavljanje spam vanjskih linkova\n**Ubacivanje gluposti/grafita\n**Osobni napadi (ili napadačko ponašanje)\n**Čarapare (zloupotreba više korisničkih računa)\n**Neprihvatljivo korisničko ime",
-       "ipb-hardblock": "Onemogući prijavljene korisnike da uređuju sa ove IP adrese",
+       "ipb-hardblock": "Spriječi prijavljene korisnike da uređuju s ove IP-adrese",
        "ipbcreateaccount": "Spriječi pravljenje računa",
        "ipbemailban": "Spriječi korisnika da šalje e-poštu",
        "ipbenableautoblock": "Automatski blokiraj posljednju IP-adresu koju je koristio ovaj korisnik i sve druge IP-adrese s kojih je pokušao uređivati",
        "ipboptions": "2 sata:2 hours,1 dan:1 day,3 dana:3 days,1 sedmica:1 week,2 sedmice:2 weeks,1 mjesec:1 month,3 mjeseca:3 months,6 mjeseci:6 months,1 godine:1 year,beskonačno:infinite",
        "ipbhidename": "Sakrij korisničko ime iz uređivanja i spiskova",
        "ipbwatchuser": "Prati korisničku stranicu i stranicu za razgovor ovog korisnika",
-       "ipb-disableusertalk": "Onemogući ovog korisnika da uređuje svoju stranicu za razgovor dok je blokiran",
+       "ipb-disableusertalk": "Spriječi ovog korisnika da uređuje svoju stranicu za razgovor dok je blokiran",
        "ipb-change-block": "Ponovno blokiraj korisnika sa novim postavkama",
        "ipb-confirm": "Potvrdite blokiranje",
        "badipaddress": "Pogrešna IP adresa",
        "hours": "{{PLURAL:$1|$1 sat|$1 sata|$1 sati}}",
        "days": "{{PLURAL:$1|$1 dan|$1 dana|$1 dana}}",
        "weeks": "{{PLURAL:$1|$1 sedmica}}",
-       "months": "{{PLURAL:$1|$1 mjesec|$1 mjeseci}}",
+       "months": "{{PLURAL:$1|$1 mjesec|$1 mjeseca|$1 mjeseci}}",
        "years": "{{PLURAL:$1|$1 godina|$1 godine|$1 godina}}",
        "ago": "prije $1",
        "just-now": "upravo sad",
        "api-error-stashfailed": "Unutrašnja greška: server nije mogao da spremi privremenu datoteku.",
        "api-error-unknown-warning": "Nepoznato upozorenje: \"$1\".",
        "api-error-unknownerror": "Nepoznata greška: \"$1\"",
-       "duration-seconds": "$1 {{PLURAL:$1|sekunda|sekunde}}",
+       "duration-seconds": "$1 {{PLURAL:$1|sekunda|sekunde|sekundi}}",
        "duration-minutes": "$1 {{PLURAL:$1|minut|minute|minuta}}",
        "duration-hours": "$1 {{PLURAL:$1|sat|sata|sati}}",
        "duration-days": "$1 {{PLURAL:$1|dan|dana}}",
index 7f8ed9a..97f68c2 100644 (file)
        "unblock-hideuser": "No podeu desblocar aquest usuari, perquè el seu nom d'usuari està ocult.",
        "ipb_cant_unblock": "Errada: No s'ha trobat el núm. ID de bloqueig $1. És possible que ja s'haguera desblocat.",
        "ipb_blocked_as_range": "Error: L'adreça IP $1 no està blocada directament i per tant no pot ésser desbloquejada. Ara bé, sí que ho està per formar part del rang $2 que sí que pot ser desblocat.",
-       "ip_range_invalid": "Rang d'IP no vàlid.",
+       "ip_range_invalid": "L’interval d’adreces IP no és vàlid.",
        "ip_range_toolarge": "No són permesos els bloquejos de rangs més grans que /$1.",
        "proxyblocker": "Bloqueig de proxy",
        "proxyblockreason": "S'ha blocat la vostra adreça IP perquè és un proxy obert. Contactau el vostre proveïdor d'Internet o servei tècnic i informau-los d'aquest seriós problema de seguretat.",
index 0f4ad80..a8bb14c 100644 (file)
        "rcfilters-filter-minor-description": "Editace, které autor označil jako malé.",
        "rcfilters-filter-major-label": "Nemalé editace",
        "rcfilters-filter-major-description": "Editace neoznačené jako malé.",
+       "rcfilters-filtergroup-watchlist": "Sledované stránky",
+       "rcfilters-filter-watchlist-watched-label": "Na seznamu sledovaných stránek",
+       "rcfilters-filter-watchlist-watched-description": "Změny stránek z vašeho seznamu sledovaných.",
+       "rcfilters-filter-watchlist-watchednew-label": "Nové změny sledovaných stránek",
+       "rcfilters-filter-watchlist-watchednew-description": "Změny stránek z vašeho seznamu sledovaných, které jste od jejich změny nenavštívili.",
+       "rcfilters-filter-watchlist-notwatched-label": "Nesledované stránky",
+       "rcfilters-filter-watchlist-notwatched-description": "Vše kromě změn vašich sledovaných stránek.",
        "rcfilters-filtergroup-changetype": "Typ změny",
        "rcfilters-filter-pageedits-label": "Editace stránek",
        "rcfilters-filter-pageedits-description": "Editace obsahu wiki, diskusí, popisů kategorií...",
        "rcfilters-hideminor-conflicts-typeofchange-global": "Filtr „Malé editace“ je v konfliktu s jedním nebo více filtry podle typu změny, protože určité typy změn nelze označit jako malé. Dotyčné filtry jsou označeny nahoře, v prostoru „Aktivní filtry“.",
        "rcfilters-hideminor-conflicts-typeofchange": "Určité typy změn nelze označit jako malé, tento filtr je proto v konfliktu s následujícími filtry podle typu změny: $1",
        "rcfilters-typeofchange-conflicts-hideminor": "Tento filtr podle typu změny je v konfliktu s filtrem „Malé editace“. Určité typy změn nelze označit jako malé.",
+       "rcfilters-filtergroup-lastRevision": "Aktuální verze",
+       "rcfilters-filter-lastrevision-label": "Aktuální verze",
+       "rcfilters-filter-lastrevision-description": "Poslední změna stránky.",
+       "rcfilters-filter-previousrevision-label": "Dřívější verze",
+       "rcfilters-filter-previousrevision-description": "Všechny změny, které nejsou nejnovější úpravou stránky.",
        "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",
index d864bb9..4de20a8 100644 (file)
        "botpasswords-label-delete": "Slet",
        "botpasswords-label-resetpassword": "Nulstil adgangskode",
        "botpasswords-label-grants": "Tilgængelige bevillinger:",
+       "botpasswords-updated-title": "Bot kodeord opdateret",
+       "botpasswords-deleted-title": "Bot kodeord slettet",
        "resetpass_forbidden": "Adgangskoder kan ikke ændres",
+       "resetpass_forbidden-reason": "Adgangskoder kan ikke ændres: $1",
        "resetpass-no-info": "Du skal være logget på for at komme direkte til denne side.",
        "resetpass-submit-loggedin": "Skift adgangskode",
        "resetpass-submit-cancel": "Annuller",
        "passwordreset-emailelement": "Brugernavn: \n$1\n\nMidlertidig adgangskode: \n$2",
        "passwordreset-emailsentemail": "Hvis denne e-mailadresse er knyttet til din konto, så vil en e-mail om nulstilling af adgangskoden blive sendt.",
        "passwordreset-emailsentusername": "Hvis der er en e-mailadresse forbundet med dette brugernavn, så vil en e-mail om nulstilling af adgangskoden blive sendt.",
+       "passwordreset-invalidemail": "Ugyldig e-mailadresse",
+       "passwordreset-nodata": "Hverken et brugernavn eller en e-mailadresse blev angivet",
        "changeemail": "Ændr eller fjern e-mailadresse",
        "changeemail-header": "Udfyld denne formular for at ændre din e-mailadresse. Hvis du gerne vil fjerne forbindelsen af en e-mailadresse fra din konto, så lad den nye e-mailadresse være blank, når du sender formularen.",
        "changeemail-no-info": "Du skal være logget på for at komme direkte til denne side.",
        "blockedtitle": "Du eller din IP-adresse er blokeret",
        "blockedtext": "'''Dit brugernavn eller din IP-adresse er blevet blokeret.'''\n\nBlokeringen er foretaget af $1.\nDen anførte grund er ''$2''.\n\nBlokeringen starter: $8\nBlokeringen udløber: $6\nBlokeringen er rettet mod: $7\n\nDu kan kontakte $1 eller en af de andre [[{{MediaWiki:Grouppage-sysop}}|administratorer]] for at diskutere blokeringen.\nDu kan ikke bruge funktionen 'e-mail til denne bruger' medmindre der er angivet en gyldig e-mailadresse i dine\n[[Special:Preferences|kontoindstillinger]], og du ikke er blevet blokeret fra at bruge den.\n\nDin nuværende IP-adresse er $3, og blokerings-id er #$5.\nAngiv venligst alle ovenstående detaljer ved henvendelser om blokeringen.",
        "autoblockedtext": "Din IP-adresse er blevet blokeret automatisk fordi den blev brugt af en anden bruger som er blevet blokeret af $1.\nBegrundelsen for det er:\n\n:''$2''\n\n* Blokeringsperiodens start: $8\n* Blokeringen udløber: $6\n* Blokeringen er ment for: $7\n\nDu kan kontakte $1 eller en af de andre [[{{MediaWiki:Grouppage-sysop}}|administratorer]] for at diskutere blokeringen.\n\nBemærk at du ikke kan bruge funktionen \"e-mail til denne bruger\" medmindre du har en gyldig e-mailadresse registreret i din [[Special:Preferences|brugerindstilling]], og du ikke er blevet blokeret fra at bruge den.\n\nDin nuværende IP-adresse er $3, og blokerings-id'et er #$5.\nAngiv venligst alle de ovenstående detaljer ved eventuelle henvendelser.",
+       "systemblockedtext": "Dit brugernavn eller din IP-adresse er automatisk blokeret af MediaWiki.\nBegrundelsen for det er:\n\n:<em>$2</em>\n\n* Blokeringsperiodens start: $8\n* Blokeringen udløber: $6\n* Blokeringen er ment for: $7\n\nDin nuværende IP-adresse er $3.\nAngiv venligst alle de ovenstående detaljer ved eventuelle henvendelser.\")",
        "blockednoreason": "ingen begrundelse givet",
        "whitelistedittext": "Du skal $1 for at kunne redigere sider.",
        "confirmedittext": "Du skal først bekræfte din e-mailadresse, før du kan redigere sider. Udfyld og bekræft din e-mailadresse i dine [[Special:Preferences|indstillinger]].",
        "userrights-unchangeable-col": "Uredigerbare grupper",
        "userrights-expiry-current": "Udløber $1",
        "userrights-expiry-none": "Udløber ikke",
+       "userrights-expiry": "Udløber:",
+       "userrights-expiry-existing": "Nugældende udløbstid: $2 $3",
+       "userrights-expiry-othertime": "Anden tid:",
        "userrights-expiry-options": "1 dag:1 day,1 uge:1 week,1 måned:1 month,3 måneder:3 months,6 måneder:6 months,1 år:1 year",
+       "userrights-invalid-expiry": "Udløbstiden for gruppen \"$1\" er ugyldig.",
+       "userrights-expiry-in-past": "Udløbstiden for gruppen \"$1\" er i fortiden.",
        "userrights-conflict": "Konflikt i ændringer af brugerrettigheder!\nVær venlig at gennemse og bekræft dine ændringer.",
        "group": "Gruppe:",
        "group-user": "Brugere",
        "action-writeapi": "bruge skrive-API'et",
        "action-delete": "slette denne side",
        "action-deleterevision": "slette siderevisioner",
+       "action-deletelogentry": "slet logposter",
        "action-deletedhistory": "se en sides slettede historik",
+       "action-deletedtext": "se slettet revisionstekst",
        "action-browsearchive": "søge i slettede sider",
        "action-undelete": "gendanne sider",
        "action-suppressrevision": "se og gendanne skjulte siderevisioner",
        "recentchanges-legend-plusminus": "(''±123'')",
        "recentchanges-submit": "Vis",
        "rcfilters-activefilters": "Aktive filtre",
+       "rcfilters-restore-default-filters": "Gendan standardfiltre",
+       "rcfilters-clear-all-filters": "Ryd alle filtre",
        "rcfilters-invalid-filter": "Ugyldigt filter",
        "rcfilters-filterlist-title": "Filtre",
+       "rcfilters-filterlist-whatsthis": "Hvad er dette?",
+       "rcfilters-highlightmenu-title": "Vælg en farve",
+       "rcfilters-highlightmenu-help": "Vælg en farve for at fremhæve denne egenskab",
+       "rcfilters-filterlist-noresults": "Ingen filtre fundet",
+       "rcfilters-filtergroup-registration": "Brugerregistrering",
+       "rcfilters-filter-registered-label": "Registreret",
+       "rcfilters-filter-unregistered-label": "Uregistreret",
+       "rcfilters-filter-unregistered-description": "Redaktører, der ikke er logget ind.",
+       "rcfilters-filter-editsbyself-label": "Ændringer af dig",
+       "rcfilters-filter-editsbyself-description": "Dine egne bidrag.",
+       "rcfilters-filter-editsbyother-label": "Ændringer af andre",
+       "rcfilters-filter-editsbyother-description": "Alle ændringer undtagen din egen.",
+       "rcfilters-filtergroup-userExpLevel": "Erfaringsniveau (kun for registrerede brugere)",
        "rcfilters-filter-user-experience-level-experienced-label": "Erfarne brugere",
        "rcnotefrom": "Nedenfor er op til '''$1''' {{PLURAL:$5|ændring|ændringer}} siden '''$2''' vist.",
        "rclistfrom": "Vis nye ændringer startende fra den $3 kl. $2",
index a6d3045..05164df 100644 (file)
        "search-file-match": "(matches file content)",
        "search-suggest": "Did you mean: $1",
        "search-rewritten": "Showing results for $1. Search instead for $2.",
-       "search-interwiki-caption": "Sister projects",
+       "search-interwiki-caption": "Results from sister projects",
        "search-interwiki-default": "Results from $1:",
        "search-interwiki-custom": "",
        "search-interwiki-more": "(more)",
        "recentchanges-legend-plusminus": "(<em>±123</em>)",
        "recentchanges-submit": "Show",
        "rcfilters-activefilters": "Active filters",
+       "rcfilters-quickfilters": "Quick links",
+       "rcfilters-savedqueries-defaultlabel": "Saved filters",
+       "rcfilters-savedqueries-rename": "Rename",
+       "rcfilters-savedqueries-setdefault": "Set as default",
+       "rcfilters-savedqueries-unsetdefault": "Unset as default",
+       "rcfilters-savedqueries-remove": "Remove",
+       "rcfilters-savedqueries-new-name-label": "Name",
+       "rcfilters-savedqueries-apply-label": "Create quick link",
+       "rcfilters-savedqueries-cancel-label": "Cancel",
+       "rcfilters-savedqueries-add-new-title": "Save filters as a quick link",
        "rcfilters-restore-default-filters": "Restore default filters",
        "rcfilters-clear-all-filters": "Clear all filters",
        "rcfilters-search-placeholder": "Filter recent changes (browse or start typing)",
        "rcfilters-filter-user-experience-level-newcomer-label": "Newcomers",
        "rcfilters-filter-user-experience-level-newcomer-description": "Fewer than 10 edits and 4 days of activity.",
        "rcfilters-filter-user-experience-level-learner-label": "Learners",
-       "rcfilters-filter-user-experience-level-learner-description": "More days of activity and edits than \"Newcomers\" but fewer than \"Experienced users\".",
+       "rcfilters-filter-user-experience-level-learner-description": "More experience than \"Newcomers\" but less than \"Experienced users\".",
        "rcfilters-filter-user-experience-level-experienced-label": "Experienced users",
        "rcfilters-filter-user-experience-level-experienced-description": "More than 30 days of activity and 500 edits.",
        "rcfilters-filtergroup-automated": "Automated contributions",
index 0017d66..3b33502 100644 (file)
        "editlink": "editar",
        "viewsourcelink": "ver código",
        "editsectionhint": "Editar sección: $1",
-       "toc": "Contenido",
+       "toc": "Sumario",
        "showtoc": "mostrar",
        "hidetoc": "ocultar",
        "collapsible-collapse": "Contraer",
        "internalerror": "Error interno",
        "internalerror_info": "Error interno: $1",
        "internalerror-fatal-exception": "Excepción grave de tipo \"$1\"",
-       "filecopyerror": "No se ha podido copiar el archivo «$1» a «$2».",
-       "filerenameerror": "No se ha podido renombrar el archivo «$1» a «$2».",
+       "filecopyerror": "No se ha podido copiar el archivo «$1» en «$2».",
+       "filerenameerror": "No se pudo cambiar el nombre del archivo «$1» a «$2».",
        "filedeleteerror": "No se ha podido borrar el archivo «$1».",
        "directorycreateerror": "No se ha podido crear el directorio «$1».",
        "directoryreadonlyerror": "El directorio «$1» es de solo lectura.",
        "preview": "Previsualizar",
        "showpreview": "Mostrar previsualización",
        "showdiff": "Mostrar los cambios",
-       "blankarticle": "<strong>Aviso:</strong> estás a punto de crear una página vacía.\nSi pulsas en «$1» de nuevo, se creará la página sin ningún contenido.",
+       "blankarticle": "<strong>Aviso:</strong> estás a punto de crear una página vacía.\nSi haces clic en «$1» de nuevo, se creará la página sin ningún contenido.",
        "anoneditwarning": "<strong>Advertencia:</strong> no has iniciado sesión. Tu dirección IP se hará pública si haces cualquier edición en estas condiciones. Si <strong>[$1 inicias sesión]</strong> o <strong>[$2 creas una cuenta]</strong>, tus ediciones se atribuirán a tu nombre de usuario, además de otros beneficios.",
        "anonpreviewwarning": "<em>No has iniciado sesión. Al guardar los cambios se almacenará tu dirección IP en el historial de edición de esta página.</em>",
-       "missingsummary": "<strong>Atención:</strong> No has escrito un resumen de edición.\nSi haces clic nuevamente en «$1» tu edición se grabará sin él.",
+       "missingsummary": "<strong>Atención:</strong> no has escrito un resumen de edición.\nSi haces clic de nuevo en «$1» tu edición se grabará sin él.",
        "selfredirect": "<strong>Advertencia:</strong> estás redirigiendo esta página a sí misma.\nPuede que hayas especificado erróneamente el destino de la redirección, o quizá estés editando la página equivocada. En cualquier caso, si haces clic de nuevo en \"$1\", se creará la redirección.",
        "missingcommenttext": "Escribe un comentario a continuación.",
        "missingcommentheader": "<strong>Atención:</strong> no has escrito un asunto para este comentario.\nSi haces clic nuevamente en \"$1\" tu edición se grabará sin él.",
        "editingsection": "Edición de «$1» (sección)",
        "editingcomment": "Edición de «$1» (sección nueva)",
        "editconflict": "Conflicto de edición: $1",
-       "explainconflict": "Alguien ha realizado cambios en esta página desde que empezaste a editarla.\nEl cuadro de texto superior contiene el texto de la página tal como está guardado en este momento.\nTus cambios sobre la versión que editaste se muestran en el cuadro de texto inferior.\nSi quieres guardar tus cambios, has de trasladarlos al cuadro superior.\nAl pulsar «$1», se guardará <strong>solo</strong> el texto del cuadro superior.",
+       "explainconflict": "Alguien ha realizado cambios en esta página desde que empezaste a editarla.\nEl cuadro de texto superior contiene el texto de la página tal como está guardado en este momento.\nTus cambios sobre la versión que editaste se muestran en el cuadro de texto inferior.\nSi quieres guardar tus cambios, has de trasladarlos al cuadro superior.\nAl pulsar «$1», se guardará <strong>solamente</strong> el texto del cuadro superior.",
        "yourtext": "Tu texto",
        "storedversion": "Versión guardada",
        "nonunicodebrowser": "<strong>Advertencia: tu navegador no es compatible con los caracteres Unicode.</strong>\nSe ha activado un sistema de edición alternativo que te permitirá editar artículos con seguridad: los caracteres no pertenecientes al estándar ASCII aparecerán como códigos hexadecimales en el cuadro de edición.",
        "prefs-watchlist-edits": "Número máximo de ediciones que mostrar en la lista expandida:",
        "prefs-watchlist-edits-max": "Cantidad máxima: 1000",
        "prefs-watchlist-token": "Clave de lista de seguimiento:",
-       "prefs-misc": "Miscelánea",
+       "prefs-misc": "Varias",
        "prefs-resetpass": "Cambiar contraseña",
        "prefs-changeemail": "Cambiar o eliminar la dirección de correo electrónico",
        "prefs-setemail": "Establecer una dirección de correo electrónico",
        "rcfilters-filter-minor-description": "Ediciones etiquetadas por el autor como menores.",
        "rcfilters-filter-major-label": "Ediciones no menores",
        "rcfilters-filter-major-description": "Ediciones no etiquetadas como menores.",
+       "rcfilters-filtergroup-watchlist": "Páginas vigiladas",
+       "rcfilters-filter-watchlist-watched-label": "En mi lista de seguimiento",
+       "rcfilters-filter-watchlist-watched-description": "Cambios en las páginas de tu lista de seguimiento.",
+       "rcfilters-filter-watchlist-watchednew-label": "Cambios nuevos en tu lista de seguimiento",
+       "rcfilters-filter-watchlist-watchednew-description": "Cambios en las páginas de tu lista de seguimiento que no has visitado desde que se produjeron los cambios.",
+       "rcfilters-filter-watchlist-notwatched-label": "No en mi lista de seguimiento",
+       "rcfilters-filter-watchlist-notwatched-description": "Todos, excepto los cambios en las páginas de tu lista de seguimiento.",
        "rcfilters-filtergroup-changetype": "Tipo de cambio",
        "rcfilters-filter-pageedits-label": "Ediciones de páginas",
        "rcfilters-filter-pageedits-description": "Modificaciones del contenido wiki, discusiones, descripción de categorías...",
        "rcfilters-hideminor-conflicts-typeofchange-global": "El filtro \"Ediciones menores\" está en conflicto con uno o más Tipos de filtros de Cambio, ya que ciertos tipos de cambio no pueden ser designados como \"menores\". Los filtros en conflicto están marcados en el área Filtros activos, anterior.",
        "rcfilters-hideminor-conflicts-typeofchange": "Ciertos tipos de cambio no pueden ser designados como \"menores\", por lo que este filtro entra en conflicto con los siguientes  Tipos de filtros de Cambio: $1",
        "rcfilters-typeofchange-conflicts-hideminor": "Este filtro «Tipo de cambio» entra en conflicto con el filtro «Ediciones menores». Hay ciertos tipos de cambios que no pueden denominarse «menores».",
+       "rcfilters-filtergroup-lastRevision": "Revisión actual",
+       "rcfilters-filter-lastrevision-label": "Revisión actual",
+       "rcfilters-filter-lastrevision-description": "El cambio más reciente a una página.",
+       "rcfilters-filter-previousrevision-label": "Revisiones anteriores",
+       "rcfilters-filter-previousrevision-description": "Todos los cambios que no son los más recientes cambian a una página.",
        "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",
        "backend-fail-describe": "No se pudieron cambiar los metadatos del archivo \"$1\".",
        "backend-fail-alreadyexists": "El archivo \"$1\" ya existe.",
        "backend-fail-store": "No se pudo almacenar el archivo \"$1\" en \"$2\".",
-       "backend-fail-copy": "No se pudo copiar el archivo \"$1\" a \"$2\".",
+       "backend-fail-copy": "No se ha podido copiar el archivo «$1» en «$2».",
        "backend-fail-move": "No se pudo trasladar el archivo \"$1\" a \"$2\".",
        "backend-fail-opentemp": "No se pudo crear archivo temporal.",
        "backend-fail-writetemp": "No se pudo escribir en el archivo temporal.",
        "unblock-hideuser": "No puedes desbloquear a este usuario porque su nombre ha sido ocultado.",
        "ipb_cant_unblock": "Error: no se encuentra el identificador de bloque $1. Pudo haber sido desbloqueado ya.",
        "ipb_blocked_as_range": "Error: la dirección IP $1 no está bloqueada directamente y no puede ser desbloqueada.\nSin embargo, está bloqueada como parte del rango $2, que puede ser desbloqueado.",
-       "ip_range_invalid": "El rango de IP no es válido.",
+       "ip_range_invalid": "El intervalo de IP no es válido.",
        "ip_range_toolarge": "Los bloqueos de rango superiores a /$1 no están permitidos.",
        "proxyblocker": "Bloqueador de proxies",
        "proxyblockreason": "Tu dirección IP ha sido bloqueada porque es un proxy abierto.\nContacta con tu proveedor de servicios de Internet o con tu servicio de asistencia técnica e infórmales de este grave problema de seguridad.",
        "newimages-showbots": "Mostrar cargas de bots",
        "newimages-hidepatrolled": "Ocultar las subidas verificadas",
        "noimages": "No hay nada que ver.",
-       "gallery-slideshow-toggle": "Alternar las miniaturas",
+       "gallery-slideshow-toggle": "Activar o desactivar las miniaturas",
        "ilsubmit": "Buscar",
        "bydate": "por fecha",
        "sp-newimages-showfrom": "Mostrar archivos nuevos empezando desde $2, $1",
        "json-error-inf-or-nan": "Hay uno o más valores «NAN» o «INF» en el valor que se codificará",
        "json-error-unsupported-type": "Se proporcionó un valor en un tipo que no se puede codificar",
        "headline-anchor-title": "Enlace a esta sección",
-       "special-characters-group-latin": "Latín",
+       "special-characters-group-latin": "Latino",
        "special-characters-group-latinextended": "Latino ampliado",
        "special-characters-group-ipa": "AFI",
        "special-characters-group-symbols": "Símbolos",
index 7647732..ea201f1 100644 (file)
@@ -77,9 +77,9 @@
        "tog-prefershttps": "Kasuta sisselogimisel alati turvalist ühendust",
        "underline-always": "Alati",
        "underline-never": "Mitte kunagi",
-       "underline-default": "Kujunduse või veebilehitseja vaikeväärtus",
+       "underline-default": "Kujunduse või brauseri vaikeväärtus",
        "editfont-style": "Redigeerimisala kirjatüüp:",
-       "editfont-default": "Veebilehitseja vaikesäte",
+       "editfont-default": "Brauseri vaikesäte",
        "editfont-monospace": "Püsisammuga font",
        "editfont-sansserif": "Seriifideta kiri",
        "editfont-serif": "Seriifidega kiri",
        "virus-badscanner": "Viga konfiguratsioonis: tundmatu viirusetõrje: ''$1''",
        "virus-scanfailed": "skaneerimine ebaõnnestus (veakood $1)",
        "virus-unknownscanner": "tundmatu viirusetõrje:",
-       "logouttext": "<strong>Oled nüüd välja loginud.</strong>\n\nPane tähele, et seni, kuni sa pole veebilehitseja puhvrit tühjendanud, võidakse mõni lehekülg endiselt kuvada nii nagu oleksid ikka sisse logitud.",
+       "logouttext": "<strong>Oled nüüd välja logitud.</strong>\n\nPane tähele, et seni, kuni sa pole brauseri puhvrit tühjendanud, võidakse mõni lehekülg endiselt kuvada nii nagu oleksid ikka sisse logitud.",
        "cannotlogoutnow-title": "Praegu ei saa välja logida",
        "cannotlogoutnow-text": "Väljalogimine pole võimalik, kui kasutad $1.",
        "welcomeuser": "Tere tulemast, $1!",
        "login-abort-generic": "Sisselogimine ebaõnnestus – Katkestatud",
        "login-migrated-generic": "Sinu konto on migreeritud ja sinu kasutajanime pole enam selles vikis.",
        "loginlanguagelabel": "Keel: $1",
-       "suspicious-userlogout": "Sinu väljalogimiskatse nurjus, sest see näis olevat katkise veebilehitseja või puhverserveri saadetud.",
+       "suspicious-userlogout": "Sinu väljalogimiskatse nurjus, sest see näis olevat katkise brauseri või puhverserveri saadetud.",
        "createacct-another-realname-tip": "Tegelik nimi on valikuline.\nKui otsustad selle sisestada, kasutatakse seda kasutaja töö temale omistamiseks.",
        "pt-login": "Logi sisse",
        "pt-login-button": "Logi sisse",
        "accmailtitle": "Parool saadetud",
        "accmailtext": "Kasutajale [[User talk:$1|$1]] genereeritud juhuslik parool saadeti aadressile $2.\n\nSeda saab pärast sisselogimist muuta ''[[Special:ChangePassword|parooli muutmise]]'' leheküljel.",
        "newarticle": "(Uus)",
-       "newarticletext": "Lehekülge, kuhu link sind suunas, pole veel.\nEt lehekülg luua, alusta allolevas kastis kirjutamist (lisateave [$1 juhendist]).\nKui sattusid siia kogemata, klõpsa veebilehitseja ''tagasi''-nupule.",
+       "newarticletext": "Lehekülge, kuhu link sind suunas, pole veel.\nEt lehekülg luua, alusta allolevas kastis kirjutamist (lisateave [$1 juhendist]).\nKui sattusid siia kogemata, klõpsa brauseri ''tagasi''-nupule.",
        "anontalkpagetext": "----''See on anonüümse kasutaja arutelulehekülg. See kasutaja pole kontot loonud või ei kasuta seda. Sellepärast tuleb meil kasutaja tuvastamiseks kasutada tema IP-aadressi. Sellist IP-aadressi võib kasutada mitu kasutajat. Kui oled osutatud IP-aadressi kasutaja ning leiad, et siinsed kommentaarid ei puutu kuidagi sinusse, [[Special:CreateAccount|loo palun kasutajakonto]] või [[Special:UserLogin|logi sisse]], et sind edaspidi teiste anonüümsete kasutajatega segi ei aetaks.''",
        "noarticletext": "Käesoleval leheküljel hetkel teksti ei ole.\nVõid [[Special:Search/{{PAGENAME}}|otsida pealkirjaks olevat fraasi]] teistelt lehtedelt,\n<span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} uurida asjassepuutuvaid logisid] või [{{fullurl:{{FULLPAGENAME}}|action=edit}} puuduva lehekülje ise luua]</span>.",
        "noarticletext-nopermission": "Sellel leheküljel pole praegu teksti.\nSaad [[Special:Search/{{PAGENAME}}|otsida selle lehekülje pealkirja]] teistelt lehekülgedelt või <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} otsida seonduvatest logidest]</span>, aga sul pole õigust seda lehekülge alustada.",
        "userpage-userdoesnotexist": "Kasutajakontot \"<nowiki>$1</nowiki>\" pole olemas.\nPalun mõtle järele, kas soovid seda lehte luua või muuta.",
        "userpage-userdoesnotexist-view": "Kasutajakonto \"$1\" pole registreeritud.",
        "blocked-notice-logextract": "See kasutaja on praegu blokeeritud.\nAllpool on toodud viimane blokeerimislogi sissekanne:",
-       "clearyourcache": "<strong>Märkus:</strong> Võimalik, et pärast salvestamist tuleb muudatuste nägemiseks veebilehitseja puhver tühjendada.\n* <strong>Firefox / Safari:</strong> Hoia all <em>Shift</em>-klahvi ja klõpsa <em>Laadi uuesti</em> või vajuta kas <em>Ctrl-F5</em> või <em>Ctrl-R</em> (Macis <em>⌘-R</em>).\n* <strong>Google Chrome:</strong> Vajuta <em>Ctrl-Shift-R</em> (Macis <em>⌘-Shift-R</em>).\n* <strong>Internet Explorer:</strong> Hoia all <em>Ctrl</em>-klahvi ja klõpsa <em>Värskenda</em> või vajuta <em>Ctrl-F5</em>.\n* <strong>Opera:</strong> Mine asukohta <em>Menüü → Seaded</em> (Macis <em>Opera → Eelistused</em>) ja seejärel <em>Privaatsus ja turvalisus → Tühjenda sirvimisandmed → Puhverdatud pildid ja failid</em>.",
+       "clearyourcache": "<strong>Märkus:</strong> Võimalik, et pärast salvestamist tuleb muudatuste nägemiseks brauseri puhver tühjendada.\n* <strong>Firefox / Safari:</strong> Hoia all <em>Shift</em>-klahvi ja klõpsa <em>Laadi uuesti</em> või vajuta kas <em>Ctrl-F5</em> või <em>Ctrl-R</em> (Macis <em>⌘-R</em>).\n* <strong>Google Chrome:</strong> Vajuta <em>Ctrl-Shift-R</em> (Macis <em>⌘-Shift-R</em>).\n* <strong>Internet Explorer:</strong> Hoia all <em>Ctrl</em>-klahvi ja klõpsa <em>Värskenda</em> või vajuta <em>Ctrl-F5</em>.\n* <strong>Opera:</strong> Mine asukohta <em>Menüü → Seaded</em> (Macis <em>Opera → Eelistused</em>) ja seejärel <em>Privaatsus ja turvalisus → Tühjenda sirvimisandmed → Puhverdatud pildid ja failid</em>.",
        "usercssyoucanpreview": "'''Vihje:''' Enne salvestamist kasuta oma uue CSSi proovimiseks nuppu \"{{int:showpreview}}\".",
        "userjsyoucanpreview": "'''Vihje:''' Enne salvestamist kasuta oma uue JavaScripti proovimiseks nuppu \"{{int:showpreview}}\".",
        "usercsspreview": "'''Ära unusta, et seda versiooni sinu isiklikust stiililehest pole veel salvestatud!'''",
        "post-expand-template-argument-warning": "'''Hoiatus:''' See lehekülg sisaldab argumendina vähemalt üht malli, mille määratud maht on liiga suur.\nNeed argumendid on välja jäetud.",
        "post-expand-template-argument-category": "Leheküljed, kus malli argumendid on välja jäänud",
        "parser-template-loop-warning": "Mallid moodustavad tsükli: [[$1]]",
+       "template-loop-category": "Mallisilmusega leheküljed",
+       "template-loop-category-desc": "Leheküljel on mallisilmus ehk mall kutsub rekursiivselt iseend.",
        "parser-template-recursion-depth-warning": "Malli rekursiivse kasutamise limiit on ületatud ($1)",
        "language-converter-depth-warning": "Keeleteisendaja sügavuspiir ületatud ($1)",
        "node-count-exceeded-category": "Ületatud sõlmemääraga leheküljed",
        "timezoneuseserverdefault": "Kasuta serveri vaikesätet ($1)",
        "timezoneuseoffset": "Muu (määra ajavahe)",
        "servertime": "Serveri aeg:",
-       "guesstimezone": "Loe aeg veebilehitsejast",
+       "guesstimezone": "Loe aeg brauserist",
        "timezoneregion-africa": "Aafrika",
        "timezoneregion-america": "Ameerika",
        "timezoneregion-antarctica": "Antarktika",
        "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-activefilters": "Aktiivsed filtrid",
+       "rcfilters-restore-default-filters": "Taasta vaikefiltrid",
+       "rcfilters-clear-all-filters": "Eemalda kõik filtrid",
+       "rcfilters-search-placeholder": "Filtri viimaseid muudatusi (sirvi või alusta tippimist)",
+       "rcfilters-invalid-filter": "Vigane filter",
+       "rcfilters-empty-filter": "Aktiivsed filtrid puuduvad. Näidatakse kogu kaastööd.",
+       "rcfilters-filterlist-title": "Filtrid",
+       "rcfilters-filterlist-whatsthis": "Mis see on?",
+       "rcfilters-filterlist-feedbacklink": "Anna uute filtrite beetaversiooni kohta tagasisidet",
+       "rcfilters-highlightbutton-title": "Tulemuste esiletõst",
+       "rcfilters-highlightmenu-title": "Vali värvus",
+       "rcfilters-highlightmenu-help": "Vali värvus, et see atribuut esile tõsta",
+       "rcfilters-filterlist-noresults": "Ei leitud ühtegi filtrit.",
+       "rcfilters-noresults-conflict": "Tulemusi ei leitud, sest otsikriteeriumid on konfliktsed.",
+       "rcfilters-state-message-subset": "See filter ei tee midagi, sest selle tulemused on kaasatud {{PLURAL:$2|järgmise laiema filtri|järgmiste laiemate filtrite}} tulemustes (tulemuste eristamiseks proovi esiletõstu): $1",
+       "rcfilters-state-message-fullcoverage": "Ühe rühma kõigi filtrite valimine on samaväärne mitte ühegi filtri valimisega, mistõttu ei tee see filter midagi. Rühmas on: $1",
+       "rcfilters-filtergroup-registration": "Registreerumine",
+       "rcfilters-filter-registered-label": "Registreerunud",
+       "rcfilters-filter-registered-description": "Sisse logitud kasutajad.",
+       "rcfilters-filter-unregistered-label": "Registreerumata",
+       "rcfilters-filter-unregistered-description": "Kasutajad, kes pole sisse logitud.",
+       "rcfilters-filter-unregistered-conflicts-user-experience-level": "See filter on konfliktis {{PLURAL:$2|järgmise kogemustaseme filtriga|järgmiste kogemustasemete filtritega}}, mis {{PLURAL:$2|leiab|leiavad}} ainult registreerunud kasutajaid: $1",
+       "rcfilters-filtergroup-authorship": "Kaastöö autorsus",
+       "rcfilters-filter-editsbyself-label": "Enda muudatused",
+       "rcfilters-filter-editsbyself-description": "Sinu enda muudatused.",
+       "rcfilters-filter-editsbyother-label": "Teiste muudatused",
+       "rcfilters-filter-editsbyother-description": "Kõik muudatused peale sinu enda omade.",
+       "rcfilters-filtergroup-userExpLevel": "Kogemustase (ainult registreerunud kasutajate puhul)",
+       "rcfilters-filtergroup-user-experience-level-conflicts-unregistered": "Kogemustaseme filtrid leiavad ainult registreerunud kasutajaid, mistõttu on see filter konfliktis filtriga \"{{int:rcfilters-filter-unregistered-label}}\".",
+       "rcfilters-filtergroup-user-experience-level-conflicts-unregistered-global": "Filter \"{{int:rcfilters-filter-unregistered-label}}\" on konfliktis vähemalt ühe kogemustaseme filtriga, mis leiab ainult registreerunud kasutajaid. Konfliktsed filtrid on ära märgitud ülal aktiivsete filtrite loendis.",
+       "rcfilters-filter-user-experience-level-newcomer-label": "Äsjaalustanud",
+       "rcfilters-filter-user-experience-level-newcomer-description": "Alla 10 muudatuse või tegutsenud alla 4 päeva.",
+       "rcfilters-filter-user-experience-level-learner-label": "Tutvujad",
+       "rcfilters-filter-user-experience-level-learner-description": "Tegutsenud kauem ja teinud rohkem muudatusi kui äsjaalustanud, aga vähem kui kogenud kasutajad.",
+       "rcfilters-filter-user-experience-level-experienced-label": "Kogenud kasutajad",
+       "rcfilters-filter-user-experience-level-experienced-description": "Üle 500 muudatuse ja tegutsenud üle 30 päeva.",
+       "rcfilters-filtergroup-automated": "Automaatne kaastöö",
+       "rcfilters-filter-bots-label": "Robot",
+       "rcfilters-filter-bots-description": "Automaattööriistade tehtud muudatused.",
+       "rcfilters-filter-humans-label": "Pole robot",
+       "rcfilters-filter-humans-description": "Vahetult inimese tehtud muudatused.",
+       "rcfilters-filtergroup-reviewstatus": "Ülevaatuse seis",
+       "rcfilters-filter-patrolled-label": "Kontrollitud",
+       "rcfilters-filter-patrolled-description": "Kontrollituks märgitud muudatused.",
+       "rcfilters-filter-unpatrolled-label": "Kontrollimata",
+       "rcfilters-filter-unpatrolled-description": "Muudatused, mida pole märgitud kontrollituks.",
+       "rcfilters-filtergroup-significance": "Olulisus",
+       "rcfilters-filter-minor-label": "Pisimuudatused",
+       "rcfilters-filter-minor-description": "Muudatused, mille autor märkis pisimuudatuseks.",
+       "rcfilters-filter-major-label": "Pole pisimuudatused",
+       "rcfilters-filter-major-description": "Muudatused, mida pole märgitud pisimuudatuseks.",
+       "rcfilters-filtergroup-watchlist": "Jälgimisloendi leheküljed",
+       "rcfilters-filter-watchlist-watched-label": "Jälgimisloendis",
+       "rcfilters-filter-watchlist-watched-description": "Sinu jälgimisloendi lehekülgedel tehtud muudatused.",
+       "rcfilters-filter-watchlist-watchednew-label": "Jälgimisloendis (uued muudatused)",
+       "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-changetype": "Muudatuse tüüp",
+       "rcfilters-filter-pageedits-label": "Lehekülgede muutmised",
+       "rcfilters-filter-pageedits-description": "Näiteks viki sisu, arutelude ja kategooriate kirjelduste muutmine.",
+       "rcfilters-filter-newpages-label": "Lehekülgede alustamised",
+       "rcfilters-filter-newpages-description": "Muudatused, millega alustati uut lehekülge.",
+       "rcfilters-filter-categorization-label": "Kategooriamuudatused",
+       "rcfilters-filter-categorization-description": "Kirjed lehekülgede kategooriasse lisamise ja kategooriatest eemaldamise kohta.",
+       "rcfilters-filter-logactions-label": "Logitoimingud",
+       "rcfilters-filter-logactions-description": "Näiteks administraatoritoimingud, kontode loomine, lehekülgede kustutamine ja failide üleslaadimine.",
+       "rcfilters-hideminor-conflicts-typeofchange-global": "Filter \"{{int:rcfilters-filter-minor-label}}\" on konfliktis vähemalt ühe muudatuste tüübifiltriga, sest teatud tüüpi muudatusi ei saa märkida pisimuudatusteks. Konfliktsed filtrid on ära märgitud ülal aktiivsete filtrite loendis.",
+       "rcfilters-hideminor-conflicts-typeofchange": "Teatud tüüpi muudatusi ei saa märkida pisimuudatusteks. Seetõttu on see filter konfliktis järgmiste tüübifiltritega: $1",
+       "rcfilters-typeofchange-conflicts-hideminor": "See muudatuste tüübifilter on konfliktis filtriga \"{{int:rcfilters-filter-minor-label}}\". Teatud tüüpi muudatusi ei saa märkida pisimuudatusteks.",
+       "rcfilters-filtergroup-lastRevision": "Viimane redaktsioon",
+       "rcfilters-filter-lastrevision-label": "Viimane redaktsioon",
+       "rcfilters-filter-lastrevision-description": "Muudatus, mis on leheküljel kõige viimane.",
+       "rcfilters-filter-previousrevision-label": "Varasemad redaktsioonid",
+       "rcfilters-filter-previousrevision-description": "Kõik muudatused, mis pole leheküljel kõige viimased.",
        "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",
        "rcshowhideminor": "Pisiparandused ($1)",
        "rcshowhideminor-show": "näita",
        "copyuploaddisabled": "Internetiaadressilt üleslaadimine on keelatud.",
        "uploaddisabledtext": "Faili üleslaadimine on keelatud.",
        "php-uploaddisabledtext": "Failide üleslaadmine on PHP seadetes keelatud.\nPalun vaata <code>file_uploads</code> sätet.",
-       "uploadscripted": "See fail sisaldab HTML- või skriptikoodi, mida veebilehitseja võib valesti kuvada.",
+       "uploadscripted": "See fail sisaldab HTML- või skriptikoodi, mida brauser võib valesti kuvada.",
        "upload-scripted-pi-callback": "Üles ei saa laadida faili, mis sisaldab XML-laadilehe töötluskäsku.",
        "uploaded-script-svg": "Üleslaaditud SVG-failist leiti skriptitav element \"$1\".",
        "uploaded-hostile-svg": "Üleslaaditud SVG-faili laadielemendist leiti ebaturvaline CSS.",
        "booksources-text": "Allpool on linke teistele lehekülgedele, kus müüakse uusi ja kasutatud raamatuid. Lehekülgedel võib olla ka lisainfot raamatute kohta:",
        "booksources-invalid-isbn": "Antud ISBN-number ei ole korrektne; kontrolli algallikast kopeerides vigu.",
        "magiclink-tracking-rfc": "RFC-võlulingiga leheküljed",
+       "magiclink-tracking-rfc-desc": "Sellel leheküljel on RFC-võlulinke. Ülemineku kohta loe saidilt [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Magic_links mediawiki.org].",
        "magiclink-tracking-pmid": "PMID-võlulingiga leheküljed",
+       "magiclink-tracking-pmid-desc": "Sellel leheküljel on PMID-võlulinke. Ülemineku kohta loe saidilt [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Magic_links mediawiki.org].",
        "magiclink-tracking-isbn": "ISBN-võlulingiga leheküljed",
+       "magiclink-tracking-isbn-desc": "Sellel leheküljel on ISBN-võlulinke. Ülemineku kohta loe saidilt [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Magic_links mediawiki.org].",
        "specialloguserlabel": "Täitja:",
        "speciallogtitlelabel": "Objekt (pealkiri või {{ns:user}}:kasutajanimi):",
        "log": "Logid",
        "emailtarget": "Saaja kasutajanime sisestamine",
        "emailusername": "Kasutajanimi:",
        "emailusernamesubmit": "Sobib",
-       "email-legend": "Saada e-kiri {{GRAMMAR:genitive|{{SITENAME}}}} kasutajale",
+       "email-legend": "E-kirja saatmine teisele {{GRAMMAR:genitive|{{SITENAME}}}} kasutajale",
        "emailfrom": "Kellelt:",
        "emailto": "Kellele:",
        "emailsubject": "Teema:",
        "emailmessage": "Sõnum:",
        "emailsend": "Saada",
-       "emailccme": "Saada mulle koopia.",
+       "emailccme": "Saada mulle selle e-kirja koopia",
        "emailccsubject": "Koopia sinu sõnumist kasutajale $1: $2",
        "emailsent": "E-kiri saadetud",
        "emailsenttext": "Sinu teade on e-kirjaga saadetud.",
        "confirmemail_success": "Sinu e-posti aadress on kinnitatud\nVõid nüüd [[Special:UserLogin|sisse logida]].",
        "confirmemail_loggedin": "Sinu e-posti aadress on nüüd kinnitatud.",
        "confirmemail_subject": "{{GRAMMAR:genitive|{{SITENAME}}}} e-posti aadressi kinnitamine",
-       "confirmemail_body": "Keegi IP-aadressilt $1, ilmselt sa ise, registreeris selle e-posti aadressiga {{GRAMMAR:inessive|{{SITENAME}}}} konto \"$2\".\n\nKinnitamaks, et kasutajakonto tõepoolest kuulub sulle ning et aktiveerida e-posti teenused, ava veebilehitsejas järgmine link:\n\n$3\n\nKui sa *pole* kontot registreerinud, ava järgmine link kinnituse tühistamiseks:\n\n$5\n\nKinnituskoodi aegumistähtaeg: $4.",
-       "confirmemail_body_changed": "Keegi IP-aadressilt $1, ilmselt sa ise,\nmuutis {{GRAMMAR:inessive|{{SITENAME}}}} konto \"$2\" e-posti aadressiks selle aadressi.\n\nKinnitamaks, et see konto tõepoolest kuulub sulle ja e-posti teenuste taasaktiveerimiseks, ava oma veebilehitsejas järgmine link:\n\n$3\n\nKui see *pole* sinu konto, ava järgmine link\nkinnituse tühistamiseks:\n\n$5\n\nKinnituskood aegub kuupäeval $4.",
+       "confirmemail_body": "Keegi IP-aadressilt $1, ilmselt sa ise,\nregistreeris selle e-posti aadressiga {{GRAMMAR:inessive|{{SITENAME}}}} konto \"$2\".\n\nKinnitamaks, et kasutajakonto tõepoolest kuulub sulle ning et aktiveerida e-posti teenused, ava brauseris järgmine link:\n\n$3\n\nKui sa *pole* kontot registreerinud, ava järgmine link,\net e-posti aadressi kinnitus tühistada:\n\n$5\n\nKinnituskoodi aegumistähtaeg: $4.",
+       "confirmemail_body_changed": "Keegi IP-aadressilt $1, ilmselt sa ise,\nmuutis {{GRAMMAR:inessive|{{SITENAME}}}} konto \"$2\" e-posti aadressiks selle aadressi.\n\nKinnitamaks, et see konto tõepoolest kuulub sulle ja et e-posti teenused taasaktiveerida, ava brauseris järgmine link:\n\n$3\n\nKui see *pole* sinu konto, ava järgmine link,\net kinnitus tühistada:\n\n$5\n\nKinnituskood aegub kuupäeval $4.",
        "confirmemail_body_set": "Keegi IP-aadressilt $1, arvatavasti sina ise, on {{GRAMMAR:genitive|{{SITENAME}}}} konto \"$2\" e-posti aadressiks määranud selle aadressi.\n\nKinnitamaks, et see konto kuulub tõesti sulle ja et aktiveerida e-posti teenused, ava võrgulehitsejas järgmine link:\n\n$3\n\nKui konto *ei* kuulu sulle, kasuta e-posti aadressi kinnituse tühistamiseks järgmist linki:\n\n$5\n\nSelle kinnituskoodi aegumistähtaeg on $4.",
        "confirmemail_invalidated": "E-posti aadressi kinnitamine tühistati",
        "invalidateemail": "E-posti aadressi kinnituse tühistamine",
        "confirmrecreate": "Kasutaja [[User:$1|$1]] ([[User talk:$1|arutelu]]) kustutas lehekülje sellel ajal, kui sina seda redigeerisid. Põhjus:\n: ''$2''\nPalun kinnita, et soovid tõesti selle lehekülje taasluua.",
        "confirmrecreate-noreason": "Kasutaja [[User:$1|$1]] ([[User talk:$1|arutelu]]) kustutas selle lehekülje, pärast seda kui redigeerimist alustasid. Palun kinnita, et tahad tõesti selle lehekülje uuesti luua.",
        "recreate": "Loo uuesti",
+       "confirm-purge-title": "Lehekülje vahemälu tühjendamine",
        "confirm_purge_button": "Sobib",
        "confirm-purge-top": "Tühjenda selle lehekülje vahemälu?",
        "confirm-purge-bottom": "Toiming puhastab lehekülje vahemälu ja kuvab uusima versiooni.",
        "logentry-delete-delete": "$1 {{GENDER:$2|kustutas}} lehekülje $3",
        "logentry-delete-delete_redir": "$1 {{GENDER:$2|kustutas}} ülekirjutamise teel ümbersuunamise $3",
        "logentry-delete-restore": "$1 {{GENDER:$2|taastas}} lehekülje $3 ($4)",
+       "logentry-delete-restore-nocount": "$1 {{GENDER:$2|taastas}} lehekülje $3",
        "restore-count-revisions": "{{PLURAL:$1|üks redaktsioon|$1 redaktsiooni}}",
        "restore-count-files": "{{PLURAL:$1|üks fail|$1 faili}}",
        "logentry-delete-event": "$1 {{GENDER:$2|muutis}} leheküljel $3 {{PLURAL:$5|ühe|$5}} logisündmuse nähtavust: $4",
        "feedback-message": "Sõnum:",
        "feedback-subject": "Teema:",
        "feedback-submit": "Saada",
-       "feedback-terms": "Mõistan, et minu kasutajaagendi andmed sisaldavad teavet minu veebilehitseja ja operatsioonisüsteemi täpse versiooni kohta ning need andmed tehakse minu tagasiside juures avalikuks.",
+       "feedback-terms": "Mõistan, et minu kasutajaagendi andmed sisaldavad teavet minu brauseri ja operatsioonisüsteemi täpse versiooni kohta ning need andmed tehakse minu tagasiside juures avalikuks.",
        "feedback-termsofuse": "Olen nõus andma tagasisidet vastavalt kasutustingimustele.",
        "feedback-thanks": "Aitäh! Sinu tagasiside on postitatud leheküljele \"[$2 $1]\".",
        "feedback-thanks-title": "Aitäh!",
        "special-characters-group-thai": "Tai",
        "special-characters-group-lao": "Lao",
        "special-characters-group-khmer": "Khmeeri",
+       "special-characters-group-canadianaboriginal": "Silpmärgid (Kanada)",
        "special-characters-title-endash": "mõttekriips",
        "special-characters-title-emdash": "pikk mõttekriips",
        "special-characters-title-minus": "miinusmärk",
index 3c4892b..942e935 100644 (file)
        "search-category": "($1 kategoria)",
        "search-file-match": "(fitxategiaren edukiarekin bat dator)",
        "search-suggest": "$1 esan nahi zenuen",
+       "search-rewritten": "\"$1\" bilaketaren emaitzak erakusten. Bestela, bila ezazu \"$2\".",
        "search-interwiki-caption": "Beste proiektuak",
        "search-interwiki-default": "$1(r)en emaitzak:",
        "search-interwiki-more": "(gehiago)",
        "userrights-nodatabase": "$1 datubasea ez da existitzen edo ez dago lokalki.",
        "userrights-changeable-col": "Alda ditzakezun taldeak",
        "userrights-unchangeable-col": "Aldatu ezin ditzakezun taldeak",
+       "userrights-expiry-none": "Ez da iraungitzen",
        "userrights-expiry-options": "Egun 1:Egun 1,Aste 1:Aste 1,Hilabete 1:Hilabete 1,3 hilabete:3 hilabete,6 hilabete:6 hilabete,Urte 1:Urte 1",
        "userrights-conflict": "Gatazka gertatu da erabiltzaile eskubideak aldatzean. Mesedez, berrikusi eta baieztatu zure aldaketak.",
        "group": "Taldea:",
        "rcfilters-filtergroup-significance": "Munta",
        "rcfilters-filter-minor-label": "Aldaketa txikiak",
        "rcfilters-filter-major-label": "Aldaketa ez Txikiak",
+       "rcfilters-filter-watchlist-watched-label": "Jarraipen-zerrendan",
        "rcfilters-filtergroup-changetype": "Aldaketa mota",
        "rcfilters-filter-pageedits-label": "Orrialde aldaketak",
        "rcfilters-filter-newpages-label": "Orrialde berriak",
        "uploaddisabledtext": "Fitxategiak igotzea ezgaituta dago.",
        "php-uploaddisabledtext": "Fitxategi igoerak PHP-n ezinduta daude. Ikusi fitxategi_igoerak mesedez.",
        "uploadscripted": "Fitxategi honek web zerbitzariak modu ezegokian interpretatu lezakeen HTML edo script kodea dauka.",
+       "uploadinvalidxml": "Ezin izan da analizatu XMLa igotako fitxategian.",
        "uploadvirus": "Fitxategiak birusa dauka! Xehetasunak: $1",
        "uploadjava": "Fitxategia ZIP bat da eta Java .class fitxategi bat du.\nJava fitxategiak igotzea ez dago baimendua, segurtasun muga batzuk hausteko aukera ematen duelako.",
        "upload-source": "Jatorrizko fitxategia",
        "apihelp": "API laguntza",
        "apihelp-no-such-module": "Ez da \"$1\" modulua aurkitu.",
        "apisandbox": "API proba orria",
+       "apisandbox-fullscreen": "Zabaldu panela",
        "apisandbox-unfullscreen": "Erakutsi orria",
        "apisandbox-submit": "Egin eskaera",
        "apisandbox-reset": "Garbitu",
        "apisandbox-retry": "Saiatu berriro",
+       "apisandbox-no-parameters": "API modulu honek ez du parametrorik.",
        "apisandbox-helpurls": "Laguntza estekak",
        "apisandbox-examples": "Adibideak",
        "apisandbox-dynamic-parameters": "Parametro gehigarriak",
        "apisandbox-dynamic-parameters-add-placeholder": "Parametroaren izena",
        "apisandbox-dynamic-error-exists": "$1 parametro izena dagoeneko existitzen da",
        "apisandbox-results": "Emaitzak",
+       "apisandbox-sending-request": "APIari eskaera bidaltzen...",
+       "apisandbox-loading-results": "APIaren emaitzak jasotzen...",
        "apisandbox-continue": "Jarraitu",
        "apisandbox-continue-clear": "Garbitu",
+       "apisandbox-multivalue-all-values": "$1 (balio guztiak)",
        "booksources": "Iturri liburuak",
        "booksources-search-legend": "Liburuen bilaketa",
        "booksources-search": "Bilatu",
        "booksources-text": "Jarraian liburu berri eta erabiliak saltzen dituzten guneetarako loturen zerrenda bat ikus dezakezu, bilatzen ari zaren liburu horientzako informazio gehigarria aurkitzeko lagungarria izan daitekeena:",
        "booksources-invalid-isbn": "Badirudi emandako ISBNa ez dela baliagarria; egiazta ezazu ea akatsik egin duzun jatorrizko iturritik kopiatzean.",
+       "magiclink-tracking-rfc": "RFC lotura magikoak dituzten orrialdeak",
+       "magiclink-tracking-pmid": "PMID lotura magikoak dituzten orrialdeak",
+       "magiclink-tracking-isbn": "ISBN lotura magikoak dituzten orrialdeak",
        "specialloguserlabel": "Egilea:",
        "speciallogtitlelabel": "Helburua (izenburua edo {{ns:user}}: lankidea):",
        "log": "Erregistroak",
        "checkbox-select": "Aukeratu:$1",
        "checkbox-all": "Denak",
        "checkbox-none": "Bat ere ez",
+       "checkbox-invert": "Alderantzikatu",
        "allpages": "Orri guztiak",
        "nextpage": "Hurrengo orrialdea ($1)",
        "prevpage": "Aurreko orrialdea ($1)",
        "export-download": "Gorde fitxategitzat",
        "export-templates": "Txantiloiak barneratu",
        "export-pagelinks": "Sartu lotutako orriak honako sakoneran:",
+       "export-manual": "Gehitu orrialdeak eskuz:",
        "allmessages": "Sistemako mezu guztiak",
        "allmessagesname": "Izena",
        "allmessagesdefault": "Testu lehenetsia",
        "pageinfo-length": "Orriaren neurria (byteak)",
        "pageinfo-article-id": "Orriaren identifikazio zenbakia",
        "pageinfo-language": "Orriaren edukiaren hizkuntza",
+       "pageinfo-language-change": "aldatu",
        "pageinfo-content-model": "Orrialde edukiaren eredua",
+       "pageinfo-content-model-change": "aldatu",
        "pageinfo-robot-policy": "Errobotak indexatzea egiten",
        "pageinfo-robot-index": "Baimendua",
        "pageinfo-robot-noindex": "Debekatua",
        "confirmemail_body": "Norbaitek, ziurrenik zuk $1 IP helbidetik, \"$2\" kontua erregistratu du {{SITENAME}}(e)n e-posta helbide honekin.\n\nIzen hori zuri dagokizula eta {{SITENAME}}(e)n zure e-posta egiaztatzeko, hurrengo lotura hau zure nabigatzailean ireki behar duzu:\n\n$3\n\nZu *ez* bazara, ez jo lotura horretara, jarraitu beste lotura hau e-posta bidezko helbide egiaztatzea ezeztatzeko:\n\n$5\n\nEgiaztapen kode hau $4 iraungiko da.",
        "confirmemail_invalidated": "E-mail bidezko ziurtatzea kantzelatu da",
        "invalidateemail": "E-mail bidezko ziurtatzea deuseztu",
+       "notificationemail_body_changed": "Norbaitek, beharbada zuk, $1 IP helbidetik, kontuari lotutako helbide elektronikoa aldatu du \"$2\"-tik \"$3\"-ra {{SITENAME}} gunean.\n\nZu izan ez bazara, jar zaitez berehala harremanetan guneko administratzaile batekin.",
+       "notificationemail_body_removed": "Norbaitek, beharbada zuk, $1 IP helbidetik, kontuari lotutako \"$2\" helbide elektronikoa ezabatu du {{SITENAME}} gunean.\n\nZu izan ez bazara, jar zaitez berehala harremanetan guneko administratzaile batekin.",
        "scarytranscludedisabled": "[Interwikien transklusioa ezgaituta dago]",
        "scarytranscludefailed": "[Arazoa $1 txantiloia eskuratzerakoan]",
        "scarytranscludetoolong": "[URLa luzeegia da]",
        "tags-active-yes": "Bai",
        "tags-active-no": "Ez",
        "tags-source-extension": "Softwareak definitua",
+       "tags-source-manual": "Erabiltzaileek eta botek eskuz ezarrita",
        "tags-source-none": "Ez da gehiago erabiltzen",
        "tags-edit": "aldatu",
        "tags-delete": "ezabatu",
        "tags-edit-remove-all-tags": "(kendu etiketa guztiak)",
        "tags-edit-chosen-placeholder": "Hautatu etiketa batzuk",
        "tags-edit-reason": "Arrazoia:",
+       "tags-edit-success": "Aldaketak ezarri dira.",
+       "tags-edit-failure": "Ezin izan dira aldaketak ezarri:\n$1",
        "comparepages": "Orrialdeak alderatu",
        "compare-page1": "1. orrialdea",
        "compare-page2": "2. orrialdea",
        "logentry-block-reblock": "$1 administratzaileak {{GENDER:$4|$3}} wikilariaren blokeoa {{GENDER:$2|aldatu du}}. Blokeoaldia: $5 $6",
        "logentry-suppress-block": "$1 {{GENDER:$2|administratzaileak}} {{GENDER:$4|$3}} blokeatu du. Iraupena: $5 $6",
        "logentry-suppress-reblock": "$1 administratzaileak {{GENDER:$4|$3}} wikilariaren blokeoa {{GENDER:$2|aldatu du}}. Blokeoaldia: $5 $6",
+       "logentry-import-upload": "$1(e)k $3 {{GENDER:$2|inportatu du}} fitxategi-igoera bidez",
        "logentry-move-move": "$1 {{GENDER:$2|wikilariak}} «$3» orria «$4» izenera aldatu du",
        "logentry-move-move-noredirect": "$1 {{GENDER:$2|wikilariak}} «$3» orria «$4» izenera aldatu du, birzuzenketarik utzi gabe",
        "logentry-move-move_redir": "$1 {{GENDER:$2|wikilariak}} «$3» orria «$4» izenera aldatu du, birzuzenketaren gainetik",
        "logentry-newusers-byemail": "$1(e)k $3 erabiltzaile kontua {{GENDER:$2|sortu du}} eta pasahitza emailez bidali da",
        "logentry-newusers-autocreate": "$1 erabiltzaile kontua automatikoki {{GENDER:$2|sortu da}}",
        "logentry-upload-upload": "$1(e)k $3 {{GENDER:$2|igo du}}",
+       "logentry-upload-overwrite": "$1(e)k $3(r)en bertsio berria {{GENDER:$2|igo du}}",
+       "logentry-upload-revert": "$1(e)k $3 {{GENDER:$2|igo du}}",
        "logentry-managetags-create": "$1 lankideak \"$4\" etiketa {{GENDER:$2|sortu du}}",
        "log-name-tag": "Etiketen erregistroa",
        "rightsnone": "(bat ere ez)",
        "log-action-filter-managetags-delete": "Etiketa ezabaketa",
        "log-action-filter-managetags-activate": "Etiketa aktibazioa",
        "log-action-filter-managetags-deactivate": "Etiketa desaktibazioa",
+       "log-action-filter-newusers-autocreate": "Sorrera automatikoa",
+       "log-action-filter-protect-protect": "Babesa",
        "log-action-filter-rights-rights": "Eskuzko aldaketa",
        "log-action-filter-rights-autopromote": "Aldaketa automatikoa",
        "log-action-filter-upload-upload": "Igoera berria",
index 970d656..b855c2e 100644 (file)
        "preview": "Esikatselu",
        "showpreview": "Esikatsele",
        "showdiff": "Näytä muutokset",
-       "blankarticle": "<strong>Varoitus:</strong> Sivu, jota olet luomassa, on tyhjä.\nJos napsautat \"$1\" uudelleen, sivu luodaan ilman sisältöä.",
+       "blankarticle": "<strong>Varoitus:</strong> Sivu, jota olet luomassa on tyhjä.\nJos napsautat \"$1\" uudelleen, sivu luodaan ilman sisältöä.",
        "anoneditwarning": "<strong>Varoitus:</strong> Et ole kirjautunut sisään. IP-osoitteesi näkyy julkisesti kaikille, jos muokkaat. Jos <strong>[$1 kirjaudut sisään]</strong> tai <strong>[$2 luot tunnuksen]</strong>, muokkauksesi kirjataan käyttäjätunnuksesi tekemiksi ja samalla saat käyttöösi hyödyllisiä välineitä.",
        "anonpreviewwarning": "''Et ole kirjautunut sisään. Tallentaminen kirjaa IP-osoitteesi tämän sivun muutoshistoriaan.''",
        "missingsummary": "Et ole antanut yhteenvetoa. Jos valitset Tallenna uudelleen, niin muokkauksesi tallennetaan ilman yhteenvetoa.",
        "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 seuraaviin laajempiin suodattimiin (kokeile korostusta sen erottamiseksi): $1",
-       "rcfilters-state-message-fullcoverage": "Ryhmän kaikkien suodattimien valitseminen on sama, kuin ei valitse mitään. Ryhmään sisältyy: $ 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-filtergroup-registration": "Käyttäjän rekisteröinti",
        "rcfilters-filter-registered-label": "Rekisteröitynyt",
        "rcfilters-filter-registered-description": "Sisäänkirjautuneiden muokkaukset.",
        "rcfilters-filter-unregistered-label": "Rekisteröimätön",
        "rcfilters-filter-unregistered-description": "Muokkaajat, jotka eivät ole kirjautuneet sisään.",
-       "rcfilters-filter-unregistered-conflicts-user-experience-level": "Tämä suodatin on ristiriidassa seuraavien kokemustaso suodattimien kanssa, jotka löytävät vain rekisteröityneitä käyttäjiä: $1",
-       "rcfilters-filtergroup-authorship": "Muokkausten tekijä",
-       "rcfilters-filter-editsbyself-label": "Omat muokkauksesi",
-       "rcfilters-filter-editsbyself-description": "Itse tekemäsi muokkaukset.",
-       "rcfilters-filter-editsbyother-label": "Muiden muokkaukset",
-       "rcfilters-filter-editsbyother-description": "Muiden käyttäjien tekemät muokkaukset.",
+       "rcfilters-filter-unregistered-conflicts-user-experience-level": "Tämä suodatin on ristiriidassa seuraavien kokemustaso {{PLURAL:$2|suodattimen|suodattimien}} kanssa,  {{PLURAL:$2|joka|jotka}} löytävät vain rekisteröityneitä käyttäjiä: $1",
+       "rcfilters-filtergroup-authorship": "Muutoksen tekijä",
+       "rcfilters-filter-editsbyself-label": "Muutoksesi",
+       "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-filtergroup-userExpLevel": "Kokemustaso (vain rekisteröityneet käyttäjät)",
        "rcfilters-filtergroup-user-experience-level-conflicts-unregistered": "Kokemustaso suodattimet löytävät vain rekisteröityneitä käyttäjiä, joten tämä suodatin on ristiriidassa \"Rekisteröimätön\" -suodattimen kanssa.",
        "rcfilters-filtergroup-user-experience-level-conflicts-unregistered-global": "\"Rekisteröimätön\" -suodatin on ristiriidassa yhden tai useamman kokemustaso suodattimen kanssa, joka löytää vain rekisteröityneitä käyttäjiä.  Ristiriidassa oleva suodatin on merkittynä Aktiivisissa suodattimissa, yläpuolella.",
        "rcfilters-filter-minor-description": "Muokkaukset, jotka on merkitty pieniksi.",
        "rcfilters-filter-major-label": "Ei-pienet muutokset",
        "rcfilters-filter-major-description": "Muokkaukset joita ei ole merkitty pieniksi.",
+       "rcfilters-filtergroup-watchlist": "Tarkkailulistalla olevat sivut",
+       "rcfilters-filter-watchlist-watched-label": "Tarkkailulistalla",
+       "rcfilters-filter-watchlist-watched-description": "Muutokset tarkkailulistalla oleviin sivuihin.",
+       "rcfilters-filter-watchlist-notwatched-label": "Ei tarkkailulistalla",
        "rcfilters-filtergroup-changetype": "Muutoksen tyyppi",
        "rcfilters-filter-pageedits-label": "Sivun muokkaukset",
        "rcfilters-filter-pageedits-description": "Muokkaukset wikin sisältöön, keskusteluihin, luokkakuvauksiin....",
        "rcfilters-filter-newpages-label": "Sivujen luonnit",
-       "rcfilters-filter-newpages-description": "Muokkaukset jotka luovat uusia sivuja.",
+       "rcfilters-filter-newpages-description": "Muokkaukset joilla on luotu uusia sivuja.",
        "rcfilters-filter-categorization-label": "Luokkamuutokset",
-       "rcfilters-filter-categorization-description": "Tulokset sivuista joita on lisätty, tai poistettu luokista.",
+       "rcfilters-filter-categorization-description": "Tulokset sivuista, joita on lisätty tai poistettu luokista.",
        "rcfilters-filter-logactions-label": "Kirjatut toimet",
        "rcfilters-filter-logactions-description": "Hallinnolliset toimet, tunnusten luonnit, sivujen poistot, tiedostojen lähetykset...",
        "rcfilters-hideminor-conflicts-typeofchange-global": "\"Pienet muutokset\" -suodatin on ristiriidassa yhden tai useamman Muutoksen tyyppi suodattimen kanssa, koska joitain muutostyyppejä ei voida pitää \"pieninä\". Ristiriidassa oleva suodatin on merkittynä Aktiivisissa suodattimissa, yläpuolella.",
        "rcfilters-hideminor-conflicts-typeofchange": "Joitain muutostyyppejä ei voida määrittää \"pieneksi\", joten tämä suodatin on ristiriidassa seuraavien Muutoksen tyyppi suodattimien kanssa: $1",
        "rcfilters-typeofchange-conflicts-hideminor": "\"Muutoksen tyyppi\" on ristiriidassa \"Pienet muutokset\" -suodattimen kanssa. Joitain muutostyyppejä ei voida merkitä \"pieniksi\".",
+       "rcfilters-filtergroup-lastRevision": "Viimeisin versio",
+       "rcfilters-filter-lastrevision-label": "Viimeisin versio",
+       "rcfilters-filter-previousrevision-label": "Aikaisemman versiot",
        "rcnotefrom": "Alla ovat muutokset <strong>$3, $4</strong> lähtien. (Enintään <strong>$1</strong> näytetään.)",
        "rclistfrom": "Näytä uudet muutokset $3 kello $2 alkaen",
        "rcshowhideminor": "$1 pienet muutokset",
        "rcshowhidecategorization": "$1 sivujen luokkien muutokset",
        "rcshowhidecategorization-show": "Näytä",
        "rcshowhidecategorization-hide": "Piilota",
-       "rclinks": "Näytä $1 tuoretta muutosta viimeisten $2 päivän ajalta.",
+       "rclinks": "Näytä $1 muutosta viimeisten $2 päivän ajalta.",
        "diff": "ero",
        "hist": "historia",
        "hide": "Piilota",
        "enotif_body_intro_moved": "{{GENDER:$2|$2}} siirsi {{GRAMMAR:inessive|{{SITENAME}}}} sivun $1 $PAGEEDITDATE. Sivun nykyinen versio on osoitteessa $3.",
        "enotif_body_intro_restored": "{{GENDER:$2|$2}} palautti {{GRAMMAR:inessive|{{SITENAME}}}} sivun $1 $PAGEEDITDATE. Sivun nykyinen versio on osoitteessa $3.",
        "enotif_body_intro_changed": "{{GENDER:$2|$2}} muutti {{GRAMMAR:inessive|{{SITENAME}}}} sivua $1 $PAGEEDITDATE. Sivun nykyinen versio on osoitteessa $3.",
-       "enotif_lastvisited": "Osoitteessa $1 on kaikki muutokset viimeisen käyntisi jälkeen.",
+       "enotif_lastvisited": "Kaikki muutokset viimeisimmän vierailusi jälkeen näet täältä $1",
        "enotif_lastdiff": "Muutos on osoitteessa $1.",
        "enotif_anon_editor": "kirjautumaton käyttäjä $1",
        "enotif_body": "$WATCHINGUSERNAME,\n\n$PAGEINTRO $NEWPAGE\n\nMuokkaajan yhteenveto: $PAGESUMMARY $PAGEMINOREDIT\n\nOta yhteyttä muokkaajaan:\nsähköposti: $PAGEEDITOR_EMAIL\nwiki: $PAGEEDITOR_WIKI\n\nUusia ilmoituksia tästä sivusta ei tule kunnes vierailet sivulla sisään kirjautuneena. Voit myös nollata ilmoitukset kaikille tarkkailemillesi sivuille tarkkailulistallasi.\n\n             {{GRAMMAR:genitive|{{SITENAME}}}} ilmoitusjärjestelmä\n\n--\nVoit muuttaa sähköpostimuistutusten asetuksia osoitteessa:\n{{canonicalurl:{{#special:Preferences}}}}\n\nVoit muuttaa tarkkailulistasi asetuksia osoitteessa:\n{{canonicalurl:{{#special:EditWatchlist}}}}\n\nVoit poistaa sivun tarkkailulistalta osoitteessa:\n$UNWATCHURL\n\nPalaute ja lisäapu osoitteessa:\n$HELPPAGE",
        "confirmrecreate-noreason": "Käyttäjä [[User:$1|$1]] ([[User talk:$1|keskustelu]]) {{GENDER:$1|on poistanut}} tämän sivun sen jälkeen, kun aloit muokata. Varmista, että haluat tosiaan luoda sivun uudelleen.",
        "recreate": "Luo uudelleen",
        "unit-pixel": " px",
+       "confirm-purge-title": "Tyhjennä välimuistista",
        "confirm_purge_button": "Poista",
        "confirm-purge-top": "Poistetaanko tämän sivun välimuistikopiot?",
        "confirm-purge-bottom": "Välimuistikopioiden poistaminen tyhjentää välimuistin ja pakottaa sivun uusimman version näkyviin.",
        "logentry-import-upload": "$1 {{GENDER:$2|on tuonut}} kohteen $3 tiedostotallennuksella",
        "logentry-import-upload-details": "$1 {{GENDER:$2|on tuonut}} kohteen $3 tiedostotallennuksella ($4 {{PLURAL:$4|versio|versiota}})",
        "logentry-import-interwiki": "$1 {{GENDER:$2|on tuonut}} kohteen $3 muusta wikistä",
-       "logentry-import-interwiki-details": "$1 {{GENDER:$2|on tuonut}} kohteen $3 paikasta $5 ($4 {{PLURAL:$4|versio|versioita}})",
+       "logentry-import-interwiki-details": "$1 {{GENDER:$2|on tuonut}} kohteen $3 paikasta $5 ($4 {{PLURAL:$4|versio|versiota}})",
        "logentry-merge-merge": "$1 {{GENDER:$2|yhdisti}} sivun $3 sivuun $4 (versiot $5 saakka)",
        "logentry-move-move": "$1 {{GENDER:$2|siirsi}} sivun $3 uudelle nimelle $4",
        "logentry-move-move-noredirect": "$1 {{GENDER:$2|siirsi}} sivun $3 uudelle nimelle $4 luomatta ohjausta",
index e86f368..6e8d3d4 100644 (file)
        "anoneditwarning": "<strong>Attention :</strong> vous n’êtes pas connecté. Votre adresse IP sera visible de tout le monde si vous faites des modifications. Si vous <strong>[$1 vous connectez]</strong> ou <strong>[$2 créez un compte]</strong>, vos modifications seront attribuées à votre nom d’utilisateur, avec d'autres avantages.",
        "anonpreviewwarning": "<em>Vous n’êtes pas connecté{{GENDER:||e}}. Sauvegarder enregistrera votre adresse IP dans l’historique des modifications de la page.</em>",
        "missingsummary": "<strong>Rappel :</strong> vous n’avez pas encore fourni le résumé de votre modification.\nSi vous cliquez de nouveau sur le bouton « $1 », vos modifications seront sauvegardées sans résumé.",
-       "selfredirect": "<strong>Attention :</strong> vous êtes en train de rediriger la page vers elle-même.\nVous pouvez avoir spécifié la mauvaise cible pour la redirection, ou vous modifiez peut-être la mauvaise page.\nSi vous cliquez de nouveau sur « $1 », la redirection sera tout de même créée.",
+       "selfredirect": "<strong>Attention :</strong> vous êtes en train de rediriger la page vers elle-même.\nIl se peut que vous ayez spécifié la mauvaise cible pour la redirection, ou que vous modifiez peut-être la mauvaise page.\nSi vous cliquez de nouveau sur « $1 », la redirection sera tout de même créée.",
        "missingcommenttext": "Veuillez entrer un commentaire ci-dessous.",
        "missingcommentheader": "<strong>Rappel :</strong> vous n’avez pas fourni de sujet pour ce commentaire.\nSi vous cliquez de nouveau sur « {{int:Savearticle}} », votre modification sera enregistrée sans sujet.",
        "summary-preview": "Aperçu du résumé de modification :",
        "rcfilters-filter-minor-description": "Modifications que l’auteur a marquées comme mineures.",
        "rcfilters-filter-major-label": "Modifications non mineures",
        "rcfilters-filter-major-description": "Modifications non marquées comme mineures.",
+       "rcfilters-filtergroup-watchlist": "Pages de la liste de suivi",
+       "rcfilters-filter-watchlist-watched-label": "Sur la liste de suivi",
+       "rcfilters-filter-watchlist-watched-description": "Pages de votre liste de suivi modifiées.",
+       "rcfilters-filter-watchlist-watchednew-label": "Nouvelles modifications de la liste de suivi",
+       "rcfilters-filter-watchlist-watchednew-description": "Changements sur les pages de la liste de suivi que vous n'avez pas consultées depuis que ces modifications ont été faites.",
+       "rcfilters-filter-watchlist-notwatched-label": "Absent de la liste de suivi",
+       "rcfilters-filter-watchlist-notwatched-description": "Tout sauf des modifications de pages de la liste de suivi.",
        "rcfilters-filtergroup-changetype": "Type de modification",
        "rcfilters-filter-pageedits-label": "Modifications de page",
        "rcfilters-filter-pageedits-description": "Modifications du contenu du wiki, des discussions, des descriptions des catégories…",
index c07cf17..b9e588e 100644 (file)
        "rcfilters-filtergroup-watchlist": "Páxinas vixiadas",
        "rcfilters-filter-watchlist-watched-label": "Na lista de vixilancia",
        "rcfilters-filter-watchlist-watched-description": "Cambios a páxinas na súa lista de vixilancia.",
+       "rcfilters-filter-watchlist-watchednew-label": "Cambios novos na súa lista de vixilancia",
+       "rcfilters-filter-watchlist-watchednew-description": "Cambios nas páxinas da súa lista de vixilancia que non visitou dende que se produciron os cambios.",
+       "rcfilters-filter-watchlist-notwatched-label": "Ausente da lista de vixilancia",
+       "rcfilters-filter-watchlist-notwatched-description": "Todos, excepto os cambios nas páxinas da súa lista de vixilancia.",
        "rcfilters-filtergroup-changetype": "Tipo de cambio",
        "rcfilters-filter-pageedits-label": "Edicións de páxinas",
        "rcfilters-filter-pageedits-description": "Edicións do contido da wiki, de conversas, de descricións de categorías...",
        "rcfilters-filter-lastrevision-label": "Versión actual",
        "rcfilters-filter-lastrevision-description": "A última modificación a unha páxina.",
        "rcfilters-filter-previousrevision-label": "Versións anteriores",
+       "rcfilters-filter-previousrevision-description": "Tódolos cambios realizados nunha páxina e que non son os máis recentes.",
        "rcnotefrom": "A continuación {{PLURAL:$5|móstrase o cambio feito|móstranse os cambios feitos}} desde o <strong>$3</strong> ás <strong>$4</strong> (móstranse <strong>$1</strong> como máximo).",
        "rclistfromreset": "Reinicializar a selección da data",
        "rclistfrom": "Mostrar os cambios novos desde o $3 ás $2",
index 9037de1..30d040e 100644 (file)
        "rcfilters-filter-user-experience-level-newcomer-label": "חדשים",
        "rcfilters-filter-user-experience-level-newcomer-description": "פחות מ־10 עריכות ומ־4 ימים של פעילות.",
        "rcfilters-filter-user-experience-level-learner-label": "לומדים",
-       "rcfilters-filter-user-experience-level-learner-description": "×\99×\95תר ×\99×\9e×\99 ×¤×¢×\99×\9c×\95ת ×\95ער×\99×\9b×\95ת מ\"חדשים\", אבל פחות מ\"משתמשים מנוסים\".",
+       "rcfilters-filter-user-experience-level-learner-description": "×\99×\95תר × ×\99ס×\99×\95×\9f מ\"חדשים\", אבל פחות מ\"משתמשים מנוסים\".",
        "rcfilters-filter-user-experience-level-experienced-label": "משתמשים מנוסים",
        "rcfilters-filter-user-experience-level-experienced-description": "יותר מ־30 ימים של פעילות ו־500 עריכות.",
        "rcfilters-filtergroup-automated": "תרומות אוטומטיות",
        "log": "יומנים",
        "logeventslist-submit": "הצגה",
        "all-logs-page": "כל היומנים הציבוריים",
-       "alllogstext": "זוהי תצוגה משולבת של כל סוגי היומנים הזמינים ב{{grammar:תחילית|{{SITENAME}}}}.\nניתן לצמצם את התצוגה על ידי בחירת סוג היומן, שם המשתמש (תלוי רישיות) או הדף המושפע (גם כן תלוי רישיות).",
+       "alllogstext": "זוהי תצוגה משולבת של כל סוגי היומנים הזמינים ב{{grammar:תחילית|{{SITENAME}}}}.\nניתן לצמצם את התצוגה על־ידי בחירת סוג היומן, שם המשתמש (תלוי רישיות) או הדף המושפע (גם כן תלוי רישיות).",
        "logempty": "אין פריטים תואמים ביומן.",
        "log-title-wildcard": "חיפוש כותרות המתחילות באותיות אלה",
        "showhideselectedlogentries": "שינוי מצב התצוגה של פעולות היומן שנבחרו",
index 78927a8..0146cf1 100644 (file)
        "botpasswords-label-delete": "हटाएँ",
        "botpasswords-label-resetpassword": "पासवर्ड पुनः तय करें",
        "botpasswords-label-grants": "अनुदान आवेदन:",
-       "botpasswords-help-grants": "हर à¤\85नà¥\81दान à¤\9cà¥\8b à¤¸à¤¦à¤¸à¥\8dय à¤\85धिà¤\95ार à¤®à¥\87à¤\82  à¤ªà¤¹à¤²à¥\87 à¤¸à¥\87 à¤\86ता à¤¹à¥\88, à¤\89सà¥\87 à¤\85धिà¤\95ार à¤¤à¤\95 à¤ªà¤¹à¥\81à¤\81à¤\9a à¤¦à¥\87ता à¤¹à¥\88।  à¤¦à¥\87à¤\96à¥\87à¤\82 : [[Special:ListGrants|à¤\85नà¥\81दान à¤¸à¤¾à¤°à¤£à¥\80]]",
+       "botpasswords-help-grants": "à¤\85नà¥\81दान à¤\86पà¤\95à¥\8b à¤\85धिà¤\95ारà¥\8bà¤\82 à¤¤à¤\95 à¤ªà¤¹à¥\81à¤\81à¤\9aनà¥\87 à¤¦à¥\87ता à¤¹à¥\88, à¤\9cà¥\8b à¤\86पà¤\95à¥\87 à¤\96ातà¥\87 à¤\95à¥\87 à¤ªà¤¾à¤¸ à¤ªà¤¹à¤²à¥\87 à¤¸à¥\87 à¤¹à¥\88। à¤\85नà¥\81दान à¤\95à¥\8b à¤¸à¤\95à¥\8dरिय à¤\95रनà¥\87 à¤¸à¥\87 à¤\95à¥\8bà¤\88 à¤\85धिà¤\95ार à¤ªà¥\8dरापà¥\8dत à¤¨à¤¹à¥\80à¤\82 à¤¹à¥\8bà¤\97ा, à¤\9cà¥\8b à¤\86पà¤\95à¥\87 à¤\96ातà¥\87 à¤®à¥\87à¤\82 à¤¨ à¤¹à¥\8b। à¤\85धिà¤\95 à¤\9cानà¤\95ारà¥\80 à¤\95à¥\87 à¤²à¤¿à¤\8f [[Special:ListGrants|à¤\85नà¥\81दान à¤¸à¤¾à¤°à¤£à¥\80]] à¤¦à¥\87à¤\96à¥\87à¤\82।",
        "botpasswords-label-grants-column": "प्रदान किया",
        "botpasswords-bad-appid": "बॉट नाम \"$1\" मान्य नहीं है।",
        "botpasswords-insert-failed": "बॉट नाम \"$1\" को जोड़ने में विफल हुआ। क्या यह पहले से है?",
        "botpasswords-updated-body": "सदस्य \"$2\" के बॉट नाम \"$1\" का पासवर्ड सफलतापूर्वक अद्यतन हुआ।",
        "botpasswords-deleted-title": "बॉट पासवर्ड हट गया",
        "botpasswords-deleted-body": "सदस्य \"$2\" के बॉट नाम \"$1\" का पासवर्ड हट गया।",
-       "botpasswords-newpassword": "आपका नया पासवर्ड आपके प्रवेश <strong>$1</strong> के साथ <strong>$2</strong> है। <em>भविष्य में उपयोग करने हेतु इसे याद रखें</em>",
+       "botpasswords-newpassword": "<strong>$1</strong> के साथ लॉगिन करने के लिए आपका नया पासवर्ड <strong>$2</strong> है। <em>भविष्य के लिए इसे याद रखें</em> <br> (पुराने बॉट के लिए लॉगिन नाम और बॉट का सदस्य नाम समान चाहिए होता है, तो आप <strong>$3</strong> का उपयोग अपने सदस्य नाम के रूप में और <strong>$4</strong> का उपयोग अपने पासवर्ड के रूप में कर सकते हैं।)",
        "botpasswords-no-provider": "BotPasswordsSessionProvider उपलब्ध नहीं है।",
        "botpasswords-restriction-failed": "इस प्रवेश में बॉट पासवर्ड रुकावट डाल रहा है।",
        "botpasswords-invalid-name": "जो सदस्य नाम आप बता रहे हो, उसमें बॉट पासवर्ड अलग करने वाला (\"$1\") नहीं है।",
        "preview": "झलक",
        "showpreview": "झलक दिखाएँ",
        "showdiff": "बदलाव दिखाएँ",
-       "blankarticle": "<strong>à¤\9aà¥\87तावनà¥\80:</strong> à¤\86प à¤\8fà¤\95 à¤°à¤¿à¤\95à¥\8dत à¤ªà¥\83षà¥\8dठ à¤\95ा à¤¨à¤¿à¤°à¥\8dमाण à¤\95र à¤°à¤¹à¥\87 à¤¹à¥\88à¤\82।\nयदि à¤\86प \"$1\" à¤\95à¥\8b à¤ªà¥\81नà¤\83 à¤¦à¤¬à¤¾à¤¤à¥\87 à¤¹à¥\88à¤\82 à¤¤à¥\8b à¤ªà¥\83षà¥\8dठ à¤\95à¥\8b à¤¬à¤¿à¤¨à¤¾ à¤\95िसà¥\80 à¤¸à¤¾à¤®à¤\97à¥\8dरà¥\80 à¤\95à¥\87 à¤¨à¤¿à¤°à¥\8dमित à¤\95िया जाएगा।",
+       "blankarticle": "<strong>à¤\9aà¥\87तावनà¥\80:</strong> à¤\86प à¤\8fà¤\95 à¤°à¤¿à¤\95à¥\8dत à¤ªà¥\83षà¥\8dठ à¤\95ा à¤¨à¤¿à¤°à¥\8dमाण à¤\95र à¤°à¤¹à¥\87 à¤¹à¥\88à¤\82।\nयदि à¤\86प \"$1\" à¤\95à¥\8b à¤«à¤¿à¤° à¤¸à¥\87 à¤¦à¤¬à¤¾à¤¤à¥\87 à¤¹à¥\88à¤\82 à¤¤à¥\8b à¤¬à¤¿à¤¨à¤¾ à¤¸à¤¾à¤®à¤\97à¥\8dरà¥\80 à¤\95ा à¤ªà¥\83षà¥\8dठ à¤¨à¤¿à¤°à¥\8dमित à¤¹à¥\8b जाएगा।",
        "anoneditwarning": "<strong>सावधान:</strong> आपने सत्रारंभ नहीं किया है। यदि आप सम्पादन करते हैं तो इस पृष्ठ के संपादन इतिहास में आपका आइ॰पी पता अंकित किया जाएगा। यदि आप <strong>[$1 लॉगिन]</strong> करते हैं अथवा <strong>[$2 खाता बनाते हैं]</strong> तो अन्य सुविधाओं के साथ-साथ आपके संपादनों का श्रेय आपके सदस्यनाम पर दिया जाएगा।",
        "anonpreviewwarning": "''आप लॉग्ड इन नहीं हैं। पृष्ठ सहेजने पर आपका आइ॰पी पता इस पृष्ठ के इतिहास में दर्ज किया जायेगा।''",
-       "missingsummary": "'''à¤\85नà¥\81सà¥\8dमारà¤\95:''' à¤\86पनà¥\87 à¤¸à¤\82पादन à¤¸à¤¾à¤°à¤¾à¤\82श à¤¨à¤¹à¥\80à¤\82 à¤¦à¤¿à¤¯à¤¾ à¤¹à¥\88।\nà¤\85à¤\97र à¤\86प à¤¦à¥\81बारा \"$1\" à¤ªà¤° à¤\95à¥\8dलिà¤\95 à¤\95रतà¥\87 à¤¹à¥\88à¤\82 à¤¤à¥\8b à¤\86पà¤\95ा à¤¸à¤\82पादन à¤¬à¤¿à¤¨à¤¾ à¤¸à¤¾à¤°à¤¾à¤\82श à¤\95à¥\87 à¤¸à¤\82à¤\9cà¥\8bया जायेगा।",
+       "missingsummary": "'''सà¥\82à¤\9aना:''' à¤\86पनà¥\87 à¤¸à¤\82पादन à¤¸à¤¾à¤°à¤¾à¤\82श à¤¨à¤¹à¥\80à¤\82 à¤¦à¤¿à¤¯à¤¾ à¤¹à¥\88।\nà¤\85à¤\97र à¤\86प à¤¦à¥\81बारा \"$1\" à¤ªà¤° à¤\95à¥\8dलिà¤\95 à¤\95रतà¥\87 à¤¹à¥\88à¤\82 à¤¤à¥\8b à¤\86पà¤\95ा à¤¸à¤\82पादन à¤¬à¤¿à¤¨à¤¾ à¤¸à¤¾à¤°à¤¾à¤\82श à¤\95à¥\87 à¤¸à¤¹à¥\87à¤\9cा जायेगा।",
        "selfredirect": "<strong>चेतावनी:</strong> आप खुद को इस पेज पुनः निर्देशित कर रहे हैं।\nआप अनुप्रेषित के लिए गलत लक्ष्य निर्दिष्ट हो सकता है, या आप गलत पृष्ठ का संपादन किया जा सकता है।\nआप फिर से \"$1\" क्लिक करते हैं, रीडायरेक्ट वैसे भी बनाया जाएगा।",
        "missingcommenttext": "कृपया नीचे टिप्पणी दें।",
        "missingcommentheader": "'''अनुस्मारक:''' आपने इस टिप्पणी का कोई शीर्षक नहीं दिया है।\nअगर आप \"$1\" पर दोबारा क्लिक करते हैं तो आपके बदलाव बिना शीर्षक के संजोये जायेंगे।",
        "readonlywarning": "<strong>सावधान: डाटाबेस को रख-रखाव के लिये बंद कर दिया गया है, इसलिये अभी आपके बदलाव संजोए नहीं जा सकते।\nअगर आप चाहें तो इस सामग्री को बाद के लिए कॉपी-पेस्ट कर के किसी टेक्स्ट फ़ाइल में रख सकते हैं।</strong>\n\nबंद करने वाले कार्यकारी प्रबंधक ने बंद करने का यह कारण दिया है: $1",
        "protectedpagewarning": "'''चेतावनी: इस पृष्ठ को सुरक्षित कर दिया गया है और इसे केवल प्रबंधक ही सम्पादित कर सकते हैं।'''\nनवीनतम लॉग प्रविष्टि संदर्भ के लिये नीचे दी है:",
        "semiprotectedpagewarning": "'''सूचना:''' यह पृष्ठ सुरक्षित कर दिया गया है और इसे केवल पंजीकृत सदस्य ही सम्पादित कर सकते हैं।\nनवीनतम लॉग प्रविष्टि संदर्भ के लिये नीचे दी है:",
-       "cascadeprotectedwarning": "'''सावधान:''' यह पृष्ठ निम्नलिखित सुरक्षा-सीढ़ी {{PLURAL:$1|पृष्ठ से|पन्नों से}} जुड़ा हुआ होने के कारण सुरक्षित है, और केवल प्रबंधक ही इसमें बदलाव कर सकते हैं:",
+       "cascadeprotectedwarning": "<strong>सावधान:</strong> यह पृष्ठ निम्नलिखित सुरक्षा-सीढ़ी वाले {{PLURAL:$1|पृष्ठ से|पन्नों से}} जुड़ा हुआ होने के कारण सुरक्षित है, और केवल [[Special:ListGroupRights|आवश्यक अधिकार वाले]] ही इसमें बदलाव कर सकते हैं:",
        "titleprotectedwarning": "'''चेतावनी: यह पृष्ठ सुरक्षित है और इसे बनाने के लिये [[Special:ListGroupRights|विशेष अधिकारों]] की आवश्यकता है।'''\nनवीनतम लॉग प्रविष्टि संदर्भ के लिये नीचे दी है:",
        "templatesused": "इस पृष्ठ पर प्रयुक्त {{PLURAL:$1|साँचा|साँचे}}:",
        "templatesusedpreview": "इस झलक में प्रयुक्त {{PLURAL:$1|साँचा|साँचे}}:",
        "userrights-expiry-options": "एक दिन:1 day,एक सप्ताह:1 week,एक महीना:1 month,तीन महीने:3 months,छः महीने:6 months,एक वर्ष:1 year",
        "userrights-invalid-expiry": "\"$1\" समूह के लिए समाप्ती तिथि अमान्य है।",
        "userrights-expiry-in-past": "\"$1\" समूह हेतु समाप्ती का समय पहले ही बीत चुका है।",
-       "userrights-cannot-shorten-expiry": "à¤\86प \"$1\" à¤¸à¤®à¥\82ह à¤\95à¥\80 à¤¸à¤®à¤¾à¤ªà¥\8dति à¤\95à¥\8b à¤\86à¤\97à¥\87 à¤¨à¤¹à¥\80à¤\82 à¤¬à¤¢à¤¼à¤¾ à¤¸à¤\95तà¥\87 à¤¹à¥\88à¤\82। à¤\95à¥\87वल à¤\87स à¤¸à¤®à¥\82ह à¤\95à¥\8b à¤\9cà¥\8bड़नà¥\87 à¤\94र à¤¨à¤¿à¤\95ालनà¥\87 à¤\95à¥\80 à¤\85नà¥\81मति à¤µà¤¾à¤²à¥\87 à¤\89पयà¥\8bà¤\97à¤\95रà¥\8dता à¤\86à¤\97à¥\87 à¤¸à¤®à¤¾à¤ªà¥\8dति à¤¸à¤®à¤¯ à¤²ा सकते हैं।",
+       "userrights-cannot-shorten-expiry": "à¤\86प \"$1\" à¤¸à¤®à¥\82ह à¤\95à¥\80 à¤¸à¤®à¤¾à¤ªà¥\8dति à¤\95à¥\8b à¤\86à¤\97à¥\87 à¤¨à¤¹à¥\80à¤\82 à¤¬à¤¢à¤¼à¤¾ à¤¸à¤\95तà¥\87 à¤¹à¥\88à¤\82। à¤\95à¥\87वल à¤\87स à¤¸à¤®à¥\82ह à¤®à¥\87à¤\82 à¤\9cà¥\8bड़नà¥\87 à¤\94र à¤¨à¤¿à¤\95ालनà¥\87 à¤\95à¥\80 à¤\85नà¥\81मति à¤µà¤¾à¤²à¥\87 à¤¸à¤¦à¤¸à¥\8dय à¤¹à¥\80 à¤¸à¤®à¤¾à¤ªà¥\8dति à¤¸à¤®à¤¯ à¤\95à¥\8b à¤\86à¤\97à¥\87 à¤¬à¤¢à¤¼ा सकते हैं।",
        "userrights-conflict": "सदस्य अधिकार बदलावों में अंतर्विरोध! कृपया अपने बदलाव जाँचें और पुनः सुनिश्चित करें।",
        "group": "समूह:",
        "group-user": "सदस्य",
        "rcfilters-filter-registered-description": "लॉग-इन संपादक।",
        "rcfilters-filter-unregistered-label": "अपंजीकृत",
        "rcfilters-filter-unregistered-description": "संपादक जो लॉग इन नहीं हैं।",
-       "rcfilters-filtergroup-authorship": "लेखकों को संपादित करें",
+       "rcfilters-filter-unregistered-conflicts-user-experience-level": "यह फ़िल्टर निम्न {{PLURAL:$2|फ़िल्टर}} के साथ संघर्ष करता है, जो केवल पंजीकृत सदस्यों को ही {{PLURAL:$2|ढूंढ}} रहा है: $1",
+       "rcfilters-filtergroup-authorship": "लेखक योगदान",
        "rcfilters-filter-editsbyself-label": "आपके द्वारा बदलाव",
        "rcfilters-filter-editsbyself-description": "आपके अपने योगदान।",
        "rcfilters-filter-editsbyother-label": "दूसरों के द्वारा बदलाव",
        "rcfilters-filter-editsbyother-description": "आपके बदलावों को छोड़ कर सभी के बदलाव।",
        "rcfilters-filtergroup-userExpLevel": "अनुभव स्तर (केवल पंजीकृत सदस्यों के लिए)",
        "rcfilters-filtergroup-user-experience-level-conflicts-unregistered": "अनुभव फ़िल्टर केवल पंजीकृत उपयोगकर्ता पाते हैं इसलिए यह फ़िल्टर \"अपंजीकृत\" फ़िल्टर के साथ संघर्ष करता है।",
+       "rcfilters-filtergroup-user-experience-level-conflicts-unregistered-global": "\"अपंजीकृत\" फ़िल्टर एक या अधिक अनुभव फिल्टर के साथ संघर्ष करता है, जो केवल पंजीकृत उपयोगकर्ता ढूंढते हैं परस्पर विरोधी फिल्टर ऊपर सक्रिय फिल्टर क्षेत्र में चिह्नित हैं।",
        "rcfilters-filter-user-experience-level-newcomer-label": "अपरिचित",
        "rcfilters-filter-user-experience-level-newcomer-description": "4 दिनों की गतिविधि और 10 सम्पादन से कम।",
        "rcfilters-filter-user-experience-level-learner-label": "शिक्षार्थियों",
+       "rcfilters-filter-user-experience-level-learner-description": "\"नवागंतुकों\" की तुलना में गतिविधि और संपादन के अधिक दिन, लेकिन \"अनुभवी उपयोगकर्ताओं\" से कम।",
        "rcfilters-filter-user-experience-level-experienced-label": "अनुभवी सदस्य",
        "rcfilters-filter-user-experience-level-experienced-description": "30 दिन से अधिक गतिविधि और 500 सम्पादन।",
        "rcfilters-filtergroup-automated": "स्वचालित योगदान",
        "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-categorization-description": "श्रेणियों से पृष्ठों के रिकॉर्ड्स को जोड़ा या निकाला जा सकता है",
        "rcfilters-filter-logactions-label": "लॉग की गई कार्रवाई",
        "rcfilters-filter-logactions-description": "प्रशासनिक कार्रवाई, खाता निर्माण, पृष्ठ विलोपन, अपलोड ....",
+       "rcfilters-hideminor-conflicts-typeofchange-global": "\"लघु संपादन\" फ़िल्टर एक या एक से अधिक प्रकार के परिवर्तन फ़िल्टर के साथ संघर्ष करता है, क्योंकि कुछ प्रकार के परिवर्तन को \"लघु\" के रूप में निर्दिष्ट नहीं किया जा सकता है। परस्पर विरोधी फिल्टर ऊपर सक्रिय फिल्टर क्षेत्र में चिह्नित हैं।",
+       "rcfilters-hideminor-conflicts-typeofchange": "कुछ प्रकार के परिवर्तन को \"लघु\" के रूप में निर्दिष्ट नहीं किया जा सकता है\", इसलिए यह फ़िल्टर निम्न प्रकार के परिवर्तन फिल्टर के साथ संघर्ष करता है: $1",
+       "rcfilters-typeofchange-conflicts-hideminor": "इस प्रकार का परिवर्तन फ़िल्टर \"लघु संपादन\" फ़िल्टर के साथ संघर्ष करता है। कुछ प्रकार के परिवर्तन को \"लघु\" के रूप में निर्दिष्ट नहीं किया जा सकता है।",
+       "rcfilters-filtergroup-lastRevision": "सद्य अवतरण",
+       "rcfilters-filter-lastrevision-label": "अंतिम अवतरण",
+       "rcfilters-filter-lastrevision-description": "पृष्ठ का सबसे हाल में हुआ बदलाव",
+       "rcfilters-filter-previousrevision-label": "पहले के अवतरण",
+       "rcfilters-filter-previousrevision-description": "सभी परिवर्तन जो एक पृष्ठ में सबसे हाल के परिवर्तन नहीं हैं।",
        "rcnotefrom": "नीचे <strong>$2</strong> के बाद से (<strong>$1</strong> तक) {{PLURAL:$5|हुआ बदलाव दर्शाया गया है|हुए बदलाव दर्शाए गये हैं}}।",
+       "rclistfromreset": "चुने दिनांक पहले जैसा करें",
        "rclistfrom": "$3 $2 से नये बदलाव दिखाएँ",
        "rcshowhideminor": "छोटे बदलाव $1",
        "rcshowhideminor-show": "दिखाएँ",
        "recentchangeslinked-page": "पृष्ठ नाम:",
        "recentchangeslinked-to": "इसके बदले में दिये हुए पृष्ठसे जुडे पन्नोंके बदलाव दर्शायें",
        "recentchanges-page-added-to-category": "[[:$1]] श्रेणी में जुड़ा",
-       "recentchanges-page-added-to-category-bundled": "[[:$1]] à¤\94र [[Special:WhatLinksHere/$1|{{PLURAL:$2|à¤\8fà¤\95 à¤ªà¥\83षà¥\8dठ|$2 à¤ªà¥\83षà¥\8dठ}}]] à¤¶à¥\8dरà¥\87णà¥\80 à¤®à¥\87à¤\82 à¤\9cà¥\81ड़ा",
+       "recentchanges-page-added-to-category-bundled": "[[:$1]] à¤¶à¥\8dरà¥\87णà¥\80 à¤®à¥\87à¤\82 à¤\9cà¥\8bड़ा à¤\97या, [[Special:WhatLinksHere/$1|यह à¤ªà¥\87à¤\9c à¤\85नà¥\8dय à¤ªà¥\83षà¥\8dठà¥\8bà¤\82 à¤®à¥\87à¤\82 à¤¶à¤¾à¤®à¤¿à¤² à¤¹à¥\88]]",
        "recentchanges-page-removed-from-category": "[[:$1]] श्रेणी से हटा",
-       "recentchanges-page-removed-from-category-bundled": "[[:$1]] à¤\94र [[Special:WhatLinksHere/$1|{{PLURAL:$2|à¤\8fà¤\95 à¤ªà¥\83षà¥\8dठ|$2 à¤ªà¥\83षà¥\8dठ}}]] à¤¶à¥\8dरà¥\87णà¥\80 à¤¸à¥\87 à¤¹à¤\9fा",
+       "recentchanges-page-removed-from-category-bundled": "[[:$1]] à¤¶à¥\8dरà¥\87णà¥\80 à¤¸à¥\87 à¤¹à¤\9fाया à¤\97या, [[Special:WhatLinksHere/$1|यह à¤ªà¥\87à¤\9c à¤\85नà¥\8dय à¤ªà¥\83षà¥\8dठà¥\8bà¤\82 à¤®à¥\87à¤\82 à¤¶à¤¾à¤®à¤¿à¤² à¤¹à¥\88]]",
        "autochange-username": "मीडियाविकि स्वतः परिवर्तन",
        "upload": "फ़ाइल अपलोड करें",
        "uploadbtn": "फ़ाइल अपलोड करें",
        "file-thumbnail-no": "इस फ़ाइल का नाम <strong>$1</strong> से शुरू हो रहा है।\nयह आकार घटाई हुई ''(अंगूठाकार)'' हो सकती है।\nअगर यह चित्र अपने मूल आकार में है तो इसे अपलोड करें, नहीं तो फ़ाइल बदलें।",
        "fileexists-forbidden": "इस नाम की फ़ाइल पहले ही मौजूद है, और इसकी जगह और नहीं अपलोड की जा सकती।\nयदि आप इस फ़ाइल को फिर भी अपलोड करना चाहते हैं, तो कृपया वापस जा के इसके लिए कोई अन्य नाम चुनें।\n[[File:$1|thumb|center|$1]]",
        "fileexists-shared-forbidden": "इस नाम की फ़ाइल साझे फ़ाइल भंडार में पहले ही मौजूद है।\nयदि आप इस फ़ाइल को फिर भी अपलोड करना चाहते हैं, तो कृपया वापस जा के इसके लिए कोई अन्य नाम चुनें।\n[[File:$1|thumb|center|$1]]",
+       "fileexists-no-change": "अपलोड <strong>[[:$1]]</strong> के वर्तमान संस्करण का सटीक प्रतिलिपि है।",
+       "fileexists-duplicate-version": "अपलोड <strong>[[:$1]]</strong> के  {{PLURAL:$2|पुराने संस्करणों}} का सटीक प्रतिलिपि है",
        "file-exists-duplicate": "यह फ़ाइल निम्नलिखित {{PLURAL:$1|फ़ाइल|फ़ाइलों}} की प्रति है:",
        "file-deleted-duplicate": "इसी फ़ाइल ([[:$1]]) से हूबहू मेल खाती एक फ़ाइल पहले हटाई जा चुकी है।\nइसे फिर से अपलोड करने से पहले आपको पुरानी फ़ाइल का हटाने के इतिहास देख लेना चाहिए।",
        "file-deleted-duplicate-notitle": "इससे पहले इस फ़ाइल के समान एक फ़ाइल को हटाया गया है, और शीर्षक छिपा दिया गया है।\nइसे फिर से अपलोड करने से पहले आप किसी ऐसे व्यक्ति से स्थिति की समीक्षा करने के लिए कहें जिसके पास छिपी फ़ाइल का डाटा देखने की क्षमता है।",
        "php-uploaddisabledtext": "पी॰एच॰पी में फ़ाइल अपलोड बंद हैं।\nकृपया file_uploads जमाव की जाँच करें।",
        "uploadscripted": "इस फ़ाइल में एच॰टी॰एम॰एल या स्क्रिप्ट कोड है, जो वेब ब्राउज़र द्वारा गलत पढ़ा जा सकता है।",
        "upload-scripted-pi-callback": "उस फाइल को अपलोड नहीं किया जा सकता जिसमें एक्सएमएल-स्टाइलशीट प्रसंस्करण निर्देश समाविष्ट हैं।",
+       "upload-scripted-dtd": "SVG फ़ाइलों को अपलोड नहीं किया जा सकता जिसमें एक गैर-मानक DTD की घोषणा हो।",
        "uploaded-script-svg": "अपलोड की गयी एसवीजी फ़ाइल में स्क्रीप्ट अवयव \"$1\" पाया गया।",
        "uploaded-hostile-svg": "अपलोड की गयी एसवीजी फाइल के शैली अवयव में असुरक्षित सीएसएस पायी गयी।",
        "uploaded-event-handler-on-svg": "सेटिंग ईवेंट हैंडलर (आयोजन प्रबन्धनकर्ता वरियता) <code>$1=\"$2\"</code> एसवीजी फ़ाइल में अनुमत नहीं है।",
        "upload-http-error": "एक एच॰टी॰टी॰पी त्रुटि आई: $1",
        "upload-copy-upload-invalid-domain": "कॉपी अपलोड इस डोमेन से उपलब्ध नहीं हैं।",
        "upload-foreign-cant-upload": "यह विकि अन्य फ़ाइल संग्रह में अपलोड हेतु तय नहीं किया गया है।",
+       "upload-foreign-cant-load-config": "फ़ाइल अपलोड के लिए कॉन्फ़िगरेशन को विदेशी फ़ाइल रिपॉजिटरी में लोड करने में विफल।",
+       "upload-dialog-disabled": "इस बॉक्स का उपयोग कर फ़ाइल अपलोड इस विकी पर अक्षम हैं।",
        "upload-dialog-title": "फ़ाइल डालें",
        "upload-dialog-button-cancel": "रद्द करें",
        "upload-dialog-button-back": "पीछे",
        "uploadstash-errclear": "फ़ाइलों को साफ़ करना असफल रहा।",
        "uploadstash-refresh": "फ़ाइलों की सूची रिफ़्रेश करें",
        "uploadstash-thumbnail": "छवि देखें",
+       "uploadstash-exception": "गुप्त कोष में अपलोड स्टोर नहीं किया जा सका ($1): \"$2\".",
        "invalid-chunk-offset": "अग्राह्य चंक ऑफ़सेट",
        "img-auth-accessdenied": "अनुमति नहीं है",
        "img-auth-nopathinfo": "PATH_INFO मौजूद नहीं है।\nआपके सर्वर में इस जानकारी को भेजने के लिए जमाव नहीं है।\nयह सी॰जी॰आई-आधारित हो सकता है और img_auth को स्वीकार नहीं करता है।\nhttps://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Image_Authorization देखें।",
        "filerevert-submit": "पूर्ववत करें",
        "filerevert-success": "'''[[Media:$1|$1]]''' को [$4 $2 को $3 बजे के अवतरण] को पूर्ववत कर दिया गया है।",
        "filerevert-badversion": "दिये हुए समय से मेल खाने वाला इस फ़ाइल का पुराना अवतरण नहीं है।",
+       "filerevert-identical": "फ़ाइल का वर्तमान संस्करण पहले से ही चयनित एक जैसा है।",
        "filedelete": "$1 हटाएँ",
        "filedelete-legend": "फ़ाइल हटाएँ",
        "filedelete-intro": "आप फ़ाइल '''[[Media:$1|$1]]''' इतिहास समेत हटाने जा रहे हैं।",
        "uncategorizedcategories": "अश्रेणीकृत श्रेणियाँ",
        "uncategorizedimages": "अश्रेणीकृत फ़ाइलें",
        "uncategorizedtemplates": "अश्रेणीकृत साँचे",
+       "uncategorized-categories-exceptionlist": " # इसमें श्रेणियों की एक सूची है, जिसका विशेष:श्रेणीहीन_श्रेणियाँ उल्लेख नहीं किया जाना चाहिए। प्रति पंक्ति एक, \"*\" से शुरू. दूसरे वर्ण (व्हाइटस्पेस सहित) के साथ शुरू होने वाली पंक्तिओं को नजरअंदाज कर दिया जाता है। टिप्पणियों के लिए \"#\" का उपयोग करें।",
        "unusedcategories": "अप्रयुक्त श्रेणियाँ",
        "unusedimages": "अप्रयुक्त फ़ाइलें",
        "wantedcategories": "वांछित श्रेणियाँ",
        "apisandbox-sending-request": "एपीआई अनुरोध भेज रहा...",
        "apisandbox-loading-results": "एपीआई परिणाम ले रहा...",
        "apisandbox-results-error": "एपीआई के समय कोई त्रुटि हुई: $1",
+       "apisandbox-request-selectformat-label": "अनुरोध डेटा को इस रूप में दिखाएं:",
+       "apisandbox-request-format-url-label": "यूआरएल क्वेरी स्ट्रिंग",
        "apisandbox-request-url-label": "अनुरोध URL:",
        "apisandbox-request-json-label": "JSON अनुरोध:",
        "apisandbox-request-time": "अनुरोध समय: {{PLURAL:$1|$1 मि}}",
        "apisandbox-alert-field": "जगह में डाला गया जानकारी अमान्य है।",
        "apisandbox-continue": "जारी रखें",
        "apisandbox-continue-clear": "खाली करें",
+       "apisandbox-continue-help": "{{int:apisandbox-continue}} [https://www.mediawiki.org/wiki/API:Query#Continuing_queries continue] अंतिम अनुरोध होगा; {{int:apisandbox-continue-clear}} निरंतरता-संबंधित मानदंडों को साफ करेगा।",
+       "apisandbox-param-limit": "अधिकतम सीमा का उपयोग करने के लिए <kbd>अधिकतम</kbd> दर्ज करें।",
        "apisandbox-multivalue-all-namespaces": "$1 (सभी नामस्थान)",
        "apisandbox-multivalue-all-values": "$1 (सभी मूल्य)",
        "booksources": "पुस्तकों के स्रोत",
        "booksources-search": "खोजें",
        "booksources-text": "नीचे पुरानी और नई पुस्तकें बेचने वाली वेबसाइटों के एड्रेस हैं, जिसमें आपको आप द्वारा खोजी जाने वाली पुस्तक के बारे में अधिक जानकारी मिल सकती है:",
        "booksources-invalid-isbn": "यह आइ॰एस॰बी॰एन सही नहीं लग रहा है; मूल स्रोत से नकल करने में हुई त्रुटि के लिए जाँचें।",
+       "magiclink-tracking-rfc": "RFC जादू लिंक का उपयोग कर रहे पेज",
+       "magiclink-tracking-rfc-desc": "यह पृष्ठ आरएफसी जादू लिंक का उपयोग करता है। कैसे माइग्रेट करें [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Magic_links mediawiki.org] पर देखें।",
+       "magiclink-tracking-pmid": "पीएमआईडी जादू लिंक का उपयोग कर रहे पेज",
+       "magiclink-tracking-pmid-desc": "यह पृष्ठ पीएमआईडी जादू लिंक का उपयोग करता है। कैसे माइग्रेट करें [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Magic_links mediawiki.org] पर देखें।",
+       "magiclink-tracking-isbn": "आईएसबीएन के जादुई कड़ियों का उपयोग करने वाले पृष्ठ",
+       "magiclink-tracking-isbn-desc": "यह पृष्ठ आईएसबीएन जादू लिंक का उपयोग करता है। कैसे माइग्रेट करें [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Magic_links mediawiki.org] पर देखें।",
        "specialloguserlabel": "कर्ता:",
        "speciallogtitlelabel": "प्रयोजन (शीर्षक अथवा {{ns:सदस्यनाम}}:सदस्य नाम):",
        "log": "लॉग",
        "activeusers-intro": "यह सक्रिय सदस्यों की सूची है जिन्होंने पिछले $1 {{PLURAL:$1|दिन|दिनों}} में कुछ गतिविधि करी है।",
        "activeusers-count": "$1 {{PLURAL:$1|कार्य}} पिछले $3 {{PLURAL:$3|दिन|दिनों}} में",
        "activeusers-from": "इस अक्षर से शुरू होने वाले सदस्य दिखाएँ:",
+       "activeusers-groups": "इस समूह के सदस्यों को दिखाएँ:",
+       "activeusers-excludegroups": "इस समूह के सदस्यों को न दिखाएँ:",
        "activeusers-noresult": "कोई सदस्य नहीं मिले।",
        "activeusers-submit": "सक्रिय सदस्यों को दिखायें",
        "listgrouprights": "सदस्य समूह अधिकार",
        "trackingcategories-msg": "चिह्नित श्रेणी",
        "trackingcategories-name": "संदेश नाम",
        "trackingcategories-desc": "श्रेणी शामिल किए जाने के मानदंड",
+       "restricted-displaytitle-ignored": "नजरअंदाज कर दिया प्रदर्शन शीर्षक वाले पृष्ठ",
+       "restricted-displaytitle-ignored-desc": "पृष्ठ पर ध्यान नहीं दिया गया है।<code><nowiki>{{DISPLAYTITLE}}</nowiki></code> क्योंकि यह पृष्ठ के वास्तविक शीर्षक के बराबर नहीं है।",
        "noindex-category-desc": "यह पृष्ठ रोबॉटों द्वारा सूचीबद्ध नहीं है क्योंकि इसमें जादूई शब्द <code><nowiki>__NOINDEX__</nowiki></code> है और ऐसे स्थान पर है जहाँ उस झंडी की अनुमति है।",
        "index-category-desc": "इस पृष्ठ का एक <code><nowiki>__INDEX__</nowiki></code> उस पर है (ऐसे स्थान पर है जहाँ उस झंडी की अनुमति है), और इसलिए इसे रोबॉटों द्वारा सूचीबद्ध है जबकि साधारणतः ऐसा नहीं होता है।",
        "post-expand-template-inclusion-category-desc": "पृष्ठ का साइज़ <code>$wgMaxArticleSize</code> से बढ़कर है। सभी साँचों के फैलाने के बाद कुछ साँचों को फैलाया नहीं जा सकता है।",
        "emailccsubject": "आपके ई-मेल की प्रति जो $1 को भेजा गया: $2",
        "emailsent": "ई-मेल भेज दिया गया है।",
        "emailsenttext": "आपका ई-मेल संदेश भेज दिया गया है।",
-       "emailuserfooter": "इस ई-मेल को $1 {{GENDER:$1|द्वारा}} {{GENDER:$2|$2}} को भेजा गया था जिसके लिए \"{{int:emailuser}}\" कार्य को {{SITENAME}} पर प्रयोग में लाया गया था।",
+       "emailuserfooter": "इस ई-मेल को $1 {{GENDER:$1|द्वारा}} {{GENDER:$2|$2}} को भेजा गया था जिसके लिए \"{{int:emailuser}}\" कार्य को {{SITENAME}} पर प्रयोग में लाया गया था। अगर {{GENDER:$2|आप}} इस ईमेल का उत्तर देते हैं, {{GENDER:$2|आपका}} ईमेल सीधे {{GENDER:$1|मूल प्रेषक}} को भेज दिया जाएगा। {{GENDER:$1उनको}} {{GENDER:$2|अपना}} ईमेल पता बताएं।",
        "usermessage-summary": "प्रणाली सन्देश छोड़ रहा है।",
        "usermessage-editor": "सिस्टम दूत",
        "watchlist": "ध्यानसूची",
        "delete-toobig": "इस पृष्ठ का संपादन इतिहास $1 से अधिक {{PLURAL:$1|अवतरण}} होने की वजह से बहुत बड़ा है।\n{{SITENAME}} के अनपेक्षित रूप से बंद होने से रोकने के लिये ऐसे पृष्ठों को हटाने की अनुमति नहीं है।",
        "delete-warning-toobig": "इस पृष्ठ का संपादन इतिहास $1 से अधिक {{PLURAL:$1|अवतरण}} होने की वजह से बहुत बड़ा है।\nइसे हटाने से {{SITENAME}} के डाटाबेस की गतिविधियों में व्यवधान आ सकता है;\nकृपया सोच समझ कर आगे बढ़ें।",
        "deleteprotected": "आप इस पृष्ठ को हटा नहीं सकते क्योंकि इसे सुरक्षित किया गया है।",
-       "deleting-backlinks-warning": "'''चेतावनी:''' जो पृष्ठ आप हटाने जा रहे हैं उससे [[Special:WhatLinksHere/{{FULLPAGENAME}}|अन्य पृष्ठ]] जुड़ते हैं अथवा उसे ट्रांसक्लूड करते हैं।",
+       "deleting-backlinks-warning": "<strong>चेतावनी:</strong> जो पृष्ठ आप हटाने जा रहे हैं उससे [[Special:WhatLinksHere/{{FULLPAGENAME}}|अन्य पृष्ठ]] जुड़ते हैं अथवा उसे ट्रांसक्लूड करते हैं।",
        "rollback": "संपादन वापिस लें",
        "rollbacklink": "वापिस लें",
        "rollbacklinkcount": "$1 {{PLURAL:$1|सम्पादन}} वापिस लें",
        "rollbacklinkcount-morethan": "$1 से अधिक {{PLURAL:$1|सम्पादन}} वापिस लें",
        "rollbackfailed": "वापिस लेना असफल रहा",
+       "rollback-missingparam": "अनुरोध पर अपेक्षित पैरामीटर गायब हैं।",
        "rollback-missingrevision": "अवतरण डाटा दिखाने में असमर्थ।",
        "cantrollback": "पुराने अवतरण को पूर्ववत नहीं कर सकते हैं;\nइस पृष्ठ का अन्तिम योगदानकर्ता इस लेख का एकमात्र लेखक है।",
        "alreadyrolled": "[[User:$2|$2]] ([[User talk:$2|वार्ता]]{{int:pipe-separator}}[[Special:Contributions/$2|{{int:contribslink}}]]) द्वारा किए गए  [[:$1]] के पिछले संपादन को वापिस पुरानी स्थिति पर नहीं लाया जा सकता है;\nकिसी और ने इस बीच या तो इस पृष्ठ को फिर से संपादित कर दिया है या पहले ही पृष्ठ पुरानी स्थिति पर लाया जा चुका है।\n\nइस पृष्ठ का अन्तिम संपादन [[User:$3|$3]] ([[User talk:$3|वार्ता]]{{int:pipe-separator}}[[Special:Contributions/$3|{{int:contribslink}}]]) ने किया है।",
        "revertpage": "[[Special:Contributions/$2|$2]] ([[User talk:$2|Talk]]) के संपादनों को हटाकर [[User:$1|$1]] के अन्तिम अवतरण को पूर्ववत किया",
        "revertpage-nouser": "(सदस्य नाम हटाया गया है) के संपादनों को हटाकर {{GENDER:$1|[[User:$1|$1]]}} के अन्तिम अवतरण को पूर्ववत किया।",
        "rollback-success": "{{GENDER:$3|$1}} के संपादन हटाए;\n{{GENDER:$4|$2}} द्वारा संपादित अन्तिम अवतरण को पुनर्स्थापित किया।",
+       "rollback-success-notify": "$1 द्वारा वापिस लौटे संपादन; $2 द्वारा पिछली संशोधन में वापस बदल दिया। [$3 बदलाव दिखाएं]",
        "sessionfailure-title": "सत्र विफलता",
        "sessionfailure": "ऐसा प्रतीत होता है कि आपके लॉगिन सत्र के साथ कोई समस्या है।\nसत्र अपहरण से बचाने के लिए सावधानी के तौर पर आपका यह क्रियाकलाप रद्द कर दिया गया है।\nकृपया पीछे जाएँ और पृष्ठ को पुनः लोड करें, तब दुबारा कोशिश करें।",
        "changecontentmodel": "पेज कि सामगरिि मोदल को बदलिये",
        "undeletehistorynoadmin": "यह पृष्ठ हटा दिया गया है।\nहटाए जाने का कारन नीचे सारांश में दिया गया है, और साथ ही उन सदस्यों के बारे में विस्तार भी दिया गया है, जिन्होंने हटाए जाने से पहले इस पृष्ठ को संपादित किया था।\nइन हटाये गए अवतरणों का पाठ केवल प्रबंधकों को ही उपलब्ध है।",
        "undelete-revision": "$1 ($4 को $5 बजे $3 द्वारा बनाया गया) का मिटाया हुआ संस्करण:",
        "undeleterevision-missing": "अमान्य अथवा अनुपस्थित अवतरण।\nया तो आप ग़लत कड़ी प्रयोग कर रहे हैं, या यह अवतरण पुनर्स्थापित किया जा चुका है, अथवा इसे लेखागार से हटा दिया गया है।",
+       "undeleterevision-duplicate-revid": "{{PLURAL:$1|One revision|$1संशोधन}} को पुनर्स्थापित नहीं किया जा सका, क्योंकि {{PLURAL:$1|यह|अपने}} <code>rev_id</code> पहले से ही उपयोग में है।",
        "undelete-nodiff": "कोई पुराना अवतरण नहीं मिला।",
        "undeletebtn": "वापस ले आयें",
        "undeletelink": "देखें/पुनर्स्थापित करें",
        "sp-contributions-uploads": "अपलोड",
        "sp-contributions-logs": "लॉग",
        "sp-contributions-talk": "वार्ता",
-       "sp-contributions-userrights": "सदस्य अधिकार प्रबंधन",
+       "sp-contributions-userrights": "{{GENDER:$1|सदस्य}} अधिकार प्रबंधन",
        "sp-contributions-blocked-notice": "यह सदस्य फ़िलहाल अवरोधित हैं। सदंर्भ के लिए ताज़ातरीन अवरोध चिट्ठा प्रविष्टि नीचे है:",
        "sp-contributions-blocked-notice-anon": "यह आईपी पता अभी अवरोधित है। \nनवीनतम अवरोध अभिलेख प्रविष्टि सन्दर्भ के लिए नीचे दी गई है:",
        "sp-contributions-search": "योगदान के लिये खोज",
        "unblock": "उपयोक्ता पर अवरोधण हटाएँ",
        "blockip": "{{GENDER:$1|सदस्य|सदस्या}} अवरोधित करें",
        "blockip-legend": "सदस्य को ब्लॉक करें",
-       "blockiptext": "विशिष्ठ IP पते अथवा सदस्य नाम को लिखने के अधिकार से बाध्य करने के लिए निम्न पत्र का प्रयोग करें।\nयह सिर्फ बर्बरता को रोकने के लिए ही किया जाना चाहिए, और [[{{MediaWiki:Policy-url}}|नीति]] के अनुसार ही करना चाहिए।\nनीचे विशिष्ठ कारण भी लिखें (उदाहरण के लिए, सटीक पृष्ठों को दर्शाते हुए, जिनमें बर्बरता की गई हो)।",
+       "blockiptext": "विशिष्ठ IP पते अथवा सदस्य नाम को लिखने के अधिकार से बाध्य करने के लिए निम्न पत्र का प्रयोग करें।\nयह सिर्फ बर्बरता को रोकने के लिए ही किया जाना चाहिए, और [[{{MediaWiki:Policy-url}}|नीति]] के अनुसार ही करना चाहिए।\nनीचे विशिष्ठ कारण भी लिखें (उदाहरण के लिए, सटीक पृष्ठों को दर्शाते हुए, जिनमें बर्बरता की गई हो)।\nआप [https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing सीआईडीआर] सिंटैक्स का उपयोग करके आईपी पता श्रेणियां ब्लॉक कर सकते हैं। आईपीवी4 के लिए सबसे बड़ी स्वीकार्य सीमा /$1 है और आईपीवी6 के लिए /$2 है।",
        "ipaddressorusername": "आईपी एड्रेस या सदस्यनाम:",
        "ipbexpiry": "समाप्ति:",
        "ipbreason": "कारण:",
        "unblocked-id": "अवरोध $1 निकाल दिया गया है",
        "unblocked-ip": "[[Special:Contributions/$1|$1]] पर से प्रतिरोध हटाया गया है।",
        "blocklist": "अवरोधित उपयोक्ता",
+       "autoblocklist": "स्वतःअवरोध",
        "autoblocklist-submit": "खोजें",
        "autoblocklist-legend": "स्वतः अवरोध सूची",
        "autoblocklist-localblocks": "स्थानीय {{PLURAL:$1|स्वतः अवरोध}}",
        "autoblocklist-empty": "स्वतः अवरोध सूची खाली है।",
+       "autoblocklist-otherblocks": "अन्य {{PLURAL:$1|स्वतःअवरोध}}",
        "ipblocklist": "अवरोधित आईपी पते व सदस्यनाम",
        "ipblocklist-legend": "अवरोधित सदस्य को खोजें",
        "blocklist-userblocks": "खाते के अवरोध छिपाएं",
        "move-page-legend": "पृष्ठ स्थानांतरण",
        "movepagetext": "निम्नलिखित प्रारूप को काम में लेने पर पृष्ठ का नाम परिवर्तित हो जायेगा, इसका सम्पूर्ण इतिहास नये नाम पर स्थानान्तरित हो जायेगा।\nपुराना शीर्षक नये शीर्षक पर एक अनुप्रेषण पृष्ठ बन जायेगा।\nआप मूल शीर्षक पर अनुप्रेषिणों को स्वतः अद्यतन कर सकते हैं।\nयदि आप ऐसा नहीं करते हैं तो [[Special:DoubleRedirects|द्वि-अनुप्रेषण]] और [[Special:BrokenRedirects|टूटे हुये अनुप्रेषणों]] की जाँच करें।\nकड़ियों के आवश्यक रूप से सही स्थान पर जोड़ने के लिए आप उत्तरदायी हैं।\n\nयदि नये शीर्षक पर पहले से कोई पृष्ठ उपलब्ध है तो पृष्ठ का स्थानान्तरण <strong>नहीं</strong> होगा जबकि बाद वाला इतिहास रहित अनुप्रेषण नहीं है।\nइसका अर्थ यह हुआ कि आप किसी पृष्ठ का पुनः नामकरण वहाँ कर सकते हैं जहाँ से इसको गलती से यहाँ स्थानान्तरित किया गया है और आप पहले से बने हुये पृष्ठ को पुनः नहीं लिख सकते।\n\n<strong>टिप्पणी:</strong>\nयह किसी लोकप्रिय पृष्ठ के लिए कठोर और अप्रत्यासित परिवर्तन हो सकता है;\nकृपया आगे बढ़ने से पहले इसके परिणामों को अच्छे से समझ लें।",
        "movepagetext-noredirectfixer": "नीचे दिया हुआ पर्चा पृष्ठ का नाम बदल देगा, उसका सारा इतिहास भी नए नाम से दिखना शुरू हो जाएगा।\nपुराना शीर्षक नये नाम को अनुप्रेषित करेगा ।\nमूल शीर्षक की ओर ले जाने वाले अग्रेषणों को आप स्वचालित रूप से बदल सकते हैं।\nयदि आप ऐसा नहीं करते हैं तो कृपया [[Special:DoubleRedirects|दोहरे]] पुनर्निर्देशण या [[Special:BrokenRedirects|टूटे पुनर्निर्देशन]] के लिए ज़रूर जाँच करें।\nकड़ियाँ सही जगह इंगित करती रहें, यह सुनिश्चित करना आपकी जिम्मेदारी है।\n\nअगर नये शीर्षक का लेख पहले से है तो स्थानांतरण <strong>नहीं</strong> होगा। पर अगर नये शीर्षक वाला लेख खाली है अथवा कहीं और अनुप्रेषित करता है और साथ ही उसके पुराने संस्करण नहीं हैं तो स्थानांतरण हो जायेगा ।\nइसका मतलब कि यदि आपसे गलती हो जाए तो आप वापस पुराने नाम पर इस पृष्ठ का स्थानांतरण कर सकेंगे, और साथ ही आप किसी मौजूदा पृष्ठ के बदले यह स्थानांतरण नहीं कर सकते हैं।\n\n<strong>चेतावनी!</strong>\nयदि पृष्ठ काफ़ी लोकप्रिय है तो उसके लिए यह एक बहुत बड़ा व अकस्मात् परिवर्तन हो सकता है;\nआगे बढ़ने से पहले इसका अंजाम अच्छी तरह समझ लें।\n\n<strong>सूचना!</strong>\nस्थानांतरण करनेसे कोई भी महत्वपूर्ण लेख में अनपेक्षित बदलाव हो सकते है ।\nआपसे अनुरोध है कि आप इसके परिणाम जान लें ।",
-       "movepagetalktext": "सà¤\82बà¤\82धित à¤µà¤¾à¤°à¥\8dता à¤ªà¥\83षà¥\8dठ à¤\87सà¤\95à¥\87 à¤¸à¤¾à¤¥ à¤¸à¥\8dथानाà¤\82तरà¥\80त à¤¨à¤¹à¥\80à¤\82 à¤¹à¥\8bà¤\97ा '''à¤\85à¤\97र:'''\n* à¤\86प à¤ªà¥\83षà¥\8dठ à¤¦à¥\81सरà¥\87 à¤¨à¤¾à¤®à¤¸à¥\8dथान à¤®à¥\87à¤\82 à¤¸à¥\8dथानाà¤\82तरà¥\80त à¤\95र à¤°à¤¹à¥\87à¤\82 à¤¹à¥\88\n* à¤\87स à¤¨à¤¾à¤® à¤\95ा à¤µà¤¾à¤°à¥\8dता à¤ªà¥\83षà¥\8dठ à¤ªà¤¹à¤²à¥\87सà¥\87 à¤¬à¤¨à¤¾ à¤¹à¥\81वा à¤¹à¥\88, à¤¯à¤¾\n* à¤¨à¥\80à¤\9aà¥\87 à¤¦à¤¿à¤¯à¤¾ à¤¹à¥\81à¤\86 à¤\9aà¥\87à¤\95 à¤¬à¥\89à¤\95à¥\8dस à¤\86पनà¥\87 à¤¨à¤¿à¤\95ाल à¤¦à¤¿à¤¯à¤¾ à¤¹à¥\88 à¥¤\n\nà¤\87न à¤®à¤¾à¤®à¤²à¥\8bà¤\82मे आपको स्वयं यह पृष्ठ जोडने पड़ सकते है ।",
+       "movepagetalktext": "यदि à¤\86प à¤\87स à¤¬à¥\89à¤\95à¥\8dस à¤\95à¥\8b à¤\9aà¥\87à¤\95 à¤\95रतà¥\87 à¤¹à¥\88à¤\82, à¤¸à¤\82बà¤\82धित à¤µà¤¾à¤°à¥\8dता à¤ªà¥\83षà¥\8dठ à¤¸à¥\8dवà¤\9aालित à¤°à¥\82प à¤¸à¥\87 à¤¨à¤\8f à¤¶à¥\80रà¥\8dषà¤\95 à¤ªà¤° à¤²à¥\87 à¤\9cाया à¤\9cाà¤\8fà¤\97ा, à¤\9cब à¤¤à¤\95 à¤\95ि à¤\8fà¤\95 à¤°à¤¿à¤\95à¥\8dत à¤µà¤¾à¤°à¥\8dता à¤ªà¥\83षà¥\8dठ à¤ªà¤¹à¤²à¥\87 à¤¸à¥\87 à¤®à¥\8cà¤\9cà¥\82द à¤¨ à¤¹à¥\8b।\n\nà¤\87स à¤®à¤¾à¤®à¤²à¥\87 मे आपको स्वयं यह पृष्ठ जोडने पड़ सकते है ।",
        "moveuserpage-warning": "<strong>चेतावनी:</strong> आप एक सदस्य पृष्ठ स्थानांतरित करने जा रहे हैं। कृपया ध्यान दें कि केवल पृष्ठ का नाम बदला जाएगा और सदस्यनाम <em>नहीं</em> बदलेगा।",
        "movecategorypage-warning": "<strong>चेतावनी:</strong> आप एक श्रेणी पृष्ठ को स्थानांतरित करने जा रहे हैं। याद रखिए कि केवल वह पृष्ठ स्थानांतरित होगा और पुरानी श्रेणी में शामिल पृष्ठ नई श्रेणी के अंतरगत <em>नहीं</em> आएँगे।",
        "movenologintext": "लेख स्थानान्तरित करने के लिये आपका [[Special:UserLogin|लॉग इन]] किया होना आवश्यक हैं।",
        "movelogpagetext": "नीचे सभी स्थानान्तरणों की सूची दी गई है।",
        "movesubpage": "{{PLURAL:$1|उप पृष्ठ|उप पृष्ठ}}",
        "movesubpagetext": "नीचे $1 {{PLURAL:$1|पृष्ठ दिखाया गया है, जो इस पृष्ठ का उप पृष्ठ है|पृष्ठ दिखाया गया है, जो इस पृष्ठ के उप पृष्ठ हैं}}।",
+       "movesubpagetalktext": "{{PLURAL:$1|उप-पृष्ठ}} में संबंधित वार्ता पृष्ठ नीचे दिखाए गए हैं",
        "movenosubpage": "इस पृष्ठ के कोई उपपृष्ठ नहीं हैं।",
        "movereason": "कारण:",
        "revertmove": "पुराने अवतरण पर ले जाएं",
        "tooltip-pt-mycontris": "आपके योगदानों की सूची",
        "tooltip-pt-anoncontribs": "इस आईपी पते से संपादन की सूची",
        "tooltip-pt-login": "आपको सत्रारम्भ करने के लिए प्रोत्साहित किया जाता है; लेकिन यह अनिवार्य नहीं है",
+       "tooltip-pt-login-private": "इस विकि का उपयोग करने हेतु लॉगिन (प्रवेश) करें",
        "tooltip-pt-logout": "प्रस्थान",
        "tooltip-pt-createaccount": "हमारा सुझाव है की आप खाता बनाएँ और लॉगिन करें, परन्तु यह अनिवार्य नहीं है",
        "tooltip-ca-talk": "सामग्री पृष्ठ के बारे में वार्तालाप",
        "newimages-showbots": "बॉट के अपलोड दिखाइये",
        "newimages-hidepatrolled": "जाँचा हुआ अपलोड छुपाएँ",
        "noimages": "देखने के लिए कुछ नहीं है।",
+       "gallery-slideshow-toggle": "टॉगल थंबनेल",
        "ilsubmit": "खोजें",
        "bydate": "तिथि अनुसार",
        "sp-newimages-showfrom": "$2, $1 के बाद की फ़ाईलें दर्शायें",
        "tag-filter-submit": "छननी",
        "tag-list-wrapper": "([[Special:Tags|{{PLURAL:$1|टैग}}]]: $2)",
        "tag-mw-contentmodelchange": "सामग्री मॉडल परिवर्तन",
+       "tag-mw-contentmodelchange-description": "पृष्ठ [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:ChangeContentModel सामग्री मॉडल को परिवर्तित करें] के संपादन।",
        "tags-title": "चिप्पियाँ",
        "tags-intro": "यह पृष्ठ अर्थ सहित वह चिप्पियाँ दर्शाता है जिनका कोई तंत्रांश किसी संपादन पर निशान लगाने के लिए इस्तेमाल कर सकता है।",
        "tags-tag": "चिप्पी का नाम",
        "htmlform-date-placeholder": "वववव-मम-दद",
        "htmlform-time-placeholder": "घघ:मम:सस",
        "htmlform-datetime-placeholder": "वववव-मम-दद हह:मम:सस",
+       "htmlform-date-invalid": "आपने जो मान डाला है, उसे दिनांक के रूप में नहीं पहचान पा रहा है। YYYY-MM-DD के प्रारूप में प्रयास करें।",
+       "htmlform-time-invalid": "आपने जो मान डाला है, उसे समय के रूप में नहीं पहचान पा रहा है। HH:MM:SS के प्रारूप में प्रयास करें।",
+       "htmlform-datetime-invalid": "आपने जो मान डाला है, उसे दिनांक और समय के रूप में नहीं पहचान पा रहा है। YYYY-MM-DD HH:MM:SS के प्रारूप में प्रयास करें।",
+       "htmlform-date-toolow": "आपके द्वारा निर्दिष्ट मान $1 की आरंभिक तिथि से पहले है",
+       "htmlform-date-toohigh": "आपके द्वारा निर्दिष्ट मान $1 की नवीनतम अनुमत तिथि के बाद है",
+       "htmlform-time-toolow": "आपके द्वारा निर्दिष्ट मान $1 के आरंभिक समय से पहले है।",
+       "htmlform-time-toohigh": "आपके द्वारा निर्दिष्ट मान $1 के नवीनतम अनुमत समय के बाद है।",
+       "htmlform-datetime-toolow": "आपके द्वारा उल्लिखित मूल्य $1 की आरंभिक तिथि और समय से पहले है।",
+       "htmlform-datetime-toohigh": "आपके द्वारा निर्दिष्ट मूल्य $1 की नवीनतम अनुमति तिथि और समय के बाद है।",
        "htmlform-title-badnamespace": "[[:$1]] अभी \"{{ns:$2}}\" नामस्थान में नहीं है।",
        "htmlform-title-not-creatable": "\"$1\" निर्माण करने लायक शीर्षक नहीं है।",
        "htmlform-title-not-exists": "$1 नहीं बना है।",
        "logentry-delete-delete": "$1 ने पृष्ठ $3 {{GENDER:$2|हटा}} दिया",
        "logentry-delete-delete_redir": "$1 ने $3 से पुनर्निर्देशन {{GENDER:$2|हटाकर}} अन्य जानकारी डाल दी।",
        "logentry-delete-restore": "$1 ने पृष्ठ $3 ($4) को {{GENDER:$2|पुनर्स्थापित}} कर दिया",
+       "logentry-delete-restore-nocount": "$1 $3 पृष्ठ {{GENDER:$2|को बहाल किया}}",
+       "restore-count-revisions": "{{PLURAL:$1|1 संशोधन|$1 संशोधन}}",
+       "restore-count-files": "{{PLURAL:$1|1 फ़ाइल|$1 फ़ाइल}}",
        "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|बदली}}",
        "pagelang-nonexistent-page": "$1 पन्ना अभी बना नहीं है।",
        "pagelang-unchanged-language": "$1 की भाषा पहले ही $2 तय की गई है।",
        "pagelang-unchanged-language-default": "$1 पृष्ठ में विकि की मूल भाषा पहले से तय कर दी गई है।",
+       "pagelang-db-failed": "डेटाबेस पृष्ठ भाषा को बदलने में विफल रहा।",
        "right-pagelang": "पृष्ठ भाषा बदलें",
        "action-pagelang": "पृष्ठ भाषा बदलने",
        "log-name-pagelang": "भाषा बदलाव लॉग",
        "special-characters-group-thai": "थाई",
        "special-characters-group-lao": "लाओ",
        "special-characters-group-khmer": "खमेर",
+       "special-characters-group-canadianaboriginal": "कनाडाई एबोरिजिनल",
        "special-characters-title-endash": "एन डैश",
        "special-characters-title-emdash": "एम डैश",
        "special-characters-title-minus": "ऋण चिह्न",
        "sessionprovider-nocookies": "हो सकता है कि कुकी निष्क्रिय है। कृपया देखें कि और सक्रिय करें।",
        "randomrootpage": "अविशिष्ट मूल पृष्ठ",
        "log-action-filter-block": "अवरोध के प्रकार:",
+       "log-action-filter-contentmodel": "सामग्री मॉडल परिवर्तन का प्रकार:",
        "log-action-filter-delete": "हटाने के प्रकार:",
        "log-action-filter-import": "आयात के प्रकार:",
+       "log-action-filter-managetags": "टैग प्रबंधन कार्रवाई का प्रकार:",
        "log-action-filter-move": "स्थानांतरण के प्रकार:",
        "log-action-filter-newusers": "खाता निर्माण के प्रकार:",
        "log-action-filter-patrol": "परीक्षण के प्रकार:",
        "log-action-filter-protect": "सुरक्षा के प्रकार:",
        "log-action-filter-rights": "अधिकार बदलाव के प्रकार:",
+       "log-action-filter-suppress": "दमन के प्रकार:",
        "log-action-filter-upload": "अपलोड के प्रकार:",
        "log-action-filter-all": "सभी",
        "log-action-filter-block-block": "अवरोध",
        "log-action-filter-block-reblock": "अवरोध परिवर्तन",
        "log-action-filter-block-unblock": "अवरोध हटाना",
+       "log-action-filter-contentmodel-change": "सामग्री मॉडल में बदलाव",
+       "log-action-filter-contentmodel-new": "गैर-डिफ़ॉल्ट सामग्री मॉडल वाले पृष्ठ का निर्माण",
        "log-action-filter-delete-delete": "पृष्ठ हटाना",
+       "log-action-filter-delete-delete_redir": "पुननिर्देशित ओवरराइट",
        "log-action-filter-delete-restore": "पृष्ठ न हटाना",
        "log-action-filter-delete-event": "पृष्ठ हटाने का लॉग",
        "log-action-filter-delete-revision": "अवतरण हटाना",
        "log-action-filter-import-interwiki": "अंतरविकि आयात",
        "log-action-filter-import-upload": "एक्सएमएल अपलोड द्वारा आयात",
        "log-action-filter-managetags-create": "चिप्पि निर्मित",
+       "log-action-filter-managetags-delete": "टैग हटाना",
+       "log-action-filter-managetags-activate": "टैग सक्रियण",
+       "log-action-filter-managetags-deactivate": "टैग निष्क्रियकरण",
+       "log-action-filter-move-move": "पुननिर्देशों को ओवरराईट किये बिना स्थान्तरण करे",
+       "log-action-filter-move-move_redir": "पुननिर्देशों को ओवरराईट किये स्थान्तरण करे",
        "log-action-filter-newusers-create": "अज्ञात सदस्य द्वारा निर्मित",
        "log-action-filter-newusers-create2": "पंजीकृत सदस्य द्वारा निर्मित",
        "log-action-filter-newusers-autocreate": "स्वतः निर्मित",
        "log-action-filter-suppress-reblock": "पुन: ब्लॉक द्वारा युजर अवरोध",
        "log-action-filter-upload-upload": "नया अपलोड",
        "log-action-filter-upload-overwrite": "फिर से अपलोड",
+       "authmanager-authn-not-in-progress": "प्रमाणीकरण प्रगति में नहीं है या सत्र डेटा खो गया है। कृपया शुरुआत से फिर से शुरू करें",
+       "authmanager-authn-no-primary": "आपूर्ति किए गए क्रेडेंशियल्स को प्रमाणित नहीं किया जा सका।",
+       "authmanager-authn-no-local-user": "दिए गए क्रेडेंशियल इस विकी पर किसी भी उपयोगकर्ता से जुड़े नहीं हैं।",
+       "authmanager-authn-no-local-user-link": "दिए गए क्रेडेंशियल्स मान्य हैं लेकिन इस विकी पर किसी भी उपयोगकर्ता से जुड़े नहीं हैं। किसी अन्य तरीके से लॉगिन करें, या एक नया उपयोगकर्ता बनाएं, और आपके पास उस खाते में अपने पिछले क्रेडेंशियल को लिंक करने का विकल्प होगा।",
+       "authmanager-authn-autocreate-failed": "किसी स्थानीय खाते के स्वत:-निर्माण विफल हुआ:$1",
+       "authmanager-change-not-supported": "आपूर्ति की गई क्रेडेंशियल्स को बदला नहीं जा सकता, क्योंकि उनका उपयोग उनको नहीं होगा।",
        "authmanager-create-disabled": "खाता निर्माण निष्क्रिय है।",
        "authmanager-create-from-login": "अपना खाता बनाने के लिए नीचे दिये जगहों को भर दें।",
+       "authmanager-create-not-in-progress": "खाता निर्माण प्रगति में नहीं है या सत्र डेटा खो गया है। कृपया शुरुआत से फिर से शुरू करें",
+       "authmanager-create-no-primary": "खाता निर्माण के लिए आपूर्ति की गई क्रेडेंशियल्स का उपयोग नहीं किया जा सका।",
+       "authmanager-link-no-primary": "खाता लिंकिंग के लिए आपूर्ति की गई क्रेडेंशियल का उपयोग नहीं किया जा सका।",
+       "authmanager-link-not-in-progress": "खाता लिंक प्रगति में नहीं है या सत्र डेटा खो गया है। कृपया शुरुआत से फिर से शुरू करें",
        "authmanager-authplugin-setpass-failed-title": "पासवर्ड बदलाव विफल हुआ।",
+       "authmanager-authplugin-setpass-failed-message": "प्रमाणन प्लगइन ने पासवर्ड बदलाव से इनकार किया।",
+       "authmanager-authplugin-create-fail": "प्रमाणीकरण प्लग इन ने खाता निर्माण को अस्वीकार कर दिया।",
+       "authmanager-authplugin-setpass-denied": "प्रमाणन प्लगइन पासवर्ड बदलने की अनुमति नहीं देता है",
        "authmanager-authplugin-setpass-bad-domain": "अमान्य जालस्थल।",
        "authmanager-autocreate-noperm": "स्वचालित खाता निर्माण की अनुमति नहीं है।",
        "authmanager-autocreate-exception": "स्वचालित खाता निर्माण को पहले के कुछ त्रुटियों के कारण कुछ समय के लिए निष्क्रिय किया गया है।",
        "authmanager-userdoesnotexist": "सदस्य खाता \"$1\" पंजीकृत नहीं है।",
+       "authmanager-userlogin-remembermypassword-help": "क्या पासवर्ड को सत्र की लंबाई से अधिक समय तक याद रखना चाहिए।",
+       "authmanager-username-help": "प्रमाणीकरण के लिए सदस्य नाम",
+       "authmanager-password-help": "प्रमाणीकरण के लिए पासवर्ड",
+       "authmanager-domain-help": "बाह्य प्रमाणीकरण के लिए डोमेन",
        "authmanager-retype-help": "फिर पासवर्ड डालें।",
        "authmanager-email-label": "ईमेल",
        "authmanager-email-help": "ईमेल पता",
        "authmanager-realname-label": "वास्तविक नाम",
        "authmanager-realname-help": "सदस्य का वास्तविक नाम",
+       "authmanager-provider-password": "पासवर्ड-आधारित प्रमाणीकरण",
+       "authmanager-provider-password-domain": "पासवर्ड- और डोमेन-आधारित प्रमाणीकरण",
        "authmanager-provider-temporarypassword": "अस्थाई पासवर्ड",
+       "authprovider-confirmlink-message": "आपके हाल के लॉगिन प्रयासों के आधार पर, निम्न खाते  आपके विकी खाते से जोड़ा जा सकता है। उन्हें जोड़ने से उन खातों के माध्यम से लॉगिंग सक्षम हो जाता है कृपया चुनें कि कौन सा लिंक होना चाहिए।",
        "authprovider-confirmlink-request-label": "खाते जो जोड़ने हैं।",
        "authprovider-confirmlink-success-line": "$1 : सफलतापूर्वक जुड़ा।",
        "authprovider-confirmlink-failed": "खाता जोड़ने का काम पूरी तरह से नहीं हो पाया : $1",
+       "authprovider-confirmlink-ok-help": "लिंकिंग विफलता संदेशों को प्रदर्शित करने के बाद जारी रखें।",
        "authprovider-resetpass-skip-label": "छोड़ें",
        "authprovider-resetpass-skip-help": "पासवर्ड को रीसेट करना छोड़ें।",
+       "authform-nosession-login": "प्रमाणीकरण सफल था, लेकिन आपका ब्राउज़र \"याद\" नहीं किया जा सकता है।\n\n$1",
+       "authform-nosession-signup": "खाता तो बन चुका है, लेकिन आपका ब्राउज़र \"याद\" नहीं रखा है कि आपने लॉगिन (प्रवेश) कर लिया है। \n\n$1",
        "authform-newtoken": "टोकन लापता है $1",
        "authform-notoken": "टोकन लापता है",
        "authform-wrongtoken": "गलत टोकन",
        "linkaccounts-submit": "खाता जोड़ें",
        "unlinkaccounts": "खाता अलग करें",
        "unlinkaccounts-success": "खाता अलग हो गया।",
+       "authenticationdatachange-ignored": "प्रमाणीकरण डेटा परिवर्तन का संचालन नहीं किया गया था। शायद कोई प्रदाता कॉन्फ़िगर नहीं हुआ था?",
        "userjsispublic": "ध्यान दें: जावास्क्रिप्ट के उपपृष्ठ में कोई भी निजी जानकारी नहीं होनी चाहिए, क्योंकि इसे कोई भी देख सकता है।",
        "usercssispublic": "ध्यान दें: सीसीएस के उपपृष्ठ में कोई भी निजी जानकारी नहीं होनी चाहिए, क्योंकि इसे कोई भी देख सकता है।",
        "restrictionsfield-badip": "अमान्य आईपी पते या सीमा: $1",
        "restrictionsfield-label": "अनुमत आईपी सीमा:",
+       "restrictionsfield-help": "एक आईपी पता या सीडीआरएल सीमा प्रति पंक्ति में लिखें। सभी को सक्रिय करने के लिए <pre>0.0.0.0/0::/0</pre> का उपयोग करें।",
        "revid": "अवतरण $1",
        "pageid": "पेज आईडी $1",
        "rawhtml-notallowed": "&lt;html&gt; टैग का उपयोग सामान्य पन्नों के बाहर नहीं किया जा सकता है।",
index b9e2c4c..c6aed3e 100644 (file)
        "rcfilters-filterlist-title": "Filtri",
        "rcfilters-filterlist-whatsthis": "Što je ovo?",
        "rcfilters-filterlist-feedbacklink": "Napišite povratne informacije vezane za nove (beta) filtere",
-       "rcfilters-highlightbutton-title": "Označavanje rezultata",
+       "rcfilters-highlightbutton-title": "Označi rezultate",
        "rcfilters-highlightmenu-title": "Odaberite boju",
        "rcfilters-highlightmenu-help": "Odaberite boju za označavanje ovog svojstva",
        "rcfilters-filterlist-noresults": "Nema filtera",
        "rcfilters-filter-unregistered-label": "Neprijavljeni",
        "rcfilters-filter-unregistered-description": "Suradnici koji nisu prijavljeni.",
        "rcfilters-filtergroup-authorship": "Doprinosi prema autorima",
+       "rcfilters-filter-editsbyself-label": "Uređivanja koja ste Vi napravili",
        "rcfilters-filter-editsbyself-description": "Vaša uređivanja.",
        "rcfilters-filter-editsbyother-label": "Promjene drugih suradnika",
        "rcfilters-filter-editsbyother-description": "Sve promjene osim Vaših.",
-       "rcfilters-filtergroup-userExpLevel": "Napredni nivo (samo za registrirane suradnike)",
+       "rcfilters-filtergroup-userExpLevel": "Napredna razina (samo za registrirane suradnike)",
        "rcfilters-filter-user-experience-level-newcomer-label": "Novopridošli",
        "rcfilters-filter-user-experience-level-newcomer-description": "Manje od 10 uređivanja i 4 dana aktivnosti.",
-       "rcfilters-filter-user-experience-level-learner-label": "Učenici",
+       "rcfilters-filter-user-experience-level-learner-label": "Početnici",
        "rcfilters-filter-user-experience-level-learner-description": "Više dana aktivnosti i uređivanja od novih ali manje od iskusnih suradnika.",
        "rcfilters-filter-user-experience-level-experienced-label": "Iskusni suradnici",
        "rcfilters-filter-user-experience-level-experienced-description": "Aktivnost više od 30 dana i 500 uređivanja.",
        "rcfilters-filtergroup-automated": "Automatizirani doprinosi",
        "rcfilters-filter-bots-description": "Uređivanja učinjena automatiziranim alatima.",
-       "rcfilters-filter-humans-label": "Čovjek (ne bot)",
+       "rcfilters-filter-humans-label": "Osoba (ne bot)",
        "rcfilters-filter-humans-description": "Uređivanja koja su napravili suradnici.",
-       "rcfilters-filtergroup-reviewstatus": "Status pregledavanja",
+       "rcfilters-filtergroup-reviewstatus": "Stanje pregledanja",
        "rcfilters-filter-patrolled-label": "Ophođeno",
        "rcfilters-filter-patrolled-description": "Uređivanja označena ophođenima.",
        "rcfilters-filter-unpatrolled-label": "Neophođeno",
        "rcfilters-filter-unpatrolled-description": "Uređivanja koja nisu označena ophođenima.",
        "rcfilters-filtergroup-significance": "Važnost",
        "rcfilters-filter-minor-label": "Manja uređivanja",
-       "rcfilters-filter-minor-description": "Uređivanja koja je suradnik označio kao manja.",
+       "rcfilters-filter-minor-description": "Uređivanja koja je suradnik označio manjim.",
        "rcfilters-filter-major-label": "Obična uređivanja",
-       "rcfilters-filter-major-description": "Uređivanja koja nisu označena kao manja.",
+       "rcfilters-filter-major-description": "Uređivanja koja nisu označena manjim.",
        "rcfilters-filtergroup-changetype": "Vrste promjena",
        "rcfilters-filter-pageedits-label": "Uređivanja stranice",
        "rcfilters-filter-pageedits-description": "Uređivanja wikisadržaja, rasprave, opisi kategorija...",
        "rcfilters-filter-newpages-label": "Stvaranje stranica",
        "rcfilters-filter-newpages-description": "Uređivanja kojima su stvorene nove stranice.",
        "rcfilters-filter-categorization-label": "Promjene kategorija",
-       "rcfilters-filter-logactions-label": "Radnje zabilježene u zapisnike",
+       "rcfilters-filter-categorization-description": "Uređivanja kojima se dodaju ili uklanjanju stranice iz kategorija.",
+       "rcfilters-filter-logactions-label": "Radnje zabilježene u evidencijama",
        "rcfilters-filter-logactions-description": "Administrativne radnje, stvaranja računa, brisanje stranica, postavljanja datoteka...",
        "rcnotefrom": "Slijede promjene od <b>$2</b> (prikazano ih je do <b>$1</b>).",
        "rclistfrom": "Prikaži nove promjene počevši od $3 $2",
        "listgrouprights-removegroup-self": "Ukloni {{PLURAL:$2|skupinu|skupine}} iz vlastitog računa: $1",
        "listgrouprights-addgroup-self-all": "Dodaj sve skupine vlastitom računu",
        "listgrouprights-removegroup-self-all": "Uklonite sve skupine iz vlastitog računa",
-       "listgrouprights-namespaceprotection-header": "Ograničenja prostora imena",
+       "listgrouprights-namespaceprotection-header": "Ograničenja imenskoga prostora",
        "listgrouprights-namespaceprotection-namespace": "Imenski prostor",
        "listgrants": "Dozvole",
        "listgrants-summary": "Slijedi popis dozvola s pridruženim pristupom suradničkim pravima. Suradnici mogu omogućiti aplikacijama uporabu svojih računa, ali s ograničenim ovlastima na temelju dozvola koje je suradnik dodijelio aplikaciji. Aplikacija koja djeluje u ime suradnika međutim ne može rabiti prava koje suradnik nema.\nMoguće su [[{{MediaWiki:Listgrouprights-helppage}}|dodatne informacije]] o pojedinim pravima.",
index 89ec36f..2822141 100644 (file)
        "missingcommentheader": "<strong>Emlékeztető:</strong> Nem adtad meg a megjegyzés tárgyát.\nHa ismét a „$1” gombra kattintasz, akkor a szerkesztésed nélküle lesz elmentve.",
        "summary-preview": "A szerkesztési összefoglaló előnézete:",
        "subject-preview": "Tárgy előnézete:",
-       "previewerrortext": "Hiba történt a változások előnézete megjelenítése során.",
+       "previewerrortext": "Hiba történt a változások előnézetének megjelenítése során.",
        "blockedtitle": "A szerkesztő blokkolva van",
        "blockedtext": "<strong>A szerkesztőnevedet vagy az IP-címedet blokkoltuk.</strong>\n\nA blokkolást $1 végezte el.\nAz általa felhozott indok: <em>$2.</em>\n\n* A blokk kezdete: $8\n* A blokk lejárata: $6\n* Blokkolt szerkesztő: $7\n\nKapcsolatba léphetsz $1 szerkesztőnkkel vagy egy másik [[{{MediaWiki:Grouppage-sysop}}|adminisztrátorral]], és megbeszélheted vele a blokkolást.\nAz „E-mail küldése ennek a szerkesztőnek” funkciót csak akkor használhatod, ha érvényes e-mail címet adtál meg [[Special:Preferences|fiókbeállításaidban]], és nem blokkolták a használatát.\nJelenlegi IP-címed: $3, a blokkolás azonosítószáma: #$5.\nKérjük, hogy érdeklődés esetén minden fenti részletet adj meg.",
        "autoblockedtext": "Az IP-címed automatikusan blokkolva lett, mert korábban egy olyan szerkesztő használta, akit $1 blokkolt, az alábbi indoklással:\n\n:''$2''\n\n*A blokk kezdete: '''$8'''\n*A blokk lejárata: '''$6'''\n*Blokkolt szerkesztő: '''$7'''\n\nKapcsolatba léphetsz $1 szerkesztőnkkel, vagy egy másik [[{{MediaWiki:Grouppage-sysop}}|adminisztrátorral]], és megbeszélheted vele a blokkolást.\n\nAz 'E-mail küldése ennek a szerkesztőnek' funkciót csak akkor használhatod, ha érvényes e-mail címet adtál meg\n[[Special:Preferences|fiókbeállításaidban]], és nem blokkolták a használatát.\n\nJelenlegi IP-címed: $3, a blokkolás azonosítószáma: #$5.\nKérjük, hogy érdeklődés esetén mindkettőt add meg.",
index b34f90a..1009800 100644 (file)
        "otherlanguages": "In altere linguas",
        "redirectedfrom": "(Redirigite ab $1)",
        "redirectpagesub": "Pagina de redirection",
-       "redirectto": "Rediriger verso:",
+       "redirectto": "Redirection verso:",
        "lastmodifiedat": "Iste pagina esseva modificate le plus recentemente le $1 a $2.",
        "viewcount": "Iste pagina ha essite visitate {{PLURAL:$1|un vice|$1 vices}}.",
        "protectedpage": "Pagina protegite",
index 4ef4b9d..92d14d2 100644 (file)
        "missingarticle-rev": "(版番号: $1)",
        "missingarticle-diff": "(差分: $1, $2)",
        "readonly_lag": "データベースはスレーブのデータベースサーバーがマスターに同期するまで自動的にロックされています",
+       "nonwrite-api-promise-error": "「Promise-Non-Write-API-Action」HHTPヘッダーが送信されましたが、リクエストはAPI書き込みモジュールに送信されました。",
        "internalerror": "内部エラー",
        "internalerror_info": "内部エラー: $1",
        "internalerror-fatal-exception": "種別「$1」の致命的例外",
        "createacct-email-ph": "メールアドレスを入力",
        "createacct-another-email-ph": "メールアドレスを入力",
        "createaccountmail": "無作為な仮パスワードを生成し、指定のメールアドレスに送信",
+       "createaccountmail-help": "パスワードを知ることなく他の人のためにアカウントを作成するために使用することが出来ます。",
        "createacct-realname": "本名 (省略可能)",
        "createacct-reason": "理由",
        "createacct-reason-ph": "アカウントを作成する理由",
        "botpasswords-deleted-body": "利用者「$2」のボット名「$1」のためのパスワードが削除されました。",
        "botpasswords-newpassword": "<strong>$1</strong>用の新しいパスワードは<strong>$2</strong>です。<em>後で参照するために、この情報を控えておいてください。</em><br />(古いボットの制約などでログイン名と利用者名が同じでなければならない場合は、<strong>$3</strong>を利用者名とし、<strong>$4</strong>をパスワードとしてください。)",
        "botpasswords-no-provider": "BotPasswordsSessionProvider が有効ではありません。",
+       "botpasswords-restriction-failed": "ボットパスワード制限によりログインできません。",
        "botpasswords-invalid-name": "指定された利用者名には、ボット用パスワードの区切りである「$1」 が含まれていません。",
        "botpasswords-not-exist": "利用者「$1」はボット「$2」のパスワードを所持していません。",
        "resetpass_forbidden": "パスワードは変更できません",
        "passwordreset-emailelement": "利用者名: \n$1\n\n仮パスワード: \n$2",
        "passwordreset-emailsentemail": "このメールアドレスがあなたのアカウントに関連付けられている場合は、パスワードリセットのメールが送信されます。",
        "passwordreset-emailsentusername": "この利用者名に関連付けられたメールアドレスがある場合は、パスワードリセットのメールが送信されます。",
+       "passwordreset-nocaller": "送信者の情報を提供する必要があります",
+       "passwordreset-nosuchcaller": "送信者が存在しません: $1",
        "passwordreset-ignored": "パスワードのリセットが処理されませんでした。プロバイダーが設定されていない可能性があります。",
        "passwordreset-invalidemail": "無効なメールアドレスです",
        "passwordreset-nodata": "利用者名もメールアドレスも入力されていません",
        "blockedtitle": "利用者はブロックされています",
        "blockedtext": "<strong>この利用者名またはIPアドレスはブロックされています。</strong>\n\nブロックは$1によって実施されました。\nブロックの理由は <em>$2</em> です。\n\n* ブロック開始日時: $8\n* ブロック解除予定: $6\n* ブロック対象: $7\n\nこのブロックについて、$1もしくは他の[[{{MediaWiki:Grouppage-sysop}}|管理者]]に問い合わせることができます。\nただし、[[Special:Preferences|個人設定]]で有効なメールアドレスが登録されていない場合、またはメール送信機能の使用がブロックされている場合、「この利用者にメールを送信」の機能は使えません。\n現在ご使用中のIPアドレスは$3、このブロックIDは#$5です。\nお問い合わせの際には、上記の情報を必ず書いてください。",
        "autoblockedtext": "このIPアドレスは、$1によりブロックされた利用者によって使用されたため、自動的にブロックされています。\n理由は次の通りです。\n\n:<em>$2</em>\n\n* ブロック開始日時: $8\n* ブロック解除予定: $6\n* ブロック対象: $7\n\n$1または他の[[{{MediaWiki:Grouppage-sysop}}|管理者]]にこのブロックについて問い合わせることができます。\n\nただし、[[Special:Preferences|個人設定]]に正しいメールアドレスが登録されていない場合、またはメール送信がブロックされている場合、「この利用者にメールを送信」機能を使用できないことに注意してください。\n\n現在ご使用中のIPアドレスは$3 、このブロックIDは#$5です。\nお問い合わせの際は、上記の情報を必ず書いてください。",
+       "systemblockedtext": "あなたの利用者名またはIPアドレスはMediaWikiによって自動的にブロックされています。\n理由は次の通りです。\n\n:<em>$2</em>\n\n* ブロック開始日時: $8\n* ブロック解除予定: $6\n* ブロック対象: $7\n\nあなたの現在のIPアドレスは $3 です。\nお問い合わせの際は、上記の詳細情報をすべて含めてください。",
        "blockednoreason": "理由が設定されていません",
        "whitelistedittext": "このページを編集するには$1してください。",
        "confirmedittext": "ページの編集を始める前にメールアドレスの確認をする必要があります。\n[[Special:Preferences|個人設定]]でメールアドレスを設定し、確認を行ってください。",
        "search-external": "外部検索",
        "searchdisabled": "{{SITENAME}}の検索機能は無効化されています。\nさしあたってはGoogleなどで検索できます。\nただし外部の検索エンジンの索引にある{{SITENAME}}のコンテンツは古い場合があります。",
        "search-error": "検索する際にエラーが発生しました: $1",
+       "search-warning": "検索中にエラーが発生しました: $1",
        "preferences": "個人設定",
        "mypreferences": "個人設定",
        "prefs-edits": "編集回数:",
        "right-applychangetags": "自分の編集に[[Special:Tags|タグ]]を適用する",
        "right-changetags": "個々の版と記録項目の任意の[[Special:Tags|タグ]]の追加と削除",
        "right-deletechangetags": "データベースから[[Special:Tags|タグ]]を削除します",
+       "grant-generic": "「$1」の権限バンドル",
+       "grant-group-page-interaction": "ページとの相互作用",
+       "grant-group-file-interaction": "メディアとの相互作用",
+       "grant-group-watchlist-interaction": "ウォッチリストとの相互作用",
        "grant-group-email": "メールの送信",
+       "grant-group-high-volume": "大量の活動を行う",
        "grant-group-customization": "カスタマイズと個人設定",
+       "grant-group-administration": "管理操作を行う",
        "grant-group-private-information": "あなたの個人情報にアクセスする",
        "grant-group-other": "その他の活動",
        "grant-blockusers": "利用者をブロックおよびブロック解除",
        "grant-basic": "基礎的な権限",
        "grant-viewdeleted": "削除されたファイルとページを閲覧",
        "grant-viewmywatchlist": "自身のウォッチリストを閲覧",
+       "grant-viewrestrictedlogs": "制限されたログを表示する",
        "newuserlogpage": "アカウント作成記録",
        "newuserlogpagetext": "以下はアカウント作成の記録です。",
        "rightslog": "利用者権限の変更記録",
        "action-deleterevision": "版の削除",
        "action-deletelogentry": "記録項目の削除",
        "action-deletedhistory": "ページの削除履歴の閲覧",
+       "action-deletedtext": "削除された版の本文を閲覧する",
        "action-browsearchive": "削除されたページの検索",
        "action-undelete": "ページの復元",
        "action-suppressrevision": "隠された版の確認と復元",
        "action-applychangetags": "自分の編集にタグを適用する",
        "action-changetags": "個々の版および記録項目への任意のタグの追加と除去",
        "action-deletechangetags": "データベースからタグの削除",
+       "action-purge": "このページをパージする",
        "nchanges": "$1 {{PLURAL:$1|回の変更}}",
        "enhancedrc-since-last-visit": "最終閲覧以降 $1 {{PLURAL:$1|件}}",
        "enhancedrc-history": "履歴",
        "rcfilters-filter-unregistered-label": "未登録",
        "rcfilters-filter-unregistered-description": "ログインしていない編集者。",
        "rcfilters-filter-unregistered-conflicts-user-experience-level": "この項目は、登録済み利用者を編集回数別で絞り込む以下の{{PLURAL:$2|項目}}と競合しています :$1",
+       "rcfilters-filtergroup-authorship": "自分の編集か他者の編集か",
        "rcfilters-filter-editsbyself-label": "自分の編集",
        "rcfilters-filter-editsbyself-description": "自分の投稿記録を絞り込む",
        "rcfilters-filter-editsbyother-label": "自分以外の編集",
        "rcfilters-filtergroup-userExpLevel": "編集回数別(登録利用者のみが対象)",
        "rcfilters-filtergroup-user-experience-level-conflicts-unregistered": "編集回数別絞り込みは登録利用者のみが対象です。「未登録」の絞り込み項目と競合しています。",
        "rcfilters-filtergroup-user-experience-level-conflicts-unregistered-global": "「未登録」の項目が登録済み利用者を絞り込む項目と競合しています。競合している項目は項目選択欄で強調表示されています。",
-       "rcfilters-filter-user-experience-level-newcomer-label": "æ\96°è¦\8få\8f\82å\8a 者",
+       "rcfilters-filter-user-experience-level-newcomer-label": "æ\96°è¦\8få\88©ç\94¨者",
        "rcfilters-filter-user-experience-level-newcomer-description": "登録から4日以内、かつ10編集以下の利用者",
-       "rcfilters-filter-user-experience-level-learner-label": "ä¸\80è\88¬å\8f\82å\8a 者",
+       "rcfilters-filter-user-experience-level-learner-label": "ä¸\80è\88¬å\88©ç\94¨者",
        "rcfilters-filter-user-experience-level-learner-description": "「新規参加者」よりも活動履歴が長く、「定着参加者」より活動履歴が短い利用者",
-       "rcfilters-filter-user-experience-level-experienced-label": "å®\9aç\9d\80å\8f\82å\8a 者",
+       "rcfilters-filter-user-experience-level-experienced-label": "å®\9aç\9d\80å\88©ç\94¨者",
        "rcfilters-filter-user-experience-level-experienced-description": "30日以上、かつ500編集以上の活動履歴がある利用者",
        "rcfilters-filtergroup-automated": "自動編集",
        "rcfilters-filter-bots-label": "ボット",
        "rcfilters-filter-bots-description": "ツールによって自動化された編集",
        "rcfilters-filter-humans-label": "人間(ボットではない)",
        "rcfilters-filter-humans-description": "人間の手作業による編集",
+       "rcfilters-filtergroup-reviewstatus": "ステータスの確認",
        "rcfilters-filter-patrolled-label": "巡回済み",
        "rcfilters-filter-patrolled-description": "巡回済みとマークされた編集。",
        "rcfilters-filter-unpatrolled-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": "Wikiの項目編集、議論、カテゴリ変更など",
+       "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-label": "操作記録",
        "rcfilters-filter-logactions-description": "アカウント作成、削除、アップロードなどのログに残る管理操作",
        "rcfilters-hideminor-conflicts-typeofchange-global": "「細部の編集」として絞り込めない項目を「細部の編集」として絞り込もうとしています。競合している項目は項目選択欄で強調表示されています。",
        "rcfilters-hideminor-conflicts-typeofchange": "細部の編集として絞り込めない以下の項目を絞り込もうとしています: $1",
        "rcfilters-typeofchange-conflicts-hideminor": "「細部の編集」の絞り込みと競合しています。この項目を「細部の編集」として絞り込むことはできません。",
+       "rcfilters-filtergroup-lastRevision": "最新版",
+       "rcfilters-filter-lastrevision-label": "最新版",
+       "rcfilters-filter-lastrevision-description": "ページの最新の変更",
+       "rcfilters-filter-previousrevision-label": "新しい版",
+       "rcfilters-filter-previousrevision-description": "ページの最新の変更ではない全ての変更。",
        "rcnotefrom": "以下は<strong>$3 $4</strong>以降の{{PLURAL:$5|更新です}} (最大 <strong>$1</strong> 件)。",
        "rclistfromreset": "日時指定をリセット",
        "rclistfrom": "$3の$2以降の更新を表示する",
index 5ae1445..65ed3b1 100644 (file)
        "redirectedfrom": "(გადმომისამართდა $1-დან)",
        "redirectpagesub": "გადამისამართება გვერდზე",
        "redirectto": "გადამისამართება:",
-       "lastmodifiedat": "á\83\94á\83¡ á\83\92á\83\95á\83\94á\83 á\83\93á\83\98 á\83\91á\83\9dá\83\9aá\83\9dá\83¡ á\83\92á\83\90á\83\9cá\83\90á\83®á\83\9aá\83\93á\83\90 $2, $1.",
+       "lastmodifiedat": "á\83\94á\83¡ á\83\92á\83\95á\83\94á\83 á\83\93á\83\98 á\83\91á\83\9dá\83\9aá\83\9dá\83¡ á\83\93á\83\90á\83 á\83\94á\83\93á\83\90á\83¥á\83¢á\83\98á\83 á\83\93á\83\90: $2, $1.",
        "viewcount": "ეს გვერდი შემოწმდა {{PLURAL:$1|ერთხელ|$1-ჯერ}}.",
        "protectedpage": "დაბლოკილი გვერდი",
        "jumpto": "გადასვლა:",
        "page_first": "პირველი",
        "page_last": "ბოლო",
        "histlegend": "ვერსიების შედარება: აირჩიეთ სასურველი ვერსიები რადიო-რგოლების მონიშვნით და დააწკაპუნეთ შედარების ღილაკზე.<br />\nლეგენდა: '''({{int:cur}})''' = სხვაობა მიმდინარე ვერსიასთან, '''({{int:last}})''' = სხვაობა წინა ვერსიასთან, '''{{int:minoreditletter}}''' = მცირე შესწორება.",
-       "history-fieldset-title": "á\83\93á\83\90á\83\97á\83\95á\83\90á\83\9aá\83\98á\83\94á\83 á\83\94á\83\91á\83\98á\83¡ á\83\98á\83¡á\83¢á\83\9dá\83 á\83\98ა",
-       "history-show-deleted": "მხოლოდ წაშლილი",
+       "history-fieldset-title": "á\83\95á\83\94á\83 á\83¡á\83\98á\83\94á\83\91á\83\98á\83¡ á\83«á\83\98á\83\94á\83\91ა",
+       "history-show-deleted": "მხოლოდ წაშლილი ვერსიები",
        "histfirst": "უძველესი",
        "histlast": "უახლესი",
        "historysize": "({{PLURAL:$1|$1 ბაიტი|$1 ბაიტი}})",
        "search-interwiki-caption": "დობილი პროექტები",
        "search-interwiki-default": "შედეგები $1-დან:",
        "search-interwiki-more": "(გაგრძელება)",
+       "search-interwiki-more-results": "მეტი შედეგი",
        "search-relatedarticle": "დაკავშირებული",
        "searchrelated": "მიბმული",
        "searchall": "ყველა",
        "prefs-help-recentchangescount": "შეიცავს ახალ შესწორებებს, გვერდების ისტორიებს, ჟურნალებს.",
        "prefs-help-watchlist-token2": "ეს არის საიდუმლო გასაღები თქვენი კონტროლის სიის ვებ-არხისთვის. ნებისმიერს, ვინც იცის ის, შეუძლია წაიკითხოს თქვენი კონტროლის სია, ამიტომ არ გაუზიაროთ იგი სხვებს. [[Special:ResetTokens|თქვენ შეგიძლიათ ჩამოყაროთ ის]].",
        "savedprefs": "თქვენ მიერ შერჩეული პარამეტრები დამახსოვრებულია.",
-       "savedrights": "á\83\9bá\83\9dá\83\9bá\83®á\83\9bá\83\90á\83 á\83\94á\83\91á\83\9aá\83\98á\83¡ {{GENDER:$1|$1}} á\83£á\83¤á\83\9aá\83\94á\83\91ები შენახულია",
+       "savedrights": "á\83\9bá\83\9dá\83\9bá\83®á\83\9bá\83\90á\83 á\83\94á\83\91á\83\9aá\83\98á\83¡ {{GENDER:$1|$1}} á\83¯á\83\92á\83£á\83¤ები შენახულია",
        "timezonelegend": "სასაათო სარტყელი:",
        "localtime": "ადგილობრივი დრო:",
        "timezoneuseserverdefault": "გამოიყენე ნაგულისხმევი პარამეტრები ($1)",
        "username": "{{GENDER:$1|მომხმარებლის სახელი}}:",
        "prefs-memberingroups": "{{PLURAL:$1|ჯგუფის|ჯგუფების}} {{GENDER:$2|წევრი}}:",
        "prefs-memberingroups-type": "$1",
+       "group-membership-link-with-expiry": "$1 ($2-მდე)",
        "prefs-registration": "რეგისტრაციის თარიღი",
        "prefs-registration-date-time": "$1",
        "yourrealname": "ნამდვილი სახელი:",
        "prefs-help-prefershttps": "ამ კონფიგურაციის არჩევა შედეგს გამოიღებს შემდგომი ავტორიზაციის შედმეგ.",
        "prefswarning-warning": "თქვენ შეიტანეთ ცვლილება თქვენ პარამეტრებში, რომელიც ჯერ კიდევ არ არის შენახული. თუ თქვენ დატოვებთ ამ გვერდს და არ დააჭერთ \"$1\"-ს, პარამეტრები არ იქნება განახლებული.",
        "prefs-tabs-navigation-hint": "რჩევა: თქვენ შეგიძლიათ გამოიყენოთ ისრის კლავიშები მარცხნივ ან მარჯვნივ ჩანართებსა და ჩანართბის სიას შორის არსებული გადასვლებისათვის",
-       "userrights": "მომხმარებელთა უფლებების მართვა",
-       "userrights-lookup-user": "á\83\9bá\83\9dá\83\9bá\83®á\83\9bá\83\90á\83 á\83\94á\83\91á\83\94á\83\9aá\83\97á\83\90 á\83¯á\83\92á\83£á\83¤á\83\94á\83\91á\83\98á\83¡ á\83\9bá\83\90á\83 á\83\97ვა",
+       "userrights": "მომხმარებელთა უფლებები",
+       "userrights-lookup-user": "á\83\9bá\83\9dá\83\9bá\83®á\83\9bá\83\90á\83 á\83\94á\83\91á\83\9aá\83\98á\83¡ á\83\90á\83 á\83©á\83\94ვა",
        "userrights-user-editname": "შეიყვანეთ მომხმარებლის სახელი:",
-       "editusergroup": "{{GENDER:$1|მომხმარებელთა}} ჯგუფების რედაქტირება",
+       "editusergroup": "მომხმარებელთა ჯგუფების ჩატვირთვა",
        "editinguser": "უფლებების შეცვლა {{GENDER:$1|მომხმარებლისთვის}} <strong>[[User:$1|$1]]</strong> $2",
        "viewinguserrights": "{{GENDER:$1|მომხმარებლის}} უფლებების ხილვა <strong>[[User:$1|$1]]</strong> $2",
-       "userrights-editusergroup": "დაარედაქტირეთ მომხმარებელთა ჯგუფები",
+       "userrights-editusergroup": "{{GENDER:$1|მომხმარებელთა}} ჯგუფების რედაქტირება",
        "userrights-viewusergroup": "{{GENDER:$1|მომხმარებლის}} ჯგუფების ხილვა",
        "saveusergroups": "{{GENDER:$1|მომხმარებელთა}} ჯგუფების შენახვა",
        "userrights-groupsmember": "ჯგუფის წევრი:",
        "action-userrights-interwiki": "მომხმარებლების უფლებების შეცვლა სხვა ვიკიებში",
        "action-siteadmin": "მონაცემთა ბაზის დაბლოკვა და განბლოკვა",
        "action-sendemail": "ელ-ფოსტების გაგზავნა",
+       "action-editmyoptions": "თქვენი კონფიგურაციის რედაქტირება",
        "action-editmywatchlist": "თქვენი კონტროლის სიის რედაქტირება",
        "action-viewmywatchlist": "თქვენი კონტროლის სიის ხილვა",
        "action-viewmyprivateinfo": "თქვენი პირადი ინფორმაციის ხილვა",
        "rcfilters-activefilters": "აქტიური ფილტრები",
        "rcfilters-clear-all-filters": "ყველა ფილტრის გაწმენდა",
        "rcfilters-search-placeholder": "ფილტრის ბოლო ცვლილებები (დაათვალიერეთ ან დაიწყეთ შეყვანა)",
+       "rcfilters-invalid-filter": "არასწორი ფილტრი",
        "rcfilters-filterlist-title": "ფილტრები",
+       "rcfilters-filterlist-whatsthis": "ეს რა არის?",
        "rcfilters-filterlist-feedbacklink": "შეტყობინების დატოვება ახალი (ბეტა) ფილტრების შესახებ",
        "rcfilters-highlightbutton-title": "შედეგების მონიშვნა",
        "rcfilters-highlightmenu-title": "ფერის არჩევა",
        "rcfilters-highlightmenu-help": "აირჩიეთ ფერი, რათა მონიშნოთ ეს თვისება",
+       "rcfilters-filterlist-noresults": "ფილტრები ვერ მოძებნა",
        "rcfilters-filtergroup-registration": "მომხმარებლის რეგისტრაცია",
        "rcfilters-filter-registered-label": "რეგისტრირებულები",
        "rcfilters-filter-registered-description": "შესული რედაქტორები.",
        "upload-dialog-disabled": "ფაილის ატვირთვა ამ დიალოგური ფანჯრით გათიშულია ამ ვიკიზე.",
        "upload-dialog-title": "ფაილის ატვირთვა",
        "upload-dialog-button-cancel": "გაუქმება",
+       "upload-dialog-button-back": "უკან",
        "upload-dialog-button-done": "შესრულდა",
        "upload-dialog-button-save": "შენახვა",
        "upload-dialog-button-upload": "ატვირთვა",
        "apisandbox-results-fixtoken-fail": "ვერ მოხერხდა $1 ტოკენის მოძიება.",
        "apisandbox-alert-page": "ველები ამ გვერდზე არ არის ვალიდური",
        "apisandbox-alert-field": "ამ ველის მნიშვნელობა არ არის ვალიდური",
+       "apisandbox-continue": "გაგრძელება",
+       "apisandbox-continue-clear": "გასუფთავება",
+       "apisandbox-multivalue-all-namespaces": "$1 (ყველა სახელთა სივრცე)",
+       "apisandbox-multivalue-all-values": "$1 (ყველა მნიშვნელობა)",
        "booksources": "წიგნის წყაროები",
        "booksources-search-legend": "წიგნის წყაროს ძებნა",
        "booksources-isbn": "ISBN:",
        "enotif_body_intro_restored": "$PAGEEDITDATE {{gender:$2|მომხმარებელმა}} $2 აღადგინა გვერდი პროექტიდან „{{SITENAME}}“ სახელწოდებით „$1“, მიმდინარე ვერსია იხილიეთ ბმულზე: $3",
        "enotif_body_intro_changed": "$PAGEEDITDATE {{gender:$2|მომხმარებელმა}} $2 შეცვალა გვერდი პროექტიდან „{{SITENAME}}“ სახელწოდებით „$1“, მიმდინარე ვერსია იხილიეთ ბმულზე: $3",
        "enotif_lastvisited": "იხ. $1 ყველა ცვლილებისთვის თქვენი ბოლო შემოსვლის შემდეგ.",
-       "enotif_lastdiff": "á\83\98á\83®á\83\98á\83\9aá\83\94á\83\97 $1 á\83\90á\83\9b á\83ªá\83\95á\83\9aá\83\98á\83\9aá\83\94á\83\91á\83\98á\83¡ á\83¡á\83\90á\83\9cá\83\90á\83®á\83\90á\83\95á\83\90á\83\93.",
+       "enotif_lastdiff": "á\83\90á\83\9b á\83ªá\83\95á\83\9aá\83\98á\83\9aá\83\94á\83\91á\83\98á\83¡ á\83¡á\83\90á\83\9cá\83\90á\83®á\83\90á\83\95á\83\90á\83\93, á\83\98á\83®á\83\98á\83\9aá\83\94á\83\97 $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\t\t\t {{SITENAME}} შეტყობინებათა სისტემა\n\n--\nშეტყობინების პარამეტრების ცვლილება\n{{canonicalurl:{{#special:Preferences}}}}\n\nთქვენი კონტროლის სიის პარამეტრების ცვლილება\n{{canonicalurl:{{#special:EditWatchlist}}}}\n\nგვერდების ამოშლა თქვენი კონტროლის სიიდან\n$UNWATCHURL\n\nდამატებითი ინფორმაცია\n$HELPPAGE",
        "created": "შექმნილია",
        "modifiedarticleprotection": "შეცვლილია დაცვის დონე გვერდისთვის „[[$1]]“",
        "unprotectedarticle": "„[[$1]]“-დან დაცვა მოხსნილია",
        "movedarticleprotection": "დაცვის პარამეტრების გადატანა გვერდიდან „[[$2]]“ გვერდზე „[[$1]]“",
+       "protectedarticle-comment": "მომხმარებელმა {{GENDER:$2|დაიცვა}} „[[$1]]“",
+       "modifiedarticleprotection-comment": "მომხმარებელმა {{GENDER:$2|შეცვალა დაცვის დონე}} „[[$1]]“-ზე",
+       "unprotectedarticle-comment": "მომხარებელმა {{GENDER:$2|მოხსნა დაცვა}} „[[$1]]“-დან",
        "protect-title": "დაცვის დონის შეცვლა გვერდისთვის „$1“",
        "protect-title-notallowed": "დაცვის დონის ხილვა გვერდისთვის „$1“",
        "prot_1movedto2": "[[$1]] გადატანილია გვერდზე [[$2]]",
        "sp-contributions-uploads": "ატვირთვები",
        "sp-contributions-logs": "ჟურნალები",
        "sp-contributions-talk": "განხილვა",
-       "sp-contributions-userrights": "á\83\9bá\83\9dá\83\9bá\83®á\83\9bá\83\90á\83 á\83\94á\83\91á\83\94á\83\9aá\83\97á\83\90 á\83£á\83¤á\83\9aá\83\94á\83\91á\83\94á\83\91á\83\98á\83¡ მართვა",
+       "sp-contributions-userrights": "á\83\9bá\83\9dá\83\9bá\83®á\83\9bá\83\90á\83 á\83\94á\83\91á\83\9aá\83\98á\83¡ {{GENDER:$1|á\83£á\83¤á\83\9aá\83\94á\83\91á\83\94á\83\91á\83\98á\83¡}} მართვა",
        "sp-contributions-blocked-notice": "ეს მომხმარებელი ამჟამად დაბლოკილია. ქვემოთ მოყვანილია ამონაწერი წაშლათა ჟურნალიდან:",
        "sp-contributions-blocked-notice-anon": "ეს მომხმარებელი ამჟამად დაბლოკილია.\nქვემოთ მოყვანილია ამონაწერი წაშლათა ჟურნალიდან:",
        "sp-contributions-search": "წვლილის ძიება",
        "unblocked-id": "ბლოკი $1 მოიხსნა",
        "unblocked-ip": "[[Special:Contributions/$1|$1]] განიბლოკა.",
        "blocklist": "დაბლოკილი მომხმარებლები",
+       "autoblocklist": "ავტობლოკირება",
+       "autoblocklist-submit": "ძიება",
+       "autoblocklist-legend": "ავტობლოკირებების სია",
+       "autoblocklist-localblocks": "ადგილობრივი {{PLURAL:$1|ავტობლოკი|ავტობლოკირებები}}",
+       "autoblocklist-empty": "ავტობლოკირებების სია ცარიელია.",
+       "autoblocklist-otherblocks": "სხვა {{PLURAL:$1|ავტობლოკი|ავტობლოკირებები}}",
        "ipblocklist": "დაბლოკილი მომხმარებლები",
        "ipblocklist-legend": "დაბლოკილი მომხმარებლის პოვნა",
        "blocklist-userblocks": "დამალე ანგარიშის ბლოკირებები",
        "anonymous": "{{SITENAME}}-ის ანონიმური {{PLURAL:$1|მომხმარებელი|მომხმარებლები}}",
        "siteuser": "{{SITENAME}} მომხმარებელი $1",
        "anonuser": "{{SITENAME}} ანონიმური მომხმარებელი $1",
-       "lastmodifiedatby": "á\83\94á\83¡ á\83\92á\83\95á\83\94á\83 á\83\93á\83\98 á\83\91á\83\9dá\83\9aá\83\9dá\83¡ á\83¨á\83\94á\83\98á\83ªá\83\95á\83\90á\83\9aá\83\90 $2, $1  $3-á\83\98á\83\97.",
+       "lastmodifiedatby": "á\83\94á\83¡ á\83\92á\83\95á\83\94á\83 á\83\93á\83\98 á\83\91á\83\9dá\83\9aá\83\9dá\83¡ á\83\93á\83\90á\83 á\83\94á\83\93á\83\90á\83¥á\83¢á\83\98á\83 á\83\93á\83\90: $2, $1  á\83ªá\83\95á\83\9aá\83\98á\83\9aá\83\94á\83\91á\83\94á\83\91á\83\98á\83¡ á\83\90á\83\95á\83¢á\83\9dá\83 á\83\98 â\80\94 $3.",
        "othercontribs": "$1-ს ნამუშევრის მიხედვით.",
        "others": "სხვები",
        "siteusers": "{{SITENAME}}-ის {{PLURAL:$2|{{GENDER:$1|მომხმარებელი}}|მომხმარებლები}} $1",
        "pageinfo-length": "გვერდის სიგრძე (ბაიტებში)",
        "pageinfo-article-id": "გვერდის ID",
        "pageinfo-language": "გვერდის შინაარსის ენა",
+       "pageinfo-language-change": "შეცვლა",
        "pageinfo-content-model": "გვერდის შინაარსის მოდელი",
+       "pageinfo-content-model-change": "შეცვლა",
        "pageinfo-robot-policy": "ინდექსაცია საძიებო რობოტებით",
        "pageinfo-robot-index": "დაშვებულია",
        "pageinfo-robot-noindex": "არ არის დაშვებული",
        "pageinfo-category-pages": "გვერდების რაოდენობა",
        "pageinfo-category-subcats": "ქვეკატეგორიების რაოდენობა",
        "pageinfo-category-files": "ფაილების რაოდენობა",
+       "pageinfo-user-id": "მომხმარებლის იდენტიფიკატორი",
        "markaspatrolleddiff": "მონიშნე როგორც პატრულირებული",
        "markaspatrolledtext": "მონიშნე ეს სტატია როგორც პატრულირებული",
        "markaspatrolledtext-file": "მონიშნეთ ამ ფაილის ვერსია, როგორც პატრულირებული",
        "patrol-log-header": "ეს არის პატრულირებულ ვერსიათა ჟურნალი.",
        "log-show-hide-patrol": "$1 პატრულირების ჟურნალი",
        "log-show-hide-tag": "$1 დასათაურების ჟურნალი",
+       "confirm-markpatrolled-button": "კარგი",
        "deletedrevision": "წაშლილია ძველი ვერსია $1.",
        "filedeleteerror-short": "შეცდომა ფაილის $1 წაშლისას",
        "filedeleteerror-long": "ფაილის წაშლისას წარმოიშვა შეცდომები:\n\n$1",
        "newimages-summary": "ეს სპეცგვერდი აჩვენებს ბოლო დროს ატვირთულ ფაილებს.",
        "newimages-legend": "ფილტრი",
        "newimages-label": "ფაილის (ან მისი სახელის) ნაწილი",
+       "newimages-user": "IP მისამართი ან მომხმარებლის სახელი",
        "newimages-showbots": "ბოტის ატვირთვების ჩვენება",
        "newimages-hidepatrolled": "დამალე შემოწმებული ატვირთვები",
        "noimages": "გადასახედი არაფერია.",
        "htmlform-cloner-create": "მეტის დამატება",
        "htmlform-cloner-delete": "წაშლა",
        "htmlform-cloner-required": "აუცილებელია სულ მცირე ერთი მნიშვნელობა.",
+       "htmlform-date-placeholder": "წწწწ-თთ-დდ",
+       "htmlform-time-placeholder": "სთ:წთ:წმ",
+       "htmlform-datetime-placeholder": "წწწწ-თთ-დდ სთ:წთ:წმ",
        "htmlform-title-badnamespace": "[[:$1]] არ მდებარეობს \"{{ns:$2}}\"-ის სახელთა სივრცეში.",
        "htmlform-title-not-creatable": "$1\" არ არის მართებული გვერდის სათაური",
        "htmlform-title-not-exists": "$1 არ არსებობს.",
        "htmlform-user-not-valid": "<strong>$1</strong> არ არის სწორი მომხმარებლის სახელი.",
        "logentry-delete-delete": "მომხმარებელმა $1 {{GENDER:$2|წაშალა}} გვერდი: „$3“",
        "logentry-delete-delete_redir": "მომხმარებელმა $1 {{GENDER:$2|წაშალა}} გადამისამართება $3 გადაწერით",
-       "logentry-delete-restore": "მომხმარებელმა $1 {{GENDER:$2|აღადგინა}} გვერდი $3",
+       "logentry-delete-restore": "მომხმარებელმა $1 {{GENDER:$2|აღადგინა}} გვერდი $3 ($4)",
+       "logentry-delete-restore-nocount": "მომხმარებელმა $1 {{GENDER:$2|აღადგინა}} გვერდი $3",
+       "restore-count-revisions": "{{PLURAL:$1|1 ვერსია|$1 ვერსია}}",
+       "restore-count-files": "{{PLURAL:$1|1 ფაილი|$1 ფაილი}}",
        "logentry-delete-event": "მომხმარებელმა $1 {{GENDER:$2|შეცვალა}} {{PLURAL:$5|ჟურნალის ჩანაწერის|$5 ჟურნალის ჩანაწერების}} ხილვადობა $3-ზე: $4",
        "logentry-delete-revision": "მომხმარებელმა $1 {{GENDER:$2|შეცვალა}} {{PLURAL:$5|$5 ვერსიის|$5 ვერსიის}} ხილვადობა გვერდისათვის $3: $4",
        "logentry-delete-event-legacy": "მომხმარებელმა $1 {{GENDER:$2|შეცვალა}} ჩანაწერების ჟურნალის ხილვადობა $3-ზე",
        "pagelang-language": "ენა",
        "pagelang-use-default": "საწყისი ენის გამოყენება",
        "pagelang-select-lang": "აირჩიეთ ენა",
+       "pagelang-reason": "მიზეზი",
        "pagelang-submit": "გაგზავნა",
+       "pagelang-nonexistent-page": "გვერდი $1 არ არსებობს.",
        "right-pagelang": "გვერდის ენის შეცვლა",
        "action-pagelang": "გვერდის ენის შეცვლა",
        "log-name-pagelang": "ენის ცვლილებების ჟურნალი",
        "special-characters-group-thai": "ტაილანდური",
        "special-characters-group-lao": "ლაოსური",
        "special-characters-group-khmer": "ქჰმერული",
+       "special-characters-group-canadianaboriginal": "კანადური აბორიგენული",
        "special-characters-title-endash": "ტირე",
        "special-characters-title-emdash": "გრძელი ტირე",
        "special-characters-title-minus": "მინუსის ნიშანი",
        "mw-widgets-dateinput-no-date": "თარიღი არ არის არჩეული",
        "mw-widgets-dateinput-placeholder-day": "წწწწ-თთ-დდ",
        "mw-widgets-dateinput-placeholder-month": "წწწწ-თთ",
+       "mw-widgets-mediasearch-input-placeholder": "მულტიმედიის ძიება",
        "mw-widgets-mediasearch-noresults": "შედეგები ვერ მოიძებნა.",
        "mw-widgets-titleinput-description-new-page": "გვერდი ჯერ არ არსებობს",
        "mw-widgets-titleinput-description-redirect": "გადამისამართება $1-ზე",
+       "mw-widgets-categoryselector-add-category-placeholder": "კატეგორიის დამატება...",
+       "mw-widgets-usersmultiselect-placeholder": "კიდევ დამატება...",
        "sessionmanager-tie": "შეუძლებელია მრავალი მოთხოვნის ავთენთიფიკაციის ტიპების გაერთიანება: $1.",
        "sessionprovider-generic": "$1 სესიები",
        "sessionprovider-mediawiki-session-cookiesessionprovider": "cookie-სთან დაკავშირებული სესიები",
index def8db2..b83572c 100644 (file)
@@ -30,7 +30,8 @@
                        "రహ్మానుద్దీన్",
                        "ಶಿವಕುಮಾರ್ ನಾಯಕ್",
                        "Yogesh",
-                       "Lokesha kunchadka"
+                       "Lokesha kunchadka",
+                       "Anoop rao"
                ]
        },
        "tog-underline": "ಕೊಂಡಿಗಳ ಕೆಳಗೆ ಗೆರೆ ತೋರಿಸಿ",
        "tog-showtoolbar": "ಸಂಪಾದನೆಯ ಉಪಕರಣಗಳ ಪಟ್ಟಿಯನ್ನು ತೋರು",
        "tog-editondblclick": "ಎರಡು ಬಾರಿ ಕ್ಲಿಕ್ ಮಾಡಿದಾಗ ಪುಟವು ಸಂಪಾದಿಸುವಂತಾಗಲಿ",
        "tog-editsectiononrightclick": "ಪುಟದ ವಿಭಾಗಗಳನ್ನು ಅವುಗಳ ಶೀರ್ಷಿಕೆಯನ್ನು ಎರಡು ಬಾರಿ ಕ್ಲಿಕ್ ಮಾಡಿ ಸಂಪಾದನೆ ಮಾಡುವಂತೆ ಇರಲಿ",
-       "tog-watchcreations": "ನಾನು ಪ್ರಾರಂಭಿಸುವ ಲೇಖನಗಳನ್ನು ನನ್ನ ವೀಕ್ಷಣಾಪಟ್ಟಿಗೆ ಸೇರಿಸು",
-       "tog-watchdefault": "ನಾನು ಸಂಪಾದಿಸುವ ಪುಟಗಳನ್ನು ವೀಕ್ಷಣಾಪಟ್ಟಿಗೆ ಸೇರಿಸು",
-       "tog-watchmoves": "ನಾನು ಸ್ಥಳಾಂತರಿಸುವ ಪುಟಗಳನ್ನು ನನ್ನ ವೀಕ್ಷಣಾಪಟ್ಟಿಗೆ ಸೇರಿಸು",
-       "tog-watchdeletion": "ನಾನು ಅಳಿಸುವ ಪುಟಗಳನ್ನು ನನ್ನ ವೀಕ್ಷಣಾ ಪಟ್ಟಿಗೆ ಸೇರಿಸು",
+       "tog-watchcreations": "ನಾನà³\81 à²ªà³\8dರಾರà²\82ಭಿಸà³\81ವ à²²à³\87à²\96ನà²\97ಳನà³\8dನà³\81 à²®à²¤à³\8dತà³\81 à²\95ಡತà²\97ಳನà³\8dನà³\81 à²¨à²¨à³\8dನ à²µà³\80à²\95à³\8dಷಣಾಪà²\9fà³\8dà²\9fಿà²\97à³\86 à²¸à³\87ರಿಸà³\81",
+       "tog-watchdefault": "ನಾನà³\81 à²¸à²\82ಪಾದಿಸà³\81ವ à²ªà³\81à²\9fà²\97ಳನà³\8dನà³\81 à²®à²¤à³\8dತà³\81 à²\95ಡತà²\97ಳನà³\8dನà³\81 à²µà³\80à²\95à³\8dಷಣಾಪà²\9fà³\8dà²\9fಿà²\97à³\86 à²¸à³\87ರಿಸà³\81",
+       "tog-watchmoves": "ನಾನà³\81 à²¸à³\8dಥಳಾà²\82ತರಿಸà³\81ವ à²ªà³\81à²\9fà²\97ಳನà³\8dನà³\81 à²®à²¤à³\8dತà³\81 à²\95ಡತà²\97ಳನà³\8dನà³\81 à²¨à²¨à³\8dನ à²µà³\80à²\95à³\8dಷಣಾಪà²\9fà³\8dà²\9fಿà²\97à³\86 à²¸à³\87ರಿಸà³\81",
+       "tog-watchdeletion": "ನಾನà³\81 à²\85ಳಿಸà³\81ವ à²ªà³\81à²\9fà²\97ಳನà³\8dನà³\81 à²®à²¤à³\8dತà³\81 à²\95ಡತà²\97ಳನà³\8dನà³\81 à²¨à²¨à³\8dನ à²µà³\80à²\95à³\8dಷಣಾ à²ªà²\9fà³\8dà²\9fಿà²\97à³\86 à²¸à³\87ರಿಸà³\81",
        "tog-watchuploads": "ನಾನು ಹೊಸದಾಗಿ ಅಪ್‍ಲೋಡ್ ಮಾಡಿದ ಫೈಲ್‍ಗಳನ್ನು ನನ್ನ ವೀಕ್ಷಣಾಪಟ್ಟಿಗೆ ಸೇರಿಸು",
        "tog-watchrollback": "ನಾನು ಹಿಮ್ಮರಳುವಿಕೆಯನ್ನು ನಡೆಸಿದ ಪುಟಗಳನ್ನು ನನ್ನ ಗಮನಸೂಚಿಗೆ ಸೇರಿಸು",
        "tog-minordefault": "ನನ್ನ ಎಲ್ಲಾ ಸಂಪಾದನೆಗಳನ್ನು ಚುಟುಕಾದವು ಎಂದು ಗುರುತು ಮಾಡು",
@@ -59,7 +60,7 @@
        "tog-enotifrevealaddr": "ಪ್ರಕಟಣೆ ಇ-ಅಂಚೆಗಳಲ್ಲಿ ನನ್ನ ಇ-ಅಂಚೆ ವಿಳಾಸ ತೋರು",
        "tog-shownumberswatching": "ಪುಟವನ್ನು ವೀಕ್ಷಿಸುತ್ತಿರುವ ಸದಸ್ಯರ ಸಂಖ್ಯೆಯನ್ನು ತೋರಿಸು",
        "tog-oldsig": "ನಿಮ್ಮ ಪ್ರಸ್ತುತ ಸಹಿ",
-       "tog-fancysig": "ಸರಳ à²¸à²¹à²¿à²\97ಳà³\81 (à²\95à³\8aà²\82ಡಿ à²\87ಲà³\8dಲದಿರà³\81ವà²\82ತೆ)",
+       "tog-fancysig": "ಸಹಿà²\97ಳನà³\8dನà³\81 à²µà²¿à²\95ಿà²\9fà³\86à²\95à³\8dಸà³\8d à²\8eà²\82ದà³\81 à²ªà²°à²¿à²\97ಣಿಸಿ (ಸà³\8dವಯà²\82à²\9aಾಲಿತ à²²à²¿à²\82à²\95à³\8d à²\87ಲà³\8dಲದೆ)",
        "tog-uselivepreview": "ನೇರ ಮುನ್ನೋಟವನ್ನು ಉಪಯೋಗಿಸಿ",
        "tog-forceeditsummary": "ಸಂಪಾದನೆ ಸಾರಾಂಶವನ್ನು ಖಾಲಿ ಬಿಟ್ಟಲ್ಲಿ ನೆನಪಿಸು",
        "tog-watchlisthideown": "ವೀಕ್ಷಣಾ ಪಟ್ಟಿಯಲ್ಲಿ ನನ್ನ ಸಂಪಾದನೆಗಳನ್ನು ತೋರಿಸಬೇಡ",
        "tog-watchlisthideliu": "ಲಾಗ್ ಇನ್ ಆಗಿರುವ ಸದಸ್ಯರ ಸಂಪಾದನೆಗಳನ್ನು ವೀಕ್ಷಣಾಪಟ್ಟಿಯಲ್ಲಿ ಅಡಗಿಸು",
        "tog-watchlistreloadautomatically": "ಯಾವುದೇ ಫಿಲ್ಟರು ಬದಲಾದಾಗ ವೀಕ್ಷಣಾಪಟ್ಟಿ ಮತ್ತೆ ಲೋಡ್ ಆಗಲಿ (ಜಾವಾಸ್ಕ್ರಿಪ್ಟ್ ಇರಬೇಕು)",
        "tog-watchlisthideanons": "ಅನಾಮಧೇಯ ಬಳಕೆದಾರರ ಸಂಪಾದನೆಗಳನ್ನು ವೀಕ್ಷಣಾಪಟ್ಟಿಯಲ್ಲಿ ಅಡಗಿಸು",
-       "tog-watchlisthidepatrolled": "ವà³\80à²\95à³\8dಷಣಾ à²ªà²¤à³\8dತಿಯಲà³\8dಲಿ à²¹à²¸à³\8dತà³\81à²\95ದರà³\8d ಬದಲಾವಣೆಗಳನ್ನು ಅದಗಿಸು",
+       "tog-watchlisthidepatrolled": "ವà³\80à²\95à³\8dಷಣಾ à²ªà²\9fà³\8dà²\9fಿಯಲà³\8dಲಿ à²\97ಸà³\8dತà³\81 à²¤à²¿à²°à³\81à²\97ಿದ ಬದಲಾವಣೆಗಳನ್ನು ಅದಗಿಸು",
        "tog-watchlisthidecategorization": "ಪುಟಗಳ ವರ್ಗೀಕರಣವನ್ನು ಅಡಗಿಸು",
        "tog-ccmeonemails": "ಇತರರಿಗೆ ನಾನು ಕಳುಹಿಸುವ ಇ-ಅಂಚೆಯ ಪ್ರತಿಯನ್ನು ನನಗೂ ಕಳುಹಿಸು",
        "tog-diffonly": "ವ್ಯತ್ಯಾಸಗಳ ಕೆಳಗಿರುವ ಪುಟದ ವಿವರಗಳನ್ನು ತೋರಿಸಬೇಡ",
        "tog-showhiddencats": "ಅಡಗಿಸಲ್ಪಟ್ಟ ವರ್ಗಗಳನ್ನು ತೋರಿಸು",
-       "tog-norollbackdiff": "ತà³\8aಡà³\86ದà³\81ಹಾà²\95ಿದ ನಂತರ ವ್ತ್ಯತ್ಯಾಸವನ್ನು ತೋರಿಸಬೇಡ",
+       "tog-norollbackdiff": "ಹಿಮà³\8dಮರಳà³\81ವಿà²\95à³\86ಯ ನಂತರ ವ್ತ್ಯತ್ಯಾಸವನ್ನು ತೋರಿಸಬೇಡ",
        "tog-useeditwarning": "ಸಂಪಾದನೆಯನ್ನು ಉಳಿಸದೆ ಹೊರಟಲ್ಲಿ ನನಗೆ ಎಚ್ಚರಿಸು",
        "tog-prefershttps": "ಯಾವತ್ತು ಸಹ ಲಾಗಿನ್ ನಂತರ ಸುರಕ್ಷಿತ ಸಂಪರ್ಕವನ್ನು ಬಳಸಿ",
        "underline-always": "ಯಾವಾಗಲೂ",
        "underline-never": "ಎಂದಿಗೂ ಇಲ್ಲ",
        "underline-default": "ಬ್ರೌಸರ್‍ನ ಯಥಾಸ್ಥಿತಿ",
        "editfont-style": "ಬದಲಾಣೆಯ ಜಾಗಾದ ಬರಿಯುವ ಶೈಲ",
-       "editfont-default": "ಬà³\8dರà³\8cಸರದ ಯಥಾಸ್ಥಿತಿ",
-       "editfont-monospace": "à²\92à²\82ದà³\81ಸà³\8dಥಳದ ಮುದ್ರಲಿಪಿ",
+       "editfont-default": "ಬà³\8dರà³\8cಸರà³\8dâ\80\8dನ ಯಥಾಸ್ಥಿತಿ",
+       "editfont-monospace": "ಮà³\8aನà³\8aಸà³\8dಪà³\87ಸà³\8d ಮುದ್ರಲಿಪಿ",
        "editfont-sansserif": "ಸಾನ್ಸ್-ಸೆರಿಫ಼್ ಮುದ್ರಲಿಪಿ",
        "editfont-serif": "ಸೆರಿಫ಼್ ಮುದ್ರಲಿಪಿ",
        "sunday": "ಭಾನುವಾರ",
        "searcharticle": "ಹೋಗು",
        "history": "ಪುಟದ ಇತಿಹಾಸ",
        "history_short": "ಇತಿಹಾಸ",
+       "history_small": "ಇತಿಹಾಸ",
        "updatedmarker": "ನನ್ನ ಕೊನೆಯ ವೀಕ್ಷಣೆಯ ನಂತರ ಬದಲಾಗಿರುವವು",
        "printableversion": "ಪ್ರಿಂಟ್ ಆವೃತ್ತಿ",
        "permalink": "ಸ್ಥಿರ ಕೊಂಡಿ",
        "talk": "ಚರ್ಚೆ",
        "views": "ನೋಟಗಳು",
        "toolbox": "ಉಪಕರಣಗಳು",
+       "tool-link-userrights": "{{GENDER:$1|ಬಳಕೆದಾರರ}} ಗುಂಪುಗಳನ್ನು ಬದಲಾಯಿಸಿ",
+       "tool-link-userrights-readonly": "{{GENDER:$1|ಬಳಕೆದಾರರ}} ಗುಂಪುಗಳನ್ನು ವೀಕ್ಷಿಸಿ",
        "userpage": "ಸದಸ್ಯರ ಪುಟವನ್ನು ವೀಕ್ಷಿಸು",
        "projectpage": "ಯೋಜನೆಯ ಪುಟವನ್ನು ನೋಡು",
        "imagepage": "ಕಡತದ ಪುಟ ವೀಕ್ಷಿಸಿ",
        "redirectedfrom": "($1 ಇಂದ ಪುನರ್ನಿರ್ದೇಶಿತ)",
        "redirectpagesub": "ಪುನರ್ನಿರ್ದೇಶನ ಪುಟ",
        "redirectto": "ಪುನರ್ನಿರ್ದೇಶನ ಇದಕ್ಕೆ:",
-       "lastmodifiedat": "ಈ ಪುಟವನ್ನು ಕೊನೆಯಾಗಿ $2, $1 ರಂದು ಬದಲಾಯಿಸಲಾಗಿತ್ತು.",
+       "lastmodifiedat": "ಈ ಪುಟವನ್ನು $1, $2 ರಂದು ಕೊನೆಯಾಗಿ ಸಂಪಾದಿಸಲಾಯಿತು.",
        "viewcount": "ಈ ಪುಟವನ್ನು {{PLURAL:$1|೧ ಬಾರಿ|$1 ಬಾರಿ}} ವೀಕ್ಷಿಸಲಾಗಿದೆ.",
        "protectedpage": "ಸಂರಕ್ಷಿತ ಪುಟ",
        "jumpto": "ಇಲ್ಲಿಗೆ ಹೋಗು:",
        "badtitletext": "ನೀವು ಕೋರಿದ ಪುಟದ ಶೀರ್ಷಿಕೆ ಸಿಂಧುವಲ್ಲದ್ದು ಅಥವ ಖಾಲಿ ಅಥವ ಸರಿಯಾದ ಕೊಂಡಿಯಲ್ಲದ ಅಂತರ-ಭಾಷೆ/ಅಂತರ-ವಿಕಿ ಸಂಪರ್ಕವಾಗಿದೆ.\nಅದರಲ್ಲಿ ಒಂದು ಅಥವ ಹೆಚ್ಚು ಶೀರ್ಷಿಕೆಯಲ್ಲಿ ಬಳಸಲು ನಿಷಿದ್ಧವಾಗಿರುವ ಅಕ್ಷರಗಳು ಇರಬಹುದು.",
        "title-invalid-empty": "ಮನವಿ ಮಾಡಲಾದ ಪುಟದ ಶೀರ್ಷಿಕೆಯು ಖಾಲಿಯಾಗಿದೆ ಅಥವ ಕೇವಲ ನಾಮಸ್ಥಳದ ಹೆಸರನ್ನು ಮಾತ್ರ ಹೊಂದಿದೆ.",
        "title-invalid-utf8": "ಮನವಿ ಮಾಡಲಾದ ಪುಟದ ಶೀರ್ಷಿಕೆಯು ಒಂದು ಅಮಾನ್ಯವಾದ UTF-8 ಅನುಕ್ರಮವನ್ನು ಹೊಂದಿದೆ.",
-       "title-invalid-interwiki": "ಶà³\80ರà³\8dಷಿà²\95à³\86ಯà³\81 à²\85à²\82ತರ-ವಿà²\95ಿ à²\95à³\8aà²\82ಡಿಯನà³\8dನà³\81 à²¹à³\8aà²\82ದಿದà³\86",
+       "title-invalid-interwiki": "ವಿನà²\82ತಿಸಿದ à²ªà³\81à²\9fದ à²¶à³\80ರà³\8dಷಿà²\95à³\86ಯà³\81 à²\85à²\82ತರ-ವಿà²\95ಿ à²\95à³\8aà²\82ಡಿಯನà³\8dನà³\81 à²\92ಳà²\97à³\8aà²\82ಡಿದà³\86, à²\85ದನà³\8dನà³\81 à²¶à³\80ರà³\8dಷಿà²\95à³\86à²\97ಳಲà³\8dಲಿ à²¬à²³à²¸à²²à²¾à²\97à³\81ವà³\81ದಿಲà³\8dಲ.",
        "title-invalid-talk-namespace": "ಮನವಿ ಮಾಡಲಾದ ಪುಟದ ಶೀರ್ಷಿಕೆಯು ಒಂದು ಅಸ್ತಿತ್ವದಲ್ಲಿರದೆ ಇರುವ ಮಾತಿನ ಪುಟವನ್ನು ಸೂಚಿಸುತ್ತದೆ.",
        "title-invalid-characters": "ಮನವಿ ಮಾಡಲಾದ ಪುಟದ ಶೀರ್ಷಿಕೆಯು ಅಮಾನ್ಯವಾದ ಅಕ್ಷರಗಳನ್ನು ಹೊಂದಿದೆ: \"$1\".",
        "title-invalid-relative": "ಶೀರ್ಷಿಕೆಯು ಒಂದು ಸಾಂದರ್ಭಿಕ ಮಾರ್ಗವಾಗಿರುತ್ತದೆ. ಸಾಂಧರ್ಭಿಕ ಪುಟದ ಶೀರ್ಷಿಕೆಗಳು (./, ../) ಅಮಾನ್ಯವಾಗಿರುತ್ತದೆ, ಏಕೆಂದರೆ ಬಳಕೆದಾರರ ಜಾಲವೀಕ್ಷಕದಿಂದ ಅವುಗಳನ್ನು ತಲುಪುವುದು ಸಾಮಾನ್ಯವಾಗಿ ಅಸಾಧ್ಯವಾಗಿರುತ್ತದೆ.",
        "noname": "ನೀವು ಸರಿಯಾದ ಬಳಕೆದಾರ ಹೆಸರನ್ನು ಸೂಚಿಸಿಲ್ಲ.",
        "loginsuccesstitle": "ಲಾಗಿನ್ ಯಶಸ್ವಿ",
        "loginsuccess": "ನೀವು ಈಗ \"$1\" ಆಗಿ ವಿಕಿಪೀಡಿಯಕ್ಕೆ ಲಾಗಿನ್ ಆಗಿದ್ದೀರಿ.",
-       "nosuchuser": "\"$1\" ಹೆಸರಿನ ಯಾವ ಸದಸ್ಯರೂ ಇಲ್ಲ.\nಸದಸ್ಯನಾಮದಲ್ಲಿ ಲಘು ಮತ್ತು ದೀರ್ಘ ಅಕ್ಷರಗಳಲ್ಲಿ ವ್ಯತ್ಯಾಸವಿದೆ.\nಕಾಗುಣಿತವನ್ನು ಪರೀಕ್ಷಿಸಿ, ಅಥವಾ [[Special:CreateAccount|ಹೊಸ ಸದಸ್ಯತ್ವ ಖಾತೆಯನ್ನು ಸೃಷ್ಟಿಸಿ]].",
+       "nosuchuser": "\"$1\" à²¹à³\86ಸರಿನ à²¯à²¾à²µ à²¸à²¦à²¸à³\8dಯರà³\82 à²\87ಲà³\8dಲ.\nಸದಸà³\8dಯನಾಮದಲà³\8dಲಿ à²²à²\98à³\81 à²®à²¤à³\8dತà³\81 à²¦à³\80ರà³\8dà²\98 à²\85à²\95à³\8dಷರà²\97ಳಲà³\8dಲಿ à²¸à³\82à²\95à³\8dಷà³\8dಮವಾದ à²µà³\8dಯತà³\8dಯಾಸವಿದà³\86.\nà²\95ಾà²\97à³\81ಣಿತವನà³\8dನà³\81 à²ªà²°à³\80à²\95à³\8dಷಿಸಿ, à²\85ಥವಾ [[Special:CreateAccount|ಹà³\8aಸ à²¸à²¦à²¸à³\8dಯತà³\8dವ à²\96ಾತà³\86ಯನà³\8dನà³\81 à²¸à³\83ಷà³\8dà²\9fಿಸಿ]].",
        "nosuchusershort": "\"$1\" ಹೆಸರಿನ ಸದಸ್ಯರು ಯಾರೂ ಇಲ್ಲ.\nಹೆಸರಲ್ಲಿ ಕಾಗುಣಿತ ತಪ್ಪಿದೆಯೆ ಎಂದು ಪರೀಕ್ಷಿಸಿ.",
        "nouserspecified": "ನೀವು ಒಂದು ಸದಸ್ಯತ್ವದ ಹೆಸರನ್ನು ಸೂಚಿಸಬೇಕು.",
        "login-userblocked": "ಈ ಬಳಕೆದಾರರನ್ನು ನಿರ್ಬಂಧಿಸಲಾಗಿದೆ. ಲಾಗಿನ್ ಆಗಲು ಸಾದ್ಯವಿಲ್ಲ.",
        "wrongpassword": "ತಪ್ಪು ಪ್ರವೇಶ ಪದ ನೀಡಿರುವಿರಿ. ಮತ್ತೊಮ್ಮೆ ಪ್ರಯತ್ನಿಸಿ.",
        "wrongpasswordempty": "ಖಾಲಿ ಪ್ರವೇಶ ಪದವನ್ನು ನೀಡಿರುವಿರಿ. ಮತ್ತೊಮ್ಮೆ ಪ್ರಯತ್ನಿಸಿ.",
        "passwordtooshort": "ಪ್ರವೇಶಪದ ಕನಿಷ್ಟ {{PLURAL:$1|೧ ಅಕ್ಷರವನ್ನು|$1 ಅಕ್ಷರಗಳನ್ನು}} ಹೊಂದಿರಬೇಕು.",
+       "passwordtoolong": "ಪ್ರವೇಶ ಸಂಕೇತ ಪದ ಕನಿಷ್ಟ {{PLURAL:$1|೧ ಅಕ್ಷರವನ್ನು|$1 ಅಕ್ಷರಗಳನ್ನು}} ಹೊಂದಿರಬೇಕು.",
+       "passwordtoopopular": "ಸಾಮಾನ್ಯವಾಗಿ ಆಯ್ಕೆ ಮಾಡಿದ ಪ್ರವೇಶ ಸಂಕೇತ ಪದಗಳನ್ನು ಬಳಸಲಾಗುವುದಿಲ್ಲ. ದಯವಿಟ್ಟು ಇನ್ನಷ್ಟು ಅನನ್ಯ ಪ್ರವೇಶ ಸಂಕೇತ ಪದಗಳನ್ನು ಅನ್ನು ಆಯ್ಕೆ ಮಾಡಿ.",
        "password-name-match": "ನಿಮ್ಮ ಬಳಕೆದಾರ ಹೆಸರಿನಿಂದ ಪ್ರವೇಶಪದ ವಿಭಿನ್ನವಾಗಿರಬೇಕು.",
        "password-login-forbidden": "ಈ ಬಳಕೆದಾರರ ಹೆಸರು ಮತ್ತು ಪ್ರವೇಶಪದವನ್ನು ನಿರ್ಬಂಧಿಸಲಾಗಿದೆ.",
        "mailmypassword": "ಪ್ರವೇಶಪದವನ್ನು ಪುನಃಸ್ಥಾಪಿಸಿ.",
        "passwordremindertitle": "{{SITENAME}}ಗೆ ಹೊಸ ತಾತ್ಕಾಲಿಕ ಪ್ರವೇಶ ಪದ",
-       "passwordremindertext": "{{SITENAME}} ($4) ಸೈಟಿಗೆ ಹೊಸ ಪ್ರವೇಶಪದವನ್ನು $1 ಐ.ಪಿ. ವಿಳಾಸದಿಂದ ಕೋರಲಾಗಿದೆ.\nಸದಸ್ಯ \"$2\" ಅವರ ಹೊಸ ಪ್ರವೇಶಪದ ಈಗ \"$3\".\nನೀವು ಲಾಗ್ ಇನ್ ಆಗಿ ತಮ್ಮ ಪ್ರವೇಶಪದವನ್ನು ಬದಲಾಯಿಸಿ.\n\nನೀವು ಈ ಕೋರಿಕೆಯನ್ನು ಮಾಡಿಲ್ಲದಿದ್ದರೆ, ಅಥವ ನೀವು ನಿಮ್ಮ ಹಳೆಯ ಪ್ರವೇಶಪದವನ್ನು ನೆನಪಿಸಿಕೊಂಡರೆ ಈ ಮಾಹಿತಿಗೆ ಗಮನ ನೀಡದೆ ನಿಮ್ಮ ಹಳೆಯ ಪ್ರವೇಶಪದವನ್ನು ಉಪಯೋಗಿಸಲು ಮುಂದುವರೆಸಿರಿ.",
+       "passwordremindertext": "{{SITENAME}} ($4) ಸೈಟಿಗೆ ಹೊಸ ಪ್ರವೇಶಪದವನ್ನು $1 ಐ.ಪಿ. ವಿಳಾಸದಿಂದ ಕೋರಲಾಗಿದೆ.\nಸದಸ್ಯ \"$2\" ಅವರ ಹೊಸ ಪ್ರವೇಶಪದ ಈಗ \"$3\".\nನೀವು ಲಾಗ್ ಇನ್ ಆಗಿ ತಮ್ಮ ಪ್ರವೇಶಪದವನ್ನು ಬದಲಾಯಿಸಿ.\nನಿಮ್ಮ ತಾತ್ಕಾಲಿಕ ಪಾಸ್ವರ್ಡ್ {{PLURAL:$5|ಒಂದು ದಿನ|$5 ದಿನಗಳಲ್ಲಿ}}. ಕೊನೆಗೊಳ್ಳಲಿದೆ.\nನೀವು ಈ ಕೋರಿಕೆಯನ್ನು ಮಾಡಿಲ್ಲದಿದ್ದರೆ, ಅಥವ ನೀವು ನಿಮ್ಮ ಹಳೆಯ ಪ್ರವೇಶಪದವನ್ನು ನೆನಪಿಸಿಕೊಂಡರೆ ಈ ಮಾಹಿತಿಗೆ ಗಮನ ನೀಡದೆ ನಿಮ್ಮ ಹಳೆಯ ಪ್ರವೇಶಪದವನ್ನು ಉಪಯೋಗಿಸಲು ಮುಂದುವರೆಸಿರಿ.",
        "noemail": "ಸದಸ್ಯ \"$1\" ಅವರ ಹೆಸರಿನಲ್ಲಿ ಯಾವ ಇ-ಅಂಚೆ ವಿಳಾಸವೂ ದಾಖಲಾಗಿಲ್ಲ.",
        "noemailcreate": "ನೀವು ಬಳಕೆಯಲ್ಲಿರುವ ಮಿಂಚಂಚೆ ವಿಳಾಸ ನೀಡಬೇಕಾಗುವುದು.",
        "passwordsent": "\"$1\" ಅವರ ಹೆಸರಿನಲ್ಲಿ ನೋಂದಾಯಿತವಾದ ಇ-ಅಂಚೆ ವಿಳಾಸಕ್ಕೆ ಹೊಸ ಪ್ರವೇಶಪದವನ್ನು ಕಳುಹಿಸಲಾಗಿದೆ.\nಅದನ್ನು ಪಡೆದ ಮೇಲೆ ಮತ್ತೆ ಲಾಗಿನ್ ಆಗಿ.",
        "eauthentsent": "ನೀವು ನೊಂದಾಯಿಸಿದ ಇ-ಅಂಚೆ ವಿಳಾಸಕ್ಕೆ ಧೃಡೀಕರಣ ಅಂಚೆಯನ್ನು ಕಳುಹಿಸಲಾಗಿದೆ.\nಈ ವಿಳಾಸಕ್ಕೆ ಮುಂದೆ ಯಾವುದೇ ಇ-ಅಂಚೆ ಕಳುಹಿಸಲ್ಪಡುವ ಮುನ್ನ ನೀವು ಈ ಕಳುಹಿಸಿರುವ ಅಂಚೆಯಲ್ಲಿನ ನಿರ್ದೇಶನಗಳನ್ನು ಪಾಲಿಸಿ, ಈ ವಿಳಾಸವು ನಿಮ್ಮದೇ ಎಂದು ಧೃಡೀಕರಿಸಬೇಕು.",
        "throttled-mailpassword": "ಕಳೆದ $1 ಗಂಟೆಗಳ ಒಳಗೆ ಒಂದು ಪ್ರವೇಶ ಪದವನ್ನು ಕಳುಹಿಸಲಾಗಿದೆ.\nದುರುಪಯೋಗಗಳನ್ನು ತಡೆಗಟ್ಟಲು ಪ್ರವೇಶಪದಗಳನ್ನು ಪ್ರತಿ {{PLURAL:$1|ಗಂಟೆಗೆ|$1 ಗಂಟೆಗಳಲ್ಲಿ}} ಕೇವಲ ಒಂದು ಬಾರಿ ಕಳುಹಿಸಲಾಗುವುದು.",
        "mailerror": "ಅಂಚೆ ಕಳುಹಿಸುವಲ್ಲಿ ದೋಷ: $1",
-       "acct_creation_throttle_hit": "ಕ್ಷಮಿಸಿ, ನೀವಾಗಲೇ{{PLURAL:$1|೧ ಖಾತೆಯನ್ನು|$1 ಖಾತೆಗಳನ್ನು}} ತೆರೆದಿದ್ದೀರಿ.\nಇನ್ನು ಹೆಚ್ಚಿನ ಖಾತೆಗಳನ್ನು ತೆರೆಯಲಾಗುವುದಿಲ್ಲ.",
+       "acct_creation_throttle_hit": "ಕ್ಷಮಿಸಿ, ನೀವಾಗಲೇ{{PLURAL:$1|೧ ಖಾತೆಯನ್ನು|$1 ಖಾತೆಗಳನ್ನು}} ತೆರೆದಿದ್ದೀರಿ. ಕಳೆದ $2, ಅವಧಿಯಲ್ಲಿ ಅನುಮತಿಸಲಾದ ಗರಿಷ್ಠ.\nಇನ್ನು ಹೆಚ್ಚಿನ ಖಾತೆಗಳನ್ನು ತೆರೆಯಲಾಗುವುದಿಲ್ಲ.",
        "emailauthenticated": "ನಿಮ್ಮ ಇ-ಅಂಚೆ ವಿಳಾಸವು ದಿನಾಂಕ $2 ಸಮಯ $3 ಅಂದು ಧೃಡೀಕೃತವಾಗಿದೆ.",
        "emailnotauthenticated": "ನಿಮ್ಮ ಇ-ಅಂಚೆ ವಿಳಾಸ ಇನ್ನೂ ಧೃಡೀಕೃತವಾಗಿಲ್ಲ.\nಈ ಕೆಳಗಿನ ಆಯ್ಕೆಗಳಿಗೆ ಇ-ಅಂಚೆಯನ್ನು ನಿಮಗೆ ಕಳುಹಿಸಲು ಆಗುವುದಿಲ್ಲ.",
        "noemailprefs": "ಈ ಸೌಲಭ್ಯಗಳು ಕೆಲಸ ಮಾಡಬೇಕಾದರೆ ಒಂದು ಇ-ಅಂಚೆ ವಿಳಾಸವನ್ನು ನಮೂದಿಸಿ.",
        "emailconfirmlink": "ನಿಮ್ಮ ಇ-ಅಂಚೆ ವಿಳಾಸವನ್ನು ಧೃಡೀಕರಿಸಿ",
        "invalidemailaddress": "ಈ ಇ-ಅಂಚೆ ವಿಳಾಸವು ಸರಿಯಾದ ಪ್ರಕಾರದಲ್ಲಿ ಇಲ್ಲದಿರುವುದರಿಂದ ಇದನ್ನು ಸ್ವೀಕಾರ ಮಾಡಲಾಗುವುದಿಲ್ಲ.\nದಯವಿಟ್ಟು ಸರಿಯಾದ ಪ್ರಕಾರದ ವಿಳಾಸವನ್ನು ಸೇರಿಸಿ ಅಥವ ಆ ಚೌಕವನ್ನು ಖಾಲಿ ಬಿಡಿ.",
+       "cannotchangeemail": "ಈ ವಿಕಿ ಖಾತೆಯಲ್ಲಿ ಇಮೇಲ್ ವಿಳಾಸಗಳನ್ನು ಬದಲಾಯಿಸಲಾಗುವುದಿಲ್ಲ.",
        "emaildisabled": "ಈ ಜಾಲತಾಣವು ಮಿಂಚಂಚೆ ಕಳುಹಿಸಲು ಸಾದ್ಯವಿಲ್ಲ.",
        "accountcreated": "ಖಾತೆಯನ್ನು ಸೃಷ್ಟಿಸಲಾಯಿತು",
-       "accountcreatedtext": "$1 ಅವರ ಬಳಕೆದಾರ ಖಾತೆ ಸೃಷ್ಟಿಸಲ್ಪಟ್ಟಿದೆ.",
+       "accountcreatedtext": "[[{{ns:User}}:$1|$1]] ([[{{ns:User talk}}:$1|ಚರ್ಚೆ]])\n, ಅವರ ಬಳಕೆದಾರ ಖಾತೆ ಸೃಷ್ಟಿಸಲ್ಪಟ್ಟಿದೆ.",
        "createaccount-title": "{{SITENAME}} ತಾಣಕ್ಕೆ ಬಳಕೆದಾರ ಖಾತೆ ಸೃಷ್ಟಿ ಮಾಡುವಿಕೆ",
        "createaccount-text": "ನಿಮ್ಮ ಇ-ಅಂಚೆ ವಿಳಾಸ ನೀಡಿ {{SITENAME}} ($4) ಅಲ್ಲಿ ಯಾರೊ \"$2\" ಹೆಸರಿನ ಖಾತೆಯೊಂದನ್ನು ತೆಗೆದಿದ್ದಾರೆ, ಮತ್ತು ಅದರ ಪ್ರವೇಶ ಪದ \"$3\".\nನೀವು ಲಾಗ್ ಇನ್ ಆಗಿ ನಿಮ್ಮ ಪ್ರವೇಶ ಪದವನ್ನು ಬದಲಾಯಿಸಬೇಕು.\n\nಆ ಖಾತೆ ತಪ್ಪಾಗಿ ತೆಗೆದಿದ್ದಲ್ಲಿ, ಈ ಸಂದೇಶವನ್ನು ನೀವು ಅಲಕ್ಷಿಸಬಹುದು.",
+       "login-throttled": "ನೀವು ಬಹಳ ಸಾರಿ ಲಾಗ್ ಇನ್ ಆಗಲು ಪ್ರಯತ್ನಿಸಿರುವಿರಿ. \nಮತ್ತೆ ಪ್ರಯತ್ನಿಸಲು $1 ಕಾಯಬೇಕು.",
        "login-abort-generic": "ನಿಮ್ಮ ಲಾಗಿನ್ ಪಲಪ್ರದವಾಗಿಲ್ಲ-ವಿಫಲವಾಗಿದೆ",
+       "login-migrated-generic": "ನಿಮ್ಮ ಖಾತೆಯನ್ನು ಸ್ಥಳಾಂತರಗೊಳಿಸಲಾಗಿದೆ, ಮತ್ತು ನಿಮ್ಮ ಬಳಕೆದಾರಹೆಸರು ಈ ವಿಕಿ ಯಲ್ಲಿ ಅಸ್ತಿತ್ವದಲ್ಲಿಲ್ಲ.",
        "loginlanguagelabel": "ಭಾಷೆ: $1",
+       "suspicious-userlogout": "ಲಾಗ್ ಔಟ್ ಮಾಡಲು ನಿಮ್ಮ ವಿನಂತಿಯನ್ನು ನಿರಾಕರಿಸಲಾಗಿದೆ ಏಕೆಂದರೆ ಅದು ಮುರಿದ ಬ್ರೌಸರ್ ಅಥವಾ ಕ್ಯಾಶಿಂಗ್ ಪ್ರಾಕ್ಸಿನಿಂದ ಕಳುಹಿಸಲ್ಪಟ್ಟಿದೆ ಎಂದು ತೋರುತ್ತಿದೆ.",
        "createacct-another-realname-tip": "ಹೆಸರು ನೀಡುವುದು ಐಚ್ಛಿಕ. ನೀವು ಅದನ್ನು ನೀಡಿದಲ್ಲಿ ನಿಮ್ಮ ಕಾಣಿಕೆಗಳಿಗೆ ನಿಮಗೆ ಮನ್ನಣೆ ನೀಡಲಾಗುವುದು.",
        "pt-login": "ಲಾಗ್ ಇನ್",
        "pt-login-button": "ಲಾಗ್ ಇನ್",
+       "pt-login-continue-button": "ಲಾಗಿನ್ ಮುಂದುವರಿಸಿ",
        "pt-createaccount": "ಹೊಸ ಖಾತೆ ತೆರೆಯಿರಿ",
        "pt-userlogout": "ಲಾಗ್ ಔಟ್",
+       "php-mail-error-unknown": "PHP's mail() ಕಾರ್ಯದಲ್ಲಿ ಅಜ್ಞಾತ ದೋಷ.",
+       "user-mail-no-addy": "ಇಮೇಲ್ ವಿಳಾಸವಿಲ್ಲದೆ ಇಮೇಲ್ ಕಳುಹಿಸಲು ಪ್ರಯತ್ನಿಸಿದರು.",
+       "user-mail-no-body": "ಖಾಲಿ ಅಥವಾ ಅವಿವೇಕದ ಚಿಕ್ಕ ದೇಹದೊಂದಿಗೆ ಇಮೇಲ್ ಕಳುಹಿಸಲು ಪ್ರಯತ್ನಿಸಿದರು.",
        "changepassword": "ಪ್ರವೇಶ ಪದ ಬದಲಾಯಿಸಿ",
        "resetpass_announce": "ಲಾಗ್ ಇನ್ ಪೂರ್ಣಗೊಳಿಸಲು ನೀವು ಹೊಸ ಪ್ರವೇಶಪದವನ್ನು ನಮೂದಿಸಬೇಕು.",
        "resetpass_header": "ಖಾತೆಯ ಪ್ರವೇಶಪದ ಬದಲಾಯಿಸಿ",
        "passwordreset-username": "ಬಳಕೆದಾರರ ಹೆಸರು:",
        "passwordreset-domain": "ಕ್ಷೇತ್ರ:",
        "passwordreset-email": "ಇ-ಮೇಲ್ ವಿಳಾಸ:",
-       "passwordreset-emailsentemail": "ಪà³\8dರವà³\87ಶಪದವನà³\8dನà³\81 à²ªà³\81ನà²\83ಸà³\8dಥಾಪಿಸಿದ à²®à²¿à²\82à²\9aà²\82à²\9aà³\86ಯನà³\8dನà³\81 à²\95ಳà³\81ಹಿಸಲಾà²\97ಿದೆ.",
-       "changeemail": "ಮಿà²\82à²\9aà²\82à²\9aà³\86 à²µà²¿à²³à²¾à²¸à²µà²¨à³\8dನà³\81 à²¬à²¦à²²à²¾à²¯à²¿à²¸ಿ",
+       "passwordreset-emailsentemail": "à²\88 à²\87ಮà³\87ಲà³\8d à²µà²¿à²³à²¾à²¸à²µà³\81 à²¨à²¿à²®à³\8dಮ à²\96ಾತà³\86ಯà³\8aà²\82ದಿà²\97à³\86 à²¸à²\82ಯà³\8bà²\9cಿತà²\97à³\8aà²\82ಡಿದà³\8dದರà³\86, à²ªà³\8dರವà³\87ಶಪದ à²®à²°à³\81ಹà³\8aà²\82ದಿಸಲà³\81 à²\87ಮà³\87ಲà³\8d à²\85ನà³\8dನà³\81 à²\95ಳà³\81ಹಿಸಲಾà²\97à³\81ತà³\8dತದೆ.",
+       "changeemail": "à²\87ಮà³\87ಲà³\8d à²µà²¿à²³à²¾à²¸à²µà²¨à³\8dನà³\81 à²¬à²¦à²²à²¾à²¯à²¿à²¸à²¿ à²\85ಥವಾ à²¤à³\86à²\97à³\86ದà³\81ಹಾà²\95ಿ",
        "changeemail-no-info": "ನೀವು ಈ ಪುಟವನ್ನು ನೇರತಲುಪಲು ಲಾಗಿನ್ ಆಗಿರುವುದು ಆವಶ್ಯಕ.",
        "changeemail-oldemail": "ಪ್ರಸ್ತುತ ಮಿಂಚಂಚೆ ವಿಳಾಸ:",
        "changeemail-newemail": "ಹೊಸ  ಇ-ಅಂಚೆ ವಿಳಾಸ:",
        "accmailtext": "[[User talk:$1|$1]] ಅವರ ಹೊಸ ಪ್ರವೇಶಪದ $2 ಗೆ ಕಳುಹಿಸಲಾಗಿದೆ.\n\nಈ ಖಾತೆಯ ಪ್ರವೇಶಪದವನ್ನು ಲಾಗಿನ್ ಆದ ನಂತರ ''[[Special:ChangePassword|ಪ್ರವೇಶಪದ ಬದಲಾವಣೆ]]'' ಪುಟದಲ್ಲಿ ಬದಲಾಯಿಸಬಹುದು.",
        "newarticle": "(ಹೊಸತು)",
        "newarticletext": "ಇನ್ನೂ ಅಸ್ಥಿತ್ವದಲ್ಲಿ ಇರದ ಪುಟದ ಲಿಂಕ್ ಅನ್ನು ನೀವು ಒತ್ತಿರುವಿರಿ.\nಈ ಪುಟವನ್ನು ಸೃಷ್ಟಿಸಲು ಕೆಳಗಿನ ಚೌಕದಲ್ಲಿ ಬರೆಯಲು ಆರಂಭಿಸಿರಿ.\n(ಹೆಚ್ಚು ಮಾಹಿತಿಗೆ [$1 ಸಹಾಯ ಪುಟ] ನೋಡಿ).\nಈ ಪುಟಕ್ಕೆ ನೀವು ತಪ್ಪಾಗಿ ಬಂದಿದ್ದಲ್ಲಿ ನಿಮ್ಮ ಬ್ರೌಸರ್‍ನ '''back''' ಬಟನ್ ಅನ್ನು ಒತ್ತಿ.",
-       "anontalkpagetext": "----''ಇದು ಖಾತೆಯೊಂದನ್ನು ಹೊಂದಿರದ ಅನಾಮಧೇಯ ಬಳಕೆದಾರರೊಬ್ಬರ ಚರ್ಚೆ ಪುಟ.\nಖಾತೆಯಿಲ್ಲದಿರುವುದರಿಂದ ಅವರನ್ನು ಗುರುತಿಸಲು ಅವರ IP ವಿಳಾಸವನ್ನು ಉಪಯೋಗಿಸುತ್ತಿದ್ದೇವೆ.\nಈ ರೀತಿಯ IP ವಿಳಾಸವು ಅನೇಕ ಬಳಕೆದಾರರಿಂದ ಉಪಯೋಗದಲ್ಲಿರಬಹುದು.\nನೀವು ಅನಾಮಧೇಯ ಬಳಕೆದಾರರಾಗಿದ್ದಲ್ಲಿ, ಹಾಗು ನಿಮಗೆ ಸಂಬಂಧವಿಲ್ಲದಂತ ಸಂದೇಶಗಳು ಬರುತ್ತಿವೆ ಎಂದು ಅನಿಸಿದರೆ, ಮುಂದೆ ಬೇರೆ ಅನಾಮಧೇಯ ಬಳಕೆದಾರರೊಂದಿಗೆ ತಪ್ಪಾಗಿ ಗುರುತಿಸಬಾರದೆಂದಿದ್ದರೆ ದಯವಿಟ್ಟು [[Special:CreateAccount|ಸದಸ್ಯರಾಗಿ]] ಅಥವ [[Special:UserLogin|ಲಾಗ್ ಇನ್ ಆಗಿ]].''",
+       "anontalkpagetext": "----\n<em>ಇದು ಖಾತೆಯೊಂದನ್ನು ಹೊಂದಿರದ ಅನಾಮಧೇಯ ಬಳಕೆದಾರರೊಬ್ಬರ ಚರ್ಚೆ ಪುಟ. ಖಾತೆಯಿಲ್ಲದಿರುವುದರಿಂದ ಅವರನ್ನು ಗುರುತಿಸಲು ಅವರ IP ವಿಳಾಸವನ್ನು ಉಪಯೋಗಿಸುತ್ತಿದ್ದೇವೆ.</em>\nಈ ರೀತಿಯ IP ವಿಳಾಸವು ಅನೇಕ ಬಳಕೆದಾರರಿಂದ ಉಪಯೋಗದಲ್ಲಿರಬಹುದು.\nನೀವು ಅನಾಮಧೇಯ ಬಳಕೆದಾರರಾಗಿದ್ದಲ್ಲಿ, ಹಾಗು ನಿಮಗೆ ಸಂಬಂಧವಿಲ್ಲದಂತ ಸಂದೇಶಗಳು ಬರುತ್ತಿವೆ ಎಂದು ಅನಿಸಿದರೆ, ಮುಂದೆ ಬೇರೆ ಅನಾಮಧೇಯ ಬಳಕೆದಾರರೊಂದಿಗೆ ತಪ್ಪಾಗಿ ಗುರುತಿಸಬಾರದೆಂದಿದ್ದರೆ ದಯವಿಟ್ಟು [[Special:CreateAccount|ಸದಸ್ಯರಾಗಿ]] ಅಥವ [[Special:UserLogin|ಲಾಗ್ ಇನ್ ಆಗಿ]].''",
        "noarticletext": "ಈ ಪುಟದಲ್ಲಿ ಸದ್ಯಕ್ಕೆ ಏನೂ ಇಲ್ಲ.\nನೀವು ಇತರ ಪುಟಗಳಲ್ಲಿ [[Special:Search/{{PAGENAME}}|ಈ ಹೆಸರನ್ನು ಹುಡುಕಬಹುದು]],\n<span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} ಸಂಬಂಧಿತ ದಾಖಲೆಗಳನ್ನು ಹುಡುಕಬಹುದು],\nಅಥವ [{{fullurl:{{FULLPAGENAME}}|action=edit}} ಈ ಪುಟವನ್ನು ಸೃಷ್ಟಿಸಬಹುದು]</span>.",
        "noarticletext-nopermission": "ಈ ಪುಟದಲ್ಲಿ ಸದ್ಯಕ್ಕೆ ಯಾವ ಪಠ್ಯವೂ ಇಲ್ಲ.\nನೀವು ಇತರ ಪುಟಗಳಲ್ಲಿ [[Special:Search/{{PAGENAME}}|ಈ ಶೀರ್ಷಿಕೆಗಾಗಿ ಹುಡುಕಬಹುದು]], ಅಥವಾ <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} ಸಂಬಂಧಿಸಿದ ದಾಖಲೆಗಳನ್ನು ಹುಡುಕಬಹುದು]</span>, ಆದರೆ ನಿಮಗೆ ಈ ಪುಟವನ್ನು ಸೃಷ್ಟಿಸಲು ಅನುಮತಿಯಿಲ್ಲ.",
        "userpage-userdoesnotexist": "ಬಳಕೆದಾರ ಖಾತೆ \"<nowiki>$1</nowiki>\" ದಾಖಲಾಗಿಲ್ಲ. ನೀವು ಇದೇ ಪುಟವನ್ನು ಸೃಷ್ಟಿ/ಸಂಪಾದನೆ ಮಾಡಬೇಕೆಂದಿರುವಿರಿ ಎಂದು ಖಾತ್ರಿ ಮಾಡಿಕೊಳ್ಳಿ.",
        "blocked-notice-logextract": "ಈ ಬಳಕೆದಾರರನ್ನು  ಪ್ರಸ್ತುತವಾಗಿ  ನಿರ್ಬಂಧಿಸಲಾಗಿದೆ. \nಇತ್ತೀಚಿನ  ನಿರ್ಬಂಧನೆಯ ದಾಖಲೆಯನ್ನು ಉಲ್ಲೇಖಕ್ಕಾಗಿ ಕೆಳಗೆ ಕೊಟ್ಟಿದೆ:",
-       "usercssyoucanpreview": "'''ಗಮನಿಸಿ:''' ಉಳಿಸುವ ಮುನ್ನ 'ಮುನ್ನೋಟ' ಗುಂಡಿಯನ್ನು ಉಪಯೋಗಿಸಿ ನಿಮ್ಮ ಹೊಸ CSS ಅನ್ನು ಪ್ರಯೋಗ ಮಾಡಿ.",
+       "usercssyoucanpreview": "<strong>ಗಮನಿಸಿ:</strong> ಉಳಿಸುವ ಮುನ್ನ \"{{int:showpreview}}\" ಗುಂಡಿಯನ್ನು ಉಪಯೋಗಿಸಿ ನಿಮ್ಮ ಹೊಸ CSS ಅನ್ನು ಪ್ರಯೋಗ ಮಾಡಿ.",
        "userjsyoucanpreview": "'''ಗಮನಿಸಿ:''' ಉಳಿಸುವ ಮುನ್ನ 'ಮುನ್ನೋಟ' ಗುಂಡಿಯನ್ನು ಉಪಯೋಗಿಸಿ ನಿಮ್ಮ ಹೊಸ JS ಅನ್ನು ಪ್ರಯೋಗ ಮಾಡಿ.",
        "usercsspreview": "'''ನೆನಪಿಡಿ: ನೀವು ಇಲ್ಲಿ ಕೇವಲ ನಿಮ್ಮ ಬಳಕೆದಾರ CSSನ ಮುನ್ನೋಟ ನೋಡುತ್ತಿರುವಿರಿ.'''\n'''ಅದನ್ನು ಇನ್ನೂ ಉಳಿಸಲಾಗಿಲ್ಲ!'''",
        "userjspreview": "'''ಗಮನಿಸಿ: ನೀವು ನಿಮ್ಮ ಬಳಕೆದಾರ JavaScriptನ ಮುನ್ನೋಟ ನೋಡುತ್ತಿರುವಿರಿ ಅಥವ ಪ್ರಯೋಗ ಮಾಡುತ್ತಿರುವಿರಿ. ಅದನ್ನಿನ್ನೂ ಉಳಿಸಲಾಗಿಲ್ಲ!'''",
        "right-upload": "ಕಡತಗಳನ್ನು ಅಪ್ಲೋಡ್ ಮಾಡು",
        "right-reupload": "ಅಸ್ತಿತ್ವದಲ್ಲಿರುವ ಫೈಲ್ ಗಳ ಕಡತಗಳ ಮೇಲೆ ಬರೆಯಿರಿ",
        "right-reupload-own": "ವತಃ ತಾವೇ ನಕಲೆರಿಸಿರುವ ಅಸ್ತಿತ್ವದಲ್ಲಿರುವ ಫೈಲ್ ಗಳ ಕಡತಗಳ ಮೇಲೆ ಬರೆಯಿರಿ",
-       "right-writeapi": "ಬರà³\8aವà³\81â\80\8dà²\9fà³\8d à²\87à²\82ದà³\86ನà³\8d à²¬à²²à²\95à³\86 à²®à²¾à²²à³\8dಪà³\81ಲà³\86 API",
+       "right-writeapi": "ಬರಹ API à²¯ à²¬à²³à²\95à³\86",
        "right-delete": "ಪುಟಗಳನ್ನು ಅಳಿಸಿ",
        "right-bigdelete": "ಜಾಸ್ತಿ ಇತಿಹಾಸವಿರುವ ಪುಟಗಳನ್ನು ಅಳಿಸಿ",
        "right-deleterevision": "ಪುಟದ ಕೆಲ ಆವೃತ್ತಿಗಳನ್ನು ಅಳಿಸಿ ಹಾಗು ಉಳಿಸಿ",
        "rcshowhidemine": "ನನ್ನ ಸಂಪಾದನೆಗಳನ್ನು $1",
        "rcshowhidemine-show": "ತೊರಿಸಿ",
        "rcshowhidemine-hide": "ಮರೆ ಮಾಡಿ",
-       "rclinks": "à²\95à³\8aನà³\86ಯ $2 à²¦à²¿à²¨à²\97ಳಲà³\8dಲಿ à²®à²¾à²¡à²¿à²¦ $1 à²\95à³\8aನà³\86ಯ à²¬à²¦à²²à²¾à²µà²£à³\86à²\97ಳನà³\8dನà³\81 à²¨à³\8bಡಿ",
+       "rclinks": "ಕೊನೆಯ $2 ದಿನಗಳಲ್ಲಿ ಮಾಡಿದ $1 ಬದಲಾವಣೆಗಳನ್ನು ನೋಡಿ",
        "diff": "ವ್ಯತ್ಯಾಸ",
        "hist": "ಇತಿಹಾಸ",
        "hide": "ಅಡಗಿಸು",
        "undelete-show-file-submit": "ಹೌದು",
        "namespace": "ಹೆಸರಿನ ಬಗೆ:",
        "invert": "ಆಯ್ಕೆಯನ್ನು ತಿರುಗಿಸು",
+       "tooltip-invert": "ಆಯ್ದ ಹೆಸರಿನ ಜಾಗದಲ್ಲಿ ಬದಲಾವಣೆಗಳನ್ನು ಮರೆಮಾಡಲು ಈ ಪೆಟ್ಟಿಗೆಯನ್ನು ಪರಿಶೀಲಿಸಿ (ಮತ್ತು ಪರಿಶೀಲಿಸಿದ ವೇಳೆ ಸಂಬಂಧಿತ ನೇಮ್ಸ್ಪೇಸ್)",
+       "namespace_association": "ಅಸೋಸಿಯೇಟೆಡ್ ನೇಮ್ಸ್ಪೇಸ್",
+       "tooltip-namespace_association": "ಆಯ್ಕೆ ಮಾಡಲಾದ ಹೆಸರಿನೊಂದಿಗೆ ಸಂಬಂಧಿಸಿದ ಚರ್ಚೆ ಅಥವಾ ವಿಷಯ ನಾಮಪದವನ್ನು ಸೇರಿಸಲು ಈ ಪೆಟ್ಟಿಗೆಯನ್ನು ಪರಿಶೀಲಿಸಿ",
        "blanknamespace": "(ಮುಖ್ಯ)",
        "contributions": "{{GENDER:$1|User}} ಕಾಣಿಕೆಗಳು",
        "contributions-title": "$1 ಸದಸ್ಯರ ಕಾಣಿಕೆಗಳು",
        "tooltip-feed-atom": "ಈ ಪುಟಕ್ಕೆ Atom ಫೀಡು",
        "tooltip-t-contributions": "{{GENDER:$1|ಈ ಸದಸ್ಯರ}} ಕಾಣಿಕೆಗಳ ಪಟ್ಟಿ",
        "tooltip-t-emailuser": "ಈ ಸದಸ್ಯರಿಗೆ ಇ-ಅಂಚೆಯನ್ನು ಕಳುಹಿಸು",
-       "tooltip-t-upload": "ಕಡತ ಸೇರಿಸಿ",
+       "tooltip-t-upload": "ಕಡತಗಳನ್ನು ಸೇರಿಸಿ",
        "tooltip-t-specialpages": "ಎಲ್ಲಾ ವಿಶೇಷ ಪುಟಗಳ ಪಟ್ಟಿ",
        "tooltip-t-print": "ಈ ಪುಟದ ಮುದ್ರಣ ಮಾಡಬಹುದಾದಂತ ಆವೃತ್ತಿ",
        "tooltip-t-permalink": "ಪುಟದ ಈ ಆವೃತ್ತಿಗೆ ಶಾಶ್ವತ ಕೊಂಡಿ",
index f9338d2..cebe1be 100644 (file)
        "preview": "미리 보기",
        "showpreview": "미리 보기",
        "showdiff": "차이 보기",
-       "blankarticle": "<strong>경고:</strong> 만들려는 문서가 비어 있습니다.\n\"$1\"을 다시 클릭하면, 아무 내용 없이 문서가 만들어집니다.",
+       "blankarticle": "<strong>경고:</strong> 만들려는 문서가 비어 있습니다.\n\"$1\" 버튼을 다시 클릭하면, 아무 내용 없이 문서가 만들어집니다.",
        "anoneditwarning": "<strong>경고:</strong> 로그인하지 않았습니다. 편집을 하면 IP 주소가 공개되게 됩니다. <strong>[$1 로그인]</strong>하거나 <strong>[$2 계정을 생성하면]</strong> 편집자가 사용자 이름으로 기록되고, 다른 장점도 있습니다.",
        "anonpreviewwarning": "<em>로그인하고 있지 않습니다. 문서를 저장하면 당신의 IP 주소가 문서의 편집 역사에 남게 됩니다.</em>",
-       "missingsummary": "'''알림:''' 편집 요약을 적지 않았습니다.\n이대로 \"$1\"을 클릭하면 편집 요약 없이 저장됩니다.",
-       "selfredirect": "<strong>경고:</strong> 자기 자신으로 문서를 넘겨주고 있습니다.\n넘겨줄 대상을 잘못 입력했거나, 잘못된 문서를 편집하고 있을 수 있습니다.\n\"$1\"을 입력하면, 넘겨주기 문서가 생성될 것입니다.",
+       "missingsummary": "'''알림:''' 편집 요약을 적지 않았습니다.\n\"$1\" 버튼을 다시 클릭하면 편집 요약 없이 편집이 저장됩니다.",
+       "selfredirect": "<strong>경고:</strong> 자기 자신으로 문서를 넘겨주고 있습니다.\n넘겨줄 대상을 잘못 입력했거나, 잘못된 문서를 편집하고 있을 수 있습니다.\n\"$1\" 버튼을 다시 클릭하면, 넘겨주기 문서가 생성됩니다.",
        "missingcommenttext": "아래에 내용을 채워 넣어 주세요.",
-       "missingcommentheader": "<strong>알림:</strong> 글의 제목을 입력하지 않았습니다.\n다시 \"$1\" 버튼을 클릭하면 글이 제목 없이 저장됩니다.",
+       "missingcommentheader": "<strong>알림:</strong> 이 댓글에 제목을 입력하지 않았습니다.\n\"$1\" 버튼을 다시 클릭하면 제목 없이 편집이 저장됩니다.",
        "summary-preview": "편집 요약 미리 보기:",
        "subject-preview": "주제 미리 보기:",
        "previewerrortext": "변경사항을 미리보기하는 도중 오류가 발생했습니다.",
        "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-notwatched-label": "주시문서 목록에서가 아닌",
+       "rcfilters-filter-watchlist-notwatched-description": "주시 중인 문서의 변경사항을 제외한 모든 사항입니다.",
        "rcfilters-filtergroup-changetype": "차이 종류",
        "rcfilters-filter-pageedits-label": "문서 편집",
        "rcfilters-filter-pageedits-description": "위키 내용, 토론, 분류 설명에 대한 편집....",
        "rcfilters-hideminor-conflicts-typeofchange-global": "특정한 유형의 변경사항을 \"사소한 편집\"으로 지정할 수 없기 때문에 \"사소한 편집\" 필터는 하나 이상의 변경사항 유형 필터와 충돌합니다. 충돌되는 필터들은 위의 사용 중인 필터 영역에 표시됩니다.",
        "rcfilters-hideminor-conflicts-typeofchange": "특정한 종류의 변경사항은 \"사소한 편집\"으로 지정할 수 없으므로 이 필터는 다음 유형의 변경사항 필터와 충돌합니다: $1",
        "rcfilters-typeofchange-conflicts-hideminor": "이 유형의 변경사항 필터는 \"사소한 편집\" 필터와 충돌합니다. 특정한 종류의 변경사항은 \"사소한 편집\"으로 지정할 수 없습니다.",
+       "rcfilters-filtergroup-lastRevision": "마지막 판",
+       "rcfilters-filter-lastrevision-description": "문서의 최근 변경사항입니다.",
        "rcnotefrom": "아래는 <strong>$3, $4</strong>부터 시작하는 {{PLURAL:$5|바뀜이 있습니다}}. (최대 <strong>$1</strong>개가 표시됨)",
        "rclistfromreset": "날짜 선택 초기화",
        "rclistfrom": "$3 $2부터 시작하는 새로 바뀐 문서 보기",
index 49147ea..631f1f8 100644 (file)
        "anoneditwarning": "<strong>Opgepasst:</strong> Dir sidd net ageloggt. Dowéinst gëtt amplaz vun engem Benotzernumm Är IP Adress ëffentlech gewise wann Dir Ännerunge maacht. Wann Dir <strong>[$1 Iech aloggt]</strong> oder <strong>[$2 e Benotzerkont opmaachen]</strong>, Är Ännerunge ginn dann Ärem Benotzerkont zougedeelt, genee wéi aner Avantagen.",
        "anonpreviewwarning": "''Dir sidd net ageloggt. Wann Dir ofspäichert gëtt Är IP-Adress an der Lëscht vun de Versioune vun dëser Säit enregistréiert.''",
        "missingsummary": "'''Erënnerung:''' Dir hutt kee Resumé aginn.\nWann Dir nacheemol op \"$1\" klickt, gëtt Är Ännerung ouni Resumé ofgespäichert.",
-       "selfredirect": "<strong>Opgepasst:</strong> Dir maacht eng Viruleedung vun dëser Aäit op sech selwer.\n\nEt ka sinn datt Dir déi falsch Zilsäit fir d'Viruleedung aginn hutt oder datt Dir déi falsch Säit ännert.\n\nWann Dir nach eng Kéier op \"$1\" klickt, da gëtt d'Viruleedung trotzdem ugeluecht.",
+       "selfredirect": "<strong>Opgepasst:</strong> Dir maacht eng Viruleedung vun dëser Säit op sech selwer.\n\nEt ka sinn datt Dir déi falsch Zilsäit fir d'Viruleedung aginn hutt oder datt Dir déi falsch Säit ännert.\n\nWann Dir nach eng Kéier op \"$1\" klickt, da gëtt d'Viruleedung trotzdem ugeluecht.",
        "missingcommenttext": "Gitt w.e.g. eng Bemierkung an.",
        "missingcommentheader": "<strong>Denkt drun:</strong> Dir hutt kee Sujet fir dës Bemierkung aginn.\nWann Dir nach en Kéier op \"$1\" klickt da gëtt Är Ännerung ouni Titel gespäichert.",
        "summary-preview": "Resumé vun der Ännerung kucken ouni ze späicheren:",
        "rcfilters-filter-major-label": "Keng kleng Ännerungen",
        "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-watchlist-watchednew-label": "Nei Ännerunge vu Säiten op der Iwwerwaachungslëscht",
        "rcfilters-filter-watchlist-notwatched-label": "Net op der Iwwerwaachungslëscht",
        "rcfilters-filter-pageedits-label": "Säitenännerungen",
        "rcfilters-filter-lastrevision-label": "Lescht Versioun",
        "rcfilters-filter-lastrevision-description": "Déi lescht Ännerung op enger Säit",
        "rcfilters-filter-previousrevision-label": "Méi fréi Versiounen",
+       "rcfilters-filter-previousrevision-description": "All Ännerungen, déi net déi rezenst Ännerung vun enger Säit sinn.",
        "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",
index 28d987f..0f4fb62 100644 (file)
        "rcfilters-filter-registered-description": "Pieslēgušies redaktori.",
        "rcfilters-filter-unregistered-label": "Nereģistrēti",
        "rcfilters-filter-unregistered-description": "Nepieslēgušies redaktori.",
+       "rcfilters-filtergroup-authorship": "Devuma autors",
        "rcfilters-filter-editsbyself-label": "Tavi labojumi",
        "rcfilters-filter-editsbyself-description": "Tevis veiktie labojumi.",
        "rcfilters-filter-editsbyother-label": "Citu labojumi",
index 0b4642d..987faf3 100644 (file)
        "accmailtitle": "Лозинката е испратена.",
        "accmailtext": "На $2 е спратена е случајно создадена лозинка за [[User talk:$1|$1]] е испратена. Истата може да се смени на страницата ''[[Special:ChangePassword|Менување на лозинка]]'' откако ќе се најавите.",
        "newarticle": "(нова)",
-       "newarticletext": "Ð\9fÑ\80оÑ\81ледивÑ\82е Ð²Ñ\80Ñ\81ка Ð´Ð¾ Ñ\81Ñ\82Ñ\80аниÑ\86а ÐºÐ¾Ñ\98а не постои.\nЗа да ја создадете страницата, напишете текст во полето подолу ([$1 помош]). Ако сте овде по грешка, само систнете на копчето '''назад''' во вашиот прелистувач.",
+       "newarticletext": "Ð\94оÑ\98довÑ\82е Ð½Ð° Ð²Ñ\80Ñ\81ка Ð´Ð¾ Ñ\81Ñ\82Ñ\80аниÑ\86а Ñ\88Ñ\82о не постои.\nЗа да ја создадете страницата, напишете текст во полето подолу ([$1 помош]). Ако сте овде по грешка, само систнете на копчето '''назад''' во вашиот прелистувач.",
        "anontalkpagetext": "----\n<em>Ова е страница за разговор со анонимен корисник кој сè уште не регистрирал корисничка сметка или не ја користи.<em>\nЗатоа мораме да ја користиме неговата бројчена IP-адреса за да го препознаеме.\nЕдна ваква IP-адреса може да ја делат повеќе корисници.\nАко сте анонимен корисник и сметате дека кон вас се упатени нерелевантни коментари, тогаш [[Special:CreateAccount|создајте корисничка сметка]] или [[Special:UserLogin|најавете се]] за да избегнете поистоветување со други анонимни корисници во иднина.''",
        "noarticletext": "Таква страница сè уште не постои.\nМожете да проверите [[Special:Search/{{PAGENAME}}|дали насловот се споменува]] во други статии,\nда ги <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} пребарате дневниците],\nили да [{{fullurl:{{FULLPAGENAME}}|action=edit}} ја создадете]</span>.",
        "noarticletext-nopermission": "Таква страница сè уште не постои.\nМожете да проверите [[Special:Search/{{PAGENAME}}|дали насловот се споменува]] во други статии или пак да <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} пребарате поврзаните дневници]</span>, но немате дозвола да ја создадете страницата.",
index 75a85d3..291b46d 100644 (file)
        "preview": "Forhåndsvisning",
        "showpreview": "Forhåndsvisning",
        "showdiff": "Vis endringer",
-       "blankarticle": "<strong>Advarsel:</strong> Siden du er i ferd med å opprette er tom.\nHvis du trykker \"$1\" en gang til, vil siden opprettes uten innhold.",
+       "blankarticle": "<strong>Advarsel:</strong> Siden du er i ferd med å opprette er tom.\nHvis du trykker «$1» en gang til, vil siden opprettes uten innhold.",
        "anoneditwarning": "<strong>Advarsel:</strong> Du er ikke innlogget. IP-adressen din vil bli vist offentlig om du redigerer. Hvis du <strong>[$1 logger inn]</strong> eller <strong>[$2 oppretter en konto]</strong> vil redigeringene dine tilskrives brukernavnet ditt, og du vil få flere andre fordeler.",
        "anonpreviewwarning": "<em>Du er ikke logget inn. Ved lagring vil IP-adressen din lagres i sidens redigeringshistorikk.</em>",
        "missingsummary": "'''Påminnelse:''' Du har ikke lagt inn en redigeringsforklaring.\nVelger du ''Lagre siden'' en gang til blir endringene lagret uten forklaring.",
        "rcfilters-filter-minor-description": "Redigeringer merket som mindre av brukeren.",
        "rcfilters-filter-major-label": "Ikke-mindre endringer",
        "rcfilters-filter-major-description": "Redigeringer som ikke er merket som mindre.",
+       "rcfilters-filtergroup-watchlist": "Overvåkede sider",
+       "rcfilters-filter-watchlist-watched-label": "På overvåkningslisten",
+       "rcfilters-filter-watchlist-watched-description": "Endringer til sider på overvåkningslista di.",
+       "rcfilters-filter-watchlist-watchednew-label": "Nye endringer på overvåkningslista",
+       "rcfilters-filter-watchlist-watchednew-description": "Endringer i overvåkede sider du ikke har besøkt siden endringen(e) ble gjort.",
+       "rcfilters-filter-watchlist-notwatched-label": "Ikke på overvåkningslista.",
+       "rcfilters-filter-watchlist-notwatched-description": "Alt utenom endringer på sider på overvåkningslista di.",
        "rcfilters-filtergroup-changetype": "Type endring",
        "rcfilters-filter-pageedits-label": "Sideredigeringer",
        "rcfilters-filter-pageedits-description": "Redigeringer til wikiinnhold, diskusjoner, kategoribeskrivelser ...",
index 75b6c2b..c28d728 100644 (file)
        "watchthis": "यो पृष्ठ अवलोकन गर्नुहोस्",
        "savearticle": "सङ्ग्रह गर्ने",
        "savechanges": "परिवर्तन सङ्ग्रह गर्नुहोस्",
+       "publishchanges": "परिवर्तनहरू प्रकाशित गर्ने",
        "preview": "पूर्वावलोकन",
        "showpreview": "पूर्वालोकन देखाउनुहोस्",
        "showdiff": "परिवर्तन देखाउनुहोस्",
        "tooltip-ca-nstab-category": "श्रेणी पृष्ठ हेर्ने",
        "tooltip-minoredit": "यसलाई सामान्य सम्पादनको रुपमा चिनो लगाउने",
        "tooltip-save": "तपाईंका परिवर्तनहरू सङ्ग्रह गर्नुहोस्",
+       "tooltip-publish": "तपाईंका परिवर्तनहरू प्रकाशित गर्नुहोस्",
        "tooltip-preview": "तपाईंको परिवर्तनको पूर्वरूप , कृपया सङ्ग्रह गर्नु अघि यो प्रयोग गर्नुहोला !",
        "tooltip-diff": "तपाईंले पाठमा के के परिवर्तन गर्नुभयो भनेर देखाउने",
        "tooltip-compareselectedversions": "यस पृष्ठको छानिएका दुई पुनरावलोकन बीच फरक हेर्नुहोस्",
index 35c3888..bc80c2e 100644 (file)
        "otherlanguages": "In andere talen",
        "redirectedfrom": "(Doorverwezen vanaf $1)",
        "redirectpagesub": "Doorverwijspagina",
-       "redirectto": "Doorverwijzen naar:",
+       "redirectto": "Doorverwijzing naar:",
        "lastmodifiedat": "Deze pagina is voor het laatst bewerkt op $1 om $2.",
        "viewcount": "Deze pagina is {{PLURAL:$1|één keer|$1 keer}} bekeken.",
        "protectedpage": "Beveiligde pagina",
index c04fca5..fd95ccb 100644 (file)
        "rcfilters-filter-minor-description": "Zmiany, które autor oznaczył jako drobne.",
        "rcfilters-filter-major-label": "Zmiany nie oznaczone jako drobne",
        "rcfilters-filter-major-description": "Zmiany nie oznaczone jako drobne.",
+       "rcfilters-filtergroup-watchlist": "Strony z listy obserwowanych",
+       "rcfilters-filter-watchlist-watched-label": "Z listy obserwowanych",
+       "rcfilters-filter-watchlist-watched-description": "Zmiany na stronach, które masz na liście obserwowanych.",
+       "rcfilters-filter-watchlist-watchednew-label": "Nowe zmiany na obserwowanych stronach",
+       "rcfilters-filter-watchlist-watchednew-description": "Zmiany na obserwowanych stronach, których jeszcze nie odwiedziłeś.",
+       "rcfilters-filter-watchlist-notwatched-label": "Tylko z poza obserwowanych",
+       "rcfilters-filter-watchlist-notwatched-description": "Wszystko oprócz zmian na obserwowanych przez ciebie stronach.",
        "rcfilters-filtergroup-changetype": "Rodzaj zmiany",
        "rcfilters-filter-pageedits-label": "Edycje strony",
        "rcfilters-filter-pageedits-description": "Edycje treści, stron dyskusji, opisów kategorii...",
        "rcfilters-hideminor-conflicts-typeofchange-global": "Filtr „Drobne zmiany” koliduje z jednym lub wieloma filtrami Rodzaju zmian, ponieważ niektóre rodzaje zmian nie mogą być uznawane za  „drobne”. Kolidujące filtry zostały powyżej odpowiednio zaznaczone na pasku aktywnych filtrów.",
        "rcfilters-hideminor-conflicts-typeofchange": "Niektóre rodzaje zmian nie mogą być uznawane za „drobne”, dlatego ten filtr koliduje z następującymi filtrami Rodzaju zmian: $1",
        "rcfilters-typeofchange-conflicts-hideminor": "Ten filtr Rodzaju zmian koliduje z filtrem „Drobne zmiany”. Nie wszystkie zmiany mogą być uznawane za „drobne”.",
+       "rcfilters-filtergroup-lastRevision": "Ostatnia wersja",
+       "rcfilters-filter-lastrevision-label": "Ostatnie wersje",
+       "rcfilters-filter-lastrevision-description": "Tylko najnowsze zmiany dla każdej ze stron.",
+       "rcfilters-filter-previousrevision-label": "Wcześniejsze wersje",
+       "rcfilters-filter-previousrevision-description": "Wszystkie edycje, które nie są najnowszą zmianą strony.",
        "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",
        "blocklist": "Zablokowani użytkownicy",
        "autoblocklist": "Blokady automatyczne",
        "autoblocklist-submit": "Szukaj",
+       "autoblocklist-legend": "Lista blokad automatycznych",
        "autoblocklist-localblocks": "{{PLURAL:$1|Lokalna blokada automatyczna|Lokalne blokady automatyczne}}",
+       "autoblocklist-empty": "Lista blokad automatycznych jest pusta.",
        "autoblocklist-otherblocks": "{{PLURAL:$1|Inna blokada automatyczna|Inne blokady automatyczne}}",
        "ipblocklist": "Zablokowani użytkownicy",
        "ipblocklist-legend": "Znajdź zablokowanego użytkownika",
        "tooltip-pt-mycontris": "Lista {{GENDER:|moich}} edycji",
        "tooltip-pt-anoncontribs": "Lista edycji wykonanych z tego adresu IP",
        "tooltip-pt-login": "Zachęcamy do zalogowania się, choć nie jest to obowiązkowe.",
+       "tooltip-pt-login-private": "Należy się zalogować, aby korzystać z tej wiki",
        "tooltip-pt-logout": "Wyloguj",
        "tooltip-pt-createaccount": "Zachęcamy do stworzenia konta i zalogowania, ale nie jest to obowiązkowe.",
        "tooltip-ca-talk": "Dyskusja o zawartości tej strony",
        "confirmrecreate": "{{GENDER:$1|Użytkownik|Użytkowniczka}} [[User:$1|$1]] ([[User talk:$1|dyskusja]]) {{GENDER:$1|usunął|usunęła}} tę stronę po tym, jak rozpocząłeś/rozpoczęłaś jej edycję, podając jako powód usunięcia:\n: <em>$2</em>\nPotwierdź, że na pewno chcesz odtworzyć tę stronę.",
        "confirmrecreate-noreason": "{{GENDER:$1|Użytkownik|Użytkowniczka}} [[User:$1|$1]] ([[User talk:$1|dyskusja]]) {{GENDER:$1|usunął|usunęła}} tę stronę po tym, jak rozpocząłeś/rozpoczęłaś jej edycję. Potwierdź, że naprawdę chcesz odtworzyć tę stronę.",
        "recreate": "Utwórz powtórnie",
+       "confirm-purge-title": "Wyczyść pamięć podręczną tej strony",
        "confirm_purge_button": "Wyczyść",
        "confirm-purge-top": "Wyczyścić pamięć podręczną dla tej strony?",
        "confirm-purge-bottom": "Odświeżenie strony wyczyści pamięć podręczną i wymusi pokazanie jej aktualnej wersji.",
index a2f1aea..2d339bb 100644 (file)
        "missingsummary": "'''Nòta:''' a l'ha butà gnun resumé dla modìfica. Se a sgnaca «$1» n'àutra vira, soa modìfica a resterà salvà sensa resumé.",
        "selfredirect": "<strong>Atension:</strong> A l'é an camin ch'a ridiression-a sa pàgina a chila-midema.\nMiraco a l'ha spessificà ël bërsaj sbalià për la ridiression, opura a l'é an camin ch'a modìfica la pàgina sbalià.\nS'a sgnaca torna ansima a «$1», la ridiression a sarà creà istess.",
        "missingcommenttext": "Për piasì, che a buta un coment sì-sota.",
-       "missingcommentheader": "'''Ch'a arcòrda:''' A l'ha pa dàit ëd soget o d'intestassion për cost coment.\nSe a sgnaca torna «$1», soa modìfica a sarà salvà sensa gnun-a intestassion.",
+       "missingcommentheader": "'''Ch'a ten-a da ment:''' A l'ha pa dàit ëd soget o d'intestassion për cost coment.\nSe a sgnaca torna «$1», soa modìfica a sarà salvà sensa gnun-a intestassion.",
        "summary-preview": "Preuva dël resumé:",
        "subject-preview": "Preuva dl'oget/intestassion:",
        "previewerrortext": "A l'é rivaje n'eror durant ël tentativ ëd previsualisassion ëd soe modìfiche.",
index 20dd1fb..27dacfa 100644 (file)
        "otherlanguages": "This message is shown under the toolbox. It is used if there are interwiki links added to the page, like <code><nowiki>[[</nowiki>en:Interwiki article]]</code>.\n{{Identical|Otherlanguages}}",
        "redirectedfrom": "The text displayed when a certain page is redirected to another page. Parameters:\n* $1 - the name of the page user came from",
        "redirectpagesub": "Displayed under the page title of a page which is a redirect to another page, see [{{fullurl:Project:Translators|redirect=no}} Project:Translators] for example.\n\n{{Identical|Redirect page}}",
-       "redirectto": "Alt text of the arrow icon shown on redirect pages ([[commons:File:Sample redirect page.jpg]]).\n\n{{Identical|Redirect to}}",
+       "redirectto": "Alt text of the arrow icon shown on redirect pages ([[commons:File:Sample redirect page.jpg]]).\n\n{{Identical|Redirect to}}\n\nOn Wikidata, this message is shown directly on redirect pages.\n\n\"Redirect\" is a noun, not a verb. That is, translate \"redirect\" as in \"This is a redirect to:\"",
        "talkpageheader": "{{notranslate}}",
        "lastmodifiedat": "This message is shown below each page, in the footer with the logos and links.\n\nParameters:\n* $1 - date\n* $2 - time\nSee also:\n* {{msg-mw|Lastmodifiedatby}}",
        "viewcount": "Used as page-view counter. Parameters:\n* $1 - number of pageviews",
        "shown-title": "Parameters:\n* $1 - number of search results",
        "viewprevnext": "This is part of the navigation message on the top and bottom of Special pages which are lists of things, e.g. the User's contributions page (in date order) or the list of all categories (in alphabetical order). ($1) and ($2) are either {{msg-mw|Pager-older-n}} and {{msg-mw|Pager-newer-n}} (for date order) or {{msg-mw|Prevn}} and {{msg-mw|Nextn}} (for alphabetical order).\n\nIt is also used by [[Special:WhatLinksHere|Whatlinkshere]] pages, where ($1) and ($2) are {{msg-mw|Whatlinkshere-prev}} and {{msg-mw|Whatlinkshere-next}}.\n($3) is made up in all cases of the various proposed numbers of results per page, e.g. \"(20 | 50 | 100 | 250 | 500)\".\nFor Special pages, the navigation bar is prefixed by \"({{msg-mw|Page first}} | {{msg-mw|Page last}})\" (alphabetical order) or \"({{msg-mw|Histfirst}} | {{msg-mw|Histlast}})\" (date order).\n\nViewprevnext is sometimes preceded by the {{msg-mw|Showingresults}} or {{msg-mw|Showingresultsnum}} message (for Special pages) or by the {{msg-mw|Linkshere}} message (for Whatlinkshere pages).\n\nRefers to {{msg-mw|Pipe-separator}}.",
        "searchmenu-exists": "An option shown in a menu beside search form offering a link to the existing page having the specified title (when using the default MediaWiki search engine).\n\nParameters:\n* $1 - page title\n* $2 - the number of search results found",
-       "searchmenu-new": "An option shown in a menu beside search form offering a red link to the not yet existing page having the specified title (when using the default MediaWiki search engine).\nParameters:\n* $1 - page title\n* $2 - the number of search results found\nParameterless gender ({{GENDER:|male|female|unspecified}}) can be used in translations.",
+       "searchmenu-new": "An option shown in a menu beside search form offering a red link to the not yet existing page having the specified title (when using the default MediaWiki search engine).\nParameters:\n* $1 - page title\n* $2 - the number of search results found\nParameterless gender (<code><nowiki>{{GENDER:|male|female|unspecified}}</nowiki></code>) can be used in translations.",
        "searchmenu-new-nocreate": "{{notranslate}}",
        "searchprofile-articles": "A quick link in the advanced search box on [[Special:Search]]. Clicking on this link starts a search in the content pages of the wiki.\n\nA 'content page' is a page that forms part of the purpose of the wiki. It includes the main page and pages in the main namespace and any other namespaces that are included when the wiki is customised. For example on Wikimedia Commons 'content pages' include pages in the file and category namespaces. On Wikinews 'content pages' include pages in the Portal namespace. For technical definition of 'content namespaces' see [[mw:Manual:Using_custom_namespaces#Content_namespaces|MediaWiki]].\n\nPossible alternatives to the word 'content' are 'subject matter' or 'wiki subject' or 'wiki purpose'.\n\n{{Identical|Content page}}",
        "searchprofile-images": "An option in the [[Special:Search]].\n\nSee also:\n* {{msg-mw|Searchprofile-images|message}}\n* {{msg-mw|Searchprofile-images-tooltip|tooltip}}\n{{Identical|Muitimedia}}",
        "recentchanges-legend-plusminus": "{{optional}}\nA plus/minus sign with a number for the legend.",
        "recentchanges-submit": "Label for submit button in [[Special:RecentChanges]]\n{{Identical|Show}}",
        "rcfilters-activefilters": "Title for the filters selection showing the active filters.",
+       "rcfilters-quickfilters": "Label for the button that opens the quick filters menu in [[Special:RecentChanges]]",
+       "rcfilters-savedqueries-defaultlabel": "Default name for saving a new set of quick filters [[Special:RecentChanges]]",
+       "rcfilters-savedqueries-rename": "Label for the menu option that edits a quick filter in [[Special:RecentChanges]]",
+       "rcfilters-savedqueries-setdefault": "Label for the menu option that sets a quick filter as default in [[Special:RecentChanges]]",
+       "rcfilters-savedqueries-unsetdefault": "Label for the menu option that unsets a quick filter as default in [[Special:RecentChanges]]",
+       "rcfilters-savedqueries-remove": "Label for the menu option that removes a quick filter as default in [[Special:RecentChanges]]",
+       "rcfilters-savedqueries-new-name-label": "Label for the input that holds the name of the new saved filters in [[Special:RecentChanges]]",
+       "rcfilters-savedqueries-add-new-title": "Title for the popup to add new quick link in [[Special:RecentChanges]]",
+       "rcfilters-savedqueries-apply-label": "Label for the button to apply saving a new quick link in [[Special:RecentChanges]]",
+       "rcfilters-savedqueries-cancel-label": "Label for the button to cancel the saving of a new quick link in [[Special:RecentChanges]]",
        "rcfilters-restore-default-filters": "Label for the button that resets filters to defaults",
        "rcfilters-clear-all-filters": "Title for the button that clears all filters",
        "rcfilters-search-placeholder": "Placeholder for the filter search input.",
index 2783bda..3de2287 100644 (file)
        "confirmable-no": "Нет",
        "thisisdeleted": "Просмотреть или восстановить $1?",
        "viewdeleted": "Просмотреть $1?",
-       "restorelink": "{{PLURAL:$1|1=$1 удалённую правку|$1 удалённые правки|$1 удалённых правок|1=удалённую правку}}",
+       "restorelink": "{{PLURAL:$1|$1 удалённую правку|$1 удалённые правки|$1 удалённых правок|1=удалённую правку}}",
        "feedlinks": "В виде:",
        "feed-invalid": "Неправильный тип канала для подписки.",
        "feed-unavailable": "Ленты синдикации недоступны",
        "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-notwatched-label": "Нет в Списке наблюдения",
        "rcfilters-filtergroup-changetype": "Тип изменения",
        "rcfilters-filter-pageedits-label": "Правки страницы",
        "rcfilters-filter-pageedits-description": "Правки содержимого, обсуждений, описания категорий…",
        "rcfilters-filter-logactions-label": "Протоколируемые действия",
        "rcfilters-filter-logactions-description": "Административные действия, создания учётных записей, удаления страниц, загрузки файлов…",
        "rcfilters-hideminor-conflicts-typeofchange-global": "Фильтр \"малые правки\" конфликтует с одним или несколькими фильтрами, поскольку некоторые типы правок не могут быть названы малыми. Конфликтные фильтры отмечены вверху, в области Активных фильтров.",
+       "rcfilters-filter-previousrevision-label": "Более ранние версии",
        "rcnotefrom": "Ниже {{PLURAL:$5|указано изменение|перечислены изменения}} с <strong>$3, $4</strong> (показано не более <strong>$1</strong>).",
        "rclistfromreset": "Сбросить выбор даты",
        "rclistfrom": "Показать изменения с $3 $2.",
        "enotif_body_intro_moved": "$PAGEEDITDATE {{gender:$2|участником|участницей}} $2 была переименована страница проекта «{{SITENAME}}» с именем «$1», см. текущую версию по ссылке: $3",
        "enotif_body_intro_restored": "$PAGEEDITDATE {{gender:$2|участником|участницей}} $2 была восстановлена страница проекта «{{SITENAME}}» с именем «$1», см. текущую версию по ссылке: $3",
        "enotif_body_intro_changed": "$PAGEEDITDATE {{gender:$2|участником|участницей}} $2 была изменена страница проекта «{{SITENAME}}» с именем «$1», см. текущую версию по ссылке: $3",
-       "enotif_lastvisited": "См. $1 для просмотра всех изменений, произошедших с вашего последнего посещения.",
-       "enotif_lastdiff": "См. $1 для ознакомления с изменением.",
+       "enotif_lastvisited": "См. $1 для просмотра всех изменений, произошедших с вашего последнего посещения",
+       "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:genitive|{{SITENAME}}}}\n\n--\nИзменение настройки уведомлений\n{{canonicalurl:{{#special:Preferences}}}}\n\nИзменение настройки вашего списка наблюдения\n{{canonicalurl:{{#special:EditWatchlist}}}}\n\nУдалить страницы из вашего списка наблюдения\n$UNWATCHURL\n\nОбратная связь и помощь\n$HELPPAGE",
        "created": "создана",
index 666d46b..03c1b6d 100644 (file)
        "botpasswords-label-delete": "ڊاهيو",
        "botpasswords-label-resetpassword": "ڳجھولفظ ٻيھر مقرر ڪريو",
        "botpasswords-label-grants-column": "منظور",
+       "botpasswords-bad-appid": "بوٽ نانءُ \"$1\" قابلِڪار ناھي.",
        "resetpass_forbidden": "ڳجھالفظ بدلائي نٿا سگھجن",
        "resetpass_forbidden-reason": "ڳجھالفظ بدلائي نٿا سگھجن:$1",
        "resetpass-no-info": "هيءُ صفحو پڙهڻ لاءِ داخل ٿيڻ ضروري آهي.",
        "continue-editing": "ترميم گاھ ڏانھن وڃو",
        "editing": "$1 سنواريندي",
        "creating": "$1 سرجيندي",
-       "editingsection": "زÙ\8aر ØªØ±Ù\85Ù\8aÙ\85 $1 (سيڪشن)",
+       "editingsection": "ترÙ\85Ù\8aÙ\85 Ú¾Ù\8aÙº $1 (سيڪشن)",
        "editingcomment": "ترميم هيٺ $1 (نئون سيڪشن)",
        "editconflict": "ترميمي تڪرار: $1",
        "yourtext": "توهان جو ٽيڪسٽ",
        "recentchanges-legend-heading": "<strong>ڪنجي:</strong>",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (پڻ ڏسو [[Special:NewPages|نون صفحن جي فھرست]])",
        "recentchanges-submit": "ڏيکاريو",
+       "rcfilters-activefilters": "سرگرم ڇاڻيون",
+       "rcfilters-empty-filter": "ڪي بہ سرگرم ڇاڻيون ناھن. سڀ ڀاڱيداريون ڏيکاريل آھن.",
+       "rcfilters-filterlist-title": "ڇاڻيون",
        "rcfilters-filterlist-whatsthis": "هي ڇا آهي؟",
        "rcfilters-highlightbutton-title": "نتيجن کي نمايان (هاءِ لائيٽ) ڪيو",
        "rcfilters-highlightmenu-title": "رنگ چونڊيو",
+       "rcfilters-filter-bots-label": "بوٽ",
+       "rcfilters-filter-humans-label": "انسان (بوٽ نہ)",
+       "rcfilters-filter-humans-description": "انساني ايڊيٽرن پاران ڪيل ترميمون.",
+       "rcfilters-filter-pageedits-label": "صفحي ترميمون",
+       "rcfilters-filter-newpages-label": "صفحي تخليقون",
        "rcnotefrom": "هيٺ {{PLURAL:$5|تبديلي آهي|تبديليون آهن}} کان <strong>$3, $4</strong> (تائين <strong>$1</strong> ) ڏيکاريل آهن.",
        "rclistfrom": "$2، $3 کان شروع ٿيندڙ نيون تبديليون ڏيکاريو",
        "rcshowhideminor": "$1 معمولي ترميمون",
        "wlshowhidebots": "بوٽس",
        "wlshowhideliu": "کاتيدار يُوزرس",
        "wlshowhideanons": "گمنام يُوزرس",
-       "wlshowhidemine": "منهنجون ترميمون",
+       "wlshowhidemine": "منھنجون ترميمون",
        "watchlist-options": "نظر ۾ فھرست جا چارا",
        "watching": "نظر ۾ رکندي...",
        "unwatching": "نظر مان ڪڍندي...",
        "tags-title": "ٽيگس",
        "tags-tag": "ٽيگ نانءُ",
        "tags-source-header": "ذريعو",
+       "tags-active-header": "سرگرم؟",
        "tags-active-yes": "ها",
        "tags-active-no": "نہ",
        "tags-edit": "سنواريو",
index b572b68..8eaba92 100644 (file)
        "qbedit": "Уреди",
        "qbpageoptions": "Ова страница",
        "qbmyoptions": "Моје странице",
-       "faq": "Ð\9dПП",
+       "faq": "ЧПП",
        "faqpage": "Project:НПП",
        "actions": "Радње",
        "namespaces": "Именски простори",
index f1cd7ec..159e3ea 100644 (file)
        "qbedit": "Uredi",
        "qbpageoptions": "Ova stranica",
        "qbmyoptions": "Moje stranice",
-       "faq": "NPP",
+       "faq": "ČPP",
        "faqpage": "Project:NPP",
        "actions": "Radnje",
        "namespaces": "Imenski prostori",
index 7432feb..4e99575 100644 (file)
        "rcfilters-filter-registered-description": "Éditor asup log",
        "rcfilters-filter-unregistered-label": "Teu kadaptar",
        "rcfilters-filter-unregistered-description": "Éditor nu teu asup log.",
+       "rcfilters-filtergroup-authorship": "Kontribusi kapangarangan",
        "rcfilters-filter-editsbyself-label": "Éditan meunang anjeun",
        "rcfilters-filter-editsbyself-description": "Kontribusi anjeun.",
        "rcfilters-filter-editsbyother-label": "Éditan ku batur",
index b4584ab..ebde407 100644 (file)
        "editingsection": "Redigerar $1 (avsnitt)",
        "editingcomment": "Redigerar $1 (nytt avsnitt)",
        "editconflict": "Redigeringskonflikt: $1",
-       "explainconflict": "Någon har ändrat den här sidan efter att du började att redigera den.\nDen översta textrutan innehåller den nuvarande sparade versionen av texten.\nDin ändrade version visas i den nedre rutan.\nOm du vill spara dina ändringar så måste du infoga dem i den övre texten.\n'''Endast''' texten i den översta textrutan kommer att sparas när du trycker på \"$1\".",
+       "explainconflict": "Någon har ändrat den här sidan efter att du började att redigera den.\nDen översta textrutan innehåller den nuvarande sparade versionen av texten.\nDin ändrade version visas i den nedre rutan.\nOm du vill spara dina ändringar så måste du infoga dem i den övre texten.\n<strong>Endast</strong> texten i den översta textrutan kommer att sparas när du trycker på \"$1\".",
        "yourtext": "Din text",
        "storedversion": "Den sparade versionen",
        "nonunicodebrowser": "'''VARNING: Din webbläsare saknar stöd för unicode. För att du ska kunna redigera sidor utan problem, så visas icke-ASCII-tecken som hexadecimala koder i redigeringsrutan.'''",
        "rcfilters-filter-unregistered-label": "Oregistrerade",
        "rcfilters-filter-unregistered-description": "Redigerare som inte är inloggade.",
        "rcfilters-filter-unregistered-conflicts-user-experience-level": "Detta filter är i konflikt med följande {{PLURAL:$2|upplevelsefilter}}, som endast {{PLURAL:$2|hittar}} registrerade användare: $1",
-       "rcfilters-filtergroup-authorship": "Redigera författarskap",
-       "rcfilters-filter-editsbyself-label": "Dina egna redigeringar",
-       "rcfilters-filter-editsbyself-description": "Redigeringar av dig.",
-       "rcfilters-filter-editsbyother-label": "Redigeringar av andra",
-       "rcfilters-filter-editsbyother-description": "Redigeringar som har skapats av andra användare (inte dig).",
+       "rcfilters-filtergroup-authorship": "Författarskap av bidrag",
+       "rcfilters-filter-editsbyself-label": "Redigeringar av dig",
+       "rcfilters-filter-editsbyself-description": "Dina egna bidrag.",
+       "rcfilters-filter-editsbyother-label": "Ändringar av andra",
+       "rcfilters-filter-editsbyother-description": "Alla ändringar förutom dina egna.",
        "rcfilters-filtergroup-userExpLevel": "Erfarenhetsnivå (endast för registrerade användare)",
        "rcfilters-filtergroup-user-experience-level-conflicts-unregistered": "Upplevelsefilter hittar endast registrerade användare, så detta filter är i konflikt med filtret \"Oregistrerade\".",
        "rcfilters-filtergroup-user-experience-level-conflicts-unregistered-global": "Filtret \"Oregistrerade\" är i konflikt med en eller flera upplevelsefilter, som endast hittar registrerade användare. Filtren som är i konflikt är markerade i området med aktiva filter ovan.",
        "rcfilters-filter-minor-description": "Redigeringar som är märkta som mindre.",
        "rcfilters-filter-major-label": "Icke-mindre redigeringar",
        "rcfilters-filter-major-description": "Redigeringar som inte är märkta som mindre.",
+       "rcfilters-filtergroup-watchlist": "Bevakade sidor",
+       "rcfilters-filter-watchlist-watched-label": "I bevakningslistan",
+       "rcfilters-filter-watchlist-watched-description": "Ändringar i sidor på din bevakningslista.",
+       "rcfilters-filter-watchlist-watchednew-label": "Nya ändringar i bevakningslistan",
+       "rcfilters-filter-watchlist-watchednew-description": "Ändringar i bevakade sidor som du inte har besökt sedan ändringarna ägde rum.",
+       "rcfilters-filter-watchlist-notwatched-label": "Inte i bevakningslistan",
+       "rcfilters-filter-watchlist-notwatched-description": "Allting förutom ändringar i sidor på din bevakningslista.",
        "rcfilters-filtergroup-changetype": "Typ av ändring",
        "rcfilters-filter-pageedits-label": "Sidredigeringar",
        "rcfilters-filter-pageedits-description": "Redigeringar till wikiinnehåll, diskussioner, kategoribeskrivningar...",
        "rcfilters-hideminor-conflicts-typeofchange-global": "Filtret \"Mindre redigering\" är i konflikt med en eller flera ändringstypfilter, eftersom vissa ändringstyper inte kan betecknas som \"mindre\". Filtren som är i konflikt är markerade i området med aktiva filter ovan.",
        "rcfilters-hideminor-conflicts-typeofchange": "Vissa ändringstyper kan inte betecknas som \"mindre\", så detta filter är i konflikt med följande ändringstypfilter: $1",
        "rcfilters-typeofchange-conflicts-hideminor": "Detta ändringstypfilter är i konflikt med filtret \"Mindre ändringar\". Vissa ändringstyper kan inte betecknas som \"mindre\".",
+       "rcfilters-filtergroup-lastRevision": "Senaste version",
+       "rcfilters-filter-lastrevision-label": "Senaste version",
+       "rcfilters-filter-lastrevision-description": "Den senaste ändringen av en sida.",
+       "rcfilters-filter-previousrevision-label": "Tidigare versioner",
+       "rcfilters-filter-previousrevision-description": "Alla ändringar som inte är den senaste ändringen av en sida.",
        "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",
        "enotif_body_intro_moved": "{{SITENAME}}sidan $1 flyttades den $PAGEEDITDATE av {{gender:$2|$2}}, se $3 för den aktuella versionen.",
        "enotif_body_intro_restored": "{{SITENAME}}sidan $1 återställdes den $PAGEEDITDATE av {{gender:$2|$2}}, se $3 för den aktuella versionen.",
        "enotif_body_intro_changed": "{{SITENAME}}sidan $1 ändrades den $PAGEEDITDATE av {{gender:$2|$2}}, se $3 för den aktuella versionen.",
-       "enotif_lastvisited": "På $1 återfinner du alla ändringar sedan ditt senaste besök.",
-       "enotif_lastdiff": "Se denna ändring på $1",
+       "enotif_lastvisited": "För alla ändringar sedan ditt senaste besök, se $1",
+       "enotif_lastdiff": "För att se denna ändring, se $1",
        "enotif_anon_editor": "anonym användare $1",
        "enotif_body": "Hej $WATCHINGUSERNAME,\n\n$PAGEINTRO $NEWPAGE\n\nAngiven sammanfattning av redigeringen: $PAGESUMMARY $PAGEMINOREDIT\n\nKontakta användaren:\ne-post: $PAGEEDITOR_EMAIL\nwiki: $PAGEEDITOR_WIKI\n\nSåvida du inte besöker sidan, kommer du inte att få flera meddelanden om aktivitet på sidan när du är inloggad. Du kan också ta bort flaggan för meddelanden om ändringar på alla sidor i din bevakningslista.\n\nHälsningar från {{SITENAME}}s meddelandesystem\n\n--\nFör att ändra inställningarna för dina uppdateringar via e-post, besök\n{{canonicalurl:{{#special:Preferences}}}}\n\nFör att ändra inställningarna i din bevakningslista, besök\n{{canonicalurl:{{#special:EditWatchlist}}}}\n\nFör att radera sidan från din bevakningslista, besök\n$UNWATCHURL\n\nFeedback och ytterligare hjälp:\n$HELPPAGE",
        "created": "skapad",
        "sp-contributions-uploads": "uppladdningar",
        "sp-contributions-logs": "loggar",
        "sp-contributions-talk": "diskussion",
-       "sp-contributions-userrights": "hantering av användarrättigheter",
+       "sp-contributions-userrights": "hantering av {{GENDER:$1|användarrättigheter}}",
        "sp-contributions-blocked-notice": "Användaren är blockerad.\nDen senaste posten i blockeringsloggen visas nedan som referens:",
        "sp-contributions-blocked-notice-anon": "Denna IP-adress är för närvarande blockerad.\nDen senaste posten i blockeringsloggen visas nedan som referens:",
        "sp-contributions-search": "Sök efter användarbidrag",
        "tooltip-pt-mycontris": "Lista över {{GENDER:|dina}} bidrag",
        "tooltip-pt-anoncontribs": "En lista över redigeringar från denna IP-adress",
        "tooltip-pt-login": "Du uppmuntras att logga in, men det är inget krav",
+       "tooltip-pt-login-private": "Du måste logga in på denna wiki",
        "tooltip-pt-logout": "Logga ut",
        "tooltip-pt-createaccount": "Du uppmuntras att skapa ett konto och logga in, men det är inte obligatoriskt",
        "tooltip-ca-talk": "Diskussion om innehållssidan",
        "anonymous": "{{PLURAL:$1|Anonym användare|Anonyma användare}} på {{SITENAME}}",
        "siteuser": "användaren $1 på {{SITENAME}}",
        "anonuser": "{{SITENAME}} anonym användare $1",
-       "lastmodifiedatby": "Den här sidan ändrades senast kl. $2 den $1 av $3.",
+       "lastmodifiedatby": "Den här sidan redigerades senast kl. $2 den $1 av $3.",
        "othercontribs": "Baserad på arbete av $1.",
        "others": "andra",
        "siteusers": "{{SITENAME}}-{{PLURAL:$2|{{GENDER:$1|användaren}}|användarna}} $1",
        "confirmrecreate": "Användaren [[User:$1|$1]] ([[User talk:$1|diskussion]]) raderade den här sidan efter att du började redigera den med motiveringen:\n: <em>$2</em>\nBekräfta att du verkligen vill återskapa sidan.",
        "confirmrecreate-noreason": "Användare [[User:$1|$1]] ([[User talk:$1|diskussion]]) {{GENDER:$1|raderade}} den här sidan efter att du började redigera. Bekräfta att du verkligen vill återskapa sidan.",
        "recreate": "Återskapa",
+       "confirm-purge-title": "Rensa cachen för denna sida",
        "confirm_purge_button": "OK",
        "confirm-purge-top": "Rensa denna sidas cache?",
        "confirm-purge-bottom": "Rensning av en sida tömmer cachen och tvingar fram den senaste versionen.",
index cde6674..759183e 100644 (file)
        "metadata-help": "此文件中包含有额外的信息。这些信息可能是由数码相机或扫描仪在创建或数字化过程中所添加的。如果文件自初始状态已受到修改,一些详细说明可能无法反映修改后的文件。",
        "metadata-expand": "显示详细资料",
        "metadata-collapse": "隐藏详细资料",
-       "metadata-fields": "在本信息中所列出的 EXIF 元数据域将包含在图片显示页面,当元数据表损坏时只显示以下信息。\n其他的元数据默认为隐藏。\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",
+       "metadata-fields": "在本信息中所列出的 EXIF 元数据域将包含在图片显示页面,当元数据表损坏时只显示以下信息。其他的元数据默认为隐藏。\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": "宽度",
        "exif-imagelength": "高度",
        "exif-bitspersample": "每像素字节数",
diff --git a/maintenance/benchmarks/benchmarkCSSMin.php b/maintenance/benchmarks/benchmarkCSSMin.php
new file mode 100644 (file)
index 0000000..3eaa88d
--- /dev/null
@@ -0,0 +1,76 @@
+<?php
+/**
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ * @ingroup Benchmark
+ * @author Timo Tijhof
+ */
+
+require_once __DIR__ . '/Benchmarker.php';
+
+/**
+ * Maintenance script that benchmarks CSSMin.
+ *
+ * @ingroup Benchmark
+ */
+class BenchmarkCSSMin extends Benchmarker {
+       public function __construct() {
+               parent::__construct();
+               $this->addDescription( 'Benchmarks CSSMin.' );
+               $this->addOption( 'file', 'Path to CSS file (may be gzipped)', false, true );
+               $this->addOption( 'out', 'Echo output of one run to stdout for inspection', false, false );
+       }
+
+       public function execute() {
+               $file = $this->getOption( 'file', __DIR__ . '/cssmin/styles.css' );
+               $filename = basename( $file );
+               $css = $this->loadFile( $file );
+
+               if ( $this->hasOption( 'out' ) ) {
+                       echo "## minify\n\n",
+                               CSSMin::minify( $css ),
+                               "\n\n";
+                       echo "## remap\n\n",
+                               CSSMin::remap( $css, dirname( $file ), 'https://example.org/test/', true ),
+                               "\n";
+                       return;
+               }
+
+               $this->bench( [
+                       "minify ($filename)" => [
+                               'function' => [ 'CSSMin', 'minify' ],
+                               'args' => [ $css ]
+                       ],
+                       "remap ($filename)" => [
+                               'function' => [ 'CSSMin', 'remap' ],
+                               'args' => [ $css, dirname( $file ), 'https://example.org/test/', true ]
+                       ],
+               ] );
+       }
+
+       private function loadFile( $file ) {
+               $css = file_get_contents( $file );
+               // Detect GZIP compression header
+               if ( substr( $css, 0, 2 ) === "\037\213" ) {
+                       $css = gzdecode( $css );
+               }
+               return $css;
+       }
+}
+
+$maintClass = 'BenchmarkCSSMin';
+require_once RUN_MAINTENANCE_IF_MAIN;
diff --git a/maintenance/benchmarks/cssmin/circle.svg b/maintenance/benchmarks/cssmin/circle.svg
new file mode 100644 (file)
index 0000000..6b7d1af
--- /dev/null
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="8" height="8">
+<circle cx="4" cy="4" r="2"/>
+</svg>
diff --git a/maintenance/benchmarks/cssmin/styles.css b/maintenance/benchmarks/cssmin/styles.css
new file mode 100644 (file)
index 0000000..3cc1520
--- /dev/null
@@ -0,0 +1,32 @@
+/**
+ * Header
+ */
+
+.foo {
+       background: url(wiki.png);
+}
+
+.foo {
+       background: url(unknown.png);
+}
+
+.foo {
+       background: url(https://example.org/foo.png);
+       background: url('https://example.org/foo.png');
+       background: url("https://example.org/foo.png");
+}
+
+.foo {
+       /* @embed */
+       background: url(wiki.png);
+}
+
+.foo {
+       /* @embed */
+       background: url(circle.svg);
+}
+
+.foo {
+       /* @embed */
+       background: url(wiki.png), url(wiki.png);
+}
diff --git a/maintenance/benchmarks/cssmin/wiki.png b/maintenance/benchmarks/cssmin/wiki.png
new file mode 100644 (file)
index 0000000..8c42118
Binary files /dev/null and b/maintenance/benchmarks/cssmin/wiki.png differ
index 423686e..b487f89 100644 (file)
@@ -63,9 +63,7 @@ Because any foreign key relationships involving these titles will already be
 broken, the titles are corrected to a valid version or the rows are deleted
 entirely, depending on the table.
 
-Key progress output is printed to STDERR, while a full log of all entries that
-are deleted is sent to STDOUT. You are strongly advised to capture STDOUT into
-a file.
+The script runs with the expectation that STDOUT is redirected to a file.
 TEXT
                );
                $this->addOption( 'fix', 'Actually clean up invalid titles. If this parameter is ' .
@@ -87,7 +85,10 @@ TEXT
                        }
                }
 
-               $this->output( 'Done! Cleaned up invalid DB keys on ' . wfWikiID() . "!\n" );
+               $this->outputStatus( 'Done!' );
+               if ( $this->hasOption( 'fix' ) ) {
+                       $this->outputStatus( ' Cleaned up invalid DB keys on ' . wfWikiID() . "!\n" );
+               }
        }
 
        /**
@@ -97,10 +98,10 @@ TEXT
         * @param string $str Text to write to both places
         * @param string|null $channel Ignored
         */
-       protected function output( $str, $channel = null ) {
+       protected function outputStatus( $str, $channel = null ) {
                // Make it easier to find progress lines in the STDOUT log
                if ( trim( $str ) ) {
-                       fwrite( STDOUT, '*** ' );
+                       fwrite( STDOUT, '*** ' . trim( $str ) . "\n" );
                }
                fwrite( STDERR, $str );
        }
@@ -132,7 +133,7 @@ TEXT
                        $tableParams['titleField'] :
                        "{$prefix}_title";
 
-               $this->output( "Looking for invalid $titleField entries in $table...\n" );
+               $this->outputStatus( "Looking for invalid $titleField entries in $table...\n" );
 
                // Do all the select queries on the replicas, as they are slow (they use
                // unanchored LIKEs). Naturally this could cause problems if rows are
@@ -153,9 +154,9 @@ TEXT
                        // The REGEXP operator is not cross-DBMS, so we have to use lots of LIKEs
                        [ $dbr->makeList( [
                                $titleField . $dbr->buildLike( $percent, ' ', $percent ),
-                               $titleField . $dbr->buildLike( $percent, '\r', $percent ),
-                               $titleField . $dbr->buildLike( $percent, '\n', $percent ),
-                               $titleField . $dbr->buildLike( $percent, '\t', $percent ),
+                               $titleField . $dbr->buildLike( $percent, "\r", $percent ),
+                               $titleField . $dbr->buildLike( $percent, "\n", $percent ),
+                               $titleField . $dbr->buildLike( $percent, "\t", $percent ),
                                $titleField . $dbr->buildLike( '_', $percent ),
                                $titleField . $dbr->buildLike( $percent, '_' ),
                        ], LIST_OR ) ],
@@ -163,9 +164,9 @@ TEXT
                        [ 'LIMIT' => $this->mBatchSize ]
                );
 
-               $this->output( "Number of invalid rows: " . $res->numRows() . "\n" );
+               $this->outputStatus( "Number of invalid rows: " . $res->numRows() . "\n" );
                if ( !$res->numRows() ) {
-                       $this->output( "\n" );
+                       $this->outputStatus( "\n" );
                        return;
                }
 
@@ -191,9 +192,9 @@ TEXT
                        }
 
                        if ( $table !== 'page' && $table !== 'redirect' ) {
-                               $this->output( "Run with --fix to clean up these rows\n" );
+                               $this->outputStatus( "Run with --fix to clean up these rows\n" );
                        }
-                       $this->output( "\n" );
+                       $this->outputStatus( "\n" );
                        return;
                }
 
@@ -205,7 +206,7 @@ TEXT
                                // This shouldn't happen on production wikis, and we already have a script
                                // to handle 'page' rows anyway, so just notify the user and let them decide
                                // what to do next.
-                               $this->output( <<<TEXT
+                               $this->outputStatus( <<<TEXT
 IMPORTANT: This script does not fix invalid entries in the $table table.
 Consider repairing these rows, and rows in related tables, by hand.
 You may like to run, or borrow logic from, the cleanupTitles.php script.
@@ -220,7 +221,7 @@ TEXT
                                // to the page_title field are already broken, so this will just make sure
                                // users can still access the log entries/deleted revisions from the interface
                                // using a valid page title.
-                               $this->output(
+                               $this->outputStatus(
                                        "Updating these rows, setting $titleField to the closest valid DB key...\n" );
                                $affectedRowCount = 0;
                                foreach ( $res as $row ) {
@@ -235,7 +236,7 @@ TEXT
                                        $affectedRowCount += $dbw->affectedRows();
                                }
                                wfWaitForSlaves();
-                               $this->output( "Updated $affectedRowCount rows on $table.\n" );
+                               $this->outputStatus( "Updated $affectedRowCount rows on $table.\n" );
 
                                break;
 
@@ -245,17 +246,17 @@ TEXT
                                // Since these broken titles can't exist, there's really nothing to watch,
                                // nothing can be categorised in them, and they can't have been changed
                                // recently, so we can just remove these rows.
-                               $this->output( "Deleting invalid $table rows...\n" );
+                               $this->outputStatus( "Deleting invalid $table rows...\n" );
                                $dbw->delete( $table, [ $idField => $ids ], __METHOD__ );
                                wfWaitForSlaves();
-                               $this->output( 'Deleted ' . $dbw->affectedRows() . " rows from $table.\n" );
+                               $this->outputStatus( 'Deleted ' . $dbw->affectedRows() . " rows from $table.\n" );
                                break;
 
                        case 'protected_titles':
                                // Since these broken titles can't exist, there's really nothing to protect,
                                // so we can just remove these rows. Made more complicated by this table
                                // not having an ID field
-                               $this->output( "Deleting invalid $table rows...\n" );
+                               $this->outputStatus( "Deleting invalid $table rows...\n" );
                                $affectedRowCount = 0;
                                foreach ( $res as $row ) {
                                        $dbw->delete( $table,
@@ -264,7 +265,7 @@ TEXT
                                        $affectedRowCount += $dbw->affectedRows();
                                }
                                wfWaitForSlaves();
-                               $this->output( "Deleted $affectedRowCount rows from $table.\n" );
+                               $this->outputStatus( "Deleted $affectedRowCount rows from $table.\n" );
                                break;
 
                        case 'pagelinks':
@@ -273,7 +274,7 @@ TEXT
                                // Update links tables for each page where these bogus links are supposedly
                                // located. If the invalid rows don't go away after these jobs go through,
                                // they're probably being added by a buggy hook.
-                               $this->output( "Queueing link update jobs for the pages in $idField...\n" );
+                               $this->outputStatus( "Queueing link update jobs for the pages in $idField...\n" );
                                foreach ( $res as $row ) {
                                        $wp = WikiPage::newFromID( $row->id );
                                        if ( $wp ) {
@@ -286,11 +287,11 @@ TEXT
                                        }
                                }
                                wfWaitForSlaves();
-                               $this->output( "Link update jobs have been added to the job queue.\n" );
+                               $this->outputStatus( "Link update jobs have been added to the job queue.\n" );
                                break;
                }
 
-               $this->output( "\n" );
+               $this->outputStatus( "\n" );
                return;
        }
 
index eb717e8..287a40c 100644 (file)
@@ -59,7 +59,7 @@ unset( $lines );
 
 $lines = explode( "\n", shell_exec( 'git log --format="%aN"' ) );
 foreach ( $lines as $line ) {
-       if ( empty( $line ) )  {
+       if ( empty( $line ) ) {
                continue;
        }
        if ( substr( $line, 0, 5 ) === '[BOT]' ) {
index 55f36a3..ee42b07 100644 (file)
@@ -9,7 +9,7 @@
   "devDependencies": {
     "deepmerge": "1.3.2",
     "eslint": "3.12.2",
-    "eslint-config-wikimedia": "0.3.0",
+    "eslint-config-wikimedia": "0.4.0",
     "grunt": "1.0.1",
     "grunt-banana-checker": "0.6.0",
     "grunt-contrib-copy": "1.0.0",
index 4693b42..b2c8d89 100644 (file)
--- a/phpcs.xml
+++ b/phpcs.xml
@@ -1,6 +1,32 @@
 <?xml version="1.0"?>
 <ruleset name="MediaWiki">
-       <rule ref="vendor/mediawiki/mediawiki-codesniffer/MediaWiki" />
+       <rule ref="vendor/mediawiki/mediawiki-codesniffer/MediaWiki">
+               <!-- Disable rules added in 0.8.0 that don't pass yet -->
+               <exclude name="MediaWiki.Commenting.FunctionComment.ExtraParamComment" />
+               <exclude name="MediaWiki.Commenting.FunctionComment.MissingParamComment" />
+               <exclude name="MediaWiki.Commenting.FunctionComment.MissingParamName" />
+               <exclude name="MediaWiki.Commenting.FunctionComment.MissingParamTag" />
+               <exclude name="MediaWiki.Commenting.FunctionComment.MissingReturn" />
+               <exclude name="MediaWiki.Commenting.FunctionComment.Missing.Protected" />
+               <exclude name="MediaWiki.Commenting.FunctionComment.Missing.Public" />
+               <exclude name="MediaWiki.Commenting.FunctionComment.ParamNameNoMatch" />
+               <exclude name="MediaWiki.Commenting.FunctionComment.SpacingAfter" />
+               <exclude name="MediaWiki.Commenting.FunctionComment.SpacingAfterParamName" />
+               <exclude name="MediaWiki.Commenting.FunctionComment.SpacingAfterParamType" />
+               <exclude name="MediaWiki.Commenting.IllegalSingleLineComment.IllegalSingleLineCommentStart" />
+               <exclude name="MediaWiki.Commenting.IllegalSingleLineComment.IllegalSingleLineCommentEnd" />
+               <exclude name="MediaWiki.ControlStructures.AssignmentInControlStructures.AssignmentInControlStructures" />
+               <exclude name="MediaWiki.ExtraCharacters.ParenthesesAroundKeyword.ParenthesesAroundKeywords" />
+               <exclude name="MediaWiki.NamingConventions.LowerCamelFunctionsName.FunctionName" />
+               <exclude name="MediaWiki.WhiteSpace.DisallowEmptyLineFunctions.NoEmptyLine" />
+               <exclude name="MediaWiki.WhiteSpace.SpaceBeforeControlStructureBrace.EmptyLines" />
+               <exclude name="MediaWiki.WhiteSpace.SpaceBeforeClassBrace.NoSpaceBeforeBrace" />
+               <exclude name="MediaWiki.WhiteSpace.SpaceBeforeSingleLineComment.NewLineComment" />
+               <exclude name="MediaWiki.WhiteSpace.SpaceBeforeSingleLineComment.SingleSpaceBeforeSingleLineComment" />
+               <exclude name="MediaWiki.Usage.DbrQueryUsage.DbrQueryFound" />
+               <exclude name="MediaWiki.Usage.ExtendClassUsage.FunctionVarUsage" />
+               <exclude name="MediaWiki.Usage.SuperGlobalsUsage.SuperGlobals" />
+       </rule>
        <rule ref="MediaWiki.NamingConventions.PrefixedGlobalFunctions">
                <properties>
                        <property name="ignoreList" type="array" value="bfNormalizeTitleStrReplace,bfNormalizeTitleStrTr,cdbShowHelp,codepointToUtf8,compare_point,cssfilter,escapeSingleString,findAuxFile,findFiles,getEscapedProfileUrl,getFileCommentFromSourceWiki,getFileUserFromSourceWiki,hexSequenceToUtf8,mccGetHelp,mccShowUsage,mimeTypeMatch,moveToExternal,NothingFunction,NothingFunctionData,resolveStub,resolveStubs,showUsage,splitFilename,utf8ToCodepoint,utf8ToHexSequence" />
        <rule ref="PSR2.Methods.MethodDeclaration.Underscore">
                <exclude-pattern>*/includes/StubObject.php</exclude-pattern>
        </rule>
-       <rule ref="MediaWiki.ControlStructures.AssignmentInControlStructures.AssignmentInControlStructures">
+       <rule ref="Generic.ControlStructures.InlineControlStructure.NotAllowed">
                <severity>0</severity>
        </rule>
-       <rule ref="Generic.ControlStructures.InlineControlStructure.NotAllowed">
+       <rule ref="Generic.Formatting.NoSpaceAfterCast.SpaceFound">
                <severity>0</severity>
        </rule>
        <exclude-pattern>node_modules/</exclude-pattern>
index eabe42f..e8c8f61 100644 (file)
@@ -1493,7 +1493,6 @@ return [
                'scripts' => 'resources/src/mediawiki.action/mediawiki.action.view.postEdit.js',
                'styles' => 'resources/src/mediawiki.action/mediawiki.action.view.postEdit.less',
                'dependencies' => [
-                       'mediawiki.cookie',
                        'mediawiki.jqueryMsg',
                        'mediawiki.notification'
                ],
@@ -1743,6 +1742,8 @@ return [
                        'resources/src/mediawiki.rcfilters/dm/mw.rcfilters.dm.FilterItem.js',
                        'resources/src/mediawiki.rcfilters/dm/mw.rcfilters.dm.FilterGroup.js',
                        'resources/src/mediawiki.rcfilters/dm/mw.rcfilters.dm.FiltersViewModel.js',
+                       'resources/src/mediawiki.rcfilters/dm/mw.rcfilters.dm.SavedQueryItemModel.js',
+                       'resources/src/mediawiki.rcfilters/dm/mw.rcfilters.dm.SavedQueriesModel.js',
                        'resources/src/mediawiki.rcfilters/dm/mw.rcfilters.dm.ChangesListViewModel.js',
                        'resources/src/mediawiki.rcfilters/mw.rcfilters.Controller.js',
                ],
@@ -1764,6 +1765,9 @@ return [
                        'resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.FloatingMenuSelectWidget.js',
                        'resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.FilterWrapperWidget.js',
                        'resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.ChangesListWrapperWidget.js',
+                       'resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.SavedLinksListWidget.js',
+                       'resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.SavedLinksListItemWidget.js',
+                       'resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.SaveFiltersPopupButtonWidget.js',
                        'resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.FormWrapperWidget.js',
                        'resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.FilterItemHighlightButton.js',
                        'resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.HighlightColorPickerWidget.js',
@@ -1786,6 +1790,9 @@ return [
                        'resources/src/mediawiki.rcfilters/styles/mw.rcfilters.ui.ChangesListWrapperWidget.less',
                        'resources/src/mediawiki.rcfilters/styles/mw.rcfilters.ui.HighlightColorPickerWidget.less',
                        'resources/src/mediawiki.rcfilters/styles/mw.rcfilters.ui.FilterItemHighlightButton.less',
+                       'resources/src/mediawiki.rcfilters/styles/mw.rcfilters.ui.SavedLinksListWidget.less',
+                       'resources/src/mediawiki.rcfilters/styles/mw.rcfilters.ui.SavedLinksListItemWidget.less',
+                       'resources/src/mediawiki.rcfilters/styles/mw.rcfilters.ui.SaveFiltersPopupButtonWidget.less',
                ],
                'skinStyles' => [
                        'monobook' => [
@@ -1795,6 +1802,16 @@ return [
                ],
                'messages' => [
                        'rcfilters-activefilters',
+                       'rcfilters-quickfilters',
+                       'rcfilters-savedqueries-defaultlabel',
+                       'rcfilters-savedqueries-rename',
+                       'rcfilters-savedqueries-setdefault',
+                       'rcfilters-savedqueries-unsetdefault',
+                       'rcfilters-savedqueries-remove',
+                       'rcfilters-savedqueries-new-name-label',
+                       'rcfilters-savedqueries-add-new-title',
+                       'rcfilters-savedqueries-apply-label',
+                       'rcfilters-savedqueries-cancel-label',
                        'rcfilters-restore-default-filters',
                        'rcfilters-clear-all-filters',
                        'rcfilters-search-placeholder',
index a8eba94..bcff2ac 100644 (file)
@@ -1,3 +1,7 @@
+jquery.ui.core.js
+* I7ffbfd2e5 Avoid deprecated jQuery.expr[":"].
+
+
 jquery.ui.draggable.js
 * 71e11de2a3 Fix positioning error with draggable, revert and grid.
              https://phabricator.wikimedia.org/T140965#2944610
@@ -9,6 +13,10 @@ jquery.ui.datepicker
 * 19531f3c23 Add translations in de-AT and de-CH
 
 
+jquery.ui.widget.js
+* I7ffbfd2e5 Avoid deprecated jQuery.expr[":"].
+
+
 themes/smoothness/jquery.ui.theme.css
 * 5e772e39dd Remove dark color from links inside dialogs
              https://phabricator.wikimedia.org/T85857
index 4ef4b76..19f0069 100644 (file)
@@ -157,7 +157,7 @@ function visible( element ) {
                }).length;
 }
 
-$.extend( $.expr[ ":" ], {
+$.extend( $.expr.pseudos, {
        data: $.expr.createPseudo ?
                $.expr.createPseudo(function( dataName ) {
                        return function( elem ) {
index 067476d..4d84afc 100644 (file)
@@ -36,7 +36,7 @@ $.widget = function( name, base, prototype ) {
        }
 
        // create selector for plugin
-       $.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) {
+       $.expr.pseudos[ fullName.toLowerCase() ] = function( elem ) {
                return !!$.data( elem, fullName );
        };
 
index 15d0a39..143e46c 100644 (file)
                                                .revisions[ 0 ].diff.body;
                                        $wikiDiff.find( 'table.diff tbody' ).html( diffHtml );
                                        mw.hook( 'wikipage.diff' ).fire( $wikiDiff.find( 'table.diff' ) );
-                               } catch ( e ) {
+                               } catch ( err ) {
                                        // "result.blah is undefined" error, ignore
-                                       mw.log.warn( e );
+                                       mw.log.warn( err );
                                }
                                $wikiDiff.show();
                        } );
index 87572ec..e25c96a 100644 (file)
         * @member mw.hook
         */
 
-       var cookieVal,
-               config = mw.config.get( [ 'wgAction', 'wgCurRevisionId' ] ),
-               // This should match EditPage::POST_EDIT_COOKIE_KEY_PREFIX:
-               cookieKey = 'PostEditRevision' + config.wgCurRevisionId;
+       var postEdit = mw.config.get( 'wgPostEdit' );
 
        function showConfirmation( data ) {
                var $container, $popup, $content, timeoutId;
 
        mw.hook( 'postEdit' ).add( showConfirmation );
 
-       // Only when viewing wiki pages, that exist
-       // (E.g. not on special pages or non-view actions)
-       if ( config.wgCurRevisionId && config.wgAction === 'view' ) {
-               cookieVal = mw.cookie.get( cookieKey );
-               if ( cookieVal ) {
-                       mw.config.set( 'wgPostEdit', true );
-
-                       mw.hook( 'postEdit' ).fire( {
-                               // The following messages can be used here:
-                               // postedit-confirmation-saved
-                               // postedit-confirmation-created
-                               // postedit-confirmation-restored
-                               message: mw.msg(
-                                       'postedit-confirmation-' + cookieVal,
-                                       mw.user
-                               )
-                       } );
-
-                       mw.cookie.set( cookieKey, null );
-               }
+       if ( postEdit ) {
+               mw.hook( 'postEdit' ).fire( {
+                       // The following messages can be used here:
+                       // postedit-confirmation-saved
+                       // postedit-confirmation-created
+                       // postedit-confirmation-restored
+                       message: mw.msg(
+                               'postedit-confirmation-' + postEdit,
+                               mw.user
+                       )
+               } );
        }
 
 }( mediaWiki, jQuery ) );
index 7ce06be..f0a86ff 100644 (file)
                                }
                        }
                },
+               {
+                       "label": "‹›",
+                       "action": {
+                               "type": "encapsulate",
+                               "options": {
+                                       "pre": "‹",
+                                       "post": "›"
+                               }
+                       }
+               },
+               {
+                       "label": "⟨⟩",
+                       "action": {
+                               "type": "encapsulate",
+                               "options": {
+                                       "pre": "⟨",
+                                       "post": "⟩"
+                               }
+                       }
+               },
                "¤", "₳", "฿", "₵", "¢", "₡", "₢", "$", "₫", "₯", "€", "₠", "₣", "ƒ", "₴", "₭", "₤", "ℳ", "₥", "₦", "№", "₧", "₰", "£", "៛", "₨", "₪", "৳", "₮", "₩", "¥", "♠", "♣", "♥", "♦", "m²", "m³",
                {
                        "label": "–",
index a5494de..fb3b00e 100644 (file)
        list-style-image: e( '/* @embed */' ) url( @fallback ) e( '\9' );
 }
 
+.transform( @value ) {
+       -webkit-transform: @value; // Safari 3.1-8.0, iOS 3.2-8.4, Android 2.1-4.4.4
+       -moz-transform: @value; // Firefox 3.5-15
+       transform: @value; // Chrome 36+, Firefox 16+, IE 10+, Safari 9+, Opera 23+, iOS 9.2+, Android 5+
+}
+
 .transition( @value ) {
        -webkit-transition: @value; // Safari 3.1-6.0, iOS 3.2-6.1, Android 2.1-4.3
        -moz-transition: @value; // Firefox 4-15
index ca7c4e6..63e13fd 100644 (file)
        /**
         * Get the parameter representation from this group
         *
+        * @param {Object} [filterRepresentation] An object defining the state
+        *  of the filters in this group, keyed by their name and current selected
+        *  state value.
         * @return {Object} Parameter representation
         */
-       mw.rcfilters.dm.FilterGroup.prototype.getParamRepresentation = function () {
-               var i, values,
+       mw.rcfilters.dm.FilterGroup.prototype.getParamRepresentation = function ( filterRepresentation ) {
+               var values,
+                       areAnySelected = false,
+                       buildFromCurrentState = !filterRepresentation,
                        result = {},
-                       filterItems = this.getItems();
+                       filterParamNames = {};
+
+               filterRepresentation = filterRepresentation || {};
+
+               // Create or complete the filterRepresentation definition
+               this.getItems().forEach( function ( item ) {
+                       // Map filter names to their parameter names
+                       filterParamNames[ item.getName() ] = item.getParamName();
+
+                       if ( buildFromCurrentState ) {
+                               // This means we have not been given a filter representation
+                               // so we are building one based on current state
+                               filterRepresentation[ item.getName() ] = item.isSelected();
+                       } else if ( !filterRepresentation[ item.getName() ] ) {
+                               // We are given a filter representation, but we have to make
+                               // sure that we fill in the missing filters if there are any
+                               // we will assume they are all falsey
+                               filterRepresentation[ item.getName() ] = false;
+                       }
 
+                       if ( filterRepresentation[ item.getName() ] ) {
+                               areAnySelected = true;
+                       }
+               } );
+
+               // Build result
                if ( this.getType() === 'send_unselected_if_any' ) {
                        // First, check if any of the items are selected at all.
                        // If none is selected, we're treating it as if they are
                        // all false
 
                        // Go over the items and define the correct values
-                       for ( i = 0; i < filterItems.length; i++ ) {
-                               result[ filterItems[ i ].getParamName() ] = this.areAnySelected() ?
-                                       Number( !filterItems[ i ].isSelected() ) : 0;
-                       }
-
+                       $.each( filterRepresentation, function ( name, value ) {
+                               result[ filterParamNames[ name ] ] = areAnySelected ?
+                                       Number( !value ) : 0;
+                       } );
                } else if ( this.getType() === 'string_options' ) {
                        values = [];
-                       for ( i = 0; i < filterItems.length; i++ ) {
-                               if ( filterItems[ i ].isSelected() ) {
-                                       values.push( filterItems[ i ].getParamName() );
+
+                       $.each( filterRepresentation, function ( name, value ) {
+                               // Collect values
+                               if ( value ) {
+                                       values.push( filterParamNames[ name ] );
                                }
-                       }
+                       } );
 
-                       result[ this.getName() ] = ( values.length === filterItems.length ) ?
+                       result[ this.getName() ] = ( values.length === Object.keys( filterRepresentation ).length ) ?
                                'all' : values.join( this.getSeparator() );
                }
 
index 69210be..9054fe4 100644 (file)
                                items.push( filterItem );
                        }
 
-                       if ( data.type === 'string_options' && data.default ) {
+                       if ( data.type === 'string_options' ) {
                                // Store the default parameter group state
                                // For this group, the parameter is group name and value is the names
                                // of selected items
                                model.defaultParams[ group ] = model.sanitizeStringOptionGroup(
                                        group,
-                                       data.default.split( model.groups[ group ].getSeparator() )
+                                       data.default ?
+                                               data.default.split( model.groups[ group ].getSeparator() ) :
+                                               []
                                ).join( model.groups[ group ].getSeparator() );
                        }
                } );
                return this.defaultParams;
        };
 
-       /**
-        * Set all filter states to default values
-        */
-       mw.rcfilters.dm.FiltersViewModel.prototype.setFiltersToDefaults = function () {
-               var defaultFilterStates = this.getFiltersFromParameters( this.getDefaultParams() );
-
-               this.toggleFiltersSelected( defaultFilterStates );
-       };
-
        /**
         * Analyze the groups and their filters and output an object representing
         * the state of the parameters they represent.
         *
-        * @param {Object} [filterGroups] An object defining the filter groups to
-        *  translate to parameters. Its structure must follow that of this.groups
-        *  see #getFilterGroups
+        * @param {Object} [filterDefinition] An object defining the filter values,
+        *  keyed by filter names.
         * @return {Object} Parameter state object
         */
-       mw.rcfilters.dm.FiltersViewModel.prototype.getParametersFromFilters = function ( filterGroups ) {
-               var result = {},
-                       groupItems = filterGroups || this.getFilterGroups();
+       mw.rcfilters.dm.FiltersViewModel.prototype.getParametersFromFilters = function ( filterDefinition ) {
+               var groupItemDefinition,
+                       result = {},
+                       groupItems = this.getFilterGroups();
+
+               if ( filterDefinition ) {
+                       groupItemDefinition = {};
+                       // Filter definition is "flat", but in effect
+                       // each group needs to tell us its result based
+                       // on the values in it. We need to split this list
+                       // back into groupings so we can "feed" it to the
+                       // loop below, and we need to expand it so it includes
+                       // all filters (set to false)
+                       this.getItems().forEach( function ( filterItem ) {
+                               groupItemDefinition[ filterItem.getGroupName() ] = groupItemDefinition[ filterItem.getGroupName() ] || {};
+                               groupItemDefinition[ filterItem.getGroupName() ][ filterItem.getName() ] = !!filterDefinition[ filterItem.getName() ];
+                       } );
+               }
 
                $.each( groupItems, function ( group, model ) {
-                       $.extend( result, model.getParamRepresentation() );
+                       $.extend(
+                               result,
+                               model.getParamRepresentation(
+                                       groupItemDefinition ?
+                                               groupItemDefinition[ group ] : null
+                               )
+                       );
                } );
 
                return result;
         * @param {string[]} valueArray Array of values
         * @return {string[]} Array of valid values
         */
-       mw.rcfilters.dm.FiltersViewModel.prototype.sanitizeStringOptionGroup = function( groupName, valueArray ) {
+       mw.rcfilters.dm.FiltersViewModel.prototype.sanitizeStringOptionGroup = function ( groupName, valueArray ) {
                var result = [],
                        validNames = this.getGroupFilters( groupName ).map( function ( filterItem ) {
                                return filterItem.getParamName();
                } );
        };
 
+       /**
+        * Get items that allow highlights even if they're not currently highlighted
+        *
+        * @return {mw.rcfilters.dm.FilterItem[]} Items supporting highlights
+        */
+       mw.rcfilters.dm.FiltersViewModel.prototype.getItemsSupportingHighlights = function () {
+               return this.getItems().filter( function ( filterItem ) {
+                       return filterItem.isHighlightSupported();
+               } );
+       };
+
        /**
         * Toggle the highlight feature on and off.
         * Propagate the change to filter items.
diff --git a/resources/src/mediawiki.rcfilters/dm/mw.rcfilters.dm.SavedQueriesModel.js b/resources/src/mediawiki.rcfilters/dm/mw.rcfilters.dm.SavedQueriesModel.js
new file mode 100644 (file)
index 0000000..04fb52b
--- /dev/null
@@ -0,0 +1,192 @@
+( function ( mw, $ ) {
+       /**
+        * View model for saved queries
+        *
+        * @mixins OO.EventEmitter
+        * @mixins OO.EmitterList
+        *
+        * @constructor
+        * @param {Object} [config] Configuration options
+        * @cfg {string} [default] Default query ID
+        */
+       mw.rcfilters.dm.SavedQueriesModel = function MwRcfiltersDmSavedQueriesModel( config ) {
+               config = config || {};
+
+               // Mixin constructor
+               OO.EventEmitter.call( this );
+               OO.EmitterList.call( this );
+
+               this.default = config.default;
+
+               // Events
+               this.aggregate( { update: 'itemUpdate' } );
+       };
+
+       /* Initialization */
+
+       OO.initClass( mw.rcfilters.dm.SavedQueriesModel );
+       OO.mixinClass( mw.rcfilters.dm.SavedQueriesModel, OO.EventEmitter );
+       OO.mixinClass( mw.rcfilters.dm.SavedQueriesModel, OO.EmitterList );
+
+       /* Events */
+
+       /**
+        * @event initialize
+        *
+        * Model is initialized
+        */
+
+       /**
+        * @event itemUpdate
+        * @param {mw.rcfilters.dm.SavedQueryItemModel} Changed item
+        *
+        * An item has changed
+        */
+
+       /* Methods */
+
+       /**
+        * Initialize the saved queries model by reading it from the user's settings.
+        * The structure of the saved queries is:
+        * {
+        *    default: (string) Query ID
+        *    queries:{
+        *       query_id_1: {
+        *          data:{
+        *             filters: (Object) Minimal definition of the filters
+        *             highlights: (Object) Definition of the highlights
+        *          },
+        *          label: (optional) Name of this query
+        *       }
+        *    }
+        * }
+        *
+        * @param {Object} [savedQueries] An object with the saved queries with
+        *  the above structure.
+        * @param {Object} [baseState] An object representing the base state
+        *  so we can normalize the data
+        * @fires initialize
+        */
+       mw.rcfilters.dm.SavedQueriesModel.prototype.initialize = function ( savedQueries, baseState ) {
+               var items = [];
+
+               savedQueries = savedQueries || {};
+
+               this.baseState = baseState;
+
+               this.clearItems();
+               $.each( savedQueries.queries || {}, function ( id, obj ) {
+                       var normalizedData = $.extend( true, {}, baseState, obj.data );
+                       items.push(
+                               new mw.rcfilters.dm.SavedQueryItemModel(
+                                       id,
+                                       obj.label,
+                                       normalizedData,
+                                       { 'default': savedQueries.default === id }
+                               )
+                       );
+               } );
+
+               this.default = savedQueries.default;
+
+               this.addItems( items );
+
+               this.emit( 'initialize' );
+       };
+
+       /**
+        * Add a query item
+        *
+        * @param {string} label Label for the new query
+        * @param {Object} data Data for the new query
+        */
+       mw.rcfilters.dm.SavedQueriesModel.prototype.addNewQuery = function ( label, data ) {
+               var randomID = ( new Date() ).getTime(),
+                       normalizedData = $.extend( true, {}, this.baseState, data );
+
+               // Add item
+               this.addItems( [
+                       new mw.rcfilters.dm.SavedQueryItemModel(
+                               randomID,
+                               label,
+                               normalizedData
+                       )
+               ] );
+       };
+
+       /**
+        * Get an item that matches the requested query
+        *
+        * @param {Object} fullQueryComparison Object representing all filters and highlights to compare
+        * @return {mw.rcfilters.dm.SavedQueryItemModel} Matching item model
+        */
+       mw.rcfilters.dm.SavedQueriesModel.prototype.findMatchingQuery = function ( fullQueryComparison ) {
+               return this.getItems().filter( function ( item ) {
+                       return OO.compare(
+                               item.getData(),
+                               fullQueryComparison
+                       );
+               } )[ 0 ];
+       };
+
+       /**
+        * Get query by its identifier
+        *
+        * @param {string} queryID Query identifier
+        * @return {mw.rcfilters.dm.SavedQueryItemModel|undefined} Item matching
+        *  the search. Undefined if not found.
+        */
+       mw.rcfilters.dm.SavedQueriesModel.prototype.getItemByID = function ( queryID ) {
+               return this.getItems().filter( function ( item ) {
+                       return item.getID() === queryID;
+               } )[ 0 ];
+       };
+
+       /**
+        * Get the object representing the state of the entire model and items
+        *
+        * @return {Object} Object representing the state of the model and items
+        */
+       mw.rcfilters.dm.SavedQueriesModel.prototype.getState = function () {
+               var obj = { queries: {} };
+
+               // Translate the items to the saved object
+               this.getItems().forEach( function ( item ) {
+                       var itemState = item.getState();
+
+                       obj.queries[ item.getID() ] = itemState;
+               } );
+
+               if ( this.getDefault() ) {
+                       obj.default = this.getDefault();
+               }
+
+               return obj;
+       };
+
+       /**
+        * Set a default query. Null to unset default.
+        *
+        * @param {string} itemID Query identifier
+        * @fires default
+        */
+       mw.rcfilters.dm.SavedQueriesModel.prototype.setDefault = function ( itemID ) {
+               if ( this.default !== itemID ) {
+                       this.default = itemID;
+
+                       // Set for individual itens
+                       this.getItems().forEach( function ( item ) {
+                               item.toggleDefault( item.getID() === itemID );
+                       } );
+               }
+       };
+
+       /**
+        * Get the default query ID
+        *
+        * @return {string} Default query identifier
+        */
+       mw.rcfilters.dm.SavedQueriesModel.prototype.getDefault = function () {
+               return this.default;
+       };
+}( mediaWiki, jQuery ) );
diff --git a/resources/src/mediawiki.rcfilters/dm/mw.rcfilters.dm.SavedQueryItemModel.js b/resources/src/mediawiki.rcfilters/dm/mw.rcfilters.dm.SavedQueryItemModel.js
new file mode 100644 (file)
index 0000000..729aee3
--- /dev/null
@@ -0,0 +1,115 @@
+( function ( mw ) {
+       /**
+        * View model for a single saved query
+        *
+        * @mixins OO.EventEmitter
+        *
+        * @constructor
+        * @param {string} id Unique identifier
+        * @param {string} label Saved query label
+        * @param {Object} data Saved query data
+        * @param {Object} [config] Configuration options
+        * @param {boolean} [default] This item is the default
+        */
+       mw.rcfilters.dm.SavedQueryItemModel = function MwRcfiltersDmSavedQueriesModel( id, label, data, config ) {
+               config = config || {};
+
+               // Mixin constructor
+               OO.EventEmitter.call( this );
+
+               this.id = id;
+               this.label = label;
+               this.data = data;
+               this.default = !!config.default;
+       };
+
+       /* Initialization */
+
+       OO.initClass( mw.rcfilters.dm.SavedQueryItemModel );
+       OO.mixinClass( mw.rcfilters.dm.SavedQueryItemModel, OO.EventEmitter );
+
+       /* Events */
+
+       /**
+        * @update
+        *
+        * Model has been updated
+        */
+
+       /* Methods */
+
+       /**
+        * Get an object representing the state of this item
+        *
+        * @returns {Object} Object representing the current data state
+        *  of the object
+        */
+       mw.rcfilters.dm.SavedQueryItemModel.prototype.getState = function () {
+               return {
+                       data: this.getData(),
+                       label: this.getLabel()
+               };
+       };
+
+       /**
+        * Get the query's identifier
+        *
+        * @return {string} Query identifier
+        */
+       mw.rcfilters.dm.SavedQueryItemModel.prototype.getID = function () {
+               return this.id;
+       };
+
+       /**
+        * Get query label
+        *
+        * @return {label} Query label
+        */
+       mw.rcfilters.dm.SavedQueryItemModel.prototype.getLabel = function () {
+               return this.label;
+       };
+
+       /**
+        * Update the query label
+        *
+        * @param {string} newLabel New label
+        */
+       mw.rcfilters.dm.SavedQueryItemModel.prototype.updateLabel = function ( newLabel ) {
+               if ( newLabel && this.label !== newLabel ) {
+                       this.label = newLabel;
+                       this.emit( 'update' );
+               }
+       };
+
+       /**
+        * Get query data
+        *
+        * @return {Object} Object representing parameter and highlight data
+        */
+       mw.rcfilters.dm.SavedQueryItemModel.prototype.getData = function () {
+               return this.data;
+       };
+
+       /**
+        * Check whether this item is the default
+        *
+        * @return {boolean} Query is set to be default
+        */
+       mw.rcfilters.dm.SavedQueryItemModel.prototype.isDefault = function () {
+               return this.default;
+       };
+
+       /**
+        * Toggle the default state of this query item
+        *
+        * @param {boolean} isDefault Query is default
+        */
+       mw.rcfilters.dm.SavedQueryItemModel.prototype.toggleDefault = function ( isDefault ) {
+               isDefault = isDefault === undefined ? !this.default : isDefault;
+
+               if ( this.default !== isDefault ) {
+                       this.default = isDefault;
+                       this.emit( 'update' );
+               }
+       };
+}( mediaWiki ) );
diff --git a/resources/src/mediawiki.rcfilters/images/clip.svg b/resources/src/mediawiki.rcfilters/images/clip.svg
new file mode 100644 (file)
index 0000000..86d1dbf
--- /dev/null
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
+    <path d="M17.5 4.5v13.2L12 13.5l-5.5 4.2V4.5zM5 21l7-6 7 6V3H5z" fill-rule="evenodd"/>
+</svg>
diff --git a/resources/src/mediawiki.rcfilters/images/pushPin.svg b/resources/src/mediawiki.rcfilters/images/pushPin.svg
new file mode 100644 (file)
index 0000000..b852cd0
--- /dev/null
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
+    <path d="M17.445 12.225c-.813-.935-1.775-.739-2.883-1.768-.55-.511-.498-2.36-.498-2.36s-.041-1.836.524-2.401c.39-.39 1.076-.49 1.475-.883a.973.973 0 0 0 .217-.317c.007-.013.014-.023.018-.035.035-.092.054-.2.064-.316.003-.03.017-.055.017-.085 0-.005-.003-.01-.004-.015.001-.008.004-.014.004-.022 0-.02-.015-.03-.017-.048a1.052 1.052 0 0 0-1.043-.974H8.681c-.555 0-.997.43-1.043.974-.002.018-.017.028-.017.048 0 .008.003.014.003.022 0 .006-.003.01-.003.015 0 .03.014.055.017.085.01.116.029.224.064.316.004.012.012.022.018.035a.965.965 0 0 0 .217.317c.399.393 1.084.493 1.475.883.565.565.523 2.401.523 2.401s.053 1.849-.497 2.36c-1.108 1.03-2.07.833-2.883 1.768C5.979 12.887 6 14 6 14h5.333v4.578L12 21l.668-2.422V14H18s.02-1.113-.555-1.775z"/>
+</svg>
diff --git a/resources/src/mediawiki.rcfilters/images/unClip.svg b/resources/src/mediawiki.rcfilters/images/unClip.svg
new file mode 100644 (file)
index 0000000..68459db
--- /dev/null
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
+    <path d="M5 21l7-6 7 6V3H5z" fill-rule="evenodd"/>
+</svg>
index 669420c..35541d1 100644 (file)
@@ -1,14 +1,18 @@
 ( function ( mw, $ ) {
+       /* eslint no-underscore-dangle: "off" */
        /**
         * Controller for the filters in Recent Changes
         *
         * @param {mw.rcfilters.dm.FiltersViewModel} filtersModel Filters view model
         * @param {mw.rcfilters.dm.ChangesListViewModel} changesListModel Changes list view model
+        * @param {mw.rcfilters.dm.SavedQueriesModel} savedQueriesModel Saved queries model
         */
-       mw.rcfilters.Controller = function MwRcfiltersController( filtersModel, changesListModel ) {
+       mw.rcfilters.Controller = function MwRcfiltersController( filtersModel, changesListModel, savedQueriesModel ) {
                this.filtersModel = filtersModel;
                this.changesListModel = changesListModel;
+               this.savedQueriesModel = savedQueriesModel;
                this.requestCounter = 0;
+               this.baseState = {};
        };
 
        /* Initialization */
         * @param {Array} filterStructure Filter definition and structure for the model
         */
        mw.rcfilters.Controller.prototype.initialize = function ( filterStructure ) {
-               var $changesList = $( '.mw-changeslist' ).first().contents();
+               var parsedSavedQueries,
+                       $changesList = $( '.mw-changeslist' ).first().contents();
                // Initialize the model
                this.filtersModel.initializeFilters( filterStructure );
+
+               this._buildBaseFilterState();
+
+               try {
+                       parsedSavedQueries = JSON.parse( mw.user.options.get( 'rcfilters-saved-queries' ) || '{}' );
+               } catch ( err ) {
+                       parsedSavedQueries = {};
+               }
+
+               // The queries are saved in a minimized state, so we need
+               // to send over the base state so the saved queries model
+               // can normalize them per each query item
+               this.savedQueriesModel.initialize(
+                       parsedSavedQueries,
+                       this._getBaseState()
+               );
                this.updateStateBasedOnUrl();
 
                // Update the changes list with the existing data
                        $changesList.length ? $changesList : 'NO_RESULTS',
                        $( 'fieldset.rcoptions' ).first()
                );
-
-       };
-
-       /**
-        * Update filter state (selection and highlighting) based
-        * on current URL and default values.
-        */
-       mw.rcfilters.Controller.prototype.updateStateBasedOnUrl = function () {
-               var uri = new mw.Uri();
-
-               // Set filter states based on defaults and URL params
-               this.filtersModel.toggleFiltersSelected(
-                       this.filtersModel.getFiltersFromParameters(
-                               // Merge defaults with URL params for initialization
-                               $.extend(
-                                       true,
-                                       {},
-                                       this.filtersModel.getDefaultParams(),
-                                       // URI query overrides defaults
-                                       uri.query
-                               )
-                       )
-               );
-
-               // Initialize highlights
-               this.filtersModel.toggleHighlight( !!uri.query.highlight );
-               this.filtersModel.getItems().forEach( function ( filterItem ) {
-                       var color = uri.query[ filterItem.getName() + '_color' ];
-                       if ( color ) {
-                               filterItem.setHighlightColor( color );
-                       } else {
-                               filterItem.clearHighlightColor();
-                       }
-               } );
-
-               // Check all filter interactions
-               this.filtersModel.reassessFilterInteractions();
        };
 
        /**
         * Reset to default filters
         */
        mw.rcfilters.Controller.prototype.resetToDefaults = function () {
-               this.filtersModel.setFiltersToDefaults();
-               this.filtersModel.clearAllHighlightColors();
-               // Check all filter interactions
-               this.filtersModel.reassessFilterInteractions();
-
+               this._updateModelState( this._getDefaultParams() );
                this.updateChangesList();
        };
 
@@ -98,7 +78,7 @@
                this.updateChangesList();
 
                if ( highlightedFilterNames ) {
-                       this.trackHighlight( 'clearAll', highlightedFilterNames );
+                       this._trackHighlight( 'clearAll', highlightedFilterNames );
                }
        };
 
                }
        };
 
+       /**
+        * Clear both highlight and selection of a filter
+        *
+        * @param {string} filterName Name of the filter item
+        */
+       mw.rcfilters.Controller.prototype.clearFilter = function ( filterName ) {
+               var filterItem = this.filtersModel.getItemByName( filterName ),
+                       isHighlighted = filterItem.isHighlighted();
+
+               if ( filterItem.isSelected() || isHighlighted ) {
+                       this.filtersModel.clearHighlightColor( filterName );
+                       this.filtersModel.toggleFilterSelected( filterName, false );
+                       this.updateChangesList();
+                       this.filtersModel.reassessFilterInteractions( filterItem );
+               }
+
+               if ( isHighlighted ) {
+                       this._trackHighlight( 'clear', filterName );
+               }
+       };
+
+       /**
+        * Toggle the highlight feature on and off
+        */
+       mw.rcfilters.Controller.prototype.toggleHighlight = function () {
+               this.filtersModel.toggleHighlight();
+               this._updateURL();
+
+               if ( this.filtersModel.isHighlightEnabled() ) {
+                       mw.hook( 'RcFilters.highlight.enable' ).fire();
+               }
+       };
+
+       /**
+        * Set the highlight color for a filter item
+        *
+        * @param {string} filterName Name of the filter item
+        * @param {string} color Selected color
+        */
+       mw.rcfilters.Controller.prototype.setHighlightColor = function ( filterName, color ) {
+               this.filtersModel.setHighlightColor( filterName, color );
+               this._updateURL();
+               this._trackHighlight( 'set', { name: filterName, color: color } );
+       };
+
+       /**
+        * Clear highlight for a filter item
+        *
+        * @param {string} filterName Name of the filter item
+        */
+       mw.rcfilters.Controller.prototype.clearHighlightColor = function ( filterName ) {
+               this.filtersModel.clearHighlightColor( filterName );
+               this._updateURL();
+               this._trackHighlight( 'clear', filterName );
+       };
+
+       /**
+        * Save the current model state as a saved query
+        *
+        * @param {string} [label] Label of the saved query
+        */
+       mw.rcfilters.Controller.prototype.saveCurrentQuery = function ( label ) {
+               var highlightedItems = {},
+                       highlightEnabled = this.filtersModel.isHighlightEnabled();
+
+               // Prepare highlights
+               this.filtersModel.getHighlightedItems().forEach( function ( item ) {
+                       highlightedItems[ item.getName() ] = highlightEnabled ?
+                               item.getHighlightColor() : null;
+               } );
+               highlightedItems.highlights = this.filtersModel.isHighlightEnabled();
+
+               // Add item
+               this.savedQueriesModel.addNewQuery(
+                       label || mw.msg( 'rcfilters-savedqueries-defaultlabel' ),
+                       {
+                               filters: this.filtersModel.getSelectedState(),
+                               highlights: highlightedItems
+                       }
+               );
+
+               // Save item
+               this._saveSavedQueries();
+       };
+
+       /**
+        * Remove a saved query
+        *
+        * @param {string} queryID Query id
+        */
+       mw.rcfilters.Controller.prototype.removeSavedQuery = function ( queryID ) {
+               var query = this.savedQueriesModel.getItemByID( queryID );
+
+               this.savedQueriesModel.removeItems( [ query ] );
+
+               // Check if this item was the default
+               if ( this.savedQueriesModel.getDefault() === queryID ) {
+                       // Nulify the default
+                       this.savedQueriesModel.setDefault( null );
+               }
+               this._saveSavedQueries();
+       };
+
+       /**
+        * Rename a saved query
+        *
+        * @param {string} queryID Query id
+        * @param {string} newLabel New label for the query
+        */
+       mw.rcfilters.Controller.prototype.renameSavedQuery = function ( queryID, newLabel ) {
+               var queryItem = this.savedQueriesModel.getItemByID( queryID );
+
+               if ( queryItem ) {
+                       queryItem.updateLabel( newLabel );
+               }
+               this._saveSavedQueries();
+       };
+
+       /**
+        * Set a saved query as default
+        *
+        * @param {string} queryID Query Id. If null is given, default
+        *  query is reset.
+        */
+       mw.rcfilters.Controller.prototype.setDefaultSavedQuery = function ( queryID ) {
+               this.savedQueriesModel.setDefault( queryID );
+               this._saveSavedQueries();
+       };
+
+       /**
+        * Load a saved query
+        *
+        * @param {string} queryID Query id
+        */
+       mw.rcfilters.Controller.prototype.applySavedQuery = function ( queryID ) {
+               var data, highlights,
+                       queryItem = this.savedQueriesModel.getItemByID( queryID );
+
+               if ( queryItem ) {
+                       data = queryItem.getData();
+                       highlights = data.highlights;
+
+                       // Update model state from filters
+                       this.filtersModel.toggleFiltersSelected( data.filters );
+
+                       // Update highlight state
+                       this.filtersModel.toggleHighlight( !!highlights.highlights );
+                       this.filtersModel.getItems().forEach( function ( filterItem ) {
+                               var color = highlights[ filterItem.getName() ];
+                               if ( color ) {
+                                       filterItem.setHighlightColor( color );
+                               } else {
+                                       filterItem.clearHighlightColor();
+                               }
+                       } );
+
+                       // Check all filter interactions
+                       this.filtersModel.reassessFilterInteractions();
+
+                       this.updateChangesList();
+               }
+       };
+
+       /**
+        * Check whether the current filter and highlight state exists
+        * in the saved queries model.
+        *
+        * @return {boolean} Query exists
+        */
+       mw.rcfilters.Controller.prototype.findQueryMatchingCurrentState = function () {
+               var highlightedItems = {};
+
+               // Prepare highlights of the current query
+               this.filtersModel.getItemsSupportingHighlights().forEach( function ( item ) {
+                       highlightedItems[ item.getName() ] = item.getHighlightColor();
+               } );
+               highlightedItems.highlights = this.filtersModel.isHighlightEnabled();
+
+               return this.savedQueriesModel.findMatchingQuery(
+                       {
+                               filters: this.filtersModel.getSelectedState(),
+                               highlights: highlightedItems
+                       }
+               );
+       };
+
+       /**
+        * Get an object representing the base state of parameters
+        * and highlights.
+        *
+        * This is meant to make sure that the saved queries that are
+        * in memory are always the same structure as what we would get
+        * by calling the current model's "getSelectedState" and by checking
+        * highlight items.
+        *
+        * In cases where a user saved a query when the system had a certain
+        * set of filters, and then a filter was added to the system, we want
+        * to make sure that the stored queries can still be comparable to
+        * the current state, which means that we need the base state for
+        * two operations:
+        *
+        * - Saved queries are stored in "minimal" view (only changed filters
+        *   are stored); When we initialize the system, we merge each minimal
+        *   query with the base state (using 'getNormalizedFilters') so all
+        *   saved queries have the exact same structure as what we would get
+        *   by checking the getSelectedState of the filter.
+        * - When we save the queries, we minimize the object to only represent
+        *   whatever has actually changed, rather than store the entire
+        *   object. To check what actually is different so we can store it,
+        *   we need to obtain a base state to compare against, this is
+        *   what #_getMinimalFilterList does
+        */
+       mw.rcfilters.Controller.prototype._buildBaseFilterState = function () {
+               var defaultParams = this.filtersModel.getDefaultParams(),
+                       highlightedItems = {};
+
+               // Prepare highlights
+               this.filtersModel.getItemsSupportingHighlights().forEach( function ( item ) {
+                       highlightedItems[ item.getName() ] = null;
+               } );
+               highlightedItems.highlights = false;
+
+               this.baseState = {
+                       filters: this.filtersModel.getFiltersFromParameters( defaultParams ),
+                       highlights: highlightedItems
+               };
+       };
+
+       /**
+        * Get an object representing the base state of parameters
+        * and highlights. The structure is similar to what we use
+        * to store each query in the saved queries object:
+        * {
+        *    filters: {
+        *        filterName: (bool)
+        *    },
+        *    highlights: {
+        *        filterName: (string|null)
+        *    }
+        * }
+        *
+        * @return {Object} Object representing the base state of
+        *  parameters and highlights
+        */
+       mw.rcfilters.Controller.prototype._getBaseState = function () {
+               return this.baseState;
+       };
+
+       /**
+        * Get an object that holds only the parameters and highlights that have
+        * values different than the base default value.
+        *
+        * This is the reverse of the normalization we do initially on loading and
+        * initializing the saved queries model.
+        *
+        * @param {Object} valuesObject Object representing the state of both
+        *  filters and highlights in its normalized version, to be minimized.
+        * @return {Object} Minimal filters and highlights list
+        */
+       mw.rcfilters.Controller.prototype._getMinimalFilterList = function ( valuesObject ) {
+               var result = { filters: {}, highlights: {} },
+                       baseState = this._getBaseState();
+
+               // XOR results
+               $.each( valuesObject.filters, function ( name, value ) {
+                       if ( baseState.filters !== undefined && baseState.filters[ name ] !== value ) {
+                               result.filters[ name ] = value;
+                       }
+               } );
+
+               $.each( valuesObject.highlights, function ( name, value ) {
+                       if ( baseState.highlights !== undefined && baseState.highlights[ name ] !== value ) {
+                               result.highlights[ name ] = value;
+                       }
+               } );
+
+               return result;
+       };
+
+       /**
+        * Save the current state of the saved queries model with all
+        * query item representation in the user settings.
+        */
+       mw.rcfilters.Controller.prototype._saveSavedQueries = function () {
+               var stringified,
+                       state = this.savedQueriesModel.getState(),
+                       controller = this;
+
+               // Minimize before save
+               $.each( state.queries, function ( queryID, info ) {
+                       state.queries[ queryID ].data = controller._getMinimalFilterList( info.data );
+               } );
+
+               // Stringify state
+               stringified = JSON.stringify( state );
+
+               if ( stringified.length > 65535 ) {
+                       // Sanity check, since the preference can only hold that.
+                       return;
+               }
+
+               // Save the preference
+               new mw.Api().saveOption( 'rcfilters-saved-queries', stringified );
+               // Update the preference for this session
+               mw.user.options.set( 'rcfilters-saved-queries', stringified );
+       };
+
+       /**
+        * Synchronize the URL with the current state of the filters
+        * without adding an history entry.
+        */
+       mw.rcfilters.Controller.prototype.replaceUrl = function () {
+               window.history.replaceState(
+                       { tag: 'rcfilters' },
+                       document.title,
+                       this._getUpdatedUri().toString()
+               );
+       };
+
+       /**
+        * Update filter state (selection and highlighting) based
+        * on current URL and default values.
+        */
+       mw.rcfilters.Controller.prototype.updateStateBasedOnUrl = function () {
+               var uri = new mw.Uri(),
+                       defaultParams = this._getDefaultParams();
+
+               this._updateModelState( $.extend( {}, defaultParams, uri.query ) );
+               this.updateChangesList();
+       };
+
+       /**
+        * Update the list of changes and notify the model
+        *
+        * @param {Object} [params] Extra parameters to add to the API call
+        */
+       mw.rcfilters.Controller.prototype.updateChangesList = function ( params ) {
+               this._updateURL( params );
+               this.changesListModel.invalidate();
+               this._fetchChangesList()
+                       .then(
+                               // Success
+                               function ( pieces ) {
+                                       var $changesListContent = pieces.changes,
+                                               $fieldset = pieces.fieldset;
+                                       this.changesListModel.update( $changesListContent, $fieldset );
+                               }.bind( this )
+                               // Do nothing for failure
+                       );
+       };
+
+       /**
+        * Update the model state from given the given parameters.
+        *
+        * This is an internal method, and should only be used from inside
+        * the controller.
+        *
+        * @param {Object} parameters Object representing the parameters for
+        *  filters and highlights
+        */
+       mw.rcfilters.Controller.prototype._updateModelState = function ( parameters ) {
+               // Update filter states
+               this.filtersModel.toggleFiltersSelected(
+                       this.filtersModel.getFiltersFromParameters(
+                               parameters
+                       )
+               );
+
+               // Update highlight state
+               this.filtersModel.toggleHighlight( !!parameters.highlights );
+               this.filtersModel.getItems().forEach( function ( filterItem ) {
+                       var color = parameters[ filterItem.getName() + '_color' ];
+                       if ( color ) {
+                               filterItem.setHighlightColor( color );
+                       } else {
+                               filterItem.clearHighlightColor();
+                       }
+               } );
+
+               // Check all filter interactions
+               this.filtersModel.reassessFilterInteractions();
+       };
+
+       /**
+        * Get an object representing the default parameter state, whether
+        * it is from the model defaults or from the saved queries.
+        *
+        * @return {Object} Default parameters
+        */
+       mw.rcfilters.Controller.prototype._getDefaultParams = function () {
+               var data, queryHighlights,
+                       savedParams = {},
+                       savedHighlights = {},
+                       defaultSavedQueryItem = this.savedQueriesModel.getItemByID( this.savedQueriesModel.getDefault() );
+
+               if ( defaultSavedQueryItem ) {
+                       data = defaultSavedQueryItem.getData();
+
+                       queryHighlights = data.highlights || {};
+                       savedParams = this.filtersModel.getParametersFromFilters( data.filters || {} );
+
+                       // Translate highlights to parameters
+                       savedHighlights.highlights = queryHighlights.highlights;
+                       $.each( queryHighlights, function ( filterName, color ) {
+                               if ( filterName !== 'highlights' ) {
+                                       savedHighlights[ filterName + '_color' ] = color;
+                               }
+                       } );
+
+                       return $.extend( true, {}, savedParams, savedHighlights );
+               }
+
+               return this.filtersModel.getDefaultParams();
+       };
+
        /**
         * Update the URL of the page to reflect current filters
         *
         * highlighting actions below, or call #updateChangesList which does
         * the uri corrections already.
         *
-        * @private
         * @param {Object} [params] Extra parameters to add to the API call
         */
-       mw.rcfilters.Controller.prototype.updateURL = function ( params ) {
+       mw.rcfilters.Controller.prototype._updateURL = function ( params ) {
                var updatedUri,
                        notEquivalent = function ( obj1, obj2 ) {
                                var keys = Object.keys( obj1 ).concat( Object.keys( obj2 ) );
 
                params = params || {};
 
-               updatedUri = this.getUpdatedUri();
+               updatedUri = this._getUpdatedUri();
                updatedUri.extend( params );
 
                if ( notEquivalent( updatedUri.query, new mw.Uri().query ) ) {
         *
         * @return {mw.Uri} Updated Uri
         */
-       mw.rcfilters.Controller.prototype.getUpdatedUri = function () {
+       mw.rcfilters.Controller.prototype._getUpdatedUri = function () {
                var uri = new mw.Uri(),
                        highlightParams = this.filtersModel.getHighlightParameters();
 
         * @return {jQuery.Promise} Promise object that will resolve with the changes list
         *  or with a string denoting no results.
         */
-       mw.rcfilters.Controller.prototype.fetchChangesList = function () {
-               var uri = this.getUpdatedUri(),
+       mw.rcfilters.Controller.prototype._fetchChangesList = function () {
+               var uri = this._getUpdatedUri(),
                        requestId = ++this.requestCounter,
                        latestRequest = function () {
                                return requestId === this.requestCounter;
                        );
        };
 
-       /**
-        * Update the list of changes and notify the model
-        *
-        * @param {Object} [params] Extra parameters to add to the API call
-        */
-       mw.rcfilters.Controller.prototype.updateChangesList = function ( params ) {
-               this.updateURL( params );
-               this.changesListModel.invalidate();
-               this.fetchChangesList()
-                       .then(
-                               // Success
-                               function ( pieces ) {
-                                       var $changesListContent = pieces.changes,
-                                               $fieldset = pieces.fieldset;
-                                       this.changesListModel.update( $changesListContent, $fieldset );
-                               }.bind( this )
-                               // Do nothing for failure
-                       );
-       };
-
-       /**
-        * Toggle the highlight feature on and off
-        */
-       mw.rcfilters.Controller.prototype.toggleHighlight = function () {
-               this.filtersModel.toggleHighlight();
-               this.updateURL();
-
-               if ( this.filtersModel.isHighlightEnabled() ) {
-                       mw.hook( 'RcFilters.highlight.enable' ).fire();
-               }
-       };
-
-       /**
-        * Set the highlight color for a filter item
-        *
-        * @param {string} filterName Name of the filter item
-        * @param {string} color Selected color
-        */
-       mw.rcfilters.Controller.prototype.setHighlightColor = function ( filterName, color ) {
-               this.filtersModel.setHighlightColor( filterName, color );
-               this.updateURL();
-               this.trackHighlight( 'set', { name: filterName, color: color } );
-       };
-
-       /**
-        * Clear highlight for a filter item
-        *
-        * @param {string} filterName Name of the filter item
-        */
-       mw.rcfilters.Controller.prototype.clearHighlightColor = function ( filterName ) {
-               this.filtersModel.clearHighlightColor( filterName );
-               this.updateURL();
-               this.trackHighlight( 'clear', filterName );
-       };
-
-       /**
-        * Clear both highlight and selection of a filter
-        *
-        * @param {string} filterName Name of the filter item
-        */
-       mw.rcfilters.Controller.prototype.clearFilter = function ( filterName ) {
-               var filterItem = this.filtersModel.getItemByName( filterName ),
-                       isHighlighted = filterItem.isHighlighted();
-
-               if ( filterItem.isSelected() || isHighlighted ) {
-                       this.filtersModel.clearHighlightColor( filterName );
-                       this.filtersModel.toggleFilterSelected( filterName, false );
-                       this.updateChangesList();
-                       this.filtersModel.reassessFilterInteractions( filterItem );
-               }
-
-               if ( isHighlighted ) {
-                       this.trackHighlight( 'clear', filterName );
-               }
-       };
-
-       /**
-        * Synchronize the URL with the current state of the filters
-        * without adding an history entry.
-        */
-       mw.rcfilters.Controller.prototype.replaceUrl = function () {
-               window.history.replaceState(
-                       { tag: 'rcfilters' },
-                       document.title,
-                       this.getUpdatedUri().toString()
-               );
-       };
-
        /**
         * Track usage of highlight feature
         *
         * @param {string} action
         * @param {array|object|string} filters
         */
-       mw.rcfilters.Controller.prototype.trackHighlight = function ( action, filters ) {
+       mw.rcfilters.Controller.prototype._trackHighlight = function ( action, filters ) {
                filters = typeof filters === 'string' ? { name: filters } : filters;
                filters = !Array.isArray( filters ) ? [ filters ] : filters;
                mw.track(
                        }
                );
        };
+
 }( mediaWiki, jQuery ) );
index 4a586e4..dd8fae0 100644 (file)
                init: function () {
                        var filtersModel = new mw.rcfilters.dm.FiltersViewModel(),
                                changesListModel = new mw.rcfilters.dm.ChangesListViewModel(),
-                               controller = new mw.rcfilters.Controller( filtersModel, changesListModel ),
+                               savedQueriesModel = new mw.rcfilters.dm.SavedQueriesModel(),
+                               controller = new mw.rcfilters.Controller( filtersModel, changesListModel, savedQueriesModel ),
                                $overlay = $( '<div>' )
                                        .addClass( 'mw-rcfilters-ui-overlay' ),
                                filtersWidget = new mw.rcfilters.ui.FilterWrapperWidget(
-                                       controller, filtersModel, { $overlay: $overlay } );
+                                       controller, filtersModel, savedQueriesModel, { $overlay: $overlay } );
 
                        // TODO: The changesListWrapperWidget should be able to initialize
                        // after the model is ready.
index f1b6871..66e6d96 100644 (file)
                margin-top: 0.3em;
        }
 
-       &-wrapper-content-title {
-               font-weight: bold;
-               color: #54595d;
+       &-wrapper-content {
+               &-title {
+                       font-weight: bold;
+                       color: #54595d;
+               }
+
+               &-savedQueryTitle {
+                       color: #72777d;
+                       margin-left: 1em;
+               }
        }
 
        &-emptyFilters {
diff --git a/resources/src/mediawiki.rcfilters/styles/mw.rcfilters.ui.SaveFiltersPopupButtonWidget.less b/resources/src/mediawiki.rcfilters/styles/mw.rcfilters.ui.SaveFiltersPopupButtonWidget.less
new file mode 100644 (file)
index 0000000..e19c246
--- /dev/null
@@ -0,0 +1,22 @@
+.mw-rcfilters-ui-saveFiltersPopupButtonWidget {
+       &-popup {
+               &-layout {
+                       padding-bottom: 1.5em;
+               }
+
+               > .oo-ui-popupWidget-popup > .oo-ui-popupWidget-head {
+                       > .oo-ui-iconWidget {
+                               margin: 0.75em 0.5em;
+                               float: left;
+                       }
+
+                       > .oo-ui-labelElement-label {
+                               font-size: 1.2em;
+                               padding: 0.3em;
+                               margin-left: 0;
+                               font-weight: bold;
+                       }
+               }
+       }
+
+}
diff --git a/resources/src/mediawiki.rcfilters/styles/mw.rcfilters.ui.SavedLinksListItemWidget.less b/resources/src/mediawiki.rcfilters/styles/mw.rcfilters.ui.SavedLinksListItemWidget.less
new file mode 100644 (file)
index 0000000..66ceb64
--- /dev/null
@@ -0,0 +1,52 @@
+.mw-rcfilters-ui-savedLinksListItemWidget {
+       padding: 0.5em;
+
+       &:hover {
+               // Mimicking optionWidget styles
+               background-color: #eaecf0;
+               color: #000;
+       }
+
+       .mw-rcfilters-ui-cell {
+               vertical-align: middle;
+       }
+
+       &:not( .oo-ui-iconElement ) .oo-ui-iconElement-icon {
+               // The iconElement-icon class still appears when we
+               // have an empty icon, and we need it to pretend to
+               // be there so the text has the same alignment as
+               // text next to a visible icon. #ThanksOOUI
+               width: 1.875em;
+               height: 1.875em;
+       }
+
+       &-icon span {
+               display: inline-block;
+       }
+
+       &-input {
+               display: inline-block;
+               margin-right: 0;
+               width: 15em;
+       }
+
+       &-label {
+               max-width: 15em;
+               display: inline-block;
+               vertical-align: middle;
+               text-overflow: ellipsis;
+               overflow: hidden;
+               cursor: pointer;
+               margin-left: 0.5px;
+       }
+
+       &-icon,
+       &-button {
+               width: 2em;
+       }
+
+       &-content {
+               width: 100%;
+       }
+
+}
diff --git a/resources/src/mediawiki.rcfilters/styles/mw.rcfilters.ui.SavedLinksListWidget.less b/resources/src/mediawiki.rcfilters/styles/mw.rcfilters.ui.SavedLinksListWidget.less
new file mode 100644 (file)
index 0000000..e1e55a7
--- /dev/null
@@ -0,0 +1,7 @@
+.mw-rcfilters-ui-savedLinksListWidget {
+       float: right;
+
+       &-menu {
+               width: 100%;
+       }
+}
index 957e9e9..c0f24c6 100644 (file)
        }
 }
 
+// Temporary icon classes, until these icons
+// are merged into OOUI properly
+.oo-ui-iconElement-icon.oo-ui-icon-clip {
+       /* @embed */
+       background-image: url( ../images/clip.svg );
+}
+
+.oo-ui-iconElement-icon.oo-ui-icon-unClip {
+       /* @embed */
+       background-image: url( ../images/unClip.svg );
+}
+
+.oo-ui-iconElement-icon.oo-ui-icon-pushPin {
+       /* @embed */
+       background-image: url( ../images/pushPin.svg );
+}
index c52ca1f..cbf8747 100644 (file)
@@ -8,10 +8,11 @@
         * @constructor
         * @param {mw.rcfilters.Controller} controller Controller
         * @param {mw.rcfilters.dm.FiltersViewModel} model View model
+        * @param {mw.rcfilters.dm.SavedQueriesModel} savedQueriesModel Saved queries model
         * @param {Object} config Configuration object
         * @cfg {jQuery} [$overlay] A jQuery object serving as overlay for popups
         */
-       mw.rcfilters.ui.FilterTagMultiselectWidget = function MwRcfiltersUiFilterTagMultiselectWidget( controller, model, config ) {
+       mw.rcfilters.ui.FilterTagMultiselectWidget = function MwRcfiltersUiFilterTagMultiselectWidget( controller, model, savedQueriesModel, config ) {
                var title = new OO.ui.LabelWidget( {
                                label: mw.msg( 'rcfilters-activefilters' ),
                                classes: [ 'mw-rcfilters-ui-filterTagMultiselectWidget-wrapper-content-title' ]
@@ -23,7 +24,9 @@
 
                this.controller = controller;
                this.model = model;
+               this.queriesModel = savedQueriesModel;
                this.$overlay = config.$overlay || this.$element;
+               this.matchingQuery = null;
 
                // Parent
                mw.rcfilters.ui.FilterTagMultiselectWidget.parent.call( this, $.extend( true, {
                        }
                }, config ) );
 
+               this.savedQueryTitle = new OO.ui.LabelWidget( {
+                       label: '',
+                       classes: [ 'mw-rcfilters-ui-filterTagMultiselectWidget-wrapper-content-savedQueryTitle' ]
+               } );
+
                this.resetButton = new OO.ui.ButtonWidget( {
                        framed: false,
                        classes: [ 'mw-rcfilters-ui-filterTagMultiselectWidget-resetButton' ]
                } );
 
+               this.saveQueryButton = new mw.rcfilters.ui.SaveFiltersPopupButtonWidget(
+                       this.controller,
+                       this.queriesModel
+               );
+
                this.emptyFilterMessage = new OO.ui.LabelWidget( {
                        label: mw.msg( 'rcfilters-empty-filter' ),
                        classes: [ 'mw-rcfilters-ui-filterTagMultiselectWidget-emptyFilters' ]
                // Stop propagation for mousedown, so that the widget doesn't
                // trigger the focus on the input and scrolls up when we click the reset button
                this.resetButton.$element.on( 'mousedown', function ( e ) { e.stopPropagation(); } );
+               this.saveQueryButton.$element.on( 'mousedown', function ( e ) { e.stopPropagation(); } );
                this.model.connect( this, {
                        initialize: 'onModelInitialize',
                        itemUpdate: 'onModelItemUpdate',
                        highlightChange: 'onModelHighlightChange'
                } );
+               this.saveQueryButton.connect( this, {
+                       click: 'onSaveQueryButtonClick',
+                       saveCurrent: 'setSavedQueryVisibility'
+               } );
+               this.queriesModel.connect( this, { itemUpdate: 'onSavedQueriesItemUpdate' } );
 
                // Build the content
                $contentWrapper.append(
                        title.$element,
+                       this.savedQueryTitle.$element,
                        $( '<div>' )
                                .addClass( 'mw-rcfilters-ui-table' )
                                .append(
                                                        this.$content
                                                                .addClass( 'mw-rcfilters-ui-cell' )
                                                                .addClass( 'mw-rcfilters-ui-filterTagMultiselectWidget-cell-filters' ),
+                                                       $( '<div>' )
+                                                               .addClass( 'mw-rcfilters-ui-cell' )
+                                                               .addClass( 'mw-rcfilters-ui-filterTagMultiselectWidget-cell-save' )
+                                                               .append( this.saveQueryButton.$element ),
                                                        $( '<div>' )
                                                                .addClass( 'mw-rcfilters-ui-cell' )
                                                                .addClass( 'mw-rcfilters-ui-filterTagMultiselectWidget-cell-reset' )
                // Initialize
                this.$handle.append( $contentWrapper );
                this.emptyFilterMessage.toggle( this.isEmpty() );
+               this.savedQueryTitle.toggle( false );
 
                this.$element
                        .addClass( 'mw-rcfilters-ui-filterTagMultiselectWidget' );
 
        /* Methods */
 
+       /**
+        * Respond to query button click
+        */
+       mw.rcfilters.ui.FilterTagMultiselectWidget.prototype.onSaveQueryButtonClick = function () {
+               this.getMenu().toggle( false );
+       };
+
+       /**
+        * Respond to save query item change. Mainly this is done to update the label in case
+        * a query item has been edited
+        *
+        * @param {mw.rcfilters.dm.SavedQueryItemModel} item Saved query item
+        */
+       mw.rcfilters.ui.FilterTagMultiselectWidget.prototype.onSavedQueriesItemUpdate = function ( item ) {
+               if ( this.matchingQuery === item ) {
+                       // This means we just edited the item that is currently matched
+                       this.savedQueryTitle.setLabel( item.getLabel() );
+               }
+       };
+
        /**
         * Respond to menu toggle
         *
         */
        mw.rcfilters.ui.FilterTagMultiselectWidget.prototype.onModelInitialize = function () {
                this.populateFromModel();
+
+               this.setSavedQueryVisibility();
        };
 
+       /**
+        * Set the visibility of the saved query button
+        */
+       mw.rcfilters.ui.FilterTagMultiselectWidget.prototype.setSavedQueryVisibility = function () {
+               this.matchingQuery = this.controller.findQueryMatchingCurrentState();
+
+               this.savedQueryTitle.setLabel(
+                       this.matchingQuery ? this.matchingQuery.getLabel() : ''
+               );
+               this.savedQueryTitle.toggle( !!this.matchingQuery );
+               this.saveQueryButton.toggle(
+                       !this.isEmpty() &&
+                       !this.matchingQuery
+               );
+       };
        /**
         * Respond to model itemUpdate event
         *
                        this.removeTagByData( item.getName() );
                }
 
+               this.setSavedQueryVisibility();
+
                // Re-evaluate reset state
                this.reevaluateResetRestoreState();
        };
index b7ebf34..738a981 100644 (file)
@@ -8,11 +8,12 @@
         * @constructor
         * @param {mw.rcfilters.Controller} controller Controller
         * @param {mw.rcfilters.dm.FiltersViewModel} model View model
+        * @param {mw.rcfilters.dm.SavedQueriesModel} savedQueriesModel Saved queries model
         * @param {Object} [config] Configuration object
         * @cfg {Object} [filters] A definition of the filter groups in this list
         * @cfg {jQuery} [$overlay] A jQuery object serving as overlay for popups
         */
-       mw.rcfilters.ui.FilterWrapperWidget = function MwRcfiltersUiFilterWrapperWidget( controller, model, config ) {
+       mw.rcfilters.ui.FilterWrapperWidget = function MwRcfiltersUiFilterWrapperWidget( controller, model, savedQueriesModel, config ) {
                config = config || {};
 
                // Parent
 
                this.controller = controller;
                this.model = model;
+               this.queriesModel = savedQueriesModel;
                this.$overlay = config.$overlay || this.$element;
 
                this.filterTagWidget = new mw.rcfilters.ui.FilterTagMultiselectWidget(
                        this.controller,
                        this.model,
+                       this.queriesModel,
+                       { $overlay: this.$overlay }
+               );
+
+               this.savedLinksListWidget = new mw.rcfilters.ui.SavedLinksListWidget(
+                       this.controller,
+                       this.queriesModel,
                        { $overlay: this.$overlay }
                );
 
                // Initialize
                this.$element
                        .addClass( 'mw-rcfilters-ui-filterWrapperWidget' )
-                       .append( this.filterTagWidget.$element );
+                       .append(
+                               this.savedLinksListWidget.$element,
+                               this.filterTagWidget.$element
+                       );
        };
 
        /* Initialization */
diff --git a/resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.SaveFiltersPopupButtonWidget.js b/resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.SaveFiltersPopupButtonWidget.js
new file mode 100644 (file)
index 0000000..9b7a2fb
--- /dev/null
@@ -0,0 +1,159 @@
+( function ( mw ) {
+       /**
+        * Save filters widget. This widget is displayed in the tag area
+        * and allows the user to save the current state of the system
+        * as a new saved filter query they can later load or set as
+        * default.
+        *
+        * @extends OO.ui.PopupButtonWidget
+        *
+        * @constructor
+        * @param {mw.rcfilters.Controller} controller Controller
+        * @param {mw.rcfilters.dm.SavedQueriesModel} model View model
+        * @param {Object} [config] Configuration object
+        */
+       mw.rcfilters.ui.SaveFiltersPopupButtonWidget = function MwRcfiltersUiSaveFiltersPopupButtonWidget( controller, model, config ) {
+               var layout,
+                       $popupContent = $( '<div>' );
+
+               config = config || {};
+
+               this.controller = controller;
+               this.model = model;
+
+               // Parent
+               mw.rcfilters.ui.SaveFiltersPopupButtonWidget.parent.call( this, $.extend( {
+                       framed: false,
+                       icon: 'clip',
+                       $overlay: this.$overlay,
+                       title: mw.msg( 'rcfilters-savedqueries-add-new-title' ),
+                       popup: {
+                               classes: [ 'mw-rcfilters-ui-saveFiltersPopupButtonWidget-popup' ],
+                               padded: true,
+                               head: true,
+                               label: mw.msg( 'rcfilters-savedqueries-add-new-title' ),
+                               $content: $popupContent
+                       }
+               }, config ) );
+               // // HACK: Add an icon to the popup head label
+               this.popup.$head.prepend( ( new OO.ui.IconWidget( { icon: 'clip' } ) ).$element );
+
+               this.input = new OO.ui.TextInputWidget( {
+                       validate: 'non-empty'
+               } );
+               layout = new OO.ui.FieldLayout( this.input, {
+                       label: mw.msg( 'rcfilters-savedqueries-new-name-label' ),
+                       align: 'top'
+               } );
+
+               this.applyButton = new OO.ui.ButtonWidget( {
+                       label: mw.msg( 'rcfilters-savedqueries-apply-label' ),
+                       classes: [ 'mw-rcfilters-ui-saveFiltersPopupButtonWidget-popup-buttons-apply' ],
+                       flags: [ 'primary', 'progressive' ]
+               } );
+               this.cancelButton = new OO.ui.ButtonWidget( {
+                       label: mw.msg( 'rcfilters-savedqueries-cancel-label' ),
+                       classes: [ 'mw-rcfilters-ui-saveFiltersPopupButtonWidget-popup-buttons-cancel' ]
+               } );
+
+               $popupContent
+                       .append(
+                               $( '<div>' )
+                                       .addClass( 'mw-rcfilters-ui-saveFiltersPopupButtonWidget-popup-layout' )
+                                       .append( layout.$element ),
+                               $( '<div>' )
+                                       .addClass( 'mw-rcfilters-ui-saveFiltersPopupButtonWidget-popup-buttons' )
+                                       .append(
+                                               this.cancelButton.$element,
+                                               this.applyButton.$element
+                                       )
+                       );
+
+               // Events
+               this.popup.connect( this, {
+                       ready: 'onPopupReady',
+                       toggle: 'onPopupToggle'
+               } );
+               this.input.connect( this, { enter: 'onInputEnter' } );
+               this.input.$input.on( {
+                       keyup: this.onInputKeyup.bind( this )
+               } );
+               this.cancelButton.connect( this, { click: 'onCancelButtonClick' } );
+               this.applyButton.connect( this, { click: 'onApplyButtonClick' } );
+
+               // Initialize
+               this.$element
+                       .addClass( 'mw-rcfilters-ui-saveFiltersPopupButtonWidget' );
+       };
+
+       /* Initialization */
+       OO.inheritClass( mw.rcfilters.ui.SaveFiltersPopupButtonWidget, OO.ui.PopupButtonWidget );
+
+       /**
+        * Respond to input enter event
+        */
+       mw.rcfilters.ui.SaveFiltersPopupButtonWidget.prototype.onInputEnter = function () {
+               this.apply();
+       };
+
+       /**
+        * Respond to input keyup event, this is the way to intercept 'escape' key
+        *
+        * @param {jQuery.Event} e Event data
+        * @returns {boolean} false
+        */
+       mw.rcfilters.ui.SaveFiltersPopupButtonWidget.prototype.onInputKeyup = function ( e ) {
+               if ( e.which === OO.ui.Keys.ESCAPE ) {
+                       this.popup.toggle( false );
+                       return false;
+               }
+       };
+
+       /**
+        * Respond to popup toggle event
+        *
+        * @param {boolean} isVisible Popup is visible
+        */
+       mw.rcfilters.ui.SaveFiltersPopupButtonWidget.prototype.onPopupToggle = function ( isVisible ) {
+               this.setIcon( isVisible ? 'unClip' : 'clip' );
+       };
+
+       /**
+        * Respond to popup ready event
+        */
+       mw.rcfilters.ui.SaveFiltersPopupButtonWidget.prototype.onPopupReady = function () {
+               this.input.focus();
+       };
+
+       /**
+        * Respond to cancel button click event
+        */
+       mw.rcfilters.ui.SaveFiltersPopupButtonWidget.prototype.onCancelButtonClick = function () {
+               this.popup.toggle( false );
+       };
+
+       /**
+        * Respond to apply button click event
+        */
+       mw.rcfilters.ui.SaveFiltersPopupButtonWidget.prototype.onApplyButtonClick = function () {
+               this.apply();
+       };
+
+       /**
+        * Apply and add the new quick link
+        */
+       mw.rcfilters.ui.SaveFiltersPopupButtonWidget.prototype.apply = function () {
+               var widget = this,
+                       label = this.input.getValue();
+
+               this.input.getValidity()
+                       .done( function () {
+                               widget.controller.saveCurrentQuery( label );
+                               widget.input.setValue( this.input, '' );
+                               widget.emit( 'saveCurrent' );
+                       } )
+                       .always( function () {
+                               widget.popup.toggle( false );
+                       } );
+       };
+}( mediaWiki ) );
diff --git a/resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.SavedLinksListItemWidget.js b/resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.SavedLinksListItemWidget.js
new file mode 100644 (file)
index 0000000..51b348e
--- /dev/null
@@ -0,0 +1,293 @@
+( function ( mw ) {
+       /**
+        * Quick links menu option widget
+        *
+        * @extends OO.ui.Widget
+        * @mixins OO.ui.mixin.LabelElement
+        * @mixins OO.ui.mixin.IconElement
+        *
+        * @constructor
+        * @param {mw.rcfilters.dm.SavedQueryItemModel} model View model
+        * @param {Object} [config] Configuration object
+        * @cfg {jQuery} [$overlay] A jQuery object serving as overlay for popups
+        */
+       mw.rcfilters.ui.SavedLinksListItemWidget = function MwRcfiltersUiSavedLinksListWidget( model, config ) {
+               config = config || {};
+
+               this.model = model;
+
+               // Parent
+               mw.rcfilters.ui.SavedLinksListItemWidget.parent.call( this, $.extend( {
+                       data: this.model.getID()
+               }, config ) );
+
+               // Mixin constructors
+               OO.ui.mixin.LabelElement.call( this, $.extend( {
+                       label: this.model.getLabel()
+               }, config ) );
+               OO.ui.mixin.IconElement.call( this, $.extend( {
+                       icon: ''
+               }, config ) );
+
+               this.edit = false;
+               this.$overlay = config.$overlay || this.$element;
+
+               this.popupButton = new OO.ui.ButtonWidget( {
+                       classes: [ 'mw-rcfilters-ui-savedLinksListItemWidget-button' ],
+                       icon: 'ellipsis',
+                       framed: false
+               } );
+               this.menu = new OO.ui.FloatingMenuSelectWidget( {
+                       classes: [ 'mw-rcfilters-ui-savedLinksListItemWidget-menu' ],
+                       widget: this.popupButton,
+                       width: 200,
+                       horizontalPosition: 'end',
+                       $container: this.popupButton.$element,
+                       items: [
+                               new OO.ui.MenuOptionWidget( {
+                                       data: 'edit',
+                                       icon: 'edit',
+                                       label: mw.msg( 'rcfilters-savedqueries-rename' )
+                               } ),
+                               new OO.ui.MenuOptionWidget( {
+                                       data: 'delete',
+                                       icon: 'close',
+                                       label: mw.msg( 'rcfilters-savedqueries-remove' )
+                               } ),
+                               new OO.ui.MenuOptionWidget( {
+                                       data: 'default',
+                                       icon: 'pushPin',
+                                       label: mw.msg( 'rcfilters-savedqueries-setdefault' )
+                               } )
+                       ]
+               } );
+
+               this.editInput = new OO.ui.TextInputWidget( {
+                       classes: [ 'mw-rcfilters-ui-savedLinksListItemWidget-input' ]
+               } );
+               this.saveButton = new OO.ui.ButtonWidget( {
+                       icon: 'check',
+                       flags: [ 'primary', 'progressive' ]
+               } );
+               this.toggleEdit( false );
+
+               // Events
+               this.model.connect( this, { update: 'onModelUpdate' } );
+               this.popupButton.connect( this, { click: 'onPopupButtonClick' } );
+               this.menu.connect( this, {
+                       choose: 'onMenuChoose'
+               } );
+               this.saveButton.connect( this, { click: 'onSaveButtonClick' } );
+               this.editInput.connect( this, { enter: 'onEditInputEnter' } );
+               this.editInput.$input.on( {
+                       blur: this.onInputBlur.bind( this ),
+                       keyup: this.onInputKeyup.bind( this )
+               } );
+               this.$element.on( { click: this.onClick.bind( this ) } );
+               this.$label.on( { click: this.onClick.bind( this ) } );
+               // Prevent propagation on mousedown for the save button
+               // so the menu doesn't close
+               this.saveButton.$element.on( { mousedown: function () { return false; } } );
+
+               // Initialize
+               this.toggleDefault( !!this.model.isDefault() );
+               this.$overlay.append( this.menu.$element );
+               this.$element
+                       .addClass( 'mw-rcfilters-ui-savedLinksListItemWidget' )
+                       .addClass( 'mw-rcfilters-ui-savedLinksListItemWidget-query-' + this.model.getID() )
+                       .append(
+                               $( '<div>' )
+                                       .addClass( 'mw-rcfilters-ui-table' )
+                                       .append(
+                                               $( '<div>' )
+                                                       .addClass( 'mw-rcfilters-ui-row' )
+                                                       .append(
+                                                               $( '<div>' )
+                                                                       .addClass( 'mw-rcfilters-ui-cell' )
+                                                                       .addClass( 'mw-rcfilters-ui-savedLinksListItemWidget-icon' )
+                                                                       .append( this.$icon ),
+                                                               $( '<div>' )
+                                                                       .addClass( 'mw-rcfilters-ui-cell' )
+                                                                       .addClass( 'mw-rcfilters-ui-savedLinksListItemWidget-content' )
+                                                                       .append(
+                                                                               this.$label
+                                                                                       .addClass( 'mw-rcfilters-ui-savedLinksListItemWidget-label' ),
+                                                                               this.editInput.$element,
+                                                                               this.saveButton.$element
+                                                                       ),
+                                                               this.popupButton.$element
+                                                                       .addClass( 'mw-rcfilters-ui-cell' )
+                                                       )
+                                       )
+                       );
+       };
+
+       /* Initialization */
+       OO.inheritClass( mw.rcfilters.ui.SavedLinksListItemWidget, OO.ui.Widget );
+       OO.mixinClass( mw.rcfilters.ui.SavedLinksListItemWidget, OO.ui.mixin.LabelElement );
+       OO.mixinClass( mw.rcfilters.ui.SavedLinksListItemWidget, OO.ui.mixin.IconElement );
+
+       /* Events */
+
+       /**
+        * @event delete
+        *
+        * The delete option was selected for this item
+        */
+
+       /**
+        * @event default
+        * @param {boolean} default Item is default
+        *
+        * The 'make default' option was selected for this item
+        */
+
+       /**
+        * @event edit
+        * @param {string} newLabel New label for the query
+        *
+        * The label has been edited
+        */
+
+       /* Methods */
+
+       /**
+        * Respond to model update event
+        */
+       mw.rcfilters.ui.SavedLinksListItemWidget.prototype.onModelUpdate = function () {
+               this.setLabel( this.model.getLabel() );
+               this.toggleDefault( this.model.isDefault() );
+       };
+
+       /**
+        * Respond to click on the element or label
+        *
+        * @fires click
+        */
+       mw.rcfilters.ui.SavedLinksListItemWidget.prototype.onClick = function () {
+               if ( !this.editing ) {
+                       this.emit( 'click' );
+               }
+       };
+       /**
+        * Respond to popup button click event
+        */
+       mw.rcfilters.ui.SavedLinksListItemWidget.prototype.onPopupButtonClick = function () {
+               this.menu.toggle();
+       };
+
+       /**
+        * Respond to menu choose event
+        *
+        * @param {OO.ui.MenuOptionWidget} item Chosen item
+        * @fires delete
+        * @fires default
+        */
+       mw.rcfilters.ui.SavedLinksListItemWidget.prototype.onMenuChoose = function ( item ) {
+               var action = item.getData();
+
+               if ( action === 'edit' ) {
+                       this.toggleEdit( true );
+               } else if ( action === 'delete' ) {
+                       this.emit( 'delete' );
+               } else if ( action === 'default' ) {
+                       this.emit( 'default', !this.default );
+               }
+               // Reset selected
+               this.menu.selectItem( null );
+               // Close the menu
+               this.menu.toggle( false );
+       };
+
+       /**
+        * Respond to save button click
+        */
+       mw.rcfilters.ui.SavedLinksListItemWidget.prototype.onSaveButtonClick = function () {
+               this.emit( 'edit', this.editInput.getValue() );
+               this.toggleEdit( false );
+       };
+
+       /**
+        * Respond to input enter event
+        */
+       mw.rcfilters.ui.SavedLinksListItemWidget.prototype.onEditInputEnter = function () {
+               this.emit( 'edit', this.editInput.getValue() );
+               this.toggleEdit( false );
+       };
+
+       /**
+        * Respond to input keyup event, this is the way to intercept 'escape' key
+        *
+        * @param {jQuery.Event} e Event data
+        * @returns {boolean} false
+        */
+       mw.rcfilters.ui.SavedLinksListItemWidget.prototype.onInputKeyup = function ( e ) {
+               if ( e.which === OO.ui.Keys.ESCAPE ) {
+                       // Return the input to the original label
+                       this.editInput.setValue( this.getLabel() );
+                       this.toggleEdit( false );
+                       return false;
+               }
+       };
+
+       /**
+        * Respond to blur event on the input
+        */
+       mw.rcfilters.ui.SavedLinksListItemWidget.prototype.onInputBlur = function () {
+               this.emit( 'edit', this.editInput.getValue() );
+               this.toggleEdit( false );
+       };
+
+       /**
+        * Toggle edit mode on this widget
+        *
+        * @param {boolean} isEdit Widget is in edit mode
+        */
+       mw.rcfilters.ui.SavedLinksListItemWidget.prototype.toggleEdit = function ( isEdit ) {
+               isEdit = isEdit === undefined ? !this.editing : isEdit;
+
+               if ( this.editing !== isEdit ) {
+                       this.$element.toggleClass( 'mw-rcfilters-ui-savedLinksListItemWidget-edit', isEdit );
+                       this.editInput.setValue( this.getLabel() );
+
+                       this.editInput.toggle( isEdit );
+                       this.$label.toggleClass( 'oo-ui-element-hidden', isEdit );
+                       this.popupButton.toggle( !isEdit );
+                       this.saveButton.toggle( isEdit );
+
+                       if ( isEdit ) {
+                               this.editInput.$input.focus();
+                       }
+                       this.editing = isEdit;
+               }
+       };
+
+       /**
+        * Toggle default this widget
+        *
+        * @param {boolean} isDefault This item is default
+        */
+       mw.rcfilters.ui.SavedLinksListItemWidget.prototype.toggleDefault = function ( isDefault ) {
+               isDefault = isDefault === undefined ? !this.default : isDefault;
+
+               if ( this.default !== isDefault ) {
+                       this.default = isDefault;
+                       this.setIcon( this.default ? 'pushPin' : '' );
+                       this.menu.getItemFromData( 'default' ).setLabel(
+                               this.default ?
+                                       mw.msg( 'rcfilters-savedqueries-unsetdefault' ) :
+                                       mw.msg( 'rcfilters-savedqueries-setdefault' )
+                       );
+               }
+       };
+
+       /**
+        * Get item ID
+        *
+        * @returns {string} Query identifier
+        */
+       mw.rcfilters.ui.SavedLinksListItemWidget.prototype.getID = function () {
+               return this.model.getID();
+       };
+
+}( mediaWiki ) );
diff --git a/resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.SavedLinksListWidget.js b/resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.SavedLinksListWidget.js
new file mode 100644 (file)
index 0000000..9ae1d34
--- /dev/null
@@ -0,0 +1,137 @@
+( function ( mw ) {
+       /**
+        * Quick links widget
+        *
+        * @extends OO.ui.Widget
+        *
+        * @constructor
+        * @param {mw.rcfilters.Controller} controller Controller
+        * @param {mw.rcfilters.dm.SavedQueriesModel} model View model
+        * @param {Object} [config] Configuration object
+        * @cfg {jQuery} [$overlay] A jQuery object serving as overlay for popups
+        */
+       mw.rcfilters.ui.SavedLinksListWidget = function MwRcfiltersUiSavedLinksListWidget( controller, model, config ) {
+               config = config || {};
+
+               // Parent
+               mw.rcfilters.ui.SavedLinksListWidget.parent.call( this, config );
+
+               this.controller = controller;
+               this.model = model;
+               this.$overlay = config.$overlay || this.$element;
+
+               // The only reason we're using "ButtonGroupWidget" here is that
+               // straight-out "GroupWidget" is a mixin and cannot be initialized
+               // on its own, so we need something to be its widget.
+               this.menu = new OO.ui.ButtonGroupWidget( {
+                       classes: [ 'mw-rcfilters-ui-savedLinksListWidget-menu' ]
+               } );
+               this.button = new OO.ui.PopupButtonWidget( {
+                       classes: [ 'mw-rcfilters-ui-savedLinksListWidget-button' ],
+                       label: mw.msg( 'rcfilters-quickfilters' ),
+                       icon: 'unClip',
+                       $overlay: this.$overlay,
+                       popup: {
+                               width: 300,
+                               anchor: false,
+                               align: 'forwards',
+                               $autoCloseIgnore: this.$overlay,
+                               $content: this.menu.$element
+                       }
+               } );
+
+               this.menu.aggregate( {
+                       click: 'menuItemClick',
+                       'delete': 'menuItemDelete',
+                       'default': 'menuItemDefault',
+                       edit: 'menuItemEdit'
+               } );
+
+               // Events
+               this.model.connect( this, {
+                       add: 'onModelAddItem',
+                       remove: 'onModelRemoveItem'
+               } );
+               this.menu.connect( this, {
+                       menuItemClick: 'onMenuItemClick',
+                       menuItemDelete: 'onMenuItemRemove',
+                       menuItemDefault: 'onMenuItemDefault',
+                       menuItemEdit: 'onMenuItemEdit'
+               } );
+
+               this.button.toggle( !this.menu.isEmpty() );
+               // Initialize
+               this.$element
+                       .addClass( 'mw-rcfilters-ui-savedLinksListWidget' )
+                       .append( this.button.$element );
+       };
+
+       /* Initialization */
+       OO.inheritClass( mw.rcfilters.ui.SavedLinksListWidget, OO.ui.Widget );
+
+       /**
+        * Respond to menu item click event
+        *
+        * @param {mw.rcfilters.ui.SavedLinksListItemWidget} item Menu item
+        */
+       mw.rcfilters.ui.SavedLinksListWidget.prototype.onMenuItemClick = function ( item ) {
+               this.controller.applySavedQuery( item.getID() );
+               this.button.popup.toggle( false );
+       };
+
+       /**
+        * Respond to menu item remove event
+        *
+        * @param {mw.rcfilters.ui.SavedLinksListItemWidget} item Menu item
+        */
+       mw.rcfilters.ui.SavedLinksListWidget.prototype.onMenuItemRemove = function ( item ) {
+               this.controller.removeSavedQuery( item.getID() );
+               this.menu.removeItems( [ item ] );
+       };
+
+       /**
+        * Respond to menu item default event
+        *
+        * @param {mw.rcfilters.ui.SavedLinksListItemWidget} item Menu item
+        * @param {boolean} isDefault Item is default
+        */
+       mw.rcfilters.ui.SavedLinksListWidget.prototype.onMenuItemDefault = function ( item, isDefault ) {
+               this.controller.setDefaultSavedQuery( isDefault ? item.getID() : null );
+       };
+
+       /**
+        * Respond to menu item edit event
+        *
+        * @param {mw.rcfilters.ui.SavedLinksListItemWidget} item Menu item
+        * @param {string} newLabel New label
+        */
+       mw.rcfilters.ui.SavedLinksListWidget.prototype.onMenuItemEdit = function ( item, newLabel ) {
+               this.controller.renameSavedQuery( item.getID(), newLabel );
+       };
+
+       /**
+        * Respond to menu add item event
+        *
+        * @param {mw.rcfilters.ui.SavedLinksListItemWidget} item Menu item
+        */
+       mw.rcfilters.ui.SavedLinksListWidget.prototype.onModelAddItem = function ( item ) {
+               if ( this.menu.getItemFromData( item.getID() ) ) {
+                       return;
+               }
+
+               this.menu.addItems( [
+                       new mw.rcfilters.ui.SavedLinksListItemWidget( item, { $overlay: this.$overlay } )
+               ] );
+               this.button.toggle( !this.menu.isEmpty() );
+       };
+
+       /**
+        * Respond to menu remove item event
+        *
+        * @param {mw.rcfilters.ui.SavedLinksListItemWidget} item Menu item
+        */
+       mw.rcfilters.ui.SavedLinksListWidget.prototype.onModelRemoveItem = function ( item ) {
+               this.menu.removeItems( [ this.model.getItemByID( item.getID() ) ] );
+               this.button.toggle( !this.menu.isEmpty() );
+       };
+}( mediaWiki ) );
diff --git a/resources/src/mediawiki.special/images/special.search/book-icon.png b/resources/src/mediawiki.special/images/special.search/book-icon.png
deleted file mode 100644 (file)
index 07e3ec7..0000000
Binary files a/resources/src/mediawiki.special/images/special.search/book-icon.png and /dev/null differ
diff --git a/resources/src/mediawiki.special/images/special.search/book-icon.svg b/resources/src/mediawiki.special/images/special.search/book-icon.svg
deleted file mode 100644 (file)
index 6c3fa5f..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<svg width="60px" height="60px" viewBox="0 0 60 60" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
-    <!-- Generator: Sketch 41.2 (35397) - http://www.bohemiancoding.com/sketch -->
-    <title>wikisource-icon</title>
-    <desc>Created with Sketch.</desc>
-    <defs>
-        <path d="M25.9612634,4.16259168 C25.9612634,3.05318514 26.8209364,1.88015355 27.8804771,1.5831456 C27.8804771,1.5831456 45.019739,-4.60039908 52.9189989,7.7430239 C52.8276879,7.87091176 53.3244937,43.6894771 53.0961715,43.801598 C38.1346526,39.2213878 27.8617804,43.2196252 27.8617804,43.2196252 C26.8121538,43.5410399 25.9612634,42.9124575 25.9612634,41.7928397 L25.9612634,4.16259168 Z" id="path-1"></path>
-        <mask id="mask-2" maskContentUnits="userSpaceOnUse" maskUnits="objectBoundingBox" x="0" y="0" width="27.195528" height="43.7625003" fill="white">
-            <use xlink:href="#path-1"></use>
-        </mask>
-        <path d="M1.08483248,4.15020908 C1.08483248,3.04080253 1.94450542,1.86777094 3.00404616,1.57076299 C3.00404616,1.57076299 20.1433081,-4.61278168 28.0425679,7.73064129 C27.951257,7.85852916 28.4480627,43.6770945 28.2197406,43.7892154 C13.2582217,39.2090052 2.98534945,43.2072426 2.98534945,43.2072426 C1.93572291,43.5286573 1.08483248,42.9000749 1.08483248,41.7804571 L1.08483248,4.15020908 Z" id="path-3"></path>
-        <mask id="mask-4" maskContentUnits="userSpaceOnUse" maskUnits="objectBoundingBox" x="0" y="0" width="27.195528" height="43.7625003" fill="white">
-            <use xlink:href="#path-3"></use>
-        </mask>
-    </defs>
-    <g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
-        <g id="wikisource">
-            <g id="Group-2" transform="translate(3.000000, 7.000000)">
-                <g id="Group">
-                    <rect id="Rectangle-3" fill="#000000" x="19.5269846" y="36.730429" width="15.1876547" height="9.47882039" rx="4.7394102"></rect>
-                    <rect id="Rectangle" fill="#000000" x="0" y="8.29396785" width="55.3264563" height="35.5455765" rx="2"></rect>
-                    <use id="Rectangle-2" stroke="#000000" mask="url(#mask-2)" stroke-width="4" fill="#FFFFFF" transform="translate(39.559027, 21.920348) scale(-1, 1) translate(-39.559027, -21.920348) " xlink:href="#path-1"></use>
-                    <use id="Rectangle-2" stroke="#000000" mask="url(#mask-4)" stroke-width="4" fill="#FFFFFF" xlink:href="#path-3"></use>
-                </g>
-                <path d="M5.94322419,22.653192 C15.2672322,19.3261075 22.9765332,23.990418 22.9765332,23.990418" id="Line" stroke="#000000" stroke-width="2" stroke-linecap="round"></path>
-                <path d="M5.94322419,16.7331266 C15.2672322,13.4060421 22.9765332,18.0703525 22.9765332,18.0703525" id="Line" stroke="#000000" stroke-width="2" stroke-linecap="round"></path>
-                <path d="M5.94322419,11.0846878 C15.2672322,7.75760327 22.9765332,12.4219137 22.9765332,12.4219137" id="Line" stroke="#000000" stroke-width="2" stroke-linecap="round"></path>
-                <path d="M5.94322419,28.5732575 C15.2672322,25.246173 22.9765332,29.9104834 22.9765332,29.9104834" id="Line" stroke="#000000" stroke-width="2" stroke-linecap="round"></path>
-                <path d="M5.94322419,34.4933229 C15.2672322,31.1662384 22.9765332,35.8305489 22.9765332,35.8305489" id="Line" stroke="#000000" stroke-width="2" stroke-linecap="round"></path>
-                <path d="M31.8963536,26.2991517 C41.2203616,22.7867165 48.9296626,27.2977748 48.9296626,27.2977748" id="Line" stroke="#000000" stroke-width="2" stroke-linecap="round"></path>
-                <path d="M31.8963536,32.2192172 C41.2203616,28.7067819 48.9296626,33.2178402 48.9296626,33.2178402" id="Line" stroke="#000000" stroke-width="2" stroke-linecap="round"></path>
-                <path d="M32.1957977,11.8254134 C32.1957977,11.8254134 34.7092977,10.1127027 40.1604435,10.1337008 C45.6115894,10.1546989 47.8024685,11.8254134 47.8024685,11.8254134 L47.8024685,21.3219156 C47.8024685,21.3219156 43.8085467,20.1940894 39.931856,20.1940894 C36.0551653,20.1940894 32.1957977,21.3219156 32.1957977,21.3219156 L32.1957977,11.8254134 Z" id="Rectangle-4" fill="#000000"></path>
-            </g>
-        </g>
-    </g>
-</svg>
\ No newline at end of file
diff --git a/resources/src/mediawiki.special/images/special.search/course-icon.png b/resources/src/mediawiki.special/images/special.search/course-icon.png
deleted file mode 100644 (file)
index 9aad230..0000000
Binary files a/resources/src/mediawiki.special/images/special.search/course-icon.png and /dev/null differ
diff --git a/resources/src/mediawiki.special/images/special.search/course-icon.svg b/resources/src/mediawiki.special/images/special.search/course-icon.svg
deleted file mode 100644 (file)
index 4fab1f3..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<svg width="60px" height="60px" viewBox="0 0 60 60" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
-    <!-- Generator: Sketch 41.2 (35397) - http://www.bohemiancoding.com/sketch -->
-    <title>wikiversity-icon</title>
-    <desc>Created with Sketch.</desc>
-    <defs>
-        <path d="M1.79361627,13.3306367 C-0.140465792,12.4757391 -0.144839204,11.0916093 1.78234628,10.2397601 L23.5026391,0.639016247 C25.4304969,-0.213130142 28.5529839,-0.214539335 30.4952998,0.64399778 L52.8863837,10.5412429 C54.8204658,11.3961405 54.8248392,12.7802702 52.8976537,13.6321195 L31.1773609,23.2328633 C29.2495031,24.0850097 26.1270161,24.0864189 24.1847002,23.2278818 L1.79361627,13.3306367 Z" id="path-1"></path>
-        <mask id="mask-2" maskContentUnits="userSpaceOnUse" maskUnits="objectBoundingBox" x="-5" y="-5" width="64" height="33.8718796">
-            <rect x="-4.66" y="-5" width="64" height="33.8718796" fill="white"></rect>
-            <use xlink:href="#path-1" fill="black"></use>
-        </mask>
-        <circle id="path-3" cx="7" cy="27" r="5"></circle>
-        <mask id="mask-4" maskContentUnits="userSpaceOnUse" maskUnits="objectBoundingBox" x="-3" y="-3" width="16" height="16">
-            <rect x="-1" y="19" width="16" height="16" fill="white"></rect>
-            <use xlink:href="#path-3" fill="black"></use>
-        </mask>
-    </defs>
-    <g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
-        <g id="wikiversity">
-            <g id="Group-2" transform="translate(3.000000, 11.000000)">
-                <path d="M8,16 L47,16 L47,31.89585 C47,31.89585 42.2783874,38.5113751 27.5,38.8710875 C12.7216126,39.2307999 8,31.89585 8,31.89585 L8,22.2392885 L8,16 Z" id="Rectangle-3" fill="#000000"></path>
-                <g id="Rectangle">
-                    <use fill="#000000" fill-rule="evenodd" xlink:href="#path-1"></use>
-                    <use stroke="#F2F4F7" mask="url(#mask-2)" stroke-width="10" xlink:href="#path-1"></use>
-                </g>
-                <path d="M6.1310053,41.2112479 C5.27479784,42.0096083 10.4373919,43.6053602 11.2296387,43.6053602 C13.2555121,37.7460829 11.8321108,35.5517452 11.8321108,29.1181019 L11.8321108,21.2930015 C11.8321108,21.2930015 16.5515035,18.1566713 21.2216931,16.0206053 C25.8918828,13.8845392 31.215528,12.2538646 31.3550046,12.2096604 C32.1176432,11.9679575 31.2752162,9.09848389 30.5125776,9.34018676 C30.3644648,9.38712813 27.3667572,9.04545881 26.6057472,9.30621378 C24.4302064,10.0516482 11.7945726,16.3687146 9.43776817,19.1164347 C7.08096377,21.8641549 8.67910884,38.8352994 6.1310053,41.2112479 Z" id="Path-3" fill="#F2F4F7"></path>
-                <g id="Oval-3">
-                    <use fill="#000000" fill-rule="evenodd" xlink:href="#path-3"></use>
-                    <use stroke="#F2F4F7" mask="url(#mask-4)" stroke-width="6" xlink:href="#path-3"></use>
-                </g>
-                <path d="M1.13550659,38.2112479 C0.245905063,39.0096083 7.57084983,40.6053602 8.39399608,40.6053602 C9.78724127,36.7270479 9.71041095,34.4853149 9.49920479,31.5470605 C9.43416647,30.6422615 9.35638589,29.6714145 9.30486594,28.5663921 C9.27092907,27.8384991 9.24838677,27.052387 9.24838677,26.1885838 C9.24838677,21.7929074 8.92187195,20.3988432 10.0589683,18.8611032 C10.5891389,18.1441327 14.9624282,15.1566713 19.814766,13.0206053 C24.6671038,10.8845392 30.1983835,9.25386462 30.3432999,9.20966036 C31.1356832,8.96795749 30.2603996,6.09848389 29.4680164,6.34018676 C29.3141268,6.38712813 27.238504,7.04545881 26.4478128,7.30621378 C24.187421,8.05164822 9.84272127,11.7529088 7.39399608,14.500629 C4.94527088,17.2483492 3.78299204,35.8352994 1.13550659,38.2112479 Z" id="Path-3" fill="#000000"></path>
-            </g>
-        </g>
-    </g>
-</svg>
\ No newline at end of file
diff --git a/resources/src/mediawiki.special/images/special.search/definition-icon.png b/resources/src/mediawiki.special/images/special.search/definition-icon.png
deleted file mode 100644 (file)
index b279f4e..0000000
Binary files a/resources/src/mediawiki.special/images/special.search/definition-icon.png and /dev/null differ
diff --git a/resources/src/mediawiki.special/images/special.search/definition-icon.svg b/resources/src/mediawiki.special/images/special.search/definition-icon.svg
deleted file mode 100644 (file)
index 1d58906..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<svg width="60px" height="60px" viewBox="0 0 60 60" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
-    <!-- Generator: Sketch 41.2 (35397) - http://www.bohemiancoding.com/sketch -->
-    <title>wiktionary-icon</title>
-    <desc>Created with Sketch.</desc>
-    <defs>
-        <rect id="path-1" x="0" y="0" width="38.7837838" height="45.5813953" rx="3"></rect>
-        <mask id="mask-2" maskContentUnits="userSpaceOnUse" maskUnits="objectBoundingBox" x="0" y="0" width="38.7837838" height="45.5813953" fill="white">
-            <use xlink:href="#path-1"></use>
-        </mask>
-    </defs>
-    <g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
-        <g id="wiktionary">
-            <g id="Group" transform="translate(9.000000, 4.000000)">
-                <rect id="Rectangle-5" fill="#000000" x="2.21621622" y="4.55813953" width="38.7837838" height="44.4418605" rx="3"></rect>
-                <use id="Rectangle-5" stroke="#FFFFFF" mask="url(#mask-2)" stroke-width="4" fill="#000000" xlink:href="#path-1"></use>
-                <rect id="Rectangle-5" fill="#000000" x="2.21621622" y="2.27906977" width="3.32432432" height="45.5813953" rx="1.66216216"></rect>
-                <path d="M9.96584688,24.0254991 L12.5526201,16.7046287 L12.5953767,16.7046287 L15.1393934,24.0254991 L9.96584688,24.0254991 Z M11.4837056,14.8139535 L5.54054054,30.5109549 L7.61423481,30.5109549 L9.32449813,25.7842668 L15.7807422,25.7842668 L17.4482489,30.5109549 L19.6929695,30.5109549 L13.7284262,14.8139535 L11.4837056,14.8139535 Z M19.9922656,28.7521872 L19.9922656,30.5109549 L32.1351351,30.5109549 L32.1351351,28.7521872 L22.4080125,28.7521872 L31.8785956,16.5727212 L31.8785956,14.8139535 L20.7191275,14.8139535 L20.7191275,16.5727212 L29.484227,16.5727212 L19.9922656,28.7521872 Z" id="AZ" fill="#FFFFFF"></path>
-            </g>
-        </g>
-    </g>
-</svg>
\ No newline at end of file
diff --git a/resources/src/mediawiki.special/images/special.search/dna-icon.png b/resources/src/mediawiki.special/images/special.search/dna-icon.png
deleted file mode 100644 (file)
index 76ae7b9..0000000
Binary files a/resources/src/mediawiki.special/images/special.search/dna-icon.png and /dev/null differ
diff --git a/resources/src/mediawiki.special/images/special.search/dna-icon.svg b/resources/src/mediawiki.special/images/special.search/dna-icon.svg
deleted file mode 100644 (file)
index b6472d2..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<svg width="60px" height="60px" viewBox="0 0 60 60" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
-    <!-- Generator: Sketch 41.2 (35397) - http://www.bohemiancoding.com/sketch -->
-    <title>wikispecies-icon</title>
-    <desc>Created with Sketch.</desc>
-    <defs>
-        <path d="M30.7731558,0.186194824 C30.7731558,0.186194824 35.1530541,17.902764 16.3205992,24.2966289 C-2.5118558,30.6904937 1.3758711,49.1033824 1.3758711,49.1033824" id="path-1"></path>
-        <path d="M30.7473572,49.159218 C30.7473572,49.159218 35.6539441,38.982551 16.3205992,25.0539186 C-3.01274582,11.1252862 1.37060607,0.169606006 1.37060607,0.169606006" id="path-2"></path>
-    </defs>
-    <g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
-        <g id="wikispecies">
-            <g id="Group-3" transform="translate(29.651065, 29.732290) rotate(-18.000000) translate(-29.651065, -29.732290) translate(3.651065, -0.267710)">
-                <g id="Group-2" transform="translate(-0.000000, 0.000000)">
-                    <path d="M16.0550183,26.1396841 L28.2093366,18.8733993" id="Line"></path>
-                    <path d="M8.04887438,16.7717325 L25.4345247,6.48465118" id="Line" stroke="#000000" stroke-width="4" stroke-linecap="square"></path>
-                    <path d="M25.407947,53.9559038 L42.7935973,43.6688225" id="Line" stroke="#000000" stroke-width="4" stroke-linecap="square"></path>
-                    <path d="M15.372315,23.3571115 L32.7579654,13.0700302" id="Line" stroke="#000000" stroke-width="4" stroke-linecap="square"></path>
-                    <path d="M23.3476093,40.6564377 L35.5019275,33.3901529" id="Line"></path>
-                    <path d="M23.587979,44.4357028 L40.6040246,34.7578672" id="Line" stroke="#000000" stroke-width="4" stroke-linecap="square"></path>
-                    <g id="Group" transform="translate(26.088934, 30.408062) rotate(-27.000000) translate(-26.088934, -30.408062) translate(10.088934, 5.408062)">
-                        <g id="Path-2">
-                            <use stroke="#FFFFFF" stroke-width="10" xlink:href="#path-1"></use>
-                            <use stroke="#000000" stroke-width="5" xlink:href="#path-1"></use>
-                        </g>
-                        <g id="Path-2">
-                            <use stroke="#FFFFFF" stroke-width="10" xlink:href="#path-2"></use>
-                            <use stroke="#000000" stroke-width="5" xlink:href="#path-2"></use>
-                        </g>
-                    </g>
-                </g>
-            </g>
-        </g>
-    </g>
-</svg>
\ No newline at end of file
diff --git a/resources/src/mediawiki.special/images/special.search/image-icon.png b/resources/src/mediawiki.special/images/special.search/image-icon.png
deleted file mode 100644 (file)
index 1ebbc74..0000000
Binary files a/resources/src/mediawiki.special/images/special.search/image-icon.png and /dev/null differ
diff --git a/resources/src/mediawiki.special/images/special.search/image-icon.svg b/resources/src/mediawiki.special/images/special.search/image-icon.svg
deleted file mode 100644 (file)
index b68762e..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<svg width="60px" height="60px" viewBox="0 0 60 60" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
-    <!-- Generator: Sketch 41.2 (35397) - http://www.bohemiancoding.com/sketch -->
-    <title>commons-icon</title>
-    <desc>Created with Sketch.</desc>
-    <defs></defs>
-    <g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
-        <g id="commons">
-            <g id="Group" transform="translate(7.000000, 10.000000)">
-                <rect id="Rectangle-3" fill="#000000" x="0" y="7" width="47" height="32" rx="3"></rect>
-                <path d="M12.5575779,0.983966166 C12.6781522,0.440536658 13.228439,0 13.7774775,0 L33.4411152,0 C33.9942728,0 34.5376987,0.428179934 34.6610148,0.983966166 L36.1940854,7.89352671 C36.3146597,8.43695622 35.9679607,8.87749288 35.4086105,8.87749288 L11.8099821,8.87749288 C11.255602,8.87749288 10.9011913,8.44931294 11.0245073,7.89352671 L12.5575779,0.983966166 Z" id="Rectangle-3" fill="#000000"></path>
-                <ellipse id="Oval" stroke="#FFFFFF" stroke-width="3" cx="23.1981132" cy="23.2091168" rx="10.1981132" ry="10.2091168"></ellipse>
-            </g>
-        </g>
-    </g>
-</svg>
\ No newline at end of file
diff --git a/resources/src/mediawiki.special/images/special.search/news-icon.png b/resources/src/mediawiki.special/images/special.search/news-icon.png
deleted file mode 100644 (file)
index 6b79590..0000000
Binary files a/resources/src/mediawiki.special/images/special.search/news-icon.png and /dev/null differ
diff --git a/resources/src/mediawiki.special/images/special.search/news-icon.svg b/resources/src/mediawiki.special/images/special.search/news-icon.svg
deleted file mode 100644 (file)
index 996bc84..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<svg width="60px" height="60px" viewBox="0 0 60 60" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
-    <!-- Generator: Sketch 41.2 (35397) - http://www.bohemiancoding.com/sketch -->
-    <title>wikinews-icon</title>
-    <desc>Created with Sketch.</desc>
-    <defs>
-        <rect id="path-1" x="0" y="0" width="40.3125" height="44.3773585" rx="3"></rect>
-        <mask id="mask-2" maskContentUnits="userSpaceOnUse" maskUnits="objectBoundingBox" x="0" y="0" width="40.3125" height="44.3773585" fill="white">
-            <use xlink:href="#path-1"></use>
-        </mask>
-    </defs>
-    <g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
-        <g id="wikinews">
-            <g id="Group-2" transform="translate(7.000000, 2.000000)">
-                <g id="Group">
-                    <use id="Rectangle" stroke="#000000" mask="url(#mask-2)" stroke-width="8" xlink:href="#path-1"></use>
-                    <rect id="Rectangle-2" fill="#000000" x="5.87890625" y="7.10037736" width="14.2773438" height="15.0883019" rx="1"></rect>
-                    <path d="M23.9355469,8.32075472 L33.2060822,8.32075472" id="Line" stroke="#000000" stroke-width="2" stroke-linecap="square"></path>
-                    <path d="M23.9355469,13.8679245 L33.2060822,13.8679245" id="Line" stroke="#000000" stroke-width="2" stroke-linecap="square"></path>
-                    <path d="M23.9355469,19.4150943 L33.2060822,19.4150943" id="Line" stroke="#000000" stroke-width="2" stroke-linecap="square"></path>
-                    <path d="M22.5550667,30.509434 L33.1506715,30.509434" id="Line" stroke="#000000" stroke-width="2" stroke-linecap="square"></path>
-                    <path d="M7.17212403,30.509434 L17.1811761,30.509434" id="Line" stroke="#000000" stroke-width="2" stroke-linecap="square"></path>
-                    <path d="M7.17212403,35.1320755 L17.1811761,35.1320755" id="Line" stroke="#000000" stroke-width="2" stroke-linecap="square"></path>
-                    <path d="M22.5550667,35.1320755 L33.1506715,35.1320755" id="Line" stroke="#000000" stroke-width="2" stroke-linecap="square"></path>
-                    <path d="M7.12514628,24.9622642 L33.2060822,24.9622642" id="Line" stroke="#000000" stroke-width="2" stroke-linecap="square"></path>
-                </g>
-                <path d="M42.1813257,4.62264151 C43.7380365,4.62264151 45,5.85586295 45,7.39864403 L45,46.2239975 C45,47.7571413 43.7493218,49 42.1813257,49 L7.50617429,49 C5.94946346,49 4.6875,47.7667786 4.6875,46.2239975" id="Rectangle" stroke="#000000" stroke-width="4"></path>
-            </g>
-        </g>
-    </g>
-</svg>
\ No newline at end of file
diff --git a/resources/src/mediawiki.special/images/special.search/quotation-icon.png b/resources/src/mediawiki.special/images/special.search/quotation-icon.png
deleted file mode 100644 (file)
index 9d3ade3..0000000
Binary files a/resources/src/mediawiki.special/images/special.search/quotation-icon.png and /dev/null differ
diff --git a/resources/src/mediawiki.special/images/special.search/quotation-icon.svg b/resources/src/mediawiki.special/images/special.search/quotation-icon.svg
deleted file mode 100644 (file)
index 0a24b3e..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<svg width="60px" height="60px" viewBox="0 0 60 60" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
-    <!-- Generator: Sketch 41.2 (35397) - http://www.bohemiancoding.com/sketch -->
-    <title>wikiquote-icon</title>
-    <desc>Created with Sketch.</desc>
-    <defs></defs>
-    <g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
-        <g id="wikiquote" fill="#000000">
-            <path d="M25.6795093,50 L25.6795093,29.5241523 L16.904146,29.5241523 C16.904146,26.2444546 17.52462,23.4744813 18.7655867,21.2141491 C20.0065533,18.9538169 22.3111712,17.2475134 25.6795093,16.0951872 L25.6795093,7.31982385 C22.9316545,7.67438575 20.383279,8.49429786 18.0343064,9.77958478 C15.6853338,11.0648717 13.6687932,12.6825361 11.9846241,14.6326266 C10.300455,16.5827171 8.99302762,18.8430154 8.06230261,21.4135892 C7.13157761,23.984163 6.71054166,26.7319766 6.79918214,29.6571123 L6.79918214,50 L25.6795093,50 Z M54,50 L54,29.5241523 L45.2246367,29.5241523 C45.2246367,26.2444546 45.8451107,23.4744813 47.0860774,21.2141491 C48.3270441,18.9538169 50.6316619,17.2475134 54,16.0951872 L54,7.31982385 C51.2521452,7.67438575 48.7037697,8.49429786 46.3547971,9.77958478 C44.0058245,11.0648717 41.9892839,12.6825361 40.3051148,14.6326266 C38.6209458,16.5827171 37.3135183,18.8430154 36.3827933,21.4135892 C35.4520683,23.984163 35.0310324,26.7319766 35.1196729,29.6571123 L35.1196729,50 L54,50 Z" id="“"></path>
-        </g>
-    </g>
-</svg>
\ No newline at end of file
diff --git a/resources/src/mediawiki.special/images/special.search/textbook-icon.png b/resources/src/mediawiki.special/images/special.search/textbook-icon.png
deleted file mode 100644 (file)
index 0de2821..0000000
Binary files a/resources/src/mediawiki.special/images/special.search/textbook-icon.png and /dev/null differ
diff --git a/resources/src/mediawiki.special/images/special.search/textbook-icon.svg b/resources/src/mediawiki.special/images/special.search/textbook-icon.svg
deleted file mode 100644 (file)
index 52446b8..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<svg width="60px" height="60px" viewBox="0 0 60 60" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
-    <!-- Generator: Sketch 41.2 (35397) - http://www.bohemiancoding.com/sketch -->
-    <title>wikibooks-icon</title>
-    <desc>Created with Sketch.</desc>
-    <defs></defs>
-    <g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
-        <g id="wikibooks">
-            <g id="Group-2" transform="translate(7.000000, 6.000000)">
-                <rect id="Rectangle" fill="#000000" x="0" y="0" width="13.4872062" height="46.9333333" rx="1"></rect>
-                <rect id="Rectangle" fill="#000000" x="16.3773218" y="0" width="13.4872062" height="46.9333333" rx="1"></rect>
-                <rect id="Rectangle-2" fill="#FFFFFF" x="18.3040656" y="3.2" width="9.63371872" height="2.13333333" rx="1"></rect>
-                <rect id="Rectangle-2" fill="#FFFFFF" x="18.3040656" y="7.46666667" width="9.63371872" height="2.13333333" rx="1"></rect>
-                <rect id="Rectangle-2" fill="#FFFFFF" x="18.3040656" y="42.6666667" width="9.63371872" height="2.13333333" rx="1"></rect>
-                <g id="Group" transform="translate(41.629197, 24.582549) rotate(-15.000000) translate(-41.629197, -24.582549) translate(36.629197, 2.082549)">
-                    <rect id="Rectangle" fill="#000000" x="-9.14823772e-14" y="1.0658141e-14" width="9.63371872" height="44.8" rx="1"></rect>
-                    <rect id="Rectangle-2" fill="#FFFFFF" x="1.37624553" y="3.05454545" width="6.88122765" height="2.03636364" rx="1"></rect>
-                    <rect id="Rectangle-2" fill="#FFFFFF" x="4.12873659" y="18.3272727" width="2.0643683" height="8.14545455" rx="1"></rect>
-                    <rect id="Rectangle-2" fill="#FFFFFF" x="1.37624553" y="40.7272727" width="6.88122765" height="2.03636364" rx="1"></rect>
-                </g>
-                <rect id="Rectangle-2" fill="#FFFFFF" x="1.92674374" y="42.6666667" width="9.63371872" height="2.13333333" rx="1"></rect>
-                <rect id="Rectangle-2" fill="#FFFFFF" x="3.85348749" y="21.3333333" width="5.78023123" height="6.4" rx="1"></rect>
-                <rect id="Rectangle-2" fill="#FFFFFF" x="20.2308093" y="21.3333333" width="5.78023123" height="6.4" rx="1"></rect>
-                <rect id="Rectangle-2" fill="#FFFFFF" x="1.92674374" y="2.13333333" width="9.63371872" height="6.4" rx="1"></rect>
-            </g>
-        </g>
-    </g>
-</svg>
\ No newline at end of file
diff --git a/resources/src/mediawiki.special/images/special.search/travel-icon.png b/resources/src/mediawiki.special/images/special.search/travel-icon.png
deleted file mode 100644 (file)
index 9540e5b..0000000
Binary files a/resources/src/mediawiki.special/images/special.search/travel-icon.png and /dev/null differ
diff --git a/resources/src/mediawiki.special/images/special.search/travel-icon.svg b/resources/src/mediawiki.special/images/special.search/travel-icon.svg
deleted file mode 100644 (file)
index c61da34..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<svg width="60px" height="60px" viewBox="0 0 60 60" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
-    <!-- Generator: Sketch 41.2 (35397) - http://www.bohemiancoding.com/sketch -->
-    <title>wikivoyage-icon</title>
-    <desc>Created with Sketch.</desc>
-    <defs></defs>
-    <g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
-        <g id="wikivoyage">
-            <circle id="Oval" stroke="#000000" stroke-width="5" cx="30.5" cy="29.5" r="22.5"></circle>
-            <polygon id="Line" fill="#000000" points="7.94117647 26 51.7647059 26 51.7647059 21 7.94117647 21"></polygon>
-            <polygon id="Line" fill="#000000" points="11 41 51.7647059 41 51.7647059 36 11 36"></polygon>
-            <path d="M33.3291453,53.239081 C33.3291453,53.239081 36.1487341,50.645866 37.4655139,48.564933 C41.2810931,42.5350981 43.5882353,36.2426616 43.5882353,29.9411765 C43.5882353,23.6228427 41.2687791,17.4752409 37.4345128,11.7108181 C36.1106408,9.72051335 34.6944337,8.91628537 33.2755423,7.32564334 C32.4145319,6.36041143 26.8207622,5.36041143 25.9597518,6.32564334 C24.5408604,7.91628537 23.1246533,9.72051335 21.8007813,11.7108181 C17.9665151,17.4752409 15.6470588,23.6228427 15.6470588,29.9411765 C15.6470588,36.2426616 17.954201,42.5350981 21.7697802,48.564933 C23.08656,50.645866 26.9061488,53.239081 26.9061488,53.239081 L33.3291453,53.239081 Z M25.9949257,45.8913313 C22.6413872,40.5916685 20.6470588,35.1523918 20.6470588,29.9411765 C20.6470588,24.7468098 22.6290732,19.4935807 25.9639246,14.4799765 C27.1264205,12.7322841 28.3724952,11.1396672 29.6176471,9.73642318 C30.8627989,11.1396672 32.1088737,12.7322841 33.2713695,14.4799765 C36.6062209,19.4935807 38.5882353,24.7468098 38.5882353,29.9411765 C38.5882353,35.1523918 36.5939069,40.5916685 33.2403685,45.8913313 C32.0874519,47.7133081 30.8528466,49.389908 29.6176471,50.8822433 C28.3824475,49.389908 27.1478422,47.7133081 25.9949257,45.8913313 Z" id="Oval" fill="#000000"></path>
-        </g>
-    </g>
-</svg>
\ No newline at end of file
index f3eef7c..f53850a 100644 (file)
 
                Util.fetchModuleInfo( this.apiModule )
                        .done( function ( pi ) {
-                               var prefix, i, j, descriptionContainer, widget, $widgetLabel, widgetField, helpField, tmp, flag, count,
+                               var prefix, i, j, descriptionContainer, widget, widgetField, helpField, tmp, flag, count,
                                        items = [],
                                        deprecatedItems = [],
                                        buttons = [],
                                                        }
                                                );
 
-                                               $widgetLabel = $( '<span>' );
                                                widgetField = new OO.ui.FieldLayout(
                                                        widget,
                                                        {
                                                                align: 'left',
                                                                classes: [ 'mw-apisandbox-widget-field' ],
-                                                               label: prefix + pi.parameters[ i ].name,
-                                                               $label: $widgetLabel
+                                                               label: prefix + pi.parameters[ i ].name
                                                        }
                                                );
 
-                                               // FieldLayout only does click for InputElement
-                                               // widgets. So supply our own click handler.
-                                               $widgetLabel.on( 'click', widgetLabelOnClick.bind( widgetField ) );
+                                               // We need our own click handler on the widget label to
+                                               // turn off the disablement.
+                                               widgetField.$label.on( 'click', widgetLabelOnClick.bind( widgetField ) );
 
                                                // Don't grey out the label when the field is disabled,
                                                // it makes it too hard to read and our "disabled"
index 7e42886..9518283 100644 (file)
@@ -30,7 +30,6 @@
 
                return '<li class="iw-resultset iw-resultset--image" data-iw-resultset-pos="0">' +
                                '<div class="iw-result__header">' +
-                                       '<span class="iw-result__icon iw-result__icon--image"></span>' +
                                        '<strong>' + imagesText.escaped() + '</strong>' +
                                '</div>' +
                                '<div class="iw-result__content">' +
                        return;
                }
 
-               results.sort( function( a, b ) {
+               results.sort( function ( a, b ) {
                        return a.index - b.index;
                } );
 
                multimediaWidgetTemplate = itemWrapperTemplate( pageUrl.query.search, itemTemplate( results ) );
                /* we really only need to wait for document ready for DOM manipulation */
                $( function () {
-                       $( '.iw-results' ).prepend( multimediaWidgetTemplate );
+                       $( '.iw-results' ).append( multimediaWidgetTemplate );
                } );
        } );
 
index 3f23dc4..92e3e1c 100644 (file)
 /* interwiki search results */
 /*==========================*/
 
-.iw-headline {
-       font-weight: bold;
-       font-size: 1rem;
-       font-size: 16px;
-       opacity: 0.7;
-}
-
-.iw-results {
-       list-style: none;
-       margin: 0;
-}
-
-.iw-resultset {
-       margin-bottom: 1.2em;
-       background-color: #f2f4f7;
-       vertical-align: top;
-       width: 100%;
-       float: left;
-       list-style-type: none;
-       word-break: break-word;
-}
-
-/* clearfix */
-.iw-result:after {
-       visibility: hidden;
-       display: block;
-       font-size: 0;
-       content: ' ';
-       clear: both;
-       height: 0;
-}
-
-* html .interwiki-result { /* IE6 */
-       zoom: 1;
-}
-*:first-child + html .iw-resultset { /* IE7 */
-       zoom: 1;
-}
-
-/* padding each .iw-resultset section seperately.
-This allows us greater flexibility in the design.
-For example changing the background color on the
-header and footer. */
-.iw-result__header,
-.iw-result__title,
-.iw-result__content,
-.iw-result__footer {
-       padding: 0.25em 0.85em;
-}
-
-/* definition titles appear inline,
-to resemble a traditional dictionary definition */
-.iw-resultset--definition .iw-result__title {
-       display: inline;
-       padding: 0;
-}
-
-.iw-resultset > div:first-child {
-       padding-top: 0.85em;
-}
-
-.iw-resultset > div:last-child {
-       padding-bottom: 0.85em;
-}
-
-.iw-result__title {
-       font-size: 16px; /* rem fallback */
-       font-size: 1rem;
-}
-
-.iw-result__title a.extiw {
-       font-weight: bold;
-}
-
-.iw-result__content:after { /* clearfix */
-       visibility: hidden;
-       display: block;
-       font-size: 0;
-       content: ' ';
-       clear: both;
-       height: 0;
-}
-
-.iw-result__footer {
-       float: right;
-}
-
-.iw-result__icon {
-       display: inline-block;
-       width: 24px;
-       height: 24px;
-       vertical-align: middle;
-       margin-right: 0.25em;
-       background: url( images/special.search/definition-icon.svg ) no-repeat 0 0;
-       background-size: 100% 100%;
-}
+@import 'mediawiki.ui/variables.less';
+@import 'mediawiki.mixins';
 
-@interwikiContentTypes: definition, travel, quotation, book, course, news, textbook, image;
+.mw-searchresults-has-iw {
 
-.generate-iwIcons();
-
-.generate-iwIcons( @i:1 ) when ( @i =< length( @interwikiContentTypes ) ) {
-       @iwIcon: extract( @interwikiContentTypes, @i );
-
-       .iw-result__icon--@{iwIcon} {
-               /*  stylelint-disable-next-line function-url-quotes */
-               background-image: url( 'images/special.search/@{iwIcon}-icon.png' );
-               /*  stylelint-disable-next-line function-url-quotes */
-               background-image: url( 'images/special.search/@{iwIcon}-icon.svg' );
+       .iw-headline {
+               font-weight: bold;
        }
 
-       .generate-iwIcons( @i + 1 );
-}
+       .iw-results {
+               list-style: none;
+               margin: 0;
+       }
 
-/* image search result */
-.iw-result__mini-gallery {
-       position: relative;
-       float: left;
-       width: 60%;
-       height: 200px;
-       box-sizing: border-box;
-       padding: 0.25rem;
-}
+       .iw-resultset {
+               .box-sizing(border-box);
+               padding: 0.5em;
+               vertical-align: top;
+               width: 100%;
+               float: left;
+               background-color: @colorGray15;
+               margin-bottom: 1em;
+               word-break: break-word;
+       }
 
-/* second and third images are small */
-.iw-result__mini-gallery:nth-child( 2 ),
-.iw-result__mini-gallery:nth-child( 3 ) { /* stylelint-disable-line indentation */
-       width: 40%;
-       height: 100px;
-}
+       .iw-result__title {
+               font-size: 108%; /* matching regular search title */
+       }
 
-.iw-result__mini-gallery__image {
-       display: block;
-       position: relative;
-       width: 100%;
-       height: 100%;
-       background-size: cover;
-       background-repeat: no-repeat;
-       background-position: center center;
-}
+       .iw-result:after,
+       .iw-result__content:after { /* clearfix */
+               visibility: hidden;
+               display: block;
+               font-size: 0;
+               content: ' ';
+               clear: both;
+               height: 0;
+       }
 
-.iw-result__mini-gallery__image > .iw-result__mini-gallery__caption { /* image gallery text */
-       visibility: hidden;
-       position: absolute;
-       bottom: 0;
-       left: 0;
-       text-align: center;
-       color: #fff;
-       text-shadow: 0 0 10px rgba( 0, 0, 0, 0.4 ); /* improves legibility on white background */
-       font-size: 0.8em;
-       padding: 5px;
-       background-color: rgba( 0, 0, 0, 0.5 );
-}
+       .iw-result__footer {
+               float: right;
+               font-size: 97%; /* matching main search result font-size */
+               margin-top: 0.5em;
+       }
+       .iw-result__footer a {
+               vertical-align: middle;
+               color: @colorGray7;
+               font-style: italic;
+       }
 
-.iw-result__mini-gallery__image:hover > .iw-result__mini-gallery__caption {
-       visibility: visible;
-}
+       .oo-ui-icon-favicon {
+               padding-right: 1em;
+       }
 
-/* different types of interwiki result boxes */
-/* quotation box */
-.iw-resultset--quotation .iw-result__content {
-       border-left: 4px solid #afb1b5;
-       margin-left: 1em;
-       padding-top: 0;
-       margin-top: 0.25em;
-}
-.iw-resultset--quotation .iw-result__title {
-       margin-left: 1em;
-}
-.iw-result--quotation .iw-result__title:before {
-       content: ' — ';
-       display: inline-block;
-}
-.iw-result--quotation .iw-result__footer {
-       text-align: right;
-}
+       /* image search result */
+       .iw-result__mini-gallery {
+               position: relative;
+               float: left;
+               width: 100%;
+               height: 200px;
+               .box-sizing(border-box);
+               padding: 0.25rem;
+       }
 
-/* desktop only */
+       /* second and third images are small */
+       .iw-result__mini-gallery:nth-child( 2 ),
+       .iw-result__mini-gallery:nth-child( 3 ) { /* stylelint-disable-line indentation */
+               width: 50%;
+               height: 100px;
+       }
 
-@media only screen and ( min-width: @deviceWidthTablet ) {
+       .iw-result__mini-gallery__image {
+               display: block;
+               position: relative;
+               width: 100%;
+               height: 100%;
+               background-size: 100% auto;
+               background-size: cover;
+               background-repeat: no-repeat;
+               background-position: center center;
+       }
 
-       #mw-interwiki-results {
-               width: 30%;
-               display: inline-block; /* used to align iw sidebar with the top of the main search results */
-               margin-left: 10%;
+       /* image gallery text */
+       .iw-result__mini-gallery__image > .iw-result__mini-gallery__caption {
+               visibility: hidden;
+               position: absolute;
+               bottom: 0;
+               left: 0;
+               text-align: center;
+               color: #fff;
+               font-size: 0.8em;
+               padding: 0.5em;
+               background-color: rgba( 0, 0, 0, 0.5 );
        }
-       .searchresults .mw-search-createlink,
-       .searchresults .mw-search-nonefound,
-       .searchresults .mw-search-results {
-               float: left;
-               width: 60%;
+
+       .iw-result__mini-gallery__image:hover > .iw-result__mini-gallery__caption {
+               visibility: visible;
        }
 
+       /* tablet and up */
+
+       @media only screen and ( min-width: @deviceWidthTablet ) {
+
+               #mw-interwiki-results {
+                       width: 30%;
+                       display: inline-block; /* used to align interwiki sidebar with the top of the main search results */
+                       margin-left: 10%;
+               }
+               .mw-search-createlink,
+               .mw-search-nonefound,
+               .mw-search-results {
+                       float: left;
+                       width: 60%;
+                       clear: left;
+                       max-width: 60%;
+               }
+       }
 }
index 70d7cb5..d7464b9 100644 (file)
@@ -85,7 +85,7 @@
         *
         * @return {Array} usernames
         */
-       mw.widgets.UsersMultiselectWidget.prototype.getSelectedUsernames = function() {
+       mw.widgets.UsersMultiselectWidget.prototype.getSelectedUsernames = function () {
                return this.getItemsData();
        };
 
@@ -94,7 +94,7 @@
         *
         * @private
         */
-       mw.widgets.UsersMultiselectWidget.prototype.updateMenuItems = function() {
+       mw.widgets.UsersMultiselectWidget.prototype.updateMenuItems = function () {
                var inputValue = this.$input.val();
 
                if ( inputValue === this.inputValue ) {
                                // character to uppercase so that "fo" may yield "Foo".
                                auprefix: inputValue[ 0 ].toUpperCase() + inputValue.slice( 1 ),
                                aulimit: this.limit
-                       } ).done( function( response ) {
+                       } ).done( function ( response ) {
                                var suggestions = response.query.allusers,
                                        selected = this.getSelectedUsernames();
 
                                                        label: user.name
                                                } );
                                        }
-                               } ).filter( function( item ) {
+                               } ).filter( function ( item ) {
                                        return item !== undefined;
                                } );
 
         *
         * @private
         */
-       mw.widgets.UsersMultiselectWidget.prototype.updateHiddenInput = function() {
+       mw.widgets.UsersMultiselectWidget.prototype.updateHiddenInput = function () {
                if ( 'hiddenInput' in this ) {
                        this.hiddenInput.val( this.getSelectedUsernames().join( '\n' ) );
                }
index e3a8f7b..ee3bac2 100644 (file)
@@ -98,6 +98,7 @@
                         */
                        trigger: function () {
                                // use confirm to show the message to the user (if options.text() is true)
+                               // eslint-disable-next-line no-alert
                                if ( options.test() && !confirm( message ) ) {
                                        // the user want to keep the actual page
                                        return false;
index 638fba7..9332773 100644 (file)
                                // Use Function.prototype#call to force an exception on Firefox,
                                // which doesn't define console#table but doesn't complain if you
                                // try to invoke it.
+                               // eslint-disable-next-line no-useless-call
                                console.table.call( console, data );
                                return;
                        } catch ( e ) {}
index f100411..f44b0d5 100644 (file)
@@ -747,6 +747,10 @@ class ParserTestRunner {
                $user = $context->getUser();
                $options = ParserOptions::newFromContext( $context );
 
+               if ( !isset( $opts['wrap'] ) ) {
+                       $options->setWrapOutputClass( false );
+               }
+
                if ( isset( $opts['tidy'] ) ) {
                        if ( !$this->tidySupport->isEnabled() ) {
                                $this->recorder->skipped( $test, 'tidy extension is not installed' );
index e12c136..6477356 100644 (file)
@@ -32,6 +32,7 @@
 # local         format section links in edit comment text as local links
 # notoc         disable table of contents
 # thumbsize=NNN set the default thumb size to NNNpx for this test
+# wrap          include the normal wrapper <div class="mw-parser-output"> (since 1.30)
 #
 # You can also set the following parser properties via test options:
 #  wgEnableUploads, wgAllowExternalImages, wgMaxTocLevel,
index 4e95a30..a4e3bb9 100644 (file)
@@ -26,6 +26,7 @@ class ExtraParserTest extends MediaWikiTestCase {
                // FIXME: This test should pass without setting global content language
                $this->options = ParserOptions::newFromUserAndLang( new User, $contLang );
                $this->options->setTemplateCallback( [ __CLASS__, 'statelessFetchTemplate' ] );
+               $this->options->setWrapOutputClass( false );
                $this->parser = new Parser;
 
                MagicWord::clearCache();
@@ -40,6 +41,7 @@ class ExtraParserTest extends MediaWikiTestCase {
 
                $title = Title::newFromText( 'Unit test' );
                $options = ParserOptions::newFromUser( new User() );
+               $options->setWrapOutputClass( false );
                $this->assertEquals( "<p>$longLine</p>",
                        $this->parser->parse( $longLine, $title, $options )->getText() );
        }
index 5546de8..0015453 100644 (file)
@@ -23,7 +23,6 @@ class ChangesListFilterTest extends MediaWikiTestCase {
                                'filters' => [],
                        ]
                );
-
        }
 
        // @codingStandardsIgnoreStart
index c76e8bb..a6b220d 100644 (file)
@@ -40,6 +40,7 @@ class GlobalVarConfigTest extends MediaWikiTestCase {
 
        /**
         * @covers GlobalVarConfig::has
+        * @covers GlobalVarConfig::hasWithPrefix
         */
        public function testHas() {
                $this->maybeStashGlobal( 'wgGlobalVarConfigTestHas' );
@@ -72,12 +73,12 @@ class GlobalVarConfigTest extends MediaWikiTestCase {
        }
 
        /**
-        * @param string $name
-        * @param string $prefix
-        * @param string $expected
         * @dataProvider provideGet
         * @covers GlobalVarConfig::get
         * @covers GlobalVarConfig::getWithPrefix
+        * @param string $name
+        * @param string $prefix
+        * @param string $expected
         */
        public function testGet( $name, $prefix, $expected ) {
                $config = new GlobalVarConfig( $prefix );
index bc6d6eb..d1eb510 100644 (file)
@@ -5,6 +5,7 @@ class MultiConfigTest extends MediaWikiTestCase {
        /**
         * Tests that settings are fetched in the right order
         *
+        * @covers MultiConfig::__construct
         * @covers MultiConfig::get
         */
        public function testGet() {
index 4c69d87..b9ce997 100644 (file)
@@ -29,7 +29,7 @@ more stuff
                                "WikitextContentTest_testGetParserOutput",
                                CONTENT_MODEL_WIKITEXT,
                                "hello ''world''\n",
-                               "<p>hello <i>world</i>\n</p>"
+                               "<div class=\"mw-parser-output\"><p>hello <i>world</i>\n</p>\n\n\n</div>"
                        ],
                        // TODO: more...?
                ];
index 97e9b26..f61569a 100644 (file)
@@ -91,7 +91,6 @@ class FakeDatabaseMysqlBase extends DatabaseMysqlBase {
        }
 
        protected function mysqlRealEscapeString( $s ) {
-
        }
 
        function insertId() {
index d7ad1d1..2c199bc 100644 (file)
@@ -13,8 +13,7 @@ class DeferredUpdatesTest extends MediaWikiTestCase {
                $post = DeferredUpdates::POSTSEND;
                $all = DeferredUpdates::ALL;
 
-               $update = $this->getMockBuilder( 'DeferrableUpdate' )
-                             ->getMock();
+               $update = $this->getMock( DeferrableUpdate::class );
                $update->expects( $this->never() )
                        ->method( 'doUpdate' );
 
index 4754b04..1d62a78 100644 (file)
@@ -60,20 +60,37 @@ class InterwikiLookupAdapterTest extends MediaWikiTestCase {
        }
 
        public function testGetAllPrefixes() {
+               $foo = [
+                       'iw_prefix' => 'foo',
+                       'iw_url' => '',
+                       'iw_api' => '',
+                       'iw_wikiid' => 'foobar',
+                       'iw_local' => false,
+                       'iw_trans' => false,
+               ];
+               $enwt = [
+                       'iw_prefix' => 'enwt',
+                       'iw_url' => 'https://en.wiktionary.org/wiki/$1',
+                       'iw_api' => 'https://en.wiktionary.org/w/api.php',
+                       'iw_wikiid' => 'enwiktionary',
+                       'iw_local' => true,
+                       'iw_trans' => false,
+               ];
+
                $this->assertEquals(
-                       [ 'foo', 'enwt' ],
+                       [ $foo, $enwt ],
                        $this->interwikiLookup->getAllPrefixes(),
                        'getAllPrefixes()'
                );
 
                $this->assertEquals(
-                       [ 'foo' ],
+                       [ $foo ],
                        $this->interwikiLookup->getAllPrefixes( false ),
                        'get external prefixes'
                );
 
                $this->assertEquals(
-                       [ 'enwt' ],
+                       [ $enwt ],
                        $this->interwikiLookup->getAllPrefixes( true ),
                        'get local prefixes'
                );
index 42f08cc..d0121b1 100644 (file)
@@ -147,6 +147,45 @@ class CSSMinTest extends MediaWikiTestCase {
                ];
        }
 
+       public static function provideIsRemoteUrl() {
+               return [
+                       [ true, 'http://localhost/w/red.gif?123' ],
+                       [ true, 'https://example.org/x.png' ],
+                       [ true, '//example.org/x.y.z/image.png' ],
+                       [ true, '//localhost/styles.css?query=yes' ],
+                       [ true, 'data:image/gif;base64,R0lGODlhAQABAIAAAP8AADAAACwAAAAAAQABAAACAkQBADs=' ],
+                       [ false, 'x.gif' ],
+                       [ false, '/x.gif' ],
+                       [ false, './x.gif' ],
+                       [ false, '../x.gif' ],
+               ];
+       }
+
+       /**
+        * @dataProvider provideIsRemoteUrl
+        * @cover CSSMin::isRemoteUrl
+        */
+       public function testIsRemoteUrl( $expect, $url ) {
+               $this->assertEquals( CSSMinTestable::isRemoteUrl( $url ), $expect );
+       }
+
+       public static function provideIsLocalUrls() {
+               return [
+                       [ false, 'x.gif' ],
+                       [ true, '/x.gif' ],
+                       [ false, './x.gif' ],
+                       [ false, '../x.gif' ],
+               ];
+       }
+
+       /**
+        * @dataProvider provideIsLocalUrls
+        * @cover CSSMin::isLocalUrl
+        */
+       public function testIsLocalUrl( $expect, $url ) {
+               $this->assertEquals( CSSMinTestable::isLocalUrl( $url ), $expect );
+       }
+
        /**
         * This tests funky parameters to CSSMin::remap. testRemapRemapping tests
         * the basic functionality.
@@ -211,45 +250,6 @@ class CSSMinTest extends MediaWikiTestCase {
                $this->assertEquals( $expectedOutput, $realOutput, "CSSMin::remap: $message" );
        }
 
-       public static function provideIsRemoteUrl() {
-               return [
-                       [ true, 'http://localhost/w/red.gif?123' ],
-                       [ true, 'https://example.org/x.png' ],
-                       [ true, '//example.org/x.y.z/image.png' ],
-                       [ true, '//localhost/styles.css?query=yes' ],
-                       [ true, 'data:image/gif;base64,R0lGODlhAQABAIAAAP8AADAAACwAAAAAAQABAAACAkQBADs=' ],
-                       [ false, 'x.gif' ],
-                       [ false, '/x.gif' ],
-                       [ false, './x.gif' ],
-                       [ false, '../x.gif' ],
-               ];
-       }
-
-       /**
-        * @dataProvider provideIsRemoteUrl
-        * @cover CSSMin::isRemoteUrl
-        */
-       public function testIsRemoteUrl( $expect, $url ) {
-               $this->assertEquals( CSSMinTestable::isRemoteUrl( $url ), $expect );
-       }
-
-       public static function provideIsLocalUrls() {
-               return [
-                       [ false, 'x.gif' ],
-                       [ true, '/x.gif' ],
-                       [ false, './x.gif' ],
-                       [ false, '../x.gif' ],
-               ];
-       }
-
-       /**
-        * @dataProvider provideIsLocalUrls
-        * @cover CSSMin::isLocalUrl
-        */
-       public function testIsLocalUrl( $expect, $url ) {
-               $this->assertEquals( CSSMinTestable::isLocalUrl( $url ), $expect );
-       }
-
        public static function provideRemapRemappingCases() {
                // red.gif and green.gif are one-pixel 35-byte GIFs.
                // large.png is a 35K PNG that should be non-embeddable.
@@ -307,8 +307,8 @@ class CSSMinTest extends MediaWikiTestCase {
                        ],
                        [
                                'Remote URL (unnecessary quotes not preserved)',
-                               'foo { background: url("http://example.org/w/foo.png"); }',
-                               'foo { background: url(http://example.org/w/foo.png); }',
+                               'foo { background: url("http://example.org/w/unnecessary-quotes.png"); }',
+                               'foo { background: url(http://example.org/w/unnecessary-quotes.png); }',
                        ],
                        [
                                'Embedded file',
@@ -410,9 +410,39 @@ class CSSMinTest extends MediaWikiTestCase {
                                '@import url(http://doc.example.org/styles.css)',
                        ],
                        [
-                               '@import rule to URL (should we remap this?)',
-                               '@import url(//localhost/styles.css?query=yes)',
-                               '@import url(//localhost/styles.css?query=yes)',
+                               '@import rule to local file (should we remap this?)',
+                               '@import url(/styles.css)',
+                               '@import url(http://doc.example.org/styles.css)',
+                       ],
+                       [
+                               '@import rule to URL',
+                               '@import url(//localhost/styles.css?query=val)',
+                               '@import url(//localhost/styles.css?query=val)',
+                       ],
+                       [
+                               'Background URL (double quotes)',
+                               'foo { background: url("//localhost/styles.css?quoted=double") }',
+                               'foo { background: url(//localhost/styles.css?quoted=double) }',
+                       ],
+                       [
+                               'Background URL (single quotes)',
+                               'foo { background: url(\'//localhost/styles.css?quoted=single\') }',
+                               'foo { background: url(//localhost/styles.css?quoted=single) }',
+                       ],
+                       [
+                               'Background URL (containing parentheses; T60473)',
+                               'foo { background: url("//localhost/styles.css?query=(parens)") }',
+                               'foo { background: url("//localhost/styles.css?query=(parens)") }',
+                       ],
+                       [
+                               'Background URL (double quoted, containing single quotes; T60473)',
+                               'foo { background: url("//localhost/styles.css?quote=\'") }',
+                               'foo { background: url("//localhost/styles.css?quote=\'") }',
+                       ],
+                       [
+                               'Background URL (single quoted, containing double quotes; T60473)',
+                               'foo { background: url(\'//localhost/styles.css?quote="\') }',
+                               'foo { background: url("//localhost/styles.css?quote=\"") }',
                        ],
                        [
                                'Simple case with comments before url',
index 9d12b10..cfc2d91 100644 (file)
@@ -10,7 +10,6 @@ class DnsSrvDiscovererTest extends PHPUnit_Framework_TestCase {
                $record = $discoverer->pickServer( $params );
 
                $this->assertEquals( $expected, $record );
-
        }
 
        public static function provideRecords() {
index b0f40ef..abe0280 100644 (file)
@@ -54,7 +54,7 @@ class JpegTest extends MediaWikiMediaTestCase {
 
        /**
         * @dataProvider provideSwappingICCProfile
-        * @covers ExifBitmapHandler::swapICCProfile
+        * @covers JpegHandler::swapICCProfile
         */
        public function testSwappingICCProfile(
                $sourceFilename, $controlFilename, $newProfileFilename, $oldProfileName
index 6b911bf..556a348 100644 (file)
@@ -549,7 +549,11 @@ class WikiPageTest extends MediaWikiLangTestCase {
 
        public static function provideGetParserOutput() {
                return [
-                       [ CONTENT_MODEL_WIKITEXT, "hello ''world''\n", "<p>hello <i>world</i></p>" ],
+                       [
+                               CONTENT_MODEL_WIKITEXT,
+                               "hello ''world''\n",
+                               "<div class=\"mw-parser-output\"><p>hello <i>world</i></p></div>"
+                       ],
                        // @todo more...?
                ];
        }
@@ -566,7 +570,7 @@ class WikiPageTest extends MediaWikiLangTestCase {
                $text = $po->getText();
 
                $text = trim( preg_replace( '/<!--.*?-->/sm', '', $text ) ); # strip injected comments
-               $text = preg_replace( '!\s*(</p>)!sm', '\1', $text ); # don't let tidy confuse us
+               $text = preg_replace( '!\s*(</p>|</div>)!sm', '\1', $text ); # don't let tidy confuse us
 
                $this->assertEquals( $expectedHtml, $text );
 
index 12936ee..06fe272 100644 (file)
@@ -43,18 +43,25 @@ class TagHookTest extends MediaWikiTestCase {
                return [ [ "foo<bar" ], [ "foo>bar" ], [ "foo\nbar" ], [ "foo\rbar" ] ];
        }
 
+       private function getParserOptions() {
+               global $wgContLang;
+               $popt = ParserOptions::newFromUserAndLang( new User, $wgContLang );
+               $popt->setWrapOutputClass( false );
+               return $popt;
+       }
+
        /**
         * @dataProvider provideValidNames
         */
        public function testTagHooks( $tag ) {
-               global $wgParserConf, $wgContLang;
+               global $wgParserConf;
                $parser = new Parser( $wgParserConf );
 
                $parser->setHook( $tag, [ $this, 'tagCallback' ] );
                $parserOutput = $parser->parse(
                        "Foo<$tag>Bar</$tag>Baz",
                        Title::newFromText( 'Test' ),
-                       ParserOptions::newFromUserAndLang( new User, $wgContLang )
+                       $this->getParserOptions()
                );
                $this->assertEquals( "<p>FooOneBaz\n</p>", $parserOutput->getText() );
 
@@ -66,14 +73,14 @@ class TagHookTest extends MediaWikiTestCase {
         * @expectedException MWException
         */
        public function testBadTagHooks( $tag ) {
-               global $wgParserConf, $wgContLang;
+               global $wgParserConf;
                $parser = new Parser( $wgParserConf );
 
                $parser->setHook( $tag, [ $this, 'tagCallback' ] );
                $parser->parse(
                        "Foo<$tag>Bar</$tag>Baz",
                        Title::newFromText( 'Test' ),
-                       ParserOptions::newFromUserAndLang( new User, $wgContLang )
+                       $this->getParserOptions()
                );
                $this->fail( 'Exception not thrown.' );
        }
@@ -82,14 +89,14 @@ class TagHookTest extends MediaWikiTestCase {
         * @dataProvider provideValidNames
         */
        public function testFunctionTagHooks( $tag ) {
-               global $wgParserConf, $wgContLang;
+               global $wgParserConf;
                $parser = new Parser( $wgParserConf );
 
                $parser->setFunctionTagHook( $tag, [ $this, 'functionTagCallback' ], 0 );
                $parserOutput = $parser->parse(
                        "Foo<$tag>Bar</$tag>Baz",
                        Title::newFromText( 'Test' ),
-                       ParserOptions::newFromUserAndLang( new User, $wgContLang )
+                       $this->getParserOptions()
                );
                $this->assertEquals( "<p>FooOneBaz\n</p>", $parserOutput->getText() );
 
@@ -101,7 +108,7 @@ class TagHookTest extends MediaWikiTestCase {
         * @expectedException MWException
         */
        public function testBadFunctionTagHooks( $tag ) {
-               global $wgParserConf, $wgContLang;
+               global $wgParserConf;
                $parser = new Parser( $wgParserConf );
 
                $parser->setFunctionTagHook(
@@ -112,7 +119,7 @@ class TagHookTest extends MediaWikiTestCase {
                $parser->parse(
                        "Foo<$tag>Bar</$tag>Baz",
                        Title::newFromText( 'Test' ),
-                       ParserOptions::newFromUserAndLang( new User, $wgContLang )
+                       $this->getParserOptions()
                );
                $this->fail( 'Exception not thrown.' );
        }
index 4cf4071..78eec6a 100644 (file)
@@ -323,7 +323,6 @@ class ResourceLoaderWikiModuleTest extends ResourceLoaderTestCase {
                        $expected,
                        $module->getContent( $titleText )
                );
-
        }
 
        /**
index 6b12229..bb7508c 100644 (file)
@@ -51,7 +51,6 @@ class SearchIndexFieldTest extends MediaWikiTestCase {
                        }
                );
                $this->assertEquals( "test", $field1->merge( $field2 ) );
-
        }
 
 }
index 03e341a..b101857 100644 (file)
@@ -28,6 +28,20 @@ abstract class AbstractChangesListSpecialPageTestCase extends MediaWikiTestCase
                $wgGroupPermissions['patrollers'] = [
                        'patrol' => true,
                ];
+
+               // Deprecated
+               $this->setTemporaryHook(
+                       'ChangesListSpecialPageFilters',
+                       null
+               );
+
+               # setup the ChangesListSpecialPage (or subclass) object
+               $this->changesListSpecialPage = $this->getPage();
+               $context = $this->changesListSpecialPage->getContext();
+               $context = new DerivativeContext( $context );
+               $context->setUser( $this->getTestUser( [ 'patrollers' ] )->getUser() );
+               $this->changesListSpecialPage->setContext( $context );
+               $this->changesListSpecialPage->registerFilters();
        }
 
        protected function tearDown() {
@@ -44,13 +58,6 @@ abstract class AbstractChangesListSpecialPageTestCase extends MediaWikiTestCase
         * @dataProvider provideParseParameters
         */
        public function testParseParameters( $params, $expected ) {
-               $context = $this->changesListSpecialPage->getContext();
-               $context = new DerivativeContext( $context );
-               $context->setUser( $this->getTestUser( [ 'patrollers' ] )->getUser() );
-               $this->changesListSpecialPage->setContext( $context );
-
-               $this->changesListSpecialPage->registerFilters();
-
                $opts = new FormOptions();
                foreach ( $expected as $key => $value ) {
                        // Register it as null so sets aren't rejected.
@@ -73,4 +80,65 @@ abstract class AbstractChangesListSpecialPageTestCase extends MediaWikiTestCase
                        /** named= */ true
                );
        }
+
+       /**
+        * @dataProvider validateOptionsProvider
+        */
+       public function testValidateOptions( $optionsToSet, $expectedRedirect, $expectedRedirectOptions ) {
+               $redirectQuery = [];
+               $redirected = false;
+               $output = $this->getMockBuilder( OutputPage::class )
+                       ->disableProxyingToOriginalMethods()
+                       ->disableOriginalConstructor()
+                       ->getMock();
+               $output->method( 'redirect' )->willReturnCallback(
+                       function ( $url ) use ( &$redirectQuery, &$redirected ) {
+                               $urlParts = wfParseUrl( $url );
+                               $query = isset( $urlParts[ 'query' ] ) ? $urlParts[ 'query' ] : '';
+                               parse_str( $query, $redirectQuery );
+                               $redirected = true;
+                       }
+               );
+               $ctx = new RequestContext();
+
+               // Give users patrol permissions so we can test that.
+               $user = $this->getTestSysop()->getUser();
+               $ctx->setUser( $user );
+
+               // Disable this hook or it could break changeType
+               // depending on which other extensions are running.
+               $this->setTemporaryHook(
+                       'ChangesListSpecialPageStructuredFilters',
+                       null
+               );
+
+               $ctx->setOutput( $output );
+               $clsp = $this->changesListSpecialPage;
+               $clsp->setContext( $ctx );
+               $opts = $clsp->getDefaultOptions();
+
+               foreach ( $optionsToSet as $option => $value ) {
+                       $opts->setValue( $option, $value );
+               }
+
+               $clsp->validateOptions( $opts );
+
+               $this->assertEquals( $expectedRedirect, $redirected, 'redirection' );
+
+               if ( $expectedRedirect ) {
+                       if ( count( $expectedRedirectOptions ) > 0 ) {
+                               $expectedRedirectOptions += [
+                                       'title' => $clsp->getPageTitle()->getPrefixedText(),
+                               ];
+                       }
+
+                       $this->assertArrayEquals(
+                               $expectedRedirectOptions,
+                               $redirectQuery,
+                               /* $ordered= */ false,
+                               /* $named= */ true,
+                               'redirection query'
+                       );
+               }
+       }
 }
index 6028573..e2209eb 100644 (file)
@@ -15,23 +15,26 @@ use Wikimedia\TestingAccessWrapper;
  * @covers ChangesListSpecialPage
  */
 class ChangesListSpecialPageTest extends AbstractChangesListSpecialPageTestCase {
-       protected function setUp() {
-               parent::setUp();
-
-               # setup the rc object
-               $this->changesListSpecialPage = $this->getPage();
-       }
-
        protected function getPage() {
-               return TestingAccessWrapper::newFromObject(
-                       $this->getMockForAbstractClass(
-                               'ChangesListSpecialPage',
+               $mock = $this->getMockBuilder( ChangesListSpecialPage::class )
+                       ->setConstructorArgs(
                                [
                                        'ChangesListSpecialPage',
                                        ''
                                ]
                        )
+                       ->setMethods( [ 'getPageTitle' ] )
+                       ->getMockForAbstractClass();
+
+               $mock->method( 'getPageTitle' )->willReturn(
+                       Title::makeTitle( NS_SPECIAL, 'ChangesListSpecialPage' )
                );
+
+               $mock = TestingAccessWrapper::newFromObject(
+                       $mock
+               );
+
+               return $mock;
        }
 
        /** helper to test SpecialRecentchanges::buildMainQueryConds() */
@@ -48,6 +51,7 @@ class ChangesListSpecialPageTest extends AbstractChangesListSpecialPageTestCase
                }
 
                $this->changesListSpecialPage->setContext( $context );
+               $this->changesListSpecialPage->filterGroups = [];
                $formOptions = $this->changesListSpecialPage->setup( null );
 
                #  Filter out rc_timestamp conditions which depends on the test runtime
@@ -132,7 +136,7 @@ class ChangesListSpecialPageTest extends AbstractChangesListSpecialPageTestCase
                                "rc_namespace IN ('1','2','3')",
                        ],
                        [
-                               'namespace' => '1,2,3',
+                               'namespace' => '1;2;3',
                        ],
                        "rc conditions with multiple namespaces"
                );
@@ -144,7 +148,7 @@ class ChangesListSpecialPageTest extends AbstractChangesListSpecialPageTestCase
                                "rc_namespace IN ('0','1','4','5','6','7')",
                        ],
                        [
-                               'namespace' => '1,4,7',
+                               'namespace' => '1;4;7',
                                'associated' => 1,
                        ],
                        "rc conditions with multiple namespaces and associated"
@@ -157,7 +161,7 @@ class ChangesListSpecialPageTest extends AbstractChangesListSpecialPageTestCase
                                "rc_namespace NOT IN ('2','3','8','9')",
                        ],
                        [
-                               'namespace' => '2,3,9',
+                               'namespace' => '2;3;9',
                                'associated' => 1,
                                'invert' => 1
                        ],
@@ -171,7 +175,7 @@ class ChangesListSpecialPageTest extends AbstractChangesListSpecialPageTestCase
                                "rc_namespace NOT IN ('1','2','3')",
                        ],
                        [
-                               'namespace' => '1,2,3',
+                               'namespace' => '1;2;3',
                                'invert' => 1,
                        ],
                        "rc conditions with multiple namespaces inverted"
@@ -230,22 +234,6 @@ class ChangesListSpecialPageTest extends AbstractChangesListSpecialPageTestCase
                );
        }
 
-       public function testRcHidemyselfHidebyothersFilter() {
-               $user = $this->getTestUser()->getUser();
-               $this->assertConditions(
-                       [ # expected
-                               "rc_user_text != '{$user->getName()}'",
-                               "rc_user_text = '{$user->getName()}'",
-                       ],
-                       [
-                               'hidemyself' => 1,
-                               'hidebyothers' => 1,
-                       ],
-                       "rc conditions: hidemyself=1 hidebyothers=1 (logged in)",
-                       $user
-               );
-       }
-
        public function testRcHidepageedits() {
                $this->assertConditions(
                        [ # expected
@@ -372,22 +360,6 @@ class ChangesListSpecialPageTest extends AbstractChangesListSpecialPageTestCase
                );
        }
 
-       public function testRcHidepatrolledHideunpatrolledFilter() {
-               $user = $this->getTestSysop()->getUser();
-               $this->assertConditions(
-                       [ # expected
-                               "rc_patrolled = 0",
-                               "rc_patrolled = 1",
-                       ],
-                       [
-                               'hidepatrolled' => 1,
-                               'hideunpatrolled' => 1,
-                       ],
-                       "rc conditions: hidepatrolled=1 hideunpatrolled=1",
-                       $user
-               );
-       }
-
        public function testHideCategorization() {
                $this->assertConditions(
                        [
@@ -576,6 +548,8 @@ class ChangesListSpecialPageTest extends AbstractChangesListSpecialPageTestCase
        }
 
        public function testGetStructuredFilterJsData() {
+               $this->changesListSpecialPage->filterGroups = [];
+
                $definition = [
                        [
                                'name' => 'gub-group',
@@ -893,4 +867,47 @@ class ChangesListSpecialPageTest extends AbstractChangesListSpecialPageTestCase
                        $this->changesListSpecialPage->areFiltersInConflict()
                );
        }
+
+       public function validateOptionsProvider() {
+               return [
+                       [
+                               [ 'hideanons' => 1, 'hideliu' => 1, 'hidebots' => 1 ],
+                               true,
+                               [ 'hideliu' => 1, 'hidebots' => 1, ],
+                       ],
+
+                       [
+                               [ 'hideanons' => 1, 'hideliu' => 1, 'hidebots' => 0 ],
+                               true,
+                               [ 'hidebots' => 0, 'hidehumans' => 1 ],
+                       ],
+
+                       [
+                               [ 'hidemyself' => 1, 'hidebyothers' => 1 ],
+                               true,
+                               [],
+                       ],
+                       [
+                               [ 'hidebots' => 1, 'hidehumans' => 1 ],
+                               true,
+                               [],
+                       ],
+                       [
+                               [ 'hidepatrolled' => 1, 'hideunpatrolled' => 1 ],
+                               true,
+                               [],
+                       ],
+                       [
+                               [ 'hideminor' => 1, 'hidemajor' => 1 ],
+                               true,
+                               [],
+                       ],
+                       [
+                               // changeType
+                               [ 'hidepageedits' => 1, 'hidenewpages' => 1, 'hidecategorization' => 1, 'hidelog' => 1, ],
+                               true,
+                               [],
+                       ],
+               ];
+       }
 }
index e9c7d4b..85becff 100644 (file)
@@ -10,15 +10,15 @@ use Wikimedia\TestingAccessWrapper;
  * @covers SpecialRecentChanges
  */
 class SpecialRecentchangesTest extends AbstractChangesListSpecialPageTestCase {
-       protected function setUp() {
-               parent::setUp();
-
-               # setup the CLSP object
-               $this->changesListSpecialPage = TestingAccessWrapper::newFromObject(
+       protected function getPage() {
+               return TestingAccessWrapper::newFromObject(
                        new SpecialRecentchanges
                );
        }
 
+       // Below providers should only be for features specific to
+       // RecentChanges.  Otherwise, it should go in ChangesListSpecialPageTest
+
        public function provideParseParameters() {
                return [
                        [ 'limit=123', [ 'limit' => '123' ] ],
@@ -27,9 +27,24 @@ class SpecialRecentchangesTest extends AbstractChangesListSpecialPageTestCase {
 
                        [ 'days=3', [ 'days' => '3' ] ],
 
-                       [ 'namespace=5', [ 'namespace' => 5 ] ],
+                       [ 'namespace=5', [ 'namespace' => '5' ] ],
+
+                       [ 'namespace=5|3', [ 'namespace' => '5|3' ] ],
 
                        [ 'tagfilter=foo', [ 'tagfilter' => 'foo' ] ],
+
+                       [ 'tagfilter=foo;bar', [ 'tagfilter' => 'foo;bar' ] ],
+               ];
+       }
+
+       public function validateOptionsProvider() {
+               return [
+                       [
+                               // hidebots=1 is default for Special:RecentChanges
+                               [ 'hideanons' => 1, 'hideliu' => 1 ],
+                               true,
+                               [ 'hideliu' => 1 ],
+                       ],
                ];
        }
 }
index 7f9f25f..b0490ec 100644 (file)
@@ -43,7 +43,6 @@ class SpecialWatchlistTest extends SpecialPageTestBase {
                                'watchlistreloadautomatically' => 0,
                        ]
                );
-
        }
 
        /**
index 27d3825..bc266fb 100644 (file)
                                hidefilter6: 0,
                                group3: ''
                        },
-                       'One filters in one "send_unselected_if_any" group returns the other parameters truthy.'
+                       'Two filters in one "send_unselected_if_any" group returns the other parameters truthy.'
                );
 
                // Select 3 filters
 
        } );
 
+       QUnit.test( 'getParametersFromFilters (custom object)', function ( assert ) {
+               var originalState,
+                       model = new mw.rcfilters.dm.FiltersViewModel(),
+                       definition = [ {
+                               name: 'group1',
+                               title: 'Group 1',
+                               type: 'send_unselected_if_any',
+                               filters: [
+                                       { name: 'hidefilter1', label: 'Hide filter 1', description: '' },
+                                       { name: 'hidefilter2', label: 'Hide filter 2', description: '' },
+                                       { name: 'hidefilter3', label: 'Hide filter 3', description: '' }
+                               ]
+                       }, {
+                               name: 'group2',
+                               title: 'Group 2',
+                               type: 'send_unselected_if_any',
+                               filters: [
+                                       { name: 'hidefilter4', label: 'Hide filter 4', description: '' },
+                                       { name: 'hidefilter5', label: 'Hide filter 5', description: '' },
+                                       { name: 'hidefilter6', label: 'Hide filter 6', description: '' }
+                               ]
+                       }, {
+                               name: 'group3',
+                               title: 'Group 3',
+                               type: 'string_options',
+                               separator: ',',
+                               filters: [
+                                       { name: 'filter7', label: 'Hide filter 7', description: '' },
+                                       { name: 'filter8', label: 'Hide filter 8', description: '' },
+                                       { name: 'filter9', label: 'Hide filter 9', description: '' }
+                               ]
+                       } ],
+                       cases = [
+                               {
+                                       // This is mocking the cases above, both
+                                       // - 'Two filters in one "send_unselected_if_any" group returns the other parameters truthy.'
+                                       // - 'Two filters selected in "string_option" group returns those filters in the value.'
+                                       input: {
+                                               group1__hidefilter1: true,
+                                               group1__hidefilter2: true,
+                                               group1__hidefilter3: false,
+                                               group2__hidefilter4: false,
+                                               group2__hidefilter5: false,
+                                               group2__hidefilter6: false,
+                                               group3__filter7: true,
+                                               group3__filter8: true,
+                                               group3__filter9: false
+                                       },
+                                       expected: {
+                                               // Group 1 (two selected, the others are true)
+                                               hidefilter1: 0,
+                                               hidefilter2: 0,
+                                               hidefilter3: 1,
+                                               // Group 2 (nothing is selected, all false)
+                                               hidefilter4: 0,
+                                               hidefilter5: 0,
+                                               hidefilter6: 0,
+                                               group3: 'filter7,filter8'
+                                       },
+                                       msg: 'Given an explicit (complete) filter state object, the result is the same as if the object given represented the model state.'
+                               },
+                               {
+                                       // This is mocking case above
+                                       // - 'One filters in one "send_unselected_if_any" group returns the other parameters truthy.'
+                                       input: {
+                                               group1__hidefilter1: 1
+                                       },
+                                       expected: {
+                                               // Group 1 (one selected, the others are true)
+                                               hidefilter1: 0,
+                                               hidefilter2: 1,
+                                               hidefilter3: 1,
+                                               // Group 2 (nothing is selected, all false)
+                                               hidefilter4: 0,
+                                               hidefilter5: 0,
+                                               hidefilter6: 0,
+                                               group3: ''
+                                       },
+                                       msg: 'Given an explicit (incomplete) filter state object, the result is the same as if the object give represented the model state.'
+                               }
+                       ];
+
+               model.initializeFilters( definition );
+               // Store original state
+               originalState = model.getSelectedState();
+
+               // Test each case
+               cases.forEach( function ( test ) {
+                       assert.deepEqual(
+                               model.getParametersFromFilters( test.input ),
+                               test.expected,
+                               test.msg
+                       );
+               } );
+
+               // After doing the above tests, make sure the actual state
+               // of the filter stayed the same
+               assert.deepEqual(
+                       model.getSelectedState(),
+                       originalState,
+                       'Running the method with external definition to parse does not actually change the state of the model'
+               );
+       } );
+
        QUnit.test( 'getFiltersFromParameters', function ( assert ) {
                var definition = [ {
                                name: 'group1',
                );
        } );
 
-       QUnit.test( 'setFiltersToDefaults', function ( assert ) {
-               var definition = [ {
-                               name: 'group1',
-                               title: 'Group 1',
-                               type: 'send_unselected_if_any',
-                               filters: [
-                                       {
-                                               name: 'hidefilter1',
-                                               label: 'Show filter 1',
-                                               description: 'Description of Filter 1 in Group 1',
-                                               default: true
-                                       },
-                                       {
-                                               name: 'hidefilter2',
-                                               label: 'Show filter 2',
-                                               description: 'Description of Filter 2 in Group 1'
-                                       },
-                                       {
-                                               name: 'hidefilter3',
-                                               label: 'Show filter 3',
-                                               description: 'Description of Filter 3 in Group 1',
-                                               default: true
-                                       }
-                               ]
-                       }, {
-                               name: 'group2',
-                               title: 'Group 2',
-                               type: 'send_unselected_if_any',
-                               filters: [
-                                       {
-                                               name: 'hidefilter4',
-                                               label: 'Show filter 4',
-                                               description: 'Description of Filter 1 in Group 2'
-                                       },
-                                       {
-                                               name: 'hidefilter5',
-                                               label: 'Show filter 5',
-                                               description: 'Description of Filter 2 in Group 2',
-                                               default: true
-                                       },
-                                       {
-                                               name: 'hidefilter6',
-                                               label: 'Show filter 6',
-                                               description: 'Description of Filter 3 in Group 2'
-                                       }
-                               ]
-                       } ],
-                       defaultFilterRepresentation = {
-                               // Group 1 and 2, "send_unselected_if_any", the values of the filters are "flipped" from the values of the parameters
-                               group1__hidefilter1: false,
-                               group1__hidefilter2: true,
-                               group1__hidefilter3: false,
-                               group2__hidefilter4: true,
-                               group2__hidefilter5: false,
-                               group2__hidefilter6: true
-                       },
-                       model = new mw.rcfilters.dm.FiltersViewModel();
-
-               model.initializeFilters( definition );
-
-               assert.deepEqual(
-                       model.getSelectedState(),
-                       {
-                               group1__hidefilter1: false,
-                               group1__hidefilter2: false,
-                               group1__hidefilter3: false,
-                               group2__hidefilter4: false,
-                               group2__hidefilter5: false,
-                               group2__hidefilter6: false
-                       },
-                       'Initial state: default filters are not selected (controller selects defaults explicitly).'
-               );
-
-               model.toggleFiltersSelected( {
-                       group1__hidefilter1: false,
-                       group1__hidefilter3: false
-               } );
-
-               model.setFiltersToDefaults();
-
-               assert.deepEqual(
-                       model.getSelectedState(),
-                       defaultFilterRepresentation,
-                       'Changing values of filters and then returning to defaults still results in default filters being selected.'
-               );
-       } );
-
        QUnit.test( 'Filter interaction: subsets', function ( assert ) {
                var definition = [ {
                                name: 'group1',
index 7a0de81..06ea9bc 100644 (file)
                function isCssImportApplied() {
                        // Trigger reflow, repaint, redraw, whatever (cross-browser)
                        $element.css( 'height' );
+                       // eslint-disable-next-line no-unused-expressions
                        el.innerHTML;
                        el.className = el.className;
+                       // eslint-disable-next-line no-unused-expressions
                        document.documentElement.clientHeight;
 
                        return $element.css( prop ) === val;
index b2d0bdd..d64ada9 100644 (file)
@@ -5,6 +5,9 @@
                "mocha": true,
                "node": true
        },
+       "parserOptions": {
+               "ecmaVersion": 6
+       },
        "globals": {
                "browser": false
        }