Merge "mediawiki.skinning: Add magnify links to Parsoid output"
authorjenkins-bot <jenkins-bot@gerrit.wikimedia.org>
Wed, 9 Aug 2017 16:29:44 +0000 (16:29 +0000)
committerGerrit Code Review <gerrit@wikimedia.org>
Wed, 9 Aug 2017 16:29:45 +0000 (16:29 +0000)
213 files changed:
.gitignore
.mailmap
CREDITS
Gruntfile.js
RELEASE-NOTES-1.30
autoload.php
composer.json
docs/database.txt
includes/Block.php
includes/ConfiguredReadOnlyMode.php [new file with mode: 0644]
includes/DefaultSettings.php
includes/EditPage.php
includes/Linker.php
includes/ListToggle.php
includes/Preferences.php
includes/ReadOnlyMode.php
includes/Sanitizer.php
includes/Setup.php
includes/Title.php
includes/TrackingCategories.php
includes/actions/InfoAction.php
includes/api/ApiBase.php
includes/api/ApiMain.php
includes/api/ApiQueryLinks.php
includes/api/i18n/ko.json
includes/api/i18n/nb.json
includes/api/i18n/ru.json
includes/deferred/WANCacheReapUpdate.php
includes/htmlform/HTMLForm.php
includes/htmlform/HTMLFormField.php
includes/htmlform/OOUIHTMLForm.php
includes/htmlform/fields/HTMLCheckField.php
includes/htmlform/fields/HTMLFormFieldCloner.php
includes/htmlform/fields/HTMLMultiSelectField.php
includes/htmlform/fields/HTMLRadioField.php
includes/htmlform/fields/HTMLTextAreaField.php
includes/htmlform/fields/HTMLTextField.php
includes/installer/DatabaseUpdater.php
includes/installer/i18n/pt.json
includes/jobqueue/JobRunner.php
includes/libs/StatusValue.php
includes/libs/rdbms/database/DatabaseMysqli.php
includes/libs/rdbms/database/DatabaseSqlite.php
includes/page/Article.php
includes/page/ImagePage.php
includes/parser/Parser.php
includes/resourceloader/ResourceLoader.php
includes/resourceloader/ResourceLoaderMediaWikiUtilModule.php [new file with mode: 0644]
includes/resourceloader/ResourceLoaderModule.php
includes/skins/BaseTemplate.php
includes/skins/Skin.php
includes/specialpage/LoginSignupSpecialPage.php
includes/specials/SpecialBrokenRedirects.php
includes/specials/SpecialContributions.php
includes/specials/SpecialDoubleRedirects.php
includes/specials/SpecialImport.php
includes/specials/SpecialListgrants.php
includes/specials/SpecialListgrouprights.php
includes/specials/SpecialListredirects.php
includes/specials/SpecialRecentchanges.php
includes/specials/SpecialSearch.php
includes/specials/SpecialUncategorizedcategories.php
includes/specials/SpecialUndelete.php
includes/specials/SpecialVersion.php
includes/specials/SpecialWatchlist.php
includes/specials/pagers/AllMessagesTablePager.php
includes/specials/pagers/ContribsPager.php
jsduck.json
languages/Language.php
languages/i18n/ar.json
languages/i18n/ast.json
languages/i18n/awa.json
languages/i18n/azb.json
languages/i18n/ba.json
languages/i18n/be-tarask.json
languages/i18n/bho.json
languages/i18n/bn.json
languages/i18n/bs.json
languages/i18n/ca.json
languages/i18n/ce.json
languages/i18n/cs.json
languages/i18n/cv.json
languages/i18n/de.json
languages/i18n/en.json
languages/i18n/es.json
languages/i18n/fa.json
languages/i18n/fi.json
languages/i18n/fr.json
languages/i18n/gl.json
languages/i18n/ha.json
languages/i18n/he.json
languages/i18n/hi.json
languages/i18n/hr.json
languages/i18n/hu.json
languages/i18n/it.json
languages/i18n/ja.json
languages/i18n/jam.json
languages/i18n/jv.json
languages/i18n/kab.json
languages/i18n/ko.json
languages/i18n/lb.json
languages/i18n/li.json
languages/i18n/lv.json
languages/i18n/mk.json
languages/i18n/ml.json
languages/i18n/mwl.json
languages/i18n/nb.json
languages/i18n/ne.json
languages/i18n/nl.json
languages/i18n/nn.json
languages/i18n/pl.json
languages/i18n/pt-br.json
languages/i18n/pt.json
languages/i18n/qqq.json
languages/i18n/roa-tara.json
languages/i18n/ru.json
languages/i18n/shi.json
languages/i18n/skr-arab.json
languages/i18n/sl.json
languages/i18n/sq.json
languages/i18n/sr-ec.json
languages/i18n/sr-el.json
languages/i18n/sv.json
languages/i18n/te.json
languages/i18n/th.json
languages/i18n/tr.json
languages/i18n/tt-cyrl.json
languages/i18n/vro.json
languages/i18n/yi.json
languages/i18n/zh-hans.json
maintenance/rebuildrecentchanges.php
profileinfo.php
resources/Resources.php
resources/lib/oojs-ui/i18n/as.json
resources/lib/oojs-ui/i18n/bs.json
resources/lib/oojs-ui/i18n/pt-br.json
resources/lib/oojs-ui/oojs-ui-apex.js
resources/lib/oojs-ui/oojs-ui-core-apex.css
resources/lib/oojs-ui/oojs-ui-core-wikimediaui.css
resources/lib/oojs-ui/oojs-ui-core.js
resources/lib/oojs-ui/oojs-ui-core.js.map
resources/lib/oojs-ui/oojs-ui-toolbars-apex.css
resources/lib/oojs-ui/oojs-ui-toolbars-wikimediaui.css
resources/lib/oojs-ui/oojs-ui-toolbars.js
resources/lib/oojs-ui/oojs-ui-widgets-apex.css
resources/lib/oojs-ui/oojs-ui-widgets-wikimediaui.css
resources/lib/oojs-ui/oojs-ui-widgets.js
resources/lib/oojs-ui/oojs-ui-widgets.js.map
resources/lib/oojs-ui/oojs-ui-wikimediaui.js
resources/lib/oojs-ui/oojs-ui-windows-apex.css
resources/lib/oojs-ui/oojs-ui-windows-wikimediaui.css
resources/lib/oojs-ui/oojs-ui-windows.js
resources/lib/oojs-ui/themes/apex/icons-media.json
resources/lib/oojs-ui/themes/apex/images/icons/play-ltr.png [new file with mode: 0644]
resources/lib/oojs-ui/themes/apex/images/icons/play-ltr.svg [new file with mode: 0644]
resources/lib/oojs-ui/themes/apex/images/icons/play-rtl.png [new file with mode: 0644]
resources/lib/oojs-ui/themes/apex/images/icons/play-rtl.svg [new file with mode: 0644]
resources/lib/oojs-ui/themes/wikimediaui/images/icons/play-ltr-invert.png
resources/lib/oojs-ui/themes/wikimediaui/images/icons/play-ltr-invert.svg
resources/lib/oojs-ui/themes/wikimediaui/images/icons/play-ltr-progressive.png
resources/lib/oojs-ui/themes/wikimediaui/images/icons/play-ltr-progressive.svg
resources/lib/oojs-ui/themes/wikimediaui/images/icons/play-ltr.png
resources/lib/oojs-ui/themes/wikimediaui/images/icons/play-ltr.svg
resources/lib/oojs-ui/themes/wikimediaui/images/icons/play-rtl-invert.png
resources/lib/oojs-ui/themes/wikimediaui/images/icons/play-rtl-invert.svg
resources/lib/oojs-ui/themes/wikimediaui/images/icons/play-rtl-progressive.png
resources/lib/oojs-ui/themes/wikimediaui/images/icons/play-rtl-progressive.svg
resources/lib/oojs-ui/themes/wikimediaui/images/icons/play-rtl.png
resources/lib/oojs-ui/themes/wikimediaui/images/icons/play-rtl.svg
resources/lib/oojs-ui/themes/wikimediaui/images/icons/stop-invert.png
resources/lib/oojs-ui/themes/wikimediaui/images/icons/stop-invert.svg
resources/lib/oojs-ui/themes/wikimediaui/images/icons/stop-progressive.png
resources/lib/oojs-ui/themes/wikimediaui/images/icons/stop-progressive.svg
resources/lib/oojs-ui/themes/wikimediaui/images/icons/stop.png
resources/lib/oojs-ui/themes/wikimediaui/images/icons/stop.svg
resources/src/mediawiki.action/mediawiki.action.edit.js
resources/src/mediawiki.action/mediawiki.action.edit.preview.js
resources/src/mediawiki.less/mediawiki.ui/variables.less
resources/src/mediawiki.rcfilters/dm/mw.rcfilters.dm.ChangesListViewModel.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/mw.rcfilters.Controller.js
resources/src/mediawiki.rcfilters/mw.rcfilters.UriProcessor.js
resources/src/mediawiki.rcfilters/mw.rcfilters.js
resources/src/mediawiki.rcfilters/styles/mw.rcfilters.less
resources/src/mediawiki.rcfilters/styles/mw.rcfilters.mixins.less
resources/src/mediawiki.rcfilters/styles/mw.rcfilters.ui.ChangesLimitPopupWidget.less [new file with mode: 0644]
resources/src/mediawiki.rcfilters/styles/mw.rcfilters.ui.FilterTagMultiselectWidget.less
resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.ChangesLimitButtonWidget.js
resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.ChangesLimitPopupWidget.js
resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.ChangesListWrapperWidget.js
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.FormWrapperWidget.js
resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.LiveUpdateButtonWidget.js
resources/src/mediawiki.skinning/interface.css
resources/src/mediawiki.special/mediawiki.special.preferences.styles.css
resources/src/mediawiki.widgets.visibleByteLimit/mediawiki.widgets.visibleByteLimit.js
resources/src/mediawiki/mediawiki.checkboxtoggle.js
resources/src/mediawiki/mediawiki.util.js
resources/src/oojs-ui-local.css
tests/parser/ParserTestRunner.php
tests/parser/parserTests.txt
tests/phpunit/MediaWikiTestCase.php
tests/phpunit/includes/RevisionStorageTest.php
tests/phpunit/includes/SanitizerTest.php
tests/phpunit/includes/WatchedItemQueryServiceUnitTest.php
tests/phpunit/includes/WatchedItemStoreUnitTest.php
tests/phpunit/includes/db/LBFactoryTest.php
tests/phpunit/includes/page/WikiPageTest.php
tests/phpunit/includes/resourceloader/ResourceLoaderModuleTest.php
tests/phpunit/includes/resourceloader/ResourceLoaderTest.php
tests/qunit/suites/resources/mediawiki/mediawiki.util.test.js

index a82ae21..3e97aab 100644 (file)
@@ -48,7 +48,6 @@ node_modules/
 # Composer
 /vendor
 /composer.lock
-/composer.json
 /composer.local.json
 
 # MediaWiki UI documentation
index 2134fc5..5a76fb9 100644 (file)
--- a/.mailmap
+++ b/.mailmap
@@ -63,6 +63,7 @@ aude <aude.wiki@gmail.com>
 Audrey Tang <audreyt@audreyt.org>
 Audrey Tang <audreyt@audreyt.org> <au@localhost>
 ayush_garg <ayush.ce13@iitp.ac.in>
+Bae Junehyeon <devunt@gmail.com>
 Bahodir Mansurov <bmansurov@wikimedia.org>
 Bartosz Dziewoński <matma.rex@gmail.com>
 Bartosz Dziewoński <matma.rex@gmail.com> <bdziewonski@wikimedia.org>
@@ -227,7 +228,6 @@ Jon Robson <jrobson@wikimedia.org>
 Jon Robson <jrobson@wikimedia.org> <jdlrobson@gmail.com>
 Juliusz Gonera <jgonera@gmail.com>
 Juliusz Gonera <jgonera@gmail.com> <jgonera@wikimedia.org>
-JuneHyeon Bae <devunt@gmail.com>
 Jure Kajzer <freak@drajv.si>
 Jure Kajzer <freak@drajv.si> <freakolowsky@users.mediawiki.org>
 Justin Du <justin.d128@gmail.com>
diff --git a/CREDITS b/CREDITS
index 14c454e..c38c3fc 100644 (file)
--- a/CREDITS
+++ b/CREDITS
@@ -78,6 +78,7 @@ The following list can be found parsed under Special:Version/Credits -->
 * awu42
 * ayush_garg
 * Azliq7
+* Bae Junehyeon
 * Bagariavivek
 * Bahodir Mansurov
 * balloonguy
@@ -312,7 +313,6 @@ The following list can be found parsed under Special:Version/Credits -->
 * Julian Ostrow
 * Juliano F. Ravasi
 * Juliusz Gonera
-* JuneHyeon Bae
 * Jure Kajzer
 * Justin Du
 * Kai Nissen
index 811d2c0..dbbfcb8 100644 (file)
@@ -44,8 +44,6 @@ module.exports = function ( grunt ) {
                                '!extensions/**/*.js',
                                '!skins/**/*.js',
                                // Skip functions aren't even parseable
-                               '!resources/src/dom-level2-skip.js',
-                               '!resources/src/es5-skip.js',
                                '!resources/src/mediawiki.hidpi-skip.js'
                        ]
                },
index c5ab81a..452cb35 100644 (file)
@@ -26,6 +26,13 @@ section).
   array. This allows dependency injection to be used for ResourceLoader modules.
 * $wgExceptionHooks has been removed.
 * (T45547) $wgUsePigLatinVariant added (off by default).
+* (T152540) MediaWiki now supports a section ID escaping style that allows to display
+  non-Latin characters verbatim on many modern browsers. This is controlled by the
+  new configuration setting, $wgFragmentMode.
+* $wgExperimentalHtmlIds is now deprecated and will be removed in a future version,
+  use $wgFragmentMode to migrate off it to a modern alternative.
+* $wgExternalInterwikiFragmentMode was introduced to control how fragments in
+  sinterwikis going outside of current wiki farm are encoded.
 
 === New features in 1.30 ===
 * (T37247) Output from Parser::parse() will now be wrapped in a div with
@@ -143,6 +150,14 @@ changes to languages because of Phabricator reports.
   MediaWikiServices instead. Access to the underlying BagOStuff is possible
   through the new ParserCache::getCacheStorage() method.
 * .mw-ui-constructive CSS class (deprecated in 1.27) was removed.
+* Sanitizer::escapeId() was deprecated, use escapeIdForAttribute(),
+  escapeIdForLink() or escapeIdForExternalInterwiki() instead.
+* Title::escapeFragmentForURL() was deprecated, use one of the aforementioned
+  Sanitizer functions or, if possible, Title::getFragmentForURL().
+* Second parameter to Sanitizer::escapeIdReferenceList() ($options) now does
+  nothing and is deprecated.
+* mw.util.escapeId() was deprecated, use escapeIdForAttribute() or
+  escapeIdForLink().
 
 == Compatibility ==
 MediaWiki 1.30 requires PHP 5.5.9 or later. There is experimental support for
index 2bf1d4c..508e75b 100644 (file)
@@ -291,7 +291,7 @@ $wgAutoloadLocalClasses = [
        'Config' => __DIR__ . '/includes/config/Config.php',
        'ConfigException' => __DIR__ . '/includes/config/ConfigException.php',
        'ConfigFactory' => __DIR__ . '/includes/config/ConfigFactory.php',
-       'ConfiguredReadOnlyMode' => __DIR__ . '/includes/ReadOnlyMode.php',
+       'ConfiguredReadOnlyMode' => __DIR__ . '/includes/ConfiguredReadOnlyMode.php',
        'ConstantDependency' => __DIR__ . '/includes/cache/CacheDependency.php',
        'Content' => __DIR__ . '/includes/content/Content.php',
        'ContentHandler' => __DIR__ . '/includes/content/ContentHandler.php',
@@ -1231,6 +1231,7 @@ $wgAutoloadLocalClasses = [
        'ResourceLoaderJqueryMsgModule' => __DIR__ . '/includes/resourceloader/ResourceLoaderJqueryMsgModule.php',
        'ResourceLoaderLanguageDataModule' => __DIR__ . '/includes/resourceloader/ResourceLoaderLanguageDataModule.php',
        'ResourceLoaderLanguageNamesModule' => __DIR__ . '/includes/resourceloader/ResourceLoaderLanguageNamesModule.php',
+       'ResourceLoaderMediaWikiUtilModule' => __DIR__ . '/includes/resourceloader/ResourceLoaderMediaWikiUtilModule.php',
        'ResourceLoaderModule' => __DIR__ . '/includes/resourceloader/ResourceLoaderModule.php',
        'ResourceLoaderOOUIFileModule' => __DIR__ . '/includes/resourceloader/ResourceLoaderOOUIFileModule.php',
        'ResourceLoaderOOUIImageModule' => __DIR__ . '/includes/resourceloader/ResourceLoaderOOUIImageModule.php',
index aefc158..bc48360 100644 (file)
@@ -25,7 +25,7 @@
                "ext-xml": "*",
                "liuggio/statsd-php-client": "1.0.18",
                "mediawiki/at-ease": "1.1.0",
-               "oojs/oojs-ui": "0.22.3",
+               "oojs/oojs-ui": "0.22.4",
                "oyejorge/less.php": "1.7.0.14",
                "php": ">=5.5.9",
                "psr/log": "1.0.2",
index 44ec764..dbc9204 100644 (file)
@@ -17,7 +17,7 @@ description of the tables and their contents, please see:
 
 To make a read query, something like this usually suffices:
 
-$dbr = wfGetDB( DB_SLAVE );
+$dbr = wfGetDB( DB_REPLICA );
 $res = $dbr->select( /* ...see docs... */ );
 foreach ( $res as $row ) {
        ...
index 2a04879..8fc2686 100644 (file)
@@ -44,40 +44,40 @@ class Block {
        public $mParentBlockId;
 
        /** @var int */
-       protected $mId;
+       private $mId;
 
        /** @var bool */
-       protected $mFromMaster;
+       private $mFromMaster;
 
        /** @var bool */
-       protected $mBlockEmail;
+       private $mBlockEmail;
 
        /** @var bool */
-       protected $mDisableUsertalk;
+       private $mDisableUsertalk;
 
        /** @var bool */
-       protected $mCreateAccount;
+       private $mCreateAccount;
 
        /** @var User|string */
-       protected $target;
+       private $target;
 
        /** @var int Hack for foreign blocking (CentralAuth) */
-       protected $forcedTargetID;
+       private $forcedTargetID;
 
        /** @var int Block::TYPE_ constant. Can only be USER, IP or RANGE internally */
-       protected $type;
+       private $type;
 
        /** @var User */
-       protected $blocker;
+       private $blocker;
 
        /** @var bool */
-       protected $isHardblock;
+       private $isHardblock;
 
        /** @var bool */
-       protected $isAutoblocking;
+       private $isAutoblocking;
 
        /** @var string|null */
-       protected $systemBlockType;
+       private $systemBlockType;
 
        # TYPE constants
        const TYPE_USER = 1;
@@ -958,6 +958,7 @@ class Block {
 
        /**
         * Get the system block type, if any
+        * @since 1.29
         * @return string|null
         */
        public function getSystemBlockType() {
@@ -1450,6 +1451,8 @@ class Block {
         * Set the 'BlockID' cookie to this block's ID and expiry time. The cookie's expiry will be
         * the same as the block's, to a maximum of 24 hours.
         *
+        * @since 1.29
+        *
         * @param WebResponse $response The response on which to set the cookie.
         */
        public function setCookie( WebResponse $response ) {
@@ -1472,6 +1475,8 @@ class Block {
        /**
         * Unset the 'BlockID' cookie.
         *
+        * @since 1.29
+        *
         * @param WebResponse $response The response on which to unset the cookie.
         */
        public static function clearCookie( WebResponse $response ) {
@@ -1482,6 +1487,9 @@ class Block {
         * Get the BlockID cookie's value for this block. This is usually the block ID concatenated
         * with an HMAC in order to avoid spoofing (T152951), but if wgSecretKey is not set will just
         * be the block ID.
+        *
+        * @since 1.29
+        *
         * @return string The block ID, probably concatenated with "!" and the HMAC.
         */
        public function getCookieValue() {
@@ -1500,7 +1508,11 @@ class Block {
        /**
         * Get the stored ID from the 'BlockID' cookie. The cookie's value is usually a combination of
         * the ID and a HMAC (see Block::setCookie), but will sometimes only be the ID.
+        *
+        * @since 1.29
+        *
         * @param string $cookieValue The string in which to find the ID.
+        *
         * @return integer|null The block ID, or null if the HMAC is present and invalid.
         */
        public static function getIdFromCookieValue( $cookieValue ) {
diff --git a/includes/ConfiguredReadOnlyMode.php b/includes/ConfiguredReadOnlyMode.php
new file mode 100644 (file)
index 0000000..af7c7cb
--- /dev/null
@@ -0,0 +1,73 @@
+<?php
+
+/**
+ * A read-only mode service which does not depend on LoadBalancer.
+ * To obtain an instance, use MediaWikiServices::getConfiguredReadOnlyMode().
+ *
+ * @since 1.29
+ */
+class ConfiguredReadOnlyMode {
+       /** @var Config */
+       private $config;
+
+       /** @var string|bool|null */
+       private $fileReason;
+
+       /** @var string|null */
+       private $overrideReason;
+
+       public function __construct( Config $config ) {
+               $this->config = $config;
+       }
+
+       /**
+        * Check whether the wiki is in read-only mode.
+        *
+        * @return bool
+        */
+       public function isReadOnly() {
+               return $this->getReason() !== false;
+       }
+
+       /**
+        * Get the value of $wgReadOnly or the contents of $wgReadOnlyFile.
+        *
+        * @return string|bool String when in read-only mode; false otherwise
+        */
+       public function getReason() {
+               if ( $this->overrideReason !== null ) {
+                       return $this->overrideReason;
+               }
+               $confReason = $this->config->get( 'ReadOnly' );
+               if ( $confReason !== null ) {
+                       return $confReason;
+               }
+               if ( $this->fileReason === null ) {
+                       // Cache for faster access next time
+                       $readOnlyFile = $this->config->get( 'ReadOnlyFile' );
+                       if ( is_file( $readOnlyFile ) && filesize( $readOnlyFile ) > 0 ) {
+                               $this->fileReason = file_get_contents( $readOnlyFile );
+                       } else {
+                               $this->fileReason = false;
+                       }
+               }
+               return $this->fileReason;
+       }
+
+       /**
+        * Set the read-only mode, which will apply for the remainder of the
+        * request or until a service reset.
+        *
+        * @param string|null $msg
+        */
+       public function setReason( $msg ) {
+               $this->overrideReason = $msg;
+       }
+
+       /**
+        * Clear the cache of the read only file
+        */
+       public function clearCache() {
+               $this->fileReason = null;
+       }
+}
index b6d75ce..a28aa5b 100644 (file)
@@ -3372,16 +3372,56 @@ $wgApiFrameOptions = 'DENY';
 $wgDisableOutputCompression = false;
 
 /**
- * Should we allow a broader set of characters in id attributes, per HTML5?  If
- * not, use only HTML 4-compatible IDs.  This option is for testing -- when the
- * functionality is ready, it will be on by default with no option.
+ * Abandoned experiment with HTML5-style ID escaping. Normalized IDs a bit
+ * too aggressively, breaking preexisting content (particularly Cite).
+ * See T29733, T29694, T29474.
  *
- * Currently this appears to work fine in all browsers, but it's disabled by
- * default because it normalizes id's a bit too aggressively, breaking preexisting
- * content (particularly Cite).  See T29733, T29694, T29474.
+ * @deprecated since 1.30, use $wgFragmentMode
  */
 $wgExperimentalHtmlIds = false;
 
+/**
+ * How should section IDs be encoded?
+ * This array can contain 1 or 2 elements, each of them can be one of:
+ * - 'html5'  is modern HTML5 style encoding with minimal escaping. Allows to
+ *            display Unicode characters in many browsers' address bars.
+ * - 'legacy' is old MediaWiki-style encoding, e.g. 啤酒 turns into .E5.95.A4.E9.85.92
+ * - 'html5-legacy' corresponds to DEPRECATED $wgExperimentalHtmlIds mode. DO NOT use
+ *            it for anything but migration off that mode (see below).
+ *
+ * The first element of this array specifies the primary mode of escaping IDs. This
+ * is what users will see when they e.g. follow an [[#internal link]] to a section of
+ * a page.
+ *
+ * The optional second element defines a fallback mode, useful for migrations.
+ * If present, it will direct MediaWiki to add empty <span>s to every section with its
+ * id attribute set to fallback encoded title so that links using the previous encoding
+ * would still work.
+ *
+ * Example: you want to migrate your wiki from 'legacy' to 'html5'
+ *
+ * On the first step, set this variable to [ 'legacy', 'html5' ]. After a while, when
+ * all caches (parser, HTTP, etc.) contain only pages generated with this setting,
+ * flip the value to [ 'html5', 'legacy' ]. This will result in all internal links being
+ * generated in the new encoding while old links (both external and cached internal) will
+ * still work. After a long time, you might want to ditch backwards compatibility and
+ * set it to [ 'html5' ]. After all, pages get edited, breaking incoming links no matter which
+ * fragment mode is used.
+ *
+ * @since 1.30
+ */
+$wgFragmentMode = [ 'legacy' ];
+
+/**
+ * Which ID escaping mode should be used for external interwiki links? See documentation
+ * for $wgFragmentMode above for details of each mode. Because you can't control external sites,
+ * this setting should probably always be 'legacy', unless every wiki you link to has converted
+ * to 'html5'.
+ *
+ * @since 1.30
+ */
+$wgExternalInterwikiFragmentMode = 'legacy';
+
 /**
  * Abstract list of footer icons for skins in place of old copyrightico and poweredbyico code
  * You can add new icons to the built in copyright or poweredby, or you can create
@@ -4093,6 +4133,7 @@ $wgContentNamespaces = [ NS_MAIN ];
  * Optional array of namespaces which should be blacklisted from Special:ShortPages
  * Only pages inside $wgContentNamespaces but not $wgShortPagesNamespaceBlacklist will
  * be shown on that page.
+ * @since 1.30
  */
 $wgShortPagesNamespaceBlacklist = [];
 
@@ -8238,10 +8279,15 @@ $wgHTTPProxy = false;
  * Local virtual hosts.
  *
  * This lists domains that are configured as virtual hosts on the same machine.
- * If a request is to be made to a domain listed here, or any subdomain thereof,
- * then no proxy will be used.
- * Command-line scripts are not affected by this setting and will always use
- * proxy if it is configured.
+ *
+ * This affects the following:
+ * - MWHttpRequest: If a request is to be made to a domain listed here, or any
+ *   subdomain thereof, then no proxy will be used.
+ *   Command-line scripts are not affected by this setting and will always use
+ *   the proxy if it is configured.
+ * - ChronologyProtector: Decide to shutdown LBFactory asynchronously instead
+ *   synchronously if the current response redirects to a local virtual host.
+ *
  * @since 1.25
  */
 $wgLocalVirtualHosts = [];
index 229a36a..cfb78cd 100644 (file)
@@ -1698,7 +1698,7 @@ class EditPage {
                global $wgParser;
 
                if ( $this->sectiontitle !== '' ) {
-                       $sectionanchor = $wgParser->guessLegacySectionNameFromWikiText( $this->sectiontitle );
+                       $sectionanchor = $this->guessSectionName( $this->sectiontitle );
                        // If no edit summary was specified, create one automatically from the section
                        // title and have it link to the new section. Otherwise, respect the summary as
                        // passed.
@@ -1708,7 +1708,7 @@ class EditPage {
                                        ->rawParams( $cleanSectionTitle )->inContentLanguage()->text();
                        }
                } elseif ( $this->summary !== '' ) {
-                       $sectionanchor = $wgParser->guessLegacySectionNameFromWikiText( $this->summary );
+                       $sectionanchor = $this->guessSectionName( $this->summary );
                        # This is a new section, so create a link to the new section
                        # in the revision summary.
                        $cleanSummary = $wgParser->stripSectionName( $this->summary );
@@ -1743,7 +1743,7 @@ class EditPage {
         * time.
         */
        public function internalAttemptSave( &$result, $bot = false ) {
-               global $wgUser, $wgRequest, $wgParser, $wgMaxArticleSize;
+               global $wgUser, $wgRequest, $wgMaxArticleSize;
                global $wgContentHandlerUseDB;
 
                $status = Status::newGood();
@@ -2117,7 +2117,7 @@ class EditPage {
                                # We can't deal with anchors, includes, html etc in the header for now,
                                # headline would need to be parsed to improve this.
                                if ( $hasmatch && strlen( $matches[2] ) > 0 ) {
-                                       $sectionanchor = $wgParser->guessLegacySectionNameFromWikiText( $matches[2] );
+                                       $sectionanchor = $this->guessSectionName( $matches[2] );
                                }
                        }
                        $result['sectionanchor'] = $sectionanchor;
@@ -3076,7 +3076,7 @@ class EditPage {
                        'tabindex' => 1,
                        'size' => 60,
                        'spellcheck' => 'true',
-               ] + Linker::tooltipAndAccesskeyAttribs( 'summary' );
+               ];
        }
 
        /**
@@ -3097,6 +3097,7 @@ class EditPage {
                $inputAttrs = null, $spanLabelAttrs = null
        ) {
                $inputAttrs = $this->getSummaryInputAttributes( $inputAttrs );
+               $inputAttrs += Linker::tooltipAndAccesskeyAttribs( 'summary' );
 
                $spanLabelAttrs = ( is_array( $spanLabelAttrs ) ? $spanLabelAttrs : [] ) + [
                        'class' => $this->missingSummary ? 'mw-summarymissed' : 'mw-summary',
@@ -3132,6 +3133,10 @@ class EditPage {
                $inputAttrs = OOUI\Element::configFromHtmlAttributes(
                        $this->getSummaryInputAttributes( $inputAttrs )
                );
+               $inputAttrs += [
+                       'title' => Linker::titleAttrib( 'summary' ),
+                       'accessKey' => Linker::accesskey( 'summary' ),
+               ];
 
                // For compatibility with old scripts and extensions, we want the legacy 'id' on the `<input>`
                $inputAttrs['inputId'] = $inputAttrs['id'];
@@ -3220,16 +3225,13 @@ class EditPage {
 
        protected function showFormBeforeText() {
                global $wgOut;
-               $section = htmlspecialchars( $this->section );
-               $wgOut->addHTML( <<<HTML
-<input type='hidden' value="{$section}" name="wpSection"/>
-<input type='hidden' value="{$this->starttime}" name="wpStarttime" />
-<input type='hidden' value="{$this->edittime}" name="wpEdittime" />
-<input type='hidden' value="{$this->editRevId}" name="editRevId" />
-<input type='hidden' value="{$this->scrolltop}" name="wpScrolltop" id="wpScrolltop" />
-
-HTML
-               );
+
+               $wgOut->addHTML( Html::hidden( 'wpSection', htmlspecialchars( $this->section ) ) );
+               $wgOut->addHTML( Html::hidden( 'wpStarttime', $this->starttime ) );
+               $wgOut->addHTML( Html::hidden( 'wpEdittime', $this->edittime ) );
+               $wgOut->addHTML( Html::hidden( 'editRevId', $this->editRevId ) );
+               $wgOut->addHTML( Html::hidden( 'wpScrolltop', $this->scrolltop ) );
+
                if ( !$this->checkUnicodeCompliantBrowser() ) {
                        $wgOut->addHTML( Html::hidden( 'safemode', '1' ) );
                }
@@ -3493,8 +3495,8 @@ HTML
        }
 
        /**
-        * Inserts optional text shown below edit and upload forms. Can be used to offer special characters not present on
-        * most keyboards for copying/pasting.
+        * Inserts optional text shown below edit and upload forms. Can be used to offer special
+        * characters not present on most keyboards for copying/pasting.
         */
        protected function showEditTools() {
                global $wgOut;
@@ -4277,7 +4279,7 @@ HTML
                        $accesskey = null;
                        if ( isset( $options['tooltip'] ) ) {
                                $accesskey = $this->context->msg( "accesskey-{$options['tooltip']}" )->text();
-                               $title = Linker::titleAttrib( $options['tooltip'], 'withaccess' );
+                               $title = Linker::titleAttrib( $options['tooltip'] );
                        }
                        if ( isset( $options['title-message'] ) ) {
                                $title = $this->context->msg( $options['title-message'] )->text();
@@ -4355,8 +4357,7 @@ HTML
                $attribs = [
                        'name' => 'wpSave',
                        'tabindex' => ++$tabindex,
-               ] + Linker::tooltipAndAccesskeyAttribs( 'save' );
-
+               ];
                if ( $this->oouiEnabled ) {
                        $saveConfig = OOUI\Element::configFromHtmlAttributes( $attribs );
                        $buttons['save'] = new OOUI\ButtonInputWidget( [
@@ -4368,11 +4369,13 @@ HTML
                                'label' => $buttonLabel,
                                'infusable' => true,
                                'type' => 'submit',
+                               'title' => Linker::titleAttrib( 'save' ),
+                               'accessKey' => Linker::accesskey( 'save' ),
                        ] + $saveConfig );
                } else {
                        $buttons['save'] = Html::submitButton(
                                $buttonLabel,
-                               $attribs + [ 'id' => 'wpSave' ],
+                               $attribs + Linker::tooltipAndAccesskeyAttribs( 'save' ) + [ 'id' => 'wpSave' ],
                                [ 'mw-ui-progressive' ]
                        );
                }
@@ -4380,7 +4383,7 @@ HTML
                $attribs = [
                        'name' => 'wpPreview',
                        'tabindex' => ++$tabindex,
-               ] + Linker::tooltipAndAccesskeyAttribs( 'preview' );
+               ];
                if ( $this->oouiEnabled ) {
                        $previewConfig = OOUI\Element::configFromHtmlAttributes( $attribs );
                        $buttons['preview'] = new OOUI\ButtonInputWidget( [
@@ -4390,18 +4393,20 @@ HTML
                                'useInputTag' => true,
                                'label' => $this->context->msg( 'showpreview' )->text(),
                                'infusable' => true,
-                               'type' => 'submit'
+                               'type' => 'submit',
+                               'title' => Linker::titleAttrib( 'preview' ),
+                               'accessKey' => Linker::accesskey( 'preview' ),
                        ] + $previewConfig );
                } else {
                        $buttons['preview'] = Html::submitButton(
                                $this->context->msg( 'showpreview' )->text(),
-                               $attribs + [ 'id' => 'wpPreview' ]
+                               $attribs + Linker::tooltipAndAccesskeyAttribs( 'preview' ) + [ 'id' => 'wpPreview' ]
                        );
                }
                $attribs = [
                        'name' => 'wpDiff',
                        'tabindex' => ++$tabindex,
-               ] + Linker::tooltipAndAccesskeyAttribs( 'diff' );
+               ];
                if ( $this->oouiEnabled ) {
                        $diffConfig = OOUI\Element::configFromHtmlAttributes( $attribs );
                        $buttons['diff'] = new OOUI\ButtonInputWidget( [
@@ -4412,11 +4417,13 @@ HTML
                                'label' => $this->context->msg( 'showdiff' )->text(),
                                'infusable' => true,
                                'type' => 'submit',
+                               'title' => Linker::titleAttrib( 'diff' ),
+                               'accessKey' => Linker::accesskey( 'diff' ),
                        ] + $diffConfig );
                } else {
                        $buttons['diff'] = Html::submitButton(
                                $this->context->msg( 'showdiff' )->text(),
-                               $attribs + [ 'id' => 'wpDiff' ]
+                               $attribs + Linker::tooltipAndAccesskeyAttribs( 'diff' ) + [ 'id' => 'wpDiff' ]
                        );
                }
 
@@ -4785,4 +4792,27 @@ HTML
                }
                return $wikitext;
        }
+
+       /**
+        * Turns section name wikitext into anchors for use in HTTP redirects. Various
+        * versions of Microsoft browsers misinterpret fragment encoding of Location: headers
+        * resulting in mojibake in address bar. Redirect them to legacy section IDs,
+        * if possible. All the other browsers get HTML5 if the wiki is configured for it, to
+        * spread the new style links more efficiently.
+        *
+        * @param string $text
+        * @return string
+        */
+       private function guessSectionName( $text ) {
+               global $wgParser;
+
+               // Detect Microsoft browsers
+               $userAgent = $this->context->getRequest()->getHeader( 'User-Agent' );
+               if ( $userAgent && preg_match( '/MSIE|Edge/', $userAgent ) ) {
+                       // ...and redirect them to legacy encoding, if available
+                       return $wgParser->guessLegacySectionNameFromWikiText( $text );
+               }
+               // Meanwhile, real browsers get real anchors
+               return $wgParser->guessSectionNameFromWikiText( $text );
+       }
 }
index 4aae3ba..2ca851c 100644 (file)
@@ -1608,22 +1608,24 @@ class Linker {
         *   a space and ending with '>'
         *   This *must* be at least '>' for no attribs
         * @param string $anchor The anchor to give the headline (the bit after the #)
-        * @param string $html Html for the text of the header
+        * @param string $html HTML for the text of the header
         * @param string $link HTML to add for the section edit link
-        * @param bool|string $legacyAnchor A second, optional anchor to give for
+        * @param string|bool $fallbackAnchor A second, optional anchor to give for
         *   backward compatibility (false to omit)
         *
         * @return string HTML headline
         */
        public static function makeHeadline( $level, $attribs, $anchor, $html,
-               $link, $legacyAnchor = false
+               $link, $fallbackAnchor = false
        ) {
+               $anchorEscaped = htmlspecialchars( $anchor );
                $ret = "<h$level$attribs"
-                       . "<span class=\"mw-headline\" id=\"$anchor\">$html</span>"
+                       . "<span class=\"mw-headline\" id=\"$anchorEscaped\">$html</span>"
                        . $link
                        . "</h$level>";
-               if ( $legacyAnchor !== false ) {
-                       $ret = "<div id=\"$legacyAnchor\"></div>$ret";
+               if ( $fallbackAnchor !== false && $fallbackAnchor !== $anchor ) {
+                       $fallbackAnchor = htmlspecialchars( $fallbackAnchor );
+                       $ret = "<div id=\"$fallbackAnchor\"></div>$ret";
                }
                return $ret;
        }
index 2c87b8b..7a5fd9a 100644 (file)
@@ -42,7 +42,7 @@ class ListToggle {
        private function checkboxLink( $checkboxType ) {
                return Html::element(
                        // CSS classes: mw-checkbox-all, mw-checkbox-none, mw-checkbox-invert
-                       'a', [ 'href' => '#', 'class' => 'mw-checkbox-' . $checkboxType ],
+                       'a', [ 'class' => 'mw-checkbox-' . $checkboxType, 'role' => 'button', 'tabindex' => 0 ],
                        $this->output->msg( 'checkbox-' . $checkboxType )->text()
                );
        }
index de6d681..15ed2d4 100644 (file)
@@ -901,6 +901,8 @@ class Preferences {
                ];
                $defaultPreferences['rclimit'] = [
                        'type' => 'int',
+                       'min' => 0,
+                       'max' => 1000,
                        'label-message' => 'recentchangescount',
                        'help-message' => 'prefs-help-recentchangescount',
                        'section' => 'rc/displayrc',
index 592d495..547c2d5 100644 (file)
@@ -66,75 +66,3 @@ class ReadOnlyMode {
                $this->configuredReadOnly->clearCache();
        }
 }
-
-/**
- * A read-only mode service which does not depend on LoadBalancer.
- * To obtain an instance, use MediaWikiServices::getConfiguredReadOnlyMode().
- *
- * @since 1.29
- */
-class ConfiguredReadOnlyMode {
-       /** @var Config */
-       private $config;
-
-       /** @var string|bool|null */
-       private $fileReason;
-
-       /** @var string|null */
-       private $overrideReason;
-
-       public function __construct( Config $config ) {
-               $this->config = $config;
-       }
-
-       /**
-        * Check whether the wiki is in read-only mode.
-        *
-        * @return bool
-        */
-       public function isReadOnly() {
-               return $this->getReason() !== false;
-       }
-
-       /**
-        * Get the value of $wgReadOnly or the contents of $wgReadOnlyFile.
-        *
-        * @return string|bool String when in read-only mode; false otherwise
-        */
-       public function getReason() {
-               if ( $this->overrideReason !== null ) {
-                       return $this->overrideReason;
-               }
-               $confReason = $this->config->get( 'ReadOnly' );
-               if ( $confReason !== null ) {
-                       return $confReason;
-               }
-               if ( $this->fileReason === null ) {
-                       // Cache for faster access next time
-                       $readOnlyFile = $this->config->get( 'ReadOnlyFile' );
-                       if ( is_file( $readOnlyFile ) && filesize( $readOnlyFile ) > 0 ) {
-                               $this->fileReason = file_get_contents( $readOnlyFile );
-                       } else {
-                               $this->fileReason = false;
-                       }
-               }
-               return $this->fileReason;
-       }
-
-       /**
-        * Set the read-only mode, which will apply for the remainder of the
-        * request or until a service reset.
-        *
-        * @param string|null $msg
-        */
-       public function setReason( $msg ) {
-               $this->overrideReason = $msg;
-       }
-
-       /**
-        * Clear the cache of the read only file
-        */
-       public function clearCache() {
-               $this->fileReason = null;
-       }
-}
index 2def06a..907da16 100644 (file)
@@ -56,6 +56,21 @@ class Sanitizer {
        const EVIL_URI_PATTERN = '!(^|\s|\*/\s*)(javascript|vbscript)([^\w]|$)!i';
        const XMLNS_ATTRIBUTE_PATTERN = "/^xmlns:[:A-Z_a-z-.0-9]+$/";
 
+       /**
+        * Tells escapeUrlForHtml() to encode the ID using the wiki's primary encoding.
+        *
+        * @since 1.30
+        */
+       const ID_PRIMARY = 0;
+
+       /**
+        * Tells escapeUrlForHtml() to encode the ID using the fallback encoding, or return false
+        * if no fallback is configured.
+        *
+        * @since 1.30
+        */
+       const ID_FALLBACK = 1;
+
        /**
         * List of all named character entities defined in HTML 4.01
         * https://www.w3.org/TR/html4/sgml/entities.html
@@ -800,7 +815,7 @@ class Sanitizer {
 
                        # Escape HTML id attributes
                        if ( $attribute === 'id' ) {
-                               $value = self::escapeId( $value, 'noninitial' );
+                               $value = self::escapeIdForAttribute( $value, Sanitizer::ID_PRIMARY );
                        }
 
                        # Escape HTML id reference lists
@@ -1164,6 +1179,8 @@ class Sanitizer {
         * ambiguous if it's part of something that looks like a percent escape
         * (which don't work reliably in fragments cross-browser).
         *
+        * @deprecated since 1.30, use one of this class' escapeIdFor*() functions
+        *
         * @see https://www.w3.org/TR/html401/types.html#type-name Valid characters
         *   in the id and name attributes
         * @see https://www.w3.org/TR/html401/struct/links.html#h-12.2.3 Anchors with
@@ -1215,21 +1232,146 @@ class Sanitizer {
                return $id;
        }
 
+       /**
+        * Given a section name or other user-generated or otherwise unsafe string, escapes it to be
+        * a valid HTML id attribute.
+        *
+        * WARNING: unlike escapeId(), the output of this function is not guaranteed to be HTML safe,
+        * be sure to use proper escaping.
+        *
+        * @param string $id String to escape
+        * @param int $mode One of ID_* constants, specifying whether the primary or fallback encoding
+        *     should be used.
+        * @return string|bool Escaped ID or false if fallback encoding is requested but it's not
+        *     configured.
+        *
+        * @since 1.30
+        */
+       public static function escapeIdForAttribute( $id, $mode = self::ID_PRIMARY ) {
+               global $wgFragmentMode;
+
+               if ( !isset( $wgFragmentMode[$mode] ) ) {
+                       if ( $mode === self::ID_PRIMARY ) {
+                               throw new UnexpectedValueException( '$wgFragmentMode is configured with no primary mode' );
+                       }
+                       return false;
+               }
+
+               $internalMode = $wgFragmentMode[$mode];
+
+               return self::escapeIdInternal( $id, $internalMode );
+       }
+
+       /**
+        * Given a section name or other user-generated or otherwise unsafe string, escapes it to be
+        * a valid URL fragment.
+        *
+        * WARNING: unlike escapeId(), the output of this function is not guaranteed to be HTML safe,
+        * be sure to use proper escaping.
+        *
+        * @param string $id String to escape
+        * @return string Escaped ID
+        *
+        * @since 1.30
+        */
+       public static function escapeIdForLink( $id ) {
+               global $wgFragmentMode;
+
+               if ( !isset( $wgFragmentMode[self::ID_PRIMARY] ) ) {
+                       throw new UnexpectedValueException( '$wgFragmentMode is configured with no primary mode' );
+               }
+
+               $mode = $wgFragmentMode[self::ID_PRIMARY];
+
+               $id = self::escapeIdInternal( $id, $mode );
+               $id = self::urlEscapeId( $id, $mode );
+
+               return $id;
+       }
+
+       /**
+        * Given a section name or other user-generated or otherwise unsafe string, escapes it to be
+        * a valid URL fragment for external interwikis.
+        *
+        * @param string $id String to escape
+        * @return string Escaped ID
+        *
+        * @since 1.30
+        */
+       public static function escapeIdForExternalInterwiki( $id ) {
+               global $wgExternalInterwikiFragmentMode;
+
+               $id = self::escapeIdInternal( $id, $wgExternalInterwikiFragmentMode );
+               $id = self::urlEscapeId( $id, $wgExternalInterwikiFragmentMode );
+
+               return $id;
+       }
+
+       /**
+        * Helper for escapeIdFor*() functions. URL-escapes the ID if needed.
+        *
+        * @param string $id String to escape
+        * @param string $mode One of modes from $wgFragmentMode
+        * @return string
+        */
+       private static function urlEscapeId( $id, $mode ) {
+               if ( $mode === 'html5' ) {
+                       $id = urlencode( $id );
+                       $id = str_replace( '%3A', ':', $id );
+               }
+
+               return $id;
+       }
+
+       /**
+        * Helper for escapeIdFor*() functions. Performs most of the actual escaping.
+        *
+        * @param string $id String to escape
+        * @param string $mode One of modes from $wgFragmentMode
+        * @return string
+        */
+       private static function escapeIdInternal( $id, $mode ) {
+               $id = Sanitizer::decodeCharReferences( $id );
+
+               switch ( $mode ) {
+                       case 'html5':
+                               $id = str_replace( ' ', '_', $id );
+                               break;
+                       case 'legacy':
+                               // This corresponds to 'noninitial' mode of the old escapeId()
+                               static $replace = [
+                                       '%3A' => ':',
+                                       '%' => '.'
+                               ];
+
+                               $id = urlencode( str_replace( ' ', '_', $id ) );
+                               $id = strtr( $id, $replace );
+                               break;
+                       case 'html5-legacy':
+                               $id = preg_replace( '/[ \t\n\r\f_\'"&#%]+/', '_', $id );
+                               $id = trim( $id, '_' );
+                               if ( $id === '' ) {
+                                       // Must have been all whitespace to start with.
+                                       $id = '_';
+                               }
+                               break;
+                       default:
+                               throw new InvalidArgumentException( "Invalid mode '$mode' passed to '" . __METHOD__ );
+               }
+
+               return $id;
+       }
+
        /**
         * Given a string containing a space delimited list of ids, escape each id
         * to match ids escaped by the escapeId() function.
         *
+        * @todo wfDeprecated() uses of $options in 1.31, remove completely in 1.32
+        *
         * @since 1.27
         *
         * @param string $referenceString Space delimited list of ids
-        * @param string|array $options String or array of strings (default is array()):
-        *   'noninitial': This is a non-initial fragment of an id, not a full id,
-        *       so don't pay attention if the first character isn't valid at the
-        *       beginning of an id.  Only matters if $wgExperimentalHtmlIds is
-        *       false.
-        *   'legacy': Behave the way the old HTML 4-based ID escaping worked even
-        *       if $wgExperimentalHtmlIds is used, so we can generate extra
-        *       anchors and links won't break.
+        * @param string|array $options Deprecated and does nothing.
         * @return string
         */
        static function escapeIdReferenceList( $referenceString, $options = [] ) {
@@ -1238,7 +1380,7 @@ class Sanitizer {
 
                # Escape each token as an id
                foreach ( $references as &$ref ) {
-                       $ref = self::escapeId( $ref, $options );
+                       $ref = self::escapeIdForAttribute( $ref );
                }
 
                # Merge the array back to a space delimited list string
index 3d5bee2..68e3d96 100644 (file)
@@ -282,6 +282,11 @@ foreach ( $wgForeignFileRepos as &$repo ) {
 }
 unset( $repo ); // no global pollution; destroy reference
 
+// Convert this deprecated setting to modern system
+if ( $wgExperimentalHtmlIds ) {
+       $wgFragmentMode = [ 'html5-legacy', 'legacy' ];
+}
+
 $rcMaxAgeDays = $wgRCMaxAge / ( 3600 * 24 );
 if ( $wgRCFilterByAge ) {
        // Trim down $wgRCLinkDays so that it only lists links which are valid
index 0a2f868..5decece 100644 (file)
@@ -748,6 +748,8 @@ class Title implements LinkTarget {
        /**
         * Escape a text fragment, say from a link, for a URL
         *
+        * @deprecated since 1.30, use Sanitizer::escapeIdForLink() or escapeIdForExternalInterwiki()
+        *
         * @param string $fragment Containing a URL or link fragment (after the "#")
         * @return string Escaped string
         */
@@ -1320,6 +1322,8 @@ class Title implements LinkTarget {
         * Get a Title object associated with the talk page of this article,
         * if such a talk page can exist.
         *
+        * @since 1.30
+        *
         * @return Title The object for the talk page,
         *         or null if no associated talk page can exist, according to canHaveTalkPage().
         */
@@ -1397,14 +1401,16 @@ class Title implements LinkTarget {
 
        /**
         * Get the fragment in URL form, including the "#" character if there is one
+        *
         * @return string Fragment in URL form
         */
        public function getFragmentForURL() {
                if ( !$this->hasFragment() ) {
                        return '';
-               } else {
-                       return '#' . self::escapeFragmentForURL( $this->getFragment() );
+               } elseif ( $this->isExternal() && !$this->getTransWikiID() ) {
+                       return '#' . Sanitizer::escapeIdForExternalInterwiki( $this->getFragment() );
                }
+               return '#' . Sanitizer::escapeIdForLink( $this->getFragment() );
        }
 
        /**
index a9ebd76..b3a49c7 100644 (file)
@@ -22,6 +22,7 @@
 /**
  * This class performs some operations related to tracking categories, such as creating
  * a list of all such categories.
+ * @since 1.29
  */
 class TrackingCategories {
        /** @var Config */
index baec944..68dda37 100644 (file)
@@ -156,8 +156,8 @@ class InfoAction extends FormlessAction {
         * @return string The HTML.
         */
        protected function makeHeader( $header, $canonicalId ) {
-               $spanAttribs = [ 'class' => 'mw-headline', 'id' => Sanitizer::escapeId( $header ) ];
-               $h2Attribs = [ 'id' => Sanitizer::escapeId( $canonicalId ) ];
+               $spanAttribs = [ 'class' => 'mw-headline', 'id' => Sanitizer::escapeIdForAttribute( $header ) ];
+               $h2Attribs = [ 'id' => Sanitizer::escapeIdForAttribute( $canonicalId ) ];
 
                return Html::rawElement( 'h2', $h2Attribs, Html::element( 'span', $spanAttribs, $header ) );
        }
index 034d243..500f432 100644 (file)
@@ -2860,7 +2860,7 @@ abstract class ApiBase extends ContextSource {
         * Return the error message related to a certain array
         * @deprecated since 1.29
         * @param array|string|MessageSpecifier $error Element of a getUserPermissionsErrors()-style array
-        * @return [ 'code' => code, 'info' => info ]
+        * @return array [ 'code' => code, 'info' => info ]
         */
        public function parseMsg( $error ) {
                wfDeprecated( __METHOD__, '1.29' );
index b7d4529..6468235 100644 (file)
@@ -1931,14 +1931,15 @@ class ApiMain extends ApiBase {
 
                        $header = $this->msg( 'api-help-datatypes-header' )->parse();
 
-                       // Add an additional span with sanitized ID
-                       if ( !$this->getConfig()->get( 'ExperimentalHtmlIds' ) ) {
-                               $header = Html::element( 'span', [ 'id' => Sanitizer::escapeId( 'main/datatypes' ) ] ) .
-                                       $header;
-                       }
-                       $help['datatypes'] .= Html::rawElement( 'h' . min( 6, $level ),
-                               [ 'id' => 'main/datatypes', 'class' => 'apihelp-header' ],
-                               $header
+                       $id = Sanitizer::escapeIdForAttribute( 'main/datatypes', Sanitizer::ID_PRIMARY );
+                       $idFallback = Sanitizer::escapeIdForAttribute( 'main/datatypes', Sanitizer::ID_FALLBACK );
+
+                       $help['datatypes'] .= Linker::makeHeadline( min( 6, $level ),
+                               ' class="apihelp-header"',
+                               $id,
+                               $header,
+                               '',
+                               $idFallback
                        );
                        $help['datatypes'] .= $this->msg( 'api-help-datatypes' )->parseAsBlock();
                        if ( !isset( $tocData['main/datatypes'] ) ) {
@@ -1953,15 +1954,15 @@ class ApiMain extends ApiBase {
                                ];
                        }
 
-                       // Add an additional span with sanitized ID
-                       if ( !$this->getConfig()->get( 'ExperimentalHtmlIds' ) ) {
-                               $header = Html::element( 'span', [ 'id' => Sanitizer::escapeId( 'main/credits' ) ] ) .
-                                       $header;
-                       }
                        $header = $this->msg( 'api-credits-header' )->parse();
-                       $help['credits'] .= Html::rawElement( 'h' . min( 6, $level ),
-                               [ 'id' => 'main/credits', 'class' => 'apihelp-header' ],
-                               $header
+                       $id = Sanitizer::escapeIdForAttribute( 'main/credits', Sanitizer::ID_PRIMARY );
+                       $idFallback = Sanitizer::escapeIdForAttribute( 'main/credits', Sanitizer::ID_FALLBACK );
+                       $help['credits'] .= Linker::makeHeadline( min( 6, $level ),
+                               ' class="apihelp-header"',
+                               $id,
+                               $header,
+                               '',
+                               $idFallback
                        );
                        $help['credits'] .= $this->msg( 'api-credits' )->useDatabase( false )->parseAsBlock();
                        if ( !isset( $tocData['main/credits'] ) ) {
index 29c0b74..3639c06 100644 (file)
@@ -34,7 +34,7 @@ class ApiQueryLinks extends ApiQueryGeneratorBase {
        const LINKS = 'links';
        const TEMPLATES = 'templates';
 
-       private $table, $prefix, $helpUrl;
+       private $table, $prefix, $titlesParam, $helpUrl;
 
        public function __construct( ApiQuery $query, $moduleName ) {
                switch ( $moduleName ) {
index 37b159e..bff361e 100644 (file)
        "api-help-authmanagerhelper-continue": "이 요청은 초기 <samp>UI</samp> 또는 <samp>REDIRECT</samp> 응답 이후에 계속됩니다. 이것 또는 <var>$1returnurl</var> 중 하나가 필요합니다.",
        "api-help-authmanagerhelper-additional-params": "이 모듈은 사용 가능한 인증 요청에 따라 추가 변수를 허용합니다. 사용 가능한 요청 및 사용되는 필드를 결정하려면 <kbd>amirequestsfor=$1</kbd>(또는 해당되는 경우 이 모듈의 과거 응답)과 함께 <kbd>[[Special:ApiHelp/query+authmanagerinfo|action=query&meta=authmanagerinfo]]</kbd>을(를) 사용하십시오.",
        "apierror-articleexists": "작성하려는 문서가 이미 만들어져 있습니다.",
+       "apierror-assertbotfailed": "사용자의 <code>bot</code> 권한 보유 표명이 실패했습니다.",
+       "apierror-assertnameduserfailed": "사용자의 \"$1\" 지정 표명이 실패했습니다.",
+       "apierror-assertuserfailed": "사용자의 로그인 표명이 실패했습니다.",
        "apierror-autoblocked": "사용자의 IP 주소는 차단된 사용자에 의해 사용되었으므로 자동으로 차단된 상태입니다.",
        "apierror-badgenerator-unknown": "알 수 없는 <kbd>generator=$1</kbd>.",
        "apierror-badip": "IP 변수가 유효하지 않습니다.",
index ca3462d..8b86af5 100644 (file)
@@ -24,7 +24,7 @@
        "apihelp-main-param-origin": "Når man aksesserer API-en som bruker en domene-kryssende AJAX-forespørsel (CORS), sett denne til det opprinnelige domenet. Denne må tas med i alle pre-flight-forespørsler, og derfor være en del av spørre-URI-en (ikke POST-kroppen).\n\nFor autentiserte forespørsler må denne stemme helt med en av de opprinnelige i <code>Origin</code>-headeren, slik at den må settes til noe a la <kbd>https://en.wikipedia.org</kbd> eller <kbd>https://meta.wikimedia.org</kbd>. Hvis denne parameteren ikke stemmer med <code>Origin</code>-headeren, returneres et 403-svar. Hvis denne parameteren stemmer med <code>Origin</code>-headeren og originalen er hvitlistet, vil <code>Access-Control-Allow-Origin</code> og <code>Access-Control-Allow-Credentials</code>-headere bli satt.\n\nFor ikke-autentiserte forepørsler, spesifiser <kbd>*</kbd>. Denne vil gjøre at <code>Access-Control-Allow-Origin</code>-headeren blir satt, men <code>Access-Control-Allow-Credentials</code> blir <code>false</code> og alle bruerspesifikke data blir begrenset.",
        "apihelp-main-param-uselang": "Språk å bruke for meldingsoversettelser. <kbd>[[Special:ApiHelp/query+siteinfo|action=query&meta=siteinfo]]</kbd> med <kbd>siprop=languages</kbd> returnerer en liste over språkkoder, eller spesifiser <kbd>user</kbd> for å bruke den nåværende brukerens språkpreferanser, eller spesifiser <kbd>content</kbd> for å bruke denne wikiens innholdsspråk.",
        "apihelp-main-param-errorformat": "Formater som kan brukes for advarsels- og feiltekster.\n; plaintext: Wikitext der HTML-tagger er fjernet og elementer byttet ut.\n; wikitext: Ubehandlet wikitext.\n; html: HTML.\n; raw: Meldingsnøkler og -parametre.\n; none: Ingen tekst, bare feilkoder.\n; bc: Format brukt før MediaWiki 1.29. <var>errorlang</var> og <var>errorsuselocal</var> ses bort fra.",
-       "apihelp-main-param-errorlang": "Språk som skal brukes for advarsler og feil. <kbd>[[Specia:ApiHelp/query+siteinfo|action=query&meta=siteinfo]]</kbd> med <kbd>siprop=languages/<kbd> returnerer ei liste over språkkoder, eller angi <kbd>content</kbd> for å bruke wikiens innholdsspråk, eller angi <kbd>uselang</kbd> for å bruke samme verdi som <var>uselang</var>-parameteren.",
+       "apihelp-main-param-errorlang": "Språk som skal brukes for advarsler og feil. <kbd>[[Special:ApiHelp/query+siteinfo|action=query&meta=siteinfo]]</kbd> med <kbd>siprop=languages/<kbd> returnerer ei liste over språkkoder, eller angi <kbd>content</kbd> for å bruke wikiens innholdsspråk, eller angi <kbd>uselang</kbd> for å bruke samme verdi som <var>uselang</var>-parameteren.",
        "apihelp-main-param-errorsuselocal": "Hvis gitt, vil feiltekster bruke lokalt tilpassede meldinger fra {{ns:MediaWiki}}-navnerommet.",
        "apihelp-block-summary": "Blokker en bruker.",
        "apihelp-block-param-user": "Brukernavn, IP-adresse eller IP-intervall som skal blokkeres. Kan ikke brukes sammen med <var>$1userid</var>",
        "apihelp-compare-param-fromid": "Første side-ID å sammenligne.",
        "apihelp-compare-param-fromrev": "Første revisjon å sammenligne.",
        "apihelp-compare-param-fromtext": "Bruk denne teksten i stedet for innholdet i revisjonen som angis med <var>fromtitle</var>, <var>fromid</var> eller <var>fromrev</var>.",
+       "apihelp-compare-param-frompst": "Gjør en transformering av <var>fromtext</var> før lagring.",
        "apihelp-compare-param-fromcontentmodel": "Innholdsmodell for <var>fromtext</var>. Om den ikke angis vil den gjettes basert på de andre parameterne.",
        "apihelp-compare-param-fromcontentformat": "Innholdsserialiseringsformat for <var>fromtext</var>.",
        "apihelp-compare-param-totitle": "Andre tittel å sammenligne.",
        "apihelp-compare-param-toid": "Andre side-ID å sammenligne.",
        "apihelp-compare-param-torev": "Andre revisjon å sammenligne.",
+       "apihelp-compare-param-totext": "Bruk denne teksten i stedet for innholdet i revisjonen spesifisert av <var>totitle</var>, <var>toid</var> eller <var>torev</var>.",
+       "apihelp-compare-param-topst": "Gjør en transformering av <var>totext</var> før lagring.",
+       "apihelp-compare-param-tocontentmodel": "Innholdsmodellen til <var>totext</var>. Om denne ikke angis vil den bli gjettet ut fra andre parametere.",
+       "apihelp-compare-param-tocontentformat": "Innholdsserialiseringsformat for <var>totext</var>.",
+       "apihelp-compare-param-prop": "Hvilke informasjonsdeler som skal hentes.",
+       "apihelp-compare-paramvalue-prop-diff": "Diffens HTML.",
+       "apihelp-compare-paramvalue-prop-diffsize": "Størrelsen på diffens HTML i byte.",
+       "apihelp-compare-paramvalue-prop-rel": "Revisjons-ID-en for revisjonene foran «from» og etter «to», om de finnes.",
+       "apihelp-compare-paramvalue-prop-ids": "Side- og revisjons-ID-ene til «from»- og «to»-revisjonene.",
+       "apihelp-compare-paramvalue-prop-title": "Sidetitlene for «from»- og «to»-revisjonene.",
+       "apihelp-compare-paramvalue-prop-user": "Brukernavnet og ID-en til «from»- og «to»-revisjonene.",
+       "apihelp-compare-paramvalue-prop-comment": "Kommentaren til «from»- og «to»-revisjonene.",
+       "apihelp-compare-paramvalue-prop-size": "Størrelsen til «from»- og «to»-revisjonene.",
        "apihelp-compare-example-1": "Lag en diff mellom revisjon 1 og 2.",
        "apihelp-createaccount-summary": "Opprett en ny brukerkonto.",
        "apihelp-createaccount-param-preservestate": "Om <kbd>[[Special:ApiHelp/query+authmanagerinfo|action=query&meta=authmanagerinfo]]</kbd> returnerte true for <samp>hashprimarypreservedstate</samp> bør forespørsler merket som <samp>primary-required</samp> omgås. Om den returnerte en ikke-tom verdi for <samp>preservedusername</samp> kan det brukernavnet brukes for <var>username</var>-parameteren.",
@@ -81,6 +95,7 @@
        "apihelp-createaccount-example-pass": "Opprett bruker <kbd>testuser</kbd> med passordet <kbd>test123</kbd>.",
        "apihelp-createaccount-example-mail": "Opprett bruker <kbd>testmailuser</kbd> og send et tilfeldig generert passord med e-post.",
        "apihelp-cspreport-summary": "Brukes av nettlesere for å rapportere brudd på Content Security Policy. Denne modulen bør aldri brukes utenom av en CSP-mottakelig nettleser.",
+       "apihelp-cspreport-param-source": "Hva som genererte CSP-headeren som utløste denne rapporten",
        "apihelp-delete-summary": "Slett en side.",
        "apihelp-delete-param-title": "Tittel til siden som skal slettes. Kan ikke brukes sammen med <var>$1pageid</var>.",
        "apihelp-delete-param-pageid": "Side-ID til siden som skal slettes. Kan ikke brukes sammen med <var>$1title</var>.",
index 95e69e6..795e81b 100644 (file)
        "apihelp-json-param-utf8": "Если задано, кодирует большинство (но не все) не-ASCII символов в UTF-8 вместо замены их на шестнадцатеричные коды. Применяется по умолчанию, когда <var>formatversion</var> не равно <kbd>1</kbd>.",
        "apihelp-json-param-ascii": "Если задано, заменяет все не-ASCII-символы на шестнадцатеричные коды. Применяется по умолчанию, когда <var>formatversion</var> равно <kbd>1</kbd>.",
        "apihelp-json-param-formatversion": "Формат вывода:\n;1: Обратно совместимый формат (логические значения в стиле XML, ключи <samp>*</samp> для узлов данных, и так далее).\n;2: Экспериментальный современный формат. Детали могут меняться!\n;latest: Использовать последний формат (сейчас <kbd>2</kbd>), может меняться без предупреждения.",
-       "apihelp-jsonfm-summary": "Выводить данные в JSON-формате (хорошо читаемом в HTML).",
+       "apihelp-jsonfm-summary": "Выводить данные в формате JSON (отформатированном в HTML).",
        "apihelp-none-summary": "Ничего не выводить.",
        "apihelp-php-summary": "Выводить данные в сериализованном формате PHP.",
        "apihelp-php-param-formatversion": "Формат вывода:\n;1: Обратно совместимый формат (логические значения в стиле XML, ключи <samp>*</samp> для узлов данных, и так далее).\n;2: Экспериментальный современный формат. Детали могут меняться!\n;latest: Использовать последний формат (сейчас <kbd>2</kbd>), может меняться без предупреждения.",
-       "apihelp-phpfm-summary": "Выводить данные в сериализованном формате PHP (хорошо читаемом в HTML).",
-       "apihelp-rawfm-summary": "Выводить данные, включая элементы отладки, в формате JSON (хорошо читаемом в HTML).",
+       "apihelp-phpfm-summary": "Выводить данные в сериализованном формате PHP (отформатированном в HTML).",
+       "apihelp-rawfm-summary": "Выводить данные, включая элементы отладки, в формате JSON (отформатированном в HTML).",
        "apihelp-xml-summary": "Выводить данные в формате XML.",
        "apihelp-xml-param-xslt": "Если задано, добавляет названную страницу в качестве листа XSL. Значением должно быть название в пространстве имён {{ns:MediaWiki}}, заканчивающееся на <code>.xsl</code>.",
        "apihelp-xml-param-includexmlnamespace": "Если задано, добавляет пространство имён XML.",
-       "apihelp-xmlfm-summary": "Выводить данные в формате XML (хорошо читаемом в HTML).",
+       "apihelp-xmlfm-summary": "Выводить данные в формате XML (отформатированном в HTML).",
        "api-format-title": "Результат MediaWiki API",
        "api-format-prettyprint-header": "Это HTML-представление формата $1. HTML хорош для отладки, но неудобен для практического применения.\n\nУкажите параметр <var>format</var> для изменения формата вывода. Для отображения не-HTML-представления формата $1, присвойте <kbd>format=$2</kbd>.\n\nСм. [[mw:Special:MyLanguage/API|полную документацию]] или [[Special:ApiHelp/main|справку API]] для получения дополнительной информации.",
        "api-format-prettyprint-header-only-html": "Это HTML-представление для отладки, не рассчитанное на практическое применение.\n\nСм. [[mw:Special:MyLanguage/API|полную документацию]] или [[Special:ApiHelp/main|справку API]] для получения дополнительной информации.",
index b12af19..cbeb1fc 100644 (file)
@@ -104,7 +104,13 @@ class WANCacheReapUpdate implements DeferrableUpdate {
                /** @var WikiPage[]|LocalFile[]|User[] $entities */
                $entities = [];
 
-               $entities[] = WikiPage::factory( Title::newFromTitleValue( $t ) );
+               // You can't create a WikiPage for special pages (-1) or other virtual
+               // namespaces, but special pages do appear in RC sometimes, e.g. for logs
+               // of AbuseFilter filter changes.
+               if ( $t->getNamespace() >= 0 ) {
+                       $entities[] = WikiPage::factory( Title::newFromTitleValue( $t ) );
+               }
+
                if ( $t->inNamespace( NS_FILE ) ) {
                        $entities[] = wfLocalFile( $t->getText() );
                }
index d4351e0..702c2eb 100644 (file)
@@ -1692,7 +1692,7 @@ class HTMLForm extends ContextSource {
 
                                        $attributes = [];
                                        if ( $fieldsetIDPrefix ) {
-                                               $attributes['id'] = Sanitizer::escapeId( "$fieldsetIDPrefix$key" );
+                                               $attributes['id'] = Sanitizer::escapeIdForAttribute( "$fieldsetIDPrefix$key" );
                                        }
                                        $subsectionHtml .= $this->wrapFieldSetSection( $legend, $section, $attributes );
                                } else {
@@ -1741,7 +1741,7 @@ class HTMLForm extends ContextSource {
                ];
 
                if ( $sectionName ) {
-                       $attribs['id'] = Sanitizer::escapeId( $sectionName );
+                       $attribs['id'] = Sanitizer::escapeIdForAttribute( $sectionName );
                }
 
                if ( $displayFormat === 'table' ) {
index 83a8023..77ddc1a 100644 (file)
@@ -416,8 +416,8 @@ abstract class HTMLFormField {
                        $this->mDir = $params['dir'];
                }
 
-               $validName = Sanitizer::escapeId( $this->mName );
-               $validName = str_replace( [ '.5B', '.5D' ], [ '[', ']' ], $validName );
+               $validName = urlencode( $this->mName );
+               $validName = str_replace( [ '%5B', '%5D' ], [ '[', ']' ], $validName );
                if ( $this->mName != $validName && !isset( $params['nodata'] ) ) {
                        throw new MWException( "Invalid name '{$this->mName}' passed to " . __METHOD__ );
                }
@@ -430,7 +430,7 @@ abstract class HTMLFormField {
 
                if ( isset( $params['id'] ) ) {
                        $id = $params['id'];
-                       $validId = Sanitizer::escapeId( $id );
+                       $validId = urlencode( $id );
 
                        if ( $id != $validId ) {
                                throw new MWException( "Invalid id '$id' passed to " . __METHOD__ );
@@ -976,7 +976,7 @@ abstract class HTMLFormField {
        }
 
        /**
-        * Returns the attributes required for the tooltip and accesskey.
+        * Returns the attributes required for the tooltip and accesskey, for Html::element() etc.
         *
         * @return array Attributes
         */
@@ -988,6 +988,22 @@ abstract class HTMLFormField {
                return Linker::tooltipAndAccesskeyAttribs( $this->mParams['tooltip'] );
        }
 
+       /**
+        * Returns the attributes required for the tooltip and accesskey, for OOUI widgets' config.
+        *
+        * @return array Attributes
+        */
+       public function getTooltipAndAccessKeyOOUI() {
+               if ( empty( $this->mParams['tooltip'] ) ) {
+                       return [];
+               }
+
+               return [
+                       'title' => Linker::titleAttrib( $this->mParams['tooltip'] ),
+                       'accessKey' => Linker::accesskey( $this->mParams['tooltip'] ),
+               ];
+       }
+
        /**
         * Returns the given attributes from the parameters
         *
index ed99802..e47de61 100644 (file)
@@ -66,7 +66,10 @@ class OOUIHTMLForm extends HTMLForm {
                        }
 
                        if ( isset( $this->mSubmitTooltip ) ) {
-                               $attribs += Linker::tooltipAndAccesskeyAttribs( $this->mSubmitTooltip );
+                               $attribs += [
+                                       'title' => Linker::titleAttrib( $this->mSubmitTooltip ),
+                                       'accessKey' => Linker::accesskey( $this->mSubmitTooltip ),
+                               ];
                        }
 
                        $attribs['classes'] = [ 'mw-htmlform-submit' ];
@@ -177,7 +180,7 @@ class OOUIHTMLForm extends HTMLForm {
                        'items' => $fieldsHtml,
                ];
                if ( $sectionName ) {
-                       $config['id'] = Sanitizer::escapeId( $sectionName );
+                       $config['id'] = Sanitizer::escapeIdForAttribute( $sectionName );
                }
                if ( is_string( $this->mWrapperLegend ) ) {
                        $config['label'] = $this->mWrapperLegend;
index b080e18..9a956fb 100644 (file)
@@ -52,7 +52,7 @@ class HTMLCheckField extends HTMLFormField {
                        $value = !$value;
                }
 
-               $attr = $this->getTooltipAndAccessKey();
+               $attr = $this->getTooltipAndAccessKeyOOUI();
                $attr['id'] = $this->mID;
                $attr['name'] = $this->mName;
 
index dd9184b..53c6835 100644 (file)
@@ -93,9 +93,9 @@ class HTMLFormFieldCloner extends HTMLFormField {
                                $info['name'] = $name;
                        }
                        if ( isset( $info['id'] ) ) {
-                               $info['id'] = Sanitizer::escapeId( "{$this->mID}--$key--{$info['id']}" );
+                               $info['id'] = Sanitizer::escapeIdForAttribute( "{$this->mID}--$key--{$info['id']}" );
                        } else {
-                               $info['id'] = Sanitizer::escapeId( "{$this->mID}--$key--$fieldname" );
+                               $info['id'] = Sanitizer::escapeIdForAttribute( "{$this->mID}--$key--$fieldname" );
                        }
                        // Copy the hide-if rules to "child" fields, so that the JavaScript code handling them
                        // (resources/src/mediawiki/htmlform/hide-if.js) doesn't have to handle nested fields.
@@ -313,7 +313,7 @@ class HTMLFormFieldCloner extends HTMLFormField {
                                'type' => 'submit',
                                'formnovalidate' => true,
                                'name' => $name,
-                               'id' => Sanitizer::escapeId( "{$this->mID}--$key--delete" ),
+                               'id' => Sanitizer::escapeIdForAttribute( "{$this->mID}--$key--delete" ),
                                'cssclass' => 'mw-htmlform-cloner-delete-button',
                                'default' => $this->getMessage( $label )->text(),
                        ], $this->mParent );
@@ -386,7 +386,7 @@ class HTMLFormFieldCloner extends HTMLFormField {
                        'type' => 'submit',
                        'formnovalidate' => true,
                        'name' => $name,
-                       'id' => Sanitizer::escapeId( "{$this->mID}--create" ),
+                       'id' => Sanitizer::escapeIdForAttribute( "{$this->mID}--create" ),
                        'cssclass' => 'mw-htmlform-cloner-create-button',
                        'default' => $this->getMessage( $label )->text(),
                ], $this->mParent );
index 2b6e066..0d5eeba 100644 (file)
@@ -142,7 +142,7 @@ class HTMLMultiSelectField extends HTMLFormField implements HTMLNestedFilterable
        public function getInputOOUI( $value ) {
                $this->mParent->getOutput()->addModules( 'oojs-ui-widgets' );
 
-               $attr = $this->getTooltipAndAccessKey();
+               $attr = [];
                $attr['id'] = $this->mID;
                $attr['name'] = "{$this->mName}[]";
 
index 06ec372..77ea7cd 100644 (file)
@@ -90,7 +90,7 @@ class HTMLRadioField extends HTMLFormField {
                                $html .= Html::rawElement( 'h1', [], $label ) . "\n";
                                $html .= $this->formatOptions( $info, $value );
                        } else {
-                               $id = Sanitizer::escapeId( $this->mID . "-$info" );
+                               $id = Sanitizer::escapeIdForAttribute( $this->mID . "-$info" );
                                $classes = [ 'mw-htmlform-flatlist-item' ];
                                if ( $wgUseMediaWikiUIEverywhere || $this->mParent instanceof VFormHTMLForm ) {
                                        $classes[] = 'mw-ui-radio';
index 82ec3bf..480c5bb 100644 (file)
@@ -71,7 +71,7 @@ class HTMLTextAreaField extends HTMLFormField {
                        throw new Exception( "OOUIHTMLForm does not support the 'cols' parameter for textareas" );
                }
 
-               $attribs = $this->getTooltipAndAccessKey();
+               $attribs = $this->getTooltipAndAccessKeyOOUI();
 
                if ( $this->mClass !== '' ) {
                        $attribs['classes'] = [ $this->mClass ];
index b0b66ca..1c5a43d 100644 (file)
@@ -140,7 +140,7 @@ class HTMLTextField extends HTMLFormField {
                        $value = '';
                }
 
-               $attribs = $this->getTooltipAndAccessKey();
+               $attribs = $this->getTooltipAndAccessKeyOOUI();
 
                if ( $this->mClass !== '' ) {
                        $attribs['classes'] = [ $this->mClass ];
index 7b6ac5e..8f5858b 100644 (file)
@@ -940,10 +940,10 @@ abstract class DatabaseUpdater {
         *
         * @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
+        * @param string|bool $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 ) {
+       public function modifyTable( $table, $patch, $fullpath = false ) {
                if ( !$this->doTable( $table ) ) {
                        return true;
                }
index 686ebd2..f892527 100644 (file)
        "config-mssql-windowsauth": "Autenticação do Windows",
        "config-site-name": "Nome da wiki:",
        "config-site-name-help": "Este nome aparecerá no título da janela do seu navegador e em vários outros sítios.",
-       "config-site-name-blank": "Introduza o nome do sítio.",
+       "config-site-name-blank": "Introduza o nome do site.",
        "config-project-namespace": "Espaço nominal do projeto:",
        "config-ns-generic": "Projeto",
        "config-ns-site-name": "O mesmo que o nome da wiki: $1",
        "config-logo": "URL do logótipo:",
        "config-logo-help": "O tema padrão do MediaWiki inclui espaço para um logótipo de 135x160 píxeis acima do menu da barra lateral.\nColoque na wiki uma imagem com estas dimensões e introduza aqui o URL dessa imagem.\n\nSe não pretende usar um logótipo, deixe este campo em branco.",
        "config-instantcommons": "Ativar Instant Commons",
-       "config-instantcommons-help": "O [https://www.mediawiki.org/wiki/InstantCommons Instant Commons] é uma funcionalidade que permite que as wikis usem imagens, áudio e outros ficheiros multimédia disponíveis no sítio [https://commons.wikimedia.org/ Wikimedia Commons].\nPara poder usá-los, o MediaWiki necessita de acesso à Internet.\n\nPara mais informações sobre esta funcionalidade, incluindo instruções sobre como configurá-la para usar outras wikis em vez da Wikimedia Commons, consulte o [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:$wgForeignFileRepos Manual Técnico].",
+       "config-instantcommons-help": "O [https://www.mediawiki.org/wiki/InstantCommons Instant Commons] é uma funcionalidade que permite que as wikis usem imagens, áudio e outros ficheiros multimédia disponíveis no site [https://commons.wikimedia.org/ Wikimedia Commons].\nPara poder usá-los, o MediaWiki necessita de acesso à Internet.\n\nPara mais informações sobre esta funcionalidade, incluindo instruções sobre como configurá-la para usar outras wikis em vez da Wikimedia Commons, consulte o [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:$wgForeignFileRepos Manual Técnico].",
        "config-cc-error": "O auxiliar de escolha de licenças da Creative Commons não produziu resultados.\nIntroduza o nome da licença manualmente.",
        "config-cc-again": "Escolha outra vez...",
        "config-cc-not-chosen": "Escolha a licença da Creative Commons que pretende e clique \"proceed\".",
index 49b7a45..db881d5 100644 (file)
@@ -281,7 +281,9 @@ class JobRunner implements LoggerAwareInterface {
        private function executeJob( Job $job, LBFactory $lbFactory, $stats, $popTime ) {
                $jType = $job->getType();
                $msg = $job->toString() . " STARTING";
-               $this->logger->debug( $msg );
+               $this->logger->debug( $msg, [
+                       'job_type' => $job->getType(),
+               ] );
                $this->debugCallback( $msg );
 
                // Run the job...
@@ -339,12 +341,23 @@ class JobRunner implements LoggerAwareInterface {
                }
 
                if ( $status === false ) {
+                       $msg = $job->toString() . " t={job_duration} error={job_error}";
+                       $this->logger->error( $msg, [
+                               'job_type' => $job->getType(),
+                               'job_duration' => $timeMs,
+                               'job_error' => $error,
+                       ] );
+
                        $msg = $job->toString() . " t=$timeMs error={$error}";
-                       $this->logger->error( $msg );
                        $this->debugCallback( $msg );
                } else {
+                       $msg = $job->toString() . " t={job_duration} good";
+                       $this->logger->info( $msg, [
+                               'job_type' => $job->getType(),
+                               'job_duration' => $timeMs,
+                       ] );
+
                        $msg = $job->toString() . " t=$timeMs good";
-                       $this->logger->info( $msg );
                        $this->debugCallback( $msg );
                }
 
@@ -488,9 +501,14 @@ class JobRunner implements LoggerAwareInterface {
                }
                $usedBytes = memory_get_usage();
                if ( $maxBytes && $usedBytes >= 0.95 * $maxBytes ) {
+                       $msg = "Detected excessive memory usage ({used_bytes}/{max_bytes}).";
+                       $this->logger->error( $msg, [
+                               'used_bytes' => $usedBytes,
+                               'max_bytes' => $maxBytes,
+                       ] );
+
                        $msg = "Detected excessive memory usage ($usedBytes/$maxBytes).";
                        $this->debugCallback( $msg );
-                       $this->logger->error( $msg );
 
                        return false;
                }
@@ -552,8 +570,14 @@ class JobRunner implements LoggerAwareInterface {
                }
 
                $ms = intval( 1000 * $time );
+
+               $msg = $job->toString() . " COMMIT ENQUEUED [{job_commit_write_ms}ms of writes]";
+               $this->logger->info( $msg, [
+                       'job_type' => $job->getType(),
+                       'job_commit_write_ms' => $ms,
+               ] );
+
                $msg = $job->toString() . " COMMIT ENQUEUED [{$ms}ms of writes]";
-               $this->logger->info( $msg );
                $this->debugCallback( $msg );
 
                // Wait for an exclusive lock to commit
index e860ec4..f9dcc1b 100644 (file)
  * @since 1.25
  */
 class StatusValue {
+
        /** @var bool */
        protected $ok = true;
-       /** @var array */
+
+       /** @var array[] */
        protected $errors = [];
 
        /** @var mixed */
        public $value;
-       /** @var array Map of (key => bool) to indicate success of each part of batch operations */
+
+       /** @var bool[] Map of (key => bool) to indicate success of each part of batch operations */
        public $success = [];
+
        /** @var int Counter for batch operations */
        public $successCount = 0;
+
        /** @var int Counter for batch operations */
        public $failCount = 0;
 
@@ -138,7 +143,7 @@ class StatusValue {
         *
         * Each error is a (message:string or MessageSpecifier,params:array) map
         *
-        * @return array
+        * @return array[]
         */
        public function getErrors() {
                return $this->errors;
@@ -230,7 +235,7 @@ class StatusValue {
         *   - params: array list of parameters
         *
         * @param string $type
-        * @return array
+        * @return array[]
         */
        public function getErrorsByType( $type ) {
                $result = [];
index fcd29c3..4d1b87b 100644 (file)
@@ -23,6 +23,7 @@
 namespace Wikimedia\Rdbms;
 
 use mysqli;
+use mysqli_result;
 use IP;
 
 /**
@@ -190,7 +191,7 @@ class DatabaseMysqli extends DatabaseMysqlBase {
        }
 
        /**
-        * @param mysqli $res
+        * @param mysqli_result $res
         * @return bool
         */
        protected function mysqlFreeResult( $res ) {
@@ -200,7 +201,7 @@ class DatabaseMysqli extends DatabaseMysqlBase {
        }
 
        /**
-        * @param mysqli $res
+        * @param mysqli_result $res
         * @return bool
         */
        protected function mysqlFetchObject( $res ) {
@@ -213,7 +214,7 @@ class DatabaseMysqli extends DatabaseMysqlBase {
        }
 
        /**
-        * @param mysqli $res
+        * @param mysqli_result $res
         * @return bool
         */
        protected function mysqlFetchArray( $res ) {
@@ -226,7 +227,7 @@ class DatabaseMysqli extends DatabaseMysqlBase {
        }
 
        /**
-        * @param mysqli $res
+        * @param mysqli_result $res
         * @return mixed
         */
        protected function mysqlNumRows( $res ) {
@@ -287,7 +288,7 @@ class DatabaseMysqli extends DatabaseMysqlBase {
        }
 
        /**
-        * @param mysqli $res
+        * @param mysqli_result $res
         * @param int $row
         * @return mixed
         */
index 9242414..870fc3e 100644 (file)
@@ -567,7 +567,7 @@ class DatabaseSqlite extends Database {
 
        /**
         * @param array $options
-        * @return string
+        * @return array
         */
        protected function makeUpdateOptionsArray( $options ) {
                $options = parent::makeUpdateOptionsArray( $options );
index e2cf2cf..33f7d47 100644 (file)
@@ -1180,7 +1180,7 @@ class Article implements Page {
                $key = $cache->makeKey( 'page-recent-delete', md5( $title->getPrefixedText() ) );
                $loggedIn = $this->getContext()->getUser()->isLoggedIn();
                if ( $loggedIn || $cache->get( $key ) ) {
-                       $logTypes = [ 'delete', 'move' ];
+                       $logTypes = [ 'delete', 'move', 'protect' ];
 
                        $dbr = wfGetDB( DB_REPLICA );
 
index d37700b..b870831 100644 (file)
@@ -254,15 +254,16 @@ class ImagePage extends Article {
                $r .= "<table id=\"mw_metadata\" class=\"mw_metadata\">\n";
                foreach ( $metadata as $type => $stuff ) {
                        foreach ( $stuff as $v ) {
-                               # @todo FIXME: Why is this using escapeId for a class?!
-                               $class = Sanitizer::escapeId( $v['id'] );
+                               $class = str_replace( ' ', '_', $v['id'] );
                                if ( $type == 'collapsed' ) {
                                        // Handled by mediawiki.action.view.metadata module.
                                        $class .= ' collapsable';
                                }
-                               $r .= "<tr class=\"$class\">\n";
-                               $r .= "<th>{$v['name']}</th>\n";
-                               $r .= "<td>{$v['value']}</td>\n</tr>";
+                               $r .= Html::rawElement( 'tr',
+                                       [ 'class' => $class ],
+                                       Html::rawElement( 'th', [], $v['name'] )
+                                               . Html::rawElement( 'td', [], $v['value'] )
+                               );
                        }
                }
                $r .= "</table>\n</div>\n";
index b035b02..88439db 100644 (file)
@@ -4035,7 +4035,7 @@ class Parser {
         * @private
         */
        public function formatHeadings( $text, $origText, $isMain = true ) {
-               global $wgMaxTocLevel, $wgExperimentalHtmlIds;
+               global $wgMaxTocLevel;
 
                # Inhibit editsection links if requested in the page
                if ( isset( $this->mDoubleUnderscores['noeditsection'] ) ) {
@@ -4229,61 +4229,44 @@ class Parser {
                        # Save headline for section edit hint before it's escaped
                        $headlineHint = $safeHeadline;
 
-                       if ( $wgExperimentalHtmlIds ) {
-                               # For reverse compatibility, provide an id that's
-                               # HTML4-compatible, like we used to.
-                               # It may be worth noting, academically, that it's possible for
-                               # the legacy anchor to conflict with a non-legacy headline
-                               # anchor on the page.  In this case likely the "correct" thing
-                               # would be to either drop the legacy anchors or make sure
-                               # they're numbered first.  However, this would require people
-                               # to type in section names like "abc_.D7.93.D7.90.D7.A4"
-                               # manually, so let's not bother worrying about it.
-                               $legacyHeadline = Sanitizer::escapeId( $safeHeadline,
-                                       [ 'noninitial', 'legacy' ] );
-                               $safeHeadline = Sanitizer::escapeId( $safeHeadline );
-
-                               if ( $legacyHeadline == $safeHeadline ) {
-                                       # No reason to have both (in fact, we can't)
-                                       $legacyHeadline = false;
-                               }
-                       } else {
-                               $legacyHeadline = false;
-                               $safeHeadline = Sanitizer::escapeId( $safeHeadline,
-                                       'noninitial' );
+                       $fallbackHeadline = Sanitizer::escapeIdForAttribute( $safeHeadline, Sanitizer::ID_FALLBACK );
+                       $linkAnchor = Sanitizer::escapeIdForLink( $safeHeadline );
+                       $safeHeadline = Sanitizer::escapeIdForAttribute( $safeHeadline, Sanitizer::ID_PRIMARY );
+                       if ( $fallbackHeadline === $safeHeadline ) {
+                               # No reason to have both (in fact, we can't)
+                               $fallbackHeadline = false;
                        }
 
-                       # HTML names must be case-insensitively unique (T12721).
-                       # This does not apply to Unicode characters per
-                       # https://www.w3.org/TR/html5/infrastructure.html#case-sensitivity-and-string-comparison
+                       # HTML IDs must be case-insensitively unique for IE compatibility (T12721).
                        # @todo FIXME: We may be changing them depending on the current locale.
                        $arrayKey = strtolower( $safeHeadline );
-                       if ( $legacyHeadline === false ) {
-                               $legacyArrayKey = false;
+                       if ( $fallbackHeadline === false ) {
+                               $fallbackArrayKey = false;
                        } else {
-                               $legacyArrayKey = strtolower( $legacyHeadline );
+                               $fallbackArrayKey = strtolower( $fallbackHeadline );
                        }
 
                        # Create the anchor for linking from the TOC to the section
                        $anchor = $safeHeadline;
-                       $legacyAnchor = $legacyHeadline;
+                       $fallbackAnchor = $fallbackHeadline;
                        if ( isset( $refers[$arrayKey] ) ) {
                                // @codingStandardsIgnoreStart
                                for ( $i = 2; isset( $refers["${arrayKey}_$i"] ); ++$i );
                                // @codingStandardsIgnoreEnd
                                $anchor .= "_$i";
+                               $linkAnchor .= "_$i";
                                $refers["${arrayKey}_$i"] = true;
                        } else {
                                $refers[$arrayKey] = true;
                        }
-                       if ( $legacyHeadline !== false && isset( $refers[$legacyArrayKey] ) ) {
+                       if ( $fallbackHeadline !== false && isset( $refers[$fallbackArrayKey] ) ) {
                                // @codingStandardsIgnoreStart
-                               for ( $i = 2; isset( $refers["${legacyArrayKey}_$i"] ); ++$i );
+                               for ( $i = 2; isset( $refers["${fallbackArrayKey}_$i"] ); ++$i );
                                // @codingStandardsIgnoreEnd
-                               $legacyAnchor .= "_$i";
-                               $refers["${legacyArrayKey}_$i"] = true;
+                               $fallbackAnchor .= "_$i";
+                               $refers["${fallbackArrayKey}_$i"] = true;
                        } else {
-                               $refers[$legacyArrayKey] = true;
+                               $refers[$fallbackArrayKey] = true;
                        }
 
                        # Don't number the heading if it is the only one (looks silly)
@@ -4297,7 +4280,7 @@ class Parser {
                        }
 
                        if ( $enoughToc && ( !isset( $wgMaxTocLevel ) || $toclevel < $wgMaxTocLevel ) ) {
-                               $toc .= Linker::tocLine( $anchor, $tocline,
+                               $toc .= Linker::tocLine( $linkAnchor, $tocline,
                                        $numbering, $toclevel, ( $isTemplate ? false : $sectionIndex ) );
                        }
 
@@ -4364,7 +4347,7 @@ class Parser {
                        }
                        $head[$headlineCount] = Linker::makeHeadline( $level,
                                $matches['attrib'][$headlineCount], $anchor, $headline,
-                               $editlink, $legacyAnchor );
+                               $editlink, $fallbackAnchor );
 
                        $headlineCount++;
                }
@@ -5806,22 +5789,33 @@ class Parser {
                # Strip out wikitext links(they break the anchor)
                $text = $this->stripSectionName( $text );
                $text = Sanitizer::normalizeSectionNameWhitespace( $text );
-               return '#' . Sanitizer::escapeId( $text, 'noninitial' );
+               return '#' . Sanitizer::escapeIdForLink( $text );
        }
 
        /**
         * Same as guessSectionNameFromWikiText(), but produces legacy anchors
-        * instead.  For use in redirects, since IE6 interprets Redirect: headers
-        * as something other than UTF-8 (apparently?), resulting in breakage.
+        * instead, if possible. For use in redirects, since various versions
+        * of Microsoft browsers interpret Location: headers as something other
+        * than UTF-8, resulting in breakage.
         *
         * @param string $text The section name
         * @return string An anchor
         */
        public function guessLegacySectionNameFromWikiText( $text ) {
+               global $wgFragmentMode;
+
                # Strip out wikitext links(they break the anchor)
                $text = $this->stripSectionName( $text );
                $text = Sanitizer::normalizeSectionNameWhitespace( $text );
-               return '#' . Sanitizer::escapeId( $text, [ 'noninitial', 'legacy' ] );
+
+               if ( isset( $wgFragmentMode[1] ) && $wgFragmentMode[1] === 'legacy' ) {
+                       // ForAttribute() and ForLink() are the same for legacy encoding
+                       $id = Sanitizer::escapeIdForAttribute( $text, Sanitizer::ID_FALLBACK );
+               } else {
+                       $id = Sanitizer::escapeIdForLink( $text );
+               }
+
+               return "#$id";
        }
 
        /**
index 2f29200..ad16420 100644 (file)
@@ -79,6 +79,15 @@ class ResourceLoader implements LoggerAwareInterface {
         */
        protected $errors = [];
 
+       /**
+        * List of extra HTTP response headers provided by loaded modules.
+        *
+        * Populated by makeModuleResponse().
+        *
+        * @var array
+        */
+       protected $extraHeaders = [];
+
        /**
         * @var MessageBlobStore
         */
@@ -794,7 +803,7 @@ class ResourceLoader implements LoggerAwareInterface {
                        }
                }
 
-               $this->sendResponseHeaders( $context, $etag, (bool)$this->errors );
+               $this->sendResponseHeaders( $context, $etag, (bool)$this->errors, $this->extraHeaders );
 
                // Remove the output buffer and output the response
                ob_end_clean();
@@ -827,9 +836,12 @@ class ResourceLoader implements LoggerAwareInterface {
         * @param ResourceLoaderContext $context
         * @param string $etag ETag header value
         * @param bool $errors Whether there are errors in the response
+        * @param string[] $extra Array of extra HTTP response headers
         * @return void
         */
-       protected function sendResponseHeaders( ResourceLoaderContext $context, $etag, $errors ) {
+       protected function sendResponseHeaders(
+               ResourceLoaderContext $context, $etag, $errors, array $extra = []
+       ) {
                \MediaWiki\HeaderCallback::warnIfHeadersSent();
                $rlMaxage = $this->config->get( 'ResourceLoaderMaxage' );
                // Use a short cache expiry so that updates propagate to clients quickly, if:
@@ -873,6 +885,9 @@ class ResourceLoader implements LoggerAwareInterface {
                        $exp = min( $maxage, $smaxage );
                        header( 'Expires: ' . wfTimestamp( TS_RFC2822, $exp + time() ) );
                }
+               foreach ( $extra as $header ) {
+                       header( $header );
+               }
        }
 
        /**
@@ -1008,6 +1023,9 @@ class ResourceLoader implements LoggerAwareInterface {
        /**
         * Generate code for a response.
         *
+        * Calling this method also populates the `errors` and `headers` members,
+        * later used by respond().
+        *
         * @param ResourceLoaderContext $context Context in which to generate a response
         * @param ResourceLoaderModule[] $modules List of module objects keyed by module name
         * @param string[] $missing List of requested module names that are unregistered (optional)
@@ -1052,6 +1070,10 @@ MESSAGE;
                                $implementKey = $name . '@' . $module->getVersionHash( $context );
                                $strContent = '';
 
+                               if ( isset( $content['headers'] ) ) {
+                                       $this->extraHeaders = array_merge( $this->extraHeaders, $content['headers'] );
+                               }
+
                                // Append output
                                switch ( $context->getOnly() ) {
                                        case 'scripts':
diff --git a/includes/resourceloader/ResourceLoaderMediaWikiUtilModule.php b/includes/resourceloader/ResourceLoaderMediaWikiUtilModule.php
new file mode 100644 (file)
index 0000000..166f1ba
--- /dev/null
@@ -0,0 +1,53 @@
+<?php
+/**
+ * ResourceLoader mediawiki.util module
+ *
+ * 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
+ */
+
+/**
+ * ResourceLoader module for mediawiki.util
+ *
+ * @since 1.30
+ */
+class ResourceLoaderMediaWikiUtilModule extends ResourceLoaderFileModule {
+       /**
+        * @inheritdoc
+        */
+       public function getScript( ResourceLoaderContext $context ) {
+               return ResourceLoader::makeConfigSetScript(
+                               [ 'wgFragmentMode' => $this->getConfig()->get( 'FragmentMode' ) ]
+                       )
+                       . "\n"
+                       . parent::getScript( $context );
+       }
+
+       /**
+        * @inheritdoc
+        */
+       public function supportsURLLoading() {
+               return false;
+       }
+
+       /**
+        * @inheritdoc
+        */
+       public function enableModuleContentVersion() {
+               return true;
+       }
+}
index 1608901..b3c1cd1 100644 (file)
@@ -586,6 +586,81 @@ abstract class ResourceLoaderModule implements LoggerAwareInterface {
                $this->msgBlobs[$lang] = $blob;
        }
 
+       /**
+        * Get headers to send as part of a module web response.
+        *
+        * It is not supported to send headers through this method that are
+        * required to be unique or otherwise sent once in an HTTP response
+        * because clients may make batch requests for multiple modules (as
+        * is the default behaviour for ResourceLoader clients).
+        *
+        * For exclusive or aggregated headers, see ResourceLoader::sendResponseHeaders().
+        *
+        * @since 1.30
+        * @param ResourceLoaderContext $context
+        * @return string[] Array of HTTP response headers
+        */
+       final public function getHeaders( ResourceLoaderContext $context ) {
+               $headers = [];
+
+               $formattedLinks = [];
+               foreach ( $this->getPreloadLinks( $context ) as $url => $attribs ) {
+                       $link = "<{$url}>;rel=preload";
+                       foreach ( $attribs as $key => $val ) {
+                               $link .= ";{$key}={$val}";
+                       }
+                       $formattedLinks[] = $link;
+               }
+               if ( $formattedLinks ) {
+                       $headers[] = 'Link: ' . implode( ',', $formattedLinks );
+               }
+
+               return $headers;
+       }
+
+       /**
+        * Get a list of resources that web browsers may preload.
+        *
+        * Behaviour of rel=preload link is specified at <https://www.w3.org/TR/preload/>.
+        *
+        * Use case for ResourceLoader originally part of T164299.
+        *
+        * @par Example
+        * @code
+        *     protected function getPreloadLinks() {
+        *         return [
+        *             'https://example.org/script.js' => [ 'as' => 'script' ],
+        *             'https://example.org/image.png' => [ 'as' => 'image' ],
+        *         ];
+        *     }
+        * @encode
+        *
+        * @par Example using HiDPI image variants
+        * @code
+        *     protected function getPreloadLinks() {
+        *         return [
+        *             'https://example.org/logo.png' => [
+        *                 'as' => 'image',
+        *                 'media' => 'not all and (min-resolution: 2dppx)',
+        *             ],
+        *             'https://example.org/logo@2x.png' => [
+        *                 'as' => 'image',
+        *                 'media' => '(min-resolution: 2dppx)',
+        *             ],
+        *         ];
+        *     }
+        * @encode
+        *
+        * @see ResourceLoaderModule::getHeaders
+        * @since 1.30
+        * @param ResourceLoaderContext $context
+        * @return array Keyed by url, values must be an array containing
+        *  at least an 'as' key. Optionally a 'media' key as well.
+        */
+       protected function getPreloadLinks( ResourceLoaderContext $context ) {
+               return [];
+       }
+
        /**
         * Get module-specific LESS variables, if any.
         *
@@ -711,6 +786,11 @@ abstract class ResourceLoaderModule implements LoggerAwareInterface {
                        $content['templates'] = $templates;
                }
 
+               $headers = $this->getHeaders( $context );
+               if ( $headers ) {
+                       $content['headers'] = $headers;
+               }
+
                $statTiming = microtime( true ) - $statStart;
                $statName = strtr( $this->getName(), '.', '_' );
                $stats->timing( "resourceloader_build.all", 1000 * $statTiming );
index 0b7fc2f..aad676f 100644 (file)
@@ -678,7 +678,7 @@ abstract class BaseTemplate extends QuickTemplate {
                }
                foreach ( $validFooterIcons as $blockName => $footerIcons ) {
                        $html .= Html::openElement( 'div', [
-                               'id' => 'f-' . Sanitizer::escapeId( $blockName ) . 'ico',
+                               'id' => Sanitizer::escapeIdForAttribute( "f-{$blockName}ico" ),
                                'class' => 'footer-icons'
                        ] );
                        foreach ( $footerIcons as $icon ) {
@@ -691,7 +691,7 @@ abstract class BaseTemplate extends QuickTemplate {
                        foreach ( $validFooterLinks as $aLink ) {
                                $html .= Html::rawElement(
                                        'li',
-                                       [ 'id' => Sanitizer::escapeId( $aLink ) ],
+                                       [ 'id' => Sanitizer::escapeIdForAttribute( $aLink ) ],
                                        $this->get( $aLink )
                                );
                        }
@@ -734,7 +734,7 @@ abstract class BaseTemplate extends QuickTemplate {
                        $out .= Html::rawElement(
                                'div',
                                [
-                                       'id' => Sanitizer::escapeId( "mw-indicator-$id" ),
+                                       'id' => Sanitizer::escapeIdForAttribute( "mw-indicator-$id" ),
                                        'class' => 'mw-indicator',
                                ],
                                $content
index 40905a5..849362a 100644 (file)
@@ -1375,8 +1375,8 @@ abstract class Skin extends ContextSource {
                                        $bar[$heading][] = array_merge( [
                                                'text' => $text,
                                                'href' => $href,
-                                               'id' => 'n-' . Sanitizer::escapeId( strtr( $line[1], ' ', '-' ), 'noninitial' ),
-                                               'active' => false
+                                               'id' => Sanitizer::escapeIdForAttribute( 'n-' . strtr( $line[1], ' ', '-' ) ),
+                                               'active' => false,
                                        ], $extraAttribs );
                                } else {
                                        continue;
index 0600642..9d6fd5b 100644 (file)
@@ -26,7 +26,9 @@ use MediaWiki\Auth\AuthenticationResponse;
 use MediaWiki\Auth\AuthManager;
 use MediaWiki\Auth\Throttler;
 use MediaWiki\Logger\LoggerFactory;
+use MediaWiki\MediaWikiServices;
 use MediaWiki\Session\SessionManager;
+use Wikimedia\ScopedCallback;
 
 /**
  * Holds shared logic for login and account creation pages.
@@ -212,6 +214,15 @@ abstract class LoginSignupSpecialPage extends AuthManagerSpecialPage {
         * @param string|null $subPage
         */
        public function execute( $subPage ) {
+               if ( $this->mPosted ) {
+                       $time = microtime( true );
+                       $profilingScope = new ScopedCallback( function () use ( $time ) {
+                               $time = microtime( true ) - $time;
+                               $statsd = MediaWikiServices::getInstance()->getStatsdDataFactory();
+                               $statsd->timing( "timing.login.ui.{$this->authAction}", $time * 1000 );
+                       } );
+               }
+
                $authManager = AuthManager::singleton();
                $session = SessionManager::getGlobalSession();
 
index cd9345d..cf9ae07 100644 (file)
@@ -66,6 +66,7 @@ class BrokenRedirectsPage extends QueryPage {
                                'value' => 'p1.page_title',
                                'rd_namespace',
                                'rd_title',
+                               'rd_fragment',
                        ],
                        'conds' => [
                                // Exclude pages that don't exist locally as wiki pages,
@@ -102,7 +103,7 @@ class BrokenRedirectsPage extends QueryPage {
        function formatResult( $skin, $result ) {
                $fromObj = Title::makeTitle( $result->namespace, $result->title );
                if ( isset( $result->rd_title ) ) {
-                       $toObj = Title::makeTitle( $result->rd_namespace, $result->rd_title );
+                       $toObj = Title::makeTitle( $result->rd_namespace, $result->rd_title, $result->rd_fragment );
                } else {
                        $blinks = $fromObj->getBrokenLinksFrom(); # TODO: check for redirect, not for links
                        if ( $blinks ) {
@@ -139,7 +140,7 @@ class BrokenRedirectsPage extends QueryPage {
                                [ 'action' => 'edit' ]
                        );
                }
-               $to = $linkRenderer->makeBrokenLink( $toObj );
+               $to = $linkRenderer->makeBrokenLink( $toObj, $toObj->getFullText() );
                $arr = $this->getLanguage()->getArrow();
 
                $out = $from . $this->msg( 'word-separator' )->escaped();
index 3845649..1b14fcb 100644 (file)
@@ -131,17 +131,14 @@ class SpecialContributions extends IncludableSpecialPage {
 
                $skip = $request->getText( 'offset' ) || $request->getText( 'dir' ) == 'prev';
                # Offset overrides year/month selection
-               if ( $skip ) {
-                       $this->opts['year'] = '';
-                       $this->opts['month'] = '';
-               } else {
+               if ( !$skip ) {
                        $this->opts['year'] = $request->getVal( 'year' );
                        $this->opts['month'] = $request->getVal( 'month' );
 
                        $this->opts['start'] = $request->getVal( 'start' );
                        $this->opts['end'] = $request->getVal( 'end' );
-                       $this->opts = ContribsPager::processDateFilter( $this->opts );
                }
+               $this->opts = ContribsPager::processDateFilter( $this->opts );
 
                $feedType = $request->getVal( 'feed' );
 
index d7e99db..ba14c66 100644 (file)
@@ -66,14 +66,15 @@ class DoubleRedirectsPage extends QueryPage {
                                'title' => 'pa.page_title',
                                'value' => 'pa.page_title',
 
-                               'nsb' => 'pb.page_namespace',
-                               'tb' => 'pb.page_title',
+                               'b_namespace' => 'pb.page_namespace',
+                               'b_title' => 'pb.page_title',
 
                                // Select fields from redirect instead of page. Because there may
                                // not actually be a page table row for this target (e.g. for interwiki redirects)
-                               'nsc' => 'rb.rd_namespace',
-                               'tc' => 'rb.rd_title',
-                               'iwc' => 'rb.rd_interwiki',
+                               'c_namespace' => 'rb.rd_namespace',
+                               'c_title' => 'rb.rd_title',
+                               'c_fragment' => 'rb.rd_fragment',
+                               'c_interwiki' => 'rb.rd_interwiki',
                        ],
                        'conds' => [
                                'ra.rd_from = pa.page_id',
@@ -116,14 +117,12 @@ class DoubleRedirectsPage extends QueryPage {
         * @return string
         */
        function formatResult( $skin, $result ) {
-               $titleA = Title::makeTitle( $result->namespace, $result->title );
-
-               // If only titleA is in the query, it means this came from
-               // querycache (which only saves 3 columns).
+               // If no Title B or C is in the query, it means this came from
+               // querycache (which only saves the 3 columns for title A).
                // That does save the bulk of the query cost, but now we need to
                // get a little more detail about each individual entry quickly
                // using the filter of reallyGetQueryInfo.
-               if ( $result && !isset( $result->nsb ) ) {
+               if ( $result && !isset( $result->b_namespace ) ) {
                        $dbr = wfGetDB( DB_REPLICA );
                        $qi = $this->reallyGetQueryInfo(
                                $result->namespace,
@@ -140,21 +139,14 @@ class DoubleRedirectsPage extends QueryPage {
                                $result = $dbr->fetchObject( $res );
                        }
                }
+
+               $titleA = Title::makeTitle( $result->namespace, $result->title );
+
                $linkRenderer = $this->getLinkRenderer();
                if ( !$result ) {
                        return '<del>' . $linkRenderer->makeLink( $titleA, null, [], [ 'redirect' => 'no' ] ) . '</del>';
                }
 
-               $titleB = Title::makeTitle( $result->nsb, $result->tb );
-               $titleC = Title::makeTitle( $result->nsc, $result->tc, '', $result->iwc );
-
-               $linkA = $linkRenderer->makeKnownLink(
-                       $titleA,
-                       null,
-                       [],
-                       [ 'redirect' => 'no' ]
-               );
-
                // if the page is editable, add an edit link
                if (
                        // check user permissions
@@ -172,6 +164,14 @@ class DoubleRedirectsPage extends QueryPage {
                        $edit = '';
                }
 
+               $linkA = $linkRenderer->makeKnownLink(
+                       $titleA,
+                       null,
+                       [],
+                       [ 'redirect' => 'no' ]
+               );
+
+               $titleB = Title::makeTitle( $result->b_namespace, $result->b_title );
                $linkB = $linkRenderer->makeKnownLink(
                        $titleB,
                        null,
@@ -179,7 +179,13 @@ class DoubleRedirectsPage extends QueryPage {
                        [ 'redirect' => 'no' ]
                );
 
-               $linkC = $linkRenderer->makeKnownLink( $titleC );
+               $titleC = Title::makeTitle(
+                       $result->c_namespace,
+                       $result->c_title,
+                       $result->c_fragment,
+                       $result->c_interwiki
+               );
+               $linkC = $linkRenderer->makeKnownLink( $titleC, $titleC->getFullText() );
 
                $lang = $this->getLanguage();
                $arr = $lang->getArrow() . $lang->getDirMark();
@@ -201,13 +207,13 @@ class DoubleRedirectsPage extends QueryPage {
                $batch = new LinkBatch;
                foreach ( $res as $row ) {
                        $batch->add( $row->namespace, $row->title );
-                       if ( isset( $row->nsb ) ) {
+                       if ( isset( $row->b_namespace ) ) {
                                // lazy loaded when using cached results
-                               $batch->add( $row->nsb, $row->tb );
+                               $batch->add( $row->b_namespace, $row->b_title );
                        }
-                       if ( isset( $row->iwc ) && !$row->iwc ) {
+                       if ( isset( $row->c_interwiki ) && !$row->c_interwiki ) {
                                // lazy loaded when using cached result, not added when interwiki link
-                               $batch->add( $row->nsc, $row->tc );
+                               $batch->add( $row->c_namespace, $row->c_title );
                        }
                }
                $batch->execute();
index a827e89..beb454d 100644 (file)
@@ -173,10 +173,8 @@ class SpecialImport extends SpecialPage {
 
                $out = $this->getOutput();
                if ( !$source->isGood() ) {
-                       $out->wrapWikiMsg(
-                               "<p class=\"error\">\n$1\n</p>",
-                               [ 'importfailed', $source->getWikiText() ]
-                       );
+                       $out->addWikiText( "<p class=\"error\">\n" .
+                               $this->msg( 'importfailed', $source->getWikiText() )->parse() . "\n</p>" );
                } else {
                        $importer = new WikiImporter( $source->value, $this->getConfig() );
                        if ( !is_null( $this->namespace ) ) {
index 2c92410..1a04eec 100644 (file)
@@ -69,7 +69,7 @@ class SpecialListGrants extends SpecialPage {
                                $grantCellHtml = '<ul><li>' . implode( "</li>\n<li>", $descs ) . '</li></ul>';
                        }
 
-                       $id = \Sanitizer::escapeId( $grant );
+                       $id = Sanitizer::escapeIdForAttribute( $grant );
                        $out->addHTML( \Html::rawElement( 'tr', [ 'id' => $id ],
                                "<td>" .
                                $this->msg(
index 7a25e55..2315887 100644 (file)
@@ -126,7 +126,7 @@ class SpecialListGroupRights extends SpecialPage {
                                ? $groupsRemoveFromSelf[$group]
                                : [];
 
-                       $id = $group == '*' ? false : Sanitizer::escapeId( $group );
+                       $id = $group == '*' ? false : Sanitizer::escapeIdForAttribute( $group );
                        $out->addHTML( Html::rawElement( 'tr', [ 'id' => $id ], "
                                <td>$grouppage$grouplink</td>
                                        <td>" .
index 5f38629..f81c03c 100644 (file)
@@ -137,7 +137,7 @@ class ListredirectsPage extends QueryPage {
                        # Make a link to the destination page
                        $lang = $this->getLanguage();
                        $arr = $lang->getArrow() . $lang->getDirMark();
-                       $targetLink = $linkRenderer->makeLink( $target );
+                       $targetLink = $linkRenderer->makeLink( $target, $target->getFullText() );
 
                        return "$rd_link $arr $targetLink";
                } else {
index 1f8e3c5..6ef75e0 100644 (file)
@@ -189,12 +189,18 @@ class SpecialRecentChanges extends ChangesListSpecialPage {
                                'wgStructuredChangeFiltersEnableLiveUpdate',
                                $this->getConfig()->get( 'StructuredChangeFiltersEnableLiveUpdate' )
                        );
-                       if ( $experimentalStructuredChangeFilters ) {
-                               $out->addJsConfigVars(
-                                       'wgRCFiltersChangeTags',
-                                       $this->buildChangeTagList()
-                               );
-                       }
+                       $out->addJsConfigVars(
+                               'wgRCFiltersChangeTags',
+                               $this->buildChangeTagList()
+                       );
+                       $out->addJsConfigVars(
+                               'StructuredChangeFiltersDisplayConfig',
+                               [
+                                       'maxDays' => (int)$this->getConfig()->get( 'RCMaxAge' ) / ( 24 * 3600 ), // Translate to days
+                                       'limitArray' => $this->getConfig()->get( 'RCLinkLimits' ),
+                                       'daysArray' => $this->getConfig()->get( 'RCLinkDays' ),
+                               ]
+                       );
                }
        }
 
index eeb8823..8afea0b 100644 (file)
@@ -352,7 +352,7 @@ class SpecialSearch extends SpecialPage {
                        $out->addHTML( $dymWidget->render( $term, $textMatches ) );
                }
 
-               $hasErrors = $textStatus && $textStatus->getErrors();
+               $hasErrors = $textStatus && $textStatus->getErrors() !== [];
                $hasOtherResults = $textMatches &&
                        $textMatches->hasInterwikiResults( SearchResultSet::INLINE_RESULTS );
 
index 77b6926..5ff9e04 100644 (file)
@@ -68,7 +68,7 @@ class UncategorizedCategoriesPage extends UncategorizedPagesPage {
        }
 
        public function getQueryInfo() {
-               $dbr = wfGetDB( DB_SLAVE );
+               $dbr = wfGetDB( DB_REPLICA );
                $query = parent::getQueryInfo();
                $exceptionList = $this->getExceptionList();
                if ( $exceptionList ) {
index 28914f4..740207d 100644 (file)
@@ -277,7 +277,7 @@ class SpecialUndelete extends SpecialPage {
                        $fieldset,
                        new OOUI\HtmlSnippet(
                                Html::hidden( 'title', $this->getPageTitle()->getPrefixedDBkey() ) .
-                               Html::hidden( 'fuzzy', $this->getRequest()->getVal( 'fuzzy' ) )
+                               Html::hidden( 'fuzzy', $fuzzySearch )
                        )
                );
 
index 30c4a0b..3ea1d03 100644 (file)
@@ -840,7 +840,7 @@ class SpecialVersion extends SpecialPage {
                // Finally! Create the table
                $html = Html::openElement( 'tr', [
                                'class' => 'mw-version-ext',
-                               'id' => Sanitizer::escapeId( 'mw-version-ext-' . $type . '-' . $extension['name'] )
+                               'id' => Sanitizer::escapeIdForAttribute( 'mw-version-ext-' . $type . '-' . $extension['name'] )
                        ]
                );
 
index 549362f..9e01d2d 100644 (file)
@@ -277,7 +277,6 @@ class SpecialWatchlist extends ChangesListSpecialPage {
 
                # Toggle watchlist content (all recent edits or just the latest)
                if ( $opts['extended'] ) {
-                       $limitWatchlist = $user->getIntOption( 'wllimit' );
                        $usePage = false;
                } else {
                        # Top log Ids for a page are not stored
@@ -292,14 +291,16 @@ class SpecialWatchlist extends ChangesListSpecialPage {
                                        LIST_OR
                                );
                        }
-                       $limitWatchlist = 0;
                        $usePage = true;
                }
 
                $tables = array_merge( [ 'recentchanges', 'watchlist' ], $tables );
                $fields = array_merge( RecentChange::selectFields(), $fields );
 
-               $query_options = array_merge( [ 'ORDER BY' => 'rc_timestamp DESC' ], $query_options );
+               $query_options = array_merge( [
+                       'ORDER BY' => 'rc_timestamp DESC',
+                       'LIMIT' => $user->getIntOption( 'wllimit' )
+               ], $query_options );
                $join_conds = array_merge(
                        [
                                'watchlist' => [
@@ -317,9 +318,6 @@ class SpecialWatchlist extends ChangesListSpecialPage {
                if ( $this->getConfig()->get( 'ShowUpdatedMarker' ) ) {
                        $fields[] = 'wl_notificationtimestamp';
                }
-               if ( $limitWatchlist ) {
-                       $query_options['LIMIT'] = $limitWatchlist;
-               }
 
                $rollbacker = $user->isAllowed( 'rollback' );
                if ( $usePage || $rollbacker ) {
index ca1b7dc..e6a0f0b 100644 (file)
@@ -375,7 +375,9 @@ class AllMessagesTablePager extends TablePager {
                }
 
                if ( !$isSecond ) {
-                       $arr['id'] = Sanitizer::escapeId( 'msg_' . $this->getLanguage()->lcfirst( $row->am_title ) );
+                       $arr['id'] = Sanitizer::escapeIdForAttribute(
+                               'msg_' . $this->getLanguage()->lcfirst( $row->am_title )
+                       );
                }
 
                return $arr;
index 6bd7eb0..d7819c4 100644 (file)
@@ -583,10 +583,10 @@ class ContribsPager extends RangeChronologicalPager {
         * @return array Options array with processed start and end date filter options
         */
        public static function processDateFilter( $opts ) {
-               $start = $opts['start'] ?: '';
-               $end = $opts['end'] ?: '';
-               $year = $opts['year'] ?: '';
-               $month = $opts['month'] ?: '';
+               $start = isset( $opts['start'] ) ? $opts['start'] : '';
+               $end = isset( $opts['end'] ) ? $opts['end'] : '';
+               $year = isset( $opts['year'] ) ? $opts['year'] : '';
+               $month = isset( $opts['month'] ) ? $opts['month'] : '';
 
                if ( $start !== '' && $end !== '' && $start > $end ) {
                        $temp = $start;
index cbd4676..7e59432 100644 (file)
                "resources/src/jquery/jquery.suggestions.js",
                "resources/src/jquery/jquery.tabIndex.js",
                "resources/lib/jquery.client/jquery.client.js",
-               "resources/lib/oojs",
-               "resources/lib/oojs-ui"
+               "resources/lib/oojs/oojs.jquery.js",
+               "resources/lib/oojs-ui/oojs-ui-core.js",
+               "resources/lib/oojs-ui/oojs-ui-widgets.js",
+               "resources/lib/oojs-ui/oojs-ui-toolbars.js",
+               "resources/lib/oojs-ui/oojs-ui-windows.js",
+               "resources/lib/oojs-ui/oojs-ui-wikimediaui.js",
+               "resources/lib/oojs-ui/oojs-ui-apex.js"
        ]
 }
index 12f26c3..92dad9b 100644 (file)
@@ -1092,7 +1092,7 @@ class Language {
         *      YYYYMMDDHHMMSS
         *      01234567890123
         * @param DateTimeZone $zone Timezone of $ts
-        * @param[out] int $ttl The amount of time (in seconds) the output may be cached for.
+        * @param int &$ttl The amount of time (in seconds) the output may be cached for.
         * Only makes sense if $ts is the current time.
         * @todo handling of "o" format character for Iranian, Hebrew, Hijri & Thai?
         *
@@ -4537,7 +4537,7 @@ class Language {
        public function formatExpiry( $expiry, $format = true, $infinity = 'infinity' ) {
                static $dbInfinity;
                if ( $dbInfinity === null ) {
-                       $dbInfinity = wfGetDB( DB_SLAVE )->getInfinity();
+                       $dbInfinity = wfGetDB( DB_REPLICA )->getInfinity();
                }
 
                if ( $expiry == '' || $expiry === 'infinity' || $expiry == $dbInfinity ) {
index 69e204c..d7243a9 100644 (file)
        "tog-shownumberswatching": "اعرض عدد المستخدمين المراقبين",
        "tog-oldsig": "توقيعك الحالي:",
        "tog-fancysig": "جعل التوقيع  مثل نص الويكي  (دون  وصلة تلقائية)",
-       "tog-uselivepreview": "استعÙ\85اÙ\84 Ø§Ù\84Ù\85عاÙ\8aÙ\86Ø© Ø§Ù\84Ù\85باشرة",
+       "tog-uselivepreview": "عرض Ø§Ù\84Ù\85عاÙ\8aÙ\86ات Ø¨Ø¯Ù\88Ù\86 Ø¥Ø¹Ø§Ø¯Ø© ØªØ­Ù\85Ù\8aÙ\84 Ø§Ù\84صÙ\81Ø­ة",
        "tog-forceeditsummary": "نبهني عند عدم إدخال ملخص تعديل",
        "tog-watchlisthideown": "أخف تعديلاتي من قائمة المراقبة",
        "tog-watchlisthidebots": "أخف تعديلات البوتات من قائمة المراقبة",
        "prefs-editwatchlist-clear": "امسح قائمة المراقبة",
        "prefs-watchlist-days": "عدد الأيام للعرض في قائمة المراقبة:",
        "prefs-watchlist-days-max": "الحد الأقصى {{PLURAL:$1|أقل من يوم|يوم واحد|يومان|$1 أيام|$1 يوما|$1 يوم}}",
-       "prefs-watchlist-edits": "عدد التعديلات التي تعرض في قائمة المراقبة الموسعة:",
+       "prefs-watchlist-edits": "عدد التعديلات التي تعرض في قائمة المراقبة:",
        "prefs-watchlist-edits-max": "العدد الأقصى: 1000",
        "prefs-watchlist-token": "مفتاح قائمة المراقبة:",
        "prefs-misc": "متفرقات",
        "rcfilters-activefilters": "المرشحات النشطة",
        "rcfilters-advancedfilters": "مرشحات متقدمة",
        "rcfilters-limit-title": "عدد التعديلات",
-       "rcfilters-limit-shownum": "اعرض Ø¢Ø®Ø± $1 ØªØ¹Ø¯Ù\8aÙ\84",
+       "rcfilters-limit-shownum": "إظÙ\87ار Ø¢Ø®Ø± {{PLURAL:$1|تغÙ\8aÙ\8aر|$1 ØªØºÙ\8aÙ\8aرات}}",
        "rcfilters-days-title": "عدد الأيام الأخيرة",
        "rcfilters-hours-title": "عدد الساعات الأخيرة",
        "rcfilters-days-show-days": "{{PLURAL:$1|يوما واحدا|يومان|$1 أيام|$1 يوما}}",
        "rcfilters-invalid-filter": "مرشح غير صحيح",
        "rcfilters-empty-filter": "لا مرشحات فعالة. كل المساهمات معروضة.",
        "rcfilters-filterlist-title": "مرشحات",
-       "rcfilters-filterlist-whatsthis": "Ù\85ا Ù\87ذا؟",
+       "rcfilters-filterlist-whatsthis": "Ù\83Ù\8aÙ\81 ØªØ¹Ù\85Ù\84 Ù\87Ø°Ù\87؟",
        "rcfilters-filterlist-feedbacklink": "تقديم مراجعات لمرشحات (بيتا) الجديدة",
        "rcfilters-highlightbutton-title": "التعليم على النتائج",
        "rcfilters-highlightmenu-title": "اختر لونًا",
        "rcfilters-filter-editsbyself-description": "مساهماتك الشخصية.",
        "rcfilters-filter-editsbyother-label": "التغييرات بواسطة الآخرين",
        "rcfilters-filter-editsbyother-description": "كل التغييرات باستثناء تغييراتك.",
-       "rcfilters-filtergroup-userExpLevel": "مستوى الخبرة (للمستخدمين المسجلين فقط)",
-       "rcfilters-filter-user-experience-level-registered-label": "مسجل",
-       "rcfilters-filter-user-experience-level-registered-description": "المحررون مسجلو الدخول.",
-       "rcfilters-filter-user-experience-level-unregistered-label": "غير مسجل",
-       "rcfilters-filter-user-experience-level-unregistered-description": "اÙ\84Ù\85حررÙ\88Ù\86 ØºÙ\8aر Ù\85سجÙ\84Ù\8a الدخول.",
+       "rcfilters-filtergroup-userExpLevel": "تسجيل المستخدم وخبرته",
+       "rcfilters-filter-user-experience-level-registered-label": "مسجل الدخول",
+       "rcfilters-filter-user-experience-level-registered-description": "المحررون المسجلون.",
+       "rcfilters-filter-user-experience-level-unregistered-label": "غير المسجلين",
+       "rcfilters-filter-user-experience-level-unregistered-description": "اÙ\84Ù\85حررÙ\88Ù\86 Ø§Ù\84Ø°Ù\8aÙ\86 Ù\84Ù\85 Ù\8aسجÙ\84Ù\88ا الدخول.",
        "rcfilters-filter-user-experience-level-newcomer-label": "القادمون الجدد",
-       "rcfilters-filter-user-experience-level-newcomer-description": "Ø£Ù\82Ù\84 Ù\85Ù\86 10 ØªØ¹Ø¯Ù\8aÙ\84ات Ù\884 أيام من النشاط.",
+       "rcfilters-filter-user-experience-level-newcomer-description": "اÙ\84Ù\85حررÙ\88Ù\86 Ø§Ù\84Ù\85سجÙ\84Ù\88Ù\86 Ø§Ù\84Ø°Ù\8aÙ\86 Ù\84دÙ\8aÙ\87Ù\85 Ø£Ù\82Ù\84 Ù\85Ù\86 10 ØªØ¹Ø¯Ù\8aÙ\84ات Ù\88 4 أيام من النشاط.",
        "rcfilters-filter-user-experience-level-learner-label": "المتعلمون",
-       "rcfilters-filter-user-experience-level-learner-description": "خبرة Ø£Ù\83ثر Ù\85Ù\86 \"اÙ\84Ù\82ادÙ\85Ù\8aÙ\86 Ø§Ù\84جدد\" Ù\88Ù\84Ù\83Ù\86 Ø£Ù\82Ù\84 Ù\85Ù\86 \"المستخدمين ذوي الخبرة\".",
+       "rcfilters-filter-user-experience-level-learner-description": "اÙ\84Ù\85حررÙ\88Ù\86 Ø§Ù\84Ù\85سجÙ\84Ù\88Ù\86 Ø§Ù\84Ø°Ù\8aÙ\86 ØªÙ\82ع ØªØ¬Ø±Ø¨ØªÙ\87Ù\85 Ø¨Ù\8aÙ\86 \"اÙ\84Ù\82ادÙ\85Ù\8aÙ\86 Ø§Ù\84جدد\" Ù\88 \"المستخدمين ذوي الخبرة\".",
        "rcfilters-filter-user-experience-level-experienced-label": "المستخدمون ذوو الخبرة",
-       "rcfilters-filter-user-experience-level-experienced-description": "Ø£Ù\83ثر Ù\85Ù\86 30 Ù\8aÙ\88Ù\85ا Ù\85Ù\86 Ø§Ù\84Ù\86شاط Ù\88500 ØªØ¹Ø¯Ù\8aÙ\84.",
+       "rcfilters-filter-user-experience-level-experienced-description": "اÙ\84Ù\85حررÙ\88Ù\86 Ø§Ù\84Ù\85سجÙ\84Ù\88Ù\86 Ø§Ù\84Ø°Ù\8aÙ\86 Ù\84دÙ\8aÙ\87Ù\85 Ø£Ù\83ثر Ù\85Ù\86 500 ØªØ¹Ø¯Ù\8aÙ\84 Ù\88 30 Ù\8aÙ\88Ù\85ا Ù\85Ù\86 Ø§Ù\84Ù\86شاط.",
        "rcfilters-filtergroup-automated": "المساهمات الأوتوماتيكية",
        "rcfilters-filter-bots-label": "بوت",
        "rcfilters-filter-bots-description": "التعديلات بواسطة الأدوات الأوتوماتيكية.",
        "rcfilters-hideminor-conflicts-typeofchange-global": "مرشح \"التعديلات الطفيفة\" يتعارض مع مرشح واحد أو أكثر من مرشحات نوع التغيير، وذلك لأن بعض أنواع التغيير لا يمكن التعليم عليها ك\"طفيفة.\" المرشحات المتعارضة معلم عليها في مساحة المرشحات النشطة بالأعلى.",
        "rcfilters-hideminor-conflicts-typeofchange": "بعض أنواع التغييرات لا يمكن التعليم عليها ك\"طفيفة،\" لذا فهذا المرشح يتعارض مع مرشحات نوع التغيير التالية: $1",
        "rcfilters-typeofchange-conflicts-hideminor": "مرشح نوع التغيير هذا يتعارض مع مرشح \"التعديلات الطفيفة\". بعض أنواع التغييرات لا يمكن التعليم عليها ك\"طفيفة.\"",
-       "rcfilters-filtergroup-lastRevision": "آخر Ù\85راجعة",
+       "rcfilters-filtergroup-lastRevision": "أحدث Ø§Ù\84Ù\85راجعات",
        "rcfilters-filter-lastrevision-label": "آخر مراجعة",
-       "rcfilters-filter-lastrevision-description": "أخر تعديل للصفحة.",
-       "rcfilters-filter-previousrevision-label": "Ù\86سخ Ø³Ø§Ø¨Ù\82ة",
-       "rcfilters-filter-previousrevision-description": "كل تعديلات الصفحة ما عدا التعديل الأخير.",
+       "rcfilters-filter-lastrevision-description": "فقط أحدث التغييرات التي طرأت على الصفحة.",
+       "rcfilters-filter-previousrevision-label": "Ù\84Ù\8aس Ø¢Ø®Ø± Ù\85راجعة",
+       "rcfilters-filter-previousrevision-description": "جميع التغييرات ما عدا \"أحدث مراجعة\".",
        "rcfilters-tag-prefix-namespace-inverted": "<strong>:ليس</strong> $1",
        "rcfilters-view-tags": "تعديلات موسومة",
        "rcfilters-view-namespaces-tooltip": "رشح النتائج حسب النطاق",
        "import-nonewrevisions": "لا مراجعات تم استيرادها (كل المراجعات إما أنها كانت موجودة بالفعل، وأو تم تجاوزها نتيجة أخطاء).",
        "xml-error-string": "$1 عند السطر $2، العمود $3 (بايت $4): $5",
        "import-upload": "رفع بيانات XML",
-       "import-token-mismatch": "فقد لبيانات الجلسة.\n\nأنت لابد من أنه قد تم تسجيل خروجك. <strong>من فضلك تأكد من أنك مازلت مسجل الدخول وحاول مرة أخرى</strong>.\nلو كان مازال لا يعمل، فحاول [[Special:UserLogout|تسجيل الخروج]] وتسجيل الدخول مرة أخرى، وتحقق من أن متصفحك يسمح بالكوكيز من هذا الموقع.",
+       "import-token-mismatch": "فقد لبيانات الجلسة.\nربما تم تسجيل خروجك. '''الرجاء التحقق من أنك لا تزال مسجلا الدخول وإعادة المحاولة'''.\nإذا كان لا يزال لا يعمل، حاول [[Special:UserLogout|تسجيل الخروج]] وتسجيل الدخول مرة أخرى، وتحقق من أن متصفحك يسمح بملفات تعريف الارتباط من هذا الموقع.",
        "import-invalid-interwiki": "لم يمكن الاستيراد من الويكي المحدد.",
        "import-error-edit": "الصفحة \"$1\" لم يتم استيرادها لأنه لا يمكن لك تحريرها.",
        "import-error-create": "الصفحة \"$1\" لم يتم استيرادها لأنه لا يمكن لك استحداثها أصلا.",
index c098ef2..bef877b 100644 (file)
@@ -14,7 +14,8 @@
                        "Macofe",
                        "Matma Rex",
                        "Tokvo",
-                       "Crucifunked"
+                       "Crucifunked",
+                       "Enolp"
                ]
        },
        "tog-underline": "Sorrayar enllaces:",
        "recentchanges-legend-plusminus": "(''±123'')",
        "recentchanges-submit": "Amosar",
        "rcfilters-legend-heading": "<strong>Llista d'abreviatures:</strong>",
+       "rcfilters-other-review-tools": "<strong>Otres ferramientes de revisión</strong>",
        "rcfilters-activefilters": "Filtros activos",
        "rcfilters-advancedfilters": "Filtros avanzaos",
        "rcfilters-limit-title": "Cambios a amosar",
index 3dbda51..34b0184 100644 (file)
@@ -4,7 +4,8 @@
                        "1AnuraagPandey",
                        "राम प्रसाद जोशी",
                        "Macofe",
-                       "Matma Rex"
+                       "Matma Rex",
+                       "Sfic"
                ]
        },
        "tog-underline": "कड़ि अधोरेखन:",
        "anontalk": "ई आइ॰पी कय खरतिन बातचीत",
        "navigation": "घुमाई",
        "and": "&#32;अउर",
-       "qbfind": "खोजा जाय",
-       "qbbrowse": "ब्राउज़",
-       "qbedit": "सम्पादन",
-       "qbpageoptions": "ई पन्ना",
-       "qbmyoptions": "हमार पन्ना",
        "faq": "साधारण सवाल",
-       "faqpage": "Project:ढेर पूछा जाय वाला सवाल",
        "actions": "काम कुल",
        "namespaces": "नामस्थान",
        "variants": "संस्करण",
        "edit-local": "स्थानीय विवरण सम्पादन",
        "create": "बनावो",
        "create-local": "स्थानीय विवरण जोडो",
-       "editthispage": "ई पन्ना कय सम्पादन करा जाय",
-       "create-this-page": "ई पन्ना बनावा जाय",
        "delete": "मिटावा जाय",
-       "deletethispage": "ई पन्ना मेटावा जाय",
-       "undeletethispage": "ई पन्ना कय पुनर्स्थापित करा जाय।",
        "undelete_short": "{{PLURAL:$1|एक मेटाई गय}} बदलाव वापिस लाओ",
        "viewdeleted_short": "देखा जाय {{PLURAL:$1|एक मेटावल सम्पादन|$1 मेटावल सम्पादन}}",
        "protect": "सुरक्षित करा जाय",
        "protect_change": "बदला जाय",
-       "protectthispage": "इ पन्ना कय सुरक्षित करा जाय",
        "unprotect": "असुरक्षित",
-       "unprotectthispage": "ई पन्ना कय सुरक्षा स्तर बदला जाय",
        "newpage": "नँवा पन्ना",
-       "talkpage": "ई पन्ना कय बारे मे चर्चा करा जाय",
        "talkpagelinktext": "बातचीत",
        "specialpage": "विशेष पन्ना",
        "personaltools": "वैयक्तिक औज़ार",
-       "articlepage": "सामग्री पन्ना देखा जाय",
        "talk": "चर्चा",
        "views": "दर्शाव",
        "toolbox": "औजार कय बक्सा",
-       "userpage": "सदस्य पन्ना देखा जाय",
-       "projectpage": "परियोजना पन्ना देखा जाय",
        "imagepage": "फ़ाइल पन्ना देखा जाय",
        "mediawikipage": "सनेशा पन्ना देखा जाय",
        "templatepage": "साँचा पन्ना देखा जाय",
        "querypage-disabled": "प्रदर्शन कारणन् से इ विशेष पन्ना अक्षम कै गा है।",
        "apihelp": "API सहयोग",
        "apihelp-no-such-module": "मोड्युल \"$1\" नाइ मिला ।",
-       "apisandbox": "à¤\8f॰पà¥\80॰à¤\86à¤\87 प्रयोगस्थल",
+       "apisandbox": "à¤\8fपà¥\80à¤\86à¤\88 प्रयोगस्थल",
        "apisandbox-api-disabled": "इ साइट पे ए.पी.आइ अक्षम है ।",
        "apisandbox-submit": "अनुरोध करा जाय",
        "apisandbox-reset": "स्पष्ट",
        "fileduplicatesearch-noresults": "कवनो \"$1\" फाइल नाइ मिला।",
        "specialpages": "खाश पन्ना",
        "specialpages-note-top": "कुंजी",
-       "specialpages-note": "* साधारण विशेष पन्ना।\n* <span class=\"mw-specialpagerestricted\">प्रतिबंधित विशेष पन्ना।</span>",
        "specialpages-group-maintenance": "अनुरक्षण रिपोर्ट",
        "specialpages-group-other": "अउर खाश पन्ना",
        "specialpages-group-login": "लाग इन / खाता खोला जाय",
index b1441ff..3808631 100644 (file)
        "cannotchangeemail": "حساب ایمیل آدرسلری بو ویکی‌ده دَییشیلنمزلر.",
        "emaildisabled": "بو سایت ایمیل گؤندرنمز.",
        "accountcreated": "حساب یارادیلدی",
-       "accountcreatedtext": "[[{{ns:User}}:$1|$1]] ([[{{ns:User talk}}:$1|داÙ\86Û\8cØ´Û\8cÙ\82]]) Ø§Û\8cستÛ\8cÙ\81ادÙ\87â\80\8cÚ\86Û\8c حسابی یارادیلیب‌دیر.",
+       "accountcreatedtext": "[[{{ns:User}}:$1|$1]] ([[{{ns:User talk}}:$1|داÙ\86Û\8cØ´Û\8cÙ\82]]) Ø§Û\8cØ´Ù\84دÙ\86 حسابی یارادیلیب‌دیر.",
        "createaccount-title": "{{SITENAME}} اوچون حساب یارادیلماسی",
        "createaccount-text": "بیر کس، سیزین ایمیل آدرسینیزه {{SITENAME}} ($4) سایتیندا «$2» آدی و «$3» رمزی ایله بیر حساب آچیب‌دیر. سیز گرک گیریش ائدیب و رمزینیزی ایندی دَییشدیره‌سیز.\n\nبو حساب یانلیش دوزلیب‌سه، بو مئساژا محل قویمایابیلرسیز.",
        "login-throttled": "سیزین چوخ گیریش چالیشماغینیز اولوب‌دور.\nلوطفاً یئنی‌دن چالیشماق‌دان اؤنجه بیر آز $1 دؤزون.",
        "autosumm-replace": "صفحه‌‌نین مضمونونو ' $1' يازیسی ایله ديَیشدیریلدی",
        "autoredircomment": "[[$1]] صفحه‌‌سینه یوْللاندیریلیر",
        "autosumm-new": "صفحه‌‌نی ' $1' ایله ياراتدی",
-       "autosumm-newblank": "بوش صحفه یاراندی",
+       "autosumm-newblank": "بوش صفحه یاراندی",
        "lag-warn-normal": "$1 {{PLURAL:$1 | سانیيه‌دن | سانیيه‌ده}} يئنی ديَیشیکلیکلر بو سیياهیدا گؤرولمه‌يه.",
        "lag-warn-high": "وئریلنلر بازاسی سونوجوسونداکی هددیندن آرتیق گئجیکمه‌دن گؤره، $1 {{PLURAL:$1 | سانیيه‌دن | سانیيه‌دن}} يئنی ديَیشیکلیکلر بو سیياهیدا گؤرونمئيئبیلیر.",
        "watchlistedit-normal-title": "ایزله‌دیکلریم صفحه‌‌لری دَییشدیر",
        "fileduplicatesearch-result-n": "«$1» فایلینین، {{PLURAL:$2|بیر|$2}} عینی کوپیسی واردیر.",
        "fileduplicatesearch-noresults": "\"$1\" آدیندا فایل تاپیلمادی.",
        "specialpages": "اؤزل صفحه‌لر",
-       "specialpages-note": "* نورمال اؤزل صفحه‌لر.\n* <span class=\"mw-specialpagerestricted\">محدودلاشدیریلمیش اؤزل صفحه‌لر.</span>",
        "specialpages-group-maintenance": "ساخلانیش گوزاریشلری",
        "specialpages-group-other": "آیری اؤزل صفحه‌لر",
        "specialpages-group-login": "گیریش / حساب یارات",
index 9b11402..5a51975 100644 (file)
@@ -58,7 +58,7 @@
        "tog-shownumberswatching": "Битте күҙәтеү исемлегенә өҫтәгән ҡулланыусылар һанын күрһәтергә",
        "tog-oldsig": "Хәҙерге имза:",
        "tog-fancysig": "Имзаның үҙ вики-тамғаһы (автоматик һылтанмаһыҙ)",
-       "tog-uselivepreview": "Тиҙ ҡарап алыуҙы ҡулланырға (JavaScript, эксперименталь)",
+       "tog-uselivepreview": "Тиҙ ҡарап алыуҙы ҡулланырға",
        "tog-forceeditsummary": "Төҙәтеүҙе тасуирлау юлы тултырылмаһа, мине киҫәт",
        "tog-watchlisthideown": "Үҙгәртеүҙеремде күҙәтеү исемлегенән йәшерергә",
        "tog-watchlisthidebots": "Боттар  үҙгәртеүҙәрен күҙәтеү исемлегенән йәшерергә",
        "thu": "Кс",
        "fri": "Йм",
        "sat": "Шб",
-       "january": "Ò\92инуар",
-       "february": "Февраль",
-       "march": "Ð\9cарт",
-       "april": "Ð\90прель",
-       "may_long": "Ð\9cай",
-       "june": "Ð\98юнь",
-       "july": "Ð\98юль",
-       "august": "Ð\90вгуст",
-       "september": "Сентябрь",
-       "october": "Ð\9eктябрь",
-       "november": "Ð\9dоябрь",
-       "december": "Ð\94екабрь",
+       "january": "Ò\93инуар",
+       "february": "февраль",
+       "march": "март",
+       "april": "апрель",
+       "may_long": "май",
+       "june": "июнь",
+       "july": "июль",
+       "august": "август",
+       "september": "сентябрь",
+       "october": "октябрь",
+       "november": "ноябрь",
+       "december": "декабрь",
        "january-gen": "ғинуар",
        "february-gen": "февраль",
        "march-gen": "март",
        "blockedtitle": "Ҡулланыусы блокланған",
        "blockedtext": "'''Иҫәп яҙыуығыҙ йәки IP-адресығыҙ блокланған.'''\n\nБлоклаусы хаким: $1.\nБелдерелгән сәбәп: ''$2''.\n\n* Блоклау башланған ваҡыт: $8\n* Блоклау  аҙағы: $6\n* Блоклауҙар һаны: $7\n\nҺеҙ $1 йәки башҡа [[{{MediaWiki:Grouppage-sysop}}|хакимгә]] блоклау буйынса һорауҙарығыҙҙы ебәрә алаһығыҙ.\nИҫегеҙҙе тотоғоҙ: әгәр һеҙ теркәлмәгән һәм электрон почта адресығыҙҙы раҫламаған булһағыҙ ([[Special:Preferences|көйләүҙәрем битендә]]), хакимгә хат ебәрә алмайһығыҙ. Шулай ук блоклау ваҡытында һеҙҙең хат ебәреү мөмкинлегегеҙ сикләгән булырға ла мөмкин.\nҺеҙҙең IP-адрес — $3, блоклау идентификаторы — #$5.\nХаттарҙа был мәғлүмәттәрҙе күрһәтергә онотмағыҙ.",
        "autoblockedtext": "Һеҙҙең IP-адресығыҙ автоматик рәүештә блокланған. Сәбәбе, был адрес элек блокланған ҡулланыусыларҙың береһе тарафынан ҡулланылған. Блоклаусы хаким ($1) киләһе сәбәпте белдергән:\n\n:«$2»\n\nБлоклаусы хаким: $1.\nБелдерелгән сәбәп: ''$2''.\n\n* Блоклау башланған ваҡыт: $8\n* Блоклау  аҙағы: $6\n* Блоклауҙар һаны: $7\n\nҺеҙ $1 йәки башҡа [[{{MediaWiki:Grouppage-sysop}}|хакимгә]] блоклау буйынса һорауҙарығыҙҙы ебәрә алаһығыҙ.\nИҫегеҙҙе тотоғоҙ: әгәр һеҙ теркәлмәгән һәм электрон почта адресығыҙҙы раҫламаған булһағыҙ ([[Special:Preferences|көйләүҙәрем битендә]]), хакимгә хат ебәрә алмайһығыҙ. Шулай ук блоклау ваҡытында һеҙҙең хат ебәреү мөмкинлегегеҙ сикләгән булырға ла мөмкин.\nҺеҙҙең IP-адрес — $3, блоклау идентификаторы — #$5.\nХаттарҙа был мәғлүмәттәрҙе күрһәтергә онотмағыҙ.",
+       "systemblockedtext": "  Ҡулланыусы исемен йәки IP-адресығыҙҙы MediaWiki автоматик рәүештә туҡтатты. \nСәбәптәре:\n\n: <ем>$2</ем>\n\n* Туҡтатыу башланды:$8\n* Туҡтатыу оҙайлығы:$6\n* Туҡтатыу маҡсаты:$7\n\nӘлеге IP-адресығыҙ $3.\nЗинһар, һорау менән мөрәжәғәт иткәндә ошо мәғлүмәттәрҙе һәр ваҡыт күрһәтегеҙ.",
        "blockednoreason": "сәбәп белдерелмәгән",
        "whitelistedittext": "Биттәрҙә үҙгәртеү өсөн $1 кәрәк.",
        "confirmedittext": "Биттәрҙе үҙгәртерҙән алда электрон почта адресығыҙҙы раҫларға тейешһегеҙ.\nБыны [[Special:Preferences|көйләүҙәр битендә]] эшләй алаһығыҙ.",
        "content-not-allowed-here": "\"$1\" эстәлеге [[$2]] бит өсөн ярамай",
        "editwarning-warning": "Икенсе биткә күсеү һеҙ индергән үҙгәрештәрҙең юғалыуына килтереүе мөмкин.\nӘгәр системала танылыу үтһәгеҙ, көйләүҙәрегеҙ битенең \"Мөхәррирләү\" бүлегендә был киҫәтеүҙе һүндерә алаһығыҙ.",
        "editpage-invalidcontentmodel-title": "Йөкмәтке форматы ҡабул ителмәй",
+       "editpage-invalidcontentmodel-text": "\"$1\" йөкмәткеһенең моделе бармай",
        "editpage-notsupportedcontentformat-title": "Йөкмәтке форматы асылмай",
        "editpage-notsupportedcontentformat-text": "$1 эстәлеге форматы $2 моделе форматы менән тап килмәй.",
        "content-model-wikitext": "викитекст",
        "content-model-css": "CSS",
        "content-json-empty-object": "Буш объект",
        "content-json-empty-array": "Буш массив",
+       "deprecated-self-close-category": "Үҙенән-үҙе ябыла торған HTML-тегтарҙы ҡулланған биттәр",
+       "deprecated-self-close-category-desc": "Был биттең үҙенән-үҙе ябыла торған, мәҫәлән <code>&lt;b/></code> йәки <code>&lt;span/></code> кеүек HTML-тегтары бар. Тиҙҙән уларҙың тәъҫире, HTML5 спецификацияһына ярашлы булыу өсөн, үҙгәрәсәк. Шуға ла был иҫкергән тегтарҙы вики-текста ҡулланмау хәйерлерәк.",
        "duplicate-args-warning": "<strong>Иғтибар:</strong> [[:$1]] берәүҙән артыҡ [[:$2]]  параметры  «$3» менән саҡыра. Һуңғы дәүмәл ҡулланыласаҡ.",
        "duplicate-args-category": "Ҡалыпты сығарғанда ҡабатланған аргументтарҙы ҡулланған биттәр",
        "duplicate-args-category-desc": "Түбәндәге ҡабатланған аргументтары <code><nowiki>{{foo|bar=1|bar=2}}</nowiki></code> или <code><nowiki>{{foo|bar|1=bar}}</nowiki></code> булған ҡалыпты сығарыу эстәлекле биттәр.",
        "post-expand-template-argument-warning": "'''Иғтибар:''' Был бит, асыу өсөн бик ҙур күләмле кәмендә бер ҡалып аргументына эйә.\nБындай аргументтар төшөрөп ҡалдырылды.",
        "post-expand-template-argument-category": "Төшөрөп ҡалдырылған ҡалып аргументтары булған биттәр",
        "parser-template-loop-warning": "Төйөн табылған ҡалыптар: [[$1]]",
+       "template-loop-category": "Ҡалыплы биттәр",
+       "template-loop-category-desc": "Был биткә элмәкле, йәғни үҙенән-үҙе килеп сыға торған ҡалып бәйләнгән,",
        "parser-template-recursion-depth-warning": "($1) ҡалыбын рекурсия итеп ҡулланыу тәрәнлеге рөхсәт ителгәндән артып киткән",
        "language-converter-depth-warning": "Телдәрҙе үҙгәртеү тәрәнлегенең сиге үткән ($1)",
        "node-count-exceeded-category": "Төйөндәр һаны артҡан биттәр",
        "page_last": "аҙаҡҡы",
        "histlegend": "Айырма һайлау: сағыштырырға теләгән 2 версияны һайлап Enter-ға йәки биттең аҫҡы өлөшөндәге төймәгә баҫығыҙ.<br />\nАңлатмалар: '''({{int:cur}})''' — хәҙерге версиянан айырма, '''({{int:last}})''' — алдағы версиянан айырма, '''{{int:minoreditletter}}''' — әҙ үҙгәреш яһалған.",
        "history-fieldset-title": "Үҙгәртеүҙәрҙе эҙләү",
-       "history-show-deleted": "ЮйÑ\8bлÒ\93андаÑ\80 Ò\93Ñ\8bна",
+       "history-show-deleted": "Тик Ñ\8eйÑ\8bлÒ\93ан Ñ\82Ó©Ò\99Ó\99Ñ\82еүÒ\99Ó\99Ñ\80",
        "histfirst": "Иң иҫкеләр",
        "histlast": "Иң һуңғылар",
        "historysize": "($1 {{PLURAL:$1|байт}})",
        "search-file-match": "(файл эстәлеге менән тура килә)",
        "search-suggest": "Бәлки, ошоно эҙләйһегеҙҙер: $1",
        "search-rewritten": "$1 нәтижәһе күрһәтелгән. $2 урынына эҙләргә.",
-       "search-interwiki-caption": "Туғандаш проекттар",
+       "search-interwiki-caption": "Туғандаш проекттар һөҙөмтәләре",
        "search-interwiki-default": "$1 һөҙөмтәһе:",
        "search-interwiki-more": "(тағы)",
+       "search-interwiki-more-results": "Күберәк һөҙөмтә кәрәк",
        "search-relatedarticle": "Ҡағылышлы",
        "searchrelated": "ҡағылышлы",
        "searchall": "барыһы",
        "search-external": "Тышҡы эҙләү",
        "searchdisabled": "{{SITENAME}} эҙләүе ябыҡ.\nХәҙергә эҙләүҙе Google менән үтәй алаһығыҙ.\nТик унда {{SITENAME}} өсөн индекслауҙың иҫке булыуы мөмкинлеген онотмағыҙ.",
        "search-error": "Эҙләүҙә хата китте: $1",
+       "search-warning": "Эҙләү мәлендә хата китте:$1",
        "preferences": "Көйләүҙәр",
        "mypreferences": "Көйләүҙәр",
        "prefs-edits": "Төҙәтеүҙәр һаны:",
        "prefs-editwatchlist-clear": "Күҙәтеүҙәр исемлеген таҙартыу",
        "prefs-watchlist-days": "Күҙәтеү исемлегендә нисә көн керетелгән үҙгәртеүҙәрҙе күрһәтергә:",
        "prefs-watchlist-days-max": "Иң күбе $1 {{PLURAL:$1|1=көн|көн}}",
-       "prefs-watchlist-edits": "Киңәйтелгән күҙәтеү исемлегендә күрһәтелә торған үҙгәртеүҙәр һанының сиге:",
+       "prefs-watchlist-edits": "Күҙәтеүҙәр исемлегендә күрһәтеү өсөн төҙәтеүҙәр һанының сиге:",
        "prefs-watchlist-edits-max": "Иң күбе: 1000",
        "prefs-watchlist-token": "Күҙәтеү исемлеге токены:",
        "prefs-misc": "Башҡа көйләүҙәр",
        "prefs-help-recentchangescount": "Һуңғы үҙгәртеүҙәрҙе, биттәр тарихын, журналдарҙы үҙ эсенә ала.",
        "prefs-help-watchlist-token2": "Был - күҙәтеүҙәрегеҙ исемлегенең веб-каналы өсөн йәшерен асҡыс.\nУны белеүселәр күҙәтеүҙәрегеҙ исемлеген уҡый аласаҡ, шуға уны бер кемгә лә әйтмәгеҙ. [[Special:ResetTokens|Уны ташларға теләһәгеҙ, ошонда баҫығыҙ]].",
        "savedprefs": "Һеҙҙең көйләүҙәрегеҙ һаҡланды.",
-       "savedrights": "{{GENDER:$1|$1}} ҡулланыусының хоҡуҡтары һаҡланды.",
+       "savedrights": "{{GENDER:$1|Ҡатнашыусы}} төркөмдәре һаҡланды.",
        "timezonelegend": "Ваҡыт бүлкәте:",
        "localtime": "Урындағы ваҡыт:",
        "timezoneuseserverdefault": "Сервер көйләүҙәрен ҡулланырға $1",
        "youremail": "Электрон почта :",
        "username": "{{GENDER:$1|Ҡулланыусы исеме}}:",
        "prefs-memberingroups": "{{GENDER:$2|Ағза}} {{PLURAL:$1|төркөмө|төркөмдәре}}:",
+       "group-membership-link-with-expiry": "$1($2 ҡәҙәре)",
        "prefs-registration": "Теркәлеү ваҡыты:",
        "yourrealname": "Һеҙҙең ысын исемегеҙ:",
        "yourlanguage": "Тышҡы күренештә ҡулланылған тел:",
        "prefs-help-prefershttps": "Был көйләү системаға киләһе танылыуҙан һуң ҡулланыласаҡ.",
        "prefswarning-warning": "Һеҙ көйләүҙәрегеҙгә әле һаҡланмаған үҙгәрештәр индерҙегеҙ. Әгәр \"$1\" баҫмайынса, биттән сыҡһағыҙ, көйләүҙәр яңыртылмай.",
        "prefs-tabs-navigation-hint": "Кәңәш: Һеҙ һулға, уңға баҫмағын ҡулланып, исемлектәге ҡушымталар араһында күсә алаһығыҙ",
-       "userrights": "Ҡулланыусы хоҡуҡтарын идаралау",
-       "userrights-lookup-user": "Ҡулланыусы төркөмдәрен идаралау",
+       "userrights": "Ҡатнашыусы хоҡуҡтары",
+       "userrights-lookup-user": "Ҡулланыусы һайлауы",
        "userrights-user-editname": "Ҡулланыусы исемен керетерегеҙ:",
-       "editusergroup": "{{GENDER:$1|ҡатнашыусы}} ҡатнашыусының төркөмдәрен үҙгәртеү",
+       "editusergroup": "Ҡатнашыусы төркөмдәрен тейәү",
        "editinguser": "{{GENDER:$1|ҡатнашыусы}} <strong>[[User:$1|$1]]</strong> $2 хоҡуҡтарын үҙгәртеү",
-       "userrights-editusergroup": "Ҡулланыусы төркөмдәрен идараларға",
+       "viewinguserrights": "{{GENDER:$1|ҡатнашыусы}} <strong>[[User:$1|$1]]</strong> $2 хоҡуҡтарын ҡарау",
+       "userrights-editusergroup": "{{GENDER:$1|Ҡатнашыусы}} төркөмдәрен үҙгәртеү",
+       "userrights-viewusergroup": "{{GENDER:$1|Ҡатнашыусы}} төркөмдәрен ҡарау",
        "saveusergroups": "{{GENDER:$1|user}} ҡатнашыусының төркөмдәрен һаҡлау",
        "userrights-groupsmember": "Ағза булған төркөмдәр:",
        "userrights-groupsmember-auto": "Йәшерен ағза булған төркөмдәр:",
-       "userrights-groups-help": "Был ҡулланыусы кергән төркөмдәрҙе үҙгәртә алаһығыҙ.\n* Әгәр төркөм исеме эргәһендә билдә булһа, ҡулланыусы төркөмгә кергән була.\n* Әгәр билдә булмаһа, ҡулланыусы ул төркөмгә кермәй тимәк.\n* * билдәһе, әгәр төркөмдән ҡулланыусыны юйһағыҙ кире ҡуя алмаясағығыҙҙы аңлата һәм киреһенсә.",
+       "userrights-groups-help": "{{GENDER:$1|Был ҡатнашыусы}} кергән төркөмдәрҙе үҙгәртә алаһығыҙ.\n* Әгәр төркөм исеме эргәһендә билдә булһа, {{GENDER:$1|ҡатнашыусы}} төркөмгә кергән була.\n* Әгәр билдә булмаһа, {{GENDER:$1|ҡатнашыусы}} ул төркөмгә инмәгән.\n* * билдәһе, {{GENDER:$1|ҡатнашыусыны}} төркөмгә өҫтәһәгеҙ, {{GENDER:$1|уны}} юйып булмағанды аңлата (йәки киреһенсә).\n* # билдәһе төркөмдәге ағзалыҡтан сығыуҙы кисектерә генә алыуығыҙҙы, уны алдараҡ ваҡытҡа күсерә алмауығыҙҙы аңлата.",
        "userrights-reason": "Сәбәп:",
        "userrights-no-interwiki": "Һеҙҙең башҡа вики-проекттарҙа ҡатнашыусыларҙың хоҡуҡтарын үҙгәртергә хоҡуҡтарығыҙ юҡ.",
        "userrights-nodatabase": "$1 базаһы юҡ йәки урындағы (локаль) база түгел.",
        "userrights-changeable-col": "Һеҙ үҙгәртә алған төркөмдәр",
        "userrights-unchangeable-col": "Һеҙ үҙгәртә алмаған төркөмдәр",
+       "userrights-expiry-none": "Сикләүһеҙ",
+       "userrights-expiry-existing": "Әлеге ваҡыт сыға:$2, $3",
        "userrights-expiry-options": "1 көн:1 day,1 аҙна:1 week,1 ай:1 mopnth, 3 ай:3 months,6 ай:6 months,1 йыл:1 year",
+       "userrights-invalid-expiry": "«$1» төркөмө өсөн ваҡыт бөтөүе яңылыш бирелгән",
+       "userrights-expiry-in-past": "Время истечения для группы «$1» задано в прошлом.\n«$1» төркөмө өсөн ваҡыт бөтөүе үткән ваҡытта бирелгән.",
+       "userrights-cannot-shorten-expiry": "«$1» төркөмөндә ағза булыу осоро датаһын алғараҡ күсерә алмайһың. Был төркөмгә өҫтәү йәки алыуға хоҡуғы булған ҡатнашыусылар ғына уны алғараҡ күсерә ала.",
        "userrights-conflict": "Ҡатнашыусының хоҡуҡтарын үҙгәртеү яраманы! Зинһар, үҙгәрештәрҙе тикшерегеҙ һәм яңынан индерегеҙ.",
        "group": "Төркөм:",
        "group-user": "Ҡулланыусылар",
        "grant-group-high-volume": "Юғары әүҙемлекле алым эшләргә",
        "grant-group-customization": "Көйләүҙәр һәм өҫтөнлөк биргән көйләүҙәр",
        "grant-group-administration": "Административ алымдар ҡулланыу",
+       "grant-group-private-information": "Доступ к конфиденциальным данным о вас\nҺеҙҙең туралағы йәшерелгән белешмәләргә инеү",
        "grant-group-other": "Әүҙемлек төрлө",
        "grant-blockusers": "Иҫәп яҙмаларын блоклау һәм блоклауҙы асыу",
        "grant-createaccount": "Иҫәп яҙмаһын булдырырға",
        "grant-highvolume": " Юғары әүҙемлектә мөхәррирләү",
        "grant-oversight": "Башҡа ҡатнашыусылар тәҙәтеүенән бит версияһын йәшерергә",
        "grant-patrol": "Бит үҙгәрештәрен күҙәтеү",
+       "grant-privateinfo": "Шәхси белешмәләргә инеү",
        "grant-protect": "Битте һаҡлау һәм һаҡты сисеү",
        "grant-rollback": "Биттеге үҙгәрештәрҙе кире ҡайтарыу",
        "grant-sendemail": "Башҡа ҡатнашыусыларға электрон почта аша хат ебәреү",
        "grant-basic": "Төп хоҡуҡтар",
        "grant-viewdeleted": "Юйылған файлдарҙы һәм биттерҙе тейәү",
        "grant-viewmywatchlist": "һеҙҙең күҙәтеүҙәр исемлеген байҡау",
+       "grant-viewrestrictedlogs": "рөхсәте сикле журналдағы яҙманы ҡарау",
        "newuserlogpage": "Яңы ҡулланыусы яҙмалары",
        "newuserlogpagetext": "Яңы теркәлгән ҡатнашыусылар яҙмалары журналы.",
        "rightslog": "Ҡулланыусының хоҡуҡтары көндәлеге",
        "rightslogtext": "Был — ҡулланыусы хоҡуҡтары үҙгәрештәре яҙмалары журналы",
        "action-read": "Был битте уҡыу",
        "action-edit": "Был битте үҙгәртеү",
-       "action-createpage": "ЯңÑ\8b Ð±Ð¸Ñ\82 яһау",
-       "action-createtalk": "Фекер алышыу битен яһау",
+       "action-createpage": "бÑ\8bл Ð±Ð¸Ñ\82Ñ\82е яһау",
+       "action-createtalk": "бÑ\8bл Ñ\84екер алышыу битен яһау",
        "action-createaccount": "Был ҡулланыусы иҫәп яҙыуын яһау",
        "action-autocreateaccount": "Ҡатнашыусының тышҡы иҫәп яҙмаһы менән инергә",
        "action-history": "Был биттең тарихын ҡарарға",
        "action-upload_by_url": "Был файлды URL адрестан күсереү",
        "action-writeapi": "Яҙҙырыу өсөн API ҡулланыу",
        "action-delete": "Был битте юйыу",
-       "action-deleterevision": "Биттең был өлгөһөн юйыу",
-       "action-deletedhistory": "Был биттең юйҙырыуҙар тарихын ҡарау",
+       "action-deleterevision": "биттең өлгөләрен юйыу",
+       "action-deletelogentry": "журналдағы яҙманы юҡ итеү",
+       "action-deletedhistory": "биттең юйылған тарихын ҡарау",
+       "action-deletedtext": "текстың юйылған нөсхәһен ҡарау",
        "action-browsearchive": "Юйылған биттәрҙе эҙләү",
-       "action-undelete": "ЮйÑ\8bлÒ\93ан Ð±Ñ\8bл Ð±Ð¸Ñ\82Ñ\82е Ò¡Ð°Ð±Ð°Ñ\82 тергеҙеү",
-       "action-suppressrevision": "Ð\91Ñ\8bл Ð¹Ó\99Ñ\88еÑ\80елгÓ\99н Ó©Ð»Ð³Ó©Ð½Ó© ҡарау һәм тергеҙеү",
+       "action-undelete": "биÑ\82Ñ\82Ó\99Ñ\80Ò\99е тергеҙеү",
+       "action-suppressrevision": "биÑ\82Ñ\82Ó\99Ñ\80Ò\99ең Ð¹Ó\99Ñ\88еÑ\80елгÓ\99н Ó©Ð»Ð³Ó©Ð»Ó\99Ñ\80ен ҡарау һәм тергеҙеү",
        "action-suppressionlog": "Был шәхси журналды ҡарау",
        "action-block": "Был ҡатнашыусыға мөхәррирләүҙе тыйыу",
        "action-protect": "Был биттең һаҡланыу дәрәжәһен үҙгәртеү",
        "action-userrights-interwiki": "Ҡатнашыусыларҙың башҡа Викиларҙағы хоҡуҡтарын үҙгәртеү",
        "action-siteadmin": "Мәғлүмәттәр базаһын асыу һәм ябыу",
        "action-sendemail": "электрон хат ебәреү",
+       "action-editmyoptions": "Көйләүҙәрегеҙҙе мөхәррирләү",
        "action-editmywatchlist": "һеҙҙең күҙәтеүҙәр исемлеген мөхәррирләү",
        "action-viewmywatchlist": "һеҙҙең күҙәтеүҙәр исемлеген байҡау",
        "action-viewmyprivateinfo": "һеҙҙең шәхси мәғлүмәтте байҡау",
        "action-applychangetags": "Һеҙҙең үҙгәрештәр ТЕГын булдырырға",
        "action-changetags": "Айырым үҙгәртеүҙәрҙә һәм журнал яҙмаланыда тег өҫтәү һәм юйыу",
        "action-deletechangetags": "билдәләрҙе мәғлүмәт базаһынан юйыу",
+       "action-purge": "был биттең кешын таҙартыу",
        "nchanges": "$1 {{PLURAL:$1|үҙгәртәү|үҙгәртеүҙәр}}",
        "enhancedrc-since-last-visit": "$1 {{PLURAL:$1|һеҙҙең һуңғы визит}}",
        "enhancedrc-history": "тарих",
        "recentchanges-legend-heading": "<strong>Легенда:</strong>",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} ([[Special:NewPages|Яңы биттәр исемлеген]] ҡарағыҙ)",
        "recentchanges-submit": "Күрһәтергә",
+       "rcfilters-legend-heading": "<strong>Ҡыҫҡартыуҙар теҙмәһе:</strong>",
+       "rcfilters-other-review-tools": "<strong>Тикшереүҙең башҡа ҡоралдары</strong>",
+       "rcfilters-group-results-by-page": "Төркөмдөң төрлө биттәге һөҙөмтәләре",
+       "rcfilters-grouping-title": "Төркөмләштереү",
+       "rcfilters-activefilters": "Әүҙем фильтрҙар",
+       "rcfilters-advancedfilters": "Киңәйтелгән фильтрҙар",
+       "rcfilters-limit-title": "Күрһәтеү өсөн үҙгәртеүҙәр",
+       "rcfilters-limit-shownum": "{{PLURAL:$1|һуңғы үҙгәреш|$1 һуңғы үҙгәрештәр|$1 һуңғы үҙгәрештәрҙе}} күрһәтергә",
+       "rcfilters-days-title": "Аҙаҡҡы көндәр",
+       "rcfilters-hours-title": "Аҙаҡҡы сәғәттәр",
+       "rcfilters-quickfilters": "Һаҡланған фильтрҙар",
+       "rcfilters-quickfilters-placeholder-title": "Һаҡланған ссылкалар әлегә юҡ",
+       "rcfilters-quickfilters-placeholder-description": "Фильтрҙың көйләүҙәрен һаҡлар һәм аҙаҡтан уларҙы яңынан ҡулланыу өсөн аҫтағы \"Әүҙем фильтр\" төймәһенә сиртегеҙ.",
+       "rcfilters-savedqueries-setdefault": "Һүҙһеҙ үтәлешкә ҡуйырға",
+       "rcfilters-savedqueries-unsetdefault": "һүҙһеҙ үтәлеште юйырға",
+       "rcfilters-savedqueries-new-name-placeholder": "Фильтрҙың маҡсатын яҙығыҙ",
+       "rcfilters-savedqueries-apply-label": "Фильтр ҡуйырға",
+       "rcfilters-savedqueries-apply-and-setdefault-label": "Һүҙһеҙ үтәлгән фильтрҙы ҡуйырға",
+       "rcfilters-savedqueries-add-new-title": "Фильтрҙың әлеге көйләүҙәрен һаҡларға",
+       "rcfilters-restore-default-filters": "Фильтрҙарҙың һүҙһеҙ үтәлгәнен кире ҡуйырға",
+       "rcfilters-clear-all-filters": "Бөтә фильтрҙарҙы ла таҙартырға",
+       "rcfilters-show-new-changes": "Һуңғы үҙгәртеүҙәрҙе ҡарап сығырға",
+       "rcfilters-previous-changes-label": "Элек ҡаралған үҙгәртеүҙәр",
+       "rcfilters-search-placeholder": "Фильтрҙарҙың һуңғы үҙгәрештәре (ҡарап сығығыҙ йәки индерә башлағыҙ)",
+       "rcfilters-invalid-filter": "Ярамаған фильтр",
+       "rcfilters-empty-filter": "Әүҙем фильтрҙар юҡ. Бөтә үҙгәртеүҙәр ҙә күрһәтелә.",
+       "rcfilters-filterlist-whatsthis": "Был нисек эшләй?",
+       "rcfilters-filterlist-feedbacklink": "Яңы (бета) фильтрҙар тураһында фекер яҙығыҙ",
+       "rcfilters-highlightbutton-title": "Һөҙөмтәләрҙе билдәләгеҙ",
+       "rcfilters-highlightmenu-title": "Төҫөн һайлағыҙ",
+       "rcfilters-highlightmenu-help": "Был сифатты белгертеү өсөн төҫ һайлағыҙ",
+       "rcfilters-filterlist-noresults": "Фильтрҙар табылманы",
+       "rcfilters-state-message-subset": "Фильтр һөҙөмтәһеҙ буласаҡ, сөнки уның һөҙөмтәһе {{PLURAL:$2|киләһе киңерәк фильтр}} индерелгән (айырыу өсөн төҫ биреп ҡарағыҙ):$1",
+       "rcfilters-state-message-fullcoverage": "Төркөмдәге барлыҡ фильтрҙы ла һайлау бер нимәне лә һайламау менән бер, шуға ла был фильтрҙың әһәмиәте булмаясаҡ. Бәйләнгән төркөмдәр:$1",
+       "rcfilters-filtergroup-authorship": "Авторлыҡты мөхәррирләү",
+       "rcfilters-filter-editsbyself-label": "Һин индергән үҙгәртеүҙәр",
+       "rcfilters-filter-editsbyself-description": "Һинең өлөшөң",
+       "rcfilters-filter-editsbyother-label": "Башҡа ҡатнашыусылар индергән үҙгәртеүҙәр",
+       "rcfilters-filter-editsbyother-description": "Һинән башҡа барһының да үҙгәртеүҙәре",
+       "rcfilters-filtergroup-userExpLevel": "Ҡатнашыусыны теркәү һәм уның тәжрибәһе",
+       "rcfilters-filter-user-experience-level-registered-description": "Теркәлгән мөхәррирҙәр",
+       "rcfilters-filter-user-experience-level-unregistered-label": "Теркәлмәгән",
+       "rcfilters-filter-user-experience-level-unregistered-description": "Системаға инмәгән мөхәррирҙәр",
+       "rcfilters-filter-user-experience-level-newcomer-label": "Яңы килгәндәр",
+       "rcfilters-filter-user-experience-level-newcomer-description": "10 төҙәтеүҙән аҙ һәм 4 көн эшләүҙән кәм булған теркәлгән мөхәррирҙәр",
+       "rcfilters-filter-user-experience-level-learner-label": "Уҡыусылар",
+       "rcfilters-filter-user-experience-level-learner-description": "Тәжрибәһе \"Яңы килеүсе\" һәм \"Оҫта ҡулланыусы\" кимәле араһында булған теркәлгән мөхәррирҙәр",
+       "rcfilters-filter-user-experience-level-experienced-label": "Тәжрибәле ҡулланыусылар",
+       "rcfilters-filter-user-experience-level-experienced-description": "Төҙәтеүҙәре 500-ҙән күберәк һәм  әүҙем эш көнө 30 көндән ашҡан теркәлгән мөхәррирҙәр",
+       "rcfilters-filtergroup-automated": "Автоматлаштырылған өлөш",
+       "rcfilters-filter-bots-label": "Бот",
+       "rcfilters-filter-bots-description": "Автоматик ҡоралдар ярҙамында эшләнгән төҙәтеүҙәр",
+       "rcfilters-filter-humans-label": "Кеше (бот түгел)",
+       "rcfilters-filter-humans-description": "Мөхәррирҙәр индерген төҙәтеүҙәр",
+       "rcfilters-filtergroup-reviewstatus": "Тикшереү статусы",
+       "rcfilters-filter-patrolled-label": "Тикшерелгән",
+       "rcfilters-filter-patrolled-description": "Тикшерелгән тип билдәләнгән төҙәтеүҙәр",
+       "rcfilters-filter-unpatrolled-label": "Тикшерелмәгәндәр",
+       "rcfilters-filter-unpatrolled-description": "Тикшерелгән тип күрһәтелмәгән төҙәтеүҙәр",
+       "rcfilters-filtergroup-significance": "Мәғәнәһе",
+       "rcfilters-filter-minor-label": "Аҙ ғына төҙәтеүҙәр",
+       "rcfilters-filter-minor-description": "Автор аҙ ғына тип күрһәткән төҙәтеүҙәр",
+       "rcfilters-filter-major-label": "Ғәҙәти төҙәтеүҙәр",
+       "rcfilters-filter-major-description": "Аҙ ғына тип күрһәтелмәгән төҙәтеүҙәр",
+       "rcfilters-filtergroup-watchlist": "Күҙәтеү теҙмәһе",
+       "rcfilters-filter-watchlist-watched-label": "Күҙәтеү теҙмәһендә",
+       "rcfilters-filter-watchlist-watched-description": "Һинең күҙәтеү теҙмәһендә биттәрҙең үҙгәрештәре",
+       "rcfilters-filter-watchlist-watchednew-label": "Күҙәтеү теҙмәһендәге яңы үҙгәрештәр",
        "rcnotefrom": "Аҫта <strong>$3, $4</strong> ҡарата {{PLURAL:$5|үҙгәртеүҙәр күрһәтелгән}} (<strong>$1</strong> күберәк түгел).",
        "rclistfrom": "$3 $2 алып яңы үҙгәртеүҙәрҙе күрһәт.",
        "rcshowhideminor": "бәләкәй төҙәтеүҙәрҙе $1",
        "recentchangeslinked-page": "Бит исеме:",
        "recentchangeslinked-to": "Киреһенсә, был биткә һылтанма яһаған биттәрҙәге үҙгәртеүҙәрҙе күрһәтергә",
        "recentchanges-page-added-to-category": "[[:$1]] категорияға өҫтәлгән",
-       "recentchanges-page-added-to-category-bundled": "[[:$1]] һәм [[Special:WhatLinksHere/$1|{{PLURAL:$2|one page|$2 pages}}]]  категорияға өҫтәлгән",
+       "recentchanges-page-added-to-category-bundled": "[[:$1]] категорияға өҫтәлгән, [[Special:WhatLinksHere/$1|был бит икенсе биттәргә өҫтәлгән]]",
        "recentchanges-page-removed-from-category": "[[:$1]] категориянан алынған",
-       "recentchanges-page-removed-from-category-bundled": "[[:$1]] һәм [[Special:WhatLinksHere/$1|{{PLURAL:$2|one page|$2 pages}}]]  категориянан алынған",
+       "recentchanges-page-removed-from-category-bundled": "[[:$1]] категориянан юйылған, [[Special:WhatLinksHere/$1|был бит икенсе биттәргә индерелгән]]",
        "autochange-username": "Автоматик рәүештә MediaWiki үҙгәртелә",
        "upload": "Файл тейәү",
        "uploadbtn": "Файлды тейәргә",
        "emailccsubject": "$1 өсөн хатығыҙҙың күсермәһе: $2",
        "emailsent": "Хат ебәрелде",
        "emailsenttext": "Һеҙҙең электрон хатығыҙ ебәрелде.",
-       "emailuserfooter": "Был электрон хат $1 ҡатнашыусыһынан $2 ҡатнашыусыһына {{SITENAME}} проектының \"Ҡатнашыусыға хат\" формаһы аша ебәрелде.",
+       "emailuserfooter": "Был электрон хат $1 {{GENDER:$1|ҡатнашыусынан}} $2 {{GENDER:$2|ҡатнашыусыға}} {{SITENAME}} проектының \"Ҡатнашыусыға хат\" формаһы аша ебәрелде. Әгәр {{GENDER:$2|һеҙ}} хатҡа яуап бирһәгеҙ, ул тура {{GENDER:$1|хат яҙыусыға}} ебәреләсәк, шуға күрә {{GENDER:$2|һеҙҙең}} электрон почта адресы {{GENDER:$1|уға}} билдәле буласаҡ.",
        "usermessage-summary": "Система хәбәрен ҡалдырырға.",
        "usermessage-editor": "Система хәбәрсеһе",
        "watchlist": "Күҙәтеү исемлеге",
        "enotif_body_intro_moved": "{{SITENAME}} проектының $1 исемле бите {{gender:$2|$2}} тарафынан күсерелде. Ваҡыты: $PAGEEDITDATE. Ҡарағыҙ: $3.",
        "enotif_body_intro_restored": "{{SITENAME}} проектының $1 исемле бите {{gender:$2|$2}} тарафынан тергеҙелде. Ваҡыты: $PAGEEDITDATE. Ҡарағыҙ: $3.",
        "enotif_body_intro_changed": "{{SITENAME}} проектының $1 исемле бите {{gender:$2|$2}} тарафынан үҙгәртелде. Ваҡыты: $PAGEEDITDATE. Ҡарағыҙ: $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\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": "булдырылды",
        "editcomment": "Үҙгәртеүҙең тасуирламаһы <em>$1</em> ине.",
        "revertpage": "[[Special:Contributions/$2|$2]] ([[User talk:$2|фекер алышыу]]) уҙгәртеүҙәре [[User:$1|$1]] өлгөһөнә ҡайтарылды",
        "revertpage-nouser": "(Ҡатнашыусының исеме йәшерелгән) үҙгәртеүҙәре {{GENDER:$1|[[User:$1|$1]]}}өлгөһөнә ҡайтарылды",
-       "rollback-success": "$1 уҙгәртеүҙәре кире алдынды;\n$2 өлгөһөнә ҡайтыу.",
+       "rollback-success": "{{GENDER:$3|$1}} үҙгәртеүҙәре кире алынды; {{GENDER:$4|$2}} версияһына ҡайтарылды.",
        "sessionfailure-title": "Сеанс хатаһы",
        "sessionfailure": "Хәҙерге сеанста хаталар килеп сыҡҡан, булырға тейеш;\n\"сеансты баҫып алыу\"ға юл ҡуймау өсөн был ғәмәл үтәлмәне.\nАлдағы биткә кире  ҡайтығыҙ, битте яңыртығыҙ һәм яңынан ҡабатлап ҡарағыҙ.",
        "changecontentmodel": "Биттең контент моделен мөхәррирләү",
        "changecontentmodel-cannot-convert": "[[:$1]]  эстәлеге $2 тибына үҙгәртелә алмай",
        "changecontentmodel-nodirectediting": "$1 эстәлеге моделен тураға мөхәррирләп булмай",
        "log-name-contentmodel": "Эстәлек моделен үҙгәртеүҙәр журналы",
-       "log-description-contentmodel": "ЭÑ\81Ñ\82Ó\99лек Ð¼Ð¾Ð´ÐµÐ»ÐµÐ½ Ò¯Ò\99гÓ\99Ñ\80Ñ\82еүÒ\99Ó\99Ñ\80 Ð¼ÐµÐ½Ó\99н Ð±Ó\99йле Ð²Ð°Ò¡Ð¸Ò\93алаÑ\80",
+       "log-description-contentmodel": "Ð\91Ñ\8bнда Ð±Ð¸Ñ\82Ñ\82ең Ñ\8dÑ\81Ñ\82Ó\99лек Ð¼Ð¾Ð´ÐµÐ»ÐµÐ½ÐµÒ£ Ò¯Ò\99гÓ\99Ñ\80Ñ\82еүÒ\99Ó\99Ñ\80е Ò»Ó\99м Ñ\81Ñ\82андаÑ\80Ñ\82 Ñ\8dÑ\81Ñ\82Ó\99лек Ð¼Ð¾Ð´ÐµÐ»ÐµÐ½Ó\99н Ð°Ð¹Ñ\8bÑ\80малÑ\8b Ð¼Ð¾Ð´ÐµÐ»Ñ\8c Ð±Ñ\83йÑ\8bнÑ\81а Ñ\82Ó©Ò\99өлгÓ\99н Ð±Ð¸Ñ\82Ñ\82Ó\99Ñ\80 ÐºÒ¯Ñ\80Ò»Ó\99Ñ\82елгÓ\99н.",
        "logentry-contentmodel-new": "$1 $3 {{GENDER:$2|}} битен булдырҙы, стандарт булмаған «$5» моделе ҡулланылды.",
        "logentry-contentmodel-change": "$3 битендәге $1 {{GENDER:$2||}} эстәлек моделен $3  «$4» -тән «$5»-кә үҙгәртте.",
        "logentry-contentmodel-change-revertlink": "кире алырға",
        "undeleteviewlink": "ҡарарға",
        "undeleteinvert": "Һайланғандарҙы әйләндерергә",
        "undeletecomment": "Сәбәп:",
-       "cannotundelete": "Юйыуҙы кире алып булманы:\n$1",
+       "cannotundelete": "Һеҙҙең ҡайһы бер йәки бөтә тергеҙеүҙәр килеп сыҡманы: \n$1",
        "undeletedpage": "'''$1 бите тергеҙелде'''\n\nҺуңғы юйыуҙарҙы һәм тергеҙеүҙәрҙе ҡарау өсөн, [[Special:Log/delete|юйыу яҙмалары журналын]] ҡарағыҙ.",
        "undelete-header": "Һуңғы юйылған биттәрҙе [[Special:Log/delete|юйыу яҙмалары журналында]] ҡарағыҙ.",
        "undelete-search-title": "Юйылған биттәрҙе эҙләү",
        "sp-contributions-newbies-sub": "Яңы иҫәп яҙмалары өсөн",
        "sp-contributions-newbies-title": "Яңы теркәлгән ҡатнашыусылар башҡарған эш",
        "sp-contributions-blocklog": "блоклау яҙмалары",
-       "sp-contributions-suppresslog": "Ҡулланыусыларҙың юйылған өлөшө",
-       "sp-contributions-deleted": "юйылған үҙгәртеүҙәр",
+       "sp-contributions-suppresslog": "{{GENDER:$1|Ҡатнашыусы}} юйылған өлөшө",
+       "sp-contributions-deleted": "{{GENDER:$1|Ҡатнашыусы}} юйылған үҙгәртеүҙәре",
        "sp-contributions-uploads": "тейәүҙәр",
        "sp-contributions-logs": "журналдар",
        "sp-contributions-talk": "фекерләшеү",
-       "sp-contributions-userrights": "ҡатнашыусы хоҡуҡтарын идаралау",
+       "sp-contributions-userrights": "{{GENDER:$1|Ҡатнашыусы}} ҡатнашыусы хоҡуҡтары менән идаралау",
        "sp-contributions-blocked-notice": "Әлеге ваҡытта был ҡатнашыусы бикле.\nТүбәндә бикләү яҙмаларынан һуңғы ҡатнашыусыны бикләү яҙмаһы килтерелгән:",
        "sp-contributions-blocked-notice-anon": "Әлеге ваҡытта был IP адрес бикле.\nТүбәндә бикләү яҙмаларынан һуңғы адресты бикләү яҙмаһы килтерелгән:",
        "sp-contributions-search": "Башҡарған эште эҙләү",
        "tags-actions-header": "Ғәмәлдәр",
        "tags-active-yes": "Эйе",
        "tags-active-no": "Юҡ",
-       "tags-source-extension": "Ҡушымта билдәләй",
+       "tags-source-extension": "Программа тәьминәте менән билдәләнә",
        "tags-source-manual": "Ҡатнашыусы йәки робот ҡулдан индерә",
        "tags-source-none": "Башҡа ҡулланылмай",
        "tags-edit": "үҙгәртергә",
        "tags-deactivate": "һүндерергә",
        "tags-hitcount": "$1 {{PLURAL:$1|1=үҙгәртеү|үҙгәртеү}}",
        "tags-manage-no-permission": "Тамға исемен үҙгәртергә хоҡуғығыҙ юҡ",
-       "tags-manage-blocked": "Һеҙгә блок ҡуйылған, тамғалар менән идара итә алмайһығыҙ.",
+       "tags-manage-blocked": "Блок ҡуйылғанға күрә, {{GENDER:$1|һеҙ}} тамғалар менән идара итә алмайһығыҙ.",
        "tags-create-heading": "Яңы тамға булдырырға",
        "tags-create-explanation": "яңы булдырылған билдәләр боттар һәм ҡатнашыусылар ҡуллана алырлыҡ итеп эшләнәсәк",
        "tags-create-tag-name": "Тамға исеме",
        "tags-create-reason": "Сәбәп:",
        "tags-create-submit": "Яһау",
        "tags-create-no-name": "Тамға исемен яҙығыҙ",
-       "tags-create-invalid-chars": "Тамға исемдәрендә өтөр (<code>,</code>) йәки һыҙыҡ  (<code>/</code>) булмаҫҡа тейеш.",
+       "tags-create-invalid-chars": "Тамға исемдәрендә өтөр (<code>,</code>), пайп (<code>|</code>) йәки һыҙыҡ (<code>/</code>) булмаҫҡа тейеш.",
        "tags-create-invalid-title-chars": "Билдә исемдәрендә бит атамаларында файҙаланып булмаған символдар булмаҫҡа тейеш",
        "tags-create-already-exists": "$1 тамғаһы бар инде.",
        "tags-create-warnings-above": "«$1» билдәһен яһарға тырышҡанда асыҡлана{{PLURAL:$2|о киләһе иҫкәрмә|ы киләһе иҫкәрмә}}:",
        "tags-deactivate-not-allowed": "«$1» тамғаһын һүндереп булмай.",
        "tags-deactivate-submit": "һүндерергә",
        "tags-apply-no-permission": "Һеҙҙең үҙгәртеү тамғаһы ҡуйыу хоҡуғы юҡ.",
-       "tags-apply-blocked": "Бикле булғансы, үҙгәртеүҙәргә тамға ҡуйырға хоҡуғығыҙ юҡ.",
+       "tags-apply-blocked": "{{GENDER:$1|Һеҙ}} бикле булғансы, үҙгәртеүҙәргә тамға ҡуйырға хоҡуғығыҙ юҡ.",
        "tags-apply-not-allowed-one": " «$1» тамғаһын ҡулдан файҙаланып булмай",
        "tags-apply-not-allowed-multi": "Ҡулдан {{PLURAL:$2|түбәндәге тамғаны өҫтәп булмай}}: $1",
        "tags-update-no-permission": "Һеҙҙең айырым өлгөләрҙә һәм журнал яҙмаларында тамға йәки үҙгәртеү тамғаһы ҡуйырға хоҡуғығыҙ юҡ.",
-       "tags-update-blocked": "Блок алынғансы, үҙгәртеү тамғалары менән идара итә алмайһығыҙ.",
+       "tags-update-blocked": "Блок алынғансы, {{GENDER:$1|һеҙ}} үҙгәртеү тамғалары менән идара итә алмайһығыҙ.",
        "tags-update-add-not-allowed-one": " «$1» тамғаһын ҡулдан файҙаланып булмай",
        "tags-update-add-not-allowed-multi": "{{PLURAL:$2|түбәндәге тег}} ҡулдан өҫтәлмәй: $1",
        "tags-update-remove-not-allowed-one": " «$1» тамғаһын юйып булмай",
        "logentry-protect-protect-cascade": "$1 һаҡланы{{GENDER:$2||}} $3 $4 [каскадлы]",
        "logentry-protect-modify": "$1$ һаҡлау кимәлен {{GENDER:$2||үҙгәртте}} $3 $4",
        "logentry-protect-modify-cascade": "$1 һаҡлау кимәлен{{GENDER:$2||үҙгәртте}}  $3 $4 [каскадлы]",
-       "logentry-rights-rights": "$1  $3 файҙаланыусының төркөмдәрҙәге ағзалығын $4 урынына $5 тип {{GENDER:$2|үҙгәртте}}",
+       "logentry-rights-rights": "$1  $3 ҡатнашыусының төркөмдәрҙәге ағзалығын $4 урынына $5 тип {{GENDER:$2|үҙгәртте}}",
        "logentry-rights-rights-legacy": "$1  $3 өсөн төркөмдәрҙәге ағзалыҡты {{GENDER:$2|үҙгәртте}}",
        "logentry-rights-autopromote": "$1 {{GENDER:$2|}} автоматик рәүештә {{GENDER:$2|}} $4 урынына $5 ителде.",
        "logentry-upload-upload": "$1 $3 {{GENDER:$2|күсерҙе}}",
        "api-error-emptypage": "Яңы буш биттәр яһау тыйыла.",
        "api-error-publishfailed": "Эске хата: сервер ваҡытлыса файлды һаҡлай алманы.",
        "api-error-stashfailed": "Эске хата: сервер ваҡытлыса файлды һаҡлай алманы.",
-       "api-error-unknown-warning": "Ð\91илдÓ\99һеÒ\99 Ð±ÐµÐ»Ð´ÐµÑ\80еү: \"$1\".",
+       "api-error-unknown-warning": "Ð\91илдÓ\99һеÒ\99 ÐºÐ¸Ò«Ó\99Ñ\82еү: Â«$1».",
        "api-error-unknownerror": "Билдәһеҙ хата: «$1»",
        "duration-seconds": "$1 {{PLURAL:$1|1=секунд|секунд}}",
        "duration-minutes": "$1 {{PLURAL:$1|1=минут|минут}}",
index 251fa04..d6498c7 100644 (file)
@@ -46,7 +46,7 @@
        "tog-shownumberswatching": "Паказваць колькасьць назіральнікаў",
        "tog-oldsig": "Ваш цяперашні подпіс:",
        "tog-fancysig": "Апрацоўваць подпіс як вікітэкст (без аўтаматычнай спасылкі)",
-       "tog-uselivepreview": "Ð\92Ñ\8bкаÑ\80Ñ\8bÑ\81Ñ\82оÑ\9eваÑ\86Ñ\8c Ñ\85Ñ\83Ñ\82кÑ\96 Ð¿Ð°Ð¿Ñ\8fÑ\80Ñ\8dднÑ\96 Ð¿Ñ\80аглÑ\8fд",
+       "tog-uselivepreview": "Ð\9fаказваÑ\86Ñ\8c Ð¿Ð°Ð¿Ñ\8fÑ\80Ñ\8dднÑ\96 Ð¿Ñ\80аглÑ\8fд Ð±ÐµÐ·Ñ\8c Ð¿ÐµÑ\80азагÑ\80Ñ\83зкÑ\96 Ñ\81Ñ\82аÑ\80онкÑ\96",
        "tog-forceeditsummary": "Папярэджваць пра адсутнасьць кароткага апісаньня зьменаў",
        "tog-watchlisthideown": "Хаваць мае праўкі ў сьпісе назіраньня",
        "tog-watchlisthidebots": "Хаваць праўкі робатаў у сьпісе назіраньня",
        "permissionserrorstext-withaction": "Вы ня маеце дазволу на $2 з {{PLURAL:$1|1=наступнай прычыны|наступных прычынаў}}:",
        "contentmodelediterror": "Вы ня можаце рэдагаваць гэтую вэрсію, бо яе мадэль зьместу — <code>$1</code>, якая адрозьніваецца ад цяперашняй мадэлі зьместу старонкі — <code>$2</code>.",
        "recreate-moveddeleted-warn": "<strong>Увага: вы ствараеце старонку, якая раней была выдаленая.</strong>\n\nУпэўніцеся, што стварэньне гэтай старонкі неабходнае.\nНіжэй пададзеныя журналы выдаленьняў і пераносаў гэтай старонкі:",
-       "moveddeleted-notice": "Гэта старонка была выдаленая. Журналы выдаленьняў і пераносаў для гэтай старонкі пададзеныя ніжэй.",
-       "moveddeleted-notice-recent": "Выбачайце, гэтая старонка была нядаўна выдаленая (цягам апошніх 24 гадзінаў).\nЖурналы выдаленьняў і пераносаў для гэтай старонкі пададзеныя ніжэй для даведкі.",
+       "moveddeleted-notice": "Гэта старонка была выдаленая. Журналы выдаленьняў, абаронаў і пераносаў для гэтай старонкі пададзеныя ніжэй для даведкі.",
+       "moveddeleted-notice-recent": "Выбачайце, гэтая старонка была нядаўна выдаленая (цягам апошніх 24 гадзінаў).\nЖурналы выдаленьняў, абаронаў і пераносаў для гэтай старонкі пададзеныя ніжэй для даведкі.",
        "log-fulllog": "Паказаць журнал цалкам",
        "edit-hook-aborted": "Рэдагаваньне скасаванае працэдурай-перахопнікам.\nТлумачэньняў не было.",
        "edit-gone-missing": "Немагчыма абнавіць старонку.\nПадобна, што яна была выдаленая.",
        "prefs-editwatchlist-clear": "Ачысьціць ваш сьпіс назіраньня",
        "prefs-watchlist-days": "Колькасьць дзён для паказу ў сьпісе назіраньня:",
        "prefs-watchlist-days-max": "(максымальна $1 {{PLURAL:$1|дзень|дні|дзён}})",
-       "prefs-watchlist-edits": "Ð\9aолÑ\8cкаÑ\81Ñ\8cÑ\86Ñ\8c Ñ\80Ñ\8dдагаванÑ\8cнÑ\8fÑ\9e Ð´Ð»Ñ\8f Ð¿Ð°ÐºÐ°Ð·Ñ\83 Ñ\9e Ð¿Ð°Ñ\88Ñ\8bÑ\80анÑ\8bм сьпісе назіраньня:",
+       "prefs-watchlist-edits": "Ð\9cакÑ\81Ñ\8bмалÑ\8cнаÑ\8f ÐºÐ¾Ð»Ñ\8cкаÑ\81Ñ\8cÑ\86Ñ\8c Ð·Ñ\8cменаÑ\9e Ð´Ð»Ñ\8f Ð¿Ð°ÐºÐ°Ð·Ñ\83 Ñ\9e сьпісе назіраньня:",
        "prefs-watchlist-edits-max": "Максымальная колькасьць: 1000",
        "prefs-watchlist-token": "Сакрэтны ключ сьпісу назіраньня:",
        "prefs-misc": "Рознае",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (глядзіце таксама [[Special:NewPages|сьпіс новых старонак]])",
        "recentchanges-submit": "Паказаць",
        "rcfilters-legend-heading": "<strong>Сьпіс абрэвіятураў:</strong>",
-       "rcfilters-other-review-tools": "<strong>Іншыя інструмэнты праверкі:</strong>",
+       "rcfilters-other-review-tools": "<strong>Іншыя інструмэнты праверкі</strong>",
+       "rcfilters-group-results-by-page": "Групаваць вынікі паводле старонак",
+       "rcfilters-grouping-title": "Групаваньне",
        "rcfilters-activefilters": "Актыўныя фільтры",
        "rcfilters-advancedfilters": "Пашыраныя фільтры",
        "rcfilters-limit-title": "Паказаць зьменаў",
-       "rcfilters-limit-shownum": "Паказаць апошнія $1 зьменаў",
+       "rcfilters-limit-shownum": "Паказаць $1 {{PLURAL:$1|апошнюю зьмену|апошнія зьмены|апошніх зьменаў}}",
        "rcfilters-days-title": "Апошнія дні",
        "rcfilters-hours-title": "Апошнія гадзіны",
        "rcfilters-days-show-days": "$1 {{PLURAL:$1|дзень|дні|дзён}}",
        "rcfilters-savedqueries-add-new-title": "Захаваць цяперашнія налады фільтру",
        "rcfilters-restore-default-filters": "Аднавіць фільтры па змоўчаньні",
        "rcfilters-clear-all-filters": "Ачысьціць усе фільтры",
+       "rcfilters-show-new-changes": "Праглядзець найноўшыя зьмены",
+       "rcfilters-previous-changes-label": "Раней прагледжаныя зьмены",
        "rcfilters-search-placeholder": "Фільтар апошніх зьменаў (праглядзець або пачніце друкаваць)",
        "rcfilters-invalid-filter": "Няслушны фільтар",
        "rcfilters-empty-filter": "Няма актыўных фільтраў. Паказаны ўвесь унёсак.",
        "rcfilters-filter-excluded": "Выключаны",
        "rcfilters-tag-prefix-namespace-inverted": "<strong>:не</strong> $1",
        "rcfilters-exclude-button-off": "Выключыць абранае",
+       "rcfilters-exclude-button-on": "За выключэньнем абранага",
        "rcfilters-view-tags": "Праўкі зь меткамі",
        "rcfilters-view-namespaces-tooltip": "Фільтар вынікаў паводле прасторы назваў",
        "rcfilters-view-tags-tooltip": "Фільтар вынікаў з дапамогай метак правак",
        "import-nonewrevisions": "Ніякія праўкі не былі імпартаваныя (усе ўжо або былі апрацаваныя, або прапушчаныя праз памылкі).",
        "xml-error-string": "$1 у радку $2, пазыцыі $3 (байт $4): $5",
        "import-upload": "Загрузіць XML-зьвесткі",
-       "import-token-mismatch": "Страчаныя зьвесткі сэсіі.\n\nМагчыма, вы выйшлі з сыстэмы. <strong>Калі ласка, праверце, што вы ўсё яшчэ знаходзіцеся ў сыстэме і паспрабуйце яшчэ раз</strong>. Калі не спрацуе, паспрабуйце [[Special:UserLogout|выйсьці]] і ўвайсьці яшчэ раз, а таксама праверце, што ваш браўзэр дазваляе кукі-файлы з гэтага сайту.",
+       "import-token-mismatch": "Страчаныя зьвесткі сэсіі.\n\nМагчыма, вы выйшлі з сыстэмы. '''Калі ласка, праверце, што вы ўсё яшчэ знаходзіцеся ў сыстэме і паспрабуйце яшчэ раз'''. Калі не спрацуе, паспрабуйце [[Special:UserLogout|выйсьці]] і ўвайсьці яшчэ раз, а таксама праверце, што ваш браўзэр дазваляе кукі-файлы з гэтага сайту.",
        "import-invalid-interwiki": "Немагчыма імпартаваць з вызначанай вікі.",
        "import-error-edit": "Старонка «$1» не была імпартаваная, бо Вы ня маеце правоў на яе рэдагаваньне.",
        "import-error-create": "Старонка «$1» не была імпартаваная, бо Вы ня маеце правоў на яе стварэньне.",
        "pageinfo-title": "Інфармацыя пра «$1»",
        "pageinfo-not-current": "Даруйце, мы ня можам падаць гэтыя зьвесткі для старых вэрсіяў.",
        "pageinfo-header-basic": "Асноўныя зьвесткі",
-       "pageinfo-header-edits": "РÑ\8dдагаванÑ\8cнÑ\96",
+       "pageinfo-header-edits": "Ð\93Ñ\96Ñ\81Ñ\82оÑ\80Ñ\8bÑ\8f Ñ\80Ñ\8dдагаванÑ\8cнÑ\8fÑ\9e",
        "pageinfo-header-restrictions": "Абарона старонкі",
        "pageinfo-header-properties": "Уласьцівасьці старонкі",
        "pageinfo-display-title": "Загаловак для адлюстраваньня",
        "pageinfo-subpages-name": "Колькасьць падстаронак",
        "pageinfo-subpages-value": "$1 ($2 {{PLURAL:$2|перанакіраваньне|перанакіраваньні|перанакіраваньняў}}; $3 {{PLURAL:$3|звычайная|звычайныя|звычайных}})",
        "pageinfo-firstuser": "Стваральнік старонкі",
-       "pageinfo-firsttime": "Дата стварэньня",
+       "pageinfo-firsttime": "Дата стварэньня старонкі",
        "pageinfo-lastuser": "Апошні рэдактар",
        "pageinfo-lasttime": "Дата апошняга рэдагаваньня",
-       "pageinfo-edits": "Ð\9aолькасьць рэдагаваньняў",
-       "pageinfo-authors": "Ð\9aолÑ\8cкаÑ\81Ñ\8cÑ\86Ñ\8c аўтараў",
+       "pageinfo-edits": "Ð\90гÑ\83лÑ\8cнаÑ\8f Ðºолькасьць рэдагаваньняў",
+       "pageinfo-authors": "Ð\90гÑ\83лÑ\8cнаÑ\8f ÐºÐ¾Ð»Ñ\8cкаÑ\81Ñ\8cÑ\86Ñ\8c Ð°Ñ\81обнÑ\8bÑ\85 аўтараў",
        "pageinfo-recent-edits": "Колькасьць апошніх рэдагаваньняў (за $1)",
        "pageinfo-recent-authors": "Колькасьць апошніх аўтараў",
        "pageinfo-magic-words": "{{PLURAL:$1|1=Магічнае слова|Магічныя словы}} ($1)",
index 074c99f..3bd3da1 100644 (file)
        "blockip": "{{GENDER:$1|सदस्य}} अवरोधित करीं",
        "ipboptions": "२ घंटे:2 hours,१ दिन:1 day,३ दिन:3 days,१ हफ्ता:1 week,२ हफ्ते:2 weeks,१ महिना:1 month,३ महिने:3 months,६ महिने:6 months,१ साल:1 year,हमेशा खातिर:infinite",
        "blocklist": "अवरोधित प्रयोगकर्तासभ",
+       "infiniteblock": "अनिश्चितकाल",
        "blocklink": "रोक लगाईं",
        "unblocklink": "ताला खोलीं",
        "change-blocklink": "ब्लॉक बदलीं",
        "tooltip-summary": "संछेप में एगो सारांश लिखीं",
        "simpleantispam-label": "स्पैम-बिरोधी रोक (Anti-spam check)\nएके <strong>मत</strong> भरीं!",
        "pageinfo-length": "पन्ना लंबाई (बाइट में)",
+       "pageinfo-subpages-name": "एह पन्ना के उपपन्ना संख्या",
+       "pageinfo-magic-words": "जादुई शब्द {{{{PLURAL:$1||शब्द|शब्द}}}} ($1)",
        "pageinfo-toolboxlink": "पन्ना से जुड़ल जानकारी",
        "previousdiff": "← पुरान संपादन",
        "nextdiff": "नया संपादन →",
        "namespacesall": "सगरी",
        "monthsall": "सगरी",
        "confirmemail": "ईमेल पता कन्फर्म करीं",
+       "imgmultipagenext": "अगिला पन्ना →",
+       "imgmultigo": "जाईं!",
+       "imgmultigoto": "$1 पन्ना पर जाईं",
        "autoredircomment": "पन्ना [[$1]] पर अनुप्रेषित कइल गइल",
        "signature": "[[{{ns:user}}:$1|$2]] ([[{{ns:user_talk}}:$1|बात करीं]])",
        "version-no-ext-name": "[अज्ञात नाम]",
        "fileduplicatesearch": "नकल प्रति फाइल खोजीं",
        "specialpages": "खास पन्ना",
+       "specialpages-group-maintenance": "रखरखाव रिपोर्ट",
        "specialpages-group-login": "प्रवेश / खाता निर्माण",
        "specialpages-group-changes": "तुरंत भइल परिवर्तन आ लॉगसभ",
        "specialpages-group-media": "मीडिया रिपोर्ट आ अपलोडसभ",
index 4e8e792..50106c4 100644 (file)
@@ -64,7 +64,7 @@
        "tog-shownumberswatching": "নজরদারী করছে এমন ব্যবহারকারীর সংখ্যা দেখানো হোক",
        "tog-oldsig": "আপনার বর্তমান স্বাক্ষর:",
        "tog-fancysig": "স্বাক্ষরকে উইকিটেক্সট হিসেবে মনে করা হোক (কোন স্বয়ংক্রিয় সংযোগ ছাড়া)",
-       "tog-uselivepreview": "তাà§\8eà¦\95à§\8dষণিà¦\95 à¦ªà§\8dরাà¦\95দরà§\8dশন à¦¬à§\8dযবহার à¦\95রা à¦¹à§\8bà¦\95",
+       "tog-uselivepreview": "পà§\83ষà§\8dঠা à¦ªà§\81নরায় à¦²à§\8bড à¦¨à¦¾ à¦\95রà§\87 à¦ªà§\8dরাà¦\95দরà§\8dশন à¦¦à§\87à¦\96ান",
        "tog-forceeditsummary": "খালি সম্পাদনা সারাংশ প্রবেশ করানোর সময় আমাকে জানানো হোক",
        "tog-watchlisthideown": "আমার সম্পাদনাগুলি আমার নজরতালিকায় লুকিয়ে রাখা হোক",
        "tog-watchlisthidebots": "বটের করা সম্পাদনাগুলি নজরতালিকায় লুকিয়ে রাখা হোক",
        "prefs-editwatchlist-clear": "নজরতালিকা খালি করুন",
        "prefs-watchlist-days": "যতসংখ্যক দিনের নজরতালিকা দেখানো হবে:",
        "prefs-watchlist-days-max": "সর্বোচ্চ $1 {{PLURAL:$1|দিন|দিন}}",
-       "prefs-watchlist-edits": "সমà§\8dপà§\8dরসারিত à¦¨à¦\9cরতালিà¦\95ায় à¦ªà§\8dরদরà§\8dশিত à¦ªà¦°à¦¿à¦¬à¦°à§\8dতনà§\87র à¦¸à¦°à§\8dবà§\8bà¦\9aà§\8dà¦\9a সংখ্যা:",
+       "prefs-watchlist-edits": "নà¦\9cরতালিà¦\95াতà§\87 à¦¦à§\87à¦\96ানà§\8bর à¦\9cনà§\8dয à¦¸à¦°à§\8dবাধিà¦\95 à¦ªà¦°à¦¿à¦¬à¦°à§\8dতনà§\87র সংখ্যা:",
        "prefs-watchlist-edits-max": "সর্বোচ্চ সংখ্যা: ১০০০",
        "prefs-watchlist-token": "নজরতালিকা টোকেন:",
        "prefs-misc": "বিবিধ",
        "recentchanges-legend-plusminus": "(''±১২৩'')",
        "recentchanges-submit": "দেখাও",
        "rcfilters-legend-heading": "<strong>সংক্ষিপ্ত রূপের তালিকা:</strong>",
+       "rcfilters-other-review-tools": "<strong>অন্যান্য পর্যালোচনা সরঞ্জাম</strong>",
+       "rcfilters-group-results-by-page": "পাতা অনুযায়ী দলের ফলাফল",
        "rcfilters-activefilters": "সক্রিয় ছাঁকনিসমূহ",
        "rcfilters-advancedfilters": "উন্নত ছাঁকনি",
        "rcfilters-limit-title": "দেখানোর জন্য পরিবর্তনগুলি",
-       "rcfilters-limit-shownum": "শেষ $1টি পরিবর্তন দেখান",
+       "rcfilters-limit-shownum": "শেষ {{PLURAL:$1|পরিবর্তনটি|$1টি পরিবর্তন}} দেখান",
        "rcfilters-days-title": "সাম্প্রতিক দিন",
        "rcfilters-hours-title": "সাম্প্রতিক ঘণ্টা",
        "rcfilters-days-show-days": "$1 {{PLURAL:$1|দিন}}",
        "rcfilters-savedqueries-add-new-title": "বর্তমান ছাঁকনির সেটিং সংরক্ষণ করুন",
        "rcfilters-restore-default-filters": "পূর্বনির্ধারিত ছাঁকনি পুনরুদ্ধার করুন",
        "rcfilters-clear-all-filters": "সব ছাঁকনি পরিষ্কার করুন",
+       "rcfilters-show-new-changes": "নতুনতর পরিবর্তনসমূহ দেখুন",
        "rcfilters-search-placeholder": "সাম্প্রতিক পরিবর্তনসমূহ ছাঁকুন (ব্রাউজ বা টাইপ করা শুরু করুন)",
        "rcfilters-invalid-filter": "অকার্যকর ছাঁকনি",
        "rcfilters-empty-filter": "কোনো সক্রিয় ফিল্টার নেই। সমস্ত অবদান দেখানো হয়েছে।",
        "rcfilters-filter-previousrevision-description": "সব পরিবর্তন যা \"সর্বশেষ সংশোধন\" নয়।",
        "rcfilters-filter-excluded": "বর্জিত",
        "rcfilters-tag-prefix-namespace-inverted": "$1 <strong>:নয়</strong>",
+       "rcfilters-view-advanced-filters-label": "উন্নত ছাঁকনি",
        "rcfilters-view-tags": "ট্যাগকৃত সম্পাদনা",
        "rcfilters-view-tags-tooltip": "সম্পাদনা ট্যাগ ব্যবহার করে ফলাফল ছাঁকুন",
        "rcfilters-view-return-to-default-tooltip": "মূল ছাঁকনির মেনুতে ফিরুন",
        "rcfilters-liveupdates-button": "সরাসরি হালনাগাদ",
+       "rcfilters-liveupdates-button-title-on": "সরাসরি হালনাগাদ বন্ধ করুন",
        "rcnotefrom": "<strong>$2</strong>টা থেকে সংঘটিত পরিবর্তনগুলি (সর্বোচ্চ <strong>$1টি</strong> দেখানো হয়েছে)।",
        "rclistfromreset": "তারিখ নির্বাচন পুনঃস্থাপন করুন",
        "rclistfrom": "$2, $3 তারিখের পর সংঘটিত নতুন পরিবর্তনগুলো দেখাও",
        "import-nonewrevisions": "কোনো সংস্করণ আমদানী করা হয়নি।",
        "xml-error-string": "$1 যে লাইনে $2, কলামে $3 (বাইট $4): $5",
        "import-upload": "XML ডাটা আপলোড",
-       "import-token-mismatch": "সেশন ডাটা হারিয়ে গেছে।\n\nআপনি সম্ভবত সংযোগ হারিয়েছেন। <strong>দয়া করে যাচাই করুন যে আপনি এখনও প্রবেশরত রয়েছেন এবং আবার চেষ্টা করুন</strong>। যদি এটি এখনও কাজ না করে, তাহলে দয়া করে [[Special:UserLogout|অ্যাকাউন্ট থেকে প্রস্থান করুন]] এবং আবার অ্যাকাউন্টে প্রবেশ করে চেষ্টা করুন এবং এবং পরীক্ষা করুন যে আপনার ব্রাউজার এই সাইটে কুকি ব্যবহারের অনুমতি দেয়।",
+       "import-token-mismatch": "সেশন ডাটা হারিয়ে গেছে।\n\nআপনি সম্ভবত সংযোগ হারিয়েছেন। '''দয়া করে যাচাই করুন যে আপনি এখনও প্রবেশরত রয়েছেন এবং আবার চেষ্টা করুন'''। যদি এটি এখনও কাজ না করে, তাহলে দয়া করে [[Special:UserLogout|অ্যাকাউন্ট থেকে প্রস্থান করুন]] এবং আবার অ্যাকাউন্টে প্রবেশ করে চেষ্টা করুন এবং এবং পরীক্ষা করুন যে আপনার ব্রাউজার এই সাইটে কুকি ব্যবহারের অনুমতি দেয়।",
        "import-invalid-interwiki": "নির্ধারিত উইকি থেকে আমদানী করা যাবে না।",
        "import-error-edit": "\"$1\" পাতাটি আমদানি করা যায়নি কারণ আপনার এটি সম্পাদনা করার অনুমতি নেই।",
        "import-error-create": "\"$1\" পাতাটি আমদানি করা যায়নি কারণ আপনার এটি তৈরী করার অনুমতি নেই।",
index b6ec398..75e13f6 100644 (file)
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} ([[Special:NewPages|spisak novih stranica]])",
        "recentchanges-submit": "Prikaži",
        "rcfilters-legend-heading": "<strong>Spisak skraćenica:</strong>",
+       "rcfilters-other-review-tools": "<strong>Drugi alati za pregled</strong>",
        "rcfilters-activefilters": "Aktivni filteri",
        "rcfilters-advancedfilters": "Napredni filteri",
        "rcfilters-limit-title": "Izmjena za prikaz",
        "rcfilters-filter-categorization-label": "Izmjene kategorija",
        "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-filter-logactions-description": "Administrativne radnje, pravljenje računa, brisanje stranica, postavljanje datoteka…",
        "rcfilters-hideminor-conflicts-typeofchange": "Određene vrste izmjena ne mogu se označiti \"manjim\", tako da je ovaj filter u sukobu sa sljedećim filterima za vrstu izmjene: $1",
        "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\".",
        "rcfilters-filtergroup-lastRevision": "Posljednja izmjena",
index 64845e3..dca845c 100644 (file)
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (vegeu també la [[Special:NewPages|llista de pàgines noves]])",
        "recentchanges-legend-plusminus": "(''±123'')",
        "recentchanges-submit": "Mostra",
+       "rcfilters-group-results-by-page": "Agrupa els resultats per pàgina",
        "rcfilters-activefilters": "Filtres actius",
+       "rcfilters-hours-title": "Hores recents",
+       "rcfilters-quickfilters": "Filtres desats",
        "rcfilters-quickfilters-placeholder-title": "Encara no s’ha desat cap enllaç",
        "rcfilters-savedqueries-defaultlabel": "Filtres desats",
        "rcfilters-savedqueries-rename": "Reanomena",
        "fileduplicatesearch-noresults": "No s'ha trobat cap fitxer anomenat «$1».",
        "specialpages": "Pàgines especials",
        "specialpages-note-top": "Llegenda",
-       "specialpages-note": "* Pàgines especials normals.\n* <span class=\"mw-specialpagerestricted\">Pàgines especials restringides.</span>",
        "specialpages-group-maintenance": "Informes de manteniment",
        "specialpages-group-other": "Altres pàgines especials",
        "specialpages-group-login": "Iniciar sessió / Crear un compte",
index 2bc253d..b46df0f 100644 (file)
        "rcfilters-clear-all-filters": "Ерриге литтарш цӀанъян",
        "rcfilters-filterlist-title": "Литтарш",
        "rcfilters-filterlist-noresults": "Литтарш цакарий",
-       "rcfilters-filtergroup-registration": "Декъашхойн регистраци",
-       "rcfilters-filter-registered-label": "Регистрацийинарш",
-       "rcfilters-filter-unregistered-label": "Регистрацицайинарш",
        "rcfilters-filtergroup-authorship": "Нисде авторалла",
        "rcfilters-filter-editsbyself-label": "Хьан дисдарш",
        "rcfilters-filter-editsbyself-description": "Хьан нисдарш.",
        "rcfilters-filter-editsbyother-label": "Кхечу декъашхойн нисдарш",
+       "rcfilters-filter-user-experience-level-registered-label": "Регистрацийинарш",
+       "rcfilters-filter-user-experience-level-unregistered-label": "Регистрацицайинарш",
        "rcfilters-filter-user-experience-level-newcomer-label": "Керланиш",
        "rcfilters-filter-user-experience-level-learner-label": "Доьшуш берш",
        "rcfilters-filter-bots-label": "Бот",
        "fileduplicatesearch-noresults": "ЦӀе «$1» йолуш файл цакарий.",
        "specialpages": "Леррина агӀонаш",
        "specialpages-note-top": "Легенда",
-       "specialpages-note": "* Гуттарлера белха агlонаш.\n* <strong class=\"mw-specialpagerestricted\">Кlеззиг таронаш йолу леррина агlонаш.</strong>",
+       "specialpages-note-restricted": "* Гуттарлера белха агӀонаш.\n* <span class=\"mw-specialpagerestricted\">КӀеззиг таронаш йолу белха агӀонаш.</span>",
        "specialpages-group-maintenance": "Техникийн хьашташ кхочушдаран хаамаш",
        "specialpages-group-other": "Кхин белхан агӀонаш",
        "specialpages-group-login": "Довзийтар / дӀаяздар кхоллар",
index c564c3b..c10766c 100644 (file)
@@ -66,7 +66,7 @@
        "tog-shownumberswatching": "Zobrazovat počet sledujících uživatelů",
        "tog-oldsig": "Váš stávající podpis:",
        "tog-fancysig": "Používat v podpisu wikitext (bez automatického odkazu)",
-       "tog-uselivepreview": "Používat rychlý náhled",
+       "tog-uselivepreview": "Zobrazovat náhledy bez obnovení stránky",
        "tog-forceeditsummary": "Upozornit, když nevyplním shrnutí editace",
        "tog-watchlisthideown": "Na seznamu sledovaných stránek skrýt moje editace",
        "tog-watchlisthidebots": "Na seznamu sledovaných stránek skrýt editace botů",
        "prefs-editwatchlist-clear": "Vyprázdnit seznam sledovaných stránek",
        "prefs-watchlist-days": "Počet dní zobrazených ve sledovaných stránkách:",
        "prefs-watchlist-days-max": "Maximálně $1 {{PLURAL:$1|den|dny|dní}}",
-       "prefs-watchlist-edits": "Počet editací zobrazených ve zdokonalených sledovaných stránkách:",
+       "prefs-watchlist-edits": "Maximální počet editací zobrazených ve sledovaných stránkách:",
        "prefs-watchlist-edits-max": "Maximum: 1000",
        "prefs-watchlist-token": "Klíč k seznamu sledovaných stránek:",
        "prefs-misc": "Různé",
        "recentchanges-legend-plusminus": "(''±123'')",
        "recentchanges-submit": "Zobrazit",
        "rcfilters-legend-heading": "<strong>Seznam zkratek:</strong>",
+       "rcfilters-group-results-by-page": "Seskupit výsledky podle stránky",
        "rcfilters-activefilters": "Aktivní filtry",
        "rcfilters-advancedfilters": "Pokročilé filtry",
        "rcfilters-limit-title": "Zobrazit změny",
-       "rcfilters-limit-shownum": "Zobrazit posledních $1 změn",
+       "rcfilters-limit-shownum": "Zobrazit {{PLURAL:$1|poslední jednu změnu|poslední $1 změny|posledních $1 změn}}",
        "rcfilters-days-title": "Poslední dny",
        "rcfilters-hours-title": "Poslední hodiny",
        "rcfilters-days-show-days": "$1 {{PLURAL:$1|den|dny|dní}}",
        "rcfilters-savedqueries-new-name-label": "Název",
        "rcfilters-savedqueries-new-name-placeholder": "Popište účel filtru",
        "rcfilters-savedqueries-apply-label": "Vytvořit filtr",
+       "rcfilters-savedqueries-apply-and-setdefault-label": "Vytvořit výchozí filtr",
        "rcfilters-savedqueries-cancel-label": "Zrušit",
        "rcfilters-savedqueries-add-new-title": "Uložit současné nastavení filtrů",
        "rcfilters-restore-default-filters": "Obnovit výchozí filtry",
        "rcfilters-clear-all-filters": "Zrušit všechny filtry",
+       "rcfilters-show-new-changes": "Zobrazit nejnovější změny",
        "rcfilters-search-placeholder": "Filtrovat nedávné změny (prohlížejte nebo začněte psát)",
        "rcfilters-invalid-filter": "Neplatný filtr",
        "rcfilters-empty-filter": "Žádné aktivní filtry. Zobrazeny jsou všechny příspěvky.",
        "import-nonewrevisions": "Žádné revize nebyly importovány (buď již byly všechny importovány dříve, nebo byly přeskočeny kvůli chybám).",
        "xml-error-string": "$1 na řádku $2, sloupec $3 (bajt $4): $5",
        "import-upload": "Importovat XML data",
-       "import-token-mismatch": "Ztratila se data relace.\n\nMožná jste byli odhlášeni. <strong>Zkontrolujte, že jste stále přihlášeni a zkuste to prosím znovu.</strong>\nPokud se tento problém bude opakovat, zkuste se [[Special:UserLogout|odhlásit]] a znovu přihlásit a zkontrolujte, že váš prohlížeč dovoluje přijímat cookie z tohoto serveru.",
+       "import-token-mismatch": "Ztratila se data relace.\n\nMožná jste byli odhlášeni. '''Zkontrolujte, že jste stále přihlášeni a zkuste to prosím znovu.'''\nPokud se tento problém bude opakovat, zkuste se [[Special:UserLogout|odhlásit]] a znovu přihlásit a zkontrolujte, že váš prohlížeč dovoluje přijímat cookie z tohoto serveru.",
        "import-invalid-interwiki": "Ze zadané wiki nelze importovat.",
        "import-error-edit": "Stránka „$1“ se nenaimportovala, protože nemáte oprávnění ji editovat.",
        "import-error-create": "Stránka „$1“ se nenaimportovala, protože nemáte oprávnění ji založit.",
index ec4fe66..cac833e 100644 (file)
@@ -11,7 +11,8 @@
                        "아라",
                        "Chuvash2014",
                        "Macofe",
-                       "Chuvash"
+                       "Chuvash",
+                       "Marat-avgust"
                ]
        },
        "tog-underline": "Ссылкăсене аялтан туртса палармалла:",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (пăхăр [[Special:NewPages|çĕнĕ страницăсен списокĕ]])",
        "recentchanges-legend-plusminus": "(<em>±123</em>)",
        "recentchanges-submit": "Кăтарт",
+       "rcfilters-filter-user-experience-level-newcomer-label": "Çĕнĕ хутшăнакансем",
        "rclistfrom": "$2, $3 тытăнса çĕнĕ улăшăнисене кăтартни",
        "rcshowhideminor": "пĕчĕк тӳрлетнисене $1",
        "rcshowhideminor-show": "кăтартмалла",
index ea0381d..009b24b 100644 (file)
        "tog-shownumberswatching": "Anzahl der beobachtenden Benutzer anzeigen",
        "tog-oldsig": "Die vorhandene Signatur:",
        "tog-fancysig": "Signatur als Wikitext behandeln (ohne automatische Verlinkung)",
-       "tog-uselivepreview": "Vorschau sofort anzeigen",
+       "tog-uselivepreview": "Vorschau ohne Neuladen der Seite anzeigen",
        "tog-forceeditsummary": "Warnen, sofern beim Speichern die Zusammenfassung fehlt",
        "tog-watchlisthideown": "Eigene Bearbeitungen in der Beobachtungsliste ausblenden",
        "tog-watchlisthidebots": "Bearbeitungen durch Bots in der Beobachtungsliste ausblenden",
        "permissionserrorstext-withaction": "Du bist aus {{PLURAL:$1|dem folgenden Grund|den folgenden Gründen}} nicht berechtigt, $2:",
        "contentmodelediterror": "Du kannst diese Version nicht bearbeiten, da das Inhaltsmodell <code>$1</code> vom aktuellen Inhaltsmodell der Seite <code>$2</code> abweicht.",
        "recreate-moveddeleted-warn": "<strong>Achtung: Du erstellst eine Seite, die bereits früher gelöscht wurde.</strong>\n\nBitte prüfe sorgfältig, ob die erneute Seitenerstellung den Richtlinien entspricht.\nZu deiner Information folgt das Lösch- und Verschiebungs-Logbuch mit der Begründung für die vorhergehende Löschung:",
-       "moveddeleted-notice": "Diese Seite wurde gelöscht.\nZur Information folgt das Lösch- und Verschiebungs-Logbuch dieser Seite.",
-       "moveddeleted-notice-recent": "Diese Seite wurde kürzlich gelöscht (innerhalb der letzten 24 Stunden).\nZur Information folgt das Lösch- und Verschiebungs-Logbuch dieser Seite.",
+       "moveddeleted-notice": "Diese Seite wurde gelöscht.\nZur Information folgt das Lösch-, Seitenschutz- und Verschiebungs-Logbuch dieser Seite.",
+       "moveddeleted-notice-recent": "Diese Seite wurde kürzlich gelöscht (innerhalb der letzten 24 Stunden).\nZur Information folgt das Lösch-, Seitenschutz- und Verschiebungs-Logbuch dieser Seite.",
        "log-fulllog": "Alle Logbucheinträge ansehen",
        "edit-hook-aborted": "Die Bearbeitung wurde ohne Erklärung durch eine Schnittstelle abgebrochen.",
        "edit-gone-missing": "Die Seite konnte nicht aktualisiert werden.\nSie wurde anscheinend gelöscht.",
        "recentchanges-legend-plusminus": "''(±123)''",
        "recentchanges-submit": "Anzeigen",
        "rcfilters-legend-heading": "<strong>Liste von Abkürzungen:</strong>",
-       "rcfilters-other-review-tools": "<strong>Andere Überprüfungswerkzeuge:</strong>",
+       "rcfilters-other-review-tools": "<strong>Andere Überprüfungswerkzeuge</strong>",
+       "rcfilters-group-results-by-page": "Ergebnisse nach Seite gruppieren",
+       "rcfilters-grouping-title": "Gruppierung",
        "rcfilters-activefilters": "Aktive Filter",
        "rcfilters-advancedfilters": "Erweiterte Filter",
        "rcfilters-limit-title": "Anzuzeigende Änderungen",
-       "rcfilters-limit-shownum": "Die letzten $1 Änderungen anzeigen",
+       "rcfilters-limit-shownum": "Die {{PLURAL:$1|letzte Änderung|letzten $1 Änderungen}} anzeigen",
        "rcfilters-days-title": "Letzte Tage",
        "rcfilters-hours-title": "Letzte Stunden",
        "rcfilters-days-show-days": "{{PLURAL:$1|Ein Tag|$1 Tage}}",
        "rcfilters-savedqueries-add-new-title": "Aktuelle Filtereinstellungen speichern",
        "rcfilters-restore-default-filters": "Standardfilter wiederherstellen",
        "rcfilters-clear-all-filters": "Alle Filter löschen",
+       "rcfilters-show-new-changes": "Neueste Änderungen ansehen",
+       "rcfilters-previous-changes-label": "Zuletzt angesehene Änderungen",
        "rcfilters-search-placeholder": "Letzte Änderungen filtern (durchsuchen oder beginne mit der Eingabe)",
        "rcfilters-invalid-filter": "Ungültiger Filter",
        "rcfilters-empty-filter": "Keine aktiven Filter. Es werden alle Beiträge angezeigt.",
        "rcfilters-tag-prefix-namespace-inverted": "<strong>:nicht</strong> $1",
        "rcfilters-exclude-button-off": "Ausgewählte ausschließen",
        "rcfilters-exclude-button-on": "Ausgewählte ausgeschlossen",
+       "rcfilters-view-advanced-filters-label": "Erweiterte Filter",
        "rcfilters-view-tags": "Markierte Bearbeitungen",
        "rcfilters-view-namespaces-tooltip": "Ergebnisse nach Namensraum filtern",
        "rcfilters-view-tags-tooltip": "Ergebnisse filtern, die Bearbeitungsmarkierungen verwenden",
        "rcfilters-view-return-to-default-tooltip": "Zurück zum Hauptfiltermenü",
        "rcfilters-liveupdates-button": "Live-Aktualisierungen",
+       "rcfilters-liveupdates-button-title-on": "Live-Aktualisierungen ausschalten",
+       "rcfilters-liveupdates-button-title-off": "Neue Änderungen bei Auftreten anzeigen",
        "rcnotefrom": "Angezeigt {{PLURAL:$5|wird die Änderung|werden die Änderungen}} seit <strong>$3, $4</strong> (max. <strong>$1</strong> Einträge).",
        "rclistfromreset": "Datumsauswahl zurücksetzen",
        "rclistfrom": "Nur Änderungen seit $3, $2 Uhr zeigen.",
        "import-nonewrevisions": "Es wurden keine Versionen importiert. Entweder waren alle bereits vorhanden oder wurden aufgrund von Fehlern übersprungen.",
        "xml-error-string": "$1 Zeile $2, Spalte $3, (Byte $4): $5",
        "import-upload": "XML-Dateien importieren",
-       "import-token-mismatch": "Die Sitzungsdaten sind verloren gegangen.\n\nDu wurdest eventuell abgemeldet. <strong>Bitte verifiziere, dass du noch angemeldet bist und versuche es erneut</strong>.\nFalls dies nicht funktioniert, versuche dich [[Special:UserLogout|abzumelden]] und anschließend wieder anzumelden und überprüfe, ob dein Browser Cookies von dieser Website akzeptiert.",
+       "import-token-mismatch": "Die Sitzungsdaten sind verloren gegangen.\n\nDu wurdest eventuell abgemeldet. '''Bitte verifiziere, dass du noch angemeldet bist und versuche es erneut'''.\nFalls dies nicht funktioniert, versuche dich [[Special:UserLogout|abzumelden]] und anschließend wieder anzumelden und überprüfe, ob dein Browser Cookies von dieser Website akzeptiert.",
        "import-invalid-interwiki": "Aus dem angegebenen Wiki ist kein Import möglich.",
        "import-error-edit": "Die Seite „$1“ wurde nicht importiert, da du nicht berechtigt bist, sie zu bearbeiten.",
        "import-error-create": "Die Seite „$1“ wurde nicht importiert, da du nicht berechtigt bist, sie zu erstellen.",
index 8c295b2..61a113e 100644 (file)
@@ -30,7 +30,7 @@
        "tog-shownumberswatching": "Show the number of watching users",
        "tog-oldsig": "Your existing signature:",
        "tog-fancysig": "Treat signature as wikitext (without an automatic link)",
-       "tog-uselivepreview": "Use live preview",
+       "tog-uselivepreview": "Show previews without reloading the page",
        "tog-forceeditsummary": "Prompt me when entering a blank edit summary",
        "tog-watchlisthideown": "Hide my edits from the watchlist",
        "tog-watchlisthidebots": "Hide bot edits from the watchlist",
        "permissionserrorstext-withaction": "You do not have permission to $2, for the following {{PLURAL:$1|reason|reasons}}:",
        "contentmodelediterror": "You cannot edit this revision because its content model is <code>$1</code>, which differs from the current content model of the page <code>$2</code>.",
        "recreate-moveddeleted-warn": "<strong>Warning: You are recreating a page that was previously deleted.</strong>\n\nYou should consider whether it is appropriate to continue editing this page.\nThe deletion and move log for this page are provided here for convenience:",
-       "moveddeleted-notice": "This page has been deleted.\nThe deletion and move log for the page are provided below for reference.",
-       "moveddeleted-notice-recent": "Sorry, this page was recently deleted (within the last 24 hours).\nThe deletion and move log for the page are provided below for reference.",
+       "moveddeleted-notice": "This page has been deleted.\nThe deletion, protection, and move log for the page are provided below for reference.",
+       "moveddeleted-notice-recent": "Sorry, this page was recently deleted (within the last 24 hours).\nThe deletion, protection, and move log for the page are provided below for reference.",
        "log-fulllog": "View full log",
        "edit-hook-aborted": "Edit aborted by hook.\nIt gave no explanation.",
        "edit-gone-missing": "Could not update the page.\nIt appears to have been deleted.",
        "prefs-editwatchlist-clear": "Clear your watchlist",
        "prefs-watchlist-days": "Days to show in watchlist:",
        "prefs-watchlist-days-max": "Maximum $1 {{PLURAL:$1|day|days}}",
-       "prefs-watchlist-edits": "Maximum number of changes to show in expanded watchlist:",
+       "prefs-watchlist-edits": "Maximum number of changes to show in watchlist:",
        "prefs-watchlist-edits-max": "Maximum number: 1000",
        "prefs-watchlist-token": "Watchlist token:",
        "prefs-misc": "Misc",
        "recentchanges-legend-plusminus": "(<em>±123</em>)",
        "recentchanges-submit": "Show",
        "rcfilters-legend-heading": "<strong>List of abbreviations:</strong>",
-       "rcfilters-other-review-tools": "<strong>Other review tools:</strong>",
+       "rcfilters-other-review-tools": "<strong>Other review tools</strong>",
+       "rcfilters-group-results-by-page": "Group results by page",
+       "rcfilters-grouping-title": "Grouping",
        "rcfilters-activefilters": "Active filters",
        "rcfilters-advancedfilters": "Advanced filters",
        "rcfilters-limit-title": "Changes to show",
-       "rcfilters-limit-shownum": "Show last $1 changes",
+       "rcfilters-limit-shownum": "Show last {{PLURAL:$1|change|$1 changes}}",
        "rcfilters-days-title": "Recent days",
        "rcfilters-hours-title": "Recent hours",
        "rcfilters-days-show-days": "$1 {{PLURAL:$1|day|days}}",
        "rcfilters-savedqueries-add-new-title": "Save current filter settings",
        "rcfilters-restore-default-filters": "Restore default filters",
        "rcfilters-clear-all-filters": "Clear all filters",
-       "rcfilters-show-new-changes": "Show new changes",
+       "rcfilters-show-new-changes": "View newest changes",
        "rcfilters-previous-changes-label": "Previously viewed changes",
        "rcfilters-search-placeholder": "Filter recent changes (browse or start typing)",
        "rcfilters-invalid-filter": "Invalid filter",
        "rcfilters-tag-prefix-tags": "#$1",
        "rcfilters-exclude-button-off": "Exclude selected",
        "rcfilters-exclude-button-on": "Excluding selected",
+       "rcfilters-view-advanced-filters-label": "Advanced filters",
        "rcfilters-view-tags": "Tagged edits",
        "rcfilters-view-namespaces-tooltip": "Filter results by namespace",
        "rcfilters-view-tags-tooltip": "Filter results using edit tags",
        "rcfilters-view-return-to-default-tooltip": "Return to main filter menu",
        "rcfilters-liveupdates-button": "Live updates",
+       "rcfilters-liveupdates-button-title-on": "Turn off live updates",
+       "rcfilters-liveupdates-button-title-off": "Display new changes as they happen",
        "rcnotefrom": "Below {{PLURAL:$5|is the change|are the changes}} since <strong>$3, $4</strong> (up to <strong>$1</strong> shown).",
        "rclistfromreset": "Reset date selection",
        "rclistfrom": "Show new changes starting from $2, $3",
        "import-nonewrevisions": "No revisions imported (all were either already present, or skipped due to errors).",
        "xml-error-string": "$1 at line $2, col $3 (byte $4): $5",
        "import-upload": "Upload XML data",
-       "import-token-mismatch": "Loss of session data.\n\nYou might have been logged out. <strong>Please verify that you're still logged in and try again</strong>.\nIf it still does not work, try [[Special:UserLogout|logging out]] and logging back in, and check that your browser allows cookies from this site.",
+       "import-token-mismatch": "Loss of session data.\n\nYou might have been logged out. '''Please verify that you're still logged in and try again'''.\nIf it still does not work, try [[Special:UserLogout|logging out]] and logging back in, and check that your browser allows cookies from this site.",
        "import-invalid-interwiki": "Cannot import from the specified wiki.",
        "import-error-edit": "Page \"$1\" was not imported because you are not allowed to edit it.",
        "import-error-create": "Page \"$1\" was not imported because you are not allowed to create it.",
index b93f4c5..1bf4916 100644 (file)
                        "Javiersanp",
                        "Josecurioso",
                        "Jnistal12",
-                       "Javier"
+                       "Javier",
+                       "Luisangelrg"
                ]
        },
        "tog-underline": "Subrayar los enlaces:",
        "tog-shownumberswatching": "Mostrar el número de usuarios que la vigilan",
        "tog-oldsig": "Tu firma actual:",
        "tog-fancysig": "Tratar la firma como wikitexto (sin un enlace automático)",
-       "tog-uselivepreview": "Usar previsualización dinámica",
+       "tog-uselivepreview": "Muestra una previsualización sin tener que recargar la página",
        "tog-forceeditsummary": "Avisarme cuando deje en blanco el resumen de la edición",
        "tog-watchlisthideown": "Ocultar mis ediciones de la lista de seguimiento",
        "tog-watchlisthidebots": "Ocultar las ediciones de bots de la lista de seguimiento",
        "prefs-editwatchlist-clear": "Limpiar tu lista de seguimiento",
        "prefs-watchlist-days": "Número de días que mostrar en la lista de seguimiento:",
        "prefs-watchlist-days-max": "Máximo $1 {{PLURAL:$1|día|días}}",
-       "prefs-watchlist-edits": "Número máximo de ediciones que mostrar en la lista expandida:",
+       "prefs-watchlist-edits": "Número máximo de ediciones a mostrar en la lista de seguimiento:",
        "prefs-watchlist-edits-max": "Cantidad máxima: 1000",
        "prefs-watchlist-token": "Clave de lista de seguimiento:",
        "prefs-misc": "Varias",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (véase también la [[Special:NewPages|lista de páginas nuevas]])",
        "recentchanges-submit": "Mostrar",
        "rcfilters-legend-heading": "<strong>Lista de abreviaturas:</strong>",
-       "rcfilters-other-review-tools": "<strong>Otras herramientas de revisión:</strong>",
+       "rcfilters-other-review-tools": "<strong>Otras herramientas de revisión</strong>",
+       "rcfilters-group-results-by-page": "Agrupar resultados por página",
+       "rcfilters-grouping-title": "Agrupando",
        "rcfilters-activefilters": "Filtros activos",
        "rcfilters-advancedfilters": "Filtros avanzados",
        "rcfilters-limit-title": "Cambios para&nb