Merge "Make HTMLCheckField::loadDataFromRequest always return a boolean"
authorjenkins-bot <jenkins-bot@gerrit.wikimedia.org>
Sat, 23 Apr 2016 17:01:32 +0000 (17:01 +0000)
committerGerrit Code Review <gerrit@wikimedia.org>
Sat, 23 Apr 2016 17:01:32 +0000 (17:01 +0000)
44 files changed:
docs/extension.schema.json
includes/DefaultSettings.php
includes/LinkTarget.php
includes/Linker.php
includes/Title.php
includes/api/i18n/ur.json [new file with mode: 0644]
includes/htmlform/HTMLForm.php
includes/htmlform/OOUIHTMLForm.php
includes/htmlform/VFormHTMLForm.php
includes/libs/eventrelayer/EventRelayerKafka.php
includes/libs/objectcache/BagOStuff.php
includes/libs/objectcache/MultiWriteBagOStuff.php
includes/logging/RightsLogFormatter.php
includes/objectcache/ObjectCache.php
includes/specials/pagers/ImageListPager.php
includes/title/TitleValue.php
languages/data/Names.php
languages/i18n/ar.json
languages/i18n/ast.json
languages/i18n/be-tarask.json
languages/i18n/da.json
languages/i18n/de.json
languages/i18n/en.json
languages/i18n/eo.json
languages/i18n/es.json
languages/i18n/fi.json
languages/i18n/gl.json
languages/i18n/he.json
languages/i18n/it.json
languages/i18n/ja.json
languages/i18n/nan.json
languages/i18n/nap.json
languages/i18n/pl.json
languages/i18n/qqq.json
languages/i18n/ru.json
languages/i18n/sr-ec.json
languages/i18n/sr-el.json
languages/i18n/sv.json
languages/i18n/uk.json
languages/i18n/ur.json
languages/i18n/zh-hans.json
tests/phpunit/includes/TitleTest.php
tests/phpunit/includes/libs/objectcache/BagOStuffTest.php
tests/phpunit/includes/title/TitleValueTest.php

index 370e18e..ab0ac24 100644 (file)
                                                                },
                                                                "skipFunction": {
                                                                        "type": "string",
-                                                                       "description": "Modules that provide fallback functionality can provide a \"skip function\". This function, if provided, will be passed along to the module registry on the client. When this module is loaded (either directly or as a dependency of another module), then this function is executed first. If the function returns true, the module will instantly be considered \"ready\" without requesting the associated module resources. The value returned here must be valid javascript for execution in a private function. It must not contain the \"function () {\" and \"}\" wrapper though."
+                                                                       "description": "Path to a file containing a JavaScript \"skip function\", if desired."
                                                                },
                                                                "scripts": {
                                                                        "type": ["string", "array"],
index 08084f4..2a30352 100644 (file)
@@ -2169,7 +2169,7 @@ $wgLanguageConverterCacheType = CACHE_ANYTHING;
  * given, giving a callable function which will generate a suitable cache object.
  */
 $wgObjectCaches = [
-       CACHE_NONE => [ 'class' => 'EmptyBagOStuff' ],
+       CACHE_NONE => [ 'class' => 'EmptyBagOStuff', 'reportDupes' => false ],
        CACHE_DB => [ 'class' => 'SqlBagOStuff', 'loggroup' => 'SQLBagOStuff' ],
 
        CACHE_ANYTHING => [ 'factory' => 'ObjectCache::newAnything' ],
@@ -2189,12 +2189,12 @@ $wgObjectCaches = [
                'loggroup'  => 'SQLBagOStuff'
        ],
 
-       'apc' => [ 'class' => 'APCBagOStuff' ],
-       'xcache' => [ 'class' => 'XCacheBagOStuff' ],
-       'wincache' => [ 'class' => 'WinCacheBagOStuff' ],
+       'apc' => [ 'class' => 'APCBagOStuff', 'reportDupes' => false ],
+       'xcache' => [ 'class' => 'XCacheBagOStuff', 'reportDupes' => false ],
+       'wincache' => [ 'class' => 'WinCacheBagOStuff', 'reportDupes' => false ],
        'memcached-php' => [ 'class' => 'MemcachedPhpBagOStuff', 'loggroup' => 'memcached' ],
        'memcached-pecl' => [ 'class' => 'MemcachedPeclBagOStuff', 'loggroup' => 'memcached' ],
-       'hash' => [ 'class' => 'HashBagOStuff' ],
+       'hash' => [ 'class' => 'HashBagOStuff', 'reportDupes' => false ],
 ];
 
 /**
index 8246f7d..b7132a8 100644 (file)
@@ -44,4 +44,14 @@ interface LinkTarget {
         */
        public function getText();
 
+       /**
+        * Creates a new LinkTarget for a different fragment of the same page.
+        * It is expected that the same type of object will be returned, but the
+        * only requirement is that it is a LinkTarget.
+        *
+        * @param string $fragment The fragment name, or "" for the entire page.
+        *
+        * @return LinkTarget
+        */
+       public function createFragmentTarget( $fragment );
 }
