Merge "Rank aliases in search in order they appear in the messages file."
authorjenkins-bot <jenkins-bot@gerrit.wikimedia.org>
Thu, 1 Dec 2016 09:54:21 +0000 (09:54 +0000)
committerGerrit Code Review <gerrit@wikimedia.org>
Thu, 1 Dec 2016 09:54:21 +0000 (09:54 +0000)
148 files changed:
RELEASE-NOTES-1.29
autoload.php
composer.json
includes/DefaultSettings.php
includes/Message.php
includes/Setup.php
includes/api/ApiCheckToken.php
includes/api/ApiPageSet.php
includes/api/ApiQuerySearch.php
includes/auth/LocalPasswordPrimaryAuthenticationProvider.php
includes/cache/MessageCache.php
includes/debug/logger/monolog/LogstashFormatter.php [new file with mode: 0644]
includes/debug/logger/monolog/WikiProcessor.php
includes/filerepo/file/File.php
includes/http/CurlHttpRequest.php
includes/http/Http.php
includes/http/MWHttpRequest.php
includes/http/PhpHttpRequest.php
includes/installer/DatabaseUpdater.php
includes/libs/CookieJar.php
includes/libs/rdbms/connectionmanager/ConnectionManager.php [new file with mode: 0644]
includes/libs/rdbms/connectionmanager/SessionConsistentConnectionManager.php [new file with mode: 0644]
includes/media/Bitmap.php
includes/media/DjVu.php
includes/media/Jpeg.php
includes/media/MediaTransformOutput.php
includes/media/SVG.php
includes/media/TransformationalImageHandler.php
includes/page/ImageHistoryPseudoPager.php
includes/password/ParameterizedPassword.php
includes/password/Password.php
includes/specials/SpecialAllPages.php
includes/specials/SpecialAncientpages.php
includes/specials/SpecialBlock.php
includes/specials/SpecialBrokenRedirects.php
includes/specials/SpecialDoubleRedirects.php
includes/specials/SpecialListgrants.php
includes/specials/SpecialSearch.php
includes/specials/SpecialUserrights.php
includes/specials/pagers/CategoryPager.php
includes/user/User.php
languages/i18n/af.json
languages/i18n/azb.json
languages/i18n/be-tarask.json
languages/i18n/be.json
languages/i18n/bn.json
languages/i18n/cs.json
languages/i18n/diq.json
languages/i18n/dty.json
languages/i18n/en.json
languages/i18n/et.json
languages/i18n/fi.json
languages/i18n/hy.json
languages/i18n/kk-cyrl.json
languages/i18n/mr.json
languages/i18n/qqq.json
languages/i18n/roa-tara.json
languages/i18n/sah.json
languages/i18n/sl.json
languages/i18n/tr.json
languages/i18n/udm.json
languages/i18n/uk.json
maintenance/protect.php
resources/lib/oojs-ui/i18n/el.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-mediawiki.css
resources/lib/oojs-ui/oojs-ui-core.js
resources/lib/oojs-ui/oojs-ui-mediawiki.js
resources/lib/oojs-ui/oojs-ui-toolbars-apex.css
resources/lib/oojs-ui/oojs-ui-toolbars-mediawiki.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-mediawiki.css
resources/lib/oojs-ui/oojs-ui-widgets.js
resources/lib/oojs-ui/oojs-ui-windows-apex.css
resources/lib/oojs-ui/oojs-ui-windows-mediawiki.css
resources/lib/oojs-ui/oojs-ui-windows.js
resources/lib/oojs-ui/themes/mediawiki/icons-alerts.json
resources/lib/oojs-ui/themes/mediawiki/icons-content.json
resources/lib/oojs-ui/themes/mediawiki/icons-editing-advanced.json
resources/lib/oojs-ui/themes/mediawiki/icons-editing-core.json
resources/lib/oojs-ui/themes/mediawiki/icons-editing-list.json
resources/lib/oojs-ui/themes/mediawiki/icons-editing-styling.json
resources/lib/oojs-ui/themes/mediawiki/icons-interactions.json
resources/lib/oojs-ui/themes/mediawiki/icons-layout.json
resources/lib/oojs-ui/themes/mediawiki/icons-location.json
resources/lib/oojs-ui/themes/mediawiki/icons-media.json
resources/lib/oojs-ui/themes/mediawiki/icons-moderation.json
resources/lib/oojs-ui/themes/mediawiki/icons-movement.json
resources/lib/oojs-ui/themes/mediawiki/icons-user.json
resources/lib/oojs-ui/themes/mediawiki/icons-wikimedia.json
resources/lib/oojs-ui/themes/mediawiki/icons.json
resources/lib/oojs-ui/themes/mediawiki/images/icons/block-destructive.png
resources/lib/oojs-ui/themes/mediawiki/images/icons/block-destructive.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/cancel-destructive.png
resources/lib/oojs-ui/themes/mediawiki/images/icons/cancel-destructive.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/check-destructive.png
resources/lib/oojs-ui/themes/mediawiki/images/icons/check-destructive.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/lock-ltr-destructive.png
resources/lib/oojs-ui/themes/mediawiki/images/icons/lock-ltr-destructive.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/lock-rtl-destructive.png
resources/lib/oojs-ui/themes/mediawiki/images/icons/lock-rtl-destructive.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/tag-destructive.png
resources/lib/oojs-ui/themes/mediawiki/images/icons/tag-destructive.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/trash-destructive.png
resources/lib/oojs-ui/themes/mediawiki/images/icons/trash-destructive.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/unLock-ltr-destructive.png
resources/lib/oojs-ui/themes/mediawiki/images/icons/unLock-ltr-destructive.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/unLock-rtl-destructive.png
resources/lib/oojs-ui/themes/mediawiki/images/icons/unLock-rtl-destructive.svg
resources/lib/oojs-ui/themes/mediawiki/indicators.json
resources/src/mediawiki.action/mediawiki.action.history.styles.css
resources/src/mediawiki.action/mediawiki.action.view.filepage.css
resources/src/mediawiki.language/mediawiki.language.numbers.js
resources/src/mediawiki.legacy/shared.css
resources/src/mediawiki.less/mediawiki.ui/variables.less
resources/src/mediawiki.skinning/content.css
resources/src/mediawiki.skinning/elements.css
resources/src/mediawiki.skinning/interface.css
resources/src/mediawiki.widgets/mw.widgets.SearchInputWidget.js
resources/src/mediawiki.widgets/mw.widgets.TitleWidget.js
resources/src/mediawiki/api.js
resources/src/mediawiki/page/gallery.css
tests/common/TestsAutoLoader.php
tests/integration/includes/http/CurlHttpRequestTest.php [new file with mode: 0644]
tests/integration/includes/http/MWHttpRequestTestCase.php [new file with mode: 0644]
tests/integration/includes/http/PhpHttpRequestTest.php [new file with mode: 0644]
tests/phpunit/includes/HttpTest.php [deleted file]
tests/phpunit/includes/MessageTest.php
tests/phpunit/includes/auth/LocalPasswordPrimaryAuthenticationProviderTest.php
tests/phpunit/includes/debug/logger/monolog/LogstashFormatterTest.php [new file with mode: 0644]
tests/phpunit/includes/http/HttpTest.php [new file with mode: 0644]
tests/phpunit/includes/installer/DatabaseUpdaterTest.php [deleted file]
tests/phpunit/includes/libs/rdbms/connectionmanager/ConnectionManagerTest.php [new file with mode: 0644]
tests/phpunit/includes/libs/rdbms/connectionmanager/SessionConsistentConnectionManagerTest.php [new file with mode: 0644]
tests/phpunit/includes/registration/ExtensionRegistryTest.php
tests/qunit/suites/resources/mediawiki.api/mediawiki.ForeignApi.test.js
tests/qunit/suites/resources/mediawiki.api/mediawiki.api.category.test.js
tests/qunit/suites/resources/mediawiki.api/mediawiki.api.messages.test.js
tests/qunit/suites/resources/mediawiki.api/mediawiki.api.options.test.js
tests/qunit/suites/resources/mediawiki.api/mediawiki.api.parse.test.js
tests/qunit/suites/resources/mediawiki.api/mediawiki.api.upload.test.js
tests/qunit/suites/resources/mediawiki.api/mediawiki.api.watch.test.js
tests/qunit/suites/resources/mediawiki/mediawiki.jqueryMsg.test.js
tests/qunit/suites/resources/mediawiki/mediawiki.language.test.js
tests/qunit/suites/resources/mediawiki/mediawiki.loader.test.js
thumb.php

index 5b5640f..21a94c5 100644 (file)
@@ -54,6 +54,10 @@ changes to languages because of Phabricator reports.
 === Other changes in 1.29 ===
 * Database::getSearchEngine() (deprecated in 1.28) was removed. Use
   SearchEngineFactory::getSearchEngineClass() instead.
+* $wgSessionsInMemcached (deprecated in 1.20) was removed. No replacement is
+  required as all sessions are stored in Object Cache now.
+* MWHttpRequest::execute() should be considered to return a StatusValue; the
+  Status return type is deprecated.
 
 == Compatibility ==
 
index 30ef985..0d6407b 100644 (file)
@@ -875,6 +875,7 @@ $wgAutoloadLocalClasses = [
        'MediaWiki\\Logger\\Monolog\\LegacyFormatter' => __DIR__ . '/includes/debug/logger/monolog/LegacyFormatter.php',
        'MediaWiki\\Logger\\Monolog\\LegacyHandler' => __DIR__ . '/includes/debug/logger/monolog/LegacyHandler.php',
        'MediaWiki\\Logger\\Monolog\\LineFormatter' => __DIR__ . '/includes/debug/logger/monolog/LineFormatter.php',
+       'MediaWiki\\Logger\\Monolog\\LogstashFormatter' => __DIR__ . '/includes/debug/logger/monolog/LogstashFormatter.php',
        'MediaWiki\\Logger\\Monolog\\SyslogHandler' => __DIR__ . '/includes/debug/logger/monolog/SyslogHandler.php',
        'MediaWiki\\Logger\\Monolog\\WikiProcessor' => __DIR__ . '/includes/debug/logger/monolog/WikiProcessor.php',
        'MediaWiki\\Logger\\NullSpi' => __DIR__ . '/includes/debug/logger/NullSpi.php',
@@ -1569,6 +1570,8 @@ $wgAutoloadLocalClasses = [
        'WikiRevision' => __DIR__ . '/includes/import/WikiRevision.php',
        'WikiStatsOutput' => __DIR__ . '/maintenance/language/StatOutputs.php',
        'WikiTextStructure' => __DIR__ . '/includes/content/WikiTextStructure.php',
+       'Wikimedia\\Rdbms\\ConnectionManager' => __DIR__ . '/includes/libs/rdbms/connectionmanager/ConnectionManager.php',
+       'Wikimedia\\Rdbms\\SessionConsistentConnectionManager' => __DIR__ . '/includes/libs/rdbms/connectionmanager/SessionConsistentConnectionManager.php',
        'WikitextContent' => __DIR__ . '/includes/content/WikitextContent.php',
        'WikitextContentHandler' => __DIR__ . '/includes/content/WikitextContentHandler.php',
        'WinCacheBagOStuff' => __DIR__ . '/includes/libs/objectcache/WinCacheBagOStuff.php',
index e1d9f47..19ca238 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.18.0",
+               "oojs/oojs-ui": "0.18.1",
                "oyejorge/less.php": "1.7.0.10",
                "php": ">=5.5.9",
                "psr/log": "1.0.0",
index eb778b5..5557dca 100644 (file)
@@ -2365,13 +2365,6 @@ $wgMainStash = 'db-replicated';
  */
 $wgParserCacheExpireTime = 86400;
 
-/**
- * Deprecated alias for $wgSessionsInObjectCache.
- *
- * @deprecated since 1.20; Use $wgSessionsInObjectCache
- */
-$wgSessionsInMemcached = true;
-
 /**
  * @deprecated since 1.27, session data is always stored in object cache.
  */
index 85c78d6..7e5cc7d 100644 (file)
@@ -168,6 +168,17 @@ class Message implements MessageSpecifier, Serializable {
        /** Transform {{..}} constructs, HTML-escape the result */
        const FORMAT_ESCAPED = 'escaped';
 
+       /**
+        * Mapping from Message::listParam() types to Language methods.
+        * @var array
+        */
+       protected static $listTypeMap = [
+               'comma' => 'commaList',
+               'semicolon' => 'semicolonList',
+               'pipe' => 'pipeList',
+               'text' => 'listToText',
+       ];
+
        /**
         * In which language to get this message. True, which is the default,
         * means the current user language, false content language.
@@ -1070,6 +1081,22 @@ class Message implements MessageSpecifier, Serializable {
                return [ 'plaintext' => $plaintext ];
        }
 
+       /**
+        * @since 1.29
+        *
+        * @param array $list
+        * @param string $type 'comma', 'semicolon', 'pipe', 'text'
+        * @return array Array with "list" and "type" keys.
+        */
+       public static function listParam( array $list, $type = 'text' ) {
+               if ( !isset( self::$listTypeMap[$type] ) ) {
+                       throw new InvalidArgumentException(
+                               "Invalid type '$type'. Known types are: " . join( ', ', array_keys( self::$listTypeMap ) )
+                       );
+               }
+               return [ 'list' => $list, 'type' => $type ];
+       }
+
        /**
         * Substitutes any parameters into the message text.
         *
@@ -1123,6 +1150,8 @@ class Message implements MessageSpecifier, Serializable {
                                return [ 'before', $this->getLanguage()->formatBitrate( $param['bitrate'] ) ];
                        } elseif ( isset( $param['plaintext'] ) ) {
                                return [ 'after', $this->formatPlaintext( $param['plaintext'], $format ) ];
+                       } elseif ( isset( $param['list'] ) ) {
+                               return $this->formatListParam( $param['list'], $param['type'], $format );
                        } else {
                                $warning = 'Invalid parameter for message "' . $this->getKey() . '": ' .
                                        htmlspecialchars( serialize( $param ) );
@@ -1251,6 +1280,54 @@ class Message implements MessageSpecifier, Serializable {
 
                }
        }
+
+       /**
+        * Formats a list of parameters as a concatenated string.
+        * @since 1.29
+        * @param array $params
+        * @param string $listType
+        * @param string $format One of the FORMAT_* constants.
+        * @return array Array with the parameter type (either "before" or "after") and the value.
+        */
+       protected function formatListParam( array $params, $listType, $format ) {
+               if ( !isset( self::$listTypeMap[$listType] ) ) {
+                       $warning = 'Invalid list type for message "' . $this->getKey() . '": ' .
+                               htmlspecialchars( serialize( $param ) );
+                       trigger_error( $warning, E_USER_WARNING );
+                       $e = new Exception;
+                       wfDebugLog( 'Bug58676', $warning . "\n" . $e->getTraceAsString() );
+                       return [ 'before', '[INVALID]' ];
+               }
+               $func = self::$listTypeMap[$listType];
+
+               // Handle an empty list sensibly
+               if ( !$params ) {
+                       return [ 'before', $this->getLanguage()->$func( [] ) ];
+               }
+
+               // First, determine what kinds of list items we have
+               $types = [];
+               $vars = [];
+               $list = [];
+               foreach ( $params as $n => $p ) {
+                       list( $type, $value ) = $this->extractParam( $p, $format );
+                       $types[$type] = true;
+                       $list[] = $value;
+                       $vars[] = '$' . ( $n + 1 );
+               }
+
+               // Easy case: all are 'before' or 'after', so just join the
+               // values and use the same type.
+               if ( count( $types ) === 1 ) {
+                       return [ key( $types ), $this->getLanguage()->$func( $list ) ];
+               }
+
+               // Hard case: We need to process each value per its type, then
+               // return the concatenated values as 'after'. We handle this by turning
+               // the list into a RawMessage and processing that as a parameter.
+               $vars = $this->getLanguage()->$func( $vars );
+               return $this->extractParam( new RawMessage( $vars, $params ), $format );
+       }
 }
 
 /**
index 357c76d..9f722af 100644 (file)
@@ -462,7 +462,7 @@ if ( $wgMaximalPasswordLength !== false ) {
 }
 
 // Backwards compatibility warning
-if ( !$wgSessionsInObjectCache && !$wgSessionsInMemcached ) {
+if ( !$wgSessionsInObjectCache ) {
        wfDeprecated( '$wgSessionsInObjectCache = false', '1.27' );
        if ( $wgSessionHandler ) {
                wfDeprecated( '$wgSessionsHandler', '1.27' );
index 3d2159c..dd88b5f 100644 (file)
@@ -22,6 +22,8 @@
  * @file
  */
 
+use MediaWiki\Session\Token;
+
 /**
  * @since 1.25
  * @ingroup API
@@ -39,6 +41,13 @@ class ApiCheckToken extends ApiBase {
                $tokenObj = ApiQueryTokens::getToken(
                        $this->getUser(), $this->getRequest()->getSession(), $salts[$params['type']]
                );
+
+               if ( substr( $token, -strlen( urldecode( Token::SUFFIX ) ) ) === urldecode( Token::SUFFIX ) ) {
+                       $this->setWarning(
+                               "Check that symbols such as \"+\" in the token are properly percent-encoded in the URL."
+                       );
+               }
+
                if ( $tokenObj->match( $token, $maxage ) ) {
                        $res['result'] = 'valid';
                } elseif ( $maxage !== null && $tokenObj->match( $token ) ) {
@@ -47,7 +56,7 @@ class ApiCheckToken extends ApiBase {
                        $res['result'] = 'invalid';
                }
 
-               $ts = MediaWiki\Session\Token::getTimestamp( $token );
+               $ts = Token::getTimestamp( $token );
                if ( $ts !== null ) {
                        $mwts = new MWTimestamp();
                        $mwts->timestamp->setTimestamp( $ts );
index 1a509c5..853a805 100644 (file)
@@ -1412,13 +1412,7 @@ class ApiPageSet extends ApiBase {
                                ApiBase::PARAM_DFLT => false,
                                ApiBase::PARAM_HELP_MSG => [
                                        'api-pageset-param-converttitles',
-                                       new DeferredStringifier(
-                                               function ( IContextSource $context ) {
-                                                       return $context->getLanguage()
-                                                               ->commaList( LanguageConverter::$languagesWithVariants );
-                                               },
-                                               $this
-                                       )
+                                       [ Message::listParam( LanguageConverter::$languagesWithVariants, 'text' ) ],
                                ],
                        ],
                ];
index 6be5198..9962d5e 100644 (file)
@@ -107,10 +107,25 @@ class ApiQuerySearch extends ApiQueryGeneratorBase {
                                $matches = $search->searchText( $query );
                        }
                }
-               if ( is_null( $matches ) ) {
+
+               if ( $matches instanceof Status ) {
+                       $status = $matches;
+                       $matches = $status->getValue();
+               } else {
+                       $status = null;
+               }
+
+               if ( $status ) {
+                       if ( $status->isOK() ) {
+                               $this->getMain()->getErrorFormatter()->addMessagesFromStatus(
+                                       $this->getModuleName(),
+                                       $status
+                               );
+                       } else {
+                               $this->dieUsage( $status->getWikiText( false, false, 'en' ), 'search-error' );
+                       }
+               } elseif ( is_null( $matches ) ) {
                        $this->dieUsage( "{$what} search is disabled", "search-{$what}-disabled" );
-               } elseif ( $matches instanceof Status && !$matches->isGood() ) {
-                       $this->dieUsage( $matches->getWikiText( false, false, 'en' ), 'search-error' );
                }
 
                if ( $resultPageSet === null ) {
index 859fd0c..fd36887 100644 (file)
@@ -242,14 +242,14 @@ class LocalPasswordPrimaryAuthenticationProvider
 
                $pwhash = null;
 
-               if ( $this->loginOnly ) {
-                       $pwhash = $this->getPasswordFactory()->newFromCiphertext( null );
-                       $expiry = null;
-                       // @codeCoverageIgnoreStart
-               } elseif ( get_class( $req ) === PasswordAuthenticationRequest::class ) {
-                       // @codeCoverageIgnoreEnd
-                       $pwhash = $this->getPasswordFactory()->newFromPlaintext( $req->password );
-                       $expiry = $this->getNewPasswordExpiry( $username );
+               if ( get_class( $req ) === PasswordAuthenticationRequest::class ) {
+                       if ( $this->loginOnly ) {
+                               $pwhash = $this->getPasswordFactory()->newFromCiphertext( null );
+                               $expiry = null;
+                       } else {
+                               $pwhash = $this->getPasswordFactory()->newFromPlaintext( $req->password );
+                               $expiry = $this->getNewPasswordExpiry( $username );
+                       }
                }
 
                if ( $pwhash ) {
index 0c2f9de..4e6b2fd 100644 (file)
@@ -496,6 +496,7 @@ class MessageCache {
                        if ( $text === false ) {
                                // Failed to fetch data; possible ES errors?
                                // Store a marker to fetch on-demand as a workaround...
+                               // TODO Use a differnt marker
                                $entry = '!TOO BIG';
                                wfDebugLog(
                                        'MessageCache',
@@ -510,6 +511,10 @@ class MessageCache {
 
                $cache['VERSION'] = MSG_CACHE_VERSION;
                ksort( $cache );
+
+               # Hash for validating local cache (APC). No need to take into account
+               # messages larger than $wgMaxMsgCacheEntrySize, since those are only
+               # stored and fetched from memcache.
                $cache['HASH'] = md5( serialize( $cache ) );
                $cache['EXPIRY'] = wfTimestamp( TS_MW, time() + $this->mExpiry );
 
@@ -568,7 +573,8 @@ class MessageCache {
                }
 
                ScopedCallback::consume( $scopedLock );
-               // Relay the purge to APC and other DCs
+               // Relay the purge. Touching this check key expires cache contents
+               // and local cache (APC) validation hash across all datacenters.
                $this->wanCache->touchCheckKey( wfMemcKey( 'messages', $code ) );
 
                // Also delete cached sidebar... just in case it is affected
diff --git a/includes/debug/logger/monolog/LogstashFormatter.php b/includes/debug/logger/monolog/LogstashFormatter.php
new file mode 100644 (file)
index 0000000..553cbf6
--- /dev/null
@@ -0,0 +1,83 @@
+<?php
+
+namespace MediaWiki\Logger\Monolog;
+
+/**
+ * LogstashFormatter squashes the base message array and the context and extras subarrays into one.
+ * This can result in unfortunately named context fields overwriting other data (T145133).
+ * This class modifies the standard LogstashFormatter to rename such fields and flag the message.
+ *
+ * Compatible with Monolog 1.x only.
+ *
+ * @since 1.29
+ */
+class LogstashFormatter extends \Monolog\Formatter\LogstashFormatter {
+       /** @var array Keys which should not be used in log context */
+       protected $reservedKeys = [
+               // from LogstashFormatter
+               'message', 'channel', 'level', 'type',
+               // from WebProcessor
+               'url', 'ip', 'http_method', 'server', 'referrer',
+               // from WikiProcessor
+               'host', 'wiki', 'reqId', 'mwversion',
+               // from config magic
+               'normalized_message',
+       ];
+
+       /**
+        * Prevent key conflicts
+        * @param array $record
+        * @return array
+        */
+       protected function formatV0( array $record ) {
+               if ( $this->contextPrefix ) {
+                       return parent::formatV0( $record );
+               }
+
+               $context = !empty( $record['context'] ) ? $record['context'] : [];
+               $record['context'] = [];
+               $formatted = parent::formatV0( $record );
+
+               $formatted['@fields'] = $this->fixKeyConflicts( $formatted['@fields'], $context );
+               return $formatted;
+       }
+
+       /**
+        * Prevent key conflicts
+        * @param array $record
+        * @return array
+        */
+       protected function formatV1( array $record ) {
+               if ( $this->contextPrefix ) {
+                       return parent::formatV1( $record );
+               }
+
+               $context = !empty( $record['context'] ) ? $record['context'] : [];
+               $record['context'] = [];
+               $formatted = parent::formatV1( $record );
+
+               $formatted = $this->fixKeyConflicts( $formatted, $context );
+               return $formatted;
+       }
+
+       /**
+        * Check whether some context field would overwrite another message key. If so, rename
+        * and flag.
+        * @param array $fields Fields to be sent to logstash
+        * @param array $context Copy of the original $record['context']
+        * @return array Updated version of $fields
+        */
+       protected function fixKeyConflicts( array $fields, array $context ) {
+               foreach ( $context as $key => $val ) {
+                       if (
+                               in_array( $key, $this->reservedKeys, true ) &&
+                               isset( $fields[$key] ) && $fields[$key] !== $val
+                       ) {
+                               $fields['logstash_formatter_key_conflict'][] = $key;
+                               $key = 'c_' . $key;
+                       }
+                       $fields[$key] = $val;
+               }
+               return $fields;
+       }
+}
index 81e1e14..ad939a0 100644 (file)
@@ -29,17 +29,6 @@ namespace MediaWiki\Logger\Monolog;
  * @copyright © 2013 Bryan Davis and Wikimedia Foundation.
  */
 class WikiProcessor {
-       /** @var array Keys which should not be used in log context */
-       protected $reservedKeys = [
-               // from monolog:src/Monolog/Formatter/LogstashFormatter.php#L71-L88
-               'message', 'channel', 'level', 'type',
-               // from WebProcessor
-               'url', 'ip', 'http_method', 'server', 'referrer',
-               // from WikiProcessor
-               'host', 'wiki', 'reqId', 'mwversion',
-               // from config magic
-               'normalized_message',
-       ];
 
        /**
         * @param array $record
@@ -47,15 +36,6 @@ class WikiProcessor {
         */
        public function __invoke( array $record ) {
                global $wgVersion;
-
-               // some log aggregators such as Logstash will merge the log context into the main
-               // metadata and end up overwriting the data coming from processors
-               foreach ( $this->reservedKeys as $key ) {
-                       if ( isset( $record['context'][$key] ) ) {
-                               wfLogWarning( __METHOD__ . ": '$key' key overwritten in log context." );
-                       }
-               }
-
                $record['extra'] = array_merge(
                        $record['extra'],
                        [
@@ -67,4 +47,5 @@ class WikiProcessor {
                );
                return $record;
        }
+
 }
index c1d5573..9188cd9 100644 (file)
@@ -1018,7 +1018,7 @@ abstract class File implements IDBAccessObject {
                        return $handler->getTransform( $this, $thumbPath, $thumbUrl, $params );
                } else {
                        return new MediaTransformError( 'thumbnail_error',
-                               $params['width'], 0, wfMessage( 'thumbnail-dest-create' )->text() );
+                               $params['width'], 0, wfMessage( 'thumbnail-dest-create' ) );
                }
        }
 
index f58c3a9..7fd3e83 100644 (file)
@@ -38,11 +38,10 @@ class CurlHttpRequest extends MWHttpRequest {
        }
 
        public function execute() {
-
-               parent::execute();
+               $this->prepare();
 
                if ( !$this->status->isOK() ) {
-                       return $this->status;
+                       return Status::wrap( $this->status ); // TODO B/C; move this to callers
                }
 
                $this->curlOptions[CURLOPT_PROXY] = $this->proxy;
@@ -102,7 +101,7 @@ class CurlHttpRequest extends MWHttpRequest {
                $curlHandle = curl_init( $this->url );
 
                if ( !curl_setopt_array( $curlHandle, $this->curlOptions ) ) {
-                       throw new MWException( "Error setting curl options." );
+                       throw new InvalidArgumentException( "Error setting curl options." );
                }
 
                if ( $this->followRedirects && $this->canFollowRedirects() ) {
@@ -140,7 +139,7 @@ class CurlHttpRequest extends MWHttpRequest {
                $this->parseHeader();
                $this->setStatus();
 
-               return $this->status;
+               return Status::wrap( $this->status );  // TODO B/C; move this to callers
        }
 
        /**
index 43ae2d0..a68a63b 100644 (file)
@@ -74,7 +74,7 @@ class Http {
                } else {
                        $errors = $status->getErrorsByType( 'error' );
                        $logger = LoggerFactory::getInstance( 'http' );
-                       $logger->warning( $status->getWikiText( false, false, 'en' ),
+                       $logger->warning( Status::wrap( $status )->getWikiText( false, false, 'en' ),
                                [ 'error' => $errors, 'caller' => $caller, 'content' => $req->getContent() ] );
                        return false;
                }
index 08883ae..a42b6d0 100644 (file)
@@ -46,9 +46,11 @@ class MWHttpRequest implements LoggerAwareInterface {
        protected $reqHeaders = [];
        protected $url;
        protected $parsedUrl;
+       /** @var callable  */
        protected $callback;
        protected $maxRedirects = 5;
        protected $followRedirects = false;
+       protected $connectTimeout;
 
        /**
         * @var CookieJar
@@ -60,7 +62,8 @@ class MWHttpRequest implements LoggerAwareInterface {
        protected $respStatus = "200 Ok";
        protected $respHeaders = [];
 
-       public $status;
+       /** @var StatusValue */
+       protected $status;
 
        /**
         * @var Profiler
@@ -98,9 +101,9 @@ class MWHttpRequest implements LoggerAwareInterface {
                }
 
                if ( !$this->parsedUrl || !Http::isValidURI( $this->url ) ) {
-                       $this->status = Status::newFatal( 'http-invalid-url', $url );
+                       $this->status = StatusValue::newFatal( 'http-invalid-url', $url );
                } else {
-                       $this->status = Status::newGood( 100 ); // continue
+                       $this->status = StatusValue::newGood( 100 ); // continue
                }
 
                if ( isset( $options['timeout'] ) && $options['timeout'] != 'default' ) {
@@ -161,7 +164,7 @@ class MWHttpRequest implements LoggerAwareInterface {
         * @param string $url Url to use
         * @param array $options (optional) extra params to pass (see Http::request())
         * @param string $caller The method making this request, for profiling
-        * @throws MWException
+        * @throws DomainException
         * @return CurlHttpRequest|PhpHttpRequest
         * @see MWHttpRequest::__construct
         */
@@ -169,7 +172,7 @@ class MWHttpRequest implements LoggerAwareInterface {
                if ( !Http::$httpEngine ) {
                        Http::$httpEngine = function_exists( 'curl_init' ) ? 'curl' : 'php';
                } elseif ( Http::$httpEngine == 'curl' && !function_exists( 'curl_init' ) ) {
-                       throw new MWException( __METHOD__ . ': curl (http://php.net/curl) is not installed, but' .
+                       throw new DomainException( __METHOD__ . ': curl (http://php.net/curl) is not installed, but' .
                                ' Http::$httpEngine is set to "curl"' );
                }
 
@@ -186,7 +189,7 @@ class MWHttpRequest implements LoggerAwareInterface {
                                return new CurlHttpRequest( $url, $options, $caller, Profiler::instance() );
                        case 'php':
                                if ( !wfIniGetBool( 'allow_url_fopen' ) ) {
-                                       throw new MWException( __METHOD__ . ': allow_url_fopen ' .
+                                       throw new DomainException( __METHOD__ . ': allow_url_fopen ' .
                                                'needs to be enabled for pure PHP http requests to ' .
                                                'work. If possible, curl should be used instead. See ' .
                                                'http://php.net/curl.'
@@ -194,7 +197,7 @@ class MWHttpRequest implements LoggerAwareInterface {
                                }
                                return new PhpHttpRequest( $url, $options, $caller, Profiler::instance() );
                        default:
-                               throw new MWException( __METHOD__ . ': The setting of Http::$httpEngine is not valid.' );
+                               throw new DomainException( __METHOD__ . ': The setting of Http::$httpEngine is not valid.' );
                }
        }
 
@@ -222,7 +225,7 @@ class MWHttpRequest implements LoggerAwareInterface {
         *
         * @return void
         */
-       public function proxySetup() {
+       protected function proxySetup() {
                // If there is an explicit proxy set and proxies are not disabled, then use it
                if ( $this->proxy && !$this->noProxy ) {
                        return;
@@ -300,7 +303,7 @@ class MWHttpRequest implements LoggerAwareInterface {
         * Get an array of the headers
         * @return array
         */
-       public function getHeaderList() {
+       protected function getHeaderList() {
                $list = [];
 
                if ( $this->cookieJar ) {
@@ -333,12 +336,14 @@ class MWHttpRequest implements LoggerAwareInterface {
         * bytes are reported handled than were passed to you, the HTTP fetch
         * will be aborted.
         *
-        * @param callable $callback
-        * @throws MWException
+        * @param callable|null $callback
+        * @throws InvalidArgumentException
         */
        public function setCallback( $callback ) {
-               if ( !is_callable( $callback ) ) {
-                       throw new MWException( 'Invalid MwHttpRequest callback' );
+               if ( is_null( $callback ) ) {
+                       $callback = [ $this, 'read' ];
+               } elseif ( !is_callable( $callback ) ) {
+                       throw new InvalidArgumentException( __METHOD__ . ': invalid callback' );
                }
                $this->callback = $callback;
        }
@@ -350,6 +355,7 @@ class MWHttpRequest implements LoggerAwareInterface {
         * @param resource $fh
         * @param string $content
         * @return int
+        * @internal
         */
        public function read( $fh, $content ) {
                $this->content .= $content;
@@ -359,9 +365,14 @@ class MWHttpRequest implements LoggerAwareInterface {
        /**
         * Take care of whatever is necessary to perform the URI request.
         *
-        * @return Status
+        * @return StatusValue
+        * @note currently returns Status for B/C
         */
        public function execute() {
+               throw new LogicException( 'children must override this' );
+       }
+
+       protected function prepare() {
                $this->content = "";
 
                if ( strtoupper( $this->method ) == "HEAD" ) {
@@ -371,7 +382,7 @@ class MWHttpRequest implements LoggerAwareInterface {
                $this->proxySetup(); // set up any proxy as needed
 
                if ( !$this->callback ) {
-                       $this->setCallback( [ $this, 'read' ] );
+                       $this->setCallback( null );
                }
 
                if ( !isset( $this->reqHeaders['User-Agent'] ) ) {
@@ -494,6 +505,8 @@ class MWHttpRequest implements LoggerAwareInterface {
        /**
         * Tells the MWHttpRequest object to use this pre-loaded CookieJar.
         *
+        * To read response cookies from the jar, getCookieJar must be called first.
+        *
         * @param CookieJar $jar
         */
        public function setCookieJar( $jar ) {
@@ -519,14 +532,18 @@ class MWHttpRequest implements LoggerAwareInterface {
         * Set-Cookie headers.
         * @see Cookie::set
         * @param string $name
-        * @param mixed $value
+        * @param string $value
         * @param array $attr
         */
-       public function setCookie( $name, $value = null, $attr = null ) {
+       public function setCookie( $name, $value, $attr = [] ) {
                if ( !$this->cookieJar ) {
                        $this->cookieJar = new CookieJar;
                }
 
+               if ( $this->parsedUrl && !isset( $attr['domain'] ) ) {
+                       $attr['domain'] = $this->parsedUrl['host'];
+               }
+
                $this->cookieJar->setCookie( $name, $value, $attr );
        }
 
index 2af000f..d8a9949 100644 (file)
@@ -87,6 +87,7 @@ class PhpHttpRequest extends MWHttpRequest {
         * is completely useless (something like "fopen: failed to open stream")
         * so normal methods of handling errors programmatically
         * like get_last_error() don't work.
+        * @internal
         */
        public function errorHandler( $errno, $errstr ) {
                $n = count( $this->fopenErrors ) + 1;
@@ -94,8 +95,7 @@ class PhpHttpRequest extends MWHttpRequest {
        }
 
        public function execute() {
-
-               parent::execute();
+               $this->prepare();
 
                if ( is_array( $this->postData ) ) {
                        $this->postData = wfArrayToCgi( $this->postData );
@@ -227,12 +227,12 @@ class PhpHttpRequest extends MWHttpRequest {
                                        . ': error opening connection: {errstr1}', $this->fopenErrors );
                        }
                        $this->status->fatal( 'http-request-error' );
-                       return $this->status;
+                       return Status::wrap( $this->status ); // TODO B/C; move this to callers
                }
 
                if ( $result['timed_out'] ) {
                        $this->status->fatal( 'http-timed-out', $this->url );
-                       return $this->status;
+                       return Status::wrap( $this->status ); // TODO B/C; move this to callers
                }
 
                // If everything went OK, or we received some error code
@@ -253,6 +253,6 @@ class PhpHttpRequest extends MWHttpRequest {
                }
                fclose( $fh );
 
-               return $this->status;
+               return Status::wrap( $this->status ); // TODO B/C; move this to callers
        }
 }
index 6a702e9..6a8a99f 100644 (file)
@@ -32,8 +32,6 @@ require_once __DIR__ . '/../../maintenance/Maintenance.php';
  * @since 1.17
  */
 abstract class DatabaseUpdater {
-       protected static $updateCounter = 0;
-
        /**
         * Array of updates to perform on the database
         *
@@ -423,8 +421,6 @@ abstract class DatabaseUpdater {
         * @param array $what What updates to perform
         */
        public function doUpdates( $what = [ 'core', 'extensions', 'stats' ] ) {
-               global $wgVersion;
-
                $this->db->setSchemaVars( $this->getSchemaVars() );
 
                $what = array_flip( $what );
@@ -441,12 +437,9 @@ abstract class DatabaseUpdater {
                        $this->checkStats();
                }
 
-               $this->setAppliedUpdates( $wgVersion, $this->updates );
-
                if ( $this->fileHandle ) {
                        $this->skipSchema = false;
                        $this->writeSchemaUpdateFile();
-                       $this->setAppliedUpdates( "$wgVersion-schema", $this->updatesSkipped );
                }
        }
 
@@ -482,23 +475,6 @@ abstract class DatabaseUpdater {
                $this->updates = array_merge( $this->updates, $updatesDone );
        }
 
-       /**
-        * @param string $version
-        * @param array $updates
-        */
-       protected function setAppliedUpdates( $version, $updates = [] ) {
-               $this->db->clearFlag( DBO_DDLMODE );
-               if ( !$this->canUseNewUpdatelog() ) {
-                       return;
-               }
-               $key = "updatelist-$version-" . time() . self::$updateCounter;
-               self::$updateCounter++;
-               $this->db->insert( 'updatelog',
-                       [ 'ul_key' => $key, 'ul_value' => serialize( $updates ) ],
-                       __METHOD__ );
-               $this->db->setFlag( DBO_DDLMODE );
-       }
-
        /**
         * Helper function: check if the given key is present in the updatelog table.
         * Obviously, only use this for updates that occur after the updatelog table was
index 910a7ca..8f5700a 100644 (file)
  * @ingroup HTTP
  */
 
+/**
+ * Cookie jar to use with MWHttpRequest. Does not handle cookie unsetting.
+ */
 class CookieJar {
+       /** @var Cookie[] */
        private $cookie = [];
 
        /**
diff --git a/includes/libs/rdbms/connectionmanager/ConnectionManager.php b/includes/libs/rdbms/connectionmanager/ConnectionManager.php
new file mode 100644 (file)
index 0000000..6d5d8ab
--- /dev/null
@@ -0,0 +1,180 @@
+<?php
+
+namespace Wikimedia\Rdbms;
+
+use Database;
+use DBConnRef;
+use IDatabase;
+use InvalidArgumentException;
+use LoadBalancer;
+
+/**
+ * Database connection manager.
+ *
+ * This manages access to master and replica databases.
+ *
+ * @since 1.29
+ *
+ * @license GPL-2.0+
+ * @author Addshore
+ */
+class ConnectionManager {
+
+       /**
+        * @var LoadBalancer
+        */
+       private $loadBalancer;
+
+       /**
+        * The symbolic name of the target database, or false for the local wiki's database.
+        *
+        * @var string|false
+        */
+       private $domain;
+
+       /**
+        * @var string[]
+        */
+       private $groups = [];
+
+       /**
+        * @param LoadBalancer $loadBalancer
+        * @param string|bool $domain Optional logical DB name, defaults to current wiki.
+        *        This follows the convention for database names used by $loadBalancer.
+        * @param string[] $groups see LoadBalancer::getConnection
+        *
+        * @throws InvalidArgumentException
+        */
+       public function __construct( LoadBalancer $loadBalancer, $domain = false, array $groups = [] ) {
+               if ( !is_string( $domain ) && $domain !== false ) {
+                       throw new InvalidArgumentException( '$dbName must be a string, or false.' );
+               }
+
+               $this->loadBalancer = $loadBalancer;
+               $this->domain = $domain;
+               $this->groups = $groups;
+       }
+
+       /**
+        * @param int $i
+        * @param string[]|null $groups
+        *
+        * @return Database
+        */
+       private function getConnection( $i, array $groups = null ) {
+               $groups = $groups === null ? $this->groups : $groups;
+               return $this->loadBalancer->getConnection( $i, $groups, $this->domain );
+       }
+
+       /**
+        * @param int $i
+        * @param string[]|null $groups
+        *
+        * @return DBConnRef
+        */
+       private function getConnectionRef( $i, array $groups = null ) {
+               $groups = $groups === null ? $this->groups : $groups;
+               return $this->loadBalancer->getConnectionRef( $i, $groups, $this->domain );
+       }
+
+       /**
+        * Returns a connection to the master DB, for updating. The connection should later be released
+        * by calling releaseConnection().
+        *
+        * @since 1.29
+        *
+        * @return Database
+        */
+       public function getWriteConnection() {
+               return $this->getConnection( DB_MASTER );
+       }
+
+       /**
+        * Returns a database connection for reading. The connection should later be released by
+        * calling releaseConnection().
+        *
+        * @since 1.29
+        *
+        * @param string[]|null $groups
+        *
+        * @return Database
+        */
+       public function getReadConnection( array $groups = null ) {
+               $groups = $groups === null ? $this->groups : $groups;
+               return $this->getConnection( DB_REPLICA, $groups );
+       }
+
+       /**
+        * @since 1.29
+        *
+        * @param IDatabase $db
+        */
+       public function releaseConnection( IDatabase $db ) {
+               $this->loadBalancer->reuseConnection( $db );
+       }
+
+       /**
+        * Returns a connection ref to the master DB, for updating.
+        *
+        * @since 1.29
+        *
+        * @return DBConnRef
+        */
+       public function getWriteConnectionRef() {
+               return $this->getConnectionRef( DB_MASTER );
+       }
+
+       /**
+        * Returns a database connection ref for reading.
+        *
+        * @since 1.29
+        *
+        * @param string[]|null $groups
+        *
+        * @return DBConnRef
+        */
+       public function getReadConnectionRef( array $groups = null ) {
+               $groups = $groups === null ? $this->groups : $groups;
+               return $this->getConnectionRef( DB_REPLICA, $groups );
+       }
+
+       /**
+        * Begins an atomic section and returns a database connection to the master DB, for updating.
+        *
+        * @since 1.29
+        *
+        * @param string $fname
+        *
+        * @return Database
+        */
+       public function beginAtomicSection( $fname ) {
+               $db = $this->getWriteConnection();
+               $db->startAtomic( $fname );
+
+               return $db;
+       }
+
+       /**
+        * @since 1.29
+        *
+        * @param IDatabase $db
+        * @param string $fname
+        */
+       public function commitAtomicSection( IDatabase $db, $fname ) {
+               $db->endAtomic( $fname );
+               $this->releaseConnection( $db );
+       }
+
+       /**
+        * @since 1.29
+        *
+        * @param IDatabase $db
+        * @param string $fname
+        */
+       public function rollbackAtomicSection( IDatabase $db, $fname ) {
+               // FIXME: there does not seem to be a clean way to roll back an atomic section?!
+               $db->rollback( $fname, 'flush' );
+               $this->releaseConnection( $db );
+       }
+
+}
diff --git a/includes/libs/rdbms/connectionmanager/SessionConsistentConnectionManager.php b/includes/libs/rdbms/connectionmanager/SessionConsistentConnectionManager.php
new file mode 100644 (file)
index 0000000..02972e5
--- /dev/null
@@ -0,0 +1,118 @@
+<?php
+
+namespace Wikimedia\Rdbms;
+
+use Database;
+use DBConnRef;
+
+/**
+ * Database connection manager.
+ *
+ * This manages access to master and slave databases. It also manages state that indicates whether
+ * the slave databases are possibly outdated after a write operation, and thus the master database
+ * should be used for subsequent read operations.
+ *
+ * @note: Services that access overlapping sets of database tables, or interact with logically
+ * related sets of data in the database, should share a SessionConsistentConnectionManager.
+ * Services accessing unrelated sets of information may prefer to not share a
+ * SessionConsistentConnectionManager, so they can still perform read operations against slave
+ * databases after a (unrelated, per the assumption) write operation to the master database.
+ * Generally, sharing a SessionConsistentConnectionManager improves consistency (by avoiding race
+ * conditions due to replication lag), but can reduce performance (by directing more read
+ * operations to the master database server).
+ *
+ * @since 1.29
+ *
+ * @license GPL-2.0+
+ * @author Daniel Kinzler
+ * @author Addshore
+ */
+class SessionConsistentConnectionManager extends ConnectionManager {
+
+       /**
+        * @var bool
+        */
+       private $forceWriteConnection = false;
+
+       /**
+        * Forces all future calls to getReadConnection() to return a write connection.
+        * Use this before performing read operations that are critical for a future update.
+        * Calling beginAtomicSection() implies a call to prepareForUpdates().
+        *
+        * @since 1.29
+        */
+       public function prepareForUpdates() {
+               $this->forceWriteConnection = true;
+       }
+
+       /**
+        * @since 1.29
+        *
+        * @param string[]|null $groups
+        *
+        * @return Database
+        */
+       public function getReadConnection( array $groups = null ) {
+               if ( $this->forceWriteConnection ) {
+                       return parent::getWriteConnection();
+               }
+
+               return parent::getReadConnection( $groups );
+       }
+
+       /**
+        * @since 1.29
+        *
+        * @return Database
+        */
+       public function getWriteConnection() {
+               $this->prepareForUpdates();
+               return parent::getWriteConnection();
+       }
+
+       /**
+        * @since 1.29
+        *
+        * @param string[]|null $groups
+        *
+        * @return DBConnRef
+        */
+       public function getReadConnectionRef( array $groups = null ) {
+               if ( $this->forceWriteConnection ) {
+                       return parent::getWriteConnectionRef();
+               }
+
+               return parent::getReadConnectionRef( $groups );
+       }
+
+       /**
+        * @since 1.29
+        *
+        * @return DBConnRef
+        */
+       public function getWriteConnectionRef() {
+               $this->prepareForUpdates();
+               return parent::getWriteConnectionRef();
+       }
+
+       /**
+        * Begins an atomic section and returns a database connection to the master DB, for updating.
+        *
+        * @since 1.29
+        *
+        * @note: This causes all future calls to getReadConnection() to return a connection
+        * to the master DB, even after commitAtomicSection() or rollbackAtomicSection() have
+        * been called.
+        *
+        * @param string $fname
+        *
+        * @return Database
+        */
+       public function beginAtomicSection( $fname ) {
+               // Once we have written to master, do not read from replica.
+               $this->prepareForUpdates();
+
+               return parent::beginAtomicSection( $fname );
+       }
+
+}
index c86eabd..ac0564d 100644 (file)
@@ -541,7 +541,7 @@ class BitmapHandler extends TransformationalImageHandler {
         * @param array $params Rotate parameters.
         *   'rotation' clockwise rotation in degrees, allowed are multiples of 90
         * @since 1.21
-        * @return bool
+        * @return bool|MediaTransformError
         */
        public function rotate( $file, $params ) {
                global $wgImageMagickConvertCommand;
index 18f75ec..a852215 100644 (file)
@@ -170,7 +170,7 @@ class DjVuHandler extends ImageHandler {
                                'thumbnail_error',
                                $width,
                                $height,
-                               wfMessage( 'thumbnail_dest_directory' )->text()
+                               wfMessage( 'thumbnail_dest_directory' )
                        );
                }
 
@@ -197,7 +197,7 @@ class DjVuHandler extends ImageHandler {
 
                        return new MediaTransformError( 'thumbnail_error',
                                $params['width'], $params['height'],
-                               wfMessage( 'filemissing' )->text()
+                               wfMessage( 'filemissing' )
                        );
                }
 
index b8b6f6c..6c857a8 100644 (file)
@@ -130,7 +130,7 @@ class JpegHandler extends ExifBitmapHandler {
         * @param array $params Rotate parameters.
         *    'rotation' clockwise rotation in degrees, allowed are multiples of 90
         * @since 1.21
-        * @return bool
+        * @return bool|MediaTransformError
         */
        public function rotate( $file, $params ) {
                global $wgJpegTran;
index b3a555a..5366c4f 100644 (file)
@@ -439,19 +439,12 @@ class ThumbnailImage extends MediaTransformOutput {
  * @ingroup Media
  */
 class MediaTransformError extends MediaTransformOutput {
-       /** @var string HTML formatted version of the error */
-       private $htmlMsg;
-
-       /** @var string Plain text formatted version of the error */
-       private $textMsg;
+       /** @var Message */
+       private $msg;
 
        function __construct( $msg, $width, $height /*, ... */ ) {
                $args = array_slice( func_get_args(), 3 );
-               $htmlArgs = array_map( 'htmlspecialchars', $args );
-               $htmlArgs = array_map( 'nl2br', $htmlArgs );
-
-               $this->htmlMsg = wfMessage( $msg )->rawParams( $htmlArgs )->escaped();
-               $this->textMsg = wfMessage( $msg )->rawParams( $htmlArgs )->text();
+               $this->msg = wfMessage( $msg )->params( $args );
                $this->width = intval( $width );
                $this->height = intval( $height );
                $this->url = false;
@@ -461,21 +454,29 @@ class MediaTransformError extends MediaTransformOutput {
        function toHtml( $options = [] ) {
                return "<div class=\"MediaTransformError\" style=\"" .
                        "width: {$this->width}px; height: {$this->height}px; display:inline-block;\">" .
-                       $this->htmlMsg .
+                       $this->getHtmlMsg() .
                        "</div>";
        }
 
        function toText() {
-               return $this->textMsg;
+               return $this->msg->text();
        }
 
        function getHtmlMsg() {
-               return $this->htmlMsg;
+               return $this->msg->escaped();
+       }
+
+       function getMsg() {
+               return $this->msg;
        }
 
        function isError() {
                return true;
        }
+
+       function getHttpStatusCode() {
+               return 500;
+       }
 }
 
 /**
@@ -488,7 +489,12 @@ class TransformParameterError extends MediaTransformError {
                parent::__construct( 'thumbnail_error',
                        max( isset( $params['width'] ) ? $params['width'] : 0, 120 ),
                        max( isset( $params['height'] ) ? $params['height'] : 0, 120 ),
-                       wfMessage( 'thumbnail_invalid_params' )->text() );
+                       wfMessage( 'thumbnail_invalid_params' )
+               );
+       }
+
+       function getHttpStatusCode() {
+               return 400;
        }
 }
 
@@ -501,14 +507,18 @@ class TransformParameterError extends MediaTransformError {
 class TransformTooBigImageAreaError extends MediaTransformError {
        function __construct( $params, $maxImageArea ) {
                $msg = wfMessage( 'thumbnail_toobigimagearea' );
+               $msg->rawParams(
+                       $msg->getLanguage()->formatComputingNumbers( $maxImageArea, 1000, "size-$1pixel" )
+               );
 
                parent::__construct( 'thumbnail_error',
                        max( isset( $params['width'] ) ? $params['width'] : 0, 120 ),
                        max( isset( $params['height'] ) ? $params['height'] : 0, 120 ),
-                       $msg->rawParams(
-                               $msg->getLanguage()->formatComputingNumbers(
-                                       $maxImageArea, 1000, "size-$1pixel" )
-                               )->text()
-                       );
+                       $msg
+               );
+       }
+
+       function getHttpStatusCode() {
+               return 400;
        }
 }
index f3b33ac..0cea6d8 100644 (file)
@@ -178,14 +178,14 @@ class SvgHandler extends ImageHandler {
 
                $metadata = $this->unpackMetadata( $image->getMetadata() );
                if ( isset( $metadata['error'] ) ) { // sanity check
-                       $err = wfMessage( 'svg-long-error', $metadata['error']['message'] )->text();
+                       $err = wfMessage( 'svg-long-error', $metadata['error']['message'] );
 
                        return new MediaTransformError( 'thumbnail_error', $clientWidth, $clientHeight, $err );
                }
 
                if ( !wfMkdirParents( dirname( $dstPath ), null, __METHOD__ ) ) {
                        return new MediaTransformError( 'thumbnail_error', $clientWidth, $clientHeight,
-                               wfMessage( 'thumbnail_dest_directory' )->text() );
+                               wfMessage( 'thumbnail_dest_directory' ) );
                }
 
                $srcPath = $image->getLocalRefPath();
@@ -196,7 +196,7 @@ class SvgHandler extends ImageHandler {
 
                        return new MediaTransformError( 'thumbnail_error',
                                $params['width'], $params['height'],
-                               wfMessage( 'filemissing' )->text()
+                               wfMessage( 'filemissing' )
                        );
                }
 
@@ -219,7 +219,7 @@ class SvgHandler extends ImageHandler {
                                        wfHostname(), $lnPath, $srcPath ) );
                        return new MediaTransformError( 'thumbnail_error',
                                $params['width'], $params['height'],
-                               wfMessage( 'thumbnail-temp-create' )->text()
+                               wfMessage( 'thumbnail-temp-create' )
                        );
                }
 
index e33c27e..60aec45 100644 (file)
@@ -217,7 +217,7 @@ abstract class TransformationalImageHandler extends ImageHandler {
 
                        return new MediaTransformError( 'thumbnail_error',
                                $scalerParams['clientWidth'], $scalerParams['clientHeight'],
-                               wfMessage( 'filemissing' )->text()
+                               wfMessage( 'filemissing' )
                        );
                }
 
@@ -267,7 +267,7 @@ abstract class TransformationalImageHandler extends ImageHandler {
                        # Thumbnail was zero-byte and had to be removed
                        return new MediaTransformError( 'thumbnail_error',
                                $scalerParams['clientWidth'], $scalerParams['clientHeight'],
-                               wfMessage( 'unknown-error' )->text()
+                               wfMessage( 'unknown-error' )
                        );
                } elseif ( $mto ) {
                        return $mto;
@@ -565,7 +565,7 @@ abstract class TransformationalImageHandler extends ImageHandler {
         * @param array $params Rotate parameters.
         *   'rotation' clockwise rotation in degrees, allowed are multiples of 90
         * @since 1.24 Is non-static. From 1.21 it was static
-        * @return bool
+        * @return bool|MediaTransformError
         */
        public function rotate( $file, $params ) {
                return new MediaTransformError( 'thumbnail_error', 0, 0,
index 6ab3ffc..f4880d1 100644 (file)
@@ -42,6 +42,10 @@ class ImageHistoryPseudoPager extends ReverseChronologicalPager {
                $this->mImg = null;
                $this->mHist = [];
                $this->mRange = [ 0, 0 ]; // display range
+
+               // Only display 10 revisions at once by default, otherwise the list is overwhelming
+               $this->mLimitsShown = array_merge( [ 10 ], $this->mLimitsShown );
+               $this->setLimit( 10 );
        }
 
        /**
index 954d403..c929797 100644 (file)
@@ -90,7 +90,9 @@ abstract class ParameterizedPassword extends Password {
                        $str .= $this->getDelimiter();
                }
 
-               return $str . $this->hash;
+               $res = $str . $this->hash;
+               $this->assertIsSafeSize( $res );
+               return $res;
        }
 
        /**
index 4e395b5..13d1e6d 100644 (file)
@@ -81,6 +81,11 @@ abstract class Password {
         */
        protected $config;
 
+       /**
+        * Hash must fit in user_password, which is a tinyblob
+        */
+       const MAX_HASH_SIZE = 255;
+
        /**
         * Construct the Password object using a string hash
         *
@@ -168,9 +173,28 @@ abstract class Password {
         * are considered equivalent.
         *
         * @return string
+        * @throws PasswordError if password cannot be serialized to fit a tinyblob.
         */
        public function toString() {
-               return ':' . $this->config['type'] . ':' . $this->hash;
+               $result = ':' . $this->config['type'] . ':' . $this->hash;
+               $this->assertIsSafeSize( $result );
+               return $result;
+       }
+
+       /**
+        * Assert that hash will fit in a tinyblob field.
+        *
+        * This prevents MW from inserting it into the DB
+        * and having MySQL silently truncating it, locking
+        * the user out of their account.
+        *
+        * @param string $hash The hash in question.
+        * @throws PasswordError If hash does not fit in DB.
+        */
+       final protected function assertIsSafeSize( $hash ) {
+               if ( strlen( $hash ) > self::MAX_HASH_SIZE ) {
+                       throw new PasswordError( "Password hash is too big" );
+               }
        }
 
        /**
index 4a2a619..4b8446a 100644 (file)
@@ -204,6 +204,7 @@ class SpecialAllPages extends IncludableSpecialPage {
                                ]
                        );
 
+                       $linkRenderer = $this->getLinkRenderer();
                        if ( $res->numRows() > 0 ) {
                                $out = Html::openElement( 'ul', [ 'class' => 'mw-allpages-chunk' ] );
 
@@ -213,7 +214,7 @@ class SpecialAllPages extends IncludableSpecialPage {
                                                $out .= '<li' .
                                                        ( $s->page_is_redirect ? ' class="allpagesredirect"' : '' ) .
                                                        '>' .
-                                                       Linker::link( $t ) .
+                                                       $linkRenderer->makeLink( $t ) .
                                                        "</li>\n";
                                        } else {
                                                $out .= '<li>[[' . htmlspecialchars( $s->page_title ) . "]]</li>\n";
@@ -269,6 +270,7 @@ class SpecialAllPages extends IncludableSpecialPage {
                $navLinks = [];
                $self = $this->getPageTitle();
 
+               $linkRenderer = $this->getLinkRenderer();
                // Generate a "previous page" link if needed
                if ( $prevTitle ) {
                        $query = [ 'from' => $prevTitle->getText() ];
@@ -281,9 +283,9 @@ class SpecialAllPages extends IncludableSpecialPage {
                                $query['hideredirects'] = $hideredirects;
                        }
 
-                       $navLinks[] = Linker::linkKnown(
+                       $navLinks[] = $linkRenderer->makeKnownLink(
                                $self,
-                               $this->msg( 'prevpage', $prevTitle->getText() )->escaped(),
+                               $this->msg( 'prevpage', $prevTitle->getText() )->text(),
                                [],
                                $query
                        );
@@ -304,9 +306,9 @@ class SpecialAllPages extends IncludableSpecialPage {
                                $query['hideredirects'] = $hideredirects;
                        }
 
-                       $navLinks[] = Linker::linkKnown(
+                       $navLinks[] = $linkRenderer->makeKnownLink(
                                $self,
-                               $this->msg( 'nextpage', $t->getText() )->escaped(),
+                               $this->msg( 'nextpage', $t->getText() )->text(),
                                [],
                                $query
                        );
index 9ee1b75..ecc030e 100644 (file)
@@ -78,9 +78,10 @@ class AncientPagesPage extends QueryPage {
 
                $d = $this->getLanguage()->userTimeAndDate( $result->value, $this->getUser() );
                $title = Title::makeTitle( $result->namespace, $result->title );
-               $link = Linker::linkKnown(
+               $linkRenderer = $this->getLinkRenderer();
+               $link = $linkRenderer->makeKnownLink(
                        $title,
-                       htmlspecialchars( $wgContLang->convert( $title->getPrefixedText() ) )
+                       $wgContLang->convert( $title->getPrefixedText() )
                );
 
                return $this->getLanguage()->specialList( $link, htmlspecialchars( $d ) );
index ce7d24e..585f70b 100644 (file)
@@ -372,12 +372,13 @@ class SpecialBlock extends FormSpecialPage {
 
                $this->getOutput()->addModuleStyles( 'mediawiki.special' );
 
+               $linkRenderer = $this->getLinkRenderer();
                # Link to the user's contributions, if applicable
                if ( $this->target instanceof User ) {
                        $contribsPage = SpecialPage::getTitleFor( 'Contributions', $this->target->getName() );
-                       $links[] = Linker::link(
+                       $links[] = $linkRenderer->makeLink(
                                $contribsPage,
-                               $this->msg( 'ipb-blocklist-contribs', $this->target->getName() )->escaped()
+                               $this->msg( 'ipb-blocklist-contribs', $this->target->getName() )->text()
                        );
                }
 
@@ -392,21 +393,24 @@ class SpecialBlock extends FormSpecialPage {
                        $message = $this->msg( 'ipb-unblock' )->parse();
                        $list = SpecialPage::getTitleFor( 'Unblock' );
                }
-               $links[] = Linker::linkKnown( $list, $message, [] );
+               $links[] = $linkRenderer->makeKnownLink(
+                       $list,
+                       new HtmlArmor( $message )
+               );
 
                # Link to the block list
-               $links[] = Linker::linkKnown(
+               $links[] = $linkRenderer->makeKnownLink(
                        SpecialPage::getTitleFor( 'BlockList' ),
-                       $this->msg( 'ipb-blocklist' )->escaped()
+                       $this->msg( 'ipb-blocklist' )->text()
                );
 
                $user = $this->getUser();
 
                # Link to edit the block dropdown reasons, if applicable
                if ( $user->isAllowed( 'editinterface' ) ) {
-                       $links[] = Linker::linkKnown(
+                       $links[] = $linkRenderer->makeKnownLink(
                                $this->msg( 'ipbreason-dropdown' )->inContentLanguage()->getTitle(),
-                               $this->msg( 'ipb-edit-dropdown' )->escaped(),
+                               $this->msg( 'ipb-edit-dropdown' )->text(),
                                [],
                                [ 'action' => 'edit' ]
                        );
index 1753396..b730ecd 100644 (file)
@@ -109,12 +109,13 @@ class BrokenRedirectsPage extends QueryPage {
                        }
                }
 
+               $linkRenderer = $this->getLinkRenderer();
                // $toObj may very easily be false if the $result list is cached
                if ( !is_object( $toObj ) ) {
-                       return '<del>' . Linker::link( $fromObj ) . '</del>';
+                       return '<del>' . $linkRenderer->makeLink( $fromObj ) . '</del>';
                }
 
-               $from = Linker::linkKnown(
+               $from = $linkRenderer->makeKnownLink(
                        $fromObj,
                        null,
                        [],
@@ -128,28 +129,22 @@ class BrokenRedirectsPage extends QueryPage {
                        // check, if the content model is editable through action=edit
                        ContentHandler::getForTitle( $fromObj )->supportsDirectEditing()
                ) {
-                       $links[] = Linker::linkKnown(
+                       $links[] = $linkRenderer->makeKnownLink(
                                $fromObj,
-                               $this->msg( 'brokenredirects-edit' )->escaped(),
+                               $this->msg( 'brokenredirects-edit' )->text(),
                                [],
                                [ 'action' => 'edit' ]
                        );
                }
-               $to = Linker::link(
-                       $toObj,
-                       null,
-                       [],
-                       [],
-                       [ 'broken' ]
-               );
+               $to = $linkRenderer->makeBrokenLink( $toObj );
                $arr = $this->getLanguage()->getArrow();
 
                $out = $from . $this->msg( 'word-separator' )->escaped();
 
                if ( $this->getUser()->isAllowed( 'delete' ) ) {
-                       $links[] = Linker::linkKnown(
+                       $links[] = $linkRenderer->makeKnownLink(
                                $fromObj,
-                               $this->msg( 'brokenredirects-delete' )->escaped(),
+                               $this->msg( 'brokenredirects-delete' )->text(),
                                [],
                                [ 'action' => 'delete' ]
                        );
index 0cec9d0..9140bf1 100644 (file)
@@ -137,14 +137,15 @@ class DoubleRedirectsPage extends QueryPage {
                                $result = $dbr->fetchObject( $res );
                        }
                }
+               $linkRenderer = $this->getLinkRenderer();
                if ( !$result ) {
-                       return '<del>' . Linker::link( $titleA, null, [], [ 'redirect' => 'no' ] ) . '</del>';
+                       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 = Linker::linkKnown(
+               $linkA = $linkRenderer->makeKnownLink(
                        $titleA,
                        null,
                        [],
@@ -158,26 +159,24 @@ class DoubleRedirectsPage extends QueryPage {
                        // check, if the content model is editable through action=edit
                        ContentHandler::getForTitle( $titleA )->supportsDirectEditing()
                ) {
-                       $edit = Linker::linkKnown(
+                       $edit = $linkRenderer->makeKnownLink(
                                $titleA,
-                               $this->msg( 'parentheses', $this->msg( 'editlink' )->text() )->escaped(),
+                               $this->msg( 'parentheses', $this->msg( 'editlink' )->text() )->text(),
                                [],
-                               [
-                                       'action' => 'edit'
-                               ]
+                               [ 'action' => 'edit' ]
                        );
                } else {
                        $edit = '';
                }
 
-               $linkB = Linker::linkKnown(
+               $linkB = $linkRenderer->makeKnownLink(
                        $titleB,
                        null,
                        [],
                        [ 'redirect' => 'no' ]
                );
 
-               $linkC = Linker::linkKnown( $titleC );
+               $linkC = $linkRenderer->makeKnownLink( $titleC );
 
                $lang = $this->getLanguage();
                $arr = $lang->getArrow() . $lang->getDirMark();
index 39c8ae8..2c92410 100644 (file)
@@ -71,8 +71,14 @@ class SpecialListGrants extends SpecialPage {
 
                        $id = \Sanitizer::escapeId( $grant );
                        $out->addHTML( \Html::rawElement( 'tr', [ 'id' => $id ],
-                               "<td>" . $this->msg( "grant-$grant" )->escaped() . "</td>" .
-                               "<td>" . $grantCellHtml . '</td>'
+                               "<td>" .
+                               $this->msg(
+                                       "listgrants-grant-display",
+                                       \User::getGrantName( $grant ),
+                                       "<span class='mw-listgrants-grant-name'>" . $id . "</span>"
+                               )->parse() .
+                               "</td>" .
+                               "<td>" . $grantCellHtml . "</td>"
                        ) );
                }
 
index 9280b04..9f83832 100644 (file)
@@ -295,12 +295,12 @@ class SpecialSearch extends SpecialPage {
                $textStatus = null;
                if ( $textMatches instanceof Status ) {
                        $textStatus = $textMatches;
-                       $textMatches = null;
+                       $textMatches = $textStatus->getValue();
                }
 
                // did you mean... suggestions
                $didYouMeanHtml = '';
-               if ( $showSuggestion && $textMatches && !$textStatus ) {
+               if ( $showSuggestion && $textMatches ) {
                        if ( $textMatches->hasRewrittenQuery() ) {
                                $didYouMeanHtml = $this->getDidYouMeanRewrittenHtml( $term, $textMatches );
                        } elseif ( $textMatches->hasSuggestion() ) {
@@ -360,6 +360,25 @@ class SpecialSearch extends SpecialPage {
 
                $out->addHTML( "<div class='searchresults'>" );
 
+               $hasErrors = $textStatus && $textStatus->getErrors();
+               if ( $hasErrors ) {
+                       list( $error, $warning ) = $textStatus->splitByErrorType();
+                       if ( $error->getErrors() ) {
+                               $out->addHTML( Html::rawElement(
+                                       'div',
+                                       [ 'class' => 'errorbox' ],
+                                       $error->getHTML( 'search-error' )
+                               ) );
+                       }
+                       if ( $warning->getErrors() ) {
+                               $out->addHTML( Html::rawElement(
+                                       'div',
+                                       [ 'class' => 'warningbox' ],
+                                       $warning->getHTML( 'search-warning' )
+                               ) );
+                       }
+               }
+
                // prev/next links
                $prevnext = null;
                if ( $num || $this->offset ) {
@@ -388,7 +407,8 @@ class SpecialSearch extends SpecialPage {
                        }
                        $titleMatches->free();
                }
-               if ( $textMatches && !$textStatus ) {
+
+               if ( $textMatches ) {
                        // output appropriate heading
                        if ( $numTextMatches > 0 && $numTitleMatches > 0 ) {
                                $out->addHTML( '<div class="mw-search-visualclear"></div>' );
@@ -412,22 +432,18 @@ class SpecialSearch extends SpecialPage {
                $hasOtherResults = $textMatches &&
                        $textMatches->hasInterwikiResults( SearchResultSet::INLINE_RESULTS );
 
-               if ( $num === 0 ) {
-                       if ( $textStatus ) {
-                               $out->addHTML( '<div class="error">' .
-                                       $textStatus->getMessage( 'search-error' ) . '</div>' );
-                       } else {
-                               if ( !$this->offset ) {
-                                       // If we have an offset the create link was rendered earlier in this function.
-                                       // This class needs a good de-spaghettification, but for now this will
-                                       // do the job.
-                                       $this->showCreateLink( $title, $num, $titleMatches, $textMatches );
-                               }
-                               $out->wrapWikiMsg( "<p class=\"mw-search-nonefound\">\n$1</p>",
-                                       [ $hasOtherResults ? 'search-nonefound-thiswiki' : 'search-nonefound',
-                                                       wfEscapeWikiText( $term )
-                                       ] );
+               // If we have no results and we have not already displayed an error message
+               if ( $num === 0 && !$hasErrors ) {
+                       if ( !$this->offset ) {
+                               // If we have an offset the create link was rendered earlier in this function.
+                               // This class needs a good de-spaghettification, but for now this will
+                               // do the job.
+                               $this->showCreateLink( $title, $num, $titleMatches, $textMatches );
                        }
+                       $out->wrapWikiMsg( "<p class=\"mw-search-nonefound\">\n$1</p>", [
+                               $hasOtherResults ? 'search-nonefound-thiswiki' : 'search-nonefound',
+                               wfEscapeWikiText( $term )
+                       ] );
                }
 
                if ( $hasOtherResults ) {
index 6ded6d9..5b4f1f8 100644 (file)
@@ -331,7 +331,7 @@ class UserrightsPage extends SpecialPage {
         * @param bool $writing
         * @return Status
         */
-       public function fetchUser( $username, $writing ) {
+       public function fetchUser( $username, $writing = true ) {
                $parts = explode( $this->getConfig()->get( 'UserrightsInterwikiDelimiter' ), $username );
                if ( count( $parts ) < 2 ) {
                        $name = trim( $username );
index b78fed8..345577d 100644 (file)
@@ -52,7 +52,6 @@ class CategoryPager extends AlphabeticPager {
                return [
                        'tables' => [ 'category' ],
                        'fields' => [ 'cat_title', 'cat_pages' ],
-                       'conds' => [ 'cat_pages > 0' ],
                        'options' => [ 'USE INDEX' => 'cat_title' ],
                ];
        }
index 82d8806..f07db0e 100644 (file)
@@ -5066,13 +5066,27 @@ class User implements IDBAccessObject {
        /**
         * Get the description of a given right
         *
+        * @since 1.29
         * @param string $right Right to query
         * @return string Localized description of the right
         */
        public static function getRightDescription( $right ) {
                $key = "right-$right";
                $msg = wfMessage( $key );
-               return $msg->isBlank() ? $right : $msg->text();
+               return $msg->isDisabled() ? $right : $msg->text();
+       }
+
+       /**
+        * Get the name of a given grant
+        *
+        * @since 1.29
+        * @param string $grant Grant to query
+        * @return string Localized name of the grant
+        */
+       public static function getGrantName( $grant ) {
+               $key = "grant-$grant";
+               $msg = wfMessage( $key );
+               return $msg->isDisabled() ? $grant : $msg->text();
        }
 
        /**
index a905b3c..d435dbb 100644 (file)
        "passwordreset-emaildisabled": "E-posfunksies is afgeskakel op hierdie wiki.",
        "passwordreset-username": "Gebruiker:",
        "passwordreset-domain": "Domein:",
-       "passwordreset-capture": "Wys resulterende e-pos?",
-       "passwordreset-capture-help": "As u die boks merk, word die e-pos (met die tydelike wagwoord) aan u getoon en aan die gebruiker gestuur.",
        "passwordreset-email": "E-posadres:",
        "passwordreset-emailtitle": "Gebruiker se details op {{site name}}",
        "passwordreset-emailtext-ip": "Iemand, waarskynlik u vanaf die IP-adres $1, het u gebruikersgegewens vir {{SITENAME}} ($4) opgevra.\nDie volgende {{PLURAL:$3|gebruiker is|gebruikers is}} aan die e-posadres gekoppel:\n\n$2\n\n{{PLURAL:$3|Die tydelike wagwoord verval|Hierdie tydelike wagwoorde verval}} oor {{PLURAL:$5|een dag|$5 dae}}.\nMeld asseblief nou aan en wysig u wagwoord. As u dit nie versoek het nie, of as u die oorspronklike wagwoord nog ken en dit nie wil verander nie, ignoreer die berig en hou aan om u ou wagwoord te gebruik.",
        "userrights-reason": "Rede:",
        "userrights-no-interwiki": "U het nie toestemming om gebruikersregte op ander wiki's te verander nie.",
        "userrights-nodatabase": "Databasis $1 bestaan nie of is nie hier beskikbaar nie.",
-       "userrights-nologin": "U moet as 'n administrateur [[Special:UserLogin|aanmeld]] om gebruikersregte te kan toeken.",
-       "userrights-notallowed": "U het nie magtiging om gebruikersregte by te sit of weg te neem nie.",
        "userrights-changeable-col": "Groepe wat u kan verander",
        "userrights-unchangeable-col": "Groepe wat u nie kan verander nie",
        "userrights-conflict": "Konflik met gebruikersregte! Pas asseblief weer u wysigings toe.",
-       "userrights-removed-self": "U het u eie regte suksesvol verwyder. Gevolglik het u nie meer toegang tot hierdie bladsy nie.",
        "group": "Groep:",
        "group-user": "Gebruikers",
        "group-autoconfirmed": "Bevestigde gebruikers",
        "right-siteadmin": "Sluit en ontsluit die datbasis",
        "right-override-export-depth": "Eksporteer bladsye insluitend geskakelde bladsye tot 'n diepte van 5",
        "right-sendemail": "Stuur e-pos aan ander gebruikers",
-       "right-passwordreset": "Wys e-posse vir herstel van wagwoord",
        "newuserlogpage": "Logboek van nuwe gebruikers",
        "newuserlogpagetext": "Dit is 'n logboek van gebruikers wat onlangs ingeteken het.",
        "rightslog": "Gebruikersregtelogboek",
        "trackingcategories-disabled": "Kategorie is gedeaktiveer",
        "mailnologin": "Geen versendadres beskikbaar",
        "mailnologintext": "U moet [[Special:UserLogin|ingeteken]] wees en 'n geldige e-posadres in u [[Special:Preferences|voorkeure]] hê om e-pos aan ander gebruikers te kan stuur.",
-       "emailuser": "Stuur e-pos na hierdie gebruiker",
+       "emailuser": "Stuur e-pos na dié gebruiker",
        "emailuser-title-target": "E-pos die {{GENDER:$1|gebruiker}}",
        "emailuser-title-notarget": "E-pos gebruiker",
        "emailpagetext": "As {{GENDER:$1|dié gebruiker}} 'n geldige e-posadres in sy/haar gebruikersvoorkeure het, sal hierdie vorm 'n enkele boodskap stuur. Die e-posadres in u [[Special:Preferences|gebruikersvoorkeure]] sal verskyn as die \"Van\"-adres van die pos. Dus sal die ontvanger kan terug antwoord.",
        "namespace_association": "Gekoppelde naamruimte",
        "tooltip-namespace_association": "Merk die boks om die besprekings- en onderwerpnaamruimte die by die geselekteerde naamruimte in te sluit",
        "blanknamespace": "(Hoof)",
-       "contributions": "{{GENDER:$1|Gebruikersbydraes}}",
+       "contributions": "{{GENDER:$1|Gebruikers­bydraes}}",
        "contributions-title": "$1 se bydraes",
        "mycontris": "Bydraes",
        "anoncontribs": "Bydraes",
        "specialpage-securitylevel-not-allowed-title": "Nie toegestaan",
        "cannotauth-not-allowed-title": "Geen toegang",
        "cannotauth-not-allowed": "U word nie toegelaat om die bladsy te gebruik nie",
-       "credentialsform-account": "Gebruikersnaam:",
-       "edit-error-short": "Fout: $1",
-       "edit-error-long": "Foute:\n\n$1"
+       "credentialsform-account": "Gebruikersnaam:"
 }
index f146905..f3bbf83 100644 (file)
        "whatlinkshere-hidelinks": "$1 باغلانتیلاری",
        "whatlinkshere-hideimages": "فایل باغلانتیلارینی $1",
        "whatlinkshere-filters": "سۆزگَجلر",
+       "whatlinkshere-submit": "گئت",
        "autoblockid": "اوتوماتیک باغلانما #$1",
        "block": "ایستیفادچینی باغلاما",
        "unblock": "ایستیفاده‌چی‌نین باغلانماسین گؤتور",
index 7624ef0..ba40fdf 100644 (file)
        "movelogpagetext": "Ніжэй пададзены сьпіс перанесеных старонак.",
        "movesubpage": "{{PLURAL:$1|1=Падстаронка|Падстаронкі}}",
        "movesubpagetext": "Гэтая старонка мае $1 {{PLURAL:$1|падстаронку|падстаронкі|падстаронак}}, {{PLURAL:$1|1=якая паказаная ніжэй|якія паказаныя ніжэй}}.",
+       "movesubpagetalktext": "Адпаведная старонка абмеркаваньня мае $1 {{PLURAL:$1|падстаронку, паказаную|падстаронкі, паказаныя|падстаронак, паказаныя}} ніжэй.",
        "movenosubpage": "Гэтая старонка ня мае падстаронак.",
        "movereason": "Прычына:",
        "revertmove": "адкат",
        "pageinfo-category-pages": "Колькасьць старонак",
        "pageinfo-category-subcats": "Колькасьць падкатэгорыяў",
        "pageinfo-category-files": "Колькасьць файлаў",
+       "pageinfo-user-id": "Ідэнтыфікатар удзельніка",
        "markaspatrolleddiff": "Пазначыць як «патруляваную»",
        "markaspatrolledtext": "Пазначыць гэтую старонку як «патруляваную»",
        "markaspatrolledtext-file": "Пазначыць гэтую вэрсію файлу як патруляваную",
index 26175b3..734d773 100644 (file)
        "feedback-submit": "Даслаць",
        "feedback-thanks": "Дзякуй! Ваш водгук размешчаны на старонцы «[$2 $1]».",
        "feedback-thanks-title": "Дзякуем!",
-       "searchsuggest-search": "Шукаць у {{SITENAME}}",
+       "searchsuggest-search": "Шукаць у {{GRAMMAR:месны|{{SITENAME}}}}",
        "searchsuggest-containing": "змяшчае...",
        "api-error-badaccess-groups": "У Вас няма дазволу загружаць файлы ў гэтую вікі.",
        "api-error-badtoken": "Унутраная памылка: няслушны ключ.",
index dbf7814..8b22db4 100644 (file)
        "pageinfo-header-restrictions": "পাতা সুরক্ষা",
        "pageinfo-header-properties": "পাতা বৈশিষ্টসমূহ",
        "pageinfo-display-title": "শিরনাম প্রদর্শন",
-       "pageinfo-default-sort": "ডিফলà§\8dà¦\9f à¦¸à¦°à§\8dà¦\9f à¦\95ি",
+       "pageinfo-default-sort": "পà§\82রà§\8dবনিরà§\8dধারিত à¦¬à¦¾à¦\9bাà¦\87য়à§\87র à¦\9aাবি",
        "pageinfo-length": "পাতার দৈর্ঘ্য (বাইটে)",
        "pageinfo-article-id": "পাতার আইডি",
        "pageinfo-language": "পাতার তথ্যের ভাষা",
index d9bc4a6..10f39b4 100644 (file)
        "apisandbox-continue-clear": "Vymazat",
        "apisandbox-continue-help": "{{int:apisandbox-continue}} bude [https://www.mediawiki.org/wiki/API:Query#Continuing_queries pokračovat] v posledním požadavku; {{int:apisandbox-continue-clear}} vymaže parametry související s pokračováním.",
        "apisandbox-param-limit": "Pro použití maximálního limitu zadejte <kbd>max</kbd>.",
+       "apisandbox-multivalue-all-namespaces": "$1 (všechny jmenné prostory)",
+       "apisandbox-multivalue-all-values": "$1 (všechny hodnoty)",
        "booksources": "Zdroje knih",
        "booksources-search-legend": "Vyhledat knižní zdroje",
        "booksources-search": "Hledat",
        "mw-widgets-dateinput-placeholder-month": "RRRR-MM",
        "mw-widgets-titleinput-description-new-page": "stránka zatím neexistuje",
        "mw-widgets-titleinput-description-redirect": "přesměrování na $1",
+       "mw-widgets-categoryselector-add-category-placeholder": "Přidat kategorii…",
        "sessionmanager-tie": "Nelze kombinovat několik typů autentizace požadavků: $1.",
        "sessionprovider-generic": "relace pomocí $1",
        "sessionprovider-mediawiki-session-cookiesessionprovider": "relace pomocí cookies",
index 6137af4..fe9e024 100644 (file)
@@ -85,7 +85,7 @@
        "tuesday": "Sêşeme",
        "wednesday": "Çarşeme",
        "thursday": "Pancşeme",
-       "friday": "Yene",
+       "friday": "Êne",
        "saturday": "Şeme",
        "sun": "Krê",
        "mon": "Dış",
        "morenotlisted": "Na lista qay kemi ya.",
        "mypage": "Pele",
        "mytalk": "Mesac",
-       "anontalk": "Werênayış",
+       "anontalk": "Vaten",
        "navigation": "Pusula",
        "and": "&#32;u",
        "qbfind": "Bıvêne",
        "history_short": "Tarix",
        "updatedmarker": "cıkewtena mına peyêne ra dıme biyo rocane",
        "printableversion": "Asayışê çapkerdışi",
-       "permalink": "Gıreyo daimi",
+       "permalink": "Gıreyo bêpeyni",
        "print": "Çap ke",
        "view": "Bıvêne",
        "view-foreign": "$1 de bıvêne",
        "pool-servererror": "Amordoğa xızmeti ya istifade nëbena $1",
        "poolcounter-usage-error": "Xırab karyayış:$1",
        "aboutsite": "Heqa {{SITENAME}} de",
-       "aboutpage": "Project:Heqa",
+       "aboutpage": "Proce:Heqa",
        "copyright": "Zerrekacı $1 bındı not biya.",
        "copyrightpage": "{{ns:project}}:Heqa telifi",
        "currentevents": "Hediseyê rocaneyi",
        "currentevents-url": "Project:Hediseyê rocaneyi",
        "disclaimers": "Redê mesuliyeti",
-       "disclaimerpage": "Project:Reddê mesuliyetê bıngey",
+       "disclaimerpage": "Project:Redê mesulêtê pêroyi",
        "edithelp": "Peştdariya vurnayışi",
        "helppage-top-gethelp": "Peşti",
        "mainpage": "Pela Seri",
        "editlink": "bıvurne",
        "viewsourcelink": "çımey bıvêne",
        "editsectionhint": "Leteyo ke bıvuriyo: $1",
-       "toc": "Sernameyê meselan",
+       "toc": "Tedeestey",
        "showtoc": "bımocne",
        "hidetoc": "bınımne",
        "collapsible-collapse": "Teng kı",
        "sort-descending": "Rêzkerdışo kêmbiyaye",
        "sort-ascending": "Rêzkerdışo zêdiyaye",
        "nstab-main": "Pele",
-       "nstab-user": "Pela karberi",
+       "nstab-user": "Pella karberi",
        "nstab-media": "Pela medya",
-       "nstab-special": "Pella xısusi",
+       "nstab-special": "Pela xısusiye",
        "nstab-project": "Pela proceyi",
        "nstab-image": "Dosya",
        "nstab-mediawiki": "Mesac",
        "nstab-template": "Şablon",
        "nstab-help": "Pela peşti",
        "nstab-category": "Kategoriye",
-       "mainpage-nstab": "Pera esas",
+       "mainpage-nstab": "Pela seri",
        "nosuchaction": "Fealiyeto wınasi çıniyo",
        "nosuchactiontext": "URL ra kar qebul nêbı.\nŞıma belka URL şaş nuşt, ya zi gıreyi şaş ra ameyi.\nKeyepelê {{SITENAME}} eşkeno xeta eşkera bıkero.",
-       "nosuchspecialpage": "Pela xasa wınasiye çıniya",
+       "nosuchspecialpage": "Pella xısusi ya unasin çınya",
        "nospecialpagetext": "<strong>To yew pela xasa nêvêrdiye waşte.</strong>\n\nSeba lista pelanê xasanê vêrdeyan reca kena: [[Special:SpecialPages|{{int:specialpages}}]].",
        "error": "Xeta",
        "databaseerror": "Ğetay ardoği",
        "perfcached": "Datay cı ver hazır biye. No semedê ra nıkayin niyo! tewr zaf {{PLURAL:$1|netice|$1 netice}} debêno de",
        "perfcachedts": "Cêr de malumatê nımıteyi esti, demdê newe kerdışo peyın: $1. Tewr zaf {{PLURAL:$4|netice|$4 neticey cı}} debyayo de",
        "querypage-no-updates": "Rocanebiyayışê na pele nıka cadayiyê.\nDayiyi tiya nıka newe nêbenê.",
-       "viewsource": "Çemi bıvin",
+       "viewsource": "Çımey bıvêne",
        "viewsource-title": "Cı geyrayışê $1'i bıvin",
        "actionthrottled": "Kerden peysnaya",
        "actionthrottledtext": "Riyê tedbirê anti-spami ra,  wextê do kılmek de şıma nê fealiyeti nêşkenê zaf zêde bıkerê, şıma ki no hedi viyarna ra.\nÇend deqey ra tepeya reyna bıcerrebnên.",
        "summary": "Xulasa:",
        "subject": "Mewzu:",
        "minoredit": "No yew vurnayışo werdiyo",
-       "watchthis": "Na pele seyr ke",
-       "savearticle": "Peller qeyd kı",
+       "watchthis": "Bıewni ena perrer",
+       "savearticle": "Perrer qeyd kı",
        "savechanges": "Vuryayışa qeyd kerê",
        "publishpage": "Perer bıhesırne",
        "publishchanges": "Vurnayışa vıla ke",
        "preview": "Verqayt",
-       "showpreview": "Var asani bıvinê",
+       "showpreview": "Ver asayışi bıvinê",
        "showdiff": "Vurriyayışa bıasne",
        "anoneditwarning": "<strong>İqaz:</strong> Şıma be hesabê xo nêkewtê cı. \nAdresê şımayê IP tarixê vırnayışê na pele de do qeyd bo. Eke şıma <strong>[$1 cıkewê]</strong> ya zi <strong>[$2 hesab vırazê]</strong>, vurnayışê şıma be zewbina kare ra nameyê şıma rê bar beno.",
        "anonpreviewwarning": "\"Şıma be hesabê xo nêkewtê cı. Eke qeyd kerê, adresê şımaê IP tarixê vırnayışê na pele de do qeyd bo.\"",
        "nohistory": "Verê vurnayışanê na pele çıniyo.",
        "currentrev": "Çımraviyarnayışo rocane",
        "currentrev-asof": "$1 ra tepya mewcud weziyeta pela",
-       "revisionasof": "Verziyonê roca $1ine",
+       "revisionasof": "Çımraviyarnayışê $1",
        "revision-info": "Vurnayışo ke $1 de terefê {{GENDER:$6|$2}}$7 ra biyo",
        "previousrevision": "← Çımraviyarnayışo kıhanêr",
        "nextrevision": "Rewizyono newên →",
        "lineno": "Xeta $1:",
        "compareselectedversions": "Rewizyonanê weçineyan pêver ke",
        "showhideselectedversions": "Revizyonanê weçinıtan bımocne/bınımne",
-       "editundo": "peyser biya",
+       "editundo": "Peyser bıgêre",
        "diff-empty": "(Babetna niyo)",
        "diff-multi-sameuser": "(Terefê eyni karberi ra {{PLURAL:$1|yew revizyono miyanên nêmocno|$1 revizyonê miyanêni nêmocnê}})",
        "diff-multi-otherusers": "(Terefê {{PLURAL:$2|yew karberi|$2 karberan}} ra {{PLURAL:$1|yew revizyono miyanên nêmocno|$1 revizyonê miyanêni nêmocnê}})",
        "diff-multi-manyusers": "({{PLURAL:$1|jew timar kerdışo qıckeko|$1 timar kerdışo qıckeko}} timar kerdo, $2 {{PLURAL:$2|Karber|karberi}} memocne)",
        "difference-missing-revision": "Ferqê {{PLURAL:$2|Yew rewizyonê|$2 rewizyonê}} {{PLURAL:$2|dı|dı}} ($1) sero çıniyo.\n\nNo normal de werênayış dê pelanê besterneyan dı ena xırabin asena.\nDetayê besternayışi [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} tiya dı] aseno.",
-       "searchresults": "Neticeyê geyrayışi",
+       "searchresults": "Peyniyê cıgeyrayışi",
        "searchresults-title": "Qandê \"$1\" neticeyê geyrayışi",
        "titlematches": "Tekê (zewcê) sernameyê pele",
        "textmatches": "Tekê (zewcê) nuştey pele",
        "next-page": "Pela peyên",
        "prevn-title": "$1o verên  {{PLURAL:$1|netice|neticeyan}}",
        "nextn-title": "$1o ke yeno {{PLURAL:$1|netice|neticey}}",
-       "shown-title": "Herg per sero $1 {{PLURAL:$1|netici|netica}} bıasne",
+       "shown-title": "Her pele sero $1 {{PLURAL:$1|netici|netica}} bımocne",
        "viewprevnext": "($1 {{int:pipe-separator}} $2) ($3) bıvênên",
        "searchmenu-exists": "''Ena 'Wikipediya de ser \"[[:$1]]\" yew pel esto'''",
        "searchmenu-new": "<strong>Na wiki de pela \"[[:$1]]\" vıraze!</strong> {{PLURAL:$2|0=|Sewbina pela ke şıma geyrayê cı aye bıvênê.|Yew zi neticanê cıgeyrayışê xo bıvênê.}}",
-       "searchprofile-articles": "Perrê muhteway",
+       "searchprofile-articles": "Pelê zerreki",
        "searchprofile-images": "Zafınmedya",
        "searchprofile-everything": "Pêro çi",
        "searchprofile-advanced": "Herayen",
        "searchprofile-articles-tooltip": "$1 de cı geyre",
        "searchprofile-images-tooltip": "Dosya cı geyre",
-       "searchprofile-everything-tooltip": "Tedeesteyan hemine cı geyre (pelanê mınaqeşeyi zi tey)",
+       "searchprofile-everything-tooltip": "Tedeesteyan hemine cı geyre (pelanê werênayışi zi tey)",
        "searchprofile-advanced-tooltip": "Cayê nameyanê xısusiyan de cı geyre",
        "search-result-size": "$1 ({{PLURAL:$2|1 çeku|$2 çekuy}})",
        "search-result-category-size": "{{PLURAL:$1|1 eza|$1 ezayan}} ({{PLURAL:$2|1 kategoriyê bini|$2 kategirayanê binan}}, {{PLURAL:$3|1 dosya|$3 dosyayan}})",
        "datedefault": "Tercih çıniyo",
        "prefs-labs": "Xacetê labs",
        "prefs-user-pages": "Pelê karberi",
-       "prefs-personal": "Pela karberi",
+       "prefs-personal": "Profilê karberi",
        "prefs-rc": "Vurriyayışê peyêni",
        "prefs-watchlist": "Lista seyrkerdışi",
        "prefs-editwatchlist": "Lista seyrkerdışi bıvurne",
        "right-bot": "Zey yew kardê otomotiki kar bıvin",
        "right-nominornewtalk": "Pelanê werênayışan rê vurnayışê qıckeki çıniyê, qutiya mesacanê newiyan bıgurene",
        "right-apihighlimits": "Persanê API de sinoranê berzêran bıgurene",
-       "right-writeapi": "İstıfadey APIyê nuştey",
+       "right-writeapi": "Gurenayışê nuştey API",
        "right-delete": "Pele bestere",
        "right-bigdelete": "Pelanê be tarixanê dergan bestere",
        "right-deletelogentry": "Qeydanê cıkewtışanê xısusiyan bestere û peyser biya",
        "nchanges": "$1 {{PLURAL:$1|vurnayış|vurnayışi}}",
        "enhancedrc-since-last-visit": "$1 {{PLURAL:$1|ziyaretê peyêni ra nata}}",
        "enhancedrc-history": "tarix",
-       "recentchanges": "Vurriyayışê peyêni",
+       "recentchanges": "Vuriyayışê peyêni",
        "recentchanges-legend": "Tercihê vurnayışanê peyênan",
        "recentchanges-summary": "Wiki sero vurriyayışê peyêni asenê.",
        "recentchanges-noresult": "Goreyê kriteranê kıfşkerdeyan ra qet yew vurnayış nêvêniya.",
        "recentchanges-feed-description": "Ena feed dı vurnayişanê tewr peniyan teqip bık.",
-       "recentchanges-label-newpage": "Enê vurnayışi ra yu pera newi vıraziya ya",
+       "recentchanges-label-newpage": "Enê vurnayışi yew pela newiye vıraşta.",
        "recentchanges-label-minor": "No yew vurnayışo werdiyo",
        "recentchanges-label-bot": "Eno vurnayış terefê yew boti ra vıraziyo",
        "recentchanges-label-unpatrolled": "Eno vurnayış hewna dewriya nêbiyo",
        "rcshowhidepatr": "$1 vurnayışê ke dewriya geyrayê",
        "rcshowhidepatr-show": "Bımocne",
        "rcshowhidepatr-hide": "Bınımne",
-       "rcshowhidemine": "vurnayışanê mı $1",
+       "rcshowhidemine": "vurnayışê mı $1",
        "rcshowhidemine-show": "Bımocne",
        "rcshowhidemine-hide": "Bınımne",
        "rcshowhidecategorization": "kategorizasyonê pele $1",
        "rc_categories": "Kategoriyan rêz kı ( \"|“ ya ciya yo):",
        "rc_categories_any": "Weçinayiyan ra her yew",
        "rc-change-size": "$1",
-       "rc-change-size-new": "Vurnayışa dıma $1 {{PLURAL:$1|bayt|bayt}}",
+       "rc-change-size-new": "$1 {{PLURAL:$1|bayt|bayt}} ra dıma vurnayış",
        "newsectionsummary": "/* $1 */ qısımo newe",
        "rc-enhanced-expand": "Detaya bıvin (JavaScript lazımo)",
        "rc-enhanced-hide": "Melumat bınımne",
        "uncategorizedcategories": "Kategoriyê ke kategorize nêbiyê",
        "uncategorizedimages": "Dosye yê  bêkategori",
        "uncategorizedtemplates": "Şablonê ke bêkategoriyê",
-       "unusedcategories": "Kategoriyê ke nêgureniyê",
+       "unusedcategories": "Kategoriyê ke nêkarênê",
        "unusedimages": "Dosyeyê ke nêguriyenê",
        "wantedcategories": "Kategoriyê ke waziyayê",
        "wantedpages": "Pelê ke waziyayê",
        "mostimages": "Dosyayan ke tewr zaf link estê.",
        "mostinterwikis": "Pelan ke tewr zaf interwiki biyê.",
        "mostrevisions": "Pelan ke tewr zaf revizyonî biyê.",
-       "prefixindex": "Veroleya peley pêro",
+       "prefixindex": "Verbenda pelli heme",
        "prefixindex-namespace": "Peleyê Veroleyıni ($1 cay nami)",
        "prefixindex-submit": "Bımocne",
        "prefixindex-strip": "Listeya réz bıyayışi",
        "longpages": "Perrê  dergeki",
        "deadendpages": "Perrê kı perranê binan rê grey c çıni yo",
        "deadendpagestext": "Ena pelan ke {{SITENAME}} de zerrî ey de link çini yo.",
-       "protectedpages": "Pelê pawıteyi",
+       "protectedpages": "Pellê kı pawıyayeyè",
        "protectedpages-indef": "têna pawıteyê bêmuddeti",
        "protectedpages-summary": "Listeya ena peler newke pawıtiya.Sername de  ena lista rê pawıte vıraştışi rê [[{{#special:ProtectedTitles}}|{{int:protectedtitles}}]] bıvinê.",
        "protectedpages-cascade": "Kilit biyaye ke teyna cascadiye",
        "listusers-desc": "Kemeyen rézed ratn",
        "usereditcount": "$1 {{PLURAL:$1|vurnayîş|vurnayîşî}}",
        "usercreated": "$2 de $1 {{GENDER:$3|viraziya}}",
-       "newpages": "Perrê newey",
+       "newpages": "Pelê newey",
        "newpages-submit": "Bımocne",
        "newpages-username": "Nameyê karberi:",
        "ancientpages": "Perrê kı rewnayo kı nêvuriya yê",
        "checkbox-all": "Pêro",
        "checkbox-none": "Temam",
        "checkbox-invert": "Rageyre",
-       "allpages": "Peli pêro",
+       "allpages": "Pelli pêro",
        "nextpage": "Pela badê cû ($1)",
        "prevpage": "Pela verêne ($1)",
        "allpagesfrom": "Pera liste kerdışi bıasne:",
        "removedwatchtext": "Ena pela \"[[:$1]]\" biya wedariya [[Special:Watchlist|listeyê seyr-kerdışi şıma]].",
        "removedwatchtext-short": "Pera $1`i listeya seyran de şıma ra wedari yê",
        "watch": "Seyr ke",
-       "watchthispage": "Na pele seyr ke",
+       "watchthispage": "Peller seyr kı",
        "unwatch": "Teqib meke",
        "unwatchthispage": "temaşa kerdışê peli vındarn.",
        "notanarticle": "mebhesê peli niyo",
        "delete-warning-toobig": "no pel wayirê tarixê vurnayiş ê derg o, $1 {{PLURAL:$1|revizyonê|revizyonê}} seri de.\nhewn a kerdışê ıney {{SITENAME}} şuxul bıne gırano;\nbı diqqet dewam kerê.",
        "deleteprotected": "Şıma nêşenê ena perer esternê,  çıkı per starya ya.",
        "rollback": "vurnayişan tepiya bıger",
-       "rollbacklink": "peyser biya",
+       "rollbacklink": "peyser biyare",
        "rollbacklinkcount": "$1 {{PLURAL:$1|vurnayış|vurnayışi}} peyd gıroti",
        "rollbacklinkcount-morethan": "$1 {{PLURAL:$1|vurnayış|vuranyışi}} tewr peyd gırot",
        "rollbackfailed": "Peyserardış nêbi",
        "rollback-success": "vurnayişê no kesi $1 tepiya geriyayo u hetê no\n$2 kesi ra cıwa ver o ke revizyon biyo no revizyon tepiya anciyayo.",
        "sessionfailure-title": "Seans xeripiya",
        "sessionfailure": "cıkewtışê hesabê şıma de yew problem aseno;\nno kar semedê dızdiyê hesabi ibtal biyo.\nkerem kerê \"tepiya\" şiyerê u pel o ke şıma tera ameyî u o pel newe ra bar kerê , newe ra tesel/cereb kerê.",
+       "changecontentmodel": "Modelê zerrekê pele bıvurne",
        "changecontentmodel-title-label": "Sernameyê pele",
        "changecontentmodel-model-label": "Modelê zerrekiyo newe",
        "changecontentmodel-reason-label": "Sebeb:",
        "sp-contributions-deleted": "iştırakê {{GENDER:$1|karberi}} esterdi",
        "sp-contributions-uploads": "Barkerdışi",
        "sp-contributions-logs": "qeydi",
-       "sp-contributions-talk": "werênayış",
+       "sp-contributions-talk": "vaten",
        "sp-contributions-userrights": "idareyê heqanê karberan",
        "sp-contributions-blocked-notice": "verniyê no/na karber/e geriyayo/a\nqê referansi qeydê vernigrewtışi cêr de eşkera biyo:",
        "sp-contributions-blocked-notice-anon": "Eno adresê IPi bloke biyo.\nCıkewtışo tewr peyêno ke bloke biyo, cêr seba referansi belikerdeyo:",
        "tooltip-pt-createaccount": "Şıma rê tewsiyey ma xorê jew hesab akerê. Fına zi hesab akerdış mecburi niyo.",
        "tooltip-ca-talk": "Heqa zerrekê pele de werênayış",
        "tooltip-ca-edit": "Ena pele bıvurne",
-       "tooltip-ca-addsection": "Zu bınnusteya newi ak",
+       "tooltip-ca-addsection": "Yew leteyo newe a ke",
        "tooltip-ca-viewsource": "Ena pele kılit biya.\nŞıma şenê çımeyê aye bıvênê",
        "tooltip-ca-history": "Versiyonê verênê ena pele",
        "tooltip-ca-protect": "Ena pele bışevekne",
        "tooltip-ca-nstab-media": "Pela medya bıvêne",
        "tooltip-ca-nstab-special": "Na yew pela xasa, şıma nêşenê sero vurnayış bıkerê",
        "tooltip-ca-nstab-project": "Pela proceyi bıvêne",
-       "tooltip-ca-nstab-image": "Pera dosyayer bıvin",
+       "tooltip-ca-nstab-image": "Pela dosya bıvêne",
        "tooltip-ca-nstab-mediawiki": "Mesacê sistemi bımocne",
        "tooltip-ca-nstab-template": "Şabloni bıvêne",
        "tooltip-ca-nstab-help": "Pela peşti bıvêne",
        "tooltip-minoredit": "Nay vırnayışa werdi nışan bıkeré",
        "tooltip-save": "Vurnayışanê xo qeyd ke",
        "tooltip-publish": "Vurnayışê xo vıla kı",
-       "tooltip-preview": "Vuryayışané xo çım ra ravyarné. Verdé qeyd kerdışi eneri bıkarné!",
+       "tooltip-preview": "Vurnayışanê xo çım ra bıviyarnê. Qeydkerdış ra ver bıgurê cı!",
        "tooltip-diff": "Metni sero vurnayışan mocneno",
        "tooltip-compareselectedversions": "Ena per de ferqê rewziyonan de dı weçinaya bıvinê",
        "tooltip-watch": "Ena pele lista xoya seyrkerdışi ke",
        "tooltip-rollback": "\"Peyser biya\" be yew tık pela iştıraqanê peyênan peyser ano",
        "tooltip-undo": "\"Undo\" ena vurnayışê newi iptal kena u vurnayışê verni a kena.\nTı eşkeno yew sebeb bınus.",
        "tooltip-preferences-save": "Terciha qeyd ke",
-       "tooltip-summary": "Yew xulasaya kilm binuse",
+       "tooltip-summary": "Yew xulasa kılmeke bınuse",
        "interlanguage-link-title": "$1 - $2",
        "common.css": "/************************************************\n * COMMON CSS\n *\n * Any CSS placed in this page will be used on \n * all skins, please think carefully about if it\n * belongs here (and not in one of the skin CSS\n * pages) before adding it. Thanks.\n ************************************************/\n\n/* <table class=\"highlighthovertable\"> */\ntable.highlighthovertable tr:hover,\ntable.highlighthovertable tr:hover td,\ntable.mw-ext-translate-groupstatistics tr:hover,\ntable.mw-ext-translate-groupstatistics tr:hover td {\n background-color: white;\n}\n\n\n/* Babel wrapper layout. */\n/* XXX: This is either redundant or should be in-core */\n/* @noflip */table.mw-babel-wrapper {\n\twidth:        238px;\n\tfloat:        right;\n\tclear:        right;\n\tmargin:       1em;\n\tborder-style: solid;\n\tborder-width: 1px;\n\tborder-color: #99B3FF;\n}\n\n/* Babel box layout. */\n/* @noflip */div.mw-babel-box {\n\tfloat:  left;\n\tclear:  left;\n\tmargin: 1px;\n}\n\ndiv.mw-babel-box table {\n\twidth: 238px;\n}\n\ndiv.mw-babel-box table th {\n\twidth:       238px;\n\twidth:       45px;\n\theight:      45px;\n\tfont-size:   14pt;\n\tfont-family: monospace;\n}\n\ndiv.mw-babel-box table td {\n\tfont-size:   8pt;\n\tpadding:     4pt;\n\tline-height: 1.25em;\n}\n\n/* Babel box colours. */\ndiv.mw-babel-box-0 {\n\tborder: solid #B7B7B7 1px;\n}\n\ndiv.mw-babel-box-1 {\n\tborder: solid #C0C8FF 1px;\n}\n\ndiv.mw-babel-box-2 {\n\tborder: solid #77E0E8 1px;\n}\n\ndiv.mw-babel-box-3 {\n\tborder: solid #99B3FF 1px;\n}\n\ndiv.mw-babel-box-4 {\n\tborder: solid #CCCC00 1px;\n}\n\ndiv.mw-babel-box-5 {\n\tborder: solid #F99C99 1px;\n}\n\ndiv.mw-babel-box-N {\n\tborder: solid #6EF7A7 1px;\n}\n\ndiv.mw-babel-box-0 table th {\n\tbackground-color: #B7B7B7;\n}\n\ndiv.mw-babel-box-1 table th {\n\tbackground-color: #C0C8FF;\n}\n\ndiv.mw-babel-box-2 table th {\n\tbackground-color: #77E0E8;\n}\n\ndiv.mw-babel-box-3 table th {\n\tbackground-color: #99B3FF;\n}\n\ndiv.mw-babel-box-4 table th {\n\tbackground-color: #CCCC00;\n}\n\ndiv.mw-babel-box-5 table th {\n\tbackground-color: #F99C99;\n}\n\ndiv.mw-babel-box-N table th{\n\tbackground-color: #6EF7A7;\n}\n\ndiv.mw-babel-box-0 table {\n\tbackground-color: #E8E8E8;\n}\n\ndiv.mw-babel-box-1 table {\n\tbackground-color: #F0F8FF;\n}\n\ndiv.mw-babel-box-2 table {\n\tbackground-color: #D0F8FF;\n}\n\ndiv.mw-babel-box-3 table {\n\tbackground-color: #E0E8FF;\n}\n\ndiv.mw-babel-box-4 table {\n\tbackground-color: #FFFF99;\n}\n\ndiv.mw-babel-box-5 table {\n\tbackground-color: #F9CBC9;\n}\n\ndiv.mw-babel-box-N table {\n\tbackground-color: #C5FCDC;\n}\n\n.babel-box td.babel-footer {\n\ttext-align: center;\n}\n\n/* Styling for portals. */\ndiv.table {\n    display:        table;\n    vertical-align: top;\n    width:          100%;\n}\n\ndiv.table-row {\n    display:        table-row;\n    vertical-align: top;\n}\n\ndiv.table-cell {\n    display:        table-cell;\n    vertical-align: top;\n}\n\nbody.ns-100 table.mw-babel-wrapper {\n    border:           solid 1px #bbbbbb;\n    background-color: #f0f0f0;\n    margin-left:      1em;\n}\n\n.graytext {\n    color: #aaa;\n}\n\n/* On [[Special:RecentChanges]] and [[Special:Watchlist]] make the new pages symbol bold green and the minor edit symbol gray. */\n.newpage {\n    color:       green;\n    font-weight: bold\n}\n\n.minoredit,\n.minor {\n    color: gray;\n}\n\n/* Monospace diffs, this makes more sense since diffs show what would be seen in the edit box. */\n/* Note: Anno 2012 many browsers don't use monospace in the textarea anymore by default, notably Chrome and Safari don't (unless the user overrides this in the preferences) */\n.diff-context,\n.diff-deletedline,\n.diff-addedline {\n    font-family: monospace, \"Courier New\";\n/* Just guess does the stupid wikidiff2 extensions add extra whitespace around..... */\n    white-space: -moz-pre-wrap;\n    white-space: pre-wrap;\n}\n \n.diffchange {\n    border: 1px dotted rgb( 170, 170, 170 );\n}\n\n/* It is unclear what the following CSS does, please add comments if you can clarify. */\n/* The box which is 400px high and if its content is longer, it gets the scrollbar */\n.scrollme {\n    overflow: scroll;\n    width:    100%;\n    height:   400px;\n}\n\n/* Standard Navigationsleisten, aka box hiding thingy from .de.  Documentation at [[Wikipedia:NavFrame]]. */\ndiv.Boxmerge, div.NavFrame { margin: 0; padding: 4px; border-collapse: collapse;}\ndiv.Boxmerge div.NavFrame { border-style: none; border-style: hidden; }\ndiv.NavFrame + div.NavFrame { border-top-style: none; border-top-style: hidden; }\ndiv.NavFrame div.NavHead { height: 1.6em; position:relative; }\ndiv.NavEnd { margin: 0; padding: 0; line-height: 1px; clear: both; }\na.NavToggle { position: absolute; top: 0; right: 5px; }\n.note-flaggedrevs * a.NavToggle { right: 12px; } /* For [[Template:Flagged Revs]] */\n\n/* Template:Languages */\n.bw-languages {\n    border:          1px solid #aaaaaa;\n    padding:         0.2em;\n    border-collapse: collapse;\n    line-height:     1.2;\n    font-size:       95%;\n    margin:          1px 1px;\n}\n.bw-languages-title {\n    width:        180px;\n    border:       1px solid #aaaaaa;\n    background:   #EEF3E2;\n    padding:      0.5em;\n    font-weight:  bold;\n}\n.bw-languages-links { padding:0.5em; background:#F6F9ED; }\n\n/* Senseless in this project */\n#editpage-copywarn { display: none; }\n\n/* Hide warnings about bad links on MediaWiki:Common.css */\n.page-MediaWiki_Common_css .mw-translate-messagechecks { display: none; }\n\n/*******************\n** Faciliate RTL translation\n*******************/\n/* @noflip */\n#bodyContent .arabic a {\n\tpadding-right:0;\n\tbackground:none;\n}\n\n.vatop tr, tr.vatop, .vatop td, .vatop th {\n vertical-align: top;\n}\n\n.bw-languages {\n direction: ltr;\n}\n\n/* prevent wrapping of lines in LQT TOC if not necessary */\ntable.lqt_toc {\n\twidth: auto;\n}\n\n/* [[m:MediaZilla:35337]] */\n@media (-webkit-min-device-pixel-ratio: 1.5), (min-resolution: 1.5dppx) {\n        #p-logo a {\n                background-image: url(\"//translatewiki.net/images/thumb/7/7c/Translatewiki-logo-bare.svg/152px-Translatewiki-logo-bare.svg.png\") !important;\n                background-size: auto 135px;\n        }\n}\n@media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 2dppx) {\n        #p-logo a {\n                background-image: url(\"//translatewiki.net/images/thumb/7/7c/Translatewiki-logo-bare.svg/202px-Translatewiki-logo-bare.svg.png\") !important;\n                background-size: auto 135px;\n        }\n}\n\n/* qqq visibility, [[Thread:Support/Suggestion: Add this CSS to MediaWiki:Common.css]] */\n \n.mw-sp-translate-edit-info .mw-content-ltr {\n  background-position:left center;\n  padding-left:45px;\n}\nfieldset.mw-sp-translate-edit-info .mw-centent-rtl {\n  background-position:right center;\n  padding-right:45px;\n}\n\n/* Semantic MediaWiki - make special properties easier to identify */\n\n.smwbuiltin a,\n.smwbuiltin a.new {\n\tcolor: #FF8000;\n}\n\n/* Recentchangestext toggle link */\n.white-link a {\n    color: #fff;\n}",
        "common.js": "/* Any JavaScript here will be loaded for all users on every page load. */",
        "widthheight": "$1 - $2",
        "widthheightpage": "$1 × $2, $3 {{PLURAL:$3|pele|peli}}",
        "file-info": "ebatê dosyayi: $1, MIME tip: $2",
-       "file-info-size": "$1 × $2 pixelan, ebatê dosya: $3, MIME type: $4",
+       "file-info-size": "$1 × $2 pikselan, ebatê dosya: $3, MIME tipê cı: $4",
        "file-info-size-pages": "$1 × $2 pikse, dergeya dosyay: $3, MIME tipiya cı: $4, $5 {{PLURAL:$5|pela|pela}}",
        "file-nohires": "Deha berz agozney cı çıniyo",
        "svg-long-desc": "Dosyay SVG, zek vanê $1 × $2 piksela, ebatê dosya: $3",
        "svg-long-desc-animated": "SVG dosya, nominalin $1 × $2 piksela, ebatê dosya: $3",
        "svg-long-error": "Nêmeqbul dosyaya SVG'i: $1",
        "show-big-image": "Dosyaya oricinale",
-       "show-big-image-preview": "Verqaytê dergiya: $1.",
+       "show-big-image-preview": "Vervênayışê ebatê : $1.",
        "show-big-image-other": "Zewmi{{PLURAL:$2|Vılêşnayış|Vılêşnayışê}}: $1.",
        "show-big-image-size": "$1 × $2 piksel",
        "file-info-gif-looped": "viyariye biyo",
        "fileduplicatesearch-result-1": "Dosyayê ''$1î'' de hem-kopya çini yo.",
        "fileduplicatesearch-result-n": "Dosyayê ''$1î'' de {{PLURAL:$2|1 hem-kopya|$2 hem-kopyayî'}} esto.",
        "fileduplicatesearch-noresults": "Ebe namey \"$1\" ra dosya nêdiyayê.",
-       "specialpages": "Pellê xısusiy",
+       "specialpages": "Perrê Hısusi",
        "specialpages-note-top": "Kıtabek",
        "specialpages-note": "* Pelê xasê normali.\n* <span class=\"mw-specialpagerestricted\">Pelê xasê nımıtey.</span>",
        "specialpages-group-maintenance": "Raporê pawıtışi",
        "specialpages-group-login": "Dekew / hesab vıraz",
        "specialpages-group-changes": "Vurnayışê peyêni û qeydi",
        "specialpages-group-media": "Raporê medya û barkerdışi",
-       "specialpages-group-users": "Karberi û heqi",
+       "specialpages-group-users": "Karberi u heqê cı",
        "specialpages-group-highuse": "Peleyê ke vêşi karênê",
        "specialpages-group-pages": "Listeyê pelan",
        "specialpages-group-pagetools": "Haletê pelan",
        "mw-widgets-titleinput-description-redirect": "berd be $1",
        "randomrootpage": "Raştamaye perra çımey",
        "log-action-filter-newusers": "Babetê hesabvıraştışi:",
-       "changecredentials": "Malumatanê karberi bıvurnê"
+       "changecredentials": "Malumatanê karberi bıvurnê",
+       "removecredentials": "Kamiyer wedarne",
+       "removecredentials-submit": "Kamiyer wedarne"
 }
index 2685328..b6e1b18 100644 (file)
        "category-file-count-limited": "निम्न {{PLURAL:$1|फाइल|$1 फाइलहरू}} यै श्रेणीमी रया छ ।",
        "listingcontinuesabbrev": "निरन्तरता...",
        "index-category": "क्रमाङ्कित पानाहरू",
-       "noindex-category": "à¤\95à¥\8dरमाà¤\99à¥\8dà¤\95न à¤¨à¤\97रà¥\80याà¤\95ा à¤ªà¤¾à¤¨à¤¾à¤¹à¤°à¥\82",
+       "noindex-category": "à¤\85नà¥\81à¤\95à¥\8dरमित à¤¨à¤\85रियाऽ à¤ªà¤¨à¥\8dनाà¤\85न",
        "broken-file-category": "टुटेको फाइल लिङ्कहरूसितको पाना",
        "about": "बारेमी",
        "article": "सामाग्री पानो",
        "passwordreset": "पासवर्ड पूर्वनिर्धारित गर",
        "passwordreset-username": "प्रयोगकर्ता-नाम:",
        "passwordreset-domain": "डोमेन",
-       "passwordreset-capture": "निस्कने इमेलको नमुना हेर्ने ?",
        "passwordreset-email": "इमेल ठेगाना:",
        "passwordreset-emailtitle": "{{SITENAME}}मा खाता विवरण",
        "passwordreset-emailelement": "प्रयोगकर्ताको नाम: \n$1\n\nअस्थाई पासवर्ड: \n$2",
        "searchprofile-advanced-tooltip": "अनुकुल नेमस्पेसमा खोज्या",
        "search-result-size": "$1 ({{PLURAL:$2|1 आँखर|$2 आँखर}})",
        "search-result-category-size": "{{PLURAL:$1|एक सदस्य|$1 सदस्यहरू}} ({{PLURAL:$2|1 उपश्रेणी|$2  उपश्रेणीहरू}}, {{PLURAL:$3|एउटा फाइल|$3 फाइलहरू}})",
-       "search-redirect": "(जान्या $1)",
+       "search-redirect": "($1 बठेइ पुन:निर्देशित)",
        "search-section": "(खण्ड $1)",
        "search-category": "(श्रेणी $1)",
        "search-file-match": "(भेटिईया फाइल सामाग्री)",
        "userrights-changeable-col": "तमले परिवर्तन गद्द सक्दया समूहअन",
        "userrights-unchangeable-col": "तमीले परिवर्तन गद्द नसक्ने समूहहरू",
        "userrights-conflict": "प्रयोगकर्ताको अधिकार परिवर्तनमी मतभेद भयो ! कृपया तमरो परिवर्तन पुनरावलोकन तथा पुष्टि गर ।",
-       "userrights-removed-self": "तमले सफलतापूर्वक आफनो अधिकारहरूलाई मेटाया । त्यै कारण तम आब यो पानो हेद्द नाइसक्दा ।",
        "group": "समूह:",
        "group-user": "प्रयोगकर्ताहरू",
        "group-autoconfirmed": "स्वत स्थापित प्रयोगकर्ताहरू",
        "logentry-newusers-create": "प्रयोगकर्ता खाता $1 {{GENDER:$2|खोलियो}}",
        "logentry-upload-upload": "$1 ले $3 {{GENDER:$2|अपलोड अरेका छन्}}",
        "feedback-bugornote": "यदि तमी कुनै प्राविधिक समस्यालाई विस्तारले सम्झाउन तयार छौ भण्या कृपया [$1 बग राख]।\nयदि हैन, भण्या तमी तल दियाको सरल फारमको प्रयोग गद्दसक्द्याहौ । तमरो टिप्पणी, तमरो प्रयोगकर्ता नाम र तमरो ब्राउजरको नाम सहित \"[$3 $2]\" पानामी जोडिन्याछ ।",
-       "searchsuggest-search": "खोज:",
+       "searchsuggest-search": "{{SITENAME}} खोजऽ",
        "api-error-duplicate": "यै साइटमी पहिलीबठे यस्तै सामग्री {{PLURAL:$1|भयाको अर्को फाइल छ|भयाका  केहि अरु फाइलहरू छन्}} ।",
        "api-error-duplicate-archive": "यै साइटमी पहिलेबाट यस्तै सामग्री {{PLURAL:$1|भयाको अर्को फाइल थियो|भयाका केहि अरु फाइलहरू थिए}} ।\nतर {{PLURAL:$1|यो मेट्याको थियो|यी मेटायाका थिए}} ।",
        "expand_templates_preview_fail_html": "<em>किनकि {{SITENAME}} सिधै एचटिएमयल सक्षम छ र तमीले लग इन गर्या छैनौ, पूर्वावलोकन लुकाइयाको छ ताकि सम्भावित जाभास्क्रिप्ट आक्रमणलाई रोक्द सकियोस् ।</em>\n\n<strong>यदि यो मान्य पूर्ववावलोकन प्रयास हो भण्या पुन प्रयास गर ।</strong>\nयदि यसले कार्य पूर्ण भएन भण्या [[Special:UserLogout|लग आउट गरिबर]] फेरी लग इन गर्या ।",
index 3a8a7ae..afd13f0 100644 (file)
        "searchdisabled": "{{SITENAME}} search is disabled.\nYou can search via Google in the meantime.\nNote that their indexes of {{SITENAME}} content may be out of date.",
        "googlesearch": "<form method=\"get\" action=\"//www.google.com/search\" id=\"googlesearch\">\n\t<input type=\"hidden\" name=\"domains\" value=\"{{SERVER}}\" />\n\t<input type=\"hidden\" name=\"num\" value=\"50\" />\n\t<input type=\"hidden\" name=\"ie\" value=\"$2\" />\n\t<input type=\"hidden\" name=\"oe\" value=\"$2\" />\n\n\t<input type=\"text\" name=\"q\" size=\"31\" maxlength=\"255\" value=\"$1\" />\n\t<input type=\"submit\" name=\"btnG\" value=\"$3\" />\n  <div>\n\t<input type=\"radio\" name=\"sitesearch\" id=\"gwiki\" value=\"{{SERVER}}\" checked=\"checked\" /><label for=\"gwiki\">{{SITENAME}}</label>\n\t<input type=\"radio\" name=\"sitesearch\" id=\"gWWW\" value=\"\" /><label for=\"gWWW\">WWW</label>\n  </div>\n</form>",
        "search-error": "An error has occurred while searching: $1",
+       "search-warning": "A warning has occured while searching: $1",
        "opensearch-desc": "{{SITENAME}} ({{CONTENTLANGUAGE}})",
        "preferences": "Preferences",
        "preferences-summary": "",
        "listgrants-summary": "The following is a list of grants with their associated access to user rights. Users can authorize applications to use their account, but with limited permissions based on the grants the user gave to the application. An application acting on behalf of a user cannot actually use rights that the user does not have however.\nThere may be [[{{MediaWiki:Listgrouprights-helppage}}|additional information]] about individual rights.",
        "listgrants-grant": "Grant",
        "listgrants-rights": "Rights",
+       "listgrants-grant-display": "$1 <code>($2)</code>",
        "trackingcategories": "Tracking categories",
        "trackingcategories-summary": "This page lists tracking categories which are automatically populated by the MediaWiki software. Their names can be changed by altering the relevant system messages in the {{ns:8}} namespace.",
        "trackingcategories-msg": "Tracking category",
index 6699cc8..35a399d 100644 (file)
        "activeusers-intro": "See on loetelu kasutajatest, kes on viimase $1 {{PLURAL:$1|päev|päeva}} jooksul midagi teinud.",
        "activeusers-count": "$1 {{PLURAL:$1|toiming|toimingut}} viimase {{PLURAL:$3|päeva|$3 päeva}} jooksul",
        "activeusers-from": "Näita kasutajaid alates:",
+       "activeusers-groups": "Kuva kasutajad, kes kuuluvad järgmistesse rühmadesse:",
        "activeusers-noresult": "Kasutajaid ei leidunud.",
        "activeusers-submit": "Kuva aktiivsed kasutajad",
        "listgrouprights": "Kasutajarühma õigused",
        "mw-widgets-titleinput-description-redirect": "ümbersuunamine leheküljele \"$1\"",
        "randomrootpage": "Juhuslik juurlehekülg",
        "log-action-filter-block": "Blokeeringu tüüp:",
+       "log-action-filter-contentmodel": "Sisumudeli muudatuse tüüp:",
        "log-action-filter-delete": "Kustutamise tüüp:",
+       "log-action-filter-import": "Impordi tüüp:",
+       "log-action-filter-managetags": "Märgiste haldamistegevuse tüüp:",
+       "log-action-filter-move": "Teisaldamise tüüp:",
+       "log-action-filter-newusers": "Konto loomise tüüp:",
+       "log-action-filter-patrol": "Kontrolli tüüp:",
+       "log-action-filter-protect": "Kaitsmise tüüp:",
+       "log-action-filter-rights": "Õiguste muudatuse tüüp:",
+       "log-action-filter-upload": "Üleslaadimise tüüp:",
        "log-action-filter-all": "Kõik",
        "log-action-filter-block-block": "Blokeerimine",
        "log-action-filter-block-reblock": "Blokeeringu muutmine",
        "log-action-filter-block-unblock": "Blokeeringu tühistamine",
+       "log-action-filter-contentmodel-change": "Sisumudeli muudatus",
+       "log-action-filter-contentmodel-new": "Ebastandardse sisumudeliga lehekülje loomine",
        "log-action-filter-delete-delete": "Lehekülje kustutamine",
        "log-action-filter-delete-restore": "Lehekülje taastamine",
        "log-action-filter-delete-event": "Logi kustutamine",
        "log-action-filter-delete-revision": "Redaktsiooni kustutamine",
+       "log-action-filter-import-interwiki": "Vikidevaheline import",
+       "log-action-filter-import-upload": "XML-faili üleslaadimisega import",
+       "log-action-filter-managetags-create": "Märgise koostamine",
+       "log-action-filter-managetags-delete": "Märgise kustutamine",
+       "log-action-filter-managetags-activate": "Märgise lubamine",
+       "log-action-filter-managetags-deactivate": "Märgise keelamine",
+       "log-action-filter-move-move": "Teisaldamine ümbersuunamise ülekirjutamiseta",
+       "log-action-filter-move-move_redir": "Teisaldamine ümbersuunamise ülekirjutamisega",
+       "log-action-filter-newusers-create": "Loonud anonüümne kasutaja",
+       "log-action-filter-newusers-create2": "Loonud registreeritud kasutaja",
+       "log-action-filter-newusers-autocreate": "Loodud automaatselt",
+       "log-action-filter-newusers-byemail": "Loodud e-kirjatsi saadetud parooliga",
+       "log-action-filter-patrol-patrol": "Kontrollitud käsitsi",
+       "log-action-filter-patrol-autopatrol": "Kontrollitud automaatselt",
+       "log-action-filter-protect-protect": "Kaitsmine",
+       "log-action-filter-protect-modify": "Kaitse muutmine",
+       "log-action-filter-protect-unprotect": "Kaitse eemaldamine",
+       "log-action-filter-protect-move_prot": "Kaitse teisaldamine",
+       "log-action-filter-rights-rights": "Muudetud käsitsi",
+       "log-action-filter-rights-autopromote": "Muudetud automaatselt",
+       "log-action-filter-upload-upload": "Uus üleslaadimine",
+       "log-action-filter-upload-overwrite": "Uuesti üleslaadimine",
        "authmanager-provider-password": "Paroolipõhine autentimine",
        "authmanager-provider-password-domain": "Parooli- ja domeenipõhine autentimine",
        "authmanager-provider-temporarypassword": "Ajutine parool",
index 8cf7922..0ebbd47 100644 (file)
        "userrights-reason": "Syy:",
        "userrights-no-interwiki": "Sinulla ei ole oikeutta muokata käyttöoikeuksia muissa wikeissä.",
        "userrights-nodatabase": "Tietokantaa $1 ei ole tai se ei ole paikallinen.",
-       "userrights-nologin": "Sinun täytyy [[Special:UserLogin|kirjautua sisään]] ylläpitäjän tunnuksella, jotta voisit muuttaa käyttöoikeuksia.",
-       "userrights-notallowed": "Sinulla ei ole oikeutta lisätä tai poistaa käyttäjien oikeuksia.",
        "userrights-changeable-col": "Ryhmät, joita voit muuttaa",
        "userrights-unchangeable-col": "Ryhmät, joita et voi muuttaa",
        "userrights-conflict": "Päällekkäinen käyttöoikeuksien muutos! Tarkista tekemäsi muutokset ja vahvista ne.",
-       "userrights-removed-self": "Poistit omat oikeutesi. Tämän vuoksi sinulla ei enää ole oikeutta päästä tälle sivulle.",
        "group": "Ryhmä",
        "group-user": "käyttäjät",
        "group-autoconfirmed": "automaattisesti hyväksytyt käyttäjät",
        "apisandbox-alert-field": "Tässä kentässä oleva arvo ei ole kelvollinen.",
        "apisandbox-continue": "Jatka",
        "apisandbox-continue-clear": "Tyhjennä",
+       "apisandbox-multivalue-all-namespaces": "$1 (Kaikki nimiavaruudet)",
+       "apisandbox-multivalue-all-values": "$1 (Kaikki arvot)",
        "booksources": "Kirjalähteet",
        "booksources-search-legend": "Etsi kirjalähteitä",
        "booksources-isbn": "ISBN",
        "changecontentmodel-legend": "Muuta sisältömallia",
        "changecontentmodel-title-label": "Sivun otsikko",
        "changecontentmodel-model-label": "Uusi sisältömalli",
-       "changecontentmodel-reason-label": "Syy:",
+       "changecontentmodel-reason-label": "Syy",
        "changecontentmodel-submit": "Tee muutos",
        "changecontentmodel-success-title": "Sisältömallia on muutettu",
        "changecontentmodel-success-text": "Sisältötyyppiä kohteessa [[:$1]] on muutettu.",
        "mw-widgets-dateinput-placeholder-month": "VVVV-KK",
        "mw-widgets-titleinput-description-new-page": "sivua ei ole olemassa vielä",
        "mw-widgets-titleinput-description-redirect": "ohjaus kohteeseen $1",
+       "mw-widgets-categoryselector-add-category-placeholder": "Lisää luokka...",
        "sessionmanager-tie": "!!FYZZ!!Cannot combine multiple request authentication types: $1.",
        "sessionprovider-generic": "$1 istuntoa",
        "sessionprovider-mediawiki-session-cookiesessionprovider": "istuntoja, joissa on evästeet käytössä",
        "unlinkaccounts-success": "Tunnuksen linkitys poistettiin.",
        "authenticationdatachange-ignored": "Varmennustietojen muutosta ei käsitelty. Ehkä palveluntarjoajaa ei määritelty?",
        "restrictionsfield-badip": "Virheellinen IP-osoite tai alue: $1",
-       "restrictionsfield-label": "Sallitut IP-alueet:",
-       "edit-error-short": "$1",
-       "edit-error-long": "Virheet:\n\n$1"
+       "restrictionsfield-label": "Sallitut IP-alueet:"
 }
index ea3fd1e..a4120c9 100644 (file)
        "cannotdelete": "Չհաջողվեց ջնջել «$1» էջը կամ ֆայլը։\nՀավանաբար այն արդեն ջնջվել է մեկ այլ մասնակցի կողմից։",
        "cannotdelete-title": "Հնարավոր չէ ջնջել $1 էջը",
        "delete-hook-aborted": "Խմբագրել չեղյալ է.\nԼրացուցիչ պարզաբանումներ չի դրվել.",
-       "no-null-revision": "Չի հաջողվել ստեղծել նոր զրոյական правку համար էջը \"$1\"",
+       "no-null-revision": "Չի հաջողվել ստեղծել նոր զրոյական խմբագրում էջի համար \"$1\"",
        "badtitle": "Անընդունելի անվանում",
        "badtitletext": "Հարցված էջի անվանումը անընդունելի է, դատարկ է կամ սխալ միջ-լեզվական կամ ինտերվիքի անվանում է։ Հնարավոր է, որ այն պարունակում է անթույլատրելի սիմվոլներ։",
        "title-invalid-empty": "Էջի հայցվող վերնագիրը դատարկ է կամ պարունակում է միայն անվանատարածքի անունը։",
index 28e84bc..590caf6 100644 (file)
        "passwordreset-emaildisabled": "E-mail мүмкіндігі бұл уикиде өшірілген.",
        "passwordreset-username": "Қатысушы аты:",
        "passwordreset-domain": "Домен:",
-       "passwordreset-capture": "Келген хатты қарау керек пе?",
-       "passwordreset-capture-help": "Егер Сіз берілген белгішені қондырсаңыз, қатысушыға жіберілетін уақытша құпия сөз жазылған хат көрсетіледі.",
        "passwordreset-email": "Е-поштаның мекен-жайы:",
        "passwordreset-emailtitle": "{{SITENAME}} тіркелгісі туралы анықтама",
        "passwordreset-emailtext-ip": "Әлде кім (мүмкін сіз болуыңыз, $1 IP адресінен) {{SITENAME}} сайтында ($4) құпия сөзді өзгертуге өтініш білдірді. Мына қатысушы {{PLURAL:$3|аккаунты|аккаунттары}} осы электронды почта қатысты:\n\n$2\n\n{{PLURAL:$3|Бұл уақытша құпия сөз|Бұл уақытша құпия сөздер}} {{PLURAL:$5|бір күнде|$5 күнде}}уақыты аяқталады.\nСіз кіруіңіз және жаңа құпия сөзді таңдауыңыз керек. Егер бұл өтінішті басқа біреу жасаса, немесе сіз  бұрынғы құпия сөзіңізді еске түсірсеңіз және құпия сөзді ауыстыруды қаламасаңыз, сіз бұл хабарламаны ескермей және бұрынғы құпия сөзді қолдана беруіңізге болады.",
        "passwordreset-emailtext-user": "$1 есімді қатысушы {{SITENAME}} сайтында ($4) құпия сөзді өзгертуге өтініш білдірді. Мына қатысушы {{PLURAL:$3|аккаунт|аккаунттар}} осы електронды почта қатысты:\n\n$2\n\n{{PLURAL:$3|Бұл уақытша құпия сөз|Бұл уақытша құпия сөздер}} {{PLURAL:$5|бір күнде|$5 күнде}}уақыты аяқталады.\nСіз кіруіңіз және жаңа құпия сөзді таңдауыңыз керек. Егер бұл өтінішті басқа біреу жасаса, немесе сіз  бұрынғы құпия сөзіңізді еске түсірсеңіз, және құпия сөзді ауыстыруды қаламасаңыз, сіз бұл хабарламаны ескермей және бұрыңғы құпия сөзді қолдана беруіңізге болады.",
        "passwordreset-emailelement": "Қатысушы есімі: \n$1\n\nУақытша құпия сөз: \n$2",
        "passwordreset-emailsentemail": "Бұл email мекенжайы тіркелгіңізге байланысқан, сол себепті құпия сөзді өзгерту электронды пошта арқылы жөнелтіледі.",
-       "passwordreset-emailsent-capture2": "{{PLURAL:$1|email has|emails have}}үшін құпия сөздің қалпына келтіру хабарламасы жіберілді. {{PLURAL:$1|username and password|list of usernames and passwords}} мында көрсетілген.",
-       "passwordreset-emailerror-capture2": "{{GENDER:$2|user}}-мен электронды поштамен хабарласу нәтижесіз қалды: $1 The {{PLURAL:$3|username and password|list of usernames and passwords}} мында көрсетілген.",
        "changeemail": "Е-пошта мекенжайын өзгерту немесе аластау",
        "changeemail-header": "Е-пошта мекен-жайының өзгертілуі",
        "changeemail-no-info": "Бұл бетке тікелей ену үшін жүйеге кіруіңіз керек.",
        "userrights-reason": "Себебі:",
        "userrights-no-interwiki": "Басқа уикилердегі қатысушы құқықтарын өңдеуге рұқсатыңыз жоқ.",
        "userrights-nodatabase": "$1 дерекқоры жоқ не жергілікті емес.",
-       "userrights-nologin": "Қатысушы құқықтарын тағайындау үшін әкімші тіркелгісімен [[Special:UserLogin|кіруіңіз]] жөн.",
-       "userrights-notallowed": "Сізге қатысушы құқықтарын қосуға немесе алып тастауға рұқсат берілмеген.",
        "userrights-changeable-col": "Өзгерте алатын топтар",
        "userrights-unchangeable-col": "Өзгерте алмайтын топтар",
        "userrights-conflict": "Қатысушы құқықтарының қақтығысы! Өзгертулеріңізді қайта қарап шығыңыз және құптаңыз.",
-       "userrights-removed-self": "Өзіңіздің құқықтарыңызды алып тастадыңыз.  Осылайша бұл бетке бұдан былай қатынай алмайсыз.",
        "group": "Топ:",
        "group-user": "Қатысушылар",
        "group-autoconfirmed": "Өздіктіқұпталған қатысушылар",
        "right-siteadmin": "Дерекқорды құлыптау және құлыптауын өшіру",
        "right-override-export-depth": "Тереңдігі 5-тен жоғары сілтенген бетттерді қамти беттерді экспорттау",
        "right-sendemail": "Басқа қатысушыларға е-пошта жіберу",
-       "right-passwordreset": "Өзгерген құпия сөз арқылы хабарламаларды шолу",
        "right-managechangetags": "[[Special:Tags|Тегтерді]] дерекқордан бастау және жою",
        "right-applychangetags": "[[Special:Tags|Тегтерді]] бір өзгерісімен қолдану",
        "right-changetags": "Кез келген [[Special:Tags|тегті]] жеке нұсқалардан және журнал жазбаларынан аластау және қосу",
        "trackingcategories-msg": "Санатты қадағалау",
        "trackingcategories-name": "Хабарлама атауы",
        "trackingcategories-desc": "Санаттарды қосу шарттары",
-       "restricted-displaytitle-ignored": "Еленбеген көретілетін атауларымен беттер",
+       "restricted-displaytitle-ignored": "Еленбеген көрcетілетін атауларымен беттер",
        "noindex-category-desc": "Бұл бет роботтар арқылы индекстелмеген, себебі онда <code><nowiki>__NOINDEX__</nowiki></code> деген сиқырлы сөзі бар және бұл жалауша рұқсат етілген есім кеңістігінде орналасқан.",
        "index-category-desc": "Бұл бетте <code><nowiki>__INDEX__</nowiki></code> деген код бар (және бұл жалауша рұқсат етілген есім кеңістігінде орналасқан), демек мұнда қалыпты жағдайда роботтар арқылы индекстелмейді.",
        "post-expand-template-inclusion-category-desc": "Беттің мөлшері барлық үлгілерді кеңейткен соң мынадан <code>$wgMaxArticleSize</code> үлкенірек болады, сондықтан біраз үлгілер кеңейтілмейді.",
index ddc46f0..1596eb6 100644 (file)
        "namespaces": "नामविश्वे",
        "variants": "चले(व्हेरियंट्स)",
        "navigation-heading": "दिक्चालन यादी",
-       "errorpagetitle": "à¤\9aà¥\82à¤\95",
+       "errorpagetitle": "तà¥\8dरà¥\81à¤\9fà¥\80",
        "returnto": "$1 कडे परत चला.",
        "tagline": "{{SITENAME}} कडून",
        "help": "साहाय्य",
        "passwordreset-emaildisabled": "या विकिवर विपत्र पाठविणे 'अशक्य' करण्यात आलेले आहे.",
        "passwordreset-username": "सदस्यनाव:",
        "passwordreset-domain": "डोमेन",
-       "passwordreset-capture": "ईमेल कशी असेल ते बघायचेय ?",
-       "passwordreset-capture-help": "या चौकटीत खूण केली तर, ईमेल (तात्पुरत्या परवलीच्या शब्दासह) दाखविण्यात व सदस्यास पाठविण्यात येईल.",
        "passwordreset-email": "विपत्र पत्ता",
        "passwordreset-emailtitle": "{{SITENAME}} वरील खात्याची माहिती",
        "passwordreset-emailtext-ip": "कुणीतरी (कदाचित तुम्ही, अंकपत्ता $1 वरुन) {{SITENAME}}($4) करिता नविन 'परवलीचा शब्द' पुनर्स्थापनेबद्दल विनंती केली आहे.\nखालील{{PLURAL:$3|सदस्यखाते}}या विपत्रपत्त्याशी निगडीत आहे: \n\"$2\"\n{{PLURAL:$3|हा तात्पुरता परवलीचा शब्द|हे तात्पुरते परवलीचे शब्द}}{{PLURAL:$5|एक दिवस|$5 दिवसात}} मुदतबाह्य होतील.आता आपण लॉग-ईन करून  नविन परवलीचा शब्द निवडा.जर ईतर कोणी ही विनंती केली असेल,किंवा जर आपणास परवलीच शब्द आठवला असेल तर,व जर आपण तो बदलु इच्छित नसाल तर आपण हा संदेश टाळा व आपला जुना परवलीचा शब्द वापरणे सुरू ठेवा.",
        "userrights-reason": "कारण:",
        "userrights-no-interwiki": "इतर विकींवरचे सदस्य अधिकार बदलण्याची परवानगी तुम्हाला नाही.",
        "userrights-nodatabase": "विदा $1 अस्तित्वात नाही अथवा स्थानिक नाही.",
-       "userrights-nologin": "सदस्य अधिकार देण्यासाठी तुम्ही प्रबंधक म्हणून [[Special:UserLogin|सनोंद प्रवेशित]] असणे आवश्यक आहे.",
-       "userrights-notallowed": "तुमच्या सदस्य खात्यास, सदस्य अधिकारांची निश्चिती करण्याची परवानगी नाही.",
        "userrights-changeable-col": "गट जे तुम्ही बदलू शकता",
        "userrights-unchangeable-col": "गट जे तुम्ही बदलू शकत नाही",
        "userrights-conflict": "बदलाबाबत सदस्य-हक्क विसंवाद !कृपया आपले बदल पुन्हा पुनरावलोकित व नक्की करा.",
-       "userrights-removed-self": "आपण आपले हक्क यशस्वीरित्या काढलेत.म्हणुन, या पानात आपण दाखल होऊ शकणार नाही.",
        "group": "गट:",
        "group-user": "सदस्य",
        "group-autoconfirmed": "स्वयंशाबीत सदस्य",
        "right-siteadmin": "माहितीसाठ्याला कुलूप लावा अथवा काढा",
        "right-override-export-depth": "जोडलेल्या पानांचा पाचव्या पातळीपर्यंत अंतर्भाव करुन पाने निर्यात करा",
        "right-sendemail": "इतर सदस्यांना विपत्रे पाठवा",
-       "right-passwordreset": "परवलीचा शब्द पुनर्स्थापित केल्याचे विपत्र पहा.",
        "right-managechangetags": "डाटाबेस मधून [[Special:Tags|खूणपताका]] तयार करा किंवा  वगळा",
        "right-applychangetags": "कोणाच्याही बदलास [[Special:Tags|खूणपताका]] जोडा",
        "right-changetags": "वैयक्तिक आवृत्त्यांना व नोंद प्रवेष्ट्यांना, आहेतुक(arbitrary) [[Special:Tags|खूणपताका]] जोडा अथवा हटवा",
        "listgrants": "अनुदाने",
        "listgrants-grant": "अनुदान",
        "listgrants-rights": "अधिकार",
-       "trackingcategories": "वरà¥\8dà¤\97 à¤¶à¥\8bधत à¤\86हà¥\8bत",
+       "trackingcategories": "माà¤\97à¥\8bवा à¤\98à¥\87णारà¥\87 à¤µà¤°à¥\8dà¤\97",
        "trackingcategories-summary": "या पानात ते रेखापथनातील वर्ग(tracking categories) आहेत, जे, मिडियाविकि संचेतनाद्वारे स्वयंचलितरित्या वसविण्यात (तयार करण्यात) आले आहेत. त्यांची नावे, {{ns:8}} नामविश्वातील संबंधित प्रणाली संदेशात फेरफार करुन, बदलविता येतात.",
+       "trackingcategories-msg": "मागोवा घेणारा वर्ग",
        "trackingcategories-name": "संदेश नाम",
        "trackingcategories-desc": "वर्ग अंतर्भूत करण्याचे निकष",
        "trackingcategories-nodesc": "वर्णन उपलब्ध नाही.",
        "randomrootpage": "अविशिष्ट मूळ पान",
        "log-action-filter-suppress-block": "रोधामार्फत सदस्य दाबणे",
        "changecredentials": "अधिकारपत्रे (क्रेडेंटियल्स)बदला",
-       "removecredentials": "अधिकारपत्रे (क्रेडेंटियल्स) हटवा",
-       "edit-error-short": "त्रुटी: $1",
-       "edit-error-long": "त्रुटी:$1"
+       "removecredentials": "अधिकारपत्रे (क्रेडेंटियल्स) हटवा"
 }
index d175c86..936fd8b 100644 (file)
        "searchdisabled": "{{doc-singularthey}}\nIn this sentence, \"their indexes\" refers to \"Google's indexes\".\n\nShown on [[Special:Search]] when the internal search is disabled.",
        "googlesearch": "{{notranslate}}\nShown when [[mw:Manual:$wgDisableTextSearch|$wgDisableTextSearch]] is set to true and no [[mw:Manual:$wgSearchForwardUrl|$wgSearchForwardUrl]] is set.\n\nParameters:\n* $1 - the search term\n* $2 - \"UTF-8\" (hard-coded)\n* $3 - the message {{msg-mw|Searchbutton}}",
        "search-error": "Shown when an error has occurred when performing a search. Parameters:\n* $1 - the localized error that was returned",
+       "search-warning": "Shown when a warning has occured when performing a search. Parameters:\n* $1 - the localized warning that was returned.",
        "opensearch-desc": "{{ignored}}Link description of the [www.opensearch.org/ OpenSearch] link in the HTML head of pages.",
        "preferences": "Title of the [[Special:Preferences]] page.\n{{Identical|Preferences}}",
        "preferences-summary": "{{doc-specialpagesummary|preferences}}",
        "listgrants-summary": "Explanatory text shown at the top of the grant/rights mapping table.\n\nRefers to {{msg-mw|Listgrouprights-helppage}}.",
        "listgrants-grant": "Used as table header for the grant/rights mapping table.\n{{Identical|Grant}}",
        "listgrants-rights": "Used as table header for the grant/rights mapping table.\n{{Identical|Right}}",
+       "listgrants-grant-display": "{{optional}}\nUsed to display the code name of a grant next to the grant. Parameters:\n* $1 - the text from the \"grant-...\" messages, i.e. {{msg-mw|Grant-highvolume}}\n* $2 - the codename of this grant",
        "trackingcategories": "[[Special:TrackingCategories]] page implementing list of Tracking categories [[mw:Special:MyLanguage/Help:Tracking categories|tracking category]].\n{{Identical|Tracking category}}",
        "trackingcategories-summary": "Description for [[Special:TrackingCategories]] page [[mw:Help:Tracking categories|tracking category]]",
        "trackingcategories-msg": "Header for the message column of the table on [[Special:TrackingCategories]]. This column lists the mediawiki message that controls the tracking category in question.\n{{Identical|Tracking category}}",
index deeece5..807ced9 100644 (file)
        "mypreferencesprotected": "Non ge tìne le permesse pe cangià le preferenze tune.",
        "ns-specialprotected": "Le pàgene speciale no ponne essere cangete.",
        "titleprotected": "Stu titele ha state prutette da 'a ccreazione da [[User:$1|$1]].\n'U mutive jè <em>$2</em>.",
-       "filereadonlyerror": "Non ge pozze cangià 'u file \"$1\" purcé l'archivije de le file \"$2\" ste in mode sola letture.\n\nL'amministratore ca l'ha bloccate dèje sta spiegazione: \"$3\".",
+       "filereadonlyerror": "Non ge pozze cangià 'u file \"$1\" purcé l'archivije de le file \"$2\" ste in sola letture.\n\nL'amministratore d'u sisteme ca l'ave bloccate dèje sta spiegazione: \"$3\".",
        "invalidtitle-knownnamespace": "Titole invalide cu 'u namespace \"$2\" e teste \"$3\"",
        "invalidtitle-unknownnamespace": "Titele invalide cu numere de namespace scanusciute $1 e teste \"$2\"",
        "exception-nologin": "Non ge sì collegate",
        "noname": "Non gìè specifichete 'nu nome utende valide.",
        "loginsuccesstitle": "Tutte a poste, è trasute!",
        "loginsuccess": "'''Mò tu si colleghete jndr'à {{SITENAME}} cumme \"$1\".'''",
-       "nosuchuser": "Non g'esiste n'utende cu 'u nome \"$1\".\nFà attenzione ca le nome de l'utinde so senzibbele a le lettere granne e piccenne.\nVide bbuene a cumme l'è scritte, o [[Special:CreateAccount|ccreje n'utende nuève]].",
+       "nosuchuser": "Non g'esiste n'utende cu 'u nome \"$1\".\nLe nome de l'utinde so senzibbele a le lettere granne e piccenne.\nVide bbuene a cumme l'è scritte, o [[Special:CreateAccount|ccreje n'utende nuève]].",
        "nosuchusershort": "Non ge ste nisciune utende cu 'u nome \"$1\".\nCondrolle accume l'è scritte.",
        "nouserspecified": "A scrivere pe forze 'u nome de l'utende.",
        "login-userblocked": "Stu utende jè bloccate. Non ge puè trasè.",
        "noemail": "Non ge stonne email reggistrete pe l'utende \"$1\".",
        "noemailcreate": "Tu ha mèttere 'n'indirizze e-mail valide",
        "passwordsent": "'Na nova passuord ha state mannete a l'indirizze e-mail reggistrete pe \"$1\".\nPe piacere, colleghete n'otra vota quanne l'è ricevute.",
-       "blocked-mailpassword": "L'indirizze IP tue jè blocchete pe le cangiaminde e accussì tu non ge puè ausà 'a funzione de recupere d'a password pe prevenìe l'abbuse.",
+       "blocked-mailpassword": "L'indirizze IP tune jè bloccate pe le cangiaminde. Tu non ge puè ausà 'a funzione de recupere d'a password pe prevenìe l'abbuse.",
        "eauthentsent": "'N'e-mail de conferme ha state mannate a l'indirizze ca tu è ditte.\nApprime ca otre e-mail avènene mannate a 'u cunde tune, tu ha seguì le 'struzione ca stonne jndr'à l'e-mail, pe confermà ca 'u cunde jè une de le tune.",
        "throttled-mailpassword": "'Nu arrecordatore de passuord ha stete già mannate jndr'à {{PLURAL:$1|l'urtema ore|l'urteme $1 ore}}.\nPe prevenì l'abbuse, sulamende 'nu arrecordatore de passuord avene mannate ogne {{PLURAL:$1|ore|$1 ore}}.",
        "mailerror": "Errore mannanne 'a mail: $1",
        "passwordreset-emaildisabled": "Le funziune de l'email onne state disabbilitate sus a sta uicchi.",
        "passwordreset-username": "Nome utende:",
        "passwordreset-domain": "Dominie:",
-       "passwordreset-capture": "Vide 'a mail resultande?",
-       "passwordreset-capture-help": "Ce tu signe sta sckatele, 'a mail (cu 'a passuord temboranèe) t'avène fatte vedè cumme adda essere mannate a l'utende.",
        "passwordreset-email": "Indirizze e-mail:",
        "passwordreset-emailtitle": "Dettaglie d'u cunde utende sus a {{SITENAME}}",
        "passwordreset-emailtext-ip": "Quacchedune (pò essere tu, da 'u 'ndirizze IP $1) ha richieste 'na mail pe arrecurdarse de le dettaglie d'u cunde sue pe {{SITENAME}} ($4). {{PLURAL:$3|'U cunde utende seguende jè|le cunde utinde seguende sonde}} associate cu st'indirizze e-mail:\n\n$2\n\n{{PLURAL:$3|Sta passuord temboranèe scade|Ste passuord temboranèe scadene}} 'mbrà {{PLURAL:$5|'nu sciurne|$5 sciurne}}.\nTu avissa trasè e scacchià 'na passuord nova. Ce quacchedun'otre ha fatte sta richieste, o ce tu t'è arrecurdate 'a passuord origgenale toje, e non g'a vuè ccu cange cchiù, tu puè ignorà stu messagge e condinuà ausanne 'a passuord vecchie.",
        "userrights-reason": "Mutive:",
        "userrights-no-interwiki": "Tu non ge tìne le permesse pe cangià le deritte utende sus a l'otre uicchi.",
        "userrights-nodatabase": "'U Database $1 non g'esiste o non g'è lochele.",
-       "userrights-nologin": "Tu à essere [[Special:UserLogin|colleghete]] cu 'nu cunde utende d'amministratore pe assignà le deritte utende.",
-       "userrights-notallowed": "Non ge tìne le permesse pe aggiungere o luà le deritte a le utinde.",
        "userrights-changeable-col": "Gruppe ca tu puè cangià",
        "userrights-unchangeable-col": "Gruppe ca tu non ge puè cangià",
        "userrights-irreversible-marker": "$1*",
        "userrights-conflict": "Conflitte sus a le cangiaminde de le deritte utende! Pe piacere revide e conferme le cangiaminde tune.",
-       "userrights-removed-self": "T'è luate le deritte tune. Mò non ge puè cchiù trasè jndr'à sta pàgene.",
        "group": "Gruppe:",
        "group-user": "Utinde",
        "group-autoconfirmed": "Utinde auto confermatarije",
        "right-siteadmin": "Blocche e sblocche 'u database",
        "right-override-export-depth": "L'esportazione de pàggene inglude pàggene collegate 'mbonde a 'na profonnetà de 5",
        "right-sendemail": "Manne 'a mail a otre utinde",
-       "right-passwordreset": "Vide l'e-mail de azzeramende d'a passuord",
        "right-managechangetags": "CCreje e scangìlle [[Special:Tags|tag]] da 'u database",
        "right-applychangetags": "Appleche [[Special:Tags|tag]] sus a 'u de le cangiaminde tune",
        "right-changetags": "Aggiunge e live arbitrariamende [[Special:Tags|tag]] sus a le revisiune individuale e vôsce de l'archivije",
index ea05650..66e53af 100644 (file)
        "uploadstash-errclear": "Билэлэри сотор табыллыбата.",
        "uploadstash-refresh": "Билэлэр тиһиктэрин саҥардан биэр",
        "uploadstash-thumbnail": "ойуучааны көрдөр",
+       "uploadstash-exception": "Суруттараргын быстах уурар сиргэ харайар сатаммата ($1): \"$2\".",
        "invalid-chunk-offset": "Бобуллубут сыҕарыйыы",
        "img-auth-accessdenied": "Киирии бобуллубут",
        "img-auth-nopathinfo": "PATH_INFO суох.\nЭн сиэрбэриҥ маннык сибидиэнньэни ыытарга туруоруллубатах эбит.\nБаҕар кини CGI олоҕурара буолуо ол иһин img_auth өйөөбөтө буолуо.\nМаны https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Image_Authorization көр.",
        "filerevert-submit": "Төннөрүү",
        "filerevert-success": "'''[[Media:$1|$1]]''' бу торумҥа төннөрүлүннэ [$4 торум Filetype-missingот $3, $2].",
        "filerevert-badversion": "Бу билэ этиллибит күҥҥэ-ыйга/кэмҥэ оҥоһуллубут урукку торума суох.",
+       "filerevert-identical": "Талбыт торумуҥ билиҥҥи торуму кытта үүт үкчүлэр.",
        "filedelete": "Сот: $1",
        "filedelete-legend": "Билэни сот",
        "filedelete-intro": "Бу билэни '''[[Media:$1|$1]]''' туох баар суруллубут историятын кытта сотон эрэҕин.",
        "apisandbox": "API песочница",
        "apisandbox-jsonly": "API-песочницаны туһанарга JavaScript ирдэнэр.",
        "apisandbox-api-disabled": "Бу сайтка API араарыллыбыт.",
+       "apisandbox-intro": "Бу сирэйи <strong>MediaWiki API</strong> тургутан көрөргө туһан.\nAPI-ни туттар туһунан сиһилии манна ааҕыахха сөп [[mw:API:Main page|API туһунан]]. Холобура, [https://www.mediawiki.org/wiki/API#A_simple_example Сүрүн сирэй иһинээҕитин хайдах ылар туһунан]. Атын холобурдары көрөргө сигэни баттаа.\nБолҕой: бу тургутар сирэй эрээри, манна суруйбутуҥ биикигэ уларытыыны оҥоруон сөп.",
        "apisandbox-fullscreen": "Паныалы арыйыы.",
        "apisandbox-fullscreen-tooltip": "Браузеры толорорго песочница паныалын арыйыы.",
        "apisandbox-unfullscreen": "Сирэйи көрдөрүү",
        "apisandbox-submit": "Ыйытык оҥоруу",
        "apisandbox-reset": "Сот",
        "apisandbox-retry": "Хатылаа",
+       "apisandbox-loading": "«$1» API-модульга аналлаах хачайдана турар…",
+       "apisandbox-load-error": "«$1» API-модулга аналлаах хачайданарыгар алҕас таҕыста: $2",
+       "apisandbox-no-parameters": "Бу API-модулга туруоруута (параметра) суох.",
        "apisandbox-helpurls": "Көмө сигэлэр",
        "apisandbox-examples": "Холобурдар",
        "apisandbox-dynamic-parameters": "Дьайыы кээмэйдэрэ.",
        "apisandbox-results": "Түмүк",
        "apisandbox-sending-request": "API-көрдөбүлү ыытыы…",
        "apisandbox-loading-results": "API-түмүгүн ылыы…",
+       "apisandbox-results-error": "Көрдөбүлгэ API-хоруйу киллэрии  кэмигэр алҕас таҕыста: $1.",
+       "apisandbox-request-url-label": "Көрдөбүл URL-аадырыһа:",
+       "apisandbox-request-time": "Көрдөбүл болдьоҕо: {{PLURAL:$1|$1 мс}}",
        "apisandbox-results-fixtoken": "Токены көннөрөн баран саҥаттан ыыт.",
+       "apisandbox-results-fixtoken-fail": "«$1» токены ыҥырар табыллыбата.",
+       "apisandbox-alert-page": "Бу сирэй хонуулара алҕастаах.",
+       "apisandbox-alert-field": "Хонуу суолтата алҕастаах.",
+       "apisandbox-continue": "Салгыы",
+       "apisandbox-continue-clear": "Сот",
+       "apisandbox-continue-help": "{{int:apisandbox-continue}} бүтэһик көрдөбүлү [https://www.mediawiki.org/wiki/API:Query#Continuing_queries салгыаҕа]; {{int:apisandbox-continue-clear}} салҕааһыны кытта ситимнээх туруоруулары ырастыа.",
+       "apisandbox-param-limit": "Муҥутуур болдьох <kbd>муҥутуурдук</kbd> туттулларын туоруор.",
+       "apisandbox-multivalue-all-namespaces": "$1 (Аат даллара барыта)",
+       "apisandbox-multivalue-all-values": "$1 (Бары суолталара)",
        "booksources": "Кинигэлэр источниктара",
        "booksources-search-legend": "Кинигэ туһунан көрдөө",
        "booksources-search": "Бул",
index 12d7974..290a8b8 100644 (file)
        "tooltip-pt-mytalk": "{{GENDER:|Tvoja}} pogovorna stran",
        "tooltip-pt-anontalk": "Pogovor o urejanjih s tega IP-naslova",
        "tooltip-pt-preferences": "{{GENDER:|Tvoje}} nastavitve",
-       "tooltip-pt-watchlist": "Seznam strani, katerih spremembe spremljate",
+       "tooltip-pt-watchlist": "Seznam strani, katerih spremembe spremljaš",
        "tooltip-pt-mycontris": "Seznam {{GENDER:|tvojih}} prispevkov",
        "tooltip-pt-anoncontribs": "Seznam urejanj s tega IP-naslova",
        "tooltip-pt-login": "Prijava ni obvezna, vendar je zaželena",
index cbf3596..b272865 100644 (file)
        "passwordreset-emaildisabled": "Bu wiki'deki e-posta özellikleri devre dışı bırakıldı.",
        "passwordreset-username": "Kullanıcı adı:",
        "passwordreset-domain": "Domain:",
-       "passwordreset-capture": "Sonuç e-postasını görüntüle?",
-       "passwordreset-capture-help": "Bu kutuyu işaretlerseniz, e-posta (geçici şifre ile) size ve yanı sıra kullanıcıya gönderiliyor.",
        "passwordreset-email": "E-posta adresi:",
        "passwordreset-emailtitle": "{{SITENAME}} hesap detayları",
        "passwordreset-emailtext-ip": "Birisi, (muhtemelen siz, $1 IP adresinden) {{SITENAME}} ($4) için hesap bilgilerinizin \nhatırlatılmasını istedi. Aşağıdaki kullanıcı {{PLURAL:$3|hesabı|hesapları}} bu e-posta adresiyle ilişkili:\n\n$2\n\n{{PLURAL:$3|Bu geçici şifre|Bu geçici şifreler}} {{PLURAL:$5|bir gün|$5  gün}} geçerlidir.\nBu geçici parola ile giriş yapın ve yeni bir şifre seçin. Şifre değişimini siz istemediyseniz veya şifrenizi hatırladıysanız ve artık şifrenizi değiştirmek istemiyorsanız; bu iletiyi önemsemeyerek eski şifrenizi kullanmaya devam edebilirsiniz.",
        "userrights-reason": "Neden:",
        "userrights-no-interwiki": "Diğer vikilerdeki kullanıcıların izinlerini değiştirmeye yetkiniz yok.",
        "userrights-nodatabase": "$1 veritabanı mevcut veya bölgesel değil",
-       "userrights-nologin": "Kullanıcı haklarını atamak için hizmetli hesabı ile [[Special:UserLogin|giriş yapmanız gerekir]].",
-       "userrights-notallowed": "Kullanıcı hakları eklemek veya kaldırmak için izniniz yok.",
        "userrights-changeable-col": "Değiştirebildiğiniz gruplar",
        "userrights-unchangeable-col": "Değiştirebilmediğiniz gruplar",
        "userrights-conflict": "Kullanıcı hakları değişikliklerinde çakışma! Lütfen değişikliklerinizi gözden geçirin ve onaylayın.",
-       "userrights-removed-self": "Kendi haklarınız başarıyla kaldırıldı. Bu nedenle, artık bu sayfaya erişemeyeceksiniz.",
        "group": "Grup:",
        "group-user": "Kullanıcılar",
        "group-autoconfirmed": "Otomatik onaylanmış kullanıcılar",
        "right-siteadmin": "Veritabanını kilitle ve kilidi aç",
        "right-override-export-depth": "Sayfaları, derinlik 5'e kadar bağlantılı sayfalarla beraber, dışa aktar",
        "right-sendemail": "Diğer kullanıcılara e-posta gönder",
-       "right-passwordreset": "Parola sıfırlama e-postalarını görür",
        "right-managechangetags": "Veritabanında [[Special:Tags|etiket]] oluşturma veya silme",
        "right-applychangetags": "Değişiklikleriyle beraber [[Special:Tags|etiketleri]] uygula",
        "right-changetags": "Tekil sürümler ve günlük kayıtlarına rastgele [[Special:Tags|etiket]] ekleme veya çıkarma",
        "booksources-search": "Ara",
        "booksources-text": "Aşağıdaki, yeni ve kullanılmış kitap satan diğer sitelere bağlantıların listesidir, ve aradığınız kitaplar hakkında daha fazla bilgiye sahip olabilirler:",
        "booksources-invalid-isbn": "Verilen ISBN geçersiz gibi görünüyor; orijinal kaynaktan kopyalama hataları için kontrol edin.",
+       "magiclink-tracking-rfc": "RFC sihirli bağlantısını kullanan sayfalar",
+       "magiclink-tracking-pmid": "PMID sihirli bağlantısını kullanan sayfalar",
+       "magiclink-tracking-isbn": "ISBN sihirli bağlantısını kullanan sayfalar",
        "specialloguserlabel": "Kullanıcı:",
        "speciallogtitlelabel": "Hedef (başlık ya da kullanıcı):",
        "log": "Kayıtlar",
index 2269267..75b503c 100644 (file)
        "databaseerror-query": "Курон: $1",
        "databaseerror-function": "Функция: $1",
        "databaseerror-error": "Янгыш: $1",
+       "badtitle": "Умойтэм ним",
        "badtitletext": "Курем бам ним луэ мыдлань, буш либо кылъёс куспын яке викиос куспын нимыз умойтэм герӟамын.\nНимын, вылды, ярантэм символъёс вань.",
        "viewsource": "Кодзэ учкыны",
        "viewsource-title": "Кодзэ учкыны бам $1",
        "createacct-another-username-ph": "Учётной книга нимъёс пыртэмын",
        "yourpassword": "Лушкемкыл:",
        "userlogin-yourpassword": "Лушкемкыл",
+       "userlogin-yourpassword-ph": "Гожтэ асьтэлэсь парольдэс",
+       "createacct-yourpassword-ph": "Гожтэ паролез",
        "createacct-yourpasswordagain": "Пароль юнматэ",
+       "createacct-yourpasswordagain-ph": "Гожтэ паролез эшшо одӥг пол",
        "userlogin-remembermypassword": "Кылем сӧзнэтэз",
        "cannotcreateaccount-title": "Уг быгатиськы гожъян кылдӥз учётной",
        "yourdomainname": "Тӥ доменэн:",
        "logout": "Кошкыны",
        "userlogout": "Потыны",
        "notloggedin": "Тон эн тусбуяськыны сӧзнэтэз",
+       "userlogin-noaccount": "Ас учётной записьты ӧвӧл?",
        "nologin": "Учётной книга ӧвӧл-а? $1.",
        "nologinlink": "Выль вики-авторлэн регистрациез",
        "createaccount": "выль вики-авторлэн регистрациез",
        "userlogin-helplink2": "Пыронъя юрттэт",
        "createacct-emailrequired": "Электронной почталэн адресэз",
        "createacct-emailoptional": "Электронной почтаезлэн адресэз (необязательное)",
+       "createacct-email-ph": "Гожтэ асьтэлэн электрон почтадылэсь адрессэ",
        "createaccountmail": "Адрес электронной почта огдырлы кутӥ вылын возьматэм образъёсыныз но соослэн случайной сгенерировать пароль ыстыны",
        "createacct-submit": "Выль вики-авторлэн регистрациез",
        "createacct-another-submit": "Выль вики-авторлэн регистрациез",
+       "createacct-benefit-heading": "{{SITENAME}} — тӥ выллем адямиослэн валче ужамзы.",
+       "createacct-benefit-body1": "{{PLURAL:$1|тупатон}}",
+       "createacct-benefit-body2": "{{PLURAL:$1|бам}}",
+       "createacct-benefit-body3": "{{PLURAL:$1|викиавтор}} берло дыре",
        "loginerror": "Янгышъёс пырон",
        "createacct-error": "Янгышъёс бордын учётной книга кылдытыны",
        "createaccounterror": "Уг быгатиськы гожъян учётной кылдоз: $1",
        "blocked-notice-logextract": "Пользователь заблокирован сётӥз та учырлы.\nСправка понна радъяськылӥсь журнал блокировка лапег берпуметӥ гожтэт:",
        "continue-editing": "Тупатъянэз азьланьтоно",
        "editing": "Тупатон: $1",
+       "creating": "«$1» бамез кылдытон",
        "editingsection": "Тупатон: $1 (люкет)",
+       "templatesused": "Та бам пушкы пыртэм {{PLURAL:$1|шаблон|шаблонъёс}}:",
        "template-protected": "(утемын)",
        "template-semiprotected": "(полуутемын)",
+       "hiddencategories": "Та бам пыре {{PLURAL:$1|$1 ватэм категорие}}:",
        "nocreatetext": "Та сайтлэн бамаз выль сюбегатэм луонлыкъёсын кылдытон.\nТон улыса, берлань вуэ быгатэ бам отредактировать, [[Special:UserLogin|тусбуяськыны книгае яке выль система кылдыто учётной]].",
        "nocreate-loggedin": "Тон доразы юаськыны кылдӥз выль бам ӧвӧл.",
        "permissionserrors": "Янгышъёс юаське",
        "cantcreateaccount-text": "Та книгаез кылдытонлы учётной IP-адрес (<strong>$1</strong>) заблокировать луизы [[User:$3|$3]].\n\nМугез, вайиз $3 возьматэ <em>$2</em>",
        "cantcreateaccount-range-text": "Учётной кылдытон - гожъян IP-адрес диапазонын <strong>$1</strong>, Тон пыриське со IP-адрес (<strong>$4</strong>), заблокировать луизы [[User:$3|$3]].\n\nМугез, вайиз $3 возьматэ <em>$2</em>",
        "viewpagelogs": "Та бамлы журналъёсыз возьматыны",
+       "currentrev-asof": "Алиез версия $1",
        "revisionasof": "Версия $1",
+       "revision-info": "Версия $1; {{GENDER:$6|$2}}$7",
        "previousrevision": "← Вужгем",
+       "nextrevision": "Выльгем →",
+       "currentrevisionlink": "Алиез версия",
        "cur": "али",
        "last": "азьв.",
        "history-show-deleted": "Ӵушылэмъёссэ гинэ",
        "revdelete-radio-unset": "Адӟымон",
        "revdelete-reason-dropdown": "*Вӧлскем палэнскон мугъёсты\n** Авторской правоосты тӥян\n** Яке кулэтэм информациез личной комментарий\n** Логин несоответствовать\n** Курла информациез Потенциально",
        "history-title": "$1 — воштонъёслэн историзы",
+       "difference-title": "$1 — версиосыз куспын пӧртэмлык",
        "lineno": "$1-тӥ чур:",
        "compareselectedversions": "Быръем версиосыз ӵошатыны",
        "showhideselectedversions": "Возьматыны/ватыны быръем версиосыз",
        "search-result-size": "$1 ({{PLURAL:$2|$2 кыл}})",
        "search-redirect": "($1 бамысь ыстон)",
        "search-section": "(«$1» люкет)",
+       "search-suggest": "Тӥ, вылды, утчаллямды «$1».",
        "search-interwiki-more": "(эшшо)",
        "searchall": "Ваньзэ",
        "search-showingresults": "{{PLURAL:$4|<strong>$3</strong> пӧлысь <strong>$1-тӥ</strong> шедьтэм|<strong>$3</strong> пӧлысь <strong>$1—$2</strong> шедьтэмъёс}}",
        "rcshowhideminor-hide": "Ватыны",
        "rcshowhidebots": "$1 ботъёсыз",
        "rcshowhidebots-show": "Возьматыны",
+       "rcshowhidebots-hide": "Ватыны",
        "rcshowhideliu": "$1 пырем викиавторъёсыз",
        "rcshowhideliu-show": "Возьматыны",
        "rcshowhideliu-hide": "Ватыны",
        "upload-dialog-button-cancel": "Берытсконо",
        "license-header": "Лицензия",
        "nolicense": "Ӧвӧл",
+       "imgfile": "файл",
        "file-anchor-link": "Файл",
        "filehist": "Файллэн историез",
        "filehist-help": "Зӥбе дата/дыр шоры, кызьы файл со дырын адӟиськемез учкыны вылысь.",
        "randompage": "Олокыӵе статья",
        "withoutinterwiki-submit": "Возьматыны",
        "nbytes": "{{PLURAL:$1|$1 байт}}",
+       "nmembers": "$1 {{PLURAL:$1|объект}}",
        "prefixindex-submit": "Возьматыны",
        "newpages": "Выль бамъёс",
        "newpages-submit": "Возьматыны",
        "move": "Нимзэ воштыны",
+       "pager-older-n": "{{PLURAL:$1|вужгес $1}}",
        "booksources": "Книгаосын источникъёс",
+       "booksources-search-legend": "Книга сярысь информациез утчан",
+       "booksources-search": "Утчаны",
        "log": "Журналъёс",
        "logeventslist-submit": "Возьматыны",
        "showhideselectedlogentries": "Возьматыны/ватыны быръем журналъёсысь гожъямъёсыз",
        "checkbox-all": "Ваньзэ",
        "checkbox-none": "Номыре",
        "checkbox-invert": "Воштыны интыен",
+       "allarticles": "Ваньмыз бамъёс",
        "allpagessubmit": "Быдэстоно",
+       "categories": "Категориос",
        "categories-submit": "Возьматыны",
        "sp-deletedcontributions-contribs": "тупатонъёсыз",
        "listusers-submit": "Возьматыны",
        "watchlist-options": "Чаклан списокез тупатыны",
        "enotif_reset": "Вань бамъёсыз лыдӟем пусйыны",
        "historyaction-submit": "Возьматыны",
+       "dellogpage": "Быдтонъёсын журнал",
        "deletionlog": "палэнэ журнал",
        "rollbacklink": "ӝог берыктыны",
+       "rollbacklinkcount": "$1 {{PLURAL:$1|тупатонэз}} ӝог берыктыны",
        "revertpage": "Откат шонертон [[Special:Contributions/$2|$2]] ([[User talk:$2|обсуждение]]) доры версия [[User:$1|$1]]",
        "revertpage-nouser": "Откат шонертон (пыриськисьёс ватэм нимъёссы) доры версия {{GENDER:$1|[[User:$1|$1]]}}",
        "restriction-edit": "Тупатон",
        "mycontris": "Гожтэмъёс",
        "anoncontribs": "Гожтэмъёс",
        "nocontribs": "Критерии нокыӵе воштӥськонъёс та соответствующий шедьтыны уг луы.",
+       "month": "Толэзьысен (вазен но):",
+       "year": "Арысен (вазен но):",
        "sp-contributions-blocklog": "блокировка",
        "sp-contributions-deleted": "шонертон палэнтыны {{GENDER:$1|участник|куакеч}}",
        "sp-contributions-blocked-notice": "Пользователь заблокирован сётӥз та учырлы. Справка понна радъяськылӥсь журнал блокировка лапег берпуметӥ гожтэт:",
        "block-log-flags-nousertalk": "тупатъяны ачиз уггес быгаты бамлэн обсуждениосаз",
        "range_block_disabled": "Администратор диапазонэз блокировать али.",
        "move-watch": "Чаклан списоке пыртоно инъет но валтӥсь бамъёсыз",
+       "movelogpage": "Нимъёсты воштонъёсын журнал",
        "export": "Бамъёсты поттон",
        "allmessagesname": "Ивортон",
        "allmessages-filter-all": "Ваньзэ",
        "tooltip-ca-addsection": "Выль люкет кылдытоно",
        "tooltip-ca-viewsource": "Та бам воштонъёслэсь утемын.\nТӥ быгатӥськоды инъет текстсэ учкыны но кӧчырыны",
        "tooltip-ca-history": "Бамлэн воштонъёсыныз журнал",
+       "tooltip-ca-move": "Та бамлэсь нимзэ воштыны",
        "tooltip-ca-watch": "Та бамез чаклан списокады пыртоно",
        "tooltip-search": "Утчано {{SITENAME}}",
        "tooltip-search-go": "Выжоно сыӵе ик нимын баме",
        "tooltip-ca-nstab-main": "Валтӥсь бамез учконо",
        "tooltip-ca-nstab-user": "Викиавторлэн бамез",
        "tooltip-ca-nstab-special": "Та бам нимысьтыз, сое тупатон луонтэм",
+       "tooltip-ca-nstab-project": "Проектлэн бамез",
        "tooltip-ca-nstab-image": "Файллэн бамез",
        "tooltip-ca-nstab-template": "Шаблонлэн бамез",
        "tooltip-ca-nstab-category": "Категорилэн бамез",
        "simpleantispam-label": "Анти-спам эскерон.\n<strong>Эн</strong> гожтэ татчы!",
        "pageinfo-header-edits": "Воштонъёслэн историзы",
        "pageinfo-toolboxlink": "Бам сярысь тодэтъёс",
+       "previousdiff": "← Вужгес тупатон",
+       "nextdiff": "Выльгес тупатон →",
        "file-info-size": "$1 × $2 пиксель, файллэн быдӟалаез: $3, MIME-тип: $4",
        "file-nohires": "Бадӟымгес быдӟалаен суред ӧвӧл.",
        "svg-long-desc": "SVG файл, номинально $1 × $2 пиксель, файллэн быдӟалаез: $3",
        "tags-title": "Меткаос",
        "logentry-delete-delete": "$1 {{GENDER:$2|палэнтыны|палэнтыны}} бам $3",
        "logentry-delete-restore": "$1 {{GENDER:$2|выльысь}} бам $3",
+       "logentry-move-move": "$1 $3 бамлы $4 выль ним {{GENDER:$2|сётӥз}}",
        "logentry-newusers-create": "$1 нимо учётной запись {{GENDER:$2|кылдытэмын}} вал",
+       "logentry-upload-upload": "$1 {{GENDER:$2|понӥз}} $3",
        "searchsuggest-search": "Утчано {{SITENAME}}",
        "searchsuggest-containing": "кудъёсаз вань...",
        "api-error-autoblocked": "Тон IP-адрес заблокировать эрказ луи, малы ке шуоно со заблокировать пользователь кутыны луоз.",
index 360adef..18ad10f 100644 (file)
        "userrights-user-editname": "Введіть ім'я користувача:",
        "editusergroup": "Завантажити групи користувачів",
        "editinguser": "Зміна прав {{GENDER:$1|користувача}} <strong>[[User:$1|$1]]</strong> $2",
-       "userrights-editusergroup": "Змінити групи користувачів",
+       "userrights-editusergroup": "Змінити групи {{GENDER:$1|користувача|користувачки}}",
        "saveusergroups": "Зберегти групи {{GENDER:$1|користувачів}}",
        "userrights-groupsmember": "Член груп:",
        "userrights-groupsmember-auto": "Неявний член:",
index 31b2101..f6bb253 100644 (file)
@@ -41,8 +41,8 @@ class Protect extends Maintenance {
        }
 
        public function execute() {
-               $userName = $this->getOption( 'u', false );
-               $reason = $this->getOption( 'r', '' );
+               $userName = $this->getOption( 'user', false );
+               $reason = $this->getOption( 'reason', '' );
 
                $cascade = $this->hasOption( 'cascade' );
 
index 8538417..98835d5 100644 (file)
@@ -24,6 +24,7 @@
        "ooui-dialog-process-dismiss": "Απόρριψη",
        "ooui-dialog-process-retry": "Δοκιμάστε ξανά",
        "ooui-dialog-process-continue": "Συνέχεια",
+       "ooui-selectfile-button-select": "Επιλέξτε ένα αρχείο",
        "ooui-selectfile-not-supported": "Επιλογή αρχείου δεν υποστηρίζεται",
        "ooui-selectfile-placeholder": "Κανένα αρχείο δεν είναι επιλεγμένο",
        "ooui-selectfile-dragdrop-placeholder": "Σύρετε το αρχείο εδώ"
index 542447d..a96ae13 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOjs UI v0.18.0
+ * OOjs UI v0.18.1
  * https://www.mediawiki.org/wiki/OOjs_UI
  *
  * Copyright 2011–2016 OOjs UI Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2016-11-09T00:52:37Z
+ * Date: 2016-11-29T22:57:37Z
  */
 ( function ( OO ) {
 
index bcc3778..e5e6252 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOjs UI v0.18.0
+ * OOjs UI v0.18.1
  * https://www.mediawiki.org/wiki/OOjs_UI
  *
  * Copyright 2011–2016 OOjs UI Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2016-11-09T00:52:42Z
+ * Date: 2016-11-29T22:57:42Z
  */
 .oo-ui-element-hidden {
   display: none !important;
index e7c2ee0..6a31fe8 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOjs UI v0.18.0
+ * OOjs UI v0.18.1
  * https://www.mediawiki.org/wiki/OOjs_UI
  *
  * Copyright 2011–2016 OOjs UI Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2016-11-09T00:52:42Z
+ * Date: 2016-11-29T22:57:42Z
  */
 .oo-ui-element-hidden {
   display: none !important;
   box-shadow: none;
 }
 .oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-destructive > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
-  color: #c33;
+  color: #d33;
 }
 .oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-destructive > .oo-ui-buttonElement-button:hover > .oo-ui-labelElement-label {
-  color: #e53939;
+  color: #ff4242;
 }
 .oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-destructive > .oo-ui-buttonElement-button:active > .oo-ui-labelElement-label,
 .oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-destructive.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
-  color: #873636;
+  color: #b32424;
   box-shadow: none;
 }
 .oo-ui-buttonElement-frameless.oo-ui-widget-enabled[class*='oo-ui-flaggedElement'] > .oo-ui-buttonElement-button > .oo-ui-iconElement-icon,
 }
 .oo-ui-buttonElement-framed.oo-ui-widget-enabled > .oo-ui-buttonElement-button:active,
 .oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button {
-  background-color: #d9d9d9;
+  background-color: #c8ccd1;
   color: #000;
   border-color: #72777d;
 }
   box-shadow: inset 0 0 0 1px #36c;
 }
 .oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-destructive > .oo-ui-buttonElement-button {
-  color: #c33;
+  color: #d33;
 }
 .oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-destructive > .oo-ui-buttonElement-button:hover {
   background-color: #fff;
 .oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-destructive > .oo-ui-buttonElement-button:active:focus,
 .oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-destructive.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button,
 .oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-destructive.oo-ui-buttonElement-active > .oo-ui-buttonElement-button {
-  background-color: #fbf4f4;
-  color: #873636;
-  border-color: #873636;
+  background-color: #ffffff;
+  color: #b32424;
+  border-color: #b32424;
   box-shadow: none;
 }
 .oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-destructive > .oo-ui-buttonElement-button:focus {
-  border-color: #c33;
-  box-shadow: inset 0 0 0 1px #c33;
+  border-color: #d33;
+  box-shadow: inset 0 0 0 1px #d33;
 }
 .oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-progressive > .oo-ui-buttonElement-button {
   color: #fff;
 }
 .oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-destructive > .oo-ui-buttonElement-button {
   color: #fff;
-  background-color: #c33;
-  border-color: #c33;
+  background-color: #d33;
+  border-color: #d33;
 }
 .oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-destructive > .oo-ui-buttonElement-button:hover {
-  background-color: #e53939;
-  border-color: #e53939;
+  background-color: #ff4242;
+  border-color: #ff4242;
 }
 .oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-destructive > .oo-ui-buttonElement-button:active,
 .oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-destructive > .oo-ui-buttonElement-button:active:focus,
 .oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-destructive.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button,
 .oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-destructive.oo-ui-buttonElement-active > .oo-ui-buttonElement-button {
   color: #fff;
-  background-color: #873636;
-  border-color: #873636;
+  background-color: #b32424;
+  border-color: #b32424;
   box-shadow: none;
 }
 .oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-destructive > .oo-ui-buttonElement-button:focus {
-  border-color: #c33;
-  box-shadow: inset 0 0 0 1px #c33, inset 0 0 0 2px #fff;
+  border-color: #d33;
+  box-shadow: inset 0 0 0 1px #d33, inset 0 0 0 2px #fff;
 }
 .oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary > .oo-ui-buttonElement-button > .oo-ui-iconElement-icon,
 .oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary > .oo-ui-buttonElement-button > .oo-ui-indicatorElement-indicator {
 }
 .oo-ui-fieldLayout {
   display: block;
-  margin-bottom: 1em;
+  margin-top: 1.640625em;
 }
 .oo-ui-fieldLayout:before,
 .oo-ui-fieldLayout:after {
   padding: 0.5em 0.75em;
   line-height: 1.5;
 }
-.oo-ui-fieldLayout:last-child {
-  margin-bottom: 0;
+.oo-ui-fieldLayout.oo-ui-labelElement,
+.oo-ui-fieldLayout.oo-ui-fieldLayout-align-inline {
+  margin-top: 1.171875em;
 }
-.oo-ui-fieldLayout.oo-ui-fieldLayout-align-left.oo-ui-labelElement > .oo-ui-fieldLayout-body > .oo-ui-labelElement-label,
-.oo-ui-fieldLayout.oo-ui-fieldLayout-align-right.oo-ui-labelElement > .oo-ui-fieldLayout-body > .oo-ui-labelElement-label {
-  padding-top: 0.5em;
-  margin-right: 5%;
-  width: 35%;
+.oo-ui-fieldLayout:first-child,
+.oo-ui-fieldLayout.oo-ui-labelElement:first-child,
+.oo-ui-fieldLayout.oo-ui-fieldLayout-align-inline:first-child {
+  margin-top: 0;
 }
-.oo-ui-fieldLayout.oo-ui-fieldLayout-align-left > .oo-ui-fieldLayout-body > .oo-ui-fieldLayout-field,
-.oo-ui-fieldLayout.oo-ui-fieldLayout-align-right > .oo-ui-fieldLayout-body > .oo-ui-fieldLayout-field {
-  width: 60%;
+.oo-ui-fieldLayout.oo-ui-labelElement > .oo-ui-fieldLayout-body > .oo-ui-labelElement-label {
+  padding-bottom: 0.3125em;
 }
-.oo-ui-fieldLayout.oo-ui-fieldLayout-align-inline {
-  margin-bottom: 1.25em;
+.oo-ui-fieldLayout.oo-ui-labelElement.oo-ui-fieldLayout-align-inline > .oo-ui-fieldLayout-body > .oo-ui-labelElement-label {
+  padding: 0.3125em 0.46875em;
+}
+.oo-ui-fieldLayout.oo-ui-labelElement.oo-ui-fieldLayout-align-left > .oo-ui-fieldLayout-body > .oo-ui-labelElement-label,
+.oo-ui-fieldLayout.oo-ui-labelElement.oo-ui-fieldLayout-align-right > .oo-ui-fieldLayout-body > .oo-ui-labelElement-label {
+  width: 35%;
+  margin-right: 5%;
+  padding-top: 0.3125em;
 }
-.oo-ui-fieldLayout.oo-ui-fieldLayout-align-inline.oo-ui-labelElement > .oo-ui-fieldLayout-body > .oo-ui-labelElement-label {
-  padding: 0.25em 0.25em 0.25em 0.5em;
+.oo-ui-fieldLayout.oo-ui-labelElement.oo-ui-fieldLayout-align-left > .oo-ui-fieldLayout-body > .oo-ui-fieldLayout-field,
+.oo-ui-fieldLayout.oo-ui-labelElement.oo-ui-fieldLayout-align-right > .oo-ui-fieldLayout-body > .oo-ui-fieldLayout-field {
+  width: 60%;
 }
-.oo-ui-fieldLayout.oo-ui-fieldLayout-align-top.oo-ui-labelElement > .oo-ui-fieldLayout-body > .oo-ui-labelElement-label {
-  padding-top: 0.25em;
-  padding-bottom: 0.5em;
+.oo-ui-fieldLayout-disabled > .oo-ui-fieldLayout-body > .oo-ui-labelElement-label {
+  color: #72777d;
 }
 .oo-ui-fieldLayout > .oo-ui-popupButtonWidget {
   margin-right: 0;
 .oo-ui-fieldLayout > .oo-ui-popupButtonWidget:last-child {
   margin-right: 0;
 }
-.oo-ui-fieldLayout-disabled > .oo-ui-fieldLayout-body > .oo-ui-labelElement-label {
-  color: #72777d;
-}
 .oo-ui-fieldLayout-messages {
   list-style: none none;
   margin: 0.25em 0 0 0.25em;
 }
 .oo-ui-fieldLayout-messages .oo-ui-iconWidget {
   display: table-cell;
-  border-right: 0.5em solid transparent;
 }
 .oo-ui-fieldLayout-messages .oo-ui-labelWidget {
   display: table-cell;
-  padding: 0.1em 0;
+  padding: 0.1em 0 0.1em 0.3125em;
   line-height: 1.5;
   vertical-align: middle;
 }
@@ -552,7 +553,7 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout {
   margin-top: 2em;
 }
 .oo-ui-fieldsetLayout.oo-ui-labelElement > .oo-ui-labelElement-label {
-  margin-bottom: 0.5em;
+  margin-bottom: 0.56818em;
   font-size: 1.1em;
   font-weight: bold;
 }
@@ -687,7 +688,7 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout {
   background-color: transparent;
 }
 .oo-ui-radioOptionWidget.oo-ui-labelElement .oo-ui-labelElement-label {
-  padding: 0.25em 0.25em 0.25em 0.5em;
+  padding: 0.25em 0.25em 0.25em 0.46875em;
 }
 .oo-ui-radioOptionWidget .oo-ui-radioInputWidget {
   margin-right: 0;
@@ -1469,12 +1470,17 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout {
 }
 .oo-ui-dropdownWidget.oo-ui-widget-enabled .oo-ui-dropdownWidget-handle:hover {
   background-color: #fff;
+  color: #444;
   border-color: #a2a9b1;
 }
 .oo-ui-dropdownWidget.oo-ui-widget-enabled .oo-ui-dropdownWidget-handle:hover .oo-ui-iconElement-icon,
 .oo-ui-dropdownWidget.oo-ui-widget-enabled .oo-ui-dropdownWidget-handle:hover .oo-ui-indicatorElement-indicator {
   opacity: 0.73;
 }
+.oo-ui-dropdownWidget.oo-ui-widget-enabled .oo-ui-dropdownWidget-handle:active {
+  color: #000;
+  border-color: #72777d;
+}
 .oo-ui-dropdownWidget.oo-ui-widget-enabled .oo-ui-dropdownWidget-handle:focus {
   border-color: #36c;
   outline: 0;
@@ -1610,7 +1616,7 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout {
   vertical-align: middle;
 }
 .oo-ui-checkboxMultioptionWidget.oo-ui-labelElement .oo-ui-labelElement-label {
-  padding: 0.25em 0.25em 0.25em 0.5em;
+  padding: 0.25em 0.25em 0.25em 0.46875em;
 }
 .oo-ui-checkboxMultioptionWidget .oo-ui-checkboxInputWidget {
   margin-right: 0;
index fd4e033..66dfbe8 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOjs UI v0.18.0
+ * OOjs UI v0.18.1
  * https://www.mediawiki.org/wiki/OOjs_UI
  *
  * Copyright 2011–2016 OOjs UI Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2016-11-09T00:52:37Z
+ * Date: 2016-11-29T22:57:37Z
  */
 ( function ( OO ) {
 
@@ -414,7 +414,7 @@ OO.ui.infuse = function ( idOrNode ) {
                }
                return message;
        };
-} )();
+}() );
 
 /**
  * Package a message and arguments for deferred resolution.
@@ -4308,8 +4308,7 @@ OO.mixinClass( OO.ui.PopupWidget, OO.ui.mixin.ClippableElement );
 OO.ui.PopupWidget.prototype.onMouseDown = function ( e ) {
        if (
                this.isVisible() &&
-               !$.contains( this.$element[ 0 ], e.target ) &&
-               ( !this.$autoCloseIgnore || !this.$autoCloseIgnore.has( e.target ).length )
+               !OO.ui.contains( this.$element.add( this.$autoCloseIgnore ).get(), e.target, true )
        ) {
                this.toggle( false );
        }
@@ -4597,7 +4596,7 @@ OO.ui.mixin.PopupElement = function OoUiMixinPopupElement( config ) {
        this.popup = new OO.ui.PopupWidget( $.extend(
                { autoClose: true },
                config.popup,
-               { $autoCloseIgnore: this.$element }
+               { $autoCloseIgnore: this.$element.add( config.popup && config.popup.$autoCloseIgnore ) }
        ) );
 };
 
@@ -9797,7 +9796,7 @@ OO.ui.ComboBoxInputWidget.prototype.setOptions = function ( options ) {
  * @throws {Error} An error is thrown if no widget is specified
  */
 OO.ui.FieldLayout = function OoUiFieldLayout( fieldWidget, config ) {
-       var hasInputWidget, div;
+       var hasInputWidget, $div;
 
        // Allow passing positional parameters inside the config object
        if ( OO.isPlainObject( fieldWidget ) && config === undefined ) {
@@ -9837,14 +9836,14 @@ OO.ui.FieldLayout = function OoUiFieldLayout( fieldWidget, config ) {
                        icon: 'info'
                } );
 
-               div = $( '<div>' );
+               $div = $( '<div>' );
                if ( config.help instanceof OO.ui.HtmlSnippet ) {
-                       div.html( config.help.toString() );
+                       $div.html( config.help.toString() );
                } else {
-                       div.text( config.help );
+                       $div.text( config.help );
                }
                this.popupButtonWidget.getPopup().$body.append(
-                       div.addClass( 'oo-ui-fieldLayout-help-content' )
+                       $div.addClass( 'oo-ui-fieldLayout-help-content' )
                );
                this.$help = this.popupButtonWidget.$element;
        } else {
@@ -10138,8 +10137,13 @@ OO.inheritClass( OO.ui.ActionFieldLayout, OO.ui.FieldLayout );
  * @constructor
  * @param {Object} [config] Configuration options
  * @cfg {OO.ui.FieldLayout[]} [items] An array of fields to add to the fieldset. See OO.ui.FieldLayout for more information about fields.
+ * @cfg {string|OO.ui.HtmlSnippet} [help] Help text. When help text is specified, a "help" icon will appear
+ *  in the upper-right corner of the rendered field; clicking it will display the text in a popup.
+ *  For important messages, you are advised to use `notices`, as they are always shown.
  */
 OO.ui.FieldsetLayout = function OoUiFieldsetLayout( config ) {
+       var $div;
+
        // Configuration initialization
        config = config || {};
 
@@ -10158,10 +10162,14 @@ OO.ui.FieldsetLayout = function OoUiFieldsetLayout( config ) {
                        icon: 'info'
                } );
 
+               $div = $( '<div>' );
+               if ( config.help instanceof OO.ui.HtmlSnippet ) {
+                       $div.html( config.help.toString() );
+               } else {
+                       $div.text( config.help );
+               }
                this.popupButtonWidget.getPopup().$body.append(
-                       $( '<div>' )
-                               .text( config.help )
-                               .addClass( 'oo-ui-fieldsetLayout-help-content' )
+                       $div.addClass( 'oo-ui-fieldsetLayout-help-content' )
                );
                this.$help = this.popupButtonWidget.$element;
        } else {
index 17bca7e..962db9a 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOjs UI v0.18.0
+ * OOjs UI v0.18.1
  * https://www.mediawiki.org/wiki/OOjs_UI
  *
  * Copyright 2011–2016 OOjs UI Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2016-11-09T00:52:37Z
+ * Date: 2016-11-29T22:57:37Z
  */
 ( function ( OO ) {
 
index 7fb36c4..4b59876 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOjs UI v0.18.0
+ * OOjs UI v0.18.1
  * https://www.mediawiki.org/wiki/OOjs_UI
  *
  * Copyright 2011–2016 OOjs UI Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2016-11-09T00:52:42Z
+ * Date: 2016-11-29T22:57:42Z
  */
 .oo-ui-popupTool .oo-ui-popupWidget-popup,
 .oo-ui-popupTool .oo-ui-popupWidget-anchor {
index cb9660a..c3b0c98 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOjs UI v0.18.0
+ * OOjs UI v0.18.1
  * https://www.mediawiki.org/wiki/OOjs_UI
  *
  * Copyright 2011–2016 OOjs UI Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2016-11-09T00:52:42Z
+ * Date: 2016-11-29T22:57:42Z
  */
 .oo-ui-tool.oo-ui-widget-enabled {
   -webkit-transition: background-color 100ms;
index e17f511..f57e2db 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOjs UI v0.18.0
+ * OOjs UI v0.18.1
  * https://www.mediawiki.org/wiki/OOjs_UI
  *
  * Copyright 2011–2016 OOjs UI Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2016-11-09T00:52:37Z
+ * Date: 2016-11-29T22:57:37Z
  */
 ( function ( OO ) {
 
index d6ba00b..884e48e 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOjs UI v0.18.0
+ * OOjs UI v0.18.1
  * https://www.mediawiki.org/wiki/OOjs_UI
  *
  * Copyright 2011–2016 OOjs UI Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2016-11-09T00:52:42Z
+ * Date: 2016-11-29T22:57:42Z
  */
 .oo-ui-draggableElement-handle,
 .oo-ui-draggableElement-handle.oo-ui-widget {
index bf50532..cfbea3e 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOjs UI v0.18.0
+ * OOjs UI v0.18.1
  * https://www.mediawiki.org/wiki/OOjs_UI
  *
  * Copyright 2011–2016 OOjs UI Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2016-11-09T00:52:42Z
+ * Date: 2016-11-29T22:57:42Z
  */
 .oo-ui-draggableElement-handle,
 .oo-ui-draggableElement-handle.oo-ui-widget {
 .oo-ui-capsuleMultiselectWidget-handle > .oo-ui-iconElement-icon {
   position: absolute;
 }
+.oo-ui-capsuleMultiselectWidget-handle > .oo-ui-capsuleMultiselectWidget-content :-moz-placeholder {
+  color: #72777d;
+  opacity: 1;
+}
+.oo-ui-capsuleMultiselectWidget-handle > .oo-ui-capsuleMultiselectWidget-content ::-moz-placeholder {
+  color: #72777d;
+  opacity: 1;
+}
+.oo-ui-capsuleMultiselectWidget-handle > .oo-ui-capsuleMultiselectWidget-content :-ms-input-placeholder {
+  color: #72777d;
+}
+.oo-ui-capsuleMultiselectWidget-handle > .oo-ui-capsuleMultiselectWidget-content ::-webkit-input-placeholder {
+  color: #72777d;
+}
+.oo-ui-capsuleMultiselectWidget-handle > .oo-ui-capsuleMultiselectWidget-content :placeholder-shown {
+  color: #72777d;
+}
 .oo-ui-capsuleMultiselectWidget-handle > .oo-ui-capsuleMultiselectWidget-content > input {
   border: 0;
   line-height: 1.675;
index 6962c92..8242c86 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOjs UI v0.18.0
+ * OOjs UI v0.18.1
  * https://www.mediawiki.org/wiki/OOjs_UI
  *
  * Copyright 2011–2016 OOjs UI Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2016-11-09T00:52:37Z
+ * Date: 2016-11-29T22:57:37Z
  */
 ( function ( OO ) {
 
@@ -4074,8 +4074,7 @@ OO.ui.CapsuleMultiselectWidget.prototype.onPopupFocusOut = function () {
        setTimeout( function () {
                if (
                        widget.isVisible() &&
-                       !OO.ui.contains( widget.$element[ 0 ], document.activeElement, true ) &&
-                       ( !widget.$autoCloseIgnore || !widget.$autoCloseIgnore.has( document.activeElement ).length )
+                       !OO.ui.contains( widget.$element.add( widget.$autoCloseIgnore ).get(), document.activeElement, true )
                ) {
                        widget.toggle( false );
                }
index 6258b84..40de1d7 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOjs UI v0.18.0
+ * OOjs UI v0.18.1
  * https://www.mediawiki.org/wiki/OOjs_UI
  *
  * Copyright 2011–2016 OOjs UI Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2016-11-09T00:52:42Z
+ * Date: 2016-11-29T22:57:42Z
  */
 .oo-ui-actionWidget.oo-ui-pendingElement-pending {
   background-image: /* @embed */ url(themes/apex/images/textures/pending.gif);
index 359c469..d1b35e8 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOjs UI v0.18.0
+ * OOjs UI v0.18.1
  * https://www.mediawiki.org/wiki/OOjs_UI
  *
  * Copyright 2011–2016 OOjs UI Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2016-11-09T00:52:42Z
+ * Date: 2016-11-29T22:57:42Z
  */
 .oo-ui-window {
   background: transparent;
index 8b614c6..f6e2a39 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOjs UI v0.18.0
+ * OOjs UI v0.18.1
  * https://www.mediawiki.org/wiki/OOjs_UI
  *
  * Copyright 2011–2016 OOjs UI Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2016-11-09T00:52:37Z
+ * Date: 2016-11-29T22:57:37Z
  */
 ( function ( OO ) {
 
@@ -1286,7 +1286,8 @@ OO.ui.WindowManager.prototype.getCurrentWindow = function () {
  *
  * @param {OO.ui.Window|string} win Window object or symbolic name of window to open
  * @param {Object} [data] Window opening data
- * @param {jQuery} [data.$returnFocusTo] Element to which the window will return focus when closed.
+ * @param {jQuery|null} [data.$returnFocusTo] Element to which the window will return focus when closed.
+ *  Defaults the current activeElement. If set to null, focus isn't changed on close.
  * @return {jQuery.Promise} An `opening` promise resolved when the window is done opening.
  *  See {@link #event-opening 'opening' event}  for more information about `opening` promises.
  * @fires opening
@@ -1418,7 +1419,9 @@ OO.ui.WindowManager.prototype.closeWindow = function ( win, data ) {
                                                                manager.toggleGlobalEvents( false );
                                                                manager.toggleAriaIsolation( false );
                                                        }
-                                                       manager.$returnFocusTo[ 0 ].focus();
+                                                       if ( manager.$returnFocusTo && manager.$returnFocusTo.length ) {
+                                                               manager.$returnFocusTo[ 0 ].focus();
+                                                       }
                                                        manager.closing = null;
                                                        manager.currentWindow = null;
                                                        closing.resolve( data );
index f5694a1..e6fa863 100644 (file)
@@ -15,7 +15,7 @@
                        "color": "#36c"
                },
                "destructive": {
-                       "color": "#c33"
+                       "color": "#d33"
                },
                "warning": {
                        "color": "#ff5d00"
index 651cddf..80bbcaf 100644 (file)
@@ -15,7 +15,7 @@
                        "color": "#36c"
                },
                "destructive": {
-                       "color": "#c33"
+                       "color": "#d33"
                },
                "warning": {
                        "color": "#ff5d00"
index 6b9e490..21efb82 100644 (file)
@@ -15,7 +15,7 @@
                        "color": "#36c"
                },
                "destructive": {
-                       "color": "#c33"
+                       "color": "#d33"
                },
                "warning": {
                        "color": "#ff5d00"
index 11fcef7..4515405 100644 (file)
@@ -15,7 +15,7 @@
                        "color": "#36c"
                },
                "destructive": {
-                       "color": "#c33"
+                       "color": "#d33"
                },
                "warning": {
                        "color": "#ff5d00"
index cd4087e..3edb545 100644 (file)
@@ -15,7 +15,7 @@
                        "color": "#36c"
                },
                "destructive": {
-                       "color": "#c33"
+                       "color": "#d33"
                },
                "warning": {
                        "color": "#ff5d00"
index d168364..c97d770 100644 (file)
@@ -15,7 +15,7 @@
                        "color": "#36c"
                },
                "destructive": {
-                       "color": "#c33"
+                       "color": "#d33"
                },
                "warning": {
                        "color": "#ff5d00"
index 7efe531..f110a04 100644 (file)
@@ -15,7 +15,7 @@
                        "color": "#36c"
                },
                "destructive": {
-                       "color": "#c33"
+                       "color": "#d33"
                },
                "warning": {
                        "color": "#ff5d00"
index 765b8fe..6ff4a0e 100644 (file)
@@ -15,7 +15,7 @@
                        "color": "#36c"
                },
                "destructive": {
-                       "color": "#c33"
+                       "color": "#d33"
                },
                "warning": {
                        "color": "#ff5d00"
index c844449..7098f23 100644 (file)
@@ -15,7 +15,7 @@
                        "color": "#36c"
                },
                "destructive": {
-                       "color": "#c33"
+                       "color": "#d33"
                },
                "warning": {
                        "color": "#ff5d00"
index 8c7b845..afdb9e5 100644 (file)
@@ -15,7 +15,7 @@
                        "color": "#36c"
                },
                "destructive": {
-                       "color": "#c33"
+                       "color": "#d33"
                },
                "warning": {
                        "color": "#ff5d00"
index e98012f..3779ae3 100644 (file)
@@ -15,7 +15,7 @@
                        "color": "#36c"
                },
                "destructive": {
-                       "color": "#c33"
+                       "color": "#d33"
                },
                "warning": {
                        "color": "#ff5d00"
index c545a49..059073f 100644 (file)
@@ -15,7 +15,7 @@
                        "color": "#36c"
                },
                "destructive": {
-                       "color": "#c33"
+                       "color": "#d33"
                },
                "warning": {
                        "color": "#ff5d00"
index 39fdda5..5a70c5e 100644 (file)
@@ -15,7 +15,7 @@
                        "color": "#36c"
                },
                "destructive": {
-                       "color": "#c33"
+                       "color": "#d33"
                },
                "warning": {
                        "color": "#ff5d00"
index bac9768..61aec85 100644 (file)
@@ -15,7 +15,7 @@
                        "color": "#36c"
                },
                "destructive": {
-                       "color": "#c33"
+                       "color": "#d33"
                },
                "warning": {
                        "color": "#ff5d00"
index 6a7c565..4666fd1 100644 (file)
@@ -15,7 +15,7 @@
                        "color": "#36c"
                },
                "destructive": {
-                       "color": "#c33"
+                       "color": "#d33"
                },
                "warning": {
                        "color": "#ff5d00"
index 53460be..54b9f62 100644 (file)
Binary files a/resources/lib/oojs-ui/themes/mediawiki/images/icons/block-destructive.png and b/resources/lib/oojs-ui/themes/mediawiki/images/icons/block-destructive.png differ
index abf656f..f01a779 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #c33 }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #d33 }</style>
     <path d="M12 4c-4.4 0-8 3.6-8 8s3.6 8 8 8 8-3.6 8-8-3.6-8-8-8zm5 9H7v-2h10v2z"/>
 </svg>
index 000e529..f574a39 100644 (file)
Binary files a/resources/lib/oojs-ui/themes/mediawiki/images/icons/cancel-destructive.png and b/resources/lib/oojs-ui/themes/mediawiki/images/icons/cancel-destructive.png differ
index b2b0179..3391d4e 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #c33 }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #d33 }</style>
     <g id="cancel">
         <path id="circle-with-strike" d="M12 5.022a6.98 6.98 0 0 0-.003 13.956 6.98 6.98 0 0 0-.002-13.956zM6.885 12c0-1.092.572-3.25.93-2.93l7.113 7.114c.487.525-1.838.93-2.93.93A5.113 5.113 0 0 1 6.884 12zm9.298 2.93L9.07 7.815c-.445-.483 1.837-.93 2.93-.93a5.112 5.112 0 0 1 5.114 5.113c0 1.092-.364 3.542-.93 2.93z"/>
     </g>
index 0cc9169..305f41d 100644 (file)
Binary files a/resources/lib/oojs-ui/themes/mediawiki/images/icons/check-destructive.png and b/resources/lib/oojs-ui/themes/mediawiki/images/icons/check-destructive.png differ
index 7e3dc53..059f0bd 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #c33 }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #d33 }</style>
     <path d="M17 7.5L9.5 15 6 11.5 4.5 13l5 5L20 7.5c-.706-.706-2.294-.706-3 0z" id="check"/>
 </svg>
index 42311de..e16f042 100644 (file)
Binary files a/resources/lib/oojs-ui/themes/mediawiki/images/icons/lock-ltr-destructive.png and b/resources/lib/oojs-ui/themes/mediawiki/images/icons/lock-ltr-destructive.png differ
index a9900c1..2cfa62e 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #c33 }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #d33 }</style>
     <path d="M15 8s0-3-2.5-3S10 8 10 8v1h5zm2 0v1h2v10H9c-1.7 0-3-1.3-3-3V9h2V8s0-5 4.5-5S17 8 17 8z"/>
 </svg>
index 72d6a7b..29cd2b5 100644 (file)
Binary files a/resources/lib/oojs-ui/themes/mediawiki/images/icons/lock-rtl-destructive.png and b/resources/lib/oojs-ui/themes/mediawiki/images/icons/lock-rtl-destructive.png differ
index 2811b25..2daea47 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #c33 }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #d33 }</style>
     <path d="M10 8s0-3 2.5-3S15 8 15 8v1h-5zM8 8v1H6v10h10c1.7 0 3-1.3 3-3V9h-2V8s0-5-4.5-5S8 8 8 8z"/>
 </svg>
index 55ab6c4..cf85c4d 100644 (file)
Binary files a/resources/lib/oojs-ui/themes/mediawiki/images/icons/tag-destructive.png and b/resources/lib/oojs-ui/themes/mediawiki/images/icons/tag-destructive.png differ
index 7048a40..0732f2e 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #c33 }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #d33 }</style>
     <path d="M18.748 11.717a1 1 0 0 1 0 1.414l-4.95 4.95a1 1 0 0 1-1.413 0l-6.01-6.01c-.39-.382-.707-1.15-.707-1.7V6c0-.55.45-1 1-1h4.363c.55 0 1.32.318 1.71.707l6.01 6.01zM8.104 7.457a1.477 1.477 0 0 0 0 2.092 1.49 1.49 0 0 0 2.094 0 1.49 1.49 0 0 0 0-2.1 1.484 1.484 0 0 0-2.094 0z" id="tag"/>
 </svg>
index c1d2a66..c367e77 100644 (file)
Binary files a/resources/lib/oojs-ui/themes/mediawiki/images/icons/trash-destructive.png and b/resources/lib/oojs-ui/themes/mediawiki/images/icons/trash-destructive.png differ
index 3ebc63b..59ad3f2 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #c33 }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #d33 }</style>
     <path d="M6 8c0-1.1.9-2 2-2h2l1-1h2l1 1h2c1.1 0 2 .9 2 2H6zm1 1h10l-1 11H8z"/>
 </svg>
index 8fb039c..2cb27f1 100644 (file)
Binary files a/resources/lib/oojs-ui/themes/mediawiki/images/icons/unLock-ltr-destructive.png and b/resources/lib/oojs-ui/themes/mediawiki/images/icons/unLock-ltr-destructive.png differ
index 7ee7522..d45ebac 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #c33 }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #d33 }</style>
     <path d="M12 9V7s0-5-4.5-5S3 7 3 7h2s0-3 2.5-3S10 7 10 7v2H7v7c0 1.7 1.3 3 3 3h10V9z"/>
 </svg>
index 7c2786d..fac51b9 100644 (file)
Binary files a/resources/lib/oojs-ui/themes/mediawiki/images/icons/unLock-rtl-destructive.png and b/resources/lib/oojs-ui/themes/mediawiki/images/icons/unLock-rtl-destructive.png differ
index a5f2721..5e6d205 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #c33 }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #d33 }</style>
     <path d="M11 9V7s0-5 4.5-5S20 7 20 7h-2s0-3-2.5-3S13 7 13 7v2h3v7c0 1.7-1.3 3-3 3H3V9z"/>
 </svg>
index 349227a..91d0358 100644 (file)
@@ -15,7 +15,7 @@
                        "color": "#36c"
                },
                "destructive": {
-                       "color": "#c33"
+                       "color": "#d33"
                },
                "warning": {
                        "color": "#ff5d00"
index 5b08f95..cad530b 100644 (file)
@@ -10,8 +10,8 @@
 }
 
 #pagehistory li.selected {
-       background-color: #f9f9f9;
-       border: 1px dashed #aaa;
+       background-color: #f8f9fa;
+       border: 1px dashed #a2a9b1;
 }
 
 .mw-history-revisionactions {
index d5520a1..1f0365e 100644 (file)
@@ -46,8 +46,8 @@
  */
 #filetoc {
        text-align: center;
-       border: 1px solid #aaa;
-       background-color: #f9f9f9;
+       border: 1px solid #a2a9b1;
+       background-color: #f8f9fa;
        padding: 5px;
        font-size: 95%;
        margin-bottom: 0.5em;
 
 .mw_metadata td,
 .mw_metadata th {
-       border: 1px solid #aaa;
+       border: 1px solid #a2a9b1;
        padding-left: 5px;
        padding-right: 5px;
 }
 
 .mw_metadata th {
-       background-color: #f9f9f9;
+       background-color: #f8f9fa;
 }
 
 .mw_metadata td {
index 1192650..10ceecc 100644 (file)
                return valueParts.join( options.decimal );
        }
 
+       /**
+        * Helper function to flip transformation tables.
+        *
+        * @param {...Object} Transformation tables
+        * @return {Object}
+        */
+       function flipTransform() {
+               var i, key, table, flipped = {};
+
+               // Ensure we strip thousand separators. This might be overwritten.
+               flipped[ ',' ] = '';
+
+               for ( i = 0; i < arguments.length; i++ ) {
+                       table = arguments[ i ];
+                       for ( key in table ) {
+                               if ( table.hasOwnProperty( key ) ) {
+                                       // The thousand separator should be deleted
+                                       flipped[ table[ key ] ] = key === ',' ? '' : key;
+                               }
+                       }
+               }
+
+               return flipped;
+       }
+
        $.extend( mw.language, {
 
                /**
                 * @return {number|string} Formatted number
                 */
                convertNumber: function ( num, integer ) {
-                       var i, tmp, transformTable, numberString, convertedNumber, pattern;
-
-                       pattern = mw.language.getData( mw.config.get( 'wgUserLanguage' ),
-                               'digitGroupingPattern' ) || '#,##0.###';
+                       var transformTable, digitTransformTable, separatorTransformTable,
+                               i, numberString, convertedNumber, pattern;
 
-                       // Set the target transform table:
-                       transformTable = mw.language.getDigitTransformTable();
-
-                       if ( !transformTable ) {
+                       // Quick shortcut for plain numbers
+                       if ( integer && parseInt( num, 10 ) === num ) {
                                return num;
                        }
 
-                       // Check if the 'restore' to Latin number flag is set:
+                       // Load the transformation tables (can be empty)
+                       digitTransformTable = mw.language.getDigitTransformTable();
+                       separatorTransformTable = mw.language.getSeparatorTransformTable();
+
                        if ( integer ) {
-                               if ( parseInt( num, 10 ) === num ) {
-                                       return num;
-                               }
-                               tmp = [];
-                               for ( i in transformTable ) {
-                                       tmp[ transformTable[ i ] ] = i;
-                               }
-                               transformTable = tmp;
+                               // Reverse the digit transformation tables if we are doing unformatting
+                               transformTable = flipTransform( separatorTransformTable, digitTransformTable );
                                numberString = String( num );
                        } else {
-                               // Ignore transform table if wgTranslateNumerals is false
-                               if ( !mw.config.get( 'wgTranslateNumerals' ) ) {
-                                       transformTable = [];
+                               // This check being here means that digits can still be unformatted
+                               // even if we do not produce them. This seems sane behavior.
+                               if ( mw.config.get( 'wgTranslateNumerals' ) ) {
+                                       transformTable = digitTransformTable;
                                }
+
+                               // Commaying is more complex, so we handle it here separately.
+                               // When unformatting, we just use separatorTransformTable.
+                               pattern = mw.language.getData( mw.config.get( 'wgUserLanguage' ),
+                                       'digitGroupingPattern' ) || '#,##0.###';
                                numberString = mw.language.commafy( num, pattern );
                        }
 
                        convertedNumber = '';
                        for ( i = 0; i < numberString.length; i++ ) {
-                               if ( transformTable[ numberString[ i ] ] ) {
+                               if ( transformTable.hasOwnProperty( numberString[ i ] ) ) {
                                        convertedNumber += transformTable[ numberString[ i ] ];
                                } else {
                                        convertedNumber += numberString[ i ];
                                }
                        }
-                       return integer ? parseInt( convertedNumber, 10 ) : convertedNumber;
+
+                       if ( integer ) {
+                               // Parse string to integer. This loses decimals!
+                               convertedNumber = parseInt( convertedNumber, 10 );
+                       }
+
+                       return convertedNumber;
                },
 
                /**
index 1522de1..59f892e 100644 (file)
@@ -343,8 +343,8 @@ a.new {
  */
 table.wikitable {
        margin: 1em 0;
-       background-color: #f9f9f9;
-       border: 1px solid #aaa;
+       background-color: #f8f9fa;
+       border: 1px solid #a2a9b1;
        border-collapse: collapse;
        color: #000;
 }
@@ -359,7 +359,7 @@ table.wikitable > * > tr > td {
 
 table.wikitable > tr > th,
 table.wikitable > * > tr > th {
-       background-color: #f2f2f2;
+       background-color: #eaecf0;
        text-align: center;
 }
 
index 676ecca..9688f1f 100644 (file)
@@ -26,9 +26,9 @@
 // Orange; for contextual use of returning to a past action
 @colorRegressive: #ff5d00;
 // Red; for contextual use of a negative action of high severity
-@colorDestructive: #c33;
-@colorDestructiveHighlight: #e53939;
-@colorDestructiveActive: #873636;
+@colorDestructive: #d33;
+@colorDestructiveHighlight: #ff4242;
+@colorDestructiveActive: #b32424;
 // Orange; for contextual use of a potentially negative action of medium severity
 @colorMediumSevere: #ff5d00;
 // Yellow; for contextual use of a potentially negative action of low severity
index d4c93fd..e1df01d 100644 (file)
@@ -10,8 +10,8 @@
 .toc,
 .mw-warning,
 .toccolours {
-       border: 1px solid #aaa;
-       background-color: #f9f9f9;
+       border: 1px solid #a2a9b1;
+       background-color: #f8f9fa;
        padding: 5px;
        font-size: 95%;
 }
@@ -147,9 +147,9 @@ div.thumb {
 }
 
 div.thumbinner {
-       border: 1px solid #ccc;
+       border: 1px solid #c8ccd1;
        padding: 3px;
-       background-color: #f9f9f9;
+       background-color: #f8f9fa;
        font-size: 94%;
        text-align: center;
        /* new block formatting context,
@@ -158,7 +158,7 @@ div.thumbinner {
 }
 
 html .thumbimage {
-       border: 1px solid #ccc;
+       border: 1px solid #c8ccd1;
 }
 
 html .thumbcaption {
@@ -199,7 +199,7 @@ div.magnify a {
 }
 
 img.thumbborder {
-       border: 1px solid #ddd;
+       border: 1px solid #eaecf0;
 }
 
 /* Directionality-specific styles for thumbnails - their positioning depends on content language */
index 9c52b2a..33ceb48 100644 (file)
@@ -204,8 +204,8 @@ pre, code, tt, kbd, samp, .mw-code {
 
 code {
        color: #000;
-       background-color: #f9f9f9;
-       border: 1px solid #ddd;
+       background-color: #f8f9fa;
+       border: 1px solid #eaecf0;
        border-radius: 2px;
        padding: 1px 4px;
 }
@@ -213,8 +213,8 @@ code {
 pre,
 .mw-code {
        color: #000;
-       background-color: #f9f9f9;
-       border: 1px solid #ddd;
+       background-color: #f8f9fa;
+       border: 1px solid #eaecf0;
        padding: 1em;
        /* Wrap lines in overflow. T2260, T103780 */
        white-space: pre-wrap;
index 4ca2096..7dbcd4d 100644 (file)
@@ -8,8 +8,8 @@
 
 /* Categories */
 .catlinks {
-       border: 1px solid #aaa;
-       background-color: #f9f9f9;
+       border: 1px solid #a2a9b1;
+       background-color: #f8f9fa;
        padding: 5px;
        margin-top: 1em;
        clear: both;