Merge "Improve HTMLForm (and Special:ChangeCredentials) cancel button"
authorjenkins-bot <jenkins-bot@gerrit.wikimedia.org>
Thu, 2 Jun 2016 20:00:37 +0000 (20:00 +0000)
committerGerrit Code Review <gerrit@wikimedia.org>
Thu, 2 Jun 2016 20:00:37 +0000 (20:00 +0000)
40 files changed:
RELEASE-NOTES-1.28
autoload.php
includes/api/ApiOpenSearch.php
includes/api/ApiQueryPrefixSearch.php
includes/api/ApiQuerySearch.php
includes/api/SearchApi.php [new file with mode: 0644]
includes/api/i18n/ba.json
includes/api/i18n/de.json
includes/api/i18n/en.json
includes/api/i18n/he.json
includes/api/i18n/it.json
includes/api/i18n/qqq.json
includes/auth/AuthManager.php
includes/cache/LinkBatch.php
includes/deferred/LinksDeletionUpdate.php
includes/diff/ComplexityException.php [new file with mode: 0644]
includes/diff/DairikiDiff.php
includes/diff/DiffEngine.php
includes/diff/WordLevelDiff.php
includes/installer/i18n/lv.json
includes/search/SearchEngine.php
includes/specials/SpecialPrefixindex.php
includes/specials/pre-authmanager/SpecialUserlogin.php
languages/i18n/ba.json
languages/i18n/be-tarask.json
languages/i18n/bn.json
languages/i18n/diq.json
languages/i18n/fa.json
languages/i18n/fr.json
languages/i18n/he.json
languages/i18n/hi.json
languages/i18n/ia.json
languages/i18n/ko.json
languages/i18n/map-bms.json
languages/i18n/mk.json
languages/i18n/ps.json
languages/i18n/pt-br.json
languages/i18n/ru.json
resources/src/mediawiki/mediawiki.jqueryMsg.js
tests/phpunit/includes/auth/AuthManagerTest.php

index 6348ac3..a650a50 100644 (file)
@@ -43,7 +43,7 @@ regularly. Below only new and removed languages are listed, as well as
 changes to languages because of Phabricator reports.
 
 === Other changes in 1.28 ===
-
+* (T128697) Improved handling of large diffs.
 
 == Compatibility ==
 
index b7e3419..27da2ca 100644 (file)
@@ -830,6 +830,7 @@ $wgAutoloadLocalClasses = [
        'MediaWiki\\Auth\\Throttler' => __DIR__ . '/includes/auth/Throttler.php',
        'MediaWiki\\Auth\\UserDataAuthenticationRequest' => __DIR__ . '/includes/auth/UserDataAuthenticationRequest.php',
        'MediaWiki\\Auth\\UsernameAuthenticationRequest' => __DIR__ . '/includes/auth/UsernameAuthenticationRequest.php',
+       'MediaWiki\\Diff\\ComplexityException' => __DIR__ . '/includes/diff/ComplexityException.php',
        'MediaWiki\\Diff\\WordAccumulator' => __DIR__ . '/includes/diff/WordAccumulator.php',
        'MediaWiki\\Interwiki\\ClassicInterwikiLookup' => __DIR__ . '/includes/interwiki/ClassicInterwikiLookup.php',
        'MediaWiki\\Interwiki\\InterwikiLookup' => __DIR__ . '/includes/interwiki/InterwikiLookup.php',
@@ -1198,6 +1199,7 @@ $wgAutoloadLocalClasses = [
        'SavepointPostgres' => __DIR__ . '/includes/db/DatabasePostgres.php',
        'ScopedCallback' => __DIR__ . '/includes/libs/ScopedCallback.php',
        'ScopedLock' => __DIR__ . '/includes/filebackend/lockmanager/ScopedLock.php',
+       'SearchApi' => __DIR__ . '/includes/api/SearchApi.php',
        'SearchDatabase' => __DIR__ . '/includes/search/SearchDatabase.php',
        'SearchDump' => __DIR__ . '/maintenance/dumpIterator.php',
        'SearchEngine' => __DIR__ . '/includes/search/SearchEngine.php',
index 058e0a3..066aaa3 100644 (file)
@@ -30,10 +30,14 @@ use MediaWiki\MediaWikiServices;
  * @ingroup API
  */
 class ApiOpenSearch extends ApiBase {
+       use SearchApi;
 
        private $format = null;
        private $fm = null;
 
+       /** @var array list of api allowed params */
+       private $allowedParams = null;
+
        /**
         * Get the output format
         *
@@ -80,24 +84,13 @@ class ApiOpenSearch extends ApiBase {
        public function execute() {
                $params = $this->extractRequestParams();
                $search = $params['search'];
-               $limit = $params['limit'];
-               $namespaces = $params['namespace'];
                $suggest = $params['suggest'];
-
-               if ( $params['redirects'] === null ) {
-                       // Backwards compatibility, don't resolve for JSON.
-                       $resolveRedir = $this->getFormat() !== 'json';
-               } else {
-                       $resolveRedir = $params['redirects'] === 'resolve';
-               }
-
                $results = [];
-
                if ( !$suggest || $this->getConfig()->get( 'EnableOpenSearchSuggest' ) ) {
                        // Open search results may be stored for a very long time
                        $this->getMain()->setCacheMaxAge( $this->getConfig()->get( 'SearchSuggestCacheExpiry' ) );
                        $this->getMain()->setCacheMode( 'public' );
-                       $this->search( $search, $limit, $namespaces, $resolveRedir, $results );
+                       $results = $this->search( $search, $params );
 
                        // Allow hooks to populate extracts and images
                        Hooks::run( 'ApiOpenSearchSuggest', [ &$results ] );
@@ -117,21 +110,17 @@ class ApiOpenSearch extends ApiBase {
 
        /**
         * Perform the search
-        *
-        * @param string $search Text to search
-        * @param int $limit Maximum items to return
-        * @param array $namespaces Namespaces to search
-        * @param bool $resolveRedir Whether to resolve redirects
-        * @param array &$results Put results here. Keys have to be integers.
+        * @param string $search the search query
+        * @param array $params api request params
+        * @return array search results. Keys are integers.
         */
-       protected function search( $search, $limit, $namespaces, $resolveRedir, &$results ) {
-               $searchEngine = MediaWikiServices::getInstance()->newSearchEngine();
-               $searchEngine->setLimitOffset( $limit );
-               $searchEngine->setNamespaces( $namespaces );
+       private function search( $search, array $params ) {
+               $searchEngine = $this->buildSearchEngine( $params );
                $titles = $searchEngine->extractTitles( $searchEngine->completionSearchWithVariants( $search ) );
+               $results = [];
 
                if ( !$titles ) {
-                       return;
+                       return $results;
                }
 
                // Special pages need unique integer ids in the return list, so we just
@@ -139,6 +128,13 @@ class ApiOpenSearch extends ApiBase {
                // always positive articleIds that non-special pages get.
                $nextSpecialPageId = -1;
 
+               if ( $params['redirects'] === null ) {
+                       // Backwards compatibility, don't resolve for JSON.
+                       $resolveRedir = $this->getFormat() !== 'json';
+               } else {
+                       $resolveRedir = $params['redirects'] === 'resolve';
+               }
+
                if ( $resolveRedir ) {
                        // Query for redirects
                        $redirects = [];
@@ -206,6 +202,8 @@ class ApiOpenSearch extends ApiBase {
                                ];
                        }
                }
+
+               return $results;
        }
 
        /**
@@ -271,7 +269,10 @@ class ApiOpenSearch extends ApiBase {
        }
 
        public function getAllowedParams() {
-               return [
+               if ( $this->allowedParams !== null ) {
+                       return $this->allowedParams;
+               }
+               $this->allowedParams = [
                        'search' => null,
                        'limit' => [
                                ApiBase::PARAM_DFLT => $this->getConfig()->get( 'OpenSearchDefaultLimit' ),
@@ -295,6 +296,20 @@ class ApiOpenSearch extends ApiBase {
                        ],
                        'warningsaserror' => false,
                ];
+
+               $profileParam = $this->buildProfileApiParam( SearchEngine::COMPLETION_PROFILE_TYPE,
+                       'apihelp-query+prefixsearch-param-profile' );
+               if ( $profileParam ) {
+                       $this->allowedParams['profile'] = $profileParam;
+               }
+               return $this->allowedParams;
+       }
+
+       public function getSearchProfileParams() {
+               if ( isset( $this->getAllowedParams()['profile'] ) ) {
+                       return [ SearchEngine::COMPLETION_PROFILE_TYPE => 'profile' ];
+               }
+               return [];
        }
 
        protected function getExamplesMessages() {
index 5c50273..46538e0 100644 (file)
@@ -25,6 +25,11 @@ use MediaWiki\MediaWikiServices;
  * @ingroup API
  */
 class ApiQueryPrefixSearch extends ApiQueryGeneratorBase {
+       use SearchApi;
+
+       /** @var array list of api allowed params */
+       private $allowedParams;
+
        public function __construct( $query, $moduleName ) {
                parent::__construct( $query, $moduleName, 'ps' );
        }
@@ -44,12 +49,9 @@ class ApiQueryPrefixSearch extends ApiQueryGeneratorBase {
                $params = $this->extractRequestParams();
                $search = $params['search'];
                $limit = $params['limit'];
-               $namespaces = $params['namespace'];
                $offset = $params['offset'];
 
-               $searchEngine = MediaWikiServices::getInstance()->newSearchEngine();
-               $searchEngine->setLimitOffset( $limit + 1, $offset );
-               $searchEngine->setNamespaces( $namespaces );
+               $searchEngine = $this->buildSearchEngine( $params );
                $titles = $searchEngine->extractTitles( $searchEngine->completionSearchWithVariants( $search ) );
 
                if ( $resultPageSet ) {
@@ -60,7 +62,7 @@ class ApiQueryPrefixSearch extends ApiQueryGeneratorBase {
                                return $current;
                        } );
                        if ( count( $titles ) > $limit ) {
-                               $this->setContinueEnumParameter( 'offset', $offset + $params['limit'] );
+                               $this->setContinueEnumParameter( 'offset', $offset + $limit );
                                array_pop( $titles );
                        }
                        $resultPageSet->populateFromTitles( $titles );
@@ -72,7 +74,7 @@ class ApiQueryPrefixSearch extends ApiQueryGeneratorBase {
                        $count = 0;
                        foreach ( $titles as $title ) {
                                if ( ++$count > $limit ) {
-                                       $this->setContinueEnumParameter( 'offset', $offset + $params['limit'] );
+                                       $this->setContinueEnumParameter( 'offset', $offset + $limit );
                                        break;
                                }
                                $vals = [
@@ -101,29 +103,45 @@ class ApiQueryPrefixSearch extends ApiQueryGeneratorBase {
        }
 
        public function getAllowedParams() {
-                       return [
-                               'search' => [
-                                       ApiBase::PARAM_TYPE => 'string',
-                                       ApiBase::PARAM_REQUIRED => true,
-                               ],
-                               'namespace' => [
-                                       ApiBase::PARAM_DFLT => NS_MAIN,
-                                       ApiBase::PARAM_TYPE => 'namespace',
-                                       ApiBase::PARAM_ISMULTI => true,
-                               ],
-                               'limit' => [
-                                       ApiBase::PARAM_DFLT => 10,
-                                       ApiBase::PARAM_TYPE => 'limit',
-                                       ApiBase::PARAM_MIN => 1,
-                                       // Non-standard value for compatibility with action=opensearch
-                                       ApiBase::PARAM_MAX => 100,
-                                       ApiBase::PARAM_MAX2 => 200,
-                               ],
-                               'offset' => [
-                                       ApiBase::PARAM_DFLT => 0,
-                                       ApiBase::PARAM_TYPE => 'integer',
-                               ],
-                       ];
+               if ( $this->allowedParams !== null ) {
+                       return $this->allowedParams;
+               }
+               $this->allowedParams = [
+                       'search' => [
+                               ApiBase::PARAM_TYPE => 'string',
+                               ApiBase::PARAM_REQUIRED => true,
+                       ],
+                       'namespace' => [
+                               ApiBase::PARAM_DFLT => NS_MAIN,
+                               ApiBase::PARAM_TYPE => 'namespace',
+                               ApiBase::PARAM_ISMULTI => true,
+                       ],
+                       'limit' => [
+                               ApiBase::PARAM_DFLT => 10,
+                               ApiBase::PARAM_TYPE => 'limit',
+                               ApiBase::PARAM_MIN => 1,
+                               // Non-standard value for compatibility with action=opensearch
+                               ApiBase::PARAM_MAX => 100,
+                               ApiBase::PARAM_MAX2 => 200,
+                       ],
+                       'offset' => [
+                               ApiBase::PARAM_DFLT => 0,
+                               ApiBase::PARAM_TYPE => 'integer',
+                       ],
+               ];
+               $profileParam = $this->buildProfileApiParam( SearchEngine::COMPLETION_PROFILE_TYPE,
+                       'apihelp-query+prefixsearch-param-profile' );
+               if ( $profileParam ) {
+                       $this->allowedParams['profile'] = $profileParam;
+               }
+               return $this->allowedParams;
+       }
+
+       public function getSearchProfileParams() {
+               if ( isset( $this->getAllowedParams()['profile'] ) ) {
+                       return [ SearchEngine::COMPLETION_PROFILE_TYPE => 'profile' ];
+               }
+               return [];
        }
 
        protected function getExamplesMessages() {
index f57d3a3..80798a1 100644 (file)
@@ -32,6 +32,10 @@ use MediaWiki\MediaWikiServices;
  * @ingroup API
  */
 class ApiQuerySearch extends ApiQueryGeneratorBase {
+       use SearchApi;
+
+       /** @var array list of api allowed params */
+       private $allowedParams;
 
        /**
         * When $wgSearchType is null, $wgSearchAlternatives[0] is null. Null isn't
@@ -61,8 +65,11 @@ class ApiQuerySearch extends ApiQueryGeneratorBase {
                global $wgContLang;
                $params = $this->extractRequestParams();
 
+               if ( isset( $params['backend'] ) && $params['backend'] == self::BACKEND_NULL_PARAM ) {
+                       unset( $params['backend'] );
+               }
+
                // Extract parameters
-               $limit = $params['limit'];
                $query = $params['search'];
                $what = $params['what'];
                $interwiki = $params['interwiki'];
@@ -80,11 +87,7 @@ class ApiQuerySearch extends ApiQueryGeneratorBase {
                }
 
                // Create search engine instance and set options
-               $type = isset( $params['backend'] ) && $params['backend'] != self::BACKEND_NULL_PARAM ?
-                       $params['backend'] : null;
-               $search = MediaWikiServices::getInstance()->getSearchEngineFactory()->create( $type );
-               $search->setLimitOffset( $limit + 1, $params['offset'] );
-               $search->setNamespaces( $params['namespace'] );
+               $search = $this->buildSearchEngine( $params );
                $search->setFeatureData( 'rewrite', (bool)$params['enablerewrites'] );
 
                $query = $search->transformSearchTerm( $query );
@@ -152,6 +155,7 @@ class ApiQuerySearch extends ApiQueryGeneratorBase {
                $titles = [];
                $count = 0;
                $result = $matches->next();
+               $limit = $params['limit'];
 
                while ( $result ) {
                        if ( ++$count > $limit ) {
@@ -301,7 +305,11 @@ class ApiQuerySearch extends ApiQueryGeneratorBase {
        }
 
        public function getAllowedParams() {
-               $params = [
+               if ( $this->allowedParams !== null ) {
+                       return $this->allowedParams;
+               }
+
+               $this->allowedParams = [
                        'search' => [
                                ApiBase::PARAM_TYPE => 'string',
                                ApiBase::PARAM_REQUIRED => true
@@ -368,13 +376,31 @@ class ApiQuerySearch extends ApiQueryGeneratorBase {
                        if ( $alternatives[0] === null ) {
                                $alternatives[0] = self::BACKEND_NULL_PARAM;
                        }
-                       $params['backend'] = [
+                       $this->allowedParams['backend'] = [
                                ApiBase::PARAM_DFLT => $searchConfig->getSearchType(),
                                ApiBase::PARAM_TYPE => $alternatives,
                        ];
+                       // @todo: support profile selection when multiple
+                       // backends are available. The solution could be to
+                       // merge all possible profiles and let ApiBase
+                       // subclasses do the check. Making ApiHelp and ApiSandbox
+                       // comprehensive might be more difficult.
+               } else {
+                       $profileParam = $this->buildProfileApiParam( SearchEngine::FT_QUERY_INDEP_PROFILE_TYPE,
+                               'apihelp-query+search-param-qiprofile' );
+                       if ( $profileParam ) {
+                               $this->allowedParams['qiprofile'] = $profileParam;
+                       }
                }
 
-               return $params;
+               return $this->allowedParams;
+       }
+
+       public function getSearchProfileParams() {
+               if ( isset( $this->getAllowedParams()['qiprofile'] ) ) {
+                       return [ SearchEngine::FT_QUERY_INDEP_PROFILE_TYPE => 'qiprofile' ];
+               }
+               return [];
        }
 
        protected function getExamplesMessages() {
diff --git a/includes/api/SearchApi.php b/includes/api/SearchApi.php
new file mode 100644 (file)
index 0000000..26d7a0e
--- /dev/null
@@ -0,0 +1,116 @@
+<?php
+use MediaWiki\MediaWikiServices;
+
+/**
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ * @since 1.28
+ */
+
+/**
+ * Traits for API components that use a SearchEngine.
+ * @ingroup API
+ */
+trait SearchApi {
+       /**
+        * Build the profile api param definitions.
+        *
+        * @param string $profileType type of profile to customize
+        * @param string $helpMsg i18n message
+        * @param string|null $backendType SearchEngine backend type or null for default engine
+        * @return array|null the api param definition or null if profiles are
+        * not supported by the searchEngine implementation.
+        */
+       public function buildProfileApiParam( $profileType, $helpMsg, $backendType = null ) {
+               $searchEngine = null;
+               if ( $backendType !== null ) {
+                       $searchEngine = MediaWikiServices::getInstance()
+                               ->getSearchEngineFactory()->create( $backendType );
+               } else {
+                       $searchEngine = MediaWikiServices::getInstance()->newSearchEngine();
+               }
+
+               $profiles = $searchEngine->getProfiles( $profileType );
+               if ( $profiles ) {
+                       $types = [];
+                       $helpMessages = [];
+                       $defaultProfile = null;
+                       foreach ( $profiles as $profile ) {
+                               $types[] = $profile['name'];
+                               if ( isset ( $profile['desc-message'] ) ) {
+                                       $helpMessages[$profile['name']] = $profile['desc-message'];
+                               }
+                               if ( !empty( $profile['default'] ) ) {
+                                       $defaultProfile = $profile['name'];
+                               }
+                       }
+                       return [
+                               ApiBase::PARAM_TYPE => $types,
+                               ApiBase::PARAM_HELP_MSG => $helpMsg,
+                               ApiBase::PARAM_HELP_MSG_PER_VALUE => $helpMessages,
+                               ApiBase::PARAM_DFLT => $defaultProfile,
+                       ];
+               }
+               return null;
+       }
+
+       /**
+        * Build the search engine to use.
+        * If $params is provided then the following searchEngine options
+        * will be set:
+        *  - limit: mandatory
+        *  - offset: optional, if set limit will be incremented by
+        *    one ( to support the continue parameter )
+        *  - namespace: mandatory
+        *  - search engine profiles defined by SearchApi::getSearchProfileParams()
+        * @param string[]|null API request params (must be sanitized by
+        * ApiBase::extractRequestParams() before)
+        * @return SearchEngine the search engine
+        */
+       public function buildSearchEngine( array $params = null ) {
+               if ( $params != null ) {
+                       $type = isset( $params['backend'] ) ? $params['backend'] : null;
+                       $searchEngine = MediaWikiServices::getInstance()->getSearchEngineFactory()->create( $type );
+                       $limit = $params['limit'];
+                       $namespaces = $params['namespace'];
+                       $offset = null;
+                       if ( isset( $params['offset'] ) ) {
+                               // If the API supports offset then it probably
+                               // wants to fetch limit+1 so it can check if
+                               // more results are available to properly set
+                               // the continue param
+                               $offset = $params['offset'];
+                               $limit += 1;
+                       }
+                       $searchEngine->setLimitOffset( $limit, $offset );
+                       foreach ( $this->getSearchProfileParams() as $type => $param ) {
+                               if ( isset( $params[$param] ) ) {
+                                       $searchEngine->setFeatureData( $type, $params[$param] );
+                               }
+                       }
+               } else {
+                       $searchEngine = MediaWikiServices::getInstance()->newSearchEngine();
+               }
+               return $searchEngine;
+       }
+
+       /**
+        * @return string[] the list of supported search profile types. Key is
+        * the profile type and its associated value is the request param.
+        */
+       abstract public function getSearchProfileParams();
+}
index 512ab83..7dcc4fd 100644 (file)
        "apihelp-query+allfileusages-param-dir": "Һанау йүнәлеше.",
        "apihelp-query+allfileusages-example-unique": "Атамаларҙың уҙенсәлекле файлдары исемлеге.",
        "apihelp-query+allfileusages-example-unique-generator": "Төшөп ҡалғандарҙы айырып, барлыҡ исем-һылтанмаларҙы алырға.",
+       "apihelp-query+allfileusages-example-generator": "Һылтанмалы биттәр бар.",
        "apihelp-query+allimages-description": "Бер-бер артлы бөтә образдарҙы һанап сығырға.",
        "apihelp-query+allimages-param-sort": "Сортировкалау үҙенсәлектәре.",
        "apihelp-query+allimages-param-dir": "Һанау йүнәлеше.",
        "apihelp-query+allredirects-param-prefix": "Был мәғәнәнән башланған бар атамаларҙы категориялар буйынса эҙләргә.",
        "apihelp-query+allredirects-param-prop": "Ҡайһы мәғлүмәтте күрһәтергә:",
        "apihelp-query+allredirects-param-namespace": "Һанау өсөн исемдәр арауығы.",
+       "apihelp-query+allredirects-param-limit": "Нисә битте тергеҙергә?",
        "apihelp-query+allredirects-param-dir": "Һанау йүнәлеше.",
        "apihelp-query+allredirects-example-generator": "Һылтанмалы биттәр бар.",
        "apihelp-query+allrevisions-param-start": "Иҫәп күсереү башланған ваҡыт билдәһе",
        "apihelp-query+allrevisions-param-end": "Иҫәп күсереү башланған ваҡыт билдәһе",
        "apihelp-query+allrevisions-param-user": "Бары тик был ҡулланыусының үҙгәртеүҙәр исемлеге.",
        "apihelp-query+allrevisions-param-excludeuser": "Бары тик был ҡулланыусының үҙгәртеүҙәр исемлеге.",
+       "apihelp-query+alltransclusions-param-to": "Һанауҙы туҡтатыу һылтанмаһы атамаһы.",
+       "apihelp-query+alltransclusions-param-prop": "Ҡайһы мәғлүмәтте күрһәтергә:",
+       "apihelp-query+alltransclusions-param-namespace": "Һанау өсөн исемдәр арауығы.",
+       "apihelp-query+alltransclusions-param-limit": "Нисә битте тергеҙергә?",
+       "apihelp-query+alltransclusions-param-dir": "Һанау йүнәлеше.",
        "apihelp-query+alltransclusions-example-generator": "Һылтанмалы биттәр бар.",
        "apihelp-query+allusers-param-from": "Иҫәп күсереү башланған ваҡыт билдәһе",
        "apihelp-query+allusers-param-to": "Иҫәп күсереү башланған ваҡыт билдәһе",
        "apihelp-query+allusers-param-prefix": "Был мәғәнәнән башланған бар атамаларҙы категориялар буйынса эҙләргә.",
+       "apihelp-query+allusers-param-dir": "Сортлау йүнәлештәре.",
        "apihelp-query+allusers-param-prop": "Ҡайһы мәғлүмәтте күрһәтергә:",
        "apihelp-query+backlinks-param-title": "Мөхәриррләү өсөн биттең исеме.<var>$1биттәрҙән</var> бергә файҙаланыу  мөмкин түгел.",
        "apihelp-query+backlinks-param-pageid": "Бит идентифакторын мөхәррирләү өсөн биттәр.  <var>$1title</var> менән бергә ҡулланыла алмайҙар",
index 938a61a..3f90479 100644 (file)
@@ -61,6 +61,7 @@
        "apihelp-compare-param-torev": "Zweite zu vergleichende Version.",
        "apihelp-compare-example-1": "Unterschied zwischen Version 1 und 2 abrufen",
        "apihelp-createaccount-description": "Erstellen eines neuen Benutzerkontos.",
+       "apihelp-createaccount-param-preservestate": "Falls <kbd>[[Special:ApiHelp/query+authmanagerinfo|action=query&meta=authmanagerinfo]]</kbd> für <samp>hasprimarypreservedstate</samp> wahr ausgegeben hat, sollten Anfragen, die als <samp>primary-required</samp> markiert wurden, ausgelassen werden. Falls ein nicht-leerer Wert für <samp>preservedusername</samp> zurückgegeben wurde, muss dieser Benutzername für den Parameter <var>username</var> verwendet werden.",
        "apihelp-createaccount-param-name": "Benutzername.",
        "apihelp-createaccount-param-password": "Passwort (wird ignoriert, wenn <var>$1mailpassword</var> angegeben ist).",
        "apihelp-createaccount-param-domain": "Domain für die externe Authentifizierung (optional).",
index 0f7548b..e4a2c2e 100644 (file)
        "apihelp-query+prefixsearch-param-limit": "Maximum number of results to return.",
        "apihelp-query+prefixsearch-param-offset": "Number of results to skip.",
        "apihelp-query+prefixsearch-example-simple": "Search for page titles beginning with <kbd>meaning</kbd>.",
+       "apihelp-query+prefixsearch-param-profile": "Search profile to use.",
 
        "apihelp-query+protectedtitles-description": "List all titles protected from creation.",
        "apihelp-query+protectedtitles-param-namespace": "Only list titles in these namespaces.",
        "apihelp-query+search-param-what": "Which type of search to perform.",
        "apihelp-query+search-param-info": "Which metadata to return.",
        "apihelp-query+search-param-prop": "Which properties to return:",
+       "apihelp-query+search-param-qiprofile": "Query independent profile to use (affects ranking algorithm).",
        "apihelp-query+search-paramvalue-prop-size": "Adds the size of the page in bytes.",
        "apihelp-query+search-paramvalue-prop-wordcount": "Adds the word count of the page.",
        "apihelp-query+search-paramvalue-prop-timestamp": "Adds the timestamp of when the page was last edited.",
index 080e0dd..ae44a15 100644 (file)
@@ -61,6 +61,7 @@
        "apihelp-compare-param-torev": "גרסה שנייה להשוואה.",
        "apihelp-compare-example-1": "יצירת תיעוד שינוי בין גרסה 1 ל־2.",
        "apihelp-createaccount-description": "יצירת חשבון משתמש חדש.",
+       "apihelp-createaccount-param-preservestate": "אם <kbd>[[Special:ApiHelp/query+authmanagerinfo|action=query&meta=authmanagerinfo]]</kbd> החזיר true עבור <samp>hasprimarypreservedstate</samp>, בקשות שמסומנות בתור <samp>primary-required</samp> אמורות להיות מושמטות. אם מוחזר ערך לא ריק ל־<samp>preservedusername</samp>, שם המשתמש הזה ישמש לפרמטר <var>username</var>.",
        "apihelp-createaccount-example-create": "תחילת תהליך יצירת המשתמש <kbd>Example</kbd> עם הססמה <kbd>ExamplePassword</kbd>.",
        "apihelp-createaccount-param-name": "שם משתמש.",
        "apihelp-createaccount-param-password": "ססמה (לא ישפיע אם הוגדר <var>$1mailpassword</var>).",
index 33e8f5e..47987c5 100644 (file)
@@ -55,6 +55,7 @@
        "apihelp-compare-param-torev": "Seconda revisione da confrontare.",
        "apihelp-compare-example-1": "Crea un diff tra revisione 1 e revisione 2.",
        "apihelp-createaccount-description": "Crea un nuovo account utente.",
+       "apihelp-createaccount-param-preservestate": "Se <kbd>[[Special:ApiHelp/query+authmanagerinfo|action=query&meta=authmanagerinfo]]</kbd> ha restituito true per <samp>hasprimarypreservedstate</samp>, le richieste contrassegnate come <samp>primary-required</samp> dovrebbero essere omesse. Se invece ha restituito un valore non vuoto per <samp>preservedusername</samp>, quel nome utente deve essere utilizzato per il parametro <var>username</var>.",
        "apihelp-createaccount-example-create": "Avvia il processo di creazione utente <kbd>Example</kbd> con password <kbd>ExamplePassword</kbd>.",
        "apihelp-createaccount-param-name": "Nome utente.",
        "apihelp-createaccount-param-password": "Password (verrà ignorata se è impostato <var>$1mailpassword</var>).",
index 991326d..362a473 100644 (file)
        "apihelp-query+prefixsearch-param-limit": "{{doc-apihelp-param|query+prefixsearch|limit}}",
        "apihelp-query+prefixsearch-param-offset": "{{doc-apihelp-param|query+prefixsearch|offset}}",
        "apihelp-query+prefixsearch-example-simple": "{{doc-apihelp-example|query+prefixsearch}}",
+       "apihelp-query+prefixsearch-param-profile": "{{doc-apihelp-param|query+prefixsearch|profile|paramvalues=1}}",
        "apihelp-query+protectedtitles-description": "{{doc-apihelp-description|query+protectedtitles}}",
        "apihelp-query+protectedtitles-param-namespace": "{{doc-apihelp-param|query+protectedtitles|namespace}}",
        "apihelp-query+protectedtitles-param-level": "{{doc-apihelp-param|query+protectedtitles|level}}",
        "apihelp-query+search-param-what": "{{doc-apihelp-param|query+search|what}}",
        "apihelp-query+search-param-info": "{{doc-apihelp-param|query+search|info}}",
        "apihelp-query+search-param-prop": "{{doc-apihelp-param|query+search|prop|paramvalues=1}}",
+       "apihelp-query+search-param-qiprofile": "{{doc-apihelp-param|query+search|qiprofile|paramvalues=1}}",
        "apihelp-query+search-paramvalue-prop-size": "{{doc-apihelp-paramvalue|query+search|prop|size}}",
        "apihelp-query+search-paramvalue-prop-wordcount": "{{doc-apihelp-paramvalue|query+search|prop|wordcount}}",
        "apihelp-query+search-paramvalue-prop-timestamp": "{{doc-apihelp-paramvalue|query+search|prop|timestamp}}",
index 69f51b8..402ea96 100644 (file)
@@ -442,6 +442,7 @@ class AuthManager implements LoggerAwareInterface {
                                                case AuthenticationResponse::REDIRECT;
                                                case AuthenticationResponse::UI;
                                                        $this->logger->debug( "Primary login with $id returned $res->status" );
+                                                       $this->fillRequests( $res->neededRequests, self::ACTION_LOGIN, $guessUserName );
                                                        $state['primary'] = $id;
                                                        $state['continueRequests'] = $res->neededRequests;
                                                        $session->setSecret( 'AuthManager::authnState', $state );
@@ -504,6 +505,7 @@ class AuthManager implements LoggerAwareInterface {
                                        case AuthenticationResponse::REDIRECT;
                                        case AuthenticationResponse::UI;
                                                $this->logger->debug( "Primary login with $id returned $res->status" );
+                                               $this->fillRequests( $res->neededRequests, self::ACTION_LOGIN, $guessUserName );
                                                $state['continueRequests'] = $res->neededRequests;
                                                $session->setSecret( 'AuthManager::authnState', $state );
                                                return $res;
@@ -556,6 +558,7 @@ class AuthManager implements LoggerAwareInterface {
                                        );
                                        $ret->neededRequests[] = $ret->createRequest;
                                }
+                               $this->fillRequests( $ret->neededRequests, self::ACTION_LOGIN, null );
                                $session->setSecret( 'AuthManager::authnState', [
                                        'reqs' => [], // Will be filled in later
                                        'primary' => null,
@@ -625,6 +628,7 @@ class AuthManager implements LoggerAwareInterface {
                                        case AuthenticationResponse::REDIRECT;
                                        case AuthenticationResponse::UI;
                                                $this->logger->debug( "Secondary login with $id returned " . $res->status );
+                                               $this->fillRequests( $res->neededRequests, self::ACTION_LOGIN, $user->getName() );
                                                $state['secondary'][$id] = false;
                                                $state['continueRequests'] = $res->neededRequests;
                                                $session->setSecret( 'AuthManager::authnState', $state );
@@ -1259,6 +1263,7 @@ class AuthManager implements LoggerAwareInterface {
                                                                'user' => $user->getName(),
                                                                'creator' => $creator->getName(),
                                                        ] );
+                                                       $this->fillRequests( $res->neededRequests, self::ACTION_CREATE, null );
                                                        $state['primary'] = $id;
                                                        $state['continueRequests'] = $res->neededRequests;
                                                        $session->setSecret( 'AuthManager::accountCreationState', $state );
@@ -1321,6 +1326,7 @@ class AuthManager implements LoggerAwareInterface {
                                                        'user' => $user->getName(),
                                                        'creator' => $creator->getName(),
                                                ] );
+                                               $this->fillRequests( $res->neededRequests, self::ACTION_CREATE, null );
                                                $state['continueRequests'] = $res->neededRequests;
                                                $session->setSecret( 'AuthManager::accountCreationState', $state );
                                                return $res;
@@ -1416,6 +1422,7 @@ class AuthManager implements LoggerAwareInterface {
                                                        'user' => $user->getName(),
                                                        'creator' => $creator->getName(),
                                                ] );
+                                               $this->fillRequests( $res->neededRequests, self::ACTION_CREATE, null );
                                                $state['secondary'][$id] = false;
                                                $state['continueRequests'] = $res->neededRequests;
                                                $session->setSecret( 'AuthManager::accountCreationState', $state );
@@ -1784,6 +1791,7 @@ class AuthManager implements LoggerAwareInterface {
                                        $this->logger->debug( __METHOD__ . ": Account linking $res->status by $id", [
                                                'user' => $user->getName(),
                                        ] );
+                                       $this->fillRequests( $res->neededRequests, self::ACTION_LINK, $user->getName() );
                                        $state['primary'] = $id;
                                        $state['continueRequests'] = $res->neededRequests;
                                        $session->setSecret( 'AuthManager::accountLinkState', $state );
@@ -1886,6 +1894,7 @@ class AuthManager implements LoggerAwareInterface {
                                        $this->logger->debug( __METHOD__ . ": Account linking $res->status by $id", [
                                                'user' => $user->getName(),
                                        ] );
+                                       $this->fillRequests( $res->neededRequests, self::ACTION_LINK, $user->getName() );
                                        $state['continueRequests'] = $res->neededRequests;
                                        $session->setSecret( 'AuthManager::accountLinkState', $state );
                                        return $res;
@@ -2047,12 +2056,7 @@ class AuthManager implements LoggerAwareInterface {
                }
 
                // Fill in reqs data
-               foreach ( $reqs as $req ) {
-                       $req->action = $providerAction;
-                       if ( $req->username === null ) {
-                               $req->username = $options['username'];
-                       }
-               }
+               $this->fillRequests( $reqs, $providerAction, $options['username'] );
 
                // For self::ACTION_CHANGE, filter out any that something else *doesn't* allow changing
                if ( $providerAction === self::ACTION_CHANGE || $providerAction === self::ACTION_REMOVE ) {
@@ -2064,6 +2068,21 @@ class AuthManager implements LoggerAwareInterface {
                return array_values( $reqs );
        }
 
+       /**
+        * Set values in an array of requests
+        * @param AuthenticationRequest[] &$reqs
+        * @param string $action
+        * @param string|null $username
+        */
+       private function fillRequests( array &$reqs, $action, $username ) {
+               foreach ( $reqs as $req ) {
+                       $req->action = $action;
+                       if ( $req->username === null ) {
+                               $req->username = $username;
+                       }
+               }
+       }
+
        /**
         * Determine whether a username exists
         * @param string $username
@@ -2102,6 +2121,37 @@ class AuthManager implements LoggerAwareInterface {
                return true;
        }
 
+       /**
+        * Get a provider by ID
+        * @note This is public so extensions can check whether their own provider
+        *  is installed and so they can read its configuration if necessary.
+        *  Other uses are not recommended.
+        * @param string $id
+        * @return AuthenticationProvider|null
+        */
+       public function getAuthenticationProvider( $id ) {
+               // Fast version
+               if ( isset( $this->allAuthenticationProviders[$id] ) ) {
+                       return $this->allAuthenticationProviders[$id];
+               }
+
+               // Slow version: instantiate each kind and check
+               $providers = $this->getPrimaryAuthenticationProviders();
+               if ( isset( $providers[$id] ) ) {
+                       return $providers[$id];
+               }
+               $providers = $this->getSecondaryAuthenticationProviders();
+               if ( isset( $providers[$id] ) ) {
+                       return $providers[$id];
+               }
+               $providers = $this->getPreAuthenticationProviders();
+               if ( isset( $providers[$id] ) ) {
+                       return $providers[$id];
+               }
+
+               return null;
+       }
+
        /**@}*/
 
        /**
@@ -2251,34 +2301,6 @@ class AuthManager implements LoggerAwareInterface {
                return $this->secondaryAuthenticationProviders;
        }
 
-       /**
-        * Get a provider by ID
-        * @param string $id
-        * @return AuthenticationProvider|null
-        */
-       protected function getAuthenticationProvider( $id ) {
-               // Fast version
-               if ( isset( $this->allAuthenticationProviders[$id] ) ) {
-                       return $this->allAuthenticationProviders[$id];
-               }
-
-               // Slow version: instantiate each kind and check
-               $providers = $this->getPrimaryAuthenticationProviders();
-               if ( isset( $providers[$id] ) ) {
-                       return $providers[$id];
-               }
-               $providers = $this->getSecondaryAuthenticationProviders();
-               if ( isset( $providers[$id] ) ) {
-                       return $providers[$id];
-               }
-               $providers = $this->getPreAuthenticationProviders();
-               if ( isset( $providers[$id] ) ) {
-                       return $providers[$id];
-               }
-
-               return null;
-       }
-
        /**
         * @param User $user
         * @param bool|null $remember
@@ -2311,7 +2333,7 @@ class AuthManager implements LoggerAwareInterface {
        private function setDefaultUserOptions( User $user, $useContextLang ) {
                global $wgContLang;
 
-               \MediaWiki\Session\SessionManager::singleton()->invalidateSessionsForUser( $user );
+               $user->setToken();
 
                $lang = $useContextLang ? \RequestContext::getMain()->getLanguage() : $wgContLang;
                $user->setOption( 'language', $lang->getPreferredVariant() );
index 04d2524..f48e0a5 100644 (file)
@@ -168,7 +168,7 @@ class LinkBatch {
                // The remaining links in $data are bad links, register them as such
                foreach ( $remaining as $ns => $dbkeys ) {
                        foreach ( $dbkeys as $dbkey => $unused ) {
-                               $title = new TitleValue( (int)$ns, $dbkey );
+                               $title = new TitleValue( (int)$ns, (string)$dbkey );
                                $cache->addBadLinkObj( $title );
                                $pdbk = $titleFormatter->getPrefixedDBkey( $title );
                                $ids[$pdbk] = 0;
index 65a8c0e..d294fd2 100644 (file)
@@ -42,48 +42,95 @@ class LinksDeletionUpdate extends SqlDataUpdate implements EnqueueableDataUpdate
                } elseif ( $pageId ) {
                        $this->pageId = $pageId;
                } else {
-                       throw new MWException( "Page ID not known, perhaps the page doesn't exist?" );
+                       throw new InvalidArgumentException( "Page ID not known. Page doesn't exist?" );
                }
        }
 
        public function doUpdate() {
-               # Page may already be deleted, so don't just getId()
+               $config = RequestContext::getMain()->getConfig();
+               $batchSize = $config->get( 'UpdateRowsPerQuery' );
+
+               // Page may already be deleted, so don't just getId()
                $id = $this->pageId;
                // Make sure all links update threads see the changes of each other.
                // This handles the case when updates have to batched into several COMMITs.
                $scopedLock = LinksUpdate::acquirePageLock( $this->mDb, $id );
 
-               # Delete restrictions for it
+               // Delete restrictions for it
                $this->mDb->delete( 'page_restrictions', [ 'pr_page' => $id ], __METHOD__ );
 
-               # Fix category table counts
+               // Fix category table counts
                $cats = $this->mDb->selectFieldValues(
                        'categorylinks',
                        'cl_to',
                        [ 'cl_from' => $id ],
                        __METHOD__
                );
-               $this->page->updateCategoryCounts( [], $cats );
+               $catBatches = array_chunk( $cats, $batchSize );
+               foreach ( $catBatches as $catBatch ) {
+                       $this->page->updateCategoryCounts( [], $catBatch );
+                       if ( count( $catBatches ) > 1 ) {
+                               $this->mDb->commit( __METHOD__, 'flush' );
+                               wfGetLBFactory()->waitForReplication( [ 'wiki' => $this->mDb->getWikiID() ] );
+                       }
+               }
 
-               # If using cascading deletes, we can skip some explicit deletes
+               // If using cascading deletes, we can skip some explicit deletes
                if ( !$this->mDb->cascadingDeletes() ) {
-                       # Delete outgoing links
-                       $this->mDb->delete( 'pagelinks', [ 'pl_from' => $id ], __METHOD__ );
-                       $this->mDb->delete( 'imagelinks', [ 'il_from' => $id ], __METHOD__ );
-                       $this->mDb->delete( 'categorylinks', [ 'cl_from' => $id ], __METHOD__ );
-                       $this->mDb->delete( 'templatelinks', [ 'tl_from' => $id ], __METHOD__ );
-                       $this->mDb->delete( 'externallinks', [ 'el_from' => $id ], __METHOD__ );
-                       $this->mDb->delete( 'langlinks', [ 'll_from' => $id ], __METHOD__ );
-                       $this->mDb->delete( 'iwlinks', [ 'iwl_from' => $id ], __METHOD__ );
+                       // Delete outgoing links
+                       $this->batchDeleteByPK(
+                               'pagelinks',
+                               [ 'pl_from' => $id ],
+                               [ 'pl_from', 'pl_namespace', 'pl_title' ],
+                               $batchSize
+                       );
+                       $this->batchDeleteByPK(
+                               'imagelinks',
+                               [ 'il_from' => $id ],
+                               [ 'il_from', 'il_to' ],
+                               $batchSize
+                       );
+                       $this->batchDeleteByPK(
+                               'categorylinks',
+                               [ 'cl_from' => $id ],
+                               [ 'cl_from', 'cl_to' ],
+                               $batchSize
+                       );
+                       $this->batchDeleteByPK(
+                               'templatelinks',
+                               [ 'tl_from' => $id ],
+                               [ 'tl_from', 'tl_namespace', 'tl_title' ],
+                               $batchSize
+                       );
+                       $this->batchDeleteByPK(
+                               'externallinks',
+                               [ 'el_from' => $id ],
+                               [ 'el_id' ],
+                               $batchSize
+                       );
+                       $this->batchDeleteByPK(
+                               'langlinks',
+                               [ 'il_from' => $id ],
+                               [ 'il_from', 'll_lang' ],
+                               $batchSize
+                       );
+                       $this->batchDeleteByPK(
+                               'iwlinks',
+                               [ 'il_from' => $id ],
+                               [ 'iwl_from', 'iwl_prefix', 'iwl_title' ],
+                               $batchSize
+                       );
+                       // Delete any redirect entry or page props entries
                        $this->mDb->delete( 'redirect', [ 'rd_from' => $id ], __METHOD__ );
                        $this->mDb->delete( 'page_props', [ 'pp_page' => $id ], __METHOD__ );
                }
 
-               # If using cleanup triggers, we can skip some manual deletes
+               // If using cleanup triggers, we can skip some manual deletes
                if ( !$this->mDb->cleanupTriggers() ) {
                        $title = $this->page->getTitle();
-                       # Find recentchanges entries to clean up...
-                       $rcIdsForTitle = $this->mDb->selectFieldValues( 'recentchanges',
+                       // Find recentchanges entries to clean up...
+                       $rcIdsForTitle = $this->mDb->selectFieldValues(
+                               'recentchanges',
                                'rc_id',
                                [
                                        'rc_type != ' . RC_LOG,
@@ -92,16 +139,21 @@ class LinksDeletionUpdate extends SqlDataUpdate implements EnqueueableDataUpdate
                                ],
                                __METHOD__
                        );
-                       $rcIdsForPage = $this->mDb->selectFieldValues( 'recentchanges',
+                       $rcIdsForPage = $this->mDb->selectFieldValues(
+                               'recentchanges',
                                'rc_id',
                                [ 'rc_type != ' . RC_LOG, 'rc_cur_id' => $id ],
                                __METHOD__
                        );
 
-                       # T98706: delete PK to avoid lock contention with RC delete log insertions
-                       $rcIds = array_merge( $rcIdsForTitle, $rcIdsForPage );
-                       if ( $rcIds ) {
-                               $this->mDb->delete( 'recentchanges', [ 'rc_id' => $rcIds ], __METHOD__ );
+                       // T98706: delete by PK to avoid lock contention with RC delete log insertions
+                       $rcIdBatches = array_chunk( array_merge( $rcIdsForTitle, $rcIdsForPage ), $batchSize );
+                       foreach ( $rcIdBatches as $rcIdBatch ) {
+                               $this->mDb->delete( 'recentchanges', [ 'rc_id' => $rcIdBatch ], __METHOD__ );
+                               if ( count( $rcIdBatches ) > 1 ) {
+                                       $this->mDb->commit( __METHOD__, 'flush' );
+                                       wfGetLBFactory()->waitForReplication( [ 'wiki' => $this->mDb->getWikiID() ] );
+                               }
                        }
                }
 
@@ -111,6 +163,26 @@ class LinksDeletionUpdate extends SqlDataUpdate implements EnqueueableDataUpdate
                } );
        }
 
+       private function batchDeleteByPK( $table, array $conds, array $pk, $bSize ) {
+               $dbw = $this->mDb; // convenience
+               $res = $dbw->select( $table, $pk, $conds, __METHOD__ );
+
+               $pkDeleteConds = [];
+               foreach ( $res as $row ) {
+                       $pkDeleteConds[] = $this->mDb->makeList( (array)$row, LIST_AND );
+                       if ( count( $pkDeleteConds ) >= $bSize ) {
+                               $dbw->delete( $table, $dbw->makeList( $pkDeleteConds, LIST_OR ), __METHOD__ );
+                               $dbw->commit( __METHOD__, 'flush' );
+                               wfGetLBFactory()->waitForReplication( [ 'wiki' => $dbw->getWikiID() ] );
+                               $pkDeleteConds = [];
+                       }
+               }
+
+               if ( $pkDeleteConds ) {
+                       $dbw->delete( $table, $dbw->makeList( $pkDeleteConds, LIST_OR ), __METHOD__ );
+               }
+       }
+
        public function getAsJobSpecification() {
                return [
                        'wiki' => $this->mDb->getWikiID(),
diff --git a/includes/diff/ComplexityException.php b/includes/diff/ComplexityException.php
new file mode 100644 (file)
index 0000000..10ca964
--- /dev/null
@@ -0,0 +1,30 @@
+<?php
+/**
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ * @ingroup DifferenceEngine
+ */
+
+namespace MediaWiki\Diff;
+
+use Exception;
+
+class ComplexityException extends Exception {
+       public function __construct() {
+               parent::__construct( 'Diff is too complex to generate' );
+       }
+}
index dbb32e6..d38319e 100644 (file)
@@ -204,6 +204,12 @@ class Diff {
         */
        public $edits;
 
+       /**
+        * @var int If this diff complexity is exceeded, a ComplexityException is thrown
+        *          0 means no limit.
+        */
+       protected $bailoutComplexity = 0;
+
        /**
         * Constructor.
         * Computes diff between sequences of strings.
@@ -211,9 +217,11 @@ class Diff {
         * @param string[] $from_lines An array of strings.
         *   Typically these are lines from a file.
         * @param string[] $to_lines An array of strings.
+        * @throws \MediaWiki\Diff\ComplexityException
         */
        public function __construct( $from_lines, $to_lines ) {
                $eng = new DiffEngine;
+               $eng->setBailoutComplexity( $this->bailoutComplexity );
                $this->edits = $eng->diff( $from_lines, $to_lines );
        }
 
index 1853b86..babd00b 100644 (file)
@@ -22,6 +22,7 @@
  * @file
  * @ingroup DifferenceEngine
  */
+use MediaWiki\Diff\ComplexityException;
 
 /**
  * This diff implementation is mainly lifted from the LCS algorithm of the Eclipse project which
@@ -51,6 +52,8 @@ class DiffEngine {
        private $tooLong;
        private $powLimit;
 
+       protected $bailoutComplexity = 0;
+
        // State variables
        private $maxDifferences;
        private $lcsLengthCorrectedForHeuristic = false;
@@ -71,6 +74,7 @@ class DiffEngine {
         *
         * @param string[] $from_lines
         * @param string[] $to_lines
+        * @throws ComplexityException
         *
         * @return DiffOp[]
         */
@@ -128,6 +132,14 @@ class DiffEngine {
                return $edits;
        }
 
+       /**
+        * Sets the complexity (in comparison operations) that can't be exceeded
+        * @param int $value
+        */
+       public function setBailoutComplexity( $value ) {
+               $this->bailoutComplexity = $value;
+       }
+
        /**
         * Adjust inserts/deletes of identical lines to join changes
         * as much as possible.
@@ -265,6 +277,7 @@ class DiffEngine {
        /**
         * @param string[] $from
         * @param string[] $to
+        * @throws ComplexityException
         */
        protected function diffInternal( array $from, array $to ) {
                // remember initial lengths
@@ -323,6 +336,10 @@ class DiffEngine {
                $this->m = count( $this->from );
                $this->n = count( $this->to );
 
+               if ( $this->bailoutComplexity > 0 && $this->m * $this->n > $this->bailoutComplexity ) {
+                       throw new ComplexityException();
+               }
+
                $this->removed = $this->m > 0 ? array_fill( 0, $this->m, true ) : [];
                $this->added = $this->n > 0 ? array_fill( 0, $this->n, true ) : [];
 
index 12cf376..296e3b7 100644 (file)
@@ -23,6 +23,7 @@
  * @defgroup DifferenceEngine DifferenceEngine
  */
 
+use MediaWiki\Diff\ComplexityException;
 use MediaWiki\Diff\WordAccumulator;
 
 /**
@@ -31,7 +32,10 @@ use MediaWiki\Diff\WordAccumulator;
  * @ingroup DifferenceEngine
  */
 class WordLevelDiff extends \Diff {
-       const MAX_LINE_LENGTH = 10000;
+       /**
+        * @inheritdoc
+        */
+       protected $bailoutComplexity = 40000000; // Roughly 6K x 6K words changed
 
        /**
         * @param string[] $linesBefore
@@ -42,7 +46,12 @@ class WordLevelDiff extends \Diff {
                list( $wordsBefore, $wordsBeforeStripped ) = $this->split( $linesBefore );
                list( $wordsAfter, $wordsAfterStripped ) = $this->split( $linesAfter );
 
-               parent::__construct( $wordsBeforeStripped, $wordsAfterStripped );
+               try {
+                       parent::__construct( $wordsBeforeStripped, $wordsAfterStripped );
+               } catch ( ComplexityException $ex ) {
+                       // Too hard to diff, just show whole paragraph(s) as changed
+                       $this->edits = [ new DiffOpChange( $linesBefore, $linesAfter ) ];
+               }
 
                $xi = $yi = 0;
                $editCount = count( $this->edits );
@@ -73,28 +82,20 @@ class WordLevelDiff extends \Diff {
                $stripped = [];
                $first = true;
                foreach ( $lines as $line ) {
-                       # If the line is too long, just pretend the entire line is one big word
-                       # This prevents resource exhaustion problems
                        if ( $first ) {
                                $first = false;
                        } else {
                                $words[] = "\n";
                                $stripped[] = "\n";
                        }
-                       if ( strlen( $line ) > self::MAX_LINE_LENGTH ) {
-                               $words[] = $line;
-                               $stripped[] = $line;
-                       } else {
-                               $m = [];
-                               if ( preg_match_all( '/ ( [^\S\n]+ | [0-9_A-Za-z\x80-\xff]+ | . ) (?: (?!< \n) [^\S\n])? /xs',
-                                       $line, $m )
-                               ) {
-                                       foreach ( $m[0] as $word ) {
-                                               $words[] = $word;
-                                       }
-                                       foreach ( $m[1] as $stripped_word ) {
-                                               $stripped[] = $stripped_word;
-                                       }
+                       $m = [];
+                       if ( preg_match_all( '/ ( [^\S\n]+ | [0-9_A-Za-z\x80-\xff]+ | . ) (?: (?!< \n) [^\S\n])? /xs',
+                               $line, $m ) ) {
+                               foreach ( $m[0] as $word ) {
+                                       $words[] = $word;
+                               }
+                               foreach ( $m[1] as $stripped_word ) {
+                                       $stripped[] = $stripped_word;
                                }
                        }
                }
index b3aaef1..d21351d 100644 (file)
        "config-db-name": "Datubāzes nosaukums:",
        "config-db-username": "Datubāzes lietotājvārds:",
        "config-db-password": "Datubāzes parole:",
-       "config-db-charset": "Datubāzes rakstzīmju kopa",
-       "config-charset-mysql5-binary": "MySQL 4.1/5.0 binārs",
-       "config-charset-mysql5": "MySQL 4.1/5.0 UTF-8",
-       "config-charset-mysql4": "MySQL 4.0 atpakaļsaderīgs UTF-8",
        "config-db-port": "Datubāzes ports:",
        "config-db-schema": "MediaWiki shēma:",
        "config-db-schema-help": "Šī shēma derēs vairumā gadījumu.\nMainiet to tikai, ja zināt, ka tas nepieciešams.",
@@ -46,6 +42,7 @@
        "config-mysql-innodb": "InnoDB",
        "config-mysql-myisam": "MyISAM",
        "config-mysql-utf8": "UTF-8",
+       "config-mssql-windowsauth": "Windows Autentifikācija",
        "config-ns-generic": "Projekts",
        "config-ns-site-name": "Tāds pats kā viki nosaukums: $1",
        "config-ns-other": "Cits (jānorāda)",
@@ -56,6 +53,7 @@
        "config-admin-password-confirm": "Parole vēlreiz:",
        "config-admin-name-blank": "Ievadiet administratora lietotājvārdu.",
        "config-admin-email": "E-pasta adrese:",
+       "config-email-settings": "E-pasta iestatījumi",
        "config-logo": "Logo URL:",
        "config-cc-again": "Izvēlies vēlreiz...",
        "config-extensions": "Paplašinājumi",
index dcef95c..0171ed9 100644 (file)
@@ -54,6 +54,12 @@ abstract class SearchEngine {
        /** @var array Feature values */
        protected $features = [];
 
+       /** @const string profile type for completionSearch */
+       const COMPLETION_PROFILE_TYPE = 'completionSearchProfile';
+
+       /** @const string profile type for query independent ranking features */
+       const FT_QUERY_INDEP_PROFILE_TYPE = 'fulltextQueryIndepProfile';
+
        /**
         * Perform a full text search query and return a result set.
         * If full text searches are not supported or disabled, return null.
@@ -631,6 +637,24 @@ abstract class SearchEngine {
                return MediaWikiServices::getInstance()->getSearchEngineConfig()->getSearchTypes();
        }
 
+       /**
+        * Get a list of supported profiles.
+        * Some search engine implementations may expose specific profiles to fine-tune
+        * its behaviors.
+        * The profile can be passed as a feature data with setFeatureData( $profileType, $profileName )
+        * The array returned by this function contains the following keys:
+        * - name: the profile name to use with setFeatureData
+        * - desc-message: the i18n description
+        * - default: set to true if this profile is the default
+        *
+        * @since 1.28
+        * @param $profileType the type of profiles
+        * @return array|null the list of profiles or null if none available
+        */
+       public function getProfiles( $profileType ) {
+               return null;
+       }
+
 }
 
 /**
index 6db4f2c..87a5b27 100644 (file)
@@ -166,6 +166,8 @@ class SpecialPrefixindex extends SpecialAllPages {
                $prefixList = $this->getNamespaceKeyAndText( $namespace, $prefix );
                $namespaces = $wgContLang->getNamespaces();
                $res = null;
+               $n = 0;
+               $nextRow = null;
 
                if ( !$prefixList || !$fromList ) {
                        $out = $this->msg( 'allpagesbadtitle' )->parseAsBlock();
@@ -207,7 +209,6 @@ class SpecialPrefixindex extends SpecialAllPages {
 
                        // @todo FIXME: Side link to previous
 
-                       $n = 0;
                        if ( $res->numRows() > 0 ) {
                                $out = Html::openElement( 'ul', [ 'class' => 'mw-prefixindex-list' ] );
                                $linkCache = MediaWikiServices::getInstance()->getLinkCache();
@@ -215,6 +216,7 @@ class SpecialPrefixindex extends SpecialAllPages {
                                $prefixLength = strlen( $prefix );
                                foreach ( $res as $row ) {
                                        if ( $n >= $this->maxPerPage ) {
+                                               $nextRow = $row;
                                                break;
                                        }
                                        $title = Title::newFromRow( $row );
@@ -259,9 +261,9 @@ class SpecialPrefixindex extends SpecialAllPages {
 
                $topOut = $this->namespacePrefixForm( $namespace, $prefix );
 
-               if ( $res && ( $n == $this->maxPerPage ) && ( $s = $res->fetchObject() ) ) {
+               if ( $res && ( $n == $this->maxPerPage ) && $nextRow ) {
                        $query = [
-                               'from' => $s->page_title,
+                               'from' => $nextRow->page_title,
                                'prefix' => $prefix,
                                'hideredirects' => $this->hideRedirects,
                                'stripprefix' => $this->stripPrefix,
@@ -275,7 +277,7 @@ class SpecialPrefixindex extends SpecialAllPages {
 
                        $nextLink = Linker::linkKnown(
                                $this->getPageTitle(),
-                               $this->msg( 'nextpage', str_replace( '_', ' ', $s->page_title ) )->escaped(),
+                               $this->msg( 'nextpage', str_replace( '_', ' ', $nextRow->page_title ) )->escaped(),
                                [],
                                $query
                        );
index 8935a49..951cb52 100644 (file)
@@ -699,7 +699,7 @@ class LoginFormPreAuthManager extends SpecialPage {
 
                $u->setEmail( $this->mEmail );
                $u->setRealName( $this->mRealName );
-               SessionManager::singleton()->invalidateSessionsForUser( $u );
+               $u->setToken();
 
                Hooks::run( 'LocalUserCreated', [ $u, $autocreate ] );
                $oldUser = $u;
index 053ac54..19907c7 100644 (file)
        "right-managechangetags": "[[Special:Tags|билдәләр]] мәғлүмәттәр базаһында төҙөү һәм юйыу",
        "right-applychangetags": " [[Special:Tags|тамғаһын]] үҙегеҙҙең төҙөтеү менән ҡулланырға",
        "right-changetags": "Айырым үҙгәртеүҙәрҙә һәм журнал яҙмаланыда[[Special:Tags|тамғаһын]] өҫтәү һәм юйыу",
+       "right-deletechangetags": "[[Special:Tags|билдәләр]] мәғлүмәттәр базаһында төҙөү һәм юйыу",
        "grant-generic": "Хоҡуҡтар йыйынтығы «$1»",
        "grant-group-page-interaction": "Башҡа биттәр менән бәйләнеш",
        "grant-group-file-interaction": "Медиафайлдар менән бәйләнеш",
        "authmanager-email-help": "Электрон почта адресы",
        "authmanager-realname-label": "Ысын исемегеҙ",
        "authprovider-resetpass-skip-label": "Ҡалдырып торорға",
+       "cannotauth-not-allowed": "Һеҙ был битте ҡуллана алмайһығыҙ.",
+       "changecredentials": "Иҫәп мәғлүмәттәрен үҙгәртеү",
        "changecredentials-submit": "Иҫәп мәғлүмәттәрен үҙгәртеү",
        "changecredentials-submit-cancel": "Кире алырға",
+       "removecredentials": "Иҫәп мәғлүмәттәрен юйырға",
        "removecredentials-submit": "Иҫәп мәғлүмәттәрен юйырға",
-       "removecredentials-submit-cancel": "Кире алырға"
+       "removecredentials-submit-cancel": "Кире алырға",
+       "credentialsform-account": "Иҫәп хужаһы"
 }
index dba6036..c87e09b 100644 (file)
        "password-change-forbidden": "Вы ня можаце зьмяняць паролі ў гэтай вікі.",
        "externaldberror": "Адбылася памылка аўтэнтыфікацыі з дапамогай вонкавай базы зьвестак, ці Вам не дазволена абнаўляць свой рахунак.",
        "login": "Увайсьці",
+       "login-security": "Пацьвердзіце вашую асобу",
        "nav-login-createaccount": "Уваход / стварэньне рахунку",
        "userlogin": "Увайсьці ў сыстэму / стварыць рахунак",
        "userloginnocreate": "Увайсьці",
        "accmailtext": "Створаны адвольны пароль для [[User talk:$1|$1]] быў адасланы па адрасе $2. Яго можна зьмяніць на старонцы ''[[Special:ChangePassword|зьмены паролю]]'' пасьля ўваходу.",
        "newarticle": "(Новая)",
        "newarticletext": "Вы прыйшлі па спасылцы на старонку, якая яшчэ не існуе.\nКаб стварыць яе, напішыце тэкст у полі ніжэй (глядзіце [$1 старонку дапамогі] для дадатковай інфармацыі).\nКалі Вы трапілі сюды памылкова, націсьніце кнопку «<strong>назад</strong>» у вашым браўзэры.",
-       "anontalkpagetext": "----''Гэта старонка гутарак ананімнага ўдзельніка, які яшчэ не стварыў сабе рахунак альбо не ўжывае яго. Таму мы вымушаныя ўжываць лічбавы IP-адрас дзеля ягонай ідэнтыфікацыі. Адзін IP-адрас можа выкарыстоўвацца некалькімі ўдзельнікамі. Калі Вы — ананімны ўдзельнік і лічыце, што атрымалі не прызначаныя Вам камэнтары, калі ласка, [[Special:CreateAccount|стварыце рахунак]] альбо [[Special:UserLogin|увайдзіце ў сыстэму]], каб у будучыні пазьбегнуць магчымай блытаніны зь іншымі ананімнымі ўдзельнікамі.''",
+       "anontalkpagetext": "----\n<em>Гэта старонка гутарак ананімнага ўдзельніка, які яшчэ не стварыў сабе рахунак альбо не ўжывае яго.</em>\nТаму мы вымушаныя ўжываць лічбавы IP-адрас дзеля ягонай ідэнтыфікацыі. Адзін IP-адрас можа выкарыстоўвацца некалькімі ўдзельнікамі. Калі Вы — ананімны ўдзельнік і лічыце, што атрымалі не прызначаныя Вам камэнтары, калі ласка, [[Special:CreateAccount|стварыце рахунак]] альбо [[Special:UserLogin|ўвайдзіце ў сыстэму]], каб у будучыні пазьбегнуць магчымай блытаніны зь іншымі ананімнымі ўдзельнікамі.",
        "noarticletext": "Цяпер тэкст на гэтай старонцы адсутнічае.\nВы можаце [[Special:Search/{{PAGENAME}}|пашукаць гэтую назву]] сярод іншых старонак, <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} пашукаць у адпаведных журналах падзеяў]\nальбо [{{fullurl:{{FULLPAGENAME}}|action=edit}} стварыць гэтую старонку]</span>.",
        "noarticletext-nopermission": "Цяпер на гэтай старонцы тэкст адсутнічае.\nВы можаце [[Special:Search/{{PAGENAME}}|пашукаць назву гэтай старонкі]] на іншых старонках, альбо <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} пашукаць зьвязаныя запісы ў журналах]</span>, але ў вас няма дазволу ствараць гэтую старонку.",
        "missing-revision": "Вэрсія старонкі №$1 з назвай «{{FULLPAGENAME}}» не існуе.\n\nЗвычайна гэта здараецца з-за перахода па састарэлай спасылцы на старонку, якая была выдаленая.\nПадрабязнасьці можна знайсьці ў [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} журнале выдаленьняў].",
index 49c2839..00ece2a 100644 (file)
        "showdiff": "পরিবর্তনসমূহ",
        "blankarticle": "<strong>সতর্ক বার্তা:</strong> আপনি একটি খালি পাতা তৈরী করতে যাচ্ছেন।\nআপনি যদি পুনরায় \"{{int:savearticle}}\" বাটন ক্লিক করেন তাহলে, পাতাটি তৈরী হবে যেখানে কোনো তথ্য লেখা নেই।",
        "anoneditwarning": "<strong>সতর্কতা:</strong> আপনি বর্তমানে প্রবেশ করেননি। যদি আপনি সম্পাদনা করেন এই পাতার সম্পাদনার ইতিহাসে আপনার আইপি ঠিকানা সার্বজনীনভাবে সংরক্ষিত হবে। যদি আপনি  <strong>[$1 প্রবেশ করেন]</strong> বা  <strong>[$2 একটি অ্যাকাউন্ট তৈরি করেন]</strong>, তাহলে আপনি আপনার আইপি ঠিকানা গোপন রাখতে পারবেন ও অন্যান্য অনেক কিছু সুবিধা পাবেন।",
-       "anonpreviewwarning": "<em>à¦\86পনি à¦ªà§\8dরবà§\87শ à¦\95রà§\87ননি। à¦¸à¦®à§\8dপাদনা à¦\95রতà§\87 à¦\8fà¦\87 à¦ªà¦¾à¦¤à¦¾à¦° à¦¸à¦®à§\8dপাদনার à¦\87তিহাসà§\87 à¦\86পনার à¦\86à¦\87পি à¦¸à¦\82à¦\96à§\8dযা সংরক্ষিত হবে।</em>",
+       "anonpreviewwarning": "<em>à¦\86পনি à¦ªà§\8dরবà§\87শ à¦\95রà§\87ননি। à¦¸à¦®à§\8dপাদনা à¦\95রলà§\87 à¦\8fà¦\87 à¦ªà¦¾à¦¤à¦¾à¦° à¦¸à¦®à§\8dপাদনার à¦\87তিহাসà§\87 à¦\86পনার à¦\86à¦\87পি à¦ à¦¿à¦\95ানা সংরক্ষিত হবে।</em>",
        "missingsummary": "'''খেয়াল করুন''':  আপনি কিন্তু সম্পাদনার সারাংশ দেননি। আবার যদি \"সংরক্ষণ\" বোতামে ক্লিক করেন, তাহলে ঐ সারাংশ বাক্যটি ছাড়াই আপনার সম্পাদনা সংরক্ষিত হবে।",
        "selfredirect": "<strong>সতর্কতা:</strong> আপনি এই পাতাকে এর নিজের দিকে পুনঃনির্দেশিত করছেন।\nআপনাকে পুনঃনির্দেশিত করার জন্য হয় ভুল লক্ষ্য নির্দিষ্ট করেছেন, অথবা আপনি ভুল পাতা সম্পাদনা করছেন।\nআপনি যদি আবার \"{{int:savearticle}}\" ক্লিক করেন, পুনর্নির্দেশ যেকোনোভাবেই হোক তৈরি করা হবে।",
        "missingcommenttext": "দয়া করে নিচে মন্তব্য যোগ করুন।",
index 878984c..a38d70c 100644 (file)
        "period-am": "AM",
        "period-pm": "PM",
        "pagecategories": "{{PLURAL:$1|Kategori|Kategoriy}}",
-       "category_header": "Pelê ke kategoriye da \"$1\" miyan derê",
+       "category_header": "Pelê ke kategoriya \"$1\" derê",
        "subcategories": "Kategoriyê bınêni",
        "category-media-header": "Dosyeyê ke kategoriya \"$1\" derê",
        "category-empty": "''Ena kategoriye de hewna qet nuştey ya zi medya çıniyê.''",
        "updatedmarker": "cıkewtena mına peyêne ra dıme biyo rocane",
        "printableversion": "Versiyonê nusterin",
        "permalink": "Gıreyo jûqere",
-       "print": "Çap kerdış",
+       "print": "Çap ke",
        "view": "Bıvêne",
        "view-foreign": "$1'i bıvin",
        "edit": "Bıvurne",
        "viewhelppage": "Pela peşti bıvêne",
        "categorypage": "Pela kategoriye bıvêne",
        "viewtalkpage": "Werênayışi bıvêne",
-       "otherlanguages": "Yewna zıwand bıwan",
+       "otherlanguages": "Zıwananê binan de",
        "redirectedfrom": "(Pele da $1 ra heteneyê)",
        "redirectpagesub": "Pela berdışi",
        "redirectto": "Beno hetê:",
        "mainpage": "Pela Seri",
        "mainpage-description": "Pela seri",
        "policy-url": "Project:Terzê hereketi",
-       "portal": "Portalê Gomey",
+       "portal": "Portalê Şélıgi",
        "portal-url": "Project:Portalê cemaeti",
        "privacy": "Politikay Nımnayışi",
        "privacypage": "Project:Xısusiyetê nımtışi",
        "feed-invalid": "Qeydey cıresnayışê  beğşi nêvêreno.",
        "feed-unavailable": "Cıresnayışê şebekey çıniyê",
        "site-rss-feed": "$1 Cıresnayışê RSSi",
-       "site-atom-feed": "$1 Wari kerdena Atomi",
+       "site-atom-feed": "$1 Cıresnayışê atomi",
        "page-rss-feed": "\"$1\" Cıresnayışê RSSi",
        "page-atom-feed": "\"$1\" Cıresnayışê atomi",
        "feed-atom": "Atom",
        "red-link-title": "$1 (pele çıniya)",
        "sort-descending": "Rêzkerdışo kêmbiyaye",
        "sort-ascending": "Rêzkerdışo zêdiyaye",
-       "nstab-main": "Wesiqe",
+       "nstab-main": "Pele",
        "nstab-user": "Pela karberi",
        "nstab-media": "Pela medya",
        "nstab-special": "Pela xase",
        "last": "peyên",
        "page_first": "verên",
        "page_last": "peyên",
-       "histlegend": "Ferqê weçinıtışi: Qutiya versiyonan seba têversanayış işaret ke û dest be ''enter''i ya zi gocega cêrêne ro ne.<br />\nCedwel: <strong>({{int:cur}})</strong> = ferqê verziyonê peyêni, <strong>({{int:last}})</strong> = ferqê versiyonê verêni, <strong>{{int:minoreditletter}}</strong> = vurnayışo werdi.",
+       "histlegend": "Ferqê weçinıtışi: Qutiya versiyonan seba têversanayış işaret ke û dest be ''enter''i ya zi gocega cêrêne ro ne.<br />\nCedwel: <strong>({{int:ferq}})</strong> = ferqê verziyonê peyêni, <strong>({{int:peyên}})</strong> = ferqê versiyonê verêni, <strong>{{int:q}}</strong> = vurnayışo werdi.",
        "history-fieldset-title": "Tarixi bıvêne",
        "history-show-deleted": "Tenya esterıtey",
        "histfirst": "Verênêr",
        "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 Vinayışi",
+       "searchresults": "Neticeyê geyrayışi",
        "searchresults-title": "Qandê \"$1\" neticeyê geyrayışi",
        "titlematches": "Tekê (zewcê) sernameyê pele",
        "textmatches": "Tekê (zewcê) nuştey pele",
        "prefs-labs": "Xacetê labs",
        "prefs-user-pages": "Pela Karberi",
        "prefs-personal": "Pela karberi",
-       "prefs-rc": "Vıryayışé peyéni",
+       "prefs-rc": "Vuryayışê peyêni",
        "prefs-watchlist": "Lista seyrkerdışi",
        "prefs-watchlist-days": "Rocê ke lista seyrkerdışi de bêrê ramocnaene",
        "prefs-watchlist-days-max": "tewr vêşi $1 {{PLURAL:$1|roci|roci}}",
        "nchanges": "$1 {{PLURAL:$1|fın vurna|fıni vurna}}",
        "enhancedrc-since-last-visit": "$1 {{PLURAL:$1|ra yok wazino}}",
        "enhancedrc-history": "tarix",
-       "recentchanges": "Vıryayışé peyéni",
+       "recentchanges": "Vuryayışê peyêni",
        "recentchanges-legend": "Tercihê vurnayışanê peyênan",
-       "recentchanges-summary": "Vuryayışanê peyênanê Wikipedia  etiya ra teqib ke.",
+       "recentchanges-summary": "Ena pele de wiki sero vurnayışanê peyênan teqib ke.",
        "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 yew pela newiye vıraziye",
        "rcshowhidebots": "botan $1",
        "rcshowhidebots-show": "Bıasene",
        "rcshowhidebots-hide": "Bınımne",
-       "rcshowhideliu": "karberanê qeyd bıyayan $1",
+       "rcshowhideliu": "karberê qeydbiyayeyi $1",
        "rcshowhideliu-show": "Bıasene",
        "rcshowhideliu-hide": "Bınımne",
        "rcshowhideanons": "karberê bênameyi $1",
        "rcshowhidemine-show": "Bıasene",
        "rcshowhidemine-hide": "Bınımne",
        "rcshowhidecategorization": "kategorizasyonê pele $1",
-       "rcshowhidecategorization-show": "Bıasene",
+       "rcshowhidecategorization-show": "Bıasne",
        "rcshowhidecategorization-hide": "Bınımne",
        "rclinks": "Peyniya $2 rocan de $1 vurnayışan bımocne <br />$3",
        "diff": "ferq",
        "hist": "verên",
        "hide": "Bınımne",
-       "show": "Bıasene",
+       "show": "Bıasne",
        "minoreditletter": "q",
        "newpageletter": "N",
        "boteditletter": "b",
        "statistics-header-hooks": "Yewbina istatistiki",
        "statistics-articles": "Pelê zerreki",
        "statistics-pages": "Peli",
-       "statistics-pages-desc": "Pelanê hemî ke wîkî de estê, pelanê mineqeşeyî, redireksiyon ucb... dehil o.",
+       "statistics-pages-desc": "Wiki de peley pêro, kategoriy, hetenayışi wesaire...",
        "statistics-files": "Dosyayê bar biye",
-       "statistics-edits": "Ronayen da {SITENAME}} ra newke amora vıryayışan",
+       "statistics-edits": "Ronayen da {{SITENAME}} ra newke amora vıryayışan",
        "statistics-edits-average": "Her pele sero nısbi vurnayış",
        "statistics-users": "[[Special:ListUsers|Karber]]ê qeydıni",
        "statistics-users-active": "Karberê aktifi",
        "double-redirect-fixed-move": "[[$1]] kırışiye.\nNa otomatikmen biye rocaniye û nıka [[$2]] ser şıknena.",
        "double-redirect-fixed-maintenance": "Serkışışteno dıletê [[$1]] ra  pela da [[$2]] vuriyeno.",
        "double-redirect-fixer": "Fixerî redirek bike",
-       "brokenredirects": "Hetenayışê vengi",
+       "brokenredirects": "Serşıkıtışê xırabeyi",
        "brokenredirectstext": "Redireksiyonê ey ki pelanê hama çiniyeno ra link dano:",
        "brokenredirects-edit": "bıvurne",
        "brokenredirects-delete": "bestere",
        "wantedtemplates": "Şablonê ke waziyenê",
        "mostlinked": "Pelî ke tewr zafî lînk bîy.",
        "mostlinkedcategories": "Kategoriyê ke tewr zehf meqaley tede estê",
-       "mostlinkedtemplates": "Pelê ke zaf biye daxil",
+       "mostlinkedtemplates": "Pelê ke zêdêr gureniyenê",
        "mostcategories": "Pelan ke tewr zaf kategorî estê.",
        "mostimages": "Dosyayan ke tewr zaf link estê.",
        "mostinterwikis": "Pelan ke tewr zaf interwiki biyê.",
        "newpages-submit": "Bıasene",
        "newpages-username": "Nameyê karberi:",
        "ancientpages": "Pelê kehenêri",
-       "move": "Bere",
-       "movethispage": "Ena pele bere",
+       "move": "Wegi",
+       "movethispage": "Ena peler wegi",
        "unusedimagestext": "Enê dosyey estê, feqet zerrey yew pele de wedardey niyê.\nXo vira mekerê ke, sıteyê webiê bini şenê direkt ebe URLi yew dosya ra gırê bê, u wına şenê verba gurênayışo feal de tiya hewna lista bê.",
        "unusedcategoriestext": "Kategoriyê ke cêr derê, nê bıbê zi, terefê qet madeyan ya zi kategoriyan ra nêgureniyenê.",
        "notargettitle": "Hedef çini yo",
        "logeventslist-submit": "Bıasene",
        "all-logs-page": "Umumi qeydi pêro",
        "alllogstext": "qey {{SITENAME}}i mocnayişê heme rocaneyani.\ntipa rocaneyi, nameyê karberi (herfa pil u qıci re hessas a), ya zi peli (reyna hessasiyê herfa pil u qıciyi) bıweçine u esayiş qıc kerê.",
-       "logempty": "qaydi de weina yew malumat çino",
+       "logempty": "Qeydan dı malumato unasin çıni yo.",
        "log-title-wildcard": "sername yê ke pê ney nuşteyi destkenêpê bıgêr.",
        "showhideselectedlogentries": "Qeydê weçinayışê bımocne/bınımne dekerê",
        "log-edit-tags": "Etiketanê weçinayê qeydan bıvurnê",
        "maximum-size": "Ebatê maximumî",
        "pagesize": "(bitî)",
        "restriction-edit": "Bıvurne",
-       "restriction-move": "Bere",
+       "restriction-move": "Wegi",
        "restriction-create": "Vıraze",
        "restriction-upload": "Bar ke",
        "restriction-level-sysop": "tam pawiyayo",
        "sp-contributions-username": "Adresa IPy ya zi nameyê karberi:",
        "sp-contributions-toponly": "Tenya rewizyonanê tewr peyniyan bimocne",
        "sp-contributions-submit": "Cı geyre",
-       "whatlinkshere": "Ena perer rê grey",
+       "whatlinkshere": "Pele rê gıreyi",
        "whatlinkshere-title": "Per da \"$1\" rê perê ke gre danê",
        "whatlinkshere-page": "Pele:",
        "linkshere": "Ena peleyan grey biya '''[[:$1]]''':",
        "tooltip-ca-unprotect": "Starkerdışe ena peler bıvurne",
        "tooltip-ca-delete": "Ena pele bestere",
        "tooltip-ca-undelete": "peli biyarê halê ver hewnakerdışi",
-       "tooltip-ca-move": "Ena pele bere",
+       "tooltip-ca-move": "Ena peler wegi",
        "tooltip-ca-watch": "Ena pele lista xoya seyrkerdışi ke",
        "tooltip-ca-unwatch": "Ena pele lista xoya seyrkerdışi ra vece",
-       "tooltip-search": "{{SITENAME}} de bıvin",
+       "tooltip-search": "{{SITENAME}} de cı geyre",
        "tooltip-search-go": "Ebe nê namey tami şo yew pela ke esta",
-       "tooltip-search-fulltext": "Pela miyan dı bı geyr ena metin",
+       "tooltip-search-fulltext": "Pelan miyan de nê metıni cı geyre",
        "tooltip-p-logo": "Pela seri bıvêne",
        "tooltip-n-mainpage": "Şo pela seri",
        "tooltip-n-mainpage-description": "Şo pela seri",
        "tooltip-preferences-save": "Terciha qeyd ke",
        "tooltip-summary": "Yew xulasaya kilm binuse",
        "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. */",
        "anonymous": "{{PLURAL:$1|karberê|karberê}} anonimi yê keyepelê {{SITENAME}}i",
        "siteuser": "karberê {{SITENAME}}i $1",
        "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": "Perê Xısusi",
+       "specialpages": "Pelê xısusiy",
        "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-other": "Pelê xasiyê bini",
        "specialpages-group-login": "Cı kewe / hesab vıraze",
-       "specialpages-group-changes": "Vıryayışê peyêni u Qeydi",
+       "specialpages-group-changes": "Vurnayışê peyêni û qeydi",
        "specialpages-group-media": "Raporê medya û barkerdışi",
        "specialpages-group-users": "Karberi û heqi",
        "specialpages-group-highuse": "Peleyê ke vêşi karênê",
index e6455ce..44498b8 100644 (file)
        "rev-suppressed-unhide-diff": "یکی از نسخه‌های این تفاوت '''فرونشانی شده‌است'''.\nممکن است جزئیاتی در [{{fullurl:{{#Special:Log}}/suppress|page=سیاههٔ فرونشانی{{FULLPAGENAMEE}}}}] موجود باشد.\nشما کماکان می‌توانید در صورت تمایل [$1 این تفاوت را ببینید].",
        "rev-deleted-diff-view": "یکی از نسخه‌های این تفاوت '''حذف شده‌است'''.\nشما می‌توانید این تفاوت را ببینید؛ ممکن است جزئیاتی در [{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGENAMEE}}}} سیاههٔ حذف] موجود باشد.",
        "rev-suppressed-diff-view": "یکی از نسخه‌های این تفاوت '''فرونشانی شده‌است'''.\nشما می‌توانید این تفاوت را ببینید؛ ممکن است جزئیاتی در [{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGENAMEE}}}} سیاههٔ فرونشانی] موجود باشد.",
-       "rev-delundel": "نمایش/نهفتن",
+       "rev-delundel": "تغییر پیدایی",
        "rev-showdeleted": "نمایش",
        "revisiondelete": "حذف/احیای نسخه‌ها",
        "revdelete-nooldid-title": "نسخهٔ هدف نامجاز",
index 589346c..e3de422 100644 (file)
        "category-empty": "<em>Cette catégorie ne contient actuellement aucune page ni fichier multimédia.</em>",
        "hidden-categories": "{{PLURAL:$1|Catégorie cachée|Catégories cachées}}",
        "hidden-category-category": "Catégories cachées",
-       "category-subcat-count": "Cette catégorie {{PLURAL:$2|0=ne comprend aucune sous-catégorie|1=comprend seulement la sous-catégorie ci-dessous|comprend les $2 sous-catégories, dont {{PLURAL:$1|0=aucune|1=celle|les $1}} ci-dessous}}.",
+       "category-subcat-count": "Cette catégorie {{PLURAL:$2|0=ne comprend aucune sous-catégorie|1=comprend seulement la sous-catégorie ci-dessous|comprend $2 sous-catégories, dont {{PLURAL:$1|0=aucune|1=celle|les $1}} ci-dessous}}.",
        "category-subcat-count-limited": "Cette catégorie comprend {{PLURAL:$1|la sous-catégorie|les $1 sous-catégories}} ci-dessous.",
        "category-article-count": "Cette catégorie {{PLURAL:$2|0=ne comprend aucune page|1=comprend seulement la page ci-dessous|comprend $2 pages, dont {{PLURAL:$1|0=aucune|1=celle|les $1}} ci-dessous}}.",
        "category-article-count-limited": "{{PLURAL:$1|0=Aucune page ne figure|1=La page suivante figure|Les $1 pages suivantes figurent}} dans la présente catégorie.",
index 27372c6..80a015b 100644 (file)
        "loginerror": "שגיאה בכניסה לאתר",
        "createacct-error": "שגיאה ביצירת חשבון",
        "createaccounterror": "לא ניתן היה ליצור את החשבון: $1",
-       "nocookiesnew": "×\97ש×\91×\95×\9f ×\94×\9eשת×\9eש ×©×\9c×\9b×\9d × ×\95צר, ×\90×\9a ×\9c×\90 × ×\9bנסת×\9d ×\9b×\9eשת×\9eש×\99×\9d ×¨×©×\95×\9e×\99×\9d.\n×\9b×\93×\99 ×\9c×\94×\9b× ×\99ס ×\9eשת×\9eש×\99×\9d ×\9c×\9eער×\9bת ×¢×\95ש×\94 {{SITENAME}} ×©×\99×\9e×\95ש ×\91×¢×\95×\92×\99×\95ת.\n×\91×\93פ×\93פ×\9f ×©×\9c×\9b×\9d ×\94×¢×\95×\92×\99×\95ת ×\9e×\91×\95×\98×\9c×\95ת.\n×\90× ×\90 ×\94פע×\99×\9c×\95 ×\90×\95ת×\9f ×\9e×\97×\93ש, ×\95×\9c×\90×\97ר ×\9e×\9b×\9f ×ª×\95×\9b×\9c×\95 ×\9c×\94×\99×\9bנס ×\9c×\9eער×\9bת ×¢×\9d ×©×\9d ×\94×\9eשת×\9eש ×\95×\94ס×\99ס×\9e×\94 ×\94×\97×\93ש×\99×\9d ×©×\9c×\9b×\9d.",
-       "nocookieslogin": "אתר זה משתמש בעוגיות (cookies) כדי להכניס משתמשים למערכת.\nבדפדפן שלך העוגיות מבוטלות.\nנא להפעיל אותן ולאחר מכן לנסות שוב.",
+       "nocookiesnew": "×\94×\97ש×\91×\95×\9f ×©×\9c×\9a × ×\95צר, ×\90×\91×\9c ×\9c×\90 × ×\9bנסת ×\9c×\97ש×\91×\95×\9f.\n{{SITENAME}} ×¢×\95ש×\94 ×©×\99×\9e×\95ש ×\91×¢×\95×\92×\99×\95ת (cookies) ×\9b×\93×\99 ×\9c×\94×\9b× ×\99ס ×\9eשת×\9eש×\99×\9d ×\9c×\9eער×\9bת.\n×\91×\93פ×\93פ×\9f ×©×\9c×\9a ×\94×¢×\95×\92×\99×\95ת ×\9e×\91×\95×\98×\9c×\95ת.\n×\99ש ×\9c×\94פע×\99×\9c ×\90×\95ת×\9f, ×\95רק ×\9c×\90×\97ר ×\9e×\9b×\9f ×\9c×\94×\99×\9bנס ×\9c×\97ש×\91×\95×\9f ×¢×\9d ×©×\9d ×\94×\9eשת×\9eש ×\95×\94ס×\99ס×\9e×\94 ×©×\9c×\9a.",
+       "nocookieslogin": "{{SITENAME}} עושה שימוש בעוגיות (cookies) כדי להכניס משתמשים למערכת.\nבדפדפן שלך העוגיות מבוטלות.\nיש להפעיל אותן ולאחר מכן לנסות שוב.",
        "nocookiesfornew": "חשבון המשתמש לא נוצר, כיוון שלא יכולנו לוודא את מקורו.\nודאו שהעוגיות מופעלות בדפדפן שלכם, העלו מחדש דף זה ונסו שוב.",
        "createacct-loginerror": "החשבון נוצר בהצלחה, אבל לא ניתן היה להיכנס אליו באופן אוטומטי. נא [[Special:UserLogin|להיכנס באופן ידני]].",
        "noname": "לא הכנסת שם משתמש תקין",
        "session_fail_preview": "מצטערים! לא ניתן לבצע את עריכתכם עקב אובדן מידע הכניסה.\n\nייתכן שנותקתם מהחשבון. <strong>אנא ודאו שאתם עדיין מחוברים לחשבון ונסו שוב.</strong>\nאם זה עדיין לא עובד, נסו [[Special:UserLogout|לצאת מהחשבון]] ולהיכנס אליו שנית, וודאו שהדפדפן שלכם מאפשר קבלת עוגיות מאתר זה.",
        "session_fail_preview_html": "מצטערים! לא ניתן לבצע את עריכתם עקב אובדן מידע הכניסה.\n\n<em>כיוון שב{{grammar:תחילית|{{SITENAME}}}} אפשרות השימוש ב־HTML גולמי מופעלת, התצוגה המקדימה מוסתרת כדי למנוע התקפות JavaScript.</em>\n\n<strong>אם זהו ניסיון עריכה לגיטימי, אנא נסו שוב.</strong>\nאם זה עדיין לא עובד, נסו [[Special:UserLogout|לצאת מהחשבון]] ולהיכנס אליו שנית, וודאו שהדפדפן שלכם מאפשר קבלת עוגיות מאתר זה.",
        "token_suffix_mismatch": "'''עריכתך נדחתה כיוון שהדפדפן שלך מחק את תווי הפיסוק באסימון העריכה.'''\nהעריכה נדחתה כדי למנוע בעיות כאלה בטקסט של הדף.\nלעתים התקלה מתרחשת עקב שימוש בשירות פרוקסי אנונימי פגום.",
-       "edit_form_incomplete": "<strong>×\97×\9cק×\99×\9d ×\9eס×\95×\99×\9e×\99×\9d ×\9e×\98×\95פס ×\94ער×\99×\9b×\94 ×\9c×\90 ×\94×\92×\99×¢×\95 ×\9cשרת; × ×\90 ×\9c×\91×\93×\95ק ×©×\94ער×\99×\9b×\94 ×\9c×\90 × ×¤×\92×¢×\94 ×\95×\9cנס×\95ת שוב.</strong>",
+       "edit_form_incomplete": "<strong>×\97×\9cק×\99×\9d ×\9eס×\95×\99×\9e×\99×\9d ×\9e×\98×\95פס ×\94ער×\99×\9b×\94 ×\9c×\90 ×\94×\92×\99×¢×\95 ×\9cשרת; ×\90× ×\90 {{GENDER:|×\91×\93×\95ק|×\91Ö´×\93ק×\99\91Ö´×\93ק×\95}} ×©×\94ער×\99×\9b×\94 ×\9c×\90 × ×¤×\92×¢×\94 ×\95{{GENDER:|נס×\94|נס×\99|נס×\95}} שוב.</strong>",
        "editing": "עריכת הדף \"$1\"",
        "creating": "יצירת הדף \"$1\"",
        "editingsection": "עריכת הדף \"$1\" (פסקה)",
        "content-failed-to-parse": "פענוח $2 כתוכן מסוג $1 נכשל: $3",
        "invalid-content-data": "מידע שגוי על התוכן",
        "content-not-allowed-here": "תוכן מסוג \"$1\" אינו מותר בדף [[$2]]",
-       "editwarning-warning": "×¢×\96×\99×\91ת ×\93×£ ×\96×\94 ×¢×\9c×\95×\9c×\94 ×\9c×\92ר×\95×\9d ×\9c×\9b×\9c ×\94ש×\99× ×\95×\99×\99×\9d ×©×\91×\99צעת ×\9c×\94×\99×¢×\9c×\9d. אם יש לך חשבון באתר, באפשרותך לבטל את האזהרה הזאת בחלק \"{{int:prefs-editing}}\" שבהעדפות שלך.",
+       "editwarning-warning": "×¢×\96×\99×\91ת ×\94×\93×£ ×\94×\96×\94 ×¢×\9c×\95×\9c×\94 ×\9c×\92ר×\95×\9d ×\9c×\9a ×\9c×\90×\91×\93 ×\90ת ×\9b×\9c ×\94ש×\99× ×\95×\99×\99×\9d ×©×\91×\99צעת. אם יש לך חשבון באתר, באפשרותך לבטל את האזהרה הזאת בחלק \"{{int:prefs-editing}}\" שבהעדפות שלך.",
        "editpage-notsupportedcontentformat-title": "סוג התוכן אינו נתמך",
        "editpage-notsupportedcontentformat-text": "תוכן מסוג $1 אינו נתמך על־ידי מודל התוכן $2.",
        "content-model-wikitext": "קוד ויקי",
        "emailuser-title-target": "שליחת דואר אלקטרוני {{GENDER:$1|למשתמש זה|למשתמשת זו}}",
        "emailuser-title-notarget": "שליחת דואר אלקטרוני למשתמש",
        "emailpagetext": "ניתן להשתמש בטופס שלהלן כדי לשלוח הודעת דואר אלקטרוני {{GENDER:$1|למשתמש זה|למשתמשת זו}}.\nכתובת הדואר האלקטרוני שהזנת ב[[Special:Preferences|העדפות המשתמש שלך]] תופיע ככתובת שההודעה נשלחה ממנה, כדי לאפשר תגובה ישירה.",
-       "defemailsubject": "דוא\"ל מ{{grammar:תחילית|{{SITENAME}}}} מהמשתמש \"$1\"",
+       "defemailsubject": "דוא\"ל מ{{GRAMMAR:תחילית|{{SITENAME}}}} מה{{GENDER:$1|משתמש|משתמשת}} \"$1\"",
        "usermaildisabled": "שליחת דוא\"ל למשתמשים מבוטלת",
        "usermaildisabledtext": "אינכם מורשים לשלוח דואר אלקטרוני למשתמשים אחרים באתר זה",
        "noemailtitle": "אין כתובת דואר אלקטרוני",
        "badipaddress": "משתמש או כתובת IP שגויים.",
        "blockipsuccesssub": "החסימה הושלמה בהצלחה",
        "blockipsuccesstext": "{{GENDER:$1|המשתמש|המשתמשת}} [[Special:Contributions/$1|$1]] {{GENDER:$1|נחסם|נחסמה}}.\n\nראו את [[Special:BlockList|רשימת החסומים]] כדי לצפות בחסימות.",
-       "ipb-blockingself": "{{GENDER:|×\90ת×\94 ×¢×\95×\9e×\93\90ת ×¢×\95×\9e×\93ת|×\90ת×\9d ×¢×\95×\9e×\93×\99×\9d}} ×\9c×\97ס×\95×\9d ×\90ת {{GENDER:|עצ×\9e×\9a|עצ×\9e×\9a|עצ×\9e×\9b×\9d}}! ×\94×\90×\9d {{GENDER:|×\90ת×\94 ×\91×\98×\95×\97 ×©×\91רצ×\95× ×\9a\90ת ×\91×\98×\95×\97×\94 ×©×\91רצ×\95× ×\9a\90ת×\9d ×\91×\98×\95×\97×\99×\9d ×©×\91רצ×\95× ×\9bם}} לעשות את זה?",
+       "ipb-blockingself": "{{GENDER:|×\90ת×\94 ×¢×\95×\9e×\93\90ת ×¢×\95×\9e×\93ת|×\90ת×\9d ×¢×\95×\9e×\93×\99×\9d}} ×\9c×\97ס×\95×\9d ×\90ת {{GENDER:|עצ×\9e×\9a|עצ×\9e×\9a|עצ×\9e×\9b×\9d}}! ×\94×\90×\9d {{GENDER:|×\90ת×\94 ×\91×\98×\95×\97 ×©×\90ת×\94 ×¨×\95צ×\94\90ת ×\91×\98×\95×\97×\94 ×©×\90ת ×¨×\95צ×\94\90ת×\9d ×\91×\98×\95×\97×\99×\9d ×©×\90ת×\9d ×¨×\95צ×\99ם}} לעשות את זה?",
        "ipb-confirmhideuser": "{{GENDER:|אתה עומד|את עומדת|אתם עומדים}} לחסום משתמש עם האפשרות \"הסתרת משתמש\". זה יעלים את שם המשתמש בכל הרשימות ופעולות היומן. האם {{GENDER:|אתה בטוח שברצונך|את בטוחה שברצונך|אתם בטוחים שברצונכם}} לעשות את זה?",
        "ipb-confirmaction": "אם {{GENDER:|אתה בטוח שברצונך|את בטוחה שברצונך|אתם בטוחים שברצונכם}} לעשות זאת, אנא {{GENDER:|סמן|סמני|סמנו}} את השדה \"{{int:ipb-confirm}}\" שמופיע למטה.",
        "ipb-edit-dropdown": "עריכת סיבות החסימה",
        "emaillink": "שליחת דוא\"ל",
        "autoblocker": "נחסמתם באופן אוטומטי משום שאתם חולקים את כתובת ה־IP שלכם עם [[User:$1|$1]].\nהסיבה שניתנה לחסימת $1 היא \"$2\"",
        "blocklogpage": "יומן חסימות",
-       "blocklog-showlog": "משתמש זה נחסם בעבר.\nיומן החסימות מוצג להלן:",
-       "blocklog-showsuppresslog": "משתמש זה נחסם והוסתר בעבר.\nיומן ההעלמות מוצג להלן:",
+       "blocklog-showlog": "{{GENDER:$1|משתמש זה נחסם|משתמשת זו נחסמה}} בעבר.\nיומן החסימות מוצג להלן:",
+       "blocklog-showsuppresslog": "{{GENDER:$1|משתמש זה נחסם והוסתר|משתמשת זו נחסמה והוסתרה}} בעבר.\nיומן ההעלמות מוצג להלן:",
        "blocklogentry": "חסם את [[$1]] למשך $2 $3",
        "reblock-logentry": "שינה את הגדרות החסימה של [[$1]] עם זמן פקיעה של $2 $3",
        "blocklogtext": "זהו יומן פעולות החסימה והשחרור של משתמשים.\nכתובות IP שנחסמו אוטומטית אינן מופיעות.\nראו גם את [[Special:BlockList|רשימת החסומים]] לרשימה של החרמות וחסימות פעילות כעת.",
index efa5ee6..ab176e7 100644 (file)
        "noname": "आपने वैध सदस्यनाम नहीं दिया है।",
        "loginsuccesstitle": "प्रवेश हुआ",
        "loginsuccess": "'''आप {{SITENAME}} में \"$1\" सदस्यनाम से लॉग इन हो {{GENDER:$1|चुके|चुकी|चुके}} हैं।'''",
-       "nosuchuser": "\"$1\" नाम का कोई सदस्य नहीं है।\nसदस्यनाम में लघु और दीर्घ अक्षरों से फ़र्क पड़ता है।\nअपनी वर्तनी जाँचें, या [[Special:CreateAccount|नया खाता खोलें]]।",
+       "nosuchuser": "यहाँ \"$1\" नाम का कोई सदस्य नहीं है।\nसदस्यनाम में लघु और दीर्घ अक्षरों से फ़र्क पड़ता है।\nअपनी वर्तनी जाँचें, या [[Special:CreateAccount|नया खाता खोलें]]।",
        "nosuchusershort": "\"$1\" नाम का कोई सदस्य नहीं है।\nकृपया अपनी दी हुई वर्तनी जाँचें।",
        "nouserspecified": "सदस्यनाम देना अनिवार्य है।",
        "login-userblocked": "यह सदस्य प्रतिबन्धित है। सत्रारम्भ की अनुमति नहीं है।",
        "accmailtext": "[[User talk:$1|$1]] के लिए एक यंत्र जनित कूटशब्द $2 को भेज दिया गया है। लॉगिन करने के बाद इसे '''[[Special:ChangePassword|कूटशब्द बदलें]]'' वाले पृष्ठ पर बदला जा सकता है।",
        "newarticle": "(नया)",
        "newarticletext": "आप ऐसे पृष्ठ पर आए हैं जो अभी तक बनाया नहीं गया है।\nपृष्ठ बनाने के लिये नीचे के बौक्स में पाठ लिखें। अधिक जानकारी के लिये [$1 सहायता पृष्ठ] देखें।\nअगर आप यहाँ पर गलती से आए हैं तो अपने ब्राउज़र के बैक ('''back''') बटन पर क्लिक करें।",
-       "anontalkpagetext": "----''यह वार्ता पृष्ठ उन बेनामी सदस्यों के लिये है जिन्होंने या तो खाता नहीं खोला है या खाते का प्रयोग नहीं कर रहे हैं।\nइसलिये उनकी पहचान के लिये हमें उनका आइ॰पी पता प्रयोग करना पड़ता है।\nआइ॰पी पता कई सदस्यों के लिए साझा हो सकता है।\nयदि आप एक बेनामी सदस्य हैं और आपको लगता है कि आपके बारे में अप्रासंगिक टीका टिप्पणी की गई है तो कृपया [[Special:CreateAccount|सदस्यता लें]] या [[Special:UserLogin|सत्रारंभ करें]] ताकि अन्य बेनामी सदस्यों में से आपको अलग से पहचाना जा सके।''",
+       "anontalkpagetext": "----\n<em>यह वार्ता पृष्ठ उन बेनामी सदस्यों के लिये है जिन्होंने या तो खाता नहीं खोला है या खाते का प्रयोग नहीं कर रहे हैं।</em>\nइसलिये उनकी पहचान के लिये हमें उनका संख्यात्मक आई॰पी॰ पता प्रयोग करना पड़ता है।\nऐसा आई॰पी॰ पता कई सदस्यों के लिए साझा हो सकता है।\nयदि आप एक बेनामी सदस्य हैं और आपको लगता है कि आपके बारे में अप्रासंगिक टीका टिप्पणी की गई है तो कृपया [[Special:CreateAccount|सदस्यता लें]] या [[Special:UserLogin|सत्रारंभ करें]] ताकि अन्य बेनामी सदस्यों में से आपको अलग से पहचाना जा सके।",
        "noarticletext": "फ़िलहाल इस पृष्ठ पर कोई सामग्री नहीं है।\nआप अन्य पृष्ठों में [[Special:Search/{{PAGENAME}}|इस शीर्षक की खोज]] कर सकते हैं,\n<span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} सम्बन्धित लॉग खोज सकते हैं],\nया इस पृष्ठ को [{{fullurl:{{FULLPAGENAME}}|action=edit}} सम्पादित] कर सकते हैं</span>।",
        "noarticletext-nopermission": "फ़िलहाल इस पृष्ठ पर कोई सामग्री नहीं है।\nआप अन्य पृष्ठों में [[Special:Search/{{PAGENAME}}|इस शीर्षक की खोज]] कर सकते हैं,\nया <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} संबंधित लॉग खोज सकते हैं]</span>, परन्तु आपको यह पृष्ठ बनाने की अनुमति नहीं है।",
        "missing-revision": "\"{{FULLPAGENAME}}\" पृष्ठ का अवतरण #$1 मौजूद नहीं है।\n\nआम तौर पर यह एक हटाए गए पृष्ठ के पुराने लिंक पर क्लिक करने से होता है।\nअधिक जानकारी के लिए आप [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} हटाने का लॉग] देख सकते हैं।",
        "log-action-filter-delete-restore": "पृष्ठ न हटाना",
        "log-action-filter-delete-event": "पृष्ठ हटाने का लॉग",
        "log-action-filter-delete-revision": "अवतरण हटाना",
-       "log-action-filter-managetags-create": "à¤\9fà¥\88à¤\97 निर्मित",
+       "log-action-filter-managetags-create": "à¤\9aिपà¥\8dपि निर्मित",
        "log-action-filter-newusers-create": "अज्ञात सदस्य द्वारा निर्मित",
        "log-action-filter-newusers-create2": "पंजीकृत सदस्य द्वारा निर्मित",
        "log-action-filter-newusers-autocreate": "स्वतः निर्मित",
index edbaa7d..ccfae57 100644 (file)
        "trackingcategories-msg": "Categoria de sequimento",
        "trackingcategories-name": "Nomine del message",
        "trackingcategories-desc": "Criterios pro inclusion in categoria",
+       "restricted-displaytitle-ignored": "Paginas con titulos a monstrar ignorate",
+       "restricted-displaytitle-ignored-desc": "Le pagina ha un <code><nowiki>{{DISPLAYTITLE}}</nowiki></code> ignorate perque illo non es equivalente al titulo real del pagina.",
        "noindex-category-desc": "Iste pagina es excludite del indice perque illo contine le marca <code><nowiki>__NOINDEX__</nowiki></code> e es in un spatio de nomines ubi le uso de iste marca es permittite.",
        "index-category-desc": "Iste pagina contine le marca <code><nowiki>__INDEX__</nowiki></code> (e es in un spatio de nomines ubi le uso de iste marca es permittite), e dunque es includite in le indice mesmo si illo normalmente non lo esserea.",
        "post-expand-template-inclusion-category-desc": "Le dimension del pagina es plus grande de <code>$wgMaxArticleSize</code> post le expansion de tote le patronos, dunque alcun patronos non ha essite expandite.",
        "rollbacklinkcount": "revocar $1 {{PLURAL:$1|modification|modificationes}}",
        "rollbacklinkcount-morethan": "revocar plus de $1 {{PLURAL:$1|modification|modificationes}}",
        "rollbackfailed": "Revocation fallite",
+       "rollback-missingparam": "Manca parametros obligatori in le requesta.",
        "cantrollback": "Impossibile revocar le modification;\nle ultime contributor es le sol autor de iste pagina.",
        "alreadyrolled": "Non pote revocar le ultime modification de [[:$1]] per [[User:$2|$2]] ([[User talk:$2|discussion]]{{int:pipe-separator}}[[Special:Contributions/$2|{{int:contribslink}}]]);\nun altere persona ha ja modificate o revocate le pagina.\n\nLe ultime modification esseva facite per [[User:$3|$3]] ([[User talk:$3|discussion]]{{int:pipe-separator}}[[Special:Contributions/$3|{{int:contribslink}}]]).",
        "editcomment": "Le summario del modification esseva: <em>$1</em>.",
        "revertpage": "Reverteva modificationes per [[Special:Contributions/$2|$2]] ([[User talk:$2|Discussion]]) al ultime version per [[User:$1|$1]]",
        "revertpage-nouser": "Reverteva modificationes per un usator celate al ultime version per {{GENDER:$1|[[User:$1|$1]]}}",
        "rollback-success": "Revocava modificationes per $1;\nretornava al version per $2.",
+       "rollback-success-notify": "Modificationes de $1 revertite;\nultime version de $2 restaurate. [$3 Monstrar cambiamentos]",
        "sessionfailure-title": "Error de session",
        "sessionfailure": "Il pare haber un problema con tu session de conto;\niste action ha essite cancellate como precaution contra le sequestramento de sessiones.\nPer favor preme \"retro\" e recarga le pagina de ubi tu ha venite, postea reprova.",
        "changecontentmodel": "Cambiar le modello de contento de un pagina",
        "confirm-watch-top": "Adder iste pagina a tu observatorio?",
        "confirm-unwatch-button": "OK",
        "confirm-unwatch-top": "Remover iste pagina de tu observatorio?",
+       "confirm-rollback-top": "Reverter le modificationes a iste pagina?",
        "quotation-marks": "“$1”",
        "imgmultipageprev": "← precedente pagina",
        "imgmultipagenext": "sequente pagina →",
        "cannotauth-not-allowed-title": "Permission refusate",
        "cannotauth-not-allowed": "Tu non es autorisate a usar iste pagina",
        "changecredentials": "Cambiar credentiales",
-       "changecredentials-submit": "Cambiar",
+       "changecredentials-submit": "Cambiar credentiales",
        "changecredentials-submit-cancel": "Cancellar",
        "changecredentials-invalidsubpage": "$1 non es un typo de credential valide.",
        "changecredentials-success": "Tu credentiales ha essite cambiate.",
        "removecredentials": "Remover credentiales",
-       "removecredentials-submit": "Remover",
+       "removecredentials-submit": "Remover credentiales",
        "removecredentials-submit-cancel": "Cancellar",
        "removecredentials-invalidsubpage": "$1 non es un typo de credential valide.",
        "removecredentials-success": "Tu credentiales ha essite removite.",
index ebbfb85..527b8d9 100644 (file)
        "october-gen": "10월",
        "november-gen": "11월",
        "december-gen": "12월",
-       "jan": "1",
-       "feb": "2",
-       "mar": "3",
-       "apr": "4",
-       "may": "5",
-       "jun": "6",
-       "jul": "7",
-       "aug": "8",
-       "sep": "9",
-       "oct": "10",
-       "nov": "11",
-       "dec": "12",
+       "jan": "1",
+       "feb": "2",
+       "mar": "3",
+       "apr": "4",
+       "may": "5",
+       "jun": "6",
+       "jul": "7",
+       "aug": "8",
+       "sep": "9",
+       "oct": "10",
+       "nov": "11",
+       "dec": "12",
        "january-date": "1월 $1일",
        "february-date": "2월 $1일",
        "march-date": "3월 $1일",
index 439c36e..e0c8791 100644 (file)
        "preview": "Pra tayang",
        "showpreview": "Pra tayang",
        "showdiff": "Ndeleng bedané",
-       "anoneditwarning": "Rika ora kadaftar mlebu.\nAlamat IP-ne Rika bakal dicatet nang sajarah panyuntingane kaca kiye.",
+       "anoneditwarning": "Rika ora kadaftar utawa urung mlebu.\nAlamat IP-ne Rika bakal dicatet nang sajarah panyuntingane kaca kiye.",
        "anonpreviewwarning": "''Rika durung mlebu log. Nyimpen kaca bakal nyatetna alamat IP-ne Rika nang riwayat suntingan kaca kiye.''",
        "missingsummary": "'''Pènget:''' Rika ora nglebokna ringkesan panyuntingan. \nAngger Rika mencèt tombol Simpen maning, suntingane Rika bakal kasimpen tanpa ringkesan panyuntingan.",
        "missingcommenttext": "Tulung lebokna komentar nang ngisor kiye.",
        "shown-title": "Tidokna $1 {{PLURAL:$1|asil|asil}} saben kaca",
        "viewprevnext": "Deleng ($1 {{int:pipe-separator}} $2) ($3)",
        "searchmenu-exists": "''' Ana kaca nganggo jeneng \"[[:$1]]\" nang wiki kiye.'''",
-       "searchmenu-new": "'''Gawe kaca \"[[:$1]]\" nang wiki kiye!'''",
+       "searchmenu-new": "'''Gawe kaca \"[[:$1]]\" nang wiki kiye!''' {{PLURAL:$2|0=|Deleng uga kaca sing Rika golet.|Deleng uga penggoletan sing digolet.}}",
        "searchprofile-articles": "Isine kaca",
        "searchprofile-images": "Multimedia",
        "searchprofile-everything": "Kabèh",
        "whatlinkshere-prev": "{{PLURAL:$1|sedurungé|$1 sedurungé}}",
        "whatlinkshere-next": "{{PLURAL:$1|terusane|$1 terusane}}",
        "whatlinkshere-links": "← pranala",
-       "whatlinkshere-hideredirs": "$1 pengalihan",
+       "whatlinkshere-hideredirs": "$1 Dialihna",
        "whatlinkshere-hidetrans": "$1 transklusi",
        "whatlinkshere-hidelinks": "$1 pranala",
        "whatlinkshere-hideimages": "$1 pranala berkas",
        "allmessagesdefault": "Tèks baku",
        "thumbnail-more": "Gedhèkna",
        "thumbnail_error": "Luput gole gawe gambar cilik (''thumbnail''): $1",
-       "tooltip-pt-userpage": "Kaca panganggone Rika",
+       "tooltip-pt-userpage": "{{GENDER:|Kaca panganggone}} Rika",
        "tooltip-pt-mytalk": "Kaca dhiskusine Rika",
-       "tooltip-pt-preferences": "Preferensine Rika",
+       "tooltip-pt-preferences": "Preferensine {{GENDER:|Rika}}",
        "tooltip-pt-watchlist": "Daftar kaca sing Rika awasi owah-owahane",
        "tooltip-pt-mycontris": "Daftar kontribusine Rika",
        "tooltip-pt-login": "Rika diajak kon mlebu log; senajan kuwe ora kudu.",
        "tooltip-t-whatlinkshere": "Daftar kabeh kaca wiki sing duwe pranala maring kaca kiye",
        "tooltip-t-recentchangeslinked": "Owahan anyar nang kaca sing gandeng karo kaca kiye",
        "tooltip-feed-atom": "''Atom feed'' kanggo kaca kiye",
-       "tooltip-t-contributions": "Deleng daftar kontribusine pangganggo kiye",
+       "tooltip-t-contributions": "Deleng daftar kontribusine pangganggo  {{GENDER:$1|kiye}}",
        "tooltip-t-emailuser": "Kirimna e-mail maring panganggo kiye",
        "tooltip-t-upload": "Unggahna gambar utawa berkas media",
        "tooltip-t-specialpages": "Daftar kabeh kaca astamiwa",
        "file-info-size": "$1 × $2 piksel, ukuran berkas: $3, tipe MIME: $4",
        "file-nohires": "Ora ana résolusi sing luwih dhuwur.",
        "svg-long-desc": "Berkas SVG, nominal $1 × $2 piksel, gedhené berkas: $3",
-       "show-big-image": "Résolusi kebak",
+       "show-big-image": "Resolusi biasa",
        "bad_image_list": "Formate kaya kiye:\n\nMung butir daftar (baris sing diawali karo tanda*) sing melu diitung.\nPranala disit dhewek nang baris kuwe kudu pranala maring berkas sing ala.\nPranala seteruse nang baris sing padha dianggep dadi \"pengecualian\", yakuwe artikel sing bisa nampilna berkas kuwe mau.",
        "metadata": "Metadata",
        "metadata-help": "Berkas kiye ngandhut informasi tambahan, sing ndeyane ditambahna sekang kamera digital utawa ''scanner'' sing digunakna nggo nggawe utawa ''digitalisasi'' berkas kiye.\nAngger berkas kiye uwis diowahi sekang versi asline, rincian sing ana ndeyane wis ora sacara kebak nidokna informasi sekang gambar sing wis dimodifikasi kiye.",
index 3ff2f81..8e9b13d 100644 (file)
        "noemail": "Нема заведено е-поштенска адреса за корисник „$1“.",
        "noemailcreate": "Потребно е да наведете важечка е-поштенска адреса",
        "passwordsent": "Нова лозинка е испратена на е-поштенската адреса заведена за „$1“.\nВе молиме најавете се повторно откако ќе ја примите пораката.",
-       "blocked-mailpassword": "Ð\92аÑ\88аÑ\82а IP-адÑ\80еÑ\81а Ðµ Ð±Ð»Ð¾ÐºÐ¸Ñ\80ана Ð·Ð° Ñ\83Ñ\80едÑ\83ваÑ\9aе, Ð¸Ñ\81Ñ\82овÑ\80емено Ðµ Ñ\81Ñ\82авена Ð·Ð°Ð±Ñ\80ана Ð·Ð° ÐºÐ¾Ñ\80иÑ\81Ñ\82еÑ\9aе Ð½Ð° Ñ\84Ñ\83нкÑ\86иÑ\98аÑ\82а Ð·Ð° Ð¾Ð±Ð½Ð¾Ð²Ð° Ð½Ð° Ð»Ð¾Ð·Ð¸Ð½ÐºÐ° Ð·Ð° Ð´Ð° Ñ\81е Ñ\81пÑ\80еÑ\87и Ð¼Ð¾Ð¶Ð½Ð¾Ñ\81Ñ\82а Ð·Ð° Ð·Ð»Ð¾Ñ\83поÑ\82Ñ\80еба.",
+       "blocked-mailpassword": "Ð\92аÑ\88аÑ\82а IP-адÑ\80еÑ\81а Ð¸Ð¼Ð° Ð·Ð°Ð±Ñ\80ана Ð·Ð° Ñ\83Ñ\80едÑ\83ваÑ\9aе. Ð\97а Ð´Ð° Ñ\81е Ñ\81пÑ\80еÑ\87и Ð·Ð»Ð¾Ñ\83поÑ\82Ñ\80еба, Ð½Ðµ Ðµ Ð´Ð¾Ð·Ð²Ð¾Ð»ÐµÐ½Ð¾ Ð¿Ð¾Ð²Ñ\80аÑ\82ок Ð½Ð° Ð»Ð¾Ð·Ð¸Ð½ÐºÐ° Ð¾Ð´ Ð½Ðµа.",
        "eauthentsent": "На назначената адреса е испратена потврдна порака.\nПред да се испрати друга порака на корисничката сметка, ќе морате да ги проследите напатствијата во пораката, за да потврдите дека таа корисничка сметка е навистина ваша.",
        "throttled-mailpassword": "Веќе е испратена порака за измена на лозинката во {{PLURAL:$1|изминатиов час|изминативе $1 часа}}.\nЗа да се спречи злоупотреба, само едно потсетување може да се праќа на {{PLURAL:$1|секој час|секои $1 часа}}.",
        "mailerror": "Грешка при испраќање на е-поштата: $1",
        "mergehistory-empty": "Нема преработки кои можат да се спојат.",
        "mergehistory-done": "$3 {{PLURAL:$3|преработка |преработки}} на $1 успешно {{PLURAL:$3|е споена|се споени}} во [[:$2]].",
        "mergehistory-fail": "Не е возможно да се направи спојување на историјата, проверете ја страницата и временските параметри.",
+       "mergehistory-fail-bad-timestamp": "Временската ознака е неважечка.",
+       "mergehistory-fail-invalid-source": "Изворната страница е неважечка.",
+       "mergehistory-fail-invalid-dest": "Целната страница е неважечка.",
+       "mergehistory-fail-permission": "Немате дозвола за да ја споите историјата.",
+       "mergehistory-fail-self-merge": "Изворната и целната страница се исти.",
        "mergehistory-fail-toobig": "Не можам да извршам спојување на историјата бидејќи така ќе се надмине границата од {{PLURAL:$1|една преработка|$1 преработки}}.",
        "mergehistory-no-source": "Изворната страница $1 не постои.",
        "mergehistory-no-destination": "Целната страница $1 не постои.",
        "editusergroup": "Уреди кориснички групи",
        "editinguser": "Менување на правата на {{GENDER:$1|корисникот}} <strong>[[User:$1|$1]]</strong> $2",
        "userrights-editusergroup": "Уреди ги корисничките групи",
-       "saveusergroups": "Зачувај ги корисничките групи",
+       "saveusergroups": "Зачувај ги {{GENDER:$1|корисничките}} групи",
        "userrights-groupsmember": "Член на:",
        "userrights-groupsmember-auto": "Подразбран член на:",
        "userrights-groups-help": "Можете да измените на кои групи припаѓа корисник:\n* Штиклирано - корисникот е во таа група.\n* Нештиклирано - корисникот не припаѓа на групата.\n* Ѕвездичка (*) - не можете да ја отстраните групата откако сте ја додале (и обратно).",
        "uploadstash-badtoken": "Не успеав да го извршам бараното дејство, можеби поради тоа што вашата сигурносна шифра е истечена. Обидете се повторно.",
        "uploadstash-errclear": "Чистењето на податотеките не успеа.",
        "uploadstash-refresh": "Превчитај го списокот на податотеки",
+       "uploadstash-thumbnail": "погл. минијатура",
        "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.",
        "confirm-unwatch-button": "ОК",
        "confirm-unwatch-top": "Да ја отстранам страницава од набљудуваните?",
        "confirm-rollback-button": "ОК",
+       "confirm-rollback-top": "Да ги отповикам уредувањата на страницава?",
        "percent": "$1&#160;%",
        "quotation-marks": "„$1“",
        "imgmultipageprev": "&larr; претходна страница",
        "log-action-filter-managetags-delete": "Бришење на ознаки",
        "log-action-filter-managetags-activate": "Активирање на ознаки",
        "log-action-filter-managetags-deactivate": "Деактивирање на ознаки",
-       "log-action-filter-move-move": "Преместување без запис врз пренасочувања"
+       "log-action-filter-move-move": "Преместување без запис врз пренасочувања",
+       "authmanager-authplugin-setpass-bad-domain": "Неважечки домен.",
+       "authmanager-autocreate-noperm": "Автоматското создавање на сметки не е дозволено.",
+       "authmanager-autocreate-exception": "Автоматското создавање на сметки е привремено оневозможено поради претходни грешки.",
+       "authmanager-userdoesnotexist": "Корисничката сметка „$1“ не е регистрирана.",
+       "authmanager-userlogin-remembermypassword-help": "Дали лозинката да биде запаметена подолго од траењето на седницата.",
+       "authmanager-username-help": "Корисничко име за заверка.",
+       "authmanager-password-help": "Лозинка за заверка.",
+       "authmanager-domain-help": "Домен за надворешна заверка.",
+       "authmanager-retype-help": "Повторно лозинката (за потврда).",
+       "authmanager-email-label": "Е-пошта",
+       "authmanager-email-help": "Е-пошта:",
+       "authmanager-realname-label": "Вистинско име",
+       "authmanager-realname-help": "Вистинско име на корисникот",
+       "authmanager-provider-password": "Заверка со лозинка",
+       "authmanager-provider-password-domain": "Заверка со лозинка и домен",
+       "authmanager-provider-temporarypassword": "Привремена лозинка",
+       "authprovider-resetpass-skip-label": "Прескокни",
+       "authprovider-resetpass-skip-help": "Прескокни го задавањето на нова лозинка."
 }
index d755f65..377b489 100644 (file)
        "whatlinkshere-next": "{{PLURAL:$1|راتلونکی|راتلونکي $1}}",
        "whatlinkshere-links": "← تړنې",
        "whatlinkshere-hideredirs": "مخ گرځونې $1",
-       "whatlinkshere-hidetrans": "پاÙ\8aÙ\84ې $1",
+       "whatlinkshere-hidetrans": "Ù\88رگÚ\89Û\90دÙ\86ې $1",
        "whatlinkshere-hidelinks": "تړنې $1",
        "whatlinkshere-hideimages": "د دوتنې تړنې $1",
        "whatlinkshere-filters": "چاڼگرونه",
index 99f90b9..2a3f404 100644 (file)
        "timezone-local": "Local",
        "duplicate-defaultsort": "Aviso: A chave de ordenação padrão \"$2\" sobrepõe-se à anterior chave de ordenação padrão \"$1\".",
        "duplicate-displaytitle": "<strong>Aviso:</strong> O título exibido \"$2\" substituí o título anterior \"$1\".",
-       "restricted-displaytitle": "<Strong>Aviso:</Strong> O título de exibição “$1” foi ignorado devido a não ser equivalente ao título verdadeiro da página.",
+       "restricted-displaytitle": "<strong>Aviso:</strong> O título de exibição “$1” foi ignorado devido a não ser equivalente ao título verdadeiro da página.",
        "invalid-indicator-name": "<strong>Erro:</strong> O atributo indicador do status da página <code>name</code> não deve estar vazio.",
        "version": "Versão",
        "version-extensions": "Extensões instaladas",
index 221512b..d7e4485 100644 (file)
        "cannotauth-not-allowed-title": "Доступ запрещён",
        "cannotauth-not-allowed": "Вы не можете использовать эту страницу",
        "changecredentials": "Изменение учётных данных",
-       "changecredentials-submit": "Изменить",
+       "changecredentials-submit": "Изменить учётные данные",
        "changecredentials-submit-cancel": "Отмена",
        "changecredentials-invalidsubpage": "$1 является недопустимым типом учётных данных.",
        "changecredentials-success": "Ваши учётные данные были изменены.",
        "removecredentials": "Удалить учётные данные",
-       "removecredentials-submit": "Удалить",
+       "removecredentials-submit": "Удалить учётные данные",
        "removecredentials-submit-cancel": "Отмена",
+       "credentialsform-provider": "Тип учётных данных:",
+       "credentialsform-account": "Имя учётной записи:",
        "linkaccounts": "Связать учётные записи",
        "linkaccounts-success-text": "Учетная запись была связана.",
        "linkaccounts-submit": "Связать учётные записи",
index b8d0b09..50fef14 100644 (file)
         *
         * This method is only available when jqueryMsg is loaded.
         *
+        * @since 1.27
         * @method parseDom
         * @member mw.Message
         * @return {jQuery}
index e681be0..82608b0 100644 (file)
@@ -1059,6 +1059,10 @@ class AuthManagerTest extends \MediaWikiTestCase {
                        } else {
                                $this->assertNotNull( $session->getSecret( 'AuthManager::authnState' ),
                                        "Response $i, session state" );
+                               foreach ( $ret->neededRequests as $neededReq ) {
+                                       $this->assertEquals( AuthManager::ACTION_LOGIN, $neededReq->action,
+                                               "Response $i, neededRequest action" );
+                               }
                                $this->assertEquals(
                                        $ret->neededRequests,
                                        $this->manager->getAuthenticationRequests( AuthManager::ACTION_LOGIN_CONTINUE ),
@@ -1114,6 +1118,7 @@ class AuthManagerTest extends \MediaWikiTestCase {
                $restartResponse2->createRequest = new CreateFromLoginAuthenticationRequest(
                        null, [ $req->getUniqueId() => $req ]
                );
+               $restartResponse2->createRequest->action = AuthManager::ACTION_LOGIN;
                $restartResponse2->neededRequests = [ $rememberReq, $restartResponse2->createRequest ];
 
                return [
@@ -2102,6 +2107,10 @@ class AuthManagerTest extends \MediaWikiTestCase {
                                        $this->request->getSession()->getSecret( 'AuthManager::accountCreationState' ),
                                        "Response $i, session state"
                                );
+                               foreach ( $ret->neededRequests as $neededReq ) {
+                                       $this->assertEquals( AuthManager::ACTION_CREATE, $neededReq->action,
+                                               "Response $i, neededRequest action" );
+                               }
                                $this->assertEquals(
                                        $ret->neededRequests,
                                        $this->manager->getAuthenticationRequests( AuthManager::ACTION_CREATE_CONTINUE ),
@@ -3525,6 +3534,10 @@ class AuthManagerTest extends \MediaWikiTestCase {
                                        $this->request->getSession()->getSecret( 'AuthManager::accountLinkState' ),
                                        "Response $i, session state"
                                );
+                               foreach ( $ret->neededRequests as $neededReq ) {
+                                       $this->assertEquals( AuthManager::ACTION_LINK, $neededReq->action,
+                                               "Response $i, neededRequest action" );
+                               }
                                $this->assertEquals(
                                        $ret->neededRequests,
                                        $this->manager->getAuthenticationRequests( AuthManager::ACTION_LINK_CONTINUE ),