index a5c85a9..346ae28 100644 (file)
@@ -270,24 +270,23 @@ class Linker {
        /**
         * Returns the Url used to link to a Title
         *
-        * @param Title $target
+        * @param LinkTarget $target
         * @param array $query Query parameters
         * @param array $options
         * @return string
         */
-       private static function linkUrl( $target, $query, $options ) {
+       private static function linkUrl( LinkTarget $target, $query, $options ) {
                # We don't want to include fragments for broken links, because they
                # generally make no sense.
                if ( in_array( 'broken', $options, true ) && $target->hasFragment() ) {
-                       $target = clone $target;
-                       $target->setFragment( '' );
+                       $target = $target->createFragmentTarget( '' );
                }
 
                # If it's a broken link, add the appropriate query pieces, unless
                # there's already an action specified, or unless 'edit' makes no sense
                # (i.e., for a nonexistent special page).
                if ( in_array( 'broken', $options, true ) && empty( $query['action'] )
-                       && !$target->isSpecialPage() ) {
+                       && $target->getNamespace() !== NS_SPECIAL ) {
                        $query['action'] = 'edit';
                        $query['redlink'] = '1';
                }
@@ -300,7 +299,8 @@ class Linker {
                        $proto = PROTO_RELATIVE;
                }
 
-               $ret = $target->getLinkURL( $query, false, $proto );
+               $title = Title::newFromLinkTarget( $target );
+               $ret = $title->getLinkURL( $query, false, $proto );
                return $ret;
        }
 
index 3fd4631..7368bb0 100644 (file)
@@ -1376,7 +1376,8 @@ class Title implements LinkTarget {
         * specified fragment before setting, so it assumes you're passing it with
         * an initial "#".
         *
-        * Deprecated for public use, use Title::makeTitle() with fragment parameter.
+        * Deprecated for public use, use Title::makeTitle() with fragment parameter,
+        * or Title::createFragmentTarget().
         * Still in active use privately.
         *
         * @private
@@ -1386,6 +1387,23 @@ class Title implements LinkTarget {
                $this->mFragment = strtr( substr( $fragment, 1 ), '_', ' ' );
        }
 
+       /**
+        * Creates a new Title for a different fragment of the same page.
+        *
+        * @since 1.27
+        * @param string $fragment
+        * @return Title
+        */
+       public function createFragmentTarget( $fragment ) {
+               return self::makeTitle(
+                       $this->getNamespace(),
+                       $this->getText(),
+                       $fragment,
+                       $this->getInterwiki()
+               );
+
+       }
+
        /**
         * Prefix some arbitrary text with the namespace or interwiki prefix
         * of this object
diff --git a/includes/api/i18n/ur.json b/includes/api/i18n/ur.json
new file mode 100644 (file)
index 0000000..c0f1bcf
--- /dev/null
@@ -0,0 +1,8 @@
+{
+       "@metadata": {
+               "authors": [
+                       "Obaid Raza"
+               ]
+       },
+       "apihelp-delete-example-simple": "حذف <kbd>صفحۂ اول</kbd>."
+}
index 2b6a0aa..6f88975 100644 (file)
@@ -1146,10 +1146,12 @@ class HTMLForm extends ContextSource {
                        }
                }
 
-               $html = Html::rawElement( 'span',
-                       [ 'class' => 'mw-htmlform-submit-buttons' ], "\n$buttons" ) . "\n";
+               if ( !$buttons ) {
+                       return '';
+               }
 
-               return $html;
+               return Html::rawElement( 'span',
+                       [ 'class' => 'mw-htmlform-submit-buttons' ], "\n$buttons" ) . "\n";
        }
 
        /**
index 4f8365e..278d453 100644 (file)
@@ -121,10 +121,12 @@ class OOUIHTMLForm extends HTMLForm {
                        ] + $attrs );
                }
 
-               $html = Html::rawElement( 'div',
-                       [ 'class' => 'mw-htmlform-submit-buttons' ], "\n$buttons" ) . "\n";
+               if ( !$buttons ) {
+                       return '';
+               }
 
-               return $html;
+               return Html::rawElement( 'div',
+                       [ 'class' => 'mw-htmlform-submit-buttons' ], "\n$buttons" ) . "\n";
        }
 
        protected function wrapFieldSetSection( $legend, $section, $attributes ) {
index c446615..f3cba48 100644 (file)
@@ -137,9 +137,11 @@ class VFormHTMLForm extends HTMLForm {
                        $buttons .= Html::element( 'input', $attrs ) . "\n";
                }
 
-               $html = Html::rawElement( 'div',
-                       [ 'class' => 'mw-htmlform-submit-buttons' ], "\n$buttons" ) . "\n";
+               if ( !$buttons ) {
+                       return '';
+               }
 
-               return $html;
+               return Html::rawElement( 'div',
+                       [ 'class' => 'mw-htmlform-submit-buttons' ], "\n$buttons" ) . "\n";
        }
 }
index 3555a23..999eb43 100644 (file)
@@ -7,7 +7,6 @@ use Kafka\Produce;
  * 'relayerConfig' => [ 'class' => 'EventRelayerKafka', 'KafkaEventHost' => 'localhost:9092' ],
  */
 class EventRelayerKafka extends EventRelayer {
-
        /**
         * Configuration.
         *
@@ -25,9 +24,11 @@ class EventRelayerKafka extends EventRelayer {
        /**
         * Create Kafka producer.
         *
-        * @param Config $config
+        * @param array $params
         */
        public function __construct( array $params ) {
+               parent::__construct( $params );
+
                $this->config = new HashConfig( $params );
                if ( !$this->config->has( 'KafkaEventHost' ) ) {
                        throw new InvalidArgumentException( "KafkaEventHost must be configured" );
@@ -40,17 +41,12 @@ class EventRelayerKafka extends EventRelayer {
         */
        protected function getKafkaProducer() {
                if ( !$this->producer ) {
-                       $this->producer = Produce::getInstance( null, null, $this->config->get( 'KafkaEventHost' ) );
+                       $this->producer = Produce::getInstance(
+                               null, null, $this->config->get( 'KafkaEventHost' ) );
                }
                return $this->producer;
        }
 
-       /**
-        * (non-PHPdoc)
-        *
-        * @see EventRelayer::doNotify()
-        *
-        */
        protected function doNotify( $channel, array $events ) {
                $jsonEvents = array_map( 'json_encode', $events );
                try {
index 1aed280..8e3c0a5 100644 (file)
@@ -55,9 +55,21 @@ abstract class BagOStuff implements IExpiringStore, LoggerAwareInterface {
        /** @var LoggerInterface */
        protected $logger;
 
+       /** @var callback|null */
+       protected $asyncHandler;
+
        /** @var bool */
        private $debugMode = false;
 
+       /** @var array */
+       private $duplicateKeyLookups = [];
+
+       /** @var bool */
+       private $reportDupes = false;
+
+       /** @var bool */
+       private $dupeTrackScheduled = false;
+
        /** Possible values for getLastError() */
        const ERR_NONE = 0; // no error
        const ERR_NO_RESPONSE = 1; // no response
@@ -71,6 +83,16 @@ abstract class BagOStuff implements IExpiringStore, LoggerAwareInterface {
        const WRITE_SYNC = 1; // synchronously write to all locations for replicated stores
        const WRITE_CACHE_ONLY = 2; // Only change state of the in-memory cache
 
+       /**
+        * $params include:
+        *   - logger: Psr\Log\LoggerInterface instance
+        *   - keyspace: Default keyspace for $this->makeKey()
+        *   - asyncHandler: Callable to use for scheduling tasks after the web request ends.
+        *      In CLI mode, it should run the task immediately.
+        *   - reportDupes: Whether to emit warning log messages for all keys that were
+        *      requested more than once (requires an asyncHandler).
+        * @param array $params
+        */
        public function __construct( array $params = [] ) {
                if ( isset( $params['logger'] ) ) {
                        $this->setLogger( $params['logger'] );
@@ -81,6 +103,14 @@ abstract class BagOStuff implements IExpiringStore, LoggerAwareInterface {
                if ( isset( $params['keyspace'] ) ) {
                        $this->keyspace = $params['keyspace'];
                }
+
+               $this->asyncHandler = isset( $params['asyncHandler'] )
+                       ? $params['asyncHandler']
+                       : null;
+
+               if ( !empty( $params['reportDupes'] ) && is_callable( $this->asyncHandler ) ) {
+                       $this->reportDupes = true;
+               }
        }
 
        /**
@@ -144,9 +174,44 @@ abstract class BagOStuff implements IExpiringStore, LoggerAwareInterface {
                // B/C for ( $key, &$casToken = null, $flags = 0 )
                $flags = is_int( $oldFlags ) ? $oldFlags : $flags;
 
+               $this->trackDuplicateKeys( $key );
+
                return $this->doGet( $key, $flags );
        }
 
+       /**
+        * Track the number of times that a given key has been used.
+        * @param string $key
+        */
+       private function trackDuplicateKeys( $key ) {
+               if ( !$this->reportDupes ) {
+                       return;
+               }
+
+               if ( !isset( $this->duplicateKeyLookups[$key] ) ) {
+                       // Track that we have seen this key. This N-1 counting style allows
+                       // easy filtering with array_filter() later.
+                       $this->duplicateKeyLookups[$key] = 0;
+               } else {
+                       $this->duplicateKeyLookups[$key] += 1;
+
+                       if ( $this->dupeTrackScheduled === false ) {
+                               $this->dupeTrackScheduled = true;
+                               // Schedule a callback that logs keys processed more than once by get().
+                               call_user_func( $this->asyncHandler, function () {
+                                       $dups = array_filter( $this->duplicateKeyLookups );
+                                       foreach ( $dups as $key => $count ) {
+                                               $this->logger->warning(
+                                                       'Duplicate get(): "{key}" fetched {count} times',
+                                                       // Count is N-1 of the actual lookup count
+                                                       [ 'key' => $key, 'count' => $count + 1, ]
+                                               );
+                                       }
+                               } );
+                       }
+               }
+       }
+
        /**
         * @param string $key
         * @param integer $flags Bitfield of BagOStuff::READ_* constants [optional]
index 3e88cb1..fe61470 100644 (file)
@@ -33,8 +33,6 @@ class MultiWriteBagOStuff extends BagOStuff {
        protected $caches;
        /** @var bool Use async secondary writes */
        protected $asyncWrites = false;
-       /** @var callback|null */
-       protected $asyncHandler;
 
        /** Idiom for "write to all backends" */
        const ALL = INF;
@@ -58,8 +56,6 @@ class MultiWriteBagOStuff extends BagOStuff {
         *      safe to use for modules when cached values: are immutable,
         *      invalidation uses logical TTLs, invalidation uses etag/timestamp
         *      validation against the DB, or merge() is used to handle races.
-        *   - asyncHandler: callable that takes a callback and runs it after the
-        *      current web request ends. In CLI mode, it should run it immediately.
         * @param array $params
         * @throws InvalidArgumentException
         */
@@ -88,9 +84,6 @@ class MultiWriteBagOStuff extends BagOStuff {
                        }
                }
 
-               $this->asyncHandler = isset( $params['asyncHandler'] )
-                       ? $params['asyncHandler']
-                       : null;
                $this->asyncWrites = (
                        isset( $params['replication'] ) &&
                        $params['replication'] === 'async' &&
index 1fd4b7f..be73c86 100644 (file)
@@ -97,13 +97,15 @@ class RightsLogFormatter extends LogFormatter {
                        $params[3] = $this->msg( 'rightsnone' )->text();
                }
                if ( count( $newGroups ) ) {
-                       // Array_values is used here because of bug 42211
+                       // Array_values is used here because of T44211
                        // see use of array_unique in UserrightsPage::doSaveUserGroups on $newGroups.
                        $params[4] = $lang->listToText( array_values( $newGroups ) );
                } else {
                        $params[4] = $this->msg( 'rightsnone' )->text();
                }
 
+               $params[5] = $userName;
+
                return $params;
        }
 
index 6d26419..bf152b6 100644 (file)
@@ -174,11 +174,13 @@ class ObjectCache {
                } elseif ( isset( $params['class'] ) ) {
                        $class = $params['class'];
                        // Automatically set the 'async' update handler
-                       if ( $class === 'MultiWriteBagOStuff' ) {
-                               $params['asyncHandler'] = isset( $params['asyncHandler'] )
-                                       ? $params['asyncHandler']
-                                       : 'DeferredUpdates::addCallableUpdate';
-                       }
+                       $params['asyncHandler'] = isset( $params['asyncHandler'] )
+                               ? $params['asyncHandler']
+                               : 'DeferredUpdates::addCallableUpdate';
+                       // Enable reportDupes by default
+                       $params['reportDupes'] = isset( $params['reportDupes'] )
+                               ? $params['reportDupes']
+                               : true;
                        // Do b/c logic for MemcachedBagOStuff
                        if ( is_subclass_of( $class, 'MemcachedBagOStuff' ) ) {
                                if ( !isset( $params['servers'] ) ) {
index 45fe5c4..40706fa 100644 (file)
@@ -490,7 +490,7 @@ class ImageListPager extends TablePager {
                        case 'img_description':
                                return Linker::formatComment( $value );
                        case 'count':
-                               return intval( $value ) + 1;
+                               return $this->getLanguage()->formatNum( intval( $value ) + 1 );
                        case 'top':
                                // Messages: listfiles-latestversion-yes, listfiles-latestversion-no
                                return $this->msg( 'listfiles-latestversion-' . $value );
index 18a06ea..a0a7b1d 100644 (file)
@@ -131,11 +131,12 @@ class TitleValue implements LinkTarget {
        /**
         * Creates a new TitleValue for a different fragment of the same page.
         *
+        * @since 1.27
         * @param string $fragment The fragment name, or "" for the entire page.
         *
         * @return TitleValue
         */
-       public function createFragmentTitle( $fragment ) {
+       public function createFragmentTarget( $fragment ) {
                return new TitleValue( $this->namespace, $this->dbkey, $fragment );
        }
 
index 994eb09..a7de1f9 100644 (file)
@@ -84,7 +84,7 @@ class Names {
                'bbc-latn' => 'Batak Toba', # Batak Toba
                'bcc' => 'جهلسری بلوچی', # Southern Balochi
                'bcl' => 'Bikol Central', # Bikol: Central Bicolano language
-               'be' => 'беларуская', #  Belarusian normative
+               'be' => 'беларуская', # Belarusian normative
                'be-tarask' => "беларуская (тарашкевіца)\xE2\x80\x8E", # Belarusian in Taraskievica orthography
                'be-x-old' => "беларуская (тарашкевіца)\xE2\x80\x8E", # (be-tarask compat)
                'bg' => 'български', # Bulgarian
@@ -384,8 +384,8 @@ class Names {
                'so' => 'Soomaaliga', # Somali
                'sq' => 'shqip', # Albanian
                'sr' => 'српски / srpski', # Serbian (multiple scripts - defaults to Cyrillic)
-               'sr-ec' => "српски (ћирилица)\xE2\x80\x8E",       # Serbian Cyrillic ekavian
-               'sr-el' => "srpski (latinica)\xE2\x80\x8E",     # Serbian Latin ekavian
+               'sr-ec' => "српски (ћирилица)\xE2\x80\x8E", # Serbian Cyrillic ekavian
+               'sr-el' => "srpski (latinica)\xE2\x80\x8E", # Serbian Latin ekavian
                'srn' => 'Sranantongo', # Sranan Tongo
                'ss' => 'SiSwati', # Swati
                'st' => 'Sesotho', # Southern Sotho
@@ -427,9 +427,9 @@ class Names {
                'ug-latn' => 'Uyghurche', # Uyghur (Latin script)
                'uk' => 'українська', # Ukrainian
                'ur' => 'اردو', # Urdu
-               'uz' => 'oʻzbekcha/ўзбекча',    # Uzbek (multiple scripts - defaults to Latin)
-               'uz-cyrl' => 'ўзбекча',  # Uzbek Cyrillic
-               'uz-latn' => 'oʻzbekcha',      # Uzbek Latin (default)
+               'uz' => 'oʻzbekcha/ўзбекча', # Uzbek (multiple scripts - defaults to Latin)
+               'uz-cyrl' => 'ўзбекча', # Uzbek Cyrillic
+               'uz-latn' => 'oʻzbekcha', # Uzbek Latin (default)
                've' => 'Tshivenda', # Venda
                'vec' => 'vèneto', # Venetian
                'vep' => 'vepsän kel’', # Veps
index c3f3afc..04a111c 100644 (file)
@@ -77,6 +77,7 @@
        "tog-watchdefault": "أضف الصفحات والملفات التي أعدلها إلى قائمة مراقبتي",
        "tog-watchmoves": "أضف الصفحات والملفات التي أنقلها إلى قائمة مراقبتي",
        "tog-watchdeletion": "أضف الصفحات والملفات التي أحذفها إلى قائمة مراقبتي",
+       "tog-watchuploads": "أضف الملفات الجديدة التي رفعتها إلى قائمة مراقبتي",
        "tog-watchrollback": "أضف إلى قائمة مراقبتي الصفحات التي كنت أجريت فيها استرجاعات",
        "tog-minordefault": "أشِّر كل التعديلات على أنها طفيفة مبدئيا",
        "tog-previewontop": "أظهر معاينة النص فوق صندوق التحرير",
index 07317f0..c5f50c6 100644 (file)
        "logentry-protect-protect-cascade": "$1 {{GENDER:$2|protexó}} a $3 $4 [en cascada]",
        "logentry-protect-modify": "$1 {{GENDER:$2|camudó}} el nivel de protección de $3 $4",
        "logentry-protect-modify-cascade": "$1 {{GENDER:$2|camudó}} el nivel de protección de $3 $4 [en cascada]",
-       "logentry-rights-rights": "$1 {{GENDER:$2|camudó}} la pertenencia a grupos de {{GENDER:$3|$3}} dende $4 a $5",
+       "logentry-rights-rights": "$1 {{GENDER:$2|camudó}} la pertenencia a grupos de {{GENDER:$6|$3}} dende $4 a $5",
        "logentry-rights-rights-legacy": "$1 {{GENDER:$2|camudó}} la pertenencia a grupos de $3",
        "logentry-rights-autopromote": "$1 {{GENDER:$2|promocionó}} automáticamente de $4 a $5",
        "logentry-upload-upload": "$1 {{GENDER:$2|xubió}} $3",
index 4216c9d..60cd0a6 100644 (file)
        "apisandbox-submit-invalid-fields-title": "Некаторыя палі няслушныя",
        "apisandbox-submit-invalid-fields-message": "Калі ласка, выпраўце пазначаныя палі і паспрабуйце яшчэ раз.",
        "apisandbox-results": "Вынікі",
+       "apisandbox-sending-request": "Адпраўка API-запыту…",
        "apisandbox-request-url-label": "URL-адрас запыту:",
        "apisandbox-request-time": "Час запыту: {{PLURAL:$1|$1 мс}}",
        "booksources": "Крыніцы кніг",
        "logentry-protect-protect-cascade": "$1 {{GENDER:$2|абараніў|абараніла}} $3 $4 [каскадна]",
        "logentry-protect-modify": "$1 {{GENDER:$2|зьмяніў узровень|зьмяніла ўзровень}} абароны для $3 $4",
        "logentry-protect-modify-cascade": "$1 {{GENDER:$2|зьмяніў узровень|зьмяніла ўзровень}} абароны для $3 $4 [каскадна]",
-       "logentry-rights-rights": "$1 {{GENDER:$2|зьмяніў|зьмяніла}} прыналежнасьць {{GENDER:$3|$3}} да групы з $4 на $5",
+       "logentry-rights-rights": "$1 {{GENDER:$2|зьмяніў|зьмяніла}} прыналежнасьць {{GENDER:$6|$3}} да групы з $4 на $5",
        "logentry-rights-rights-legacy": "$1 {{GENDER:$1|зьмяніў|зьмяніла}} прыналежнасьць $3 да групаў",
        "logentry-rights-autopromote": "$1 {{GENDER:$1|быў аўтаматычна пераведзены|была аўтаматычна пераведзеная}} з групы $4 ў $5",
        "logentry-upload-upload": "$1 {{GENDER:$2|загрузіў|загрузіла}} $3",
index 77e9418..2a80b92 100644 (file)
        "botpasswords-label-delete": "Slet",
        "botpasswords-label-resetpassword": "Nulstil adgangskode",
        "botpasswords-label-grants": "Tilgængelige bevillinger:",
+       "botpasswords-label-restrictions": "Begrænsninger for brug:",
        "resetpass_forbidden": "Adgangskoder kan ikke ændres",
        "resetpass-no-info": "Du skal være logget på for at komme direkte til denne side.",
        "resetpass-submit-loggedin": "Skift adgangskode",
        "mergehistory-empty": "Der findes ingen sammenflettelige udgaver",
        "mergehistory-done": "$3 {{PLURAL:$3|version|versioner}} af $1 blev flettet sammen med [[:$2]].",
        "mergehistory-fail": "Sammenfletningen kunne ikke gennemføres. Vær venlig at kontrollere sidenavne og tidsafgrænsning.",
+       "mergehistory-fail-bad-timestamp": "Tidsangivelsen er ugyldig.",
        "mergehistory-fail-toobig": "Ude af stand til at flette historiken sammen, fordi flere end grænsen på $1 {{PLURAL:$1|version|versioner}} ville blive flyttet.",
        "mergehistory-no-source": "Kildesiden $1 findes ikke.",
        "mergehistory-no-destination": "Destinationssiden $1 findes ikke.",
        "userrights": "Håndtering af brugerrettigheder",
        "userrights-lookup-user": "Administrér brugergrupper",
        "userrights-user-editname": "Skriv et brugernavn:",
-       "editusergroup": "Redigér brugergrupper",
+       "editusergroup": "Redigér {{GENDER:$1|brugergrupper}}",
        "editinguser": "Ændrer brugerrettigheder for {{GENDER:$1|brugeren}} <strong>[[User:$1|$1]]</strong> $2",
        "userrights-editusergroup": "Redigér brugergrupper",
-       "saveusergroups": "Gem brugergrupper",
+       "saveusergroups": "Gem {{GENDER:$1|brugergrupper}}",
        "userrights-groupsmember": "Medlem af:",
        "userrights-groupsmember-auto": "Implicit medlem af:",
        "userrights-groups-help": "Du kan ændre denne brugers gruppemedlemsskaber:\n* Et markeret afkrydsningsfelt betyder at brugeren er medlen af den pågældende gruppe.\n* Et umarkeret felt betyder at brugeren ikke er medlem af gruppen.\n* En * betyder at du ikke kan fravælge gruppen, når den først er tilføjet og omvendt.",
        "upload-dialog-button-done": "Færdig",
        "upload-dialog-button-save": "Gem",
        "upload-dialog-button-upload": "Læg op",
+       "upload-form-label-infoform-title": "Detaljer",
        "upload-form-label-infoform-name": "Navn",
        "upload-form-label-infoform-description": "Beskrivelse",
        "upload-form-label-usage-filename": "Filnavn",
        "mostrevisions": "Sider med de fleste ændringer",
        "prefixindex": "Alle sider der begynder med",
        "prefixindex-namespace": "Alle sider (i navnerummet $1) der begynder med",
+       "prefixindex-submit": "Vis",
        "prefixindex-strip": "Strip præfiks i listen",
        "shortpages": "Korte sider",
        "longpages": "Lange sider",
        "usereditcount": "{{PLURAL:$1|én redigering|$1 redigeringer}}",
        "usercreated": "{{GENDER:$3|Oprettet}} den $1 $2",
        "newpages": "Nyeste sider",
+       "newpages-submit": "Vis",
        "newpages-username": "Brugernavn:",
        "ancientpages": "Ældste sider",
        "move": "Flyt",
        "apisandbox-intro": "Brug denne side til at eksperimentere med '''MediaWiki web service API'''.\nVi henviser til [//www.mediawiki.org/wiki/API:Main_page dokumentationen af API] for yderligere oplysninger om brug af API.  Eksempel: [//www.mediawiki.org/wiki/API#A_simple_example få indholdet af en forside]. Vælg en handling at se flere eksempler.\n\nBemærk, at selv om dette er en sandkasse, vil handlinger du udfører på denne side redigere wikien.",
        "apisandbox-submit": "Lav forespørgsel",
        "apisandbox-reset": "Ryd",
-       "apisandbox-examples": "Eksempel",
-       "apisandbox-results": "Resultat",
+       "apisandbox-examples": "Eksempler",
+       "apisandbox-results": "Resultater",
        "apisandbox-request-url-label": "Forespurgt URL:",
-       "apisandbox-request-time": "Forespørgselstid: $1",
+       "apisandbox-request-time": "Forespørgselstid: {{PLURAL:$1|$1 ms}}",
        "booksources": "Bogkilder",
        "booksources-search-legend": "Søgning efter bøger",
        "booksources-search": "Søg",
        "rollback-success": "Ændringerne fra $1 er fjernet,\nog den seneste version af $2 er gendannet.",
        "sessionfailure-title": "Sessionsfejl",
        "sessionfailure": "Der lader til at være et problem med din loginsession; denne handling blev annulleret som en sikkerhedsforanstaltning mod kapring af sessionen. Tryk på \"tilbage\"-knappen og genindlæs den side du kom fra, og prøv dernæst igen.",
+       "changecontentmodel-title-label": "Sidetitel",
+       "changecontentmodel-reason-label": "Begrundelse:",
        "protectlogpage": "Skrivebeskyttelseslog",
        "protectlogtext": "Herunder er en liste over ændringer til sidebeskyttelser.\nSe [[Special:ProtectedPages|listen over beskyttede sider]] for listen over sidebeskyttelser, der er i kraft i øjeblikket.",
        "protectedarticle": "[[$1]] beskyttet",
        "movenotallowedfile": "Du har ikke tilladelse til at flytte filer.",
        "cant-move-user-page": "Du har ikke tilladelse til at flytte brugersider (bortset fra undersider).",
        "cant-move-to-user-page": "Du har ikke tilladelse til at flytte brugersider (bortset fra til brugerundersider).",
-       "newtitle": "Til ny titel",
+       "newtitle": "Ny titel:",
        "move-watch": "Overvåg siden",
        "movepagebtn": "Flyt side",
        "pagemovedsub": "Flytning gennemført",
        "version-libraries": "Installerede biblioteker",
        "version-libraries-library": "Bibliotek",
        "version-libraries-version": "Version",
+       "version-libraries-license": "Licens",
+       "version-libraries-description": "Beskrivelse",
+       "version-libraries-authors": "Forfattere",
        "redirect": "Omdirigering pga. fil, bruger-, side- eller udgave-ID",
        "redirect-summary": "Denne specialside omdirigerer til en fil (hvis filnavnet er angivet), en side (hvis udgave ID'et eller side ID'et er angivet) eller en brugerside (hvis et numerisk brugernummer er angivet). Eksempler på brug: [[{{#Special:Redirect}}/file/Example.jpg]], [[{{#Special:Redirect}}/page/64308]],[[{{#Special:Redirect}}/revision/328429]] eller [[{{#Special:Redirect}}/user/101]].",
        "redirect-submit": "Vis",
        "tags-activate-submit": "Aktiver",
        "tags-deactivate-reason": "Årsag:",
        "tags-deactivate-submit": "Deaktiver",
-       "tags-edit-existing-tags-none": "\"Ingen\"",
+       "tags-edit-existing-tags-none": "<em>Ingen</em>",
        "tags-edit-reason": "Årsag:",
        "comparepages": "Sammenlign sider",
        "compare-page1": "Side 1",
        "feedback-subject": "Emne:",
        "feedback-submit": "Send",
        "feedback-thanks": "Tak! Dine tilbagemeldinger er blevet noteret på siden \"[$2 $1]\".",
+       "feedback-thanks-title": "Tak!",
        "searchsuggest-search": "Søg",
        "searchsuggest-containing": "indeholder...",
        "api-error-badaccess-groups": "Du har ikke tilladelse til at overføre filer til denne wiki.",
        "limitreport-ppvisitednodes": "Antal nodebesøg for preprocessor",
        "limitreport-ppgeneratednodes": "Antal noder genereret af preprocessor",
        "limitreport-postexpandincludesize": "Inkluderet størrelse efter udvidelse",
+       "limitreport-postexpandincludesize-value": "$1/$2 {{PLURAL:$2|byte|bytes}}",
        "limitreport-templateargumentsize": "Skabelon argumentstørrelse",
+       "limitreport-templateargumentsize-value": "$1/$2 {{PLURAL:$2|byte|bytes}}",
        "limitreport-expansiondepth": "Største udvidelsesdybde",
        "limitreport-expensivefunctioncount": "Antal dyre parserfunktioner",
        "expandtemplates": "Udfold skabeloner",
        "pagelang-select-lang": "Vælg sprog",
        "right-pagelang": "Ændre sidesproget",
        "mediastatistics": "Mediestatistik",
+       "mediastatistics-table-mimetype": "MIME-type",
+       "mediastatistics-table-extensions": "Mulige filendelser",
        "mediastatistics-table-count": "Antal filer",
        "mediastatistics-table-totalbytes": "Samlet størrelse",
        "mediastatistics-header-unknown": "Ukendt",
        "mediastatistics-header-text": "Tekstformat",
        "mediastatistics-header-executable": "Kørbare filer",
        "mediastatistics-header-archive": "Komprimerede formater",
+       "mediastatistics-header-total": "Alle filer",
        "json-error-state-mismatch": "Ugyldig eller fejlbehæftet JSON",
        "json-error-syntax": "Syntaksfejl",
        "special-characters-group-latin": "Latin",
index 0b1a874..cb8e74c 100644 (file)
        "logentry-protect-protect-cascade": "$1 {{GENDER:$2|schützte}} die Seite $3 $4 [kaskadierend]",
        "logentry-protect-modify": "$1 {{GENDER:$2|änderte}} den Schutzstatus der Seite $3 $4",
        "logentry-protect-modify-cascade": "$1 {{GENDER:$2|änderte}} den Schutzstatus der Seite $3 $4 [kaskadierend]",
-       "logentry-rights-rights": "$1 {{GENDER:$2|änderte}} die Gruppenzugehörigkeit für {{GENDER:$3|$3}} von $4 zu $5",
+       "logentry-rights-rights": "$1 {{GENDER:$2|änderte}} die Gruppenzugehörigkeit für {{GENDER:$6|$3}} von $4 zu $5",
        "logentry-rights-rights-legacy": "$1 {{GENDER:$2|änderte}} die Gruppenzugehörigkeit für $3",
        "logentry-rights-autopromote": "$1 wurde automatisch von $4 zu $5 {{GENDER:$2|zugeordnet}}",
        "logentry-upload-upload": "$1 {{GENDER:$2|lud}} $3 hoch",
index f2cdbe2..fb10358 100644 (file)
        "logentry-protect-protect-cascade": "$1 {{GENDER:$2|protected}} $3 $4 [cascading]",
        "logentry-protect-modify": "$1 {{GENDER:$2|changed}} protection level for $3 $4",
        "logentry-protect-modify-cascade": "$1 {{GENDER:$2|changed}} protection level for $3 $4 [cascading]",
-       "logentry-rights-rights": "$1 {{GENDER:$2|changed}} group membership for {{GENDER:$3|$3}} from $4 to $5",
+       "logentry-rights-rights": "$1 {{GENDER:$2|changed}} group membership for {{GENDER:$6|$3}} from $4 to $5",
        "logentry-rights-rights-legacy": "$1 {{GENDER:$2|changed}} group membership for $3",
        "logentry-rights-autopromote": "$1 was automatically {{GENDER:$2|promoted}} from $4 to $5",
        "logentry-upload-upload": "$1 {{GENDER:$2|uploaded}} $3",
index ddf8744..ad2d3a1 100644 (file)
        "botpasswords-label-cancel": "Nuligi",
        "botpasswords-label-delete": "Forigi",
        "botpasswords-label-resetpassword": "Rekomencigi la pasvorton",
+       "botpasswords-label-grants": "Aplikeblaj permesdonoj:",
+       "botpasswords-help-grants": "Ĉiu permesdono provizas aliron al listitaj uzantaj permisoj, kiujn uzantkonto jam havas. Vidu la [[Special:ListGrants|tabelon de permisdonoj]] por pli da informo.",
        "botpasswords-label-restrictions": "Limigoj de uzado:",
+       "botpasswords-label-grants-column": "Permisdonita",
        "botpasswords-bad-appid": "La robota nomo \"$1\" estas malvalida.",
        "botpasswords-insert-failed": "Aldono de la robota nomo \"$1\" ne sukcesis. Ĉu ĝi jam estis aldonita?",
        "botpasswords-update-failed": "Ĝisdatigo de la robota nomo \"$1\" ne sukcesis. Ĉu ĝi estis forigita?",
        "botpasswords-updated-body": "La robota pasvorto por robota nomo \"$1\" de la uzanto \"$2\" estis ĝisdatigita.",
        "botpasswords-deleted-title": "Robota pasvorto forigita",
        "botpasswords-deleted-body": "La robota pasvorto por robota nomo \"$1\" de la uzanto \"$2\" estis forigita.",
+       "botpasswords-newpassword": "La nova pasvorto por ensaluti kun <strong>$1</strong> estas <strong>$2</strong>. <em>Bonvolu registri tiun por referenconto.",
+       "botpasswords-no-provider": "Robotopasvortensalutoprovizilo (''BotPasswordsSessionProvider'') maldisponeblas.",
+       "botpasswords-restriction-failed": "Limigoj pri robota pasvorto maleblas tiun uzantonomon.",
+       "botpasswords-invalid-name": "La difinita uzantnomo malenhavas la robotopasvortan disigilon (\"$1\").",
+       "botpasswords-not-exist": "Uzanto \"$1\" ne havas robotopasvorton, kiu nomiĝas \"$2\".",
        "resetpass_forbidden": "Pasvortoj ne estas ŝanĝeblaj",
        "resetpass-no-info": "Vi devas ensaluti por atingi ĉi tiun paĝon rekte.",
        "resetpass-submit-loggedin": "Ŝanĝi pasvorton",
        "passwordreset-emailtext-user": "Uzanto $1 de {{SITENAME}} petis restarigo de via pasvorto por {{SITENAME}}\n($4). La {{PLURAL:$3|jena uzanto-konto estas asociita|jenaj uzanto-kontoj estas asociitaj}} kun ĉi tiu retpoŝtadreso:\n\n$2\n\nĈi {{PLURAL:$3|tiu provizora pasvorto|tiuj provizoraj pasvortoj}} findatiĝos {{PLURAL:$5|unu tagon|$5 tagojn}}.\nVi devas ensaluti kaj elekti novan pasvorton nun. Se iu alia petis ĉi tion,\naŭ se vi memoris vian originalan pasvorton, kaj vi ne plu volas ŝanĝi\nĝin, vi povas ignori ĉi tiun mesaĝon kaj uzi vian malnovan pasvorton.",
        "passwordreset-emailelement": "Salutnomo: \n$1\n\nProvizora pasvorto: \n$2",
        "passwordreset-emailsentemail": "Se tiu ĉu retpoŝta adreso estas kunligita kun via konto, tiam al ĉi tiu adreso estos sendita retpoŝto por renovigi pasvorton.",
+       "passwordreset-emailsentusername": "Se estas retpoŝta adreso, kiu estas asocigita kun tiu uzantnomo, tiam sendos retpôstan mesaĝon pri reasigno de pasvorto.",
        "passwordreset-emailsent-capture": "Retpoŝto kun renovigita pasvorto estis sendita, kiu estas montrata malsupre.",
        "passwordreset-emailerror-capture": "Retpoŝto kun renovigita pasvorto estis generita, montrata sube, sed sendado al la {{GENDER:$2|uzanto}} malsukcesis: $1",
        "changeemail": "Ŝanĝi aŭ forigi retpoŝtadreson",
index 789bc54..210f886 100644 (file)
        "logentry-protect-protect-cascade": "$1 {{GENDER:$2|protegió}} a $3 $4 [en cascada]",
        "logentry-protect-modify": "$1 {{GENDER:$2|cambió}} el nivel de protección de $3 $4",
        "logentry-protect-modify-cascade": "$1 {{GENDER:$2|cambió}} el nivel de protección de $3 $4 [en cascada]",
-       "logentry-rights-rights": "$1 {{GENDER:$2|modificó}} los grupos a los que pertenece {{GENDER:$3|$3}}: de $4 a $5",
+       "logentry-rights-rights": "$1 {{GENDER:$2|modificó}} los grupos a los que pertenece {{GENDER:$6|$3}}: de $4 a $5",
        "logentry-rights-rights-legacy": "$1 {{GENDER:$2|modificó}} los grupos a los que pertenece $3",
        "logentry-rights-autopromote": "$1 ha sido {{GENDER:$2|promocionado|promocionada}} automáticamente de $4 a $5",
        "logentry-upload-upload": "$1 {{GENDER:$2|subió}} $3",
index 2ceee0c..a2001d4 100644 (file)
        "logentry-protect-protect-cascade": "$1 {{GENDER:$2|suojasi}} kohteen $3 $4 [tarttuvasti]",
        "logentry-protect-modify": "$1 {{GENDER:$2|muutti}} suojauksen tasoa kohteessa $3 $4",
        "logentry-protect-modify-cascade": "$1 {{GENDER:$2|muutti}} suojauksen tasoa kohteessa $3 $4 [tarttuvasti]",
-       "logentry-rights-rights": "$1 {{GENDER:$2|muutti}} käyttäjän {{GENDER:$3|$3}} oikeudet ryhmistä $4 ryhmiin $5",
+       "logentry-rights-rights": "$1 {{GENDER:$2|muutti}} käyttäjän {{GENDER:$6|$3}} oikeudet ryhmistä $4 ryhmiin $5",
        "logentry-rights-rights-legacy": "$1 {{GENDER:$2|muutti}} käyttäjän $3 jäsenyyttä ryhmässä",
        "logentry-rights-autopromote": "Käyttäjän $1 oikeudet {{GENDER:$2|muuttuivat}} automaattisesti ryhmistä $4 ryhmiin $5",
        "logentry-upload-upload": "$1 {{GENDER:$2|tallensi}} tiedoston $3",
index 4cf6c83..0a4357f 100644 (file)
        "logentry-protect-protect-cascade": "$1 {{GENDER:$2|protexeu}} a $3 $4 [en cascada]",
        "logentry-protect-modify": "$1 {{GENDER:$2|cambiou}} o nivel de protección de $3 $4",
        "logentry-protect-modify-cascade": "$1 {{GENDER:$2|cambiou}} o nivel de protección de $3 $4 [en cascada]",
-       "logentry-rights-rights": "$1 {{GENDER:$2|cambiou}} o grupo ao que pertence {{GENDER:$3|$3}} de $4 a $5",
+       "logentry-rights-rights": "$1 {{GENDER:$2|cambiou}} o grupo ao que pertence {{GENDER:$6|$3}} de $4 a $5",
        "logentry-rights-rights-legacy": "$1 {{GENDER:$2|cambiou}} o grupo ao que pertence $3",
        "logentry-rights-autopromote": "$1 foi {{GENDER:$2|promovido|promovida}} automaticamente de $4 a $5",
        "logentry-upload-upload": "$1 {{GENDER:$2|cargou}} \"$3\"",
index 372611e..08e320c 100644 (file)
        "newarticletext": "הגעתם לדף שעדיין איננו קיים.\nכדי ליצור את הדף הזה, התחילו להקליד בתיבת הטקסט למטה (ראו את [$1 דף העזרה] למידע נוסף).\nאם הגעתם לכאן בטעות, לחצו על כפתור ה<strong>חזרה</strong> (Back) בדפדפן שלכם.",
        "anontalkpagetext": "----\n<em>זהו דף שיחה של משתמש אנונימי שעדיין לא יצר חשבון במערכת, או שהוא לא משתמש בו.</em>\nלכן עלינו להשתמש בכתובת ה־IP המספרית כדי לזהותו.\nייתכן שכתובת IP זו תהיה משותפת למספר משתמשים.\nאם אתם משתמשים אנונימיים ומרגישים שקיבלתם הודעות בלתי רלוונטיות, אנא [[Special:UserLogin/signup|צרו חשבון]] או [[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>,\nאך אינכם מורשים ליצור את הדף.",
+       "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}}}} יומן המחיקות].",
        "userpage-userdoesnotexist": "חשבון המשתמש \"$1\" אינו רשום.\nאנא בִּדקו אם ברצונכם ליצור/לערוך את הדף הזה.",
        "userpage-userdoesnotexist-view": "חשבון המשתמש \"$1\" אינו רשום.",
        "powersearch-ns": "חיפוש על־פי מרחבי שם:",
        "powersearch-togglelabel": "בחירה:",
        "powersearch-toggleall": "הכול",
-       "powersearch-togglenone": "×\90×£ ×\90×\97×\93",
+       "powersearch-togglenone": "×\9b×\9c×\95×\9d",
        "powersearch-remember": "שמירת הבחירה עבור חיפושים עתידיים",
        "search-external": "חיפוש חיצוני",
        "searchdisabled": "חיפוש ב{{grammar:תחילית|{{SITENAME}}}} אינו מופעל כעת.\nבינתיים אפשר לחפש באמצעות גוגל.\nשימו לב שייתכן שהמידע של {{SITENAME}} שם אינו מעודכן.",
        "logentry-protect-protect-cascade": "$1 {{GENDER:$2|הפעיל|הפעילה}} הגנה על הדף $3 $4 [מדורג]",
        "logentry-protect-modify": "$1 {{GENDER:$2|שינה|שינתה}} את רמת ההגנה של הדף $3 $4",
        "logentry-protect-modify-cascade": "$1 {{GENDER:$2|שינה|שינתה}} את רמת ההגנה של הדף $3 $4 [מדורג]",
-       "logentry-rights-rights": "$1 {{GENDER:$2|שינה|שינתה}} את ההרשאות של {{GENDER:$3|$3}} מ{{GRAMMAR:תחילית|$4}} ל{{GRAMMAR:תחילית|$5}}&rlm;",
+       "logentry-rights-rights": "$1 {{GENDER:$2|שינה|שינתה}} את ההרשאות של {{GENDER:$6|$3}} מ{{GRAMMAR:תחילית|$4}} ל{{GRAMMAR:תחילית|$5}}&rlm;",
        "logentry-rights-rights-legacy": "$1 {{GENDER:$2|שינה|שינתה}} את ההרשאות של $3&rlm;",
        "logentry-rights-autopromote": "$1 קודם אוטומטית מ{{GRAMMAR:תחילית|$4}} ל{{GRAMMAR:תחילית|$5}}",
        "logentry-upload-upload": "$1 {{GENDER:$2|העלה|העלתה}} את $3",
        "log-description-tag": "הדף הזה מראה מתי משתמשים הוסיפו [[Special:Tags|תגיות]] לגרסאות או רשומות יומן מסוימות או הסירו אותן. היומן אינו מציג פעולות תיוג שבוצעו כחלק מעריכה, מחיקה או פעולה דומה.",
        "logentry-tag-update-add-revision": "$1 {{GENDER:$2|הוסיף|הוסיפה}} את {{PLURAL:$7|התגית|התגיות}} $6 לגרסה $4 של הדף $3",
        "logentry-tag-update-add-logentry": "$1 {{GENDER:$2|הוסיף|הוסיפה}} את {{PLURAL:$7|התגית|התגיות}} $6 לרשומת היומן $5 של הדף $3",
-       "logentry-tag-update-remove-revision": "$1 {{GENDER:$2|×\94ס×\99ר|×\94ס×\99ר×\94}} ×\90ת {{PLURAL:$9|×\94ת×\92×\99ת|×\94ת×\92×\99×\95ת}} $8 ×\9e×\94×\92רס×\94 $4 ×©×\9c ×\94×\93×£ $3",
+       "logentry-tag-update-remove-revision": "$1 {{GENDER:$2|הסיר|הסירה}} את {{PLURAL:$9|התגית|התגיות}} $8 מגרסה $4 של הדף $3",
        "logentry-tag-update-remove-logentry": "$1 {{GENDER:$2|הסיר|הסירה}} את {{PLURAL:$9|התגית|התגיות}} $8 מרשומת היומן $5 של הדף $3",
        "logentry-tag-update-revision": "$1 {{GENDER:$2|עדכן|עדכנה}} את התגיות בגרסה $4 של הדף $3 ({{PLURAL:$7|הוסיף|הוסיפה}} את $6; {{PLURAL:$9|הסיר|הסירה}} את $8)",
        "logentry-tag-update-logentry": "$1 {{GENDER:$2|עדכן|עדכנה}} את התגיות ברשומת היומן $5 של הדף $3 ({{PLURAL:$7|הוסיף|הוסיפה}} את $6; {{PLURAL:$9|הסיר|הסירה}} את $8)",
index 84399c0..3c1eed2 100644 (file)
        "logentry-protect-protect-cascade": "$1 {{GENDER:$2|ha protetto}} $3 $4 [ricorsiva]",
        "logentry-protect-modify": "$1 {{GENDER:$2|ha modificato}} il livello di protezione per $3 $4",
        "logentry-protect-modify-cascade": "$1 {{GENDER:$2|ha modificato}} il livello di protezione per $3 $4 [ricorsiva]",
-       "logentry-rights-rights": "$1 {{GENDER:$2|ha modificato}} l'appartenenza di {{GENDER:$3|$3}} dal gruppo $4 al gruppo $5",
+       "logentry-rights-rights": "$1 {{GENDER:$2|ha modificato}} l'appartenenza di {{GENDER:$6|$3}} dal gruppo $4 al gruppo $5",
        "logentry-rights-rights-legacy": "$1 {{GENDER:$2|ha modificato}} l'appartenenza a gruppi di $3",
        "logentry-rights-autopromote": "$1 è {{GENDER:$2|stato promosso|stata promossa|stato/a promosso/a}} automaticamente da $4 a $5",
        "logentry-upload-upload": "$1 {{GENDER:$2|ha caricato}} $3",
index c9fa64a..1546fb8 100644 (file)
        "logentry-protect-protect-cascade": "$1 が $3 を {{GENDER:$2|保護}}しました $4 [カスケード]",
        "logentry-protect-modify": "$1 が $3 の保護レベルを{{GENDER:$2|変更}}しました $4",
        "logentry-protect-modify-cascade": "$1 が $3 の保護レベルを{{GENDER:$2|変更}}しました $4 [カスケード]",
-       "logentry-rights-rights": "$1 が {{GENDER:$3|$3}} の所属グループを $4 から $5 に{{GENDER:$2|変更しました}}",
+       "logentry-rights-rights": "$1 が {{GENDER:$6|$3}} の所属グループを $4 から $5 に{{GENDER:$2|変更しました}}",
        "logentry-rights-rights-legacy": "$1 が $3 の所属グループを{{GENDER:$2|変更しました}}",
        "logentry-rights-autopromote": "$1 が $4 から $5 に自動的に{{GENDER:$2|昇格しました}}",
        "logentry-upload-upload": "$1 が $3 を {{GENDER:$2|アップロードしました}}",
index 4ac3aa6..ed896a5 100644 (file)
        "databaseerror-query": "揣:$1",
        "databaseerror-function": "功能:$1",
        "databaseerror-error": "chhò-gō͘",
-       "transaction-duration-limit-exceeded": "Ūi tio̍h mài sán-seng koân liōng ê têng-hok iân-sî, pún kài choán-sàng in-ūi sia-ji̍p sî-kan ($1) chhiau-kòe $2 bió ê chè-hān, í-keng hong hòng-khì.\nNā chún lí sī beh chi̍t kái kái-tōng kúi--a-ê hāng-bo̍k, chhì ēng chē pái sió chhau-chok khòaⁿ-māi.",
+       "transaction-duration-limit-exceeded": "Ūi tio̍h mài sán-seng koân liōng ê têng-hok iân-sî, pún kài choán-sàng in-ūi sia-ji̍p sî-kan ($1) chhiau-kòe {{PLURAL:$2|bió-cheng}} ê chè-hān, í-keng hong hòng-khì.\nNā chún lí sī beh chi̍t kái kái-tōng kúi--a-ê hāng-bo̍k, chhì ēng chē pái sió chhau-chok khòaⁿ-māi.",
        "laggedslavemode": "'''提醒:'''頁內容可能毋是上新的。",
        "readonly": "Chu-liāu-khò· só tiâu leh",
        "enterlockreason": "Phah beh hong-só ê lí-iû, pau-koah ko͘-kè siáⁿ-mi̍h sî-chūn ē kái-tû hong-só.",
        "missingarticle-rev": "(修訂版本#:$1)",
        "missingarticle-diff": "(精差:$1,$2)",
        "readonly_lag": "佇附屬的資料庫更新到主要資料庫資料的時陣,資料庫會自動鎖定。",
+       "nonwrite-api-promise-error": "Tī leh HTTP header ê 'Promise-Non-Write-API-Action' í-keng sàng--chhut-khì m̄-koh chit-ê iau-kiû sī sàng kòe 1-ê API siá-ji̍p module.",
        "internalerror": "Loē-pō͘ ê chhò-ngō͘",
        "internalerror_info": "Loē-pō͘ ê chhò-ngō͘: $1",
+       "internalerror-fatal-exception": "\"$1\" lūi ê tì-miā lē-gōa",
        "filecopyerror": "Bô-hoat-tō· kā tóng-àn \"$1\" khó·-pih khì \"$2\".",
        "filerenameerror": "Bô-hoat-tō· kā tóng-àn \"$1\" kái-miâ chò \"$2\".",
        "filedeleteerror": "Bô-hoat-tō· kā tóng-àn \"$1\" thâi tiāu",
        "directorycreateerror": "Bô-hoat-tō͘ khui bo̍k-lo̍k \"$1\".",
+       "directoryreadonlyerror": "Bo̍k-lio̍k \"$1\" sī taⁿ ē-tàng tha̍k--ê.",
+       "directorynotreadableerror": "Bo̍k-lio̍k \"$1\" sī bē-tàng tha̍k--ê",
        "filenotfound": "Chhōe bô tóng-àn \"$1\".",
        "unexpected": "Koài-koài ê pió-tat: \"$1\"=\"$2\"。",
        "formerror": "Chhò-gō·: bô-hoat-tō· kā pió sàng chhut khì.",
        "no-null-revision": "袂當予\"$1\"產生一个空的修訂本。",
        "badtitle": "M̄-chiâⁿ piau-tê",
        "badtitletext": "Iau-kiû ê piau-tê sī bô-hāu ê, khang ê, a̍h-sī liân-kiat chhò-gō· ê inter-language/inter-wiki piau-tê.",
+       "title-invalid-empty": "Só͘ iau-kiû ê ia̍h-bīn tê-bo̍k sī khang--ê he̍k-chiá kaⁿ-taⁿ hâm liáu miâ-khong-kan.",
+       "title-invalid-utf8": "Só͘ iau-kiû ê ia̍h-bīn tê-bo̍k hâm liáu bô chiàⁿ-khak ê 1 lia̍t UTF-8 jī.",
+       "title-invalid-interwiki": "Só͘ iau-kiû ê ia̍h-bīn tê-bo̍k pau-hâm liáu 1-ê bē-tàng ēng ùi tê-bo̍k ê interwiki liân-kiat.",
        "perfcached": "Ē-kha ê chu-liāu tùi lâi--ê, só·-í bô it-tēng sī siōng sin ê. Tī khoài-chhûn-khu siōng chē ē-tàng khǹg{{PLURAL:$1| pit|$1 pit}} chu-liāu.",
        "perfcachedts": "Ē-kha ê chu-liāu tùi lâi--ê, tī $1 keng-sin--koè. Tī khoài-chûn-khu siōng chē ē-tàng khǹg {{PLURAL:$4|pit|$4 pit}} chu-liāu.",
        "querypage-no-updates": "Chit-má bē-sái kái chit ia̍h.\nChia ê chu-liāu bē-tàng sui tiông-sin chéng-lí.",
index c0886a6..dbd48f3 100644 (file)
@@ -31,6 +31,7 @@
        "tog-watchdefault": "Azzecca 'e paggene e li files cagnàte a l'elenco 'e cuntrollo",
        "tog-watchmoves": "Azzecca 'e paggene e li files spustate a l'elenco 'e cuntrollo",
        "tog-watchdeletion": "Azzecca 'e paggene e li files scancellate a l'elenco 'e cuntrollo",
+       "tog-watchuploads": "Azzecca 'e file nuove ca sto a carrecà dint'a lista 'e paggene cuntrullate",
        "tog-watchrollback": "Azzecca 'e paggene addò aggio fatto nu rollback ('o torna arreto) a l'elenco 'e cuntrollo",
        "tog-minordefault": "Indica ogne cagnamento comme piccerillo (predefinito)",
        "tog-previewontop": "Vide previsióne primma d' 'a casella 'e modifica",
        "recentchangeslinked-page": "Nomme d' 'a paggena",
        "recentchangeslinked-to": "Mmusta sulamente 'e cagnamiente a 'e paggene cullegate a chilla specificata",
        "recentchanges-page-added-to-category": "[[:$1]] azzeccato â categurìa",
-       "recentchanges-page-added-to-category-bundled": "[[:$1]] e [[Special:WhatLinksHere/$1|{{PLURAL:$2|na paggena|$2 paggene}}]] azzeccate â categurìa",
+       "recentchanges-page-added-to-category-bundled": "[[:$1]] azzeccata â categurìa,  [[Special:WhatLinksHere/$1|sta paggena azzeccat' a 'e categurìe]]",
        "recentchanges-page-removed-from-category": "[[:$1]] luvato d' 'a categurìa",
-       "recentchanges-page-removed-from-category-bundled": "[[:$1]] e [[Special:WhatLinksHere/$1|{{PLURAL:$2|na paggena|$2 paggena}}]] luvate d' 'a categurìa",
+       "recentchanges-page-removed-from-category-bundled": "[[:$1]]  luvate 'e categurìa, [[Special:WhatLinksHere/$1|sta paggena è azzeccata dint'a n'ati paggene]]",
        "autochange-username": "Cagnamiento automateco MediaWiki",
        "upload": "Carreca file",
        "uploadbtn": "Carreca file",
        "confirmemail_body_set": "Coccheruno, può darse ca site vuje, 'a l'indirizzo IP $1,\nha mpustato nu cunto utente \"$2\" cu st'indirizzo e-mail ncopp'a {{SITENAME}}.\n\nPe' putè cunfermà ca stu cunto è stato overo criato e vuje e ve putè apiccià 'a funziona e-mail 'e {{SITENAME}}, arapite stu cullegamento dint' 'o navigatóre web d' 'o vuosto:\n\n$3\n\nSi vuje *NUN* avite riggistrato 'o cunto utente, secutate stu cullegamento pe' ve scancellà st'indirizzo e-mail utente:\n\n$5\n\nStu codece 'e cunferma murarrà 'o $4.",
        "confirmemail_invalidated": "Cunferma 'e l'indirizze e-mail scangelleta",
        "invalidateemail": "Scancella 'a cunferma 'e l'e-mail",
+       "notificationemail_subject_changed": "L'indirizzo email riggistrato ncopp'a {{SITENAME}} è stato cagnato",
+       "notificationemail_subject_removed": "L'indirizzo email riggistrato dint'a {{SITENAME}} è stato luvato",
+       "notificationemail_body_changed": "Coccheruno, probbabilmente vuje, 'a ll'indirizzo IP $1,\nave cagnato l'indirizze e-mail d' 'o cunto \"$2\" a \"$3\" ncopp'a {{SITENAME}}.\n\nSi nun eravate vuje, pe' piacere tuzzuliate mò mò n'ammenistratore.",
+       "notificationemail_body_removed": "Coccheruno, probbabilmente vuje, 'a ll'indirizzo IP $1,\nave luvato l'indirizze e-mail d' 'o cunto \"$2\" ncopp'a {{SITENAME}}.\n\nSi nun eravate vuje, pe' piacere tuzzuliate mò mò n'ammenistratore.",
        "scarytranscludedisabled": "['A funziona cullegamiento nfra site wiki è stata stutata]",
        "scarytranscludefailed": "[L'analisi d' 'o template s'è scassato pe' $1]",
        "scarytranscludefailed-httpstatus": "[L'analisi d' 'o template s'è scassato pe' $1: HTTP $2]",
        "watchlistedit-raw-done": "L'elenco 'e paggene cuntrullate è stato agghiurnato.",
        "watchlistedit-raw-added": "{{PLURAL:$1|nu titolo è|$1 titule so'}} stat'azzeccate:",
        "watchlistedit-raw-removed": "{{PLURAL:$1|nu titolo è stato luvato|$1 titule so' state luvate}}:",
-       "watchlistedit-clear-title": "Elenco 'e cuntrollo pulezzato",
+       "watchlistedit-clear-title": "Pulezza 'a lista 'e cuntrollo",
        "watchlistedit-clear-legend": "Pulezza l'elenco 'e paggene cuntrullate",
        "watchlistedit-clear-explain": "Tutte sti titule se luvarranno 'a l'elenco 'e paggene cuntrullate vuosto",
        "watchlistedit-clear-titles": "Titule:",
        "logentry-protect-protect-cascade": "$1 {{GENDER:$2|pruteggette}} $3 $4 [cascading]",
        "logentry-protect-modify": "$1 {{GENDER:$2|cagnaje}} 'o livello 'e prutezione pe' $3 $4",
        "logentry-protect-modify-cascade": "$1 {{GENDER:$2|cagnaje}} 'o livello 'e prutezione pe' $3 $4 [cascading]",
-       "logentry-rights-rights": "$1 {{GENDER:$2|cagnaje}} 'e gruppo pe' {{GENDER:$3|$3}} 'a $4 a $5",
+       "logentry-rights-rights": "$1 {{GENDER:$2|cagnaje}} 'e gruppo pe' {{GENDER:$6|$3}} 'a $4 a $5",
        "logentry-rights-rights-legacy": "$1 {{GENDER:$2|cagnaje}} 'e gruppo pe' $3",
        "logentry-rights-autopromote": "$1 è {{GENDER:$2|stato promosso|stata promossa}} automatecamente 'a $4 a $5",
        "logentry-upload-upload": "$1 {{GENDER:$2|ave carrecato}} $3",
        "sessionprovider-nocookies": "'E cookie ponno stà stutate. Vedite si 'e cookie stann'appicciate e accumminciate n'ata vota.",
        "randomrootpage": "Paggena 'e rareca a ccaso",
        "log-action-filter-block": "Tipo 'e blocco:",
+       "log-action-filter-contentmodel": "Tipo 'e cagnamiento 'e mudell'e cuntenute (contentmodel)",
        "log-action-filter-delete": "Tipo 'e scancellazione:",
+       "log-action-filter-import": "Tipo 'e import:",
+       "log-action-filter-managetags": "Tipo 'e aziona 'e gistinone 'etichette:",
+       "log-action-filter-move": "Tipo 'e spostamento:",
+       "log-action-filter-newusers": "Tipo e' criazione utenza:",
        "log-action-filter-patrol": "Tipo 'e verifica:",
        "log-action-filter-protect": "Tipo 'e protezione:",
+       "log-action-filter-rights": "Tipo 'e cagnamiento 'e deritte",
+       "log-action-filter-suppress": "Tipo 'e suppressione",
        "log-action-filter-upload": "Tipo 'e carreca:",
        "log-action-filter-all": "Tutte",
        "log-action-filter-block-block": "Blocco",
        "log-action-filter-block-reblock": "Modifica blocco",
        "log-action-filter-block-unblock": "Sblocca",
+       "log-action-filter-contentmodel-change": "Cagnamiento 'e mudello 'e cuntenute (Contentmodel)",
+       "log-action-filter-contentmodel-new": "Criazione 'e na paggena 'e mudello 'e cuntenute nun standard",
        "log-action-filter-delete-delete": "Scancellazione 'e paggena",
        "log-action-filter-delete-restore": "Arrepigliament' 'e paggena",
        "log-action-filter-delete-event": "Scancellazione d' 'o reggistro",
        "log-action-filter-delete-revision": "Scancellazione d' 'a verziona",
+       "log-action-filter-import-interwiki": "Mpurtaziona transwiki",
+       "log-action-filter-import-upload": "Mpurtazione 'e XML carrecato",
+       "log-action-filter-managetags-create": "Criazione 'etichetta",
+       "log-action-filter-managetags-delete": "Scancellazione 'etichetta",
+       "log-action-filter-managetags-activate": "Appiccia 'etichetta",
+       "log-action-filter-managetags-deactivate": "Stuta etichetta",
+       "log-action-filter-move-move": "Móve senza sovrascrivere 'e redirect",
+       "log-action-filter-move-move_redir": "Móve senza sovrascrivere 'e redirect",
+       "log-action-filter-newusers-create": "Criazione 'a n'utente anonimo",
+       "log-action-filter-newusers-create2": "Criazione 'a n'utente riggistrato",
+       "log-action-filter-newusers-autocreate": "Criazione automatica",
+       "log-action-filter-newusers-byemail": "Criazione cu na password mannata via email",
        "log-action-filter-patrol-patrol": "Verifica manuale",
        "log-action-filter-patrol-autopatrol": "Verifica automatica",
        "log-action-filter-protect-protect": "Prutezione",
        "log-action-filter-protect-modify": "Cagna prutezione",
        "log-action-filter-protect-unprotect": "Sprutezione",
+       "log-action-filter-protect-move_prot": "Prutezione spustata",
+       "log-action-filter-rights-rights": "Cagnamento manuale",
+       "log-action-filter-rights-autopromote": "Cagnamento automatico",
+       "log-action-filter-suppress-event": "Scancellazione 'e riggistro",
+       "log-action-filter-suppress-revision": "Scancellazione 'e verziona",
+       "log-action-filter-suppress-delete": "Scancellazione 'e paggena",
+       "log-action-filter-suppress-block": "Scancellazione 'utente 'a blocco",
+       "log-action-filter-suppress-reblock": "Scancellazione utente 'a re-blocco",
        "log-action-filter-upload-upload": "Carreca nova",
        "log-action-filter-upload-overwrite": "Recarreca"
 }
index 9815492..77a6e8b 100644 (file)
        "logentry-protect-protect-cascade": "$1 {{GENDER:$2|zabezpieczył|zabezpieczyła|zabezpieczył(a)}} $3 $4 [kaskadowo]",
        "logentry-protect-modify": "$1 {{GENDER:$2|zmienił|zmieniła|zmienił(a)}} poziom zabezpieczenia dla $3 $4",
        "logentry-protect-modify-cascade": "$1 {{GENDER:$2|zmienił|zmieniła|zmienił(a)}} poziom zabezpieczenia dla $3 $4 [kaskadowo]",
-       "logentry-rights-rights": "$1 {{GENDER:$2|zmienił|zmieniła|zmienił(a)}} przynależność {{GENDER:$3|$3}} do grupy z $4 do $5",
+       "logentry-rights-rights": "$1 {{GENDER:$2|zmienił|zmieniła|zmienił(a)}} przynależność {{GENDER:$6|$3}} do grupy z $4 do $5",
        "logentry-rights-rights-legacy": "$1 {{GENDER:$2|zmienił|zmieniła}} przynależność $3 do grup",
        "logentry-rights-autopromote": "$1 automatycznie {{GENDER:$2|zmienił|zmieniła}} przynależność ($4 → $5)",
        "logentry-upload-upload": "$1 {{GENDER:$2|przesłał|przesłała}} $3",
index ee3bd1e..5fb6450 100644 (file)
                        "Aursani",
                        "Robin van der Vliet",
                        "Conquistador",
-                       "Frigory"
+                       "Frigory",
+                       "Psychoslave"
                ]
        },
        "sidebar": "{{notranslate}}",
        "botpasswords-label-cancel": "Button label for a button to cancel the creation or edit of a bot password.\n{{Identical|Cancel}}",
        "botpasswords-label-delete": "Button label for the button to delete a bot password.\n{{Identical|Delete}}",
        "botpasswords-label-resetpassword": "Label for the checkbox to reset the actual password for the current bot password.",
-       "botpasswords-label-grants": "Label for the checkmatrix for selecting grants allowed when the bot password is used.",
+       "botpasswords-label-grants": "Label for the checkmatrix for selecting grants allowed when the bot password is used.\n\ngrant: Vidu http://komputeko.net/index_en.php?vorto=grant sed \"konced/i\" egale funkcius.",
        "botpasswords-help-grants": "Help text for the grant selection checkmatrix.",
        "botpasswords-label-restrictions": "Label for the textarea field in which JSON defining access restrictions (e.g. which IP address ranges are allowed) is entered.",
        "botpasswords-label-grants-column": "Label for the checkbox column on the checkmatrix for selecting grants allowed when the bot password is used.",
        "logentry-protect-protect-cascade": "{{Logentry|[[Special:Log/protect]]}}\n\n* $4 - protect expiry (formatted with {{msg-mw|protect-summary-desc}}, multiple possible)\nFor word \"cascading\" see {{msg-mw|protect-summary-cascade}}",
        "logentry-protect-modify": "{{Logentry|[[Special:Log/protect]]}}\n\n* $4 - protect expiry (formatted with {{msg-mw|protect-summary-desc}}, multiple possible)",
        "logentry-protect-modify-cascade": "{{Logentry|[[Special:Log/protect]]}}\n\n* $4 - protect expiry (formatted with {{msg-mw|protect-summary-desc}}, multiple possible)\nFor word \"cascading\" see {{msg-mw|protect-summary-cascade}}",
-       "logentry-rights-rights": "* $1 - username\n* $2 - (see below)\n* $3 - username, also used for GENDER support\n* $4 - list of user groups or {{msg-mw|Rightsnone}}\n* $5 - list of user groups or {{msg-mw|Rightsnone}}\n----\n{{Logentry|[[Special:Log/rights]]}}",
+       "logentry-rights-rights": "* $1 - (see below)\n* $2 - (see below)\n* $3 - target user, like $1\n* $4 - list of user groups or {{msg-mw|Rightsnone}}\n* $5 - list of user groups or {{msg-mw|Rightsnone}}\n* $6 - target user, can be used with GENDER\n----\n{{Logentry|[[Special:Log/rights]]}}",
        "logentry-rights-rights-legacy": "* $1 - username\n* $2 - (see below)\n* $3 - username\n----\n{{Logentry|[[Special:Log/rights]]}}",
-       "logentry-rights-autopromote": "* $1 - username\n* $2 - (see below)\n* $3 - (see below)\n* $4 - comma separated list of old user groups or {{msg-mw|Rightsnone}}\n* $5 - comma separated list of new user groups\n----\n{{Logentry|[[Special:Log/rights]]}}",
+       "logentry-rights-autopromote": "* $1 - username\n* $2 - (see below)\n* $3 - (see below) - unused\n* $4 - comma separated list of old user groups or {{msg-mw|Rightsnone}}\n* $5 - comma separated list of new user groups\n* $6 - target user, can be used with GENDER for $3 - unused\n----\n{{Logentry|[[Special:Log/rights]]}}",
        "logentry-upload-upload": "{{Logentry|[[Special:Log/upload]]}}",
        "logentry-upload-overwrite": "{{Logentry|[[Special:Log/upload]]}}",
        "logentry-upload-revert": "{{Logentry|[[Special:Log/upload]]}}",
index 83e123e..bda02c8 100644 (file)
        "logentry-protect-protect-cascade": "$1 защитил{{GENDER:$2||а}} $3 $4 [каскадно]",
        "logentry-protect-modify": "$1 изменил{{GENDER:$2||а}} уровень защиты $3 $4",
        "logentry-protect-modify-cascade": "$1 изменил{{GENDER:$2||а}} уровень защиты $3 $4 [каскадно]",
-       "logentry-rights-rights": "$1 {{GENDER:$2|изменил|изменила}} членство в группах для {{GENDER:$3|$3}} с $4 на $5",
+       "logentry-rights-rights": "$1 {{GENDER:$2|изменил|изменила}} членство в группах для {{GENDER:$6|$3}} с $4 на $5",
        "logentry-rights-rights-legacy": "$1 {{GENDER:$2|изменил|изменила}} членство в группах для $3",
        "logentry-rights-autopromote": "$1 был{{GENDER:$2||а}} автоматически переведен{{GENDER:$2||а}} из $4 в $5",
        "logentry-upload-upload": "$1 загрузил{{GENDER:$2||а}} $3",
index 49d865a..3d08fa1 100644 (file)
        "logentry-protect-protect-cascade": "$1 је {{GENDER:$2|заштитио|заштитила}} $3 $4 [преносива заштита]",
        "logentry-protect-modify": "$1 је {{GENDER:$2|променио|променила}} степен заштите за $3 $4",
        "logentry-protect-modify-cascade": "$1 је {{GENDER:$2|променио|променила}} степен заштите за $3 $4 [преносива заштита]",
-       "logentry-rights-rights": "$1 је {{GENDER:$2|променио|променила}} чланство групе за {{GENDER:$3|$3}} из $4 у $5",
+       "logentry-rights-rights": "$1 је {{GENDER:$2|променио|променила}} чланство групе за {{GENDER:$6|$3}} из $4 у $5",
        "logentry-rights-rights-legacy": "$1 је {{GENDER:$2|променио|променила}} чланство групе за $3",
        "logentry-rights-autopromote": "$1 је аутоматски {{GENDER:$2|унапређен|унапређена}} из $4 у $5",
        "logentry-upload-upload": "$1 је {{GENDER:$2|послао|послала}} $3",
index aa2c828..696e8f4 100644 (file)
        "logentry-protect-protect-cascade": "$1 je {{GENDER:$2|zaštitio|zaštitila}} $3 $4 [prenosiva zaštita]",
        "logentry-protect-modify": "$1 je {{GENDER:$2|promenio|promenila}} stepen zaštite za $3 $4",
        "logentry-protect-modify-cascade": "$1 je {{GENDER:$2|promenio|promenila}} stepen zaštite za $3 $4 [prenosiva zaštita]",
-       "logentry-rights-rights": "$1 je {{GENDER:$2|promenio|promenila}} članstvo grupe za {{GENDER:$3|$3}} iz $4 u $5",
+       "logentry-rights-rights": "$1 je {{GENDER:$2|promenio|promenila}} članstvo grupe za {{GENDER:$6|$3}} iz $4 u $5",
        "logentry-rights-rights-legacy": "$1 je {{GENDER:$2|promenio|promenila}} čalnstvo grupe za $3",
        "logentry-rights-autopromote": "$1 je automatski {{GENDER:$1|unapređen|unapređena}} iz $4 u $5",
        "logentry-upload-upload": "$1 je {{GENDER:$2|poslao|poslala}} $3",
index 1cdb3a1..a81b466 100644 (file)
        "logentry-protect-protect-cascade": "$1 {{GENDER:$2|skyddade}} $3 $4 [kaskaderande]",
        "logentry-protect-modify": "$1 {{GENDER:$2|ändrade}} skyddsnivån för $3 $4",
        "logentry-protect-modify-cascade": "$1 {{GENDER:$2|ändrade}} skyddsnivån för $3 $4 [kaskaderande]",
-       "logentry-rights-rights": "$1 {{GENDER:$2|ändrade}} gruppmedlemskapet för {{GENDER:$3|$3}} från $4 till $5",
+       "logentry-rights-rights": "$1 {{GENDER:$2|ändrade}} gruppmedlemskapet för {{GENDER:$6|$3}} från $4 till $5",
        "logentry-rights-rights-legacy": "$1 {{GENDER:$2|ändrade}} gruppmedlemskapet för $3",
        "logentry-rights-autopromote": "$1 {{GENDER:$2|befordrades}} automatiskt från $4 till $5",
        "logentry-upload-upload": "$1 {{GENDER:$2|laddade upp}} $3",
index 9e1f36c..84d2d2e 100644 (file)
        "logentry-protect-protect-cascade": "$1 {{GENDER:$2|захистив|захистила}} $3 $4 [каскадно]",
        "logentry-protect-modify": "$1 {{GENDER:$2|змінив|змінила}} налаштування захисту $3 $4",
        "logentry-protect-modify-cascade": "$1 {{GENDER:$2|змінив|змінила}} налаштування захисту $3 $4 [каскадно]",
-       "logentry-rights-rights": "$1 {{GENDER:$2|змінив|змінила}} членство в групах для {{GENDER:$3|$3}} із $4 на $5",
+       "logentry-rights-rights": "$1 {{GENDER:$2|змінив|змінила}} членство в групах для {{GENDER:$6|$3}} із $4 на $5",
        "logentry-rights-rights-legacy": "$1 {{GENDER:$2|змінив|змінила}} членство в групах для $3",
        "logentry-rights-autopromote": "$1 було автоматично переведено із $4 в $5",
        "logentry-upload-upload": "$1 {{GENDER:$2|завантажив|завантажила}} $3",
index abceeb0..aae60f7 100644 (file)
        "exif-iimcategory": "زمرہ",
        "exif-orientation-1": "عام",
        "exif-meteringmode-0": "نامعلوم",
+       "exif-dc-contributor": "ترمیم کنندگان",
        "namespacesall": "تمام",
        "monthsall": "تمام",
        "deletedwhileediting": "انتباہ: آپ کے ترمیم شروع کرنے کے بعد یہ صفحہ حذف کیا جا چکا ہے!",
index 81aa690..00f6831 100644 (file)
        "search-result-size": "$1($2个字)",
        "search-result-category-size": "$1个成员($2个子分类,$3个文件)",
        "search-redirect": "(重定向自“$1”)",
-       "search-section": "(“$1”段落)",
+       "search-section": "(“$1”章节)",
        "search-category": "(分类$1)",
        "search-file-match": "(匹配文件内容)",
        "search-suggest": "您是不是要找:$1",
        "rc_categories": "分类限制(用“|”分隔):",
        "rc_categories_any": "任何选择的",
        "rc-change-size-new": "更改后有$1字节",
-       "newsectionsummary": "/* $1 */ 新段落",
+       "newsectionsummary": "/* $1 */ 新章节",
        "rc-enhanced-expand": "显示细节",
        "rc-enhanced-hide": "隐藏细节",
        "rc-old-title": "最初创建为“$1”",
        "logentry-protect-protect-cascade": "$1{{GENDER:$2|保护了}}$3 $4[级联]",
        "logentry-protect-modify": "$1{{GENDER:$2|更改了}}$3的保护等级$4",
        "logentry-protect-modify-cascade": "$1{{GENDER:$2|更改了}}$3的保护等级$4[级联]",
-       "logentry-rights-rights": "$1已将{{GENDER:$3|$3}}的用户组从$4{{GENDER:$2|更改}}至$5",
+       "logentry-rights-rights": "$1已将{{GENDER:$6|$3}}的用户组从$4{{GENDER:$2|更改}}至$5",
        "logentry-rights-rights-legacy": "$1更改$3的用户组",
        "logentry-rights-autopromote": "$1被自动地{{GENDER:$2|提升}}自$4至$5",
        "logentry-upload-upload": "$1{{GENDER:$2|上传}}$3",
index b3465e1..7d025d2 100644 (file)
@@ -665,4 +665,41 @@ class TitleTest extends MediaWikiTestCase {
                        'exists() should re-query database when GAID_FOR_UPDATE is used'
                );
        }
+
+       public function provideCreateFragmentTitle() {
+               return [
+                       [ Title::makeTitle( NS_MAIN, 'Test' ), 'foo' ],
+                       [ Title::makeTitle( NS_TALK, 'Test', 'foo' ), '' ],
+                       [ Title::makeTitle( NS_CATEGORY, 'Test', 'foo' ), 'bar' ],
+                       [ Title::makeTitle( NS_MAIN, 'Test1', '', 'interwiki' ), 'baz' ]
+               ];
+       }
+
+       /**
+        * @covers Title::createFragmentTarget
+        * @dataProvider provideCreateFragmentTitle
+        */
+       public function testCreateFragmentTitle( Title $title, $fragment ) {
+               $this->mergeMwGlobalArrayValue( 'wgHooks', [
+                       'InterwikiLoadPrefix' => [
+                               function ( $prefix, &$iwdata ) {
+                                       if ( $prefix === 'interwiki' ) {
+                                               $iwdata = [
+                                                       'iw_url' => 'http://example.com/',
+                                                       'iw_local' => 0,
+                                                       'iw_trans' => 0,
+                                               ];
+                                               return false;
+                                       }
+                               },
+                       ],
+               ] );
+
+               $fragmentTitle = $title->createFragmentTarget( $fragment );
+
+               $this->assertEquals( $title->getNamespace(), $fragmentTitle->getNamespace() );
+               $this->assertEquals( $title->getText(), $fragmentTitle->getText() );
+               $this->assertEquals( $title->getInterwiki(), $fragmentTitle->getInterwiki() );
+               $this->assertEquals( $fragment, $fragmentTitle->getFragment() );
+       }
 }
index 96e200d..a8beb91 100644 (file)
@@ -252,4 +252,29 @@ class BagOStuffTest extends MediaWikiTestCase {
                $this->assertType( 'ScopedCallback', $value1, 'First reentrant call returned lock' );
                $this->assertType( 'ScopedCallback', $value1, 'Second reentrant call returned lock' );
        }
+
+       /**
+        * @covers BagOStuff::__construct
+        * @covers BagOStuff::trackDuplicateKeys
+        */
+       public function testReportDupes() {
+               $logger = $this->getMock( 'Psr\Log\NullLogger' );
+               $logger->expects( $this->once() )
+                       ->method( 'warning' )
+                       ->with( 'Duplicate get(): "{key}" fetched {count} times', [
+                               'key' => 'foo',
+                               'count' => 2,
+                       ] );
+
+               $cache = new HashBagOStuff( [
+                       'reportDupes' => true,
+                       'asyncHandler' => 'DeferredUpdates::addCallableUpdate',
+                       'logger' => $logger,
+               ] );
+               $cache->get( 'foo' );
+               $cache->get( 'bar' );
+               $cache->get( 'foo' );
+
+               DeferredUpdates::doUpdates();
+       }
 }
index 013bbc1..913253b 100644 (file)
@@ -85,7 +85,7 @@ class TitleValueTest extends MediaWikiTestCase {
         * @dataProvider fragmentTitleProvider
         */
        public function testCreateFragmentTitle( TitleValue $title, $fragment ) {
-               $fragmentTitle = $title->createFragmentTitle( $fragment );
+               $fragmentTitle = $title->createFragmentTarget( $fragment );
 
                $this->assertEquals( $title->getNamespace(), $fragmentTitle->getNamespace() );
                $this->assertEquals( $title->getText(), $fragmentTitle->getText() );