Merge "Implement OOUI version of tag filter in ChangeTags"
authorjenkins-bot <jenkins-bot@gerrit.wikimedia.org>
Wed, 22 Jul 2015 13:44:41 +0000 (13:44 +0000)
committerGerrit Code Review <gerrit@wikimedia.org>
Wed, 22 Jul 2015 13:44:41 +0000 (13:44 +0000)
99 files changed:
.jshintrc
RELEASE-NOTES-1.26
autoload.php
includes/EditPage.php
includes/GlobalFunctions.php
includes/MediaWiki.php
includes/Message.php
includes/Title.php
includes/User.php
includes/api/i18n/fr.json
includes/api/i18n/he.json
includes/api/i18n/pl.json
includes/api/i18n/uk.json
includes/api/i18n/zh-hans.json
includes/api/i18n/zh-hant.json
includes/content/JavaScriptContent.php
includes/content/JavaScriptContentHandler.php
includes/db/Database.php
includes/filerepo/FileBackendDBRepoWrapper.php [new file with mode: 0644]
includes/filerepo/FileRepo.php
includes/filerepo/ForeignDBRepo.php
includes/filerepo/ForeignDBViaLBRepo.php
includes/filerepo/LocalRepo.php
includes/filerepo/file/File.php
includes/filerepo/file/LocalFile.php
includes/htmlform/HTMLButtonField.php
includes/htmlform/HTMLCheckField.php
includes/htmlform/HTMLFormField.php
includes/installer/PostgresUpdater.php
includes/installer/i18n/ce.json
includes/installer/i18n/hy.json
includes/installer/i18n/it.json
includes/installer/i18n/pl.json
includes/jobqueue/jobs/EmaillingJob.php
includes/libs/BufferingStatsdDataFactory.php
includes/mail/EmailNotification.php
includes/mail/UserMailer.php
includes/resourceloader/ResourceLoaderWikiModule.php
includes/search/SearchPostgres.php
includes/specials/SpecialEmailuser.php
includes/upload/UploadBase.php
includes/widget/NamespaceInputWidget.php
includes/widget/TitleInputWidget.php
includes/widget/UserInputWidget.php
languages/i18n/ar.json
languages/i18n/ast.json
languages/i18n/be-tarask.json
languages/i18n/ca.json
languages/i18n/ce.json
languages/i18n/cs.json
languages/i18n/cv.json
languages/i18n/de.json
languages/i18n/es.json
languages/i18n/et.json
languages/i18n/eu.json
languages/i18n/fa.json
languages/i18n/fi.json
languages/i18n/fr.json
languages/i18n/gom-deva.json
languages/i18n/he.json
languages/i18n/hy.json
languages/i18n/it.json
languages/i18n/ja.json
languages/i18n/kn.json
languages/i18n/lb.json
languages/i18n/lt.json
languages/i18n/mk.json
languages/i18n/ml.json
languages/i18n/nap.json
languages/i18n/pl.json
languages/i18n/pms.json
languages/i18n/sl.json
languages/i18n/sv.json
languages/i18n/tr.json
languages/i18n/uk.json
languages/i18n/vi.json
languages/i18n/zh-hans.json
languages/i18n/zh-hant.json
maintenance/migrateFileRepoLayout.php [new file with mode: 0644]
maintenance/postgres/archives/patch-textsearch_bug66650.sql [new file with mode: 0644]
maintenance/postgres/update-keys.sql
resources/lib/mustache/LICENSE [new file with mode: 0644]
resources/src/mediawiki.less/mediawiki.ui/mixins.less
resources/src/mediawiki.widgets/mw.widgets.NamespaceInputWidget.js
resources/src/mediawiki.widgets/mw.widgets.TitleInputWidget.js
resources/src/mediawiki.widgets/mw.widgets.TitleOptionWidget.js
resources/src/mediawiki.widgets/mw.widgets.UserInputWidget.js
resources/src/mediawiki/mediawiki.js
resources/src/startup.js
tests/phpunit/MediaWikiTestCase.php
tests/phpunit/includes/MessageTest.php
tests/phpunit/includes/content/CssContentTest.php
tests/phpunit/includes/content/JavaScriptContentHandlerTest.php [new file with mode: 0644]
tests/phpunit/includes/content/JavaScriptContentTest.php
tests/phpunit/includes/db/ORMTableTest.php
tests/phpunit/includes/filerepo/FileBackendDBRepoWrapperTest.php [new file with mode: 0644]
tests/phpunit/includes/filerepo/MigrateFileRepoLayoutTest.php [new file with mode: 0644]
tests/qunit/suites/resources/mediawiki/mediawiki.test.js
thumb.php

index d72c31d..b84d276 100644 (file)
--- a/.jshintrc
+++ b/.jshintrc
@@ -22,6 +22,7 @@
                "mediaWiki": true,
                "JSON": true,
                "OO": true,
+               "performance": true,
                "jQuery": false,
                "QUnit": false,
                "sinon": false
index 46ffe36..ec6bca5 100644 (file)
@@ -128,6 +128,7 @@ changes to languages because of Phabricator reports.
 * $wgSpecialPageGroups was removed (deprecated in 1.21).
 * SpecialPageFactory::setGroup was removed (deprecated in 1.21).
 * SpecialPageFactory::getGroup was removed (deprecated in 1.21).
+* DatabaseBase::ignoreErrors() is now protected.
 
 == Compatibility ==
 
index 734aa6a..a8940c4 100644 (file)
@@ -418,6 +418,7 @@ $wgAutoloadLocalClasses = array(
        'Field' => __DIR__ . '/includes/db/DatabaseUtility.php',
        'File' => __DIR__ . '/includes/filerepo/file/File.php',
        'FileBackend' => __DIR__ . '/includes/filebackend/FileBackend.php',
+       'FileBackendDBRepoWrapper' => __DIR__ . '/includes/filerepo/FileBackendDBRepoWrapper.php',
        'FileBackendError' => __DIR__ . '/includes/filebackend/FileBackend.php',
        'FileBackendException' => __DIR__ . '/includes/filebackend/FileBackend.php',
        'FileBackendGroup' => __DIR__ . '/includes/filebackend/FileBackendGroup.php',
@@ -772,6 +773,7 @@ $wgAutoloadLocalClasses = array(
        'MessageCache' => __DIR__ . '/includes/cache/MessageCache.php',
        'MessageContent' => __DIR__ . '/includes/content/MessageContent.php',
        'MessageSpecifier' => __DIR__ . '/includes/libs/MessageSpecifier.php',
+       'MigrateFileRepoLayout' => __DIR__ . '/maintenance/migrateFileRepoLayout.php',
        'MigrateUserGroup' => __DIR__ . '/maintenance/migrateUserGroup.php',
        'MimeMagic' => __DIR__ . '/includes/MimeMagic.php',
        'MinifyScript' => __DIR__ . '/maintenance/minify.php',
index bf322ae..0233b11 100644 (file)
@@ -3445,7 +3445,7 @@ HTML
 
                $this->deletedSinceEdit = false;
 
-               if ( $this->mTitle->isDeletedQuick() ) {
+               if ( !$this->mTitle->exists() && $this->mTitle->isDeletedQuick() ) {
                        $this->lastDelete = $this->getLastDelete();
                        if ( $this->lastDelete ) {
                                $deleteTime = wfTimestamp( TS_MW, $this->lastDelete->log_timestamp );
index 21b584b..6f354c3 100644 (file)
@@ -1421,7 +1421,7 @@ function wfGetLangObj( $langcode = false ) {
  *
  * This function replaces all old wfMsg* functions.
  *
- * @param string|string[] $key Message key, or array of keys
+ * @param string|string[]|MessageSpecifier $key Message key, or array of keys, or a MessageSpecifier
  * @param mixed $params,... Normal message parameters
  * @return Message
  *
index 5510d35..f488aa2 100644 (file)
@@ -363,9 +363,8 @@ class MediaWiki {
                        $this->context->setWikiPage( $article->getPage() );
                }
 
-               // NS_MEDIAWIKI has no redirects.
-               // It is also used for CSS/JS, so performance matters here...
-               if ( $title->getNamespace() == NS_MEDIAWIKI ) {
+               // Skip some unnecessary code if the content model doesn't support redirects
+               if ( !ContentHandler::getForTitle( $title )->supportsRedirects() ) {
                        return $article;
                }
 
index ee41db0..54abfd1 100644 (file)
@@ -226,8 +226,9 @@ class Message implements MessageSpecifier, Serializable {
        /**
         * @since 1.17
         *
-        * @param string|string[] $key Message key or array of message keys to try and use the first
-        * non-empty message for.
+        * @param string|string[]|MessageSpecifier $key Message key, or array of
+        * message keys to try and use the first non-empty message for, or a
+        * MessageSpecifier to copy from.
         * @param array $params Message parameters.
         * @param Language $language Optional language of the message, defaults to $wgLang.
         *
@@ -236,6 +237,16 @@ class Message implements MessageSpecifier, Serializable {
        public function __construct( $key, $params = array(), Language $language = null ) {
                global $wgLang;
 
+               if ( $key instanceof MessageSpecifier ) {
+                       if ( $params ) {
+                               throw new InvalidArgumentException(
+                                       '$params must be empty if $key is a MessageSpecifier'
+                               );
+                       }
+                       $params = $key->getParams();
+                       $key = $key->getKey();
+               }
+
                if ( !is_string( $key ) && !is_array( $key ) ) {
                        throw new InvalidArgumentException( '$key must be a string or an array' );
                }
@@ -362,7 +373,7 @@ class Message implements MessageSpecifier, Serializable {
         *
         * @since 1.17
         *
-        * @param string|string[] $key Message key or array of keys.
+        * @param string|string[]|MessageSpecifier $key
         * @param mixed $param,... Parameters as strings.
         *
         * @return Message
index fac45d0..8a15b54 100644 (file)
@@ -4547,15 +4547,17 @@ class Title {
        public function isValidRedirectTarget() {
                global $wgInvalidRedirectTargets;
 
-               // invalid redirect targets are stored in a global array, but explicitly disallow Userlogout here
-               if ( $this->isSpecial( 'Userlogout' ) ) {
-                       return false;
-               }
-
-               foreach ( $wgInvalidRedirectTargets as $target ) {
-                       if ( $this->isSpecial( $target ) ) {
+               if ( $this->isSpecialPage() ) {
+                       // invalid redirect targets are stored in a global array, but explicitly disallow Userlogout here
+                       if ( $this->isSpecial( 'Userlogout' ) ) {
                                return false;
                        }
+
+                       foreach ( $wgInvalidRedirectTargets as $target ) {
+                               if ( $this->isSpecial( $target ) ) {
+                                       return false;
+                               }
+                       }
                }
 
                return true;
index d627a6d..4c044bd 100644 (file)
@@ -4252,7 +4252,9 @@ class User implements IDBAccessObject {
                }
                $to = MailAddress::newFromUser( $this );
 
-               return UserMailer::send( $to, $sender, $subject, $body, $replyto );
+               return UserMailer::send( $to, $sender, $subject, $body, array(
+                       'replyTo' => $replyto,
+               ) );
        }
 
        /**
index 585bf6a..8bbecfa 100644 (file)
        "apihelp-xmlfm-description": "Extraire les données au format XML (affiché proprement en HTML).",
        "apihelp-yaml-description": "Extraire les données au format YAML.",
        "apihelp-yamlfm-description": "Extraire les données YAML (affiché proprement en HTML).",
-       "api-format-title": "Résultat de l’API de MédiaWiki",
+       "api-format-title": "Résultat de l’API de MediaWiki",
        "api-format-prettyprint-header": "Voici la représentation HTML du format $1. HTML est utile pour le débogage, mais inapproprié pour être utilisé dans une application.\n\nSpécifiez le paramètre <var>format</var> pour modifier le format de sortie. Pour voir la représentation non HTML du format $1, mettez <kbd>format=$2</kbd>.\n\nVoyez la [[mw:API|documentation complète]], ou l’[[Special:ApiHelp/main|aide de l’API]] pour plus d’information.",
        "api-format-prettyprint-header-only-html": "Ceci est une représentation HTML à des fins de déboguage, et n’est pas approprié à une utilisation applicative.\n\nVoir la [[mw:API|documentation complète]], ou l’[[Special:ApiHelp/main|aide de l’API]] pour plus d’information.",
        "api-orm-param-props": "Champs à rechercher.",
        "api-pageset-param-redirects-nogenerator": "Résoudre automatiquement les redirections dans <var>$1titles</var>, <var>$1pageids</var> et <var>$1revids</var>.",
        "api-pageset-param-converttitles": "Convertir les titres dans d’autres variantes si nécessaire. Fonctionne uniquement si la langue de contenu du wiki supporte la conversion en variantes. Les langues qui supportent la conversion en variante incluent $1.",
        "api-help-title": "Aide de l’API de MediaWiki",
-       "api-help-lead": "Ceci est une page d’aide de l’API de MédiaWiki générée automatiquement.\n\nDocumentation et exemples : https://www.mediawiki.org/wiki/API",
+       "api-help-lead": "Ceci est une page d’aide de l’API de MediaWiki générée automatiquement.\n\nDocumentation et exemples : https://www.mediawiki.org/wiki/API",
        "api-help-main-header": "Module principal",
        "api-help-flag-deprecated": "Ce module est obsolète.",
        "api-help-flag-internal": "<strong>Ce module est interne ou instable.</strong> Son fonctionnement peut être modifié sans préavis.",
index 3cdc992..26d11de 100644 (file)
        "apihelp-parse-paramvalue-prop-encodedjsconfigvars": "נותן משתני הגדרות של JavaScript שייחודיים לדף הזה בתור מחרוזת JSON.",
        "apihelp-parse-paramvalue-prop-iwlinks": "מתן קישורי בינוויקי בקוד הוויקי המפוענח.",
        "apihelp-parse-paramvalue-prop-wikitext": "מתן קוד הוויקי המקורי שפוענח.",
-       "apihelp-parse-param-disablepp": "×\9c×\9b×\91×\95ת ×\90ת ×\93×\95\"×\97 ×\94Ö¾PP מפלט המפענח.",
-       "apihelp-parse-param-disableeditsection": "×\9c×\9b×\91×\95ת את קישורי עריכת הפסקאות מפלט המפענח.",
+       "apihelp-parse-param-disablepp": "×\9c×\94ש×\9e×\99×\98 ×\90ת ×\93×\95\"×\97 ×\94ק×\93×\9dÖ¾×\9e×¢×\91×\93 (\"NewPP limit report\") מפלט המפענח.",
+       "apihelp-parse-param-disableeditsection": "×\9c×\94ש×\9e×\99×\98 את קישורי עריכת הפסקאות מפלט המפענח.",
        "apihelp-parse-param-preview": "לפענח במצב תצוגה מקדימה.",
        "apihelp-parse-param-sectionpreview": "לפענח במצב תצוגה מקדימה של פסקה (מדליק גם את מצב תצוגה מקדימה).",
-       "apihelp-parse-param-disabletoc": "×\9c×\9b×\91×\95ת ×ª×\95×\9b×\9f עניינים בפלט.",
+       "apihelp-parse-param-disabletoc": "×\9c×\94ש×\9e×\99×\98 ×\90ת ×ª×\95×\9b×\9f ×\94עניינים בפלט.",
        "apihelp-parse-param-contentformat": "תסדיר הסדרת תוכן שישמש לטקסט הקלט. תקף רק עם $1text.",
        "apihelp-parse-example-page": "לפענח דף.",
        "apihelp-parse-example-text": "לפענח קוד ויקי.",
        "apihelp-protect-param-protections": "רשימת רמות הכנה, בתסדיר <kbd>action=level</kbd> (למשל <kbd>edit=sysop</kbd>).",
        "apihelp-protect-param-expiry": "חותמי־זמן של תפוגה. אם הוגדר רק חותם־זמן אחד, הוא ישמש לכל ההגנות. יש להשתמש ב־<kbd>infinite</kbd>‏, <kbd>indefinite</kbd>‏, <kbd>infinity</kbd>, או <kbd>never</kbd> להגנה שלא פגה לעולם.",
        "apihelp-protect-param-reason": "סיבה להגנה או הסרת הגנה.",
-       "apihelp-protect-param-cascade": "×\94פע×\9cת ×\94×\92× ×\94 ×\9e×\93×\95ר×\92ת (×\9b×\9c×\95×\9eר, ×\9c×\94×\92×\9f ×¢×\9c ×\93פ×\99×\9d ×©×\9b×\9c×\95×\9c×\99×\9d ×\91×\93×£ ×\94×\96×\94). ×\90×\99×\9f ×\9c×\96×\94 ×\94שפע×\94 ×\90×\9d ×\9b×\9c ×¨×\9e×\95ת ×\94×\94×\92× ×\94 ×©× ×\99תנ×\95 ×\90×\99× ×\9f ×ª×\95×\9e×\9b×\95ת בדירוג.",
+       "apihelp-protect-param-cascade": "×\94פע×\9cת ×\94×\92× ×\94 ×\9e×\93×\95ר×\92ת (×\9b×\9c×\95×\9eר, ×\9c×\94×\92×\9f ×¢×\9c ×\93פ×\99×\9d ×©×\9e×\95×\9b×\9c×\9c×\99×\9d ×\91×\93×£ ×\94×\96×\94 ×\95×¢×\9c ×ª×\9e×\95× ×\95ת ×©×\9eש×\9e×\95ת ×\91×\95). ×\90×\99×\9f ×\9c×\96×\94 ×\94שפע×\94 ×\90×\9d ×\90×£ ×\90×\97ת ×\9eר×\9e×\95ת ×\94×\94×\92× ×\94 ×©× ×\99תנ×\95 ×\90×\99× ×\94 ×ª×\95×\9e×\9bת בדירוג.",
        "apihelp-protect-param-watch": "אם זה מוגדר, הוספת הדף שהגנה נוספת אליו או מוסרת ממנו לרשימת המעקב של המשתמש הנוכחי.",
        "apihelp-protect-param-watchlist": "הוספה או הסרה של הדף ללא תנאי מרשימת המעקב של המשתמש הנוכחי, להשתמש בהעדפות או לא לשנות את המעקב.",
        "apihelp-protect-example-protect": "הגנה על דף.",
        "apihelp-query+categorymembers-description": "רשימת כל הדפים בקטגוריה נתונה.",
        "apihelp-query+categorymembers-param-title": "איזו קטגוריה למנות (נדרש). חייב לכלול את התחילית <kbd>{{ns:category}}:</kbd>. לא יכול לשמש יחד עם <var>$1pageid</var>.",
        "apihelp-query+categorymembers-param-pageid": "מזהה הדף של הקטגוריה שצריך למנות. לא יכול לשמש יחד עם <var>$1title</var>.",
+       "apihelp-query+categorymembers-param-prop": "אילו חלקי מידע לכלול:\n;ids:הוספת מזהה הדף.\n;title:הוספת השם ומזהה מרחב השם של הדף.\n;sortkey:הוספת מפתח המיון שמשמש למיון בקטגוריה (מחרזות הקסדצימלית).\n;sortkeyprefix:הוספת מפתח המיון שמשמש למיון בקטגוריה (מחרוזת הקסדצימלית).\n;type:הוספת הסוג שהדף מוין אליו (דף, תת־קטגוריה, או קובץ).\n;timestamp:הוספת חותם־הזמן שבו הדף נכלל.",
        "apihelp-query+categorymembers-param-namespace": "לכלול רק דפים במרחבי השם האלה. יש לשים לב לכך ש־<kbd>$1type=subcat</kbd> או <kbd>$1type=file</kbd> יכולים לשמש במקום <kbd>$1namespace=14</kbd> או <kbd>6</kbd>.",
+       "apihelp-query+categorymembers-param-type": "איזה סוג של חברי קטגוריה לכלול. לא תקף כאשר מוגדר <kbd>$1sort=timestamp</kbd>.",
        "apihelp-query+categorymembers-param-limit": "מספר הדפים המרבי שיוחזר.",
        "apihelp-query+categorymembers-param-sort": "לפי איזה מאפיין למיין.",
        "apihelp-query+categorymembers-param-dir": "באיזה כיוון למיין.",
+       "apihelp-query+categorymembers-param-start": "מאיזה חותם־זמן להתחיל לרשום. יכול לשמש רק עם <kbd>$1sort=timestamp</kbd>.",
+       "apihelp-query+categorymembers-param-end": "באיזה חותם־זמן לסיים לרשום. יכול לשמש רק עם <kbd>$1sort=timestamp</kbd>.",
        "apihelp-query+categorymembers-param-startsortkey": "כדאי להשתמש ב־$1starthexsortkey במקום.",
        "apihelp-query+categorymembers-param-endsortkey": "כדאי להשתמש ב־$1endhexsortkey במקום.",
        "apihelp-query+categorymembers-example-simple": "קבלת עשרת העמודים הראשונים שתחת <kbd>קטגוריה:פיזיקה</kbd>.",
        "apihelp-query+contributors-param-limit": "כמה תורמים להחזיר.",
        "apihelp-query+contributors-example-simple": "הצגת תורמים לדף <kbd>עמוד ראשי</kbd>.",
+       "apihelp-query+deletedrevisions-description": "קבלת מידע על גרסה מחוקה.\n\nיכול לשמש במספר דרכים:\n# קבלת גרסאות מחוקות עבור ערכת דפים, על־ידי הגדרת שמות או מזהי דף. ממוין לפי שם וחותם־זמן.\n# קבלת מידע על ערכת גרסאות מחוקות באמצעות הגדרת המזהים שלהם עם revid־ים. ממוין לפי מזהה גרסה.",
        "apihelp-query+deletedrevisions-param-start": "באיזה חותם־זמן להתחיל למנות. לא תקף בעיבור רשימת מזהי גרסה.",
        "apihelp-query+deletedrevisions-param-end": "באיזה חותם־זמן להפסיק למנות. לא תקף בעת עיבוד רשימת מזהי גרסה.",
        "apihelp-query+deletedrevisions-param-tag": "לרשום רק גרסאות עם התג הזה.",
        "apihelp-query+deletedrevisions-param-user": "לרשום רק גרסאות מאת המשתמש הזה.",
        "apihelp-query+deletedrevisions-param-excludeuser": "לא לרשום גרסאות מאת המשתמש הזה.",
+       "apihelp-query+deletedrevs-description": "רשימת גרסאות מחוקות.\n\nפועל בשלושה אופנים:\n# רשימת גרסאות מחוקות לשמות שניתנו, ממוינות לפי חותם־זמן.\n# רשימת תרומות מחוקות של המשתמש שניתן, ממוינות לפי חותם־זמן (בלי לציין שמות).\n# רשימת כל הגרסאות המחוקות במרחב השם שניתן, ממוינות לפי שם וחותם־זמן (בלי לציין שמות, בלי להגדיר $1user).\n\nפרמטרים מסוימים חלים רק על חלק מהאופנים ולא תקפים באחרים.",
        "apihelp-query+deletedrevs-paraminfo-modes": "{{PLURAL:$1|מצב|מצבים}}: $2",
        "apihelp-query+deletedrevs-param-start": "באיזה חותם־זמן להתחיל למנות.",
        "apihelp-query+deletedrevs-param-end": "באיזה חותם־זמן להפסיק למנות.",
        "apihelp-query+imageusage-param-namespace": "איזה מרחב שם לרשום.",
        "apihelp-query+imageusage-param-dir": "באיזה כיוון לרשום.",
        "apihelp-query+info-paramvalue-prop-watchers": "מספר העוקבים, אם קיבלת הרשאה.",
+       "apihelp-query+info-paramvalue-prop-notificationtimestamp": "חותם־זמן של הודעת רשימת מעקב של כל דף.",
        "apihelp-query+info-paramvalue-prop-readable": "האם המשתמש יכול להציג דף זה.",
        "apihelp-query+iwbacklinks-param-title": "איזה קישור בינוויקי לחפש. צריך להשתמש בזה יחד עם <var>$1blprefix</var>.",
        "apihelp-query+iwbacklinks-param-limit": "כמה דפים להחזיר בסך הכול.",
        "apihelp-query+pageswithprop-param-limit": "מספר הדפים המרבי שיוחזר.",
        "apihelp-query+pageswithprop-param-dir": "באיזה כיוון לסדר.",
        "apihelp-query+pageswithprop-example-simple": "הצגת עשרת הדפים הראשונים שעושים שימוש ב־<code>&#123;&#123;DISPLAYTITLE:&#125;&#125;</code>.",
-       "apihelp-query+pageswithprop-example-generator": "ק×\91×\9cת ×¤×¨×\98×\99×\94×\9d ×©ל עשרת הדפים הראשונים המשתמשים ב־<code>_&#95;NOTOC_&#95;</code>.",
+       "apihelp-query+pageswithprop-example-generator": "ק×\91×\9cת ×\9e×\99×\93×¢ × ×\95סף ×¢ל עשרת הדפים הראשונים המשתמשים ב־<code>_&#95;NOTOC_&#95;</code>.",
        "apihelp-query+prefixsearch-param-search": "מחרוזת לחיפוש.",
        "apihelp-query+prefixsearch-param-namespace": "שמות מתחם לחיפוש.",
        "apihelp-query+prefixsearch-param-limit": "מספר התוצאות המרבי להחזרה.",
        "apihelp-query+prefixsearch-param-offset": "מספר תוצאות לדילוג.",
        "apihelp-query+protectedtitles-param-limit": "כמה דפים להחזיר בסך הכול.",
+       "apihelp-query+protectedtitles-param-start": "להתחיל לרשום בחותם־זמן ההגנה הזה.",
        "apihelp-query+protectedtitles-param-end": "באיזה חותם־זמן הגנה לסיים את הרשימה.",
        "apihelp-query+querypage-param-limit": "מספר תוצאות להחזרה.",
        "apihelp-query+recentchanges-description": "מניית השינויים האחרונים.",
        "apihelp-query+revisions-param-endid": "באיזה מזהה גרסה להפסיק את מניית הגרסאות.",
        "apihelp-query+revisions-param-start": "מאיזה חותם־זמן של גרסה להתחיל למנות.",
        "apihelp-query+revisions-param-tag": "לרשום רק גרסאות עם התג הזה.",
+       "apihelp-query+revisions+base-paramvalue-prop-timestamp": "חותם־הזמן של הגרסה.",
        "apihelp-query+revisions+base-param-limit": "הגבלת מספר הגרסאות שיוחזרו.",
        "apihelp-query+revisions+base-param-contentformat": "תסדיר ההסדרה שמשמש את <var>$1difftotext</var> וצפוי לפלט של תוכן.",
        "apihelp-query+search-description": "ביצוע חיפוש בכל הטקסט.",
        "apihelp-query+watchlist-param-user": "לרשום רק שינויים של המשתמש הזה.",
        "apihelp-query+watchlist-param-excludeuser": "Don't list changes by this user",
        "apihelp-query+watchlist-param-limit": "כמה תוצאות סך הכול להחזיר בכל בקשה.",
+       "apihelp-query+watchlist-paramvalue-prop-timestamp": "הוספת חותם־זמן של העריכה.",
        "apihelp-query+watchlistraw-param-limit": "כמה תוצאות סך הכול להחזיר בכל בקשה.",
        "apihelp-query+watchlistraw-param-fromtitle": "מאיזו כותרת (עם תחילית מרחב שם) להתחיל את המנייה.",
        "apihelp-query+watchlistraw-param-totitle": "באיזו כותרת (עם תחילית מרחב שם) להפסיק למנות.",
index 2b506d9..e295886 100644 (file)
        "apihelp-patrol-example-revid": "Sprawdź edycje.",
        "apihelp-protect-description": "Zmień poziom zabezpieczenia strony.",
        "apihelp-protect-param-reason": "Powód zabezpieczania/odbezpieczania.",
-       "apihelp-protect-param-cascade": "Włacz ochronę kaskadową (chronione są wszystkie strony zawarte w tej stronie). Ignorowane jeśli wszystkie poziomy ochrony nie wspierają kaskadowania.",
+       "apihelp-protect-param-cascade": "Włącz ochronę kaskadową (chronione są wszystkie osadzone szablony i obrazki na tej stronie). Ignorowane, jeśli żaden z danych poziomów ochrony nie wspiera kaskadowania.",
        "apihelp-protect-example-protect": "Zabezpiecz stronę",
        "apihelp-protect-example-unprotect": "Odbezpiecz stronę ustawiając ograniczenia na <kbd>wszystkie</kbd>.",
        "apihelp-protect-example-unprotect2": "Odbezpiecz stronę ustawiając brak ograniczeń.",
index 84b0663..b439fb0 100644 (file)
        "apihelp-edit-param-notminor": "Не «незначне» редагування.",
        "apihelp-edit-param-bot": "Помітити редагування як зроблене ботом.",
        "apihelp-edit-param-basetimestamp": "Мітка часу для основної версії, використовується для виявлення конфлікту редагувань. Може бути отримана через [[Special:ApiHelp/query+revisions|action=query&prop=revisions&rvprop=timestamp]].",
+       "apihelp-edit-param-starttimestamp": "Мітка часу, з якого почався процес редагування, використовується для виявлення конфліктів редагувань. Відповідне значення можна отримати з допомогою <var>[[Special:ApiHelp/main|curtimestamp]]</var> на початку процесу редагування (напр., коли завантажується вміст сторінки для редагування).",
+       "apihelp-edit-param-recreate": "Відкинути будь-які помилки щодо цієї сторінки, вилучені нещодавно.",
+       "apihelp-edit-param-createonly": "Не редагувати сторінку, якщо вона вже існує.",
+       "apihelp-edit-param-nocreate": "Видати помилку, якщо сторінка не існує.",
+       "apihelp-edit-param-watch": "Додати сторінку у список спостереження поточного користувача.",
+       "apihelp-edit-param-unwatch": "Вилучити сторінку зі списку спостереження поточного користувача.",
+       "apihelp-edit-param-watchlist": "Беззастережно додати або вилучити сторінку зі списку спостереження поточного користувача, використати налаштування або не змінювати спостереження.",
+       "apihelp-edit-param-md5": "MD5-хеш у параметрі $1text або параметрах $1prependtext і $1appendtext разом. Якщо вказано, редагування буде зроблене, лише якщо хеш правильний.",
+       "apihelp-edit-param-prependtext": "Додати цей текст на початок сторінки. Замінює $1text.",
+       "apihelp-edit-param-appendtext": "Додати цей текст у кінець сторінки. Замінює $1text.\n\nЩоб додати новий розділ, замість цього параметра використайте $1section=new.",
+       "apihelp-edit-param-undo": "Скасувати цю версію. Замінює $1text, $1prependtext та $1appendtext.",
+       "apihelp-edit-param-undoafter": "Скасувати усі версії від $1undo до цієї. Якщо не вказано, просто скасувати одну версію.",
+       "apihelp-edit-param-redirect": "Автоматично виправляти перенаправлення.",
+       "apihelp-edit-param-contentformat": "Формат серіалізації вмісту, використовуваний для введеного тексту.",
+       "apihelp-edit-param-contentmodel": "Модель вмісту нового вмісту.",
+       "apihelp-edit-param-token": "Токен завжди має надсилатися як останній параметр або хоча б після параметра $1text.",
        "apihelp-edit-example-edit": "Редагувати сторінку",
        "apihelp-edit-example-prepend": "Додати зміст на початок сторінки",
        "apihelp-edit-example-undo": "Скасувати версії з 13579 по 13585 з автоматичним описом змін",
        "apihelp-emailuser-param-subject": "Заголовок теми.",
        "apihelp-emailuser-param-text": "Тіло листа.",
        "apihelp-emailuser-param-ccme": "Надіслати копію цього повідомлення мені.",
-       "apihelp-emailuser-example-email": "Відправити листа користувачу \"WikiSysop\" з текстом \"Вміст\"",
+       "apihelp-emailuser-example-email": "Відправити листа користувачу <kbd>WikiSysop</kbd> з текстом <kbd>Вміст</kbd>.",
        "apihelp-expandtemplates-description": "Розгортає усі шаблони у вікітекст.",
        "apihelp-expandtemplates-param-title": "Заголовок сторінки.",
        "apihelp-expandtemplates-param-text": "Вікітекст для перетворення.",
+       "apihelp-expandtemplates-param-revid": "ID версії, для <nowiki>{{REVISIONID}}</nowiki> і подібних змінних.",
+       "apihelp-expandtemplates-param-prop": "Яку інформацію отримувати.\n\nЗважте, що якщо не вибрано значень, результат міститиме вікітекст, але буде в застарілому форматі.",
+       "apihelp-expandtemplates-paramvalue-prop-wikitext": "Розгорнений вікітекст.",
+       "apihelp-expandtemplates-paramvalue-prop-categories": "Будь-які категорії, наявні у джерелі, але не виведені у вікітексті результату.",
+       "apihelp-expandtemplates-paramvalue-prop-properties": "Властивості сторінки, визначені розгорненими магічними словами у вікітексті.",
+       "apihelp-expandtemplates-paramvalue-prop-volatile": "Чи результат тривкий і не повинен повторно використовуватись десь іще на сторінці.",
+       "apihelp-expandtemplates-paramvalue-prop-ttl": "Максимальний час, після якого кеш результату стане недійсним.",
+       "apihelp-expandtemplates-paramvalue-prop-modules": "Будь-які модулі ResourceLoader, які парсерні функції запитують на додання у результат. Або <kbd>jsconfigvars</kbd>, або <kbd>encodedjsconfigvars</kbd> має бути запитано разом з <kbd>modules</kbd>.",
+       "apihelp-expandtemplates-paramvalue-prop-jsconfigvars": "Дає конфігурації JavaScript змінні, притаманні для сторінки.",
+       "apihelp-expandtemplates-paramvalue-prop-encodedjsconfigvars": "Дає конфігурації JavaScript змінні, притаманні для сторінки, як рядок JSON.",
+       "apihelp-expandtemplates-paramvalue-prop-parsetree": "Дерево парсу XML вхідних даних.",
+       "apihelp-expandtemplates-param-includecomments": "Чи включати HTML-коментарі у результат.",
+       "apihelp-expandtemplates-param-generatexml": "Дерево парсу XML вхідних даних (замінене на $1prop=parsetree).",
+       "apihelp-expandtemplates-example-simple": "Розгорнути вікітекст <kbd><nowiki>{{Project:Sandbox}}</nowiki></kbd>.",
+       "apihelp-feedcontributions-description": "Повертає стрічку внеску користувача.",
+       "apihelp-feedcontributions-param-feedformat": "Формат стрічки.",
+       "apihelp-feedcontributions-param-user": "Для яких користувачів отримати внесок.",
+       "apihelp-feedcontributions-param-namespace": "За яким простором назв фільтрувати внески.",
+       "apihelp-feedcontributions-param-year": "Від року (і раніше).",
+       "apihelp-feedcontributions-param-month": "До місяця (і раніше).",
+       "apihelp-feedcontributions-param-tagfilter": "Відфільтрувати внесок, у якого є ці теґи.",
+       "apihelp-feedcontributions-param-deletedonly": "Показати лише вилучений внесок.",
+       "apihelp-feedcontributions-param-toponly": "Показати лише редагування, які є останніми версіями.",
+       "apihelp-feedcontributions-param-newonly": "Показати лише редагування, які є створеннями сторінок.",
+       "apihelp-feedcontributions-param-showsizediff": "Показати різницю розміру між версіями.",
+       "apihelp-feedcontributions-example-simple": "Вивести внесок для користувача <kbd>Example</kbd>.",
+       "apihelp-feedrecentchanges-description": "Видає стрічку нових редагувань.",
+       "apihelp-feedrecentchanges-param-feedformat": "Формат стрічки.",
+       "apihelp-feedrecentchanges-param-namespace": "Простір назв, до якого обмежити результати.",
+       "apihelp-feedrecentchanges-param-invert": "Усі простори назв, крім вибраного.",
+       "apihelp-feedrecentchanges-param-associated": "Включно з пов'язаним (обговорення чи головним) простором назв.",
+       "apihelp-feedrecentchanges-param-days": "Дні, до яких обмежити результати.",
+       "apihelp-feedrecentchanges-param-limit": "Максимальна кількість результатів для виведення.",
+       "apihelp-feedrecentchanges-param-from": "Показати зміни відтоді.",
+       "apihelp-feedrecentchanges-param-hideminor": "Приховати незначні редагування.",
+       "apihelp-feedrecentchanges-param-hidebots": "Приховати редагування ботів.",
+       "apihelp-feedrecentchanges-param-hideanons": "Приховати редагування анонімних користувачів.",
+       "apihelp-feedrecentchanges-param-hideliu": "Приховати редагування зареєстрованих користувачів.",
+       "apihelp-feedrecentchanges-param-hidepatrolled": "Приховати відпатрульовані редагування.",
+       "apihelp-feedrecentchanges-param-hidemyself": "Приховати редагування поточного користувача.",
+       "apihelp-feedrecentchanges-param-tagfilter": "Фільтрувати за теґом.",
+       "apihelp-feedrecentchanges-param-target": "Показати лише зміни на сторінках, на які посилається ця сторінка.",
+       "apihelp-feedrecentchanges-param-showlinkedto": "Показати натомість лише зміни на сторінках, які посилаються на цю сторінку.",
+       "apihelp-feedrecentchanges-example-simple": "Показати нещодавні зміни.",
+       "apihelp-feedrecentchanges-example-30days": "Показати нещодавні зміни за 30 днів.",
+       "apihelp-feedwatchlist-description": "Видає стрічку списку спостереження.",
+       "apihelp-feedwatchlist-param-feedformat": "Формат стрічки.",
+       "apihelp-feedwatchlist-param-hours": "Список сторінок, змінених за цю кількість годин від зараз.",
+       "apihelp-feedwatchlist-param-linktosections": "За можливості, посилатися безпосередньо на змінені розділи.",
+       "apihelp-feedwatchlist-example-default": "Показати стрічку списку спостереження.",
+       "apihelp-filerevert-param-filename": "Цільова назва файлу, без префіксу File:.",
+       "apihelp-filerevert-param-comment": "Завантажити коментар.",
+       "apihelp-filerevert-param-archivename": "Архівна назва версії, до якої повернути.",
+       "apihelp-filerevert-example-revert": "Повернути <kbd>Wiki.png</kbd> до версії <kbd>2011-03-05T15:27:40Z</kbd>.",
+       "apihelp-help-description": "Відображати довідку для зазначених модулів.",
+       "apihelp-help-param-modules": "Модулі, для яких відображати довідку (значення параметрів <var>action</var> і <var>format</var> або <kbd>main</kbd>). Можна вказати під модулі через <kbd>+</kbd>.",
+       "apihelp-help-param-recursivesubmodules": "Включити довідку для підмодулів рекурсивно.",
+       "apihelp-help-param-helpformat": "Формат результату довідки.",
+       "apihelp-help-param-wrap": "Помістити результат у стандартну структуру API-відповіді.",
+       "apihelp-help-param-toc": "Включити зміст у HTML-результат.",
+       "apihelp-help-example-main": "Довідка для головного модуля.",
+       "apihelp-help-example-recursive": "Уся довідка на одній сторінці.",
+       "apihelp-help-example-help": "Довідка для самого модуля довідки.",
+       "apihelp-help-example-query": "Довідка для двох підмодулів запитів.",
+       "apihelp-imagerotate-description": "Поворот одного або декількох зображень.",
+       "apihelp-imagerotate-param-rotation": "Градуси для повороту зображення за годинниковою стрілкою.",
+       "apihelp-imagerotate-example-simple": "Повернути <kbd>File:Example.png</kbd> на <kbd>90</kbd> градусів.",
+       "apihelp-imagerotate-example-generator": "Повернути усі зображення у <kbd>Category:Flip</kbd> на <kbd>180</kbd> градусів.",
+       "apihelp-import-description": "Імпортувати сторінку з іншої вікі або з XML-файлу.\n\nЗважте, що HTTP POST має бути виконано як завантаження файлу (тобто з використанням даних різних частин/форм) під час надсилання файлу для параметра <var>xml</var>.",
+       "apihelp-import-param-summary": "Імпортувати підсумок.",
+       "apihelp-import-param-xml": "Завантажено XML-файл.",
+       "apihelp-import-param-interwikisource": "Для інтервікі-імпорту: вікі, з якої імпортувати.",
+       "apihelp-import-param-interwikipage": "Для інтервікі-імпорту: сторінки для імпорту.",
+       "apihelp-import-param-fullhistory": "Для інтервікі-імпорту: імпортувати повну історію, не лише поточну версію.",
+       "apihelp-import-param-templates": "Для інтервікі-імпорту: імпортувати також усі включені шаблони.",
+       "apihelp-import-param-namespace": "Імпортувати у цей простір назв. Не можна використати разом з <var>$1rootpage</var>.",
+       "apihelp-import-param-rootpage": "Імпортувати як підсторінку цієї сторінки. Не можна використати разом з <var>$1namespace</var>.",
+       "apihelp-import-example-import": "Імпортувати [[meta:Help:ParserFunctions]] у простір назв 100 з повною історією.",
+       "apihelp-login-description": "Увійти в систему й отримати куки автентифікації.\n\nУ випадку успішного входження в систему, потрібні куки буде включено в заголовки HTTP-відповіді. У разі невдалого входу, подальші спроби будуть обмежені до ліміту автоматичних спроб підбирання пароля.",
+       "apihelp-login-param-name": "Ім'я користувача.",
+       "apihelp-login-param-password": "Пароль.",
+       "apihelp-login-param-domain": "Домен (необов'язково).",
+       "apihelp-login-param-token": "Токен входу в систему, отриманий у першому запиті.",
+       "apihelp-login-example-gettoken": "Отримати токен входу в систему.",
+       "apihelp-login-example-login": "Увійти в систему.",
+       "apihelp-logout-description": "Вийти й очистити дані сесії.",
+       "apihelp-logout-example-logout": "Вийти з поточного облікового запису.",
+       "apihelp-managetags-description": "Виконати керівні завдання щодо зміни теґів.",
        "apihelp-move-param-ignorewarnings": "Ігнорувати всі попередження",
        "api-help-datatypes-header": "Типи даних"
 }
index c75658c..fd476c6 100644 (file)
        "apihelp-query-param-prop": "要为已查询页面获取的属性。",
        "apihelp-query-param-list": "要获取的列表。",
        "apihelp-query-param-meta": "要获取的元数据。",
+       "apihelp-query-param-indexpageids": "包含一个额外的pageid段落,列举所有返回的页面ID。",
+       "apihelp-query-param-export": "导出所有指定或生成页面的当前修订。",
        "apihelp-query-param-exportnowrap": "返回导出XML,不需要将其包裹在一个XML结果中(与[[Special:Export]]格式相同)。只能与$1export一起使用。",
+       "apihelp-query-param-iwurl": "如果标题是一个跨wiki链接的话,是否获取完整URL。",
        "apihelp-query-param-rawcontinue": "为继续返回原始<samp>query-continue</samp>数据。",
        "apihelp-query-example-revisions": "获取<kbd>Main Page</kbd>的[[Special:ApiHelp/query+siteinfo|网站信息]]和[[Special:ApiHelp/query+revisions|修订版本]]。",
        "apihelp-query-example-allpages": "获取以<kbd>API/</kbd>开头的页面的修订版本。",
-       "apihelp-query+allcategories-description": "枚举所有类别。",
+       "apihelp-query+allcategories-description": "列举所有分类。",
        "apihelp-query+allcategories-param-from": "要作为枚举起始点的类别。",
        "apihelp-query+allcategories-param-to": "要作为枚举终止点的类别。",
-       "apihelp-query+allcategories-param-prefix": "æ\90\9c索此å\80¼å¼\80头ç\9a\84æ\89\80æ\9c\89分类标题。",
+       "apihelp-query+allcategories-param-prefix": "æ\90\9cç´¢æ\89\80æ\9c\89以此å\80¼å¼\80头ç\9a\84分类标题。",
        "apihelp-query+allcategories-param-dir": "排序方向。",
        "apihelp-query+allcategories-param-min": "只返回至少带这么多成员的分类。",
        "apihelp-query+allcategories-param-max": "只返回最多带这么多成员的分类。",
        "apihelp-query+alldeletedrevisions-param-end": "枚举的结束时间戳。",
        "apihelp-query+alldeletedrevisions-param-from": "从此标题开始列出。",
        "apihelp-query+alldeletedrevisions-param-to": "列出至此标题为止。",
-       "apihelp-query+alldeletedrevisions-param-prefix": "æ\90\9cç´¢æ \87é¢\98以此å\80¼å¼\80头ç\9a\84æ\89\80æ\9c\89页é\9d¢。",
+       "apihelp-query+alldeletedrevisions-param-prefix": "æ\90\9cç´¢æ\89\80æ\9c\89以此å\80¼å¼\80头ç\9a\84页é\9d¢æ \87é¢\98。",
        "apihelp-query+alldeletedrevisions-param-tag": "只列出被此标签标记的修订。",
        "apihelp-query+alldeletedrevisions-param-user": "只列出此用户做出的修订。",
        "apihelp-query+alldeletedrevisions-param-excludeuser": "不要列出此用户做出的修订。",
        "apihelp-query+allfileusages-description": "列出所有文件用途,包括不存在的。",
        "apihelp-query+allfileusages-param-from": "要列举的起始文件标题。",
        "apihelp-query+allfileusages-param-to": "要列举的最终文件标题。",
-       "apihelp-query+allfileusages-param-prefix": "æ\90\9c索此å\80¼å¼\80头ç\9a\84æ\89\80æ\9c\89文件标题。",
+       "apihelp-query+allfileusages-param-prefix": "æ\90\9cç´¢æ\89\80æ\9c\89以此å\80¼å¼\80头ç\9a\84文件标题。",
        "apihelp-query+allfileusages-param-unique": "只显示明显的文件标题。不能与$1prop=ids一起使用。\n当作为生成器使用时,产生目标页面而不是来源页面。",
        "apihelp-query+allfileusages-param-prop": "要包含的信息束:\n;ids:添加使用中的页面的页面ID(不能与$1unique一起使用)。\n;title:添加文件的标题。",
        "apihelp-query+allfileusages-param-limit": "要返回的总计项目。",
        "apihelp-query+allimages-param-to": "要列举的最终图片标题。只能与$1sort=name一起使用。",
        "apihelp-query+allimages-param-start": "要列举的起始时间戳。只能与$1sort=timestamp一起使用。",
        "apihelp-query+allimages-param-end": "要列举的最终时间戳。只能与$1sort=timestamp一起使用。",
+       "apihelp-query+allimages-param-prefix": "搜索所有以此值开头的图像标题。只能与$1sort=name一起使用。",
        "apihelp-query+allimages-param-minsize": "限于至少这么多字节的图像。",
        "apihelp-query+allimages-param-maxsize": "限于顶多这么多字节的图像。",
        "apihelp-query+allimages-param-sha1": "图像的 SHA1 哈希。覆盖$1sha1base36。",
        "apihelp-query+alllinks-description": "列举所有指向至指定名字空间的链接。",
        "apihelp-query+alllinks-param-from": "要列举的起始标题链接。",
        "apihelp-query+alllinks-param-to": "要列举的最终标题链接。",
-       "apihelp-query+alllinks-param-prefix": "搜索此值开头的所有已链接标题。",
+       "apihelp-query+alllinks-param-prefix": "搜索所有以此值开头的已链接标题。",
+       "apihelp-query+alllinks-param-unique": "只显示明显的链接标题。不能与<kbd>$1prop=ids</kbd>一起使用。\n当作为生成器使用时,产生目标页面而不是来源页面。",
+       "apihelp-query+alllinks-param-prop": "要包含的信息束:\n;ids:添加链接中的页面的页面ID(不能与<var>$1unique</var>一起使用)。\n;title:添加链接的标题。",
        "apihelp-query+alllinks-param-namespace": "要列举的名字空间。",
        "apihelp-query+alllinks-param-limit": "总共要返回多少个项目。",
        "apihelp-query+alllinks-param-dir": "列出方向。",
        "apihelp-query+allmessages-param-prefix": "返回带有该前缀的消息。",
        "apihelp-query+allmessages-example-ipb": "显示以<kbd>ipb-</kbd>开始的消息。",
        "apihelp-query+allmessages-example-de": "显示德语版的<kbd>august</kbd>和<kbd>mainpage</kbd>消息。",
+       "apihelp-query+allpages-description": "循序列举在指定名字空间中的所有页面。",
        "apihelp-query+allpages-param-from": "枚举的起始页面标题。",
        "apihelp-query+allpages-param-to": "枚举的结束页面标题。",
+       "apihelp-query+allpages-param-prefix": "搜索所有以此值开头的页面标题。",
        "apihelp-query+allpages-param-namespace": "要列举的名字空间。",
        "apihelp-query+allpages-param-filterredir": "要列出哪些页面。",
        "apihelp-query+allpages-param-minsize": "限于至少这么多字节的页面。",
        "apihelp-query+allpages-param-maxsize": "限于至多这么多字节的页面。",
        "apihelp-query+allpages-param-prtype": "仅限于受保护页面。",
+       "apihelp-query+allpages-param-prfiltercascade": "过滤基于cascadingness的保护(当$1prtype未设置时忽略)。",
        "apihelp-query+allpages-param-limit": "返回的总计页面数。",
        "apihelp-query+allpages-param-dir": "罗列所采用的方向。",
+       "apihelp-query+allpages-param-filterlanglinks": "过滤基于页面是否有语言链接。注意这可能不考虑由扩展添加的语言链接。",
+       "apihelp-query+allpages-param-prexpiry": "要在页面上过滤的保护期限:\n;indefinite:只获取带无限期保护的页面。\n;definite:只获取带指定保护期限的页面。\n;all:获取任意保护期限的页面。",
        "apihelp-query+allpages-example-B": "显示以字母<kbd>B</kbd>开头的页面的列表。",
        "apihelp-query+allpages-example-generator": "显示有关4个以字母<kbd>T</kbd>开头的页面的信息。",
        "apihelp-query+allpages-example-generator-revisions": "显示前2个以<kbd>Re</kbd>开头的非重定向页面的内容。",
        "apihelp-query+allredirects-description": "列出至一个名字空间的重定向。",
        "apihelp-query+allredirects-param-from": "要列举的起始重定向标题。",
        "apihelp-query+allredirects-param-to": "要列举的最终重定向标题。",
+       "apihelp-query+allredirects-param-prefix": "搜索所有以此值开头的目标页面。",
+       "apihelp-query+allredirects-param-prop": "要包含的信息束:\n;ids:添加重定向页面的页面ID(不能与<var>$1unique</var>一起使用)。\n;title:添加重定向的标题。\n;fragment:添加来自重定向的碎片,如果有(不能与<var>$1unique</var>一起使用)。\n;interwiki:添加来自重定向的跨wiki前缀,如果有(不能与<var>$1unique</var>一起使用)。",
        "apihelp-query+allredirects-param-namespace": "要列举的名字空间。",
        "apihelp-query+allredirects-param-limit": "返回的总计项目数。",
        "apihelp-query+allredirects-param-dir": "罗列所采用的方向。",
        "apihelp-query+alltransclusions-description": "列出所有嵌入页面(使用&#123;&#123;x&#125;&#125;嵌入的页面),包括不存在的。",
        "apihelp-query+alltransclusions-param-from": "要列举的起始嵌入标题。",
        "apihelp-query+alltransclusions-param-to": "要列举的最终嵌入标题。",
+       "apihelp-query+alltransclusions-param-prefix": "搜索所有以此值开头的嵌入的标题。",
+       "apihelp-query+alltransclusions-param-prop": "要包含的信息束:\n;ids:添加嵌入中的页面的页面ID(不能与$1unique一起使用)。\n;title:添加嵌入的标题。",
        "apihelp-query+alltransclusions-param-namespace": "要列举的名字空间。",
        "apihelp-query+alltransclusions-param-limit": "要返回的总计项目。",
        "apihelp-query+alltransclusions-param-dir": "罗列所采用的方向。",
        "apihelp-query+allusers-description": "列举所有注册用户。",
        "apihelp-query+allusers-param-from": "枚举的起始用户名。",
        "apihelp-query+allusers-param-to": "枚举的结束用户名。",
-       "apihelp-query+allusers-param-prefix": "搜索以此值开始的所有用户。",
+       "apihelp-query+allusers-param-prefix": "搜索所有以此值开头的用户。",
        "apihelp-query+allusers-param-dir": "排序方向。",
        "apihelp-query+allusers-param-group": "只包含指定组中的用户。",
        "apihelp-query+allusers-param-excludegroup": "排除指定组中的用户。",
        "apihelp-query+allusers-param-rights": "仅列出有所选权限的用户。不包括隐性的或自动加入的用户组别(如*、用户或自动确认用户)所授予的权限。",
+       "apihelp-query+allusers-param-prop": "要包含的信息束:\n;blockinfo:添加有关用户当前封禁的信息。\n;groups:列举用户所在的组。这使用更多服务器资源,并可能返回少于限制的结果。\n;implicitgroups:Lists all the groups the user is automatically in.\n;rights:Lists rights that the user has.\n;editcount:Adds the edit count of the user.\n;registration:Adds the timestamp of when the user registered if available (may be blank).",
        "apihelp-query+allusers-param-limit": "返回的总计用户数。",
        "apihelp-query+allusers-param-witheditsonly": "只列出有编辑的用户。",
        "apihelp-query+allusers-param-activeusers": "只列出最近$1{{PLURAL:$1|天}}内活跃的用户。",
        "apihelp-query+categorymembers-description": "在指定的分类中列出所有页面。",
        "apihelp-query+categorymembers-param-title": "要列举的分类(必需)。必须包括<kbd>{{ns:category}}:</kbd>前缀。不能与<var>$1pageid</var>一起使用。",
        "apihelp-query+categorymembers-param-pageid": "要枚举的分类的页面 ID。不能与<var>$1title</var>一起使用。",
+       "apihelp-query+categorymembers-param-prop": "要包含的信息束:\n;ids:添加页面ID。\n;title:添加页面标题和名字空间ID。\n;sortkey:Adds the sortkey used for sorting in the category (hexadecimal string).\n;sortkeyprefix:Adds the sortkey prefix used for sorting in the category (human-readable part of the sortkey).\n;type:Adds the type that the page has been categorised as (page, subcat or file).\n;timestamp:Adds the timestamp of when the page was included.",
        "apihelp-query+categorymembers-param-namespace": "仅包含这些名字空间的页面。注意<kbd>$1type=subcat</kbd>或<kbd>$1type=file</kbd>可能被使用,而不是<kbd>$1namespace=14</kbd>或<kbd>6</kbd>。",
        "apihelp-query+categorymembers-param-type": "包含的分类成员类型。当<kbd>$1sort=timestamp</kbd>被设置时会忽略。",
        "apihelp-query+categorymembers-param-limit": "返回页面的最大数量。",
        "apihelp-query+deletedrevisions-param-excludeuser": "不要列出此用户做出的修订。",
        "apihelp-query+deletedrevisions-example-titles": "列出页面<kbd>Main Page</kbd>和<kbd>Talk:Main Page</kbd>的已删除修订,包含内容。",
        "apihelp-query+deletedrevisions-example-revids": "列出已删除修订<kbd>123456</kbd>的信息。",
-       "apihelp-query+deletedrevs-description": "列出被删除修订。\n\n操作于三种模式中:\n# List deleted revisions for the given titles, sorted by timestamp.\n# List deleted contributions for the given user, sorted by timestamp (no titles specified).\n# List all deleted revisions in the given namespace, sorted by title and timestamp (no titles specified, $1user not set).\n\nCertain parameters only apply to some modes and are ignored in others.",
+       "apihelp-query+deletedrevs-description": "列出被删除修订。\n\n操作于三种模式中:\n# 为指定标题列举已删除修订,按时间戳排列。\n# List deleted contributions for the given user, sorted by timestamp (no titles specified).\n# List all deleted revisions in the given namespace, sorted by title and timestamp (no titles specified, $1user not set).\n\nCertain parameters only apply to some modes and are ignored in others.",
        "apihelp-query+deletedrevs-paraminfo-modes": "{{PLURAL:$1|模式}}:$2",
        "apihelp-query+deletedrevs-param-start": "枚举的起始时间戳。",
        "apihelp-query+deletedrevs-param-end": "枚举的结束时间戳。",
        "apihelp-query+deletedrevs-param-from": "从此标题开始列出。",
        "apihelp-query+deletedrevs-param-to": "列出至此标题为止。",
-       "apihelp-query+deletedrevs-param-prefix": "æ\90\9cç´¢æ \87é¢\98以此å\80¼å¼\80头ç\9a\84æ\89\80æ\9c\89页é\9d¢。",
+       "apihelp-query+deletedrevs-param-prefix": "æ\90\9cç´¢æ\89\80æ\9c\89以此å\80¼å¼\80头ç\9a\84页é\9d¢æ \87é¢\98。",
        "apihelp-query+deletedrevs-param-unique": "每个页面只列出一个修订。",
        "apihelp-query+deletedrevs-param-tag": "只列出被此标签标记的修订。",
        "apihelp-query+deletedrevs-param-user": "只列出此用户做出的修订。",
        "apihelp-query+duplicatefiles-param-localonly": "只看本地存储库的文件。",
        "apihelp-query+duplicatefiles-example-simple": "查找与[[:File:Albert Einstein Head.jpg]]重复的文件。",
        "apihelp-query+duplicatefiles-example-generated": "查找所有文件的重复文件。",
+       "apihelp-query+embeddedin-description": "查找所有嵌入指定标题的页面。",
        "apihelp-query+embeddedin-param-title": "要搜索的标题。不能与$1pageid一起使用。",
        "apihelp-query+embeddedin-param-pageid": "要搜索的页面ID。不能与$1title一起使用。",
        "apihelp-query+embeddedin-param-namespace": "列举的名字空间。",
        "apihelp-query+extlinks-param-expandurl": "扩展协议相对URL与规范协议。",
        "apihelp-query+extlinks-example-simple": "获取<kbd>Main Page<kbd>的外部链接列表。",
        "apihelp-query+exturlusage-description": "列举包含一个指定URL的页面。",
+       "apihelp-query+exturlusage-param-prop": "要包含的信息束:\n;ids:添加页面ID。\n;title:添加页面的标题和名字空间ID。\n;url:添加页面中使用的URL。",
        "apihelp-query+exturlusage-param-protocol": "URL协议。如果为空并且<var>$1query</var>被设置,协议为<kbd>http</kbd>。将此和<var>$1query</var>都留空以列举所有外部链接。",
        "apihelp-query+exturlusage-param-query": "不包括协议的搜索字符串。参见[[Special:LinkSearch]]。留空以列出所有外部链接。",
        "apihelp-query+exturlusage-param-namespace": "要列举的页面名字空间。",
        "apihelp-query+info-param-token": "请改用[[Special:ApiHelp/query+tokens|action=query&meta=tokens]]。",
        "apihelp-query+info-example-simple": "获取有关页面<kbd>Main Page</kbd>的信息。",
        "apihelp-query+info-example-protection": "获取<kbd>Main Page</kbd>相关的常规和保护信息。",
+       "apihelp-query+iwbacklinks-description": "查找所有链接至指定跨wiki链接的页面。\n\n可被用于查找带某一前缀的所有链接,或所有至某一标题的链接(带指定前缀)。两参数都不使用就意味着“所有跨wiki链接”。",
        "apihelp-query+iwbacklinks-param-prefix": "跨维基前缀。",
        "apihelp-query+iwbacklinks-param-title": "要搜索的跨wiki链接。必须与<var>$1blprefix</var>一起使用。",
        "apihelp-query+iwbacklinks-param-limit": "返回的总计页面数。",
        "apihelp-query+pagepropnames-example-simple": "获取前10个属性名称。",
        "apihelp-query+pageprops-example-simple": "获取用于页面<kbd>Main Page</kbd>和<kbd>MediaWiki</kbd>的属性。",
        "apihelp-query+pageswithprop-description": "列出所有使用指定页面属性的页面。",
+       "apihelp-query+pageswithprop-param-prop": "要包含的信息束:\n;ids:添加页面ID。\n;title:添加页面的标题和名字空间ID。\n;value:添加页面属性值。",
        "apihelp-query+pageswithprop-param-limit": "返回页面的最大数量。",
        "apihelp-query+pageswithprop-param-dir": "排序的方向。",
        "apihelp-query+pageswithprop-example-simple": "列出前10个使用<code>&#123;&#123;DISPLAYTITLE:&#125;&#125;</code>的页面。",
        "apihelp-query+usercontribs-example-user": "显示用户<kbd>Example</kbd>的贡献。",
        "apihelp-query+usercontribs-example-ipprefix": "显示来自<kbd>192.0.2.</kbd>前缀所有 IP 地址的贡献。",
        "apihelp-query+userinfo-description": "获取有关当前用户的信息。",
-       "apihelp-query+userinfo-param-prop": "要包含的信息束:\n;blockinfo:如果当前用户被封禁就标记,并注明是谁封禁,以何种原因封禁的。\n;hasmsg:Adds a tag <samp>messages</samp> if the current user has pending messages.\n;groups:Lists all the groups the current user belongs to.\n;implicitgroups:Lists all the groups the current user is automatically a member of.\n;rights:Lists all the rights the current user has.\n;changeablegroups:Lists the groups the current user can add to and remove from.\n;options:Lists all preferences the current user has set.\n;preferencestoken:<span class=\"apihelp-deprecated\">Deprecated.</span> Get a token to change current user's preferences.\n;editcount:Adds the current user's edit count.\n;ratelimits:Lists all rate limits applying to the current user.\n;realname:Adds the user's real name.\n;email:Adds the user's email address and email authentication date.\n;acceptlang:Echoes the <code>Accept-Language</code> header sent by the client in a structured format.\n;registrationdate:Adds the user's registration date.\n;unreadcount:Adds the count of unread pages on the user's watchlist (maximum $1; returns <samp>$2</samp> if more).",
+       "apihelp-query+userinfo-param-prop": "要包含的信息束:\n;blockinfo:如果当前用户被封禁就标记,并注明是谁封禁,以何种原因封禁的。\n;hasmsg:如果当前用户有等待中的消息的话,添加标签<samp>messages</samp>。\n;groups:Lists all the groups the current user belongs to.\n;implicitgroups:Lists all the groups the current user is automatically a member of.\n;rights:Lists all the rights the current user has.\n;changeablegroups:Lists the groups the current user can add to and remove from.\n;options:Lists all preferences the current user has set.\n;preferencestoken:<span class=\"apihelp-deprecated\">Deprecated.</span> Get a token to change current user's preferences.\n;editcount:Adds the current user's edit count.\n;ratelimits:Lists all rate limits applying to the current user.\n;realname:Adds the user's real name.\n;email:Adds the user's email address and email authentication date.\n;acceptlang:Echoes the <code>Accept-Language</code> header sent by the client in a structured format.\n;registrationdate:Adds the user's registration date.\n;unreadcount:Adds the count of unread pages on the user's watchlist (maximum $1; returns <samp>$2</samp> if more).",
        "apihelp-query+userinfo-example-simple": "获取有关当前用户的信息。",
        "apihelp-query+userinfo-example-data": "获取有关当前用户的额外信息。",
        "apihelp-query+users-description": "获取有关列出用户的信息。",
+       "apihelp-query+users-param-prop": "要包含的信息束:\n;blockinfo:如果用户被封禁就标记,并注明是谁封禁,以何种原因封禁的。\n;groups:列举每位用户属于的所有组。\n;implicitgroups:Lists all the groups a user is automatically a member of.\n;rights:Lists all the rights each user has.\n;editcount:Adds the user's edit count.\n;registration:Adds the user's registration timestamp.\n;emailable:Tags if the user can and wants to receive email through [[Special:Emailuser]].\n;gender:Tags the gender of the user. Returns \"male\", \"female\", or \"unknown\".",
        "apihelp-query+users-param-token": "请改用<kbd>[[Special:ApiHelp/query+tokens|action=query&meta=tokens]]</kbd>。",
        "apihelp-query+users-example-simple": "返回用户<kbd>Example</kbd>的信息。",
        "apihelp-query+watchlist-param-start": "枚举的起始时间戳。",
index 8531e23..b1e6d95 100644 (file)
@@ -43,7 +43,7 @@
        "apihelp-createaccount-param-name": "使用者名稱。",
        "apihelp-createaccount-param-password": "密碼 (若有設定 <var>$1mailpassword</var> 則可略過)。",
        "apihelp-createaccount-param-domain": "外部認証使用的網域 (選填)。",
-       "apihelp-createaccount-param-token": "å·²å\8f\96å¾\97帳è\99\9f建ç«\8bå¯\86é\91°æ\96¼ç¬¬ä¸\80次è«\8bæ±\82。",
+       "apihelp-createaccount-param-token": "å\9c¨ç¬¬ä¸\80次è«\8bæ±\82æ\99\82å·²å\8f\96å¾\97ç\9a\84帳è\99\9f建ç«\8bé\87\91é\91°。",
        "apihelp-createaccount-param-email": "使用者的電子郵件地址 (選填) 。",
        "apihelp-createaccount-param-realname": "使用者的真實姓名 (選填)。",
        "apihelp-createaccount-param-mailpassword": "若設為其他值,將會以電子郵件寄送隨機密碼給使用者。",
        "apihelp-query+stashimageinfo-example-simple": "回傳儲藏檔案的檔案資訊。",
        "apihelp-query+templates-description": "回傳指定頁面中所有引用的頁面。",
        "apihelp-query+templates-param-limit": "要回傳的模板數量。",
-       "apihelp-query+tokens-param-type": "è¦\81è«\8bæ±\82ç\9a\84å¯\86é\91°é¡\9eå\9e\8bã\80\82",
+       "apihelp-query+tokens-param-type": "請求的密鑰類型。",
        "apihelp-query+tokens-example-simple": "接收 csrf 密鑰 (預設)。",
        "apihelp-query+tokens-example-types": "接收監視密鑰以及巡邏密鑰。",
        "apihelp-query+transcludedin-param-limit": "回傳的數量。",
        "apihelp-format-example-generic": "格式化查詢結果為 $1 格式",
        "apihelp-dbg-description": "使用 PHP 的 <code>var_export()</code> 格式輸出資料。",
        "apihelp-dbgfm-description": "使用 PHP 的 <code>var_export()</code> 格式輸出資料 (使用 HTML 格式顯示)。",
-       "apihelp-dump-description": "使用 PHP 的 <code>var_dump()</code> 格式輸出資料。",
-       "apihelp-dumpfm-description": "使用 PHP 的 <code>var_dump()</code> 格式輸出資料 (使用 HTML 格式顯示)。",
        "apihelp-json-description": "使用 JSON 格式輸出資料。",
        "apihelp-jsonfm-description": "使用 JSON 格式輸出資料 (使用 HTML 格式顯示)。",
        "apihelp-none-description": "不輸出。",
        "apihelp-rawfm-description": "使用 JSON 格式的除錯元素輸出資料 (使用 HTML 格式顯示)。",
        "apihelp-txt-description": "使用 PHP 的 <code>print_r()</code> 格式輸出資料。",
        "apihelp-txtfm-description": "使用 PHP 的 <code>print_r()</code> 格式輸出資料 (使用 HTML 格式顯示)。",
-       "apihelp-wddx-description": "使用 WDDX 格式輸出資料。",
-       "apihelp-wddxfm-description": "使用 WDDX 格式輸出資料 (使用 HTML 格式顯示)。",
        "apihelp-xml-description": "使用 XML 格式輸出資料。",
        "apihelp-xmlfm-description": "使用 XML 格式輸出資料 (使用 HTML 格式顯示)。",
        "apihelp-yaml-description": "使用 YAML 格式輸出資料。",
index c0194c2..6d23656 100644 (file)
  */
 class JavaScriptContent extends TextContent {
 
+       /**
+        * @var bool|Title|null
+        */
+       private $redirectTarget = false;
+
        /**
         * @param string $text JavaScript code.
         * @param string $modelId the content model name
@@ -73,4 +78,46 @@ class JavaScriptContent extends TextContent {
                return $html;
        }
 
+       /**
+        * If this page is a redirect, return the content
+        * if it should redirect to $target instead
+        *
+        * @param Title $target
+        * @return JavaScriptContent
+        */
+       public function updateRedirect( Title $target ) {
+               if ( !$this->isRedirect() ) {
+                       return $this;
+               }
+
+               return $this->getContentHandler()->makeRedirectContent( $target );
+       }
+
+       /**
+        * @return Title|null
+        */
+       public function getRedirectTarget() {
+               if ( $this->redirectTarget !== false ) {
+                       return $this->redirectTarget;
+               }
+               $this->redirectTarget = null;
+               $text = $this->getNativeData();
+               if ( strpos( $text, '/* #REDIRECT */' ) === 0 ) {
+                       // Extract the title from the url
+                       preg_match( '/title=(.*?)\\\\u0026action=raw/', $text, $matches );
+                       if ( isset( $matches[1] ) ) {
+                               $title = Title::newFromText( $matches[1] );
+                               if ( $title ) {
+                                       // Have a title, check that the current content equals what
+                                       // the redirect content should be
+                                       if ( $this->equals( $this->getContentHandler()->makeRedirectContent( $title ) ) ) {
+                                               $this->redirectTarget = $title;
+                                       }
+                               }
+                       }
+               }
+
+               return $this->redirectTarget;
+       }
+
 }
index d221897..65e3a6f 100644 (file)
@@ -41,4 +41,22 @@ class JavaScriptContentHandler extends CodeContentHandler {
        protected function getContentClass() {
                return 'JavaScriptContent';
        }
+
+       public function supportsRedirects() {
+               return true;
+       }
+
+       /**
+        * Create a redirect that is also valid JavaScript
+        *
+        * @param Title $destination
+        * @param string $text ignored
+        * @return JavaScriptContent
+        */
+       public function makeRedirectContent( Title $destination, $text = '' ) {
+               // The parameters are passed as a string so the / is not url-encoded by wfArrayToCgi
+               $url = $destination->getFullURL( 'action=raw&ctype=text/javascript', false, PROTO_RELATIVE );
+               $class = $this->getContentClass();
+               return new $class( '/* #REDIRECT */' . Xml::encodeJsCall( 'mw.loader.load', array( $url ) ) );
+       }
 }
index 04b3edd..2ee4545 100644 (file)
@@ -230,7 +230,7 @@ abstract class DatabaseBase implements IDatabase {
         * @param null|bool $ignoreErrors
         * @return bool The previous value of the flag.
         */
-       public function ignoreErrors( $ignoreErrors = null ) {
+       protected function ignoreErrors( $ignoreErrors = null ) {
                return wfSetBit( $this->mFlags, DBO_IGNORE, $ignoreErrors );
        }
 
@@ -605,125 +605,6 @@ abstract class DatabaseBase implements IDatabase {
                return $this->getSqlFilePath( 'update-keys.sql' );
        }
 
-       /**
-        * Get the type of the DBMS, as it appears in $wgDBtype.
-        *
-        * @return string
-        */
-       abstract function getType();
-
-       /**
-        * Open a connection to the database. Usually aborts on failure
-        *
-        * @param string $server Database server host
-        * @param string $user Database user name
-        * @param string $password Database user password
-        * @param string $dbName Database name
-        * @return bool
-        * @throws DBConnectionError
-        */
-       abstract function open( $server, $user, $password, $dbName );
-
-       /**
-        * Fetch the next row from the given result object, in object form.
-        * Fields can be retrieved with $row->fieldname, with fields acting like
-        * member variables.
-        * If no more rows are available, false is returned.
-        *
-        * @param ResultWrapper|stdClass $res Object as returned from DatabaseBase::query(), etc.
-        * @return stdClass|bool
-        * @throws DBUnexpectedError Thrown if the database returns an error
-        */
-       abstract function fetchObject( $res );
-
-       /**
-        * Fetch the next row from the given result object, in associative array
-        * form. Fields are retrieved with $row['fieldname'].
-        * If no more rows are available, false is returned.
-        *
-        * @param ResultWrapper $res Result object as returned from DatabaseBase::query(), etc.
-        * @return array|bool
-        * @throws DBUnexpectedError Thrown if the database returns an error
-        */
-       abstract function fetchRow( $res );
-
-       /**
-        * Get the number of rows in a result object
-        *
-        * @param mixed $res A SQL result
-        * @return int
-        */
-       abstract function numRows( $res );
-
-       /**
-        * Get the number of fields in a result object
-        * @see http://www.php.net/mysql_num_fields
-        *
-        * @param mixed $res A SQL result
-        * @return int
-        */
-       abstract function numFields( $res );
-
-       /**
-        * Get a field name in a result object
-        * @see http://www.php.net/mysql_field_name
-        *
-        * @param mixed $res A SQL result
-        * @param int $n
-        * @return string
-        */
-       abstract function fieldName( $res, $n );
-
-       /**
-        * Get the inserted value of an auto-increment row
-        *
-        * The value inserted should be fetched from nextSequenceValue()
-        *
-        * Example:
-        * $id = $dbw->nextSequenceValue( 'page_page_id_seq' );
-        * $dbw->insert( 'page', array( 'page_id' => $id ) );
-        * $id = $dbw->insertId();
-        *
-        * @return int
-        */
-       abstract function insertId();
-
-       /**
-        * Change the position of the cursor in a result object
-        * @see http://www.php.net/mysql_data_seek
-        *
-        * @param mixed $res A SQL result
-        * @param int $row
-        */
-       abstract function dataSeek( $res, $row );
-
-       /**
-        * Get the last error number
-        * @see http://www.php.net/mysql_errno
-        *
-        * @return int
-        */
-       abstract function lastErrno();
-
-       /**
-        * Get a description of the last error
-        * @see http://www.php.net/mysql_error
-        *
-        * @return string
-        */
-       abstract function lastError();
-
-       /**
-        * mysql_fetch_field() wrapper
-        * Returns false if the field doesn't exist
-        *
-        * @param string $table Table name
-        * @param string $field Field name
-        *
-        * @return Field
-        */
-       abstract function fieldInfo( $table, $field );
-
        /**
         * Get information about an index into an object
         * @param string $table Table name
@@ -733,14 +614,6 @@ abstract class DatabaseBase implements IDatabase {
         */
        abstract function indexInfo( $table, $index, $fname = __METHOD__ );
 
-       /**
-        * Get the number of rows affected by the last write query
-        * @see http://www.php.net/mysql_affected_rows
-        *
-        * @return int
-        */
-       abstract function affectedRows();
-
        /**
         * Wrapper for addslashes()
         *
@@ -749,24 +622,6 @@ abstract class DatabaseBase implements IDatabase {
         */
        abstract function strencode( $s );
 
-       /**
-        * Returns a wikitext link to the DB's website, e.g.,
-        *   return "[http://www.mysql.com/ MySQL]";
-        * Should at least contain plain text, if for some reason
-        * your database has no website.
-        *
-        * @return string Wikitext of a link to the server software's web site
-        */
-       abstract function getSoftwareLink();
-
-       /**
-        * A string describing the current software version, like from
-        * mysql_get_server_info().
-        *
-        * @return string Version information from the database server.
-        */
-       abstract function getServerVersion();
-
        /**
         * Constructor.
         *
diff --git a/includes/filerepo/FileBackendDBRepoWrapper.php b/includes/filerepo/FileBackendDBRepoWrapper.php
new file mode 100644 (file)
index 0000000..0401d0c
--- /dev/null
@@ -0,0 +1,357 @@
+<?php
+/**
+ * Proxy backend that manages file layout rewriting for FileRepo.
+ *
+ * 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 FileRepo
+ * @ingroup FileBackend
+ * @author Aaron Schulz
+ */
+
+/**
+ * @brief Proxy backend that manages file layout rewriting for FileRepo.
+ *
+ * LocalRepo may be configured to store files under their title names or by SHA-1.
+ * This acts as a shim in the later case, providing backwards compatability for
+ * most callers. All "public"/"deleted" zone files actually go in an "original"
+ * container and are never changed.
+ *
+ * This requires something like thumb_handler.php and img_auth.php for client viewing of files.
+ *
+ * @ingroup FileRepo
+ * @ingroup FileBackend
+ * @since 1.25
+ */
+class FileBackendDBRepoWrapper extends FileBackend {
+       /** @var FileBackend */
+       protected $backend;
+       /** @var string */
+       protected $repoName;
+       /** @var Closure */
+       protected $dbHandleFunc;
+       /** @var ProcessCacheLRU */
+       protected $resolvedPathCache;
+       /** @var Array Map of (index => DBConnRef) */
+       protected $dbs;
+
+       public function __construct( array $config ) {
+               $config['name'] = $config['backend']->getName();
+               $config['wikiId'] = $config['backend']->getWikiId();
+               parent::__construct( $config );
+               $this->backend = $config['backend'];
+               $this->repoName = $config['repoName'];
+               $this->dbHandleFunc = $config['dbHandleFactory'];
+               $this->resolvedPathCache = new ProcessCacheLRU( 100 );
+       }
+
+       /**
+        * Get the underlying FileBackend that is being wrapped
+        *
+        * @return FileBackend
+        */
+       public function getInternalBackend() {
+               return $this->backend;
+       }
+
+       /**
+        * Translate a legacy "title" path to it's "sha1" counterpart
+        *
+        * E.g. mwstore://local-backend/local-public/a/ab/<name>.jpg
+        * => mwstore://local-backend/local-original/x/y/z/<sha1>.jpg
+        *
+        * @param string $path
+        * @param bool $latest
+        * @return string
+        */
+       public function getBackendPath( $path, $latest = true ) {
+               $paths = $this->getBackendPaths( array( $path ), $latest );
+               return current( $paths );
+       }
+
+       /**
+        * Translate legacy "title" paths to their "sha1" counterparts
+        *
+        * E.g. mwstore://local-backend/local-public/a/ab/<name>.jpg
+        * => mwstore://local-backend/local-original/x/y/z/<sha1>.jpg
+        *
+        * @param array $paths
+        * @param bool $latest
+        * @return array Translated paths in same order
+        */
+       public function getBackendPaths( array $paths, $latest = true ) {
+               $db = $this->getDB( $latest ? DB_MASTER : DB_SLAVE );
+               $origBasePath = $this->backend->getContainerStoragePath( "{$this->repoName}-original" );
+
+               // @TODO: batching
+               $resolved = array();
+               foreach ( $paths as $i => $path ) {
+                       if ( !$latest && $this->resolvedPathCache->has( $path, 'target', 10 ) ) {
+                               $resolved[$i] = $this->resolvedPathCache->get( $path, 'target' );
+                               continue;
+                       }
+
+                       list( , $container, $rel ) = FileBackend::splitStoragePath( $path );
+
+                       if ( $container === "{$this->repoName}-public" ) {
+                               $name = basename( $path );
+                               if ( strpos( $path, '!' ) !== false ) {
+                                       $sha1 = $db->selectField( 'oldimage', 'oi_sha1',
+                                               array( 'oi_archive_name' => $name ),
+                                               __METHOD__
+                                       );
+                               } else {
+                                       $sha1 = $db->selectField( 'image', 'img_sha1',
+                                               array( 'img_name' => $name ),
+                                               __METHOD__
+                                       );
+                               }
+                               if ( !strlen( $sha1 ) ) {
+                                       $resolved[$i] = $path; // give up
+                                       continue;
+                               }
+                               $resolved[$i] = $this->getPathForSHA1( $sha1 );
+                               $this->resolvedPathCache->set( $path, 'target', $resolved[$i] );
+                       } elseif ( $container === "{$this->repoName}-deleted" ) {
+                               $name = basename( $path ); // <hash>.<ext>
+                               $sha1 = substr( $name, 0, strpos( $name, '.' ) ); // ignore extension
+                               $resolved[$i] = $this->getPathForSHA1( $sha1 );
+                               $this->resolvedPathCache->set( $path, 'target', $resolved[$i] );
+                       } else {
+                               $resolved[$i] = $path;
+                       }
+               }
+
+               $res = array();
+               foreach ( $paths as $i => $path ) {
+                       $res[$i] = $resolved[$i];
+               }
+
+               return $res;
+       }
+
+       protected function doOperationsInternal( array $ops, array $opts ) {
+               return $this->backend->doOperationsInternal( $this->mungeOpPaths( $ops ), $opts );
+       }
+
+       protected function doQuickOperationsInternal( array $ops ) {
+               return $this->backend->doQuickOperationsInternal( $this->mungeOpPaths( $ops ) );
+       }
+
+       protected function doPrepare( array $params ) {
+               return $this->backend->doPrepare( $params );
+       }
+
+       protected function doSecure( array $params ) {
+               return $this->backend->doSecure( $params );
+       }
+
+       protected function doPublish( array $params ) {
+               return $this->backend->doPublish( $params );
+       }
+
+       protected function doClean( array $params ) {
+               return $this->backend->doClean( $params );
+       }
+
+       public function concatenate( array $params ) {
+               return $this->translateSrcParams( __FUNCTION__, $params );
+       }
+
+       public function fileExists( array $params ) {
+               return $this->translateSrcParams( __FUNCTION__, $params );
+       }
+
+       public function getFileTimestamp( array $params ) {
+               return $this->translateSrcParams( __FUNCTION__, $params );
+       }
+
+       public function getFileSize( array $params ) {
+               return $this->translateSrcParams( __FUNCTION__, $params );
+       }
+
+       public function getFileStat( array $params ) {
+               return $this->translateSrcParams( __FUNCTION__, $params );
+       }
+
+       public function getFileXAttributes( array $params ) {
+               return $this->translateSrcParams( __FUNCTION__, $params );
+       }
+
+       public function getFileSha1Base36( array $params ) {
+               return $this->translateSrcParams( __FUNCTION__, $params );
+       }
+
+       public function getFileProps( array $params ) {
+               return $this->translateSrcParams( __FUNCTION__, $params );
+       }
+
+       public function streamFile( array $params ) {
+               // The stream methods use the file extension to determine the
+               // Content-Type (as MediaWiki should already validate it on upload).
+               // The translated SHA1 path has no extension, so this needs to use
+               // the untranslated path extension.
+               $type = StreamFile::contentTypeFromPath( $params['src'] );
+               if ( $type && $type != 'unknown/unknown' ) {
+                       $params['headers'][] = "Content-type: $type";
+               }
+               return $this->translateSrcParams( __FUNCTION__, $params );
+       }
+
+       public function getFileContentsMulti( array $params ) {
+               return $this->translateArrayResults( __FUNCTION__, $params );
+       }
+
+       public function getLocalReferenceMulti( array $params ) {
+               return $this->translateArrayResults( __FUNCTION__, $params );
+       }
+
+       public function getLocalCopyMulti( array $params ) {
+               return $this->translateArrayResults( __FUNCTION__, $params );
+       }
+
+       public function getFileHttpUrl( array $params ) {
+               return $this->translateSrcParams( __FUNCTION__, $params );
+       }
+
+       public function directoryExists( array $params ) {
+               return $this->backend->directoryExists( $params );
+       }
+
+       public function getDirectoryList( array $params ) {
+               return $this->backend->getDirectoryList( $params );
+       }
+
+       public function getFileList( array $params ) {
+               return $this->backend->getFileList( $params );
+       }
+
+       public function getFeatures() {
+               return $this->backend->getFeatures();
+       }
+
+       public function clearCache( array $paths = null ) {
+               $this->backend->clearCache( null ); // clear all
+       }
+
+       public function preloadCache( array $paths ) {
+               $paths = $this->getBackendPaths( $paths );
+               $this->backend->preloadCache( $paths );
+       }
+
+       public function preloadFileStat( array $params ) {
+               return $this->translateSrcParams( __FUNCTION__, $params );
+       }
+
+       public function getScopedLocksForOps( array $ops, Status $status ) {
+               return $this->backend->getScopedFileLocks( $ops, $status );
+       }
+
+       /**
+        * Get the ultimate original storage path for a file
+        *
+        * Use this when putting a new file into the system
+        *
+        * @param string $sha1 File SHA-1 base36
+        * @return string
+        */
+       public function getPathForSHA1( $sha1 ) {
+               if ( strlen( $sha1 ) < 3 ) {
+                       throw new MWException( "Invalid file SHA-1." );
+               }
+               return $this->backend->getContainerStoragePath( "{$this->repoName}-original" ) .
+                       "/{$sha1[0]}/{$sha1[1]}/{$sha1[2]}/{$sha1}";
+       }
+
+       /**
+        * Get a connection to the repo file registry DB
+        *
+        * @param integer $index
+        * @return DBConnRef
+        */
+       protected function getDB( $index ) {
+               if ( !isset( $this->db[$index] ) ) {
+                       $func = $this->dbHandleFunc;
+                       $this->db[$index] = $func( $index );
+               }
+               return $this->db[$index];
+       }
+
+       /**
+        * Translates paths found in the "src" or "srcs" keys of a params array
+        *
+        * @param string $function
+        * @param array $params
+        */
+       protected function translateSrcParams( $function, array $params ) {
+               $latest = !empty( $params['latest'] );
+
+               if ( isset( $params['src'] ) ) {
+                       $params['src'] = $this->getBackendPath( $params['src'], $latest );
+               }
+
+               if ( isset( $params['srcs'] ) ) {
+                       $params['srcs'] = $this->getBackendPaths( $params['srcs'], $latest );
+               }
+
+               return $this->backend->$function( $params );
+       }
+
+       /**
+        * Translates paths when the backend function returns results keyed by paths
+        *
+        * @param string $function
+        * @param array $params
+        * @return array
+        */
+       protected function translateArrayResults( $function, array $params ) {
+               $origPaths = $params['srcs'];
+               $params['srcs'] = $this->getBackendPaths( $params['srcs'], !empty( $params['latest'] ) );
+               $pathMap = array_combine( $params['srcs'], $origPaths );
+
+               $results = $this->backend->$function( $params );
+
+               $contents = array();
+               foreach ( $results as $path => $result ) {
+                       $contents[$pathMap[$path]] = $result;
+               }
+
+               return $contents;
+       }
+
+       /**
+        * Translate legacy "title" source paths to their "sha1" counterparts
+        *
+        * This leaves destination paths alone since we don't want those to mutate
+        *
+        * @param array $ops
+        * @return array
+        */
+       protected function mungeOpPaths( array $ops ) {
+               // Ops that use 'src' and do not mutate core file data there
+               static $srcRefOps = array( 'store', 'copy', 'describe' );
+               foreach ( $ops as &$op ) {
+                       if ( isset( $op['src'] ) && in_array( $op['op'], $srcRefOps ) ) {
+                               $op['src'] = $this->getBackendPath( $op['src'], true );
+                       }
+                       if ( isset( $op['srcs'] ) ) {
+                               $op['srcs'] = $this->getBackendPaths( $op['srcs'], true );
+                       }
+               }
+               return $ops;
+       }
+}
index 82bbd76..7370c5c 100644 (file)
@@ -49,6 +49,9 @@ class FileRepo {
        /** @var int */
        public $descriptionCacheExpiry;
 
+       /** @var bool */
+       protected $hasSha1Storage = false;
+
        /** @var FileBackend */
        protected $backend;
 
@@ -1885,6 +1888,14 @@ class FileRepo {
 
                return $ret;
        }
+
+       /**
+        * Returns whether or not storage is SHA-1 based
+        * @return boolean
+        */
+       public function hasSha1Storage() {
+               return $this->hasSha1Storage;
+       }
 }
 
 /**
index 6e9e6ad..dfdb375 100644 (file)
@@ -76,17 +76,8 @@ class ForeignDBRepo extends LocalRepo {
         */
        function getMasterDB() {
                if ( !isset( $this->dbConn ) ) {
-                       $this->dbConn = DatabaseBase::factory( $this->dbType,
-                               array(
-                                       'host' => $this->dbServer,
-                                       'user' => $this->dbUser,
-                                       'password' => $this->dbPassword,
-                                       'dbname' => $this->dbName,
-                                       'flags' => $this->dbFlags,
-                                       'tablePrefix' => $this->tablePrefix,
-                                       'foreign' => true,
-                               )
-                       );
+                       $func = $this->getDBFactory();
+                       $this->dbConn = $func( DB_MASTER );
                }
 
                return $this->dbConn;
@@ -99,6 +90,25 @@ class ForeignDBRepo extends LocalRepo {
                return $this->getMasterDB();
        }
 
+       /**
+        * @return Closure
+        */
+       protected function getDBFactory() {
+               return function( $index ) {
+                       return DatabaseBase::factory( $this->dbType,
+                               array(
+                                       'host' => $this->dbServer,
+                                       'user' => $this->dbUser,
+                                       'password' => $this->dbPassword,
+                                       'dbname' => $this->dbName,
+                                       'flags' => $this->dbFlags,
+                                       'tablePrefix' => $this->tablePrefix,
+                                       'foreign' => true,
+                               )
+                       );
+               };
+       }
+
        /**
         * @return bool
         */
index 8153ffb..f49b716 100644 (file)
@@ -66,6 +66,16 @@ class ForeignDBViaLBRepo extends LocalRepo {
                return wfGetDB( DB_SLAVE, array(), $this->wiki );
        }
 
+       /**
+        * @return Closure
+        */
+       protected function getDBFactory() {
+               $wiki = $this->wiki;
+               return function( $index ) use ( $wiki ) {
+                       return wfGetDB( $index, array(), $wiki );
+               };
+       }
+
        function hasSharedCache() {
                return $this->hasSharedCache;
        }
index 800a230..1852912 100644 (file)
@@ -29,6 +29,9 @@
  * @ingroup FileRepo
  */
 class LocalRepo extends FileRepo {
+       /** @var bool */
+       protected $hasSha1Storage = false;
+
        /** @var array */
        protected $fileFactory = array( 'LocalFile', 'newFromTitle' );
 
@@ -47,6 +50,20 @@ class LocalRepo extends FileRepo {
        /** @var array */
        protected $oldFileFactoryKey = array( 'OldLocalFile', 'newFromKey' );
 
+       function __construct( array $info = null ) {
+               parent::__construct( $info );
+
+               $this->hasSha1Storage = isset( $info['storageLayout'] ) && $info['storageLayout'] === 'sha1';
+
+               if ( $this->hasSha1Storage() ) {
+                       $this->backend = new FileBackendDBRepoWrapper( array(
+                               'backend'         => $this->backend,
+                               'repoName'        => $this->name,
+                               'dbHandleFactory' => $this->getDBFactory()
+                       ) );
+               }
+       }
+
        /**
         * @throws MWException
         * @param stdClass $row
@@ -82,6 +99,11 @@ class LocalRepo extends FileRepo {
         * @return FileRepoStatus
         */
        function cleanupDeletedBatch( array $storageKeys ) {
+               if ( $this->hasSha1Storage() ) {
+                       wfDebug( __METHOD__ . ": skipped because storage uses sha1 paths\n" );
+                       return Status::newGood();
+               }
+
                $backend = $this->backend; // convenience
                $root = $this->getZonePath( 'deleted' );
                $dbw = $this->getMasterDB();
@@ -469,6 +491,16 @@ class LocalRepo extends FileRepo {
                return wfGetDB( DB_MASTER );
        }
 
+       /**
+        * Get a callback to get a DB handle given an index (DB_SLAVE/DB_MASTER)
+        * @return Closure
+        */
+       protected function getDBFactory() {
+               return function( $index ) {
+                       return wfGetDB( $index );
+               };
+       }
+
        /**
         * Get a key on the primary cache for this repository.
         * Returns false if the repository's cache is not accessible at this site.
@@ -514,4 +546,56 @@ class LocalRepo extends FileRepo {
                        'favicon' => wfExpandUrl( $wgFavicon ),
                ) );
        }
+
+       public function store( $srcPath, $dstZone, $dstRel, $flags = 0 ) {
+               return $this->skipWriteOperationIfSha1( __FUNCTION__, func_get_args() );
+       }
+
+       public function storeBatch( array $triplets, $flags = 0 ) {
+               return $this->skipWriteOperationIfSha1( __FUNCTION__, func_get_args() );
+       }
+
+       public function cleanupBatch( array $files, $flags = 0 ) {
+               return $this->skipWriteOperationIfSha1( __FUNCTION__, func_get_args() );
+       }
+
+       public function publish(
+               $srcPath,
+               $dstRel,
+               $archiveRel,
+               $flags = 0,
+               array $options = array()
+       ) {
+               return $this->skipWriteOperationIfSha1( __FUNCTION__, func_get_args() );
+       }
+
+       public function publishBatch( array $ntuples, $flags = 0 ) {
+               return $this->skipWriteOperationIfSha1( __FUNCTION__, func_get_args() );
+       }
+
+       public function delete( $srcRel, $archiveRel ) {
+               return $this->skipWriteOperationIfSha1( __FUNCTION__, func_get_args() );
+       }
+
+       public function deleteBatch( array $sourceDestPairs ) {
+               return $this->skipWriteOperationIfSha1( __FUNCTION__, func_get_args() );
+       }
+
+       /**
+        * Skips the write operation if storage is sha1-based, executes it normally otherwise
+        *
+        * @param string $function
+        * @param array $args
+        * @return FileRepoStatus
+        */
+       protected function skipWriteOperationIfSha1( $function, array $args ) {
+               $this->assertWritableRepo(); // fail out if read-only
+
+               if ( $this->hasSha1Storage() ) {
+                       wfDebug( __METHOD__ . ": skipped because storage uses sha1 paths\n" );
+                       return Status::newGood();
+               } else {
+                       return call_user_func_array('parent::' . $function, $args );
+               }
+       }
 }
index f9e1128..72b3ae9 100644 (file)
@@ -1149,6 +1149,8 @@ abstract class File implements IDBAccessObject {
                        Hooks::run( 'FileTransformed', array( $this, $thumb, $tmpThumbPath, $thumbPath ) );
                }
 
+               wfDebugLog( 'thumbnailaccess', time() . ' ' . $thumbPath . ' ' . filesize( $tmpThumbPath ) . ' Generated ' );
+
                return $thumb;
        }
 
index 6abe00c..4070553 100644 (file)
@@ -1459,7 +1459,7 @@ class LocalFile extends File {
         * The archive name should be passed through to recordUpload for database
         * registration.
         *
-        * @param string $srcPath Local filesystem path to the source image
+        * @param string $srcPath Local filesystem path or virtual URL to the source image
         * @param int $flags A bitwise combination of:
         *     File::DELETE_SOURCE    Delete the source file, i.e. move rather than copy
         * @param array $options Optional additional parameters
@@ -1477,7 +1477,7 @@ class LocalFile extends File {
         * The archive name should be passed through to recordUpload for database
         * registration.
         *
-        * @param string $srcPath Local filesystem path to the source image
+        * @param string $srcPath Local filesystem path or virtual URL to the source image
         * @param string $dstRel Target relative path
         * @param int $flags A bitwise combination of:
         *     File::DELETE_SOURCE    Delete the source file, i.e. move rather than copy
@@ -1486,7 +1486,8 @@ class LocalFile extends File {
         *     archive name, or an empty string if it was a new file.
         */
        function publishTo( $srcPath, $dstRel, $flags = 0, array $options = array() ) {
-               if ( $this->getRepo()->getReadOnlyReason() !== false ) {
+               $repo = $this->getRepo();
+               if ( $repo->getReadOnlyReason() !== false ) {
                        return $this->readOnlyFatalStatus();
                }
 
@@ -1494,13 +1495,29 @@ class LocalFile extends File {
 
                $archiveName = wfTimestamp( TS_MW ) . '!' . $this->getName();
                $archiveRel = 'archive/' . $this->getHashPath() . $archiveName;
-               $flags = $flags & File::DELETE_SOURCE ? LocalRepo::DELETE_SOURCE : 0;
-               $status = $this->repo->publish( $srcPath, $dstRel, $archiveRel, $flags, $options );
 
-               if ( $status->value == 'new' ) {
-                       $status->value = '';
+               if ( $repo->hasSha1Storage() ) {
+                       $sha1 = $repo->isVirtualUrl( $srcPath )
+                               ? $repo->getFileSha1( $srcPath )
+                               : File::sha1Base36( $srcPath );
+                       $dst = $repo->getBackend()->getPathForSHA1( $sha1 );
+                       $status = $repo->quickImport( $srcPath, $dst );
+                       if ( $flags & File::DELETE_SOURCE ) {
+                               unlink( $srcPath );
+                       }
+
+                       if ( $this->exists() ) {
+                               $status->value = $archiveName;
+                       }
                } else {
-                       $status->value = $archiveName;
+                       $flags = $flags & File::DELETE_SOURCE ? LocalRepo::DELETE_SOURCE : 0;
+                       $status = $repo->publish( $srcPath, $dstRel, $archiveRel, $flags, $options );
+
+                       if ( $status->value == 'new' ) {
+                               $status->value = '';
+                       } else {
+                               $status->value = $archiveName;
+                       }
                }
 
                $this->unlock(); // done
@@ -1941,14 +1958,14 @@ class LocalFileDeleteBatch {
                $this->status = $file->repo->newGood();
        }
 
-       function addCurrent() {
+       public function addCurrent() {
                $this->srcRels['.'] = $this->file->getRel();
        }
 
        /**
         * @param string $oldName
         */
-       function addOld( $oldName ) {
+       public function addOld( $oldName ) {
                $this->srcRels[$oldName] = $this->file->getArchiveRel( $oldName );
                $this->archiveUrls[] = $this->file->getArchiveUrl( $oldName );
        }
@@ -1957,7 +1974,7 @@ class LocalFileDeleteBatch {
         * Add the old versions of the image to the batch
         * @return array List of archive names from old versions
         */
-       function addOlds() {
+       public function addOlds() {
                $archiveNames = array();
 
                $dbw = $this->file->repo->getMasterDB();
@@ -1978,7 +1995,7 @@ class LocalFileDeleteBatch {
        /**
         * @return array
         */
-       function getOldRels() {
+       protected function getOldRels() {
                if ( !isset( $this->srcRels['.'] ) ) {
                        $oldRels =& $this->srcRels;
                        $deleteCurrent = false;
@@ -2050,7 +2067,7 @@ class LocalFileDeleteBatch {
                return $hashes;
        }
 
-       function doDBInserts() {
+       protected function doDBInserts() {
                $dbw = $this->file->repo->getMasterDB();
                $encTimestamp = $dbw->addQuotes( $dbw->timestamp() );
                $encUserId = $dbw->addQuotes( $this->user->getId() );
@@ -2165,8 +2182,8 @@ class LocalFileDeleteBatch {
         * Run the transaction
         * @return FileRepoStatus
         */
-       function execute() {
-
+       public function execute() {
+               $repo = $this->file->getRepo();
                $this->file->lock();
 
                // Prepare deletion batch
@@ -2180,7 +2197,7 @@ class LocalFileDeleteBatch {
                        if ( isset( $hashes[$name] ) ) {
                                $hash = $hashes[$name];
                                $key = $hash . $dotExt;
-                               $dstRel = $this->file->repo->getDeletedHashPath( $key ) . $key;
+                               $dstRel = $repo->getDeletedHashPath( $key ) . $key;
                                $this->deletionBatch[$name] = array( $srcRel, $dstRel );
                        }
                }
@@ -2193,20 +2210,22 @@ class LocalFileDeleteBatch {
                // them in a separate transaction, then run the file ops, then update the fa_name fields.
                $this->doDBInserts();
 
-               // Removes non-existent file from the batch, so we don't get errors.
-               // This also handles files in the 'deleted' zone deleted via revision deletion.
-               $checkStatus = $this->removeNonexistentFiles( $this->deletionBatch );
-               if ( !$checkStatus->isGood() ) {
-                       $this->status->merge( $checkStatus );
-                       return $this->status;
-               }
-               $this->deletionBatch = $checkStatus->value;
+               if ( !$repo->hasSha1Storage() ) {
+                       // Removes non-existent file from the batch, so we don't get errors.
+                       // This also handles files in the 'deleted' zone deleted via revision deletion.
+                       $checkStatus = $this->removeNonexistentFiles( $this->deletionBatch );
+                       if ( !$checkStatus->isGood() ) {
+                               $this->status->merge( $checkStatus );
+                               return $this->status;
+                       }
+                       $this->deletionBatch = $checkStatus->value;
 
-               // Execute the file deletion batch
-               $status = $this->file->repo->deleteBatch( $this->deletionBatch );
+                       // Execute the file deletion batch
+                       $status = $this->file->repo->deleteBatch( $this->deletionBatch );
 
-               if ( !$status->isGood() ) {
-                       $this->status->merge( $status );
+                       if ( !$status->isGood() ) {
+                               $this->status->merge( $status );
+                       }
                }
 
                if ( !$this->status->isOK() ) {
@@ -2232,7 +2251,7 @@ class LocalFileDeleteBatch {
         * @param array $batch
         * @return Status
         */
-       function removeNonexistentFiles( $batch ) {
+       protected function removeNonexistentFiles( $batch ) {
                $files = $newBatch = array();
 
                foreach ( $batch as $batchItem ) {
@@ -2293,7 +2312,7 @@ class LocalFileRestoreBatch {
         * Add a file by ID
         * @param int $fa_id
         */
-       function addId( $fa_id ) {
+       public function addId( $fa_id ) {
                $this->ids[] = $fa_id;
        }
 
@@ -2301,14 +2320,14 @@ class LocalFileRestoreBatch {
         * Add a whole lot of files by ID
         * @param int[] $ids
         */
-       function addIds( $ids ) {
+       public function addIds( $ids ) {
                $this->ids = array_merge( $this->ids, $ids );
        }
 
        /**
         * Add all revisions of the file
         */
-       function addAll() {
+       public function addAll() {
                $this->all = true;
        }
 
@@ -2320,12 +2339,13 @@ class LocalFileRestoreBatch {
         * So we save the batch and let the caller call cleanup()
         * @return FileRepoStatus
         */
-       function execute() {
+       public function execute() {
                global $wgLang;
 
+               $repo = $this->file->getRepo();
                if ( !$this->all && !$this->ids ) {
                        // Do nothing
-                       return $this->file->repo->newGood();
+                       return $repo->newGood();
                }
 
                $lockOwnsTrx = $this->file->lock();
@@ -2382,9 +2402,9 @@ class LocalFileRestoreBatch {
                                continue;
                        }
 
-                       $deletedRel = $this->file->repo->getDeletedHashPath( $row->fa_storage_key ) .
+                       $deletedRel = $repo->getDeletedHashPath( $row->fa_storage_key ) .
                                $row->fa_storage_key;
-                       $deletedUrl = $this->file->repo->getVirtualUrl() . '/deleted/' . $deletedRel;
+                       $deletedUrl = $repo->getVirtualUrl() . '/deleted/' . $deletedRel;
 
                        if ( isset( $row->fa_sha1 ) ) {
                                $sha1 = $row->fa_sha1;
@@ -2498,27 +2518,29 @@ class LocalFileRestoreBatch {
                        $status->error( 'undelete-missing-filearchive', $id );
                }
 
-               // Remove missing files from batch, so we don't get errors when undeleting them
-               $checkStatus = $this->removeNonexistentFiles( $storeBatch );
-               if ( !$checkStatus->isGood() ) {
-                       $status->merge( $checkStatus );
-                       return $status;
-               }
-               $storeBatch = $checkStatus->value;
+               if ( !$repo->hasSha1Storage() ) {
+                       // Remove missing files from batch, so we don't get errors when undeleting them
+                       $checkStatus = $this->removeNonexistentFiles( $storeBatch );
+                       if ( !$checkStatus->isGood() ) {
+                               $status->merge( $checkStatus );
+                               return $status;
+                       }
+                       $storeBatch = $checkStatus->value;
 
-               // Run the store batch
-               // Use the OVERWRITE_SAME flag to smooth over a common error
-               $storeStatus = $this->file->repo->storeBatch( $storeBatch, FileRepo::OVERWRITE_SAME );
-               $status->merge( $storeStatus );
+                       // Run the store batch
+                       // Use the OVERWRITE_SAME flag to smooth over a common error
+                       $storeStatus = $this->file->repo->storeBatch( $storeBatch, FileRepo::OVERWRITE_SAME );
+                       $status->merge( $storeStatus );
 
-               if ( !$status->isGood() ) {
-                       // Even if some files could be copied, fail entirely as that is the
-                       // easiest thing to do without data loss
-                       $this->cleanupFailedBatch( $storeStatus, $storeBatch );
-                       $status->ok = false;
-                       $this->file->unlock();
+                       if ( !$status->isGood() ) {
+                               // Even if some files could be copied, fail entirely as that is the
+                               // easiest thing to do without data loss
+                               $this->cleanupFailedBatch( $storeStatus, $storeBatch );
+                               $status->ok = false;
+                               $this->file->unlock();
 
-                       return $status;
+                               return $status;
+                       }
                }
 
                // Run the DB updates
@@ -2542,7 +2564,7 @@ class LocalFileRestoreBatch {
                }
 
                // If store batch is empty (all files are missing), deletion is to be considered successful
-               if ( $status->successCount > 0 || !$storeBatch ) {
+               if ( $status->successCount > 0 || !$storeBatch || $repo->hasSha1Storage() ) {
                        if ( !$exists ) {
                                wfDebug( __METHOD__ . " restored {$status->successCount} items, creating a new current\n" );
 
@@ -2565,7 +2587,7 @@ class LocalFileRestoreBatch {
         * @param array $triplets
         * @return Status
         */
-       function removeNonexistentFiles( $triplets ) {
+       protected function removeNonexistentFiles( $triplets ) {
                $files = $filteredTriplets = array();
                foreach ( $triplets as $file ) {
                        $files[$file[0]] = $file[0];
@@ -2591,7 +2613,7 @@ class LocalFileRestoreBatch {
         * @param array $batch
         * @return array
         */
-       function removeNonexistentFromCleanup( $batch ) {
+       protected function removeNonexistentFromCleanup( $batch ) {
                $files = $newBatch = array();
                $repo = $this->file->repo;
 
@@ -2616,7 +2638,7 @@ class LocalFileRestoreBatch {
         * This should be called from outside the transaction in which execute() was called.
         * @return FileRepoStatus
         */
-       function cleanup() {
+       public function cleanup() {
                if ( !$this->cleanupBatch ) {
                        return $this->file->repo->newGood();
                }
@@ -2635,7 +2657,7 @@ class LocalFileRestoreBatch {
         * @param Status $storeStatus
         * @param array $storeBatch
         */
-       function cleanupFailedBatch( $storeStatus, $storeBatch ) {
+       protected function cleanupFailedBatch( $storeStatus, $storeBatch ) {
                $cleanupBatch = array();
 
                foreach ( $storeStatus->success as $i => $success ) {
@@ -2693,7 +2715,7 @@ class LocalFileMoveBatch {
        /**
         * Add the current image to the batch
         */
-       function addCurrent() {
+       public function addCurrent() {
                $this->cur = array( $this->oldRel, $this->newRel );
        }
 
@@ -2701,7 +2723,7 @@ class LocalFileMoveBatch {
         * Add the old versions of the image to the batch
         * @return array List of archive names from old versions
         */
-       function addOlds() {
+       public function addOlds() {
                $archiveBase = 'archive';
                $this->olds = array();
                $this->oldCount = 0;
@@ -2751,7 +2773,7 @@ class LocalFileMoveBatch {
         * Perform the move.
         * @return FileRepoStatus
         */
-       function execute() {
+       public function execute() {
                $repo = $this->file->repo;
                $status = $repo->newGood();
 
@@ -2782,22 +2804,26 @@ class LocalFileMoveBatch {
                wfDebugLog( 'imagemove', "Renamed {$this->file->getName()} in database: " .
                        "{$statusDb->successCount} successes, {$statusDb->failCount} failures" );
 
-               // Copy the files into their new location.
-               // If a prior process fataled copying or cleaning up files we tolerate any
-               // of the existing files if they are identical to the ones being stored.
-               $statusMove = $repo->storeBatch( $triplets, FileRepo::OVERWRITE_SAME );
-               wfDebugLog( 'imagemove', "Moved files for {$this->file->getName()}: " .
-                       "{$statusMove->successCount} successes, {$statusMove->failCount} failures" );
-               if ( !$statusMove->isGood() ) {
-                       // Delete any files copied over (while the destination is still locked)
-                       $this->cleanupTarget( $triplets );
-                       $destFile->unlock();
-                       $this->file->unlockAndRollback(); // unlocks the destination
-                       wfDebugLog( 'imagemove', "Error in moving files: " . $statusMove->getWikiText() );
-                       $statusMove->ok = false;
-
-                       return $statusMove;
+               if ( !$repo->hasSha1Storage() ) {
+                       // Copy the files into their new location.
+                       // If a prior process fataled copying or cleaning up files we tolerate any
+                       // of the existing files if they are identical to the ones being stored.
+                       $statusMove = $repo->storeBatch( $triplets, FileRepo::OVERWRITE_SAME );
+                       wfDebugLog( 'imagemove', "Moved files for {$this->file->getName()}: " .
+                               "{$statusMove->successCount} successes, {$statusMove->failCount} failures" );
+                       if ( !$statusMove->isGood() ) {
+                               // Delete any files copied over (while the destination is still locked)
+                               $this->cleanupTarget( $triplets );
+                               $destFile->unlock();
+                               $this->file->unlockAndRollback(); // unlocks the destination
+                               wfDebugLog( 'imagemove', "Error in moving files: " . $statusMove->getWikiText() );
+                               $statusMove->ok = false;
+
+                               return $statusMove;
+                       }
+                       $status->merge( $statusMove );
                }
+
                $destFile->unlock();
                $this->file->unlock(); // done
 
@@ -2805,7 +2831,6 @@ class LocalFileMoveBatch {
                $this->cleanupSource( $triplets );
 
                $status->merge( $statusDb );
-               $status->merge( $statusMove );
 
                return $status;
        }
@@ -2816,7 +2841,7 @@ class LocalFileMoveBatch {
         *
         * @return FileRepoStatus
         */
-       function doDBUpdates() {
+       protected function doDBUpdates() {
                $repo = $this->file->repo;
                $status = $repo->newGood();
                $dbw = $this->db;
@@ -2868,7 +2893,7 @@ class LocalFileMoveBatch {
         * Generate triplets for FileRepo::storeBatch().
         * @return array
         */
-       function getMoveTriplets() {
+       protected function getMoveTriplets() {
                $moves = array_merge( array( $this->cur ), $this->olds );
                $triplets = array(); // The format is: (srcUrl, destZone, destUrl)
 
@@ -2890,7 +2915,7 @@ class LocalFileMoveBatch {
         * @param array $triplets
         * @return Status
         */
-       function removeNonexistentFiles( $triplets ) {
+       protected function removeNonexistentFiles( $triplets ) {
                $files = array();
 
                foreach ( $triplets as $file ) {
@@ -2920,7 +2945,7 @@ class LocalFileMoveBatch {
         * files. Called if something went wrong half way.
         * @param array $triplets
         */
-       function cleanupTarget( $triplets ) {
+       protected function cleanupTarget( $triplets ) {
                // Create dest pairs from the triplets
                $pairs = array();
                foreach ( $triplets as $triplet ) {
@@ -2936,7 +2961,7 @@ class LocalFileMoveBatch {
         * Called at the end of the move process if everything else went ok.
         * @param array $triplets
         */
-       function cleanupSource( $triplets ) {
+       protected function cleanupSource( $triplets ) {
                // Create source file names from the triplets
                $files = array();
                foreach ( $triplets as $triplet ) {
index 8d7aec3..b0b08a6 100644 (file)
@@ -44,7 +44,7 @@ class HTMLButtonField extends HTMLFormField {
        /**
         * Get the OOUI widget for this field.
         * @param string $value
-        * @return OOUI\ButtonInputWidget
+        * @return OOUI\\ButtonInputWidget
         */
        public function getInputOOUI( $value ) {
                return new OOUI\ButtonInputWidget( array(
index 55312ff..9666c4e 100644 (file)
@@ -45,7 +45,7 @@ class HTMLCheckField extends HTMLFormField {
         * Get the OOUI version of this field.
         * @since 1.26
         * @param string $value
-        * @return OOUI\CheckboxInputWidget The checkbox widget.
+        * @return OOUI\\CheckboxInputWidget The checkbox widget.
         */
        public function getInputOOUI( $value ) {
                if ( !empty( $this->mParams['invert'] ) ) {
index 21526c7..b26b45d 100644 (file)
@@ -49,7 +49,7 @@ abstract class HTMLFormField {
         * Defaults to false, which getOOUI will interpret as "use the HTML version"
         *
         * @param string $value
-        * @return OOUI\Widget|false
+        * @return OOUI\\Widget|false
         */
        function getInputOOUI( $value ) {
                return false;
index 6ac5436..4410271 100644 (file)
@@ -407,6 +407,8 @@ class PostgresUpdater extends DatabaseUpdater {
                        array( 'addPgField', 'mwuser', 'user_password_expires', 'TIMESTAMPTZ NULL' ),
                        array( 'changeFieldPurgeTable', 'l10n_cache', 'lc_value', 'bytea',
                                "replace(lc_value,'\','\\\\')::bytea" ),
+                       // 1.23.9
+                       array( 'rebuildTextSearch'),
 
                        // 1.24
                        array( 'addPgField', 'page_props', 'pp_sortkey', 'float NULL' ),
@@ -947,4 +949,12 @@ END;
                        $this->applyPatch( 'patch-tsearch2funcs.sql', false, "Rewriting tsearch2 triggers" );
                }
        }
+
+       protected function rebuildTextSearch() {
+               if ( $this->updateRowExists( 'patch-textsearch_bug66650.sql' ) ) {
+                       $this->output( "...bug 66650 already fixed or not applicable.\n" );
+                       return true;
+               };
+               $this->applyPatch( 'patch-textsearch_bug66650.sql', false, "Rebuilding text search for bug 66650" );
+       }
 }
index 077c503..0709665 100644 (file)
@@ -31,7 +31,6 @@
        "config-no-fts3": "'''Тергам бе''': SQLite гулйина хуттург йоцуш [//sqlite.org/fts3.html FTS3] — лахар болхбеш хир дац оцу бухца.",
        "config-no-cli-uri": "'''ДӀахьедар''': <code>--scriptpath</code> параметр язйина яц, иза Ӏад йитарца лелош ю: <code>$1</code> .",
        "config-db-name": "Хаамийн базан цӀе:",
-       "config-db-username-empty": "Ахьа «{{int:config-db-username}}» параметран маьӀна даздан дезаш ду.",
        "config-db-charset": "Базан хаамийн символийн гулам",
        "config-charset-mysql5-binary": "MySQL 4.1/5.0 бинаран",
        "config-charset-mysql5": "MySQL 4.1/5.0 UTF-8",
@@ -54,7 +53,7 @@
        "config-profile-no-anon": "ДӀаяздар кхолла деза",
        "config-profile-fishbowl": "ДӀаяздарш долу тадархошна бен",
        "config-profile-private": "ДӀачӀаьгӀна вики",
-       "config-license": "Авторан бакъонаш а лицензи а:",
+       "config-license": "Авторан бакъонаш а, лицензи а:",
        "config-license-cc-by-sa": "Creative Commons Attribution Share Alike",
        "config-license-cc-by": "Creative Commons Attribution",
        "config-license-cc-by-nc-sa": "Creative Commons Attribution Non-Commercial Share Alike",
index 7617942..a1f9154 100644 (file)
@@ -1,5 +1,38 @@
 {
-       "@metadata": [],
+       "@metadata": {
+               "authors": [
+                       "Vahe Gharakhanyan"
+               ]
+       },
+       "config-title": "ՄեդիաՎիքի $1-ի տեղադրում",
+       "config-information": "Տեղեկատվություն",
+       "config-localsettings-key": "Թարմացման բանալի`",
+       "config-your-language": "Ձեր լեզուն`",
+       "config-wiki-language": "Վիքի լեզու`",
+       "config-back": "← Վերադառնալ",
+       "config-continue": "Շարունակել →",
+       "config-page-language": "Լեզու",
+       "config-page-welcome": "Բարի գալուստ ՄեդիաՎիքի:",
+       "config-page-dbconnect": "Միացում տվյալների բազային",
+       "config-page-name": "Անվանում",
+       "config-page-options": "Ընտրանքներ",
+       "config-page-install": "Տեղադրում",
+       "config-page-complete": "Պատրաստ է:",
+       "config-page-readme": "Կարդա ինձ",
+       "config-page-releasenotes": "Տեղեկություն տարբերակի մասին",
+       "config-page-existingwiki": "Գոյություն ունեցող վիքի",
+       "config-restart": "Այո, նորից սկսել",
+       "config-admin-password": "Գաղտնաբառ՝",
+       "config-admin-password-confirm": "Գաղտնաբառը կրկին`",
+       "config-admin-email": "Էլ-փոստի հասցեն՝",
+       "config-license": "Հեղինակային իրավունք և արտոնագիր`",
+       "config-license-cc-by-sa": "Creative Commons Attribution-ShareAlike",
+       "config-license-cc-by": "Creative Commons Attribution",
+       "config-license-cc-by-nc-sa": "Creative Commons Attribution-NonCommercial-ShareAlike",
+       "config-license-cc-0": "Creative Commons Zero (հանրային սեփականություն)",
+       "config-license-gfdl": "GNU Free Documentation License 1.3 կամ ավելի ուշ",
+       "config-license-pd": "Հանրային սեփականություն",
+       "config-help": "օգնություն",
        "mainpagetext": "'''«MediaWiki» ծրագիրը հաջողությամբ տեղադրվեց։'''",
        "mainpagedocfooter": "Այցելեք [//meta.wikimedia.org/wiki/Help:Contents User's Guide]՝ վիքի ծրագրային ապահովման օգտագործման մասին տեղեկությունների համար։\n\n== Որոշ օգտակար ռեսուրսներ ==\n\n* [//www.mediawiki.org/wiki/Special:MyLanguage/Manual:Configuration_settings Configuration settings list]\n* [//www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ MediaWiki FAQ]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki release mailing list]"
 }
index 3547308..cbe64d6 100644 (file)
                        "Seb35",
                        "Nemo bis",
                        "Ricordisamoa",
-                       "Fpugliajno"
+                       "Fpugliajno",
+                       "The Polish"
                ]
        },
        "config-desc": "Il programma di installazione per MediaWiki",
-       "config-title": "Installazione MediaWiki $1",
+       "config-title": "Installazione di MediaWiki $1",
        "config-information": "Informazioni",
        "config-localsettings-upgrade": "È stato rilevato un file <code>LocalSettings.php</code>.\nPer aggiornare questa installazione, si prega di inserire il valore di <code>$wgUpgradeKey</code> nella casella qui sotto.\nLo potete trovare in <code>LocalSettings.php</code>.",
        "config-localsettings-cli-upgrade": "È stato rilevato un file <code>LocalSettings.php</code>.\nPer aggiornare questa installazione, eseguire <code>update.php</code>",
index e7d2388..6615026 100644 (file)
        "config-db-install-account": "Konto użytkownika dla instalatora",
        "config-db-username": "Nazwa użytkownika bazy danych:",
        "config-db-password": "Hasło bazy danych:",
-       "config-db-password-empty": "Wprowadź hasło dla nowego użytkownika bazy danych: $1.\nChoć istnieje możliwość tworzenia użytkowników bez hasła, nie jest to bezpieczne.",
-       "config-db-username-empty": "Należy podać wartość parametru \"{{int:config-db-username}}\".",
        "config-db-install-username": "Wprowadź nazwę użytkownika, który będzie używany do łączenia się z bazą danych podczas procesu instalacji.\nNie jest to nazwa konta MediaWiki, a użytkownika bazy danych.",
        "config-db-install-password": "Wprowadź hasło, które będzie wykorzystywane do łączenia się z bazą danych w procesie instalacji.\nTo nie jest hasło konta MediaWiki, lecz hasło do bazy danych.",
        "config-db-install-help": "Podaj nazwę użytkownika i jego hasło, które zostaną użyte do połączenia z bazą danych w czasie procesu instalacji.",
index 68e96fc..beeb067 100644 (file)
@@ -38,7 +38,7 @@ class EmaillingJob extends Job {
                        $this->params['from'],
                        $this->params['subj'],
                        $this->params['body'],
-                       $this->params['replyto']
+                       array( 'replyTo' => $this->params['replyto'] )
                );
 
                return $status->isOK();
index 192b119..3d7fad5 100644 (file)
@@ -42,7 +42,7 @@ class BufferingStatsdDataFactory extends StatsdDataFactory {
        /**
         * Normalize a metric key for StatsD
         *
-        * Replace occurences of '::' with dots and any other non-alphabetic
+        * Replace occurences of '::' with dots and any other non-alphanumeric
         * characters with underscores. Combine runs of dots or underscores.
         * Then trim leading or trailing dots or underscores.
         *
@@ -51,7 +51,7 @@ class BufferingStatsdDataFactory extends StatsdDataFactory {
         */
        private static function normalizeMetricKey( $key ) {
                $key = preg_replace( '/[:.]+/', '.', $key );
-               $key = preg_replace( '/[^a-z.]+/i', '_', $key );
+               $key = preg_replace( '/[^a-z0-9.]+/i', '_', $key );
                $key = trim( $key, '_.' );
                return str_replace( array( '._', '_.' ), '.', $key );
        }
index 1027732..0eed450 100644 (file)
@@ -478,7 +478,9 @@ class EmailNotification {
                                $wgContLang->userTime( $this->timestamp, $watchingUser ) ),
                        $this->body );
 
-               return UserMailer::send( $to, $this->from, $this->subject, $body, $this->replyto );
+               return UserMailer::send( $to, $this->from, $this->subject, $body, array(
+                       'replyTo' => $this->replyto,
+               ) );
        }
 
        /**
@@ -503,7 +505,9 @@ class EmailNotification {
                                $wgContLang->time( $this->timestamp, false, false ) ),
                        $this->body );
 
-               return UserMailer::send( $addresses, $this->from, $this->subject, $body, $this->replyto );
+               return UserMailer::send( $addresses, $this->from, $this->subject, $body, array(
+                       'replyTo' => $this->replyto,
+               ) );
        }
 
 }
index 546cc8c..d83ae93 100644 (file)
@@ -102,16 +102,32 @@ class UserMailer {
         * @param MailAddress $from Sender's email
         * @param string $subject Email's subject.
         * @param string $body Email's text or Array of two strings to be the text and html bodies
-        * @param MailAddress $replyto Optional reply-to email (default: null).
-        * @param string $contentType Optional custom Content-Type (default: text/plain; charset=UTF-8)
+        * @param array $options:
+        *              'replyTo' MailAddress
+        *              'contentType' string default 'text/plain; charset=UTF-8'
+        *
+        * Previous versions of this function had $replyto as the 5th argument and $contentType
+        * as the 6th. These are still supported for backwards compatability, but deprecated.
+        *
         * @throws MWException
         * @throws Exception
         * @return Status
         */
-       public static function send( $to, $from, $subject, $body, $replyto = null,
-               $contentType = 'text/plain; charset=UTF-8'
-       ) {
+       public static function send( $to, $from, $subject, $body, $options = array() ) {
                global $wgSMTP, $wgEnotifMaxRecips, $wgAdditionalMailParams, $wgAllowHTMLEmail;
+               $contentType = 'text/plain; charset=UTF-8';
+               if ( is_array( $options ) ) {
+                       $replyto = isset( $options['replyTo'] ) ? $options['replyTo'] : null;
+                       $contentType = isset( $options['contentType'] ) ? $options['contentType'] : $contentType;
+               } else {
+                       // Old calling style
+                       wfDeprecated( __METHOD__ . ' with $replyto as 5th parameter', '1.26' );
+                       $replyto = $options;
+                       if ( func_num_args() === 6 ) {
+                               $contentType = func_get_arg( 5 );
+                       }
+               }
+
                $mime = null;
                if ( !is_array( $to ) ) {
                        $to = array( $to );
index a4d94f8..0023de2 100644 (file)
@@ -149,7 +149,7 @@ class ResourceLoaderWikiModule extends ResourceLoaderModule {
         */
        protected function getContent( $titleText ) {
                $title = Title::newFromText( $titleText );
-               if ( !$title || $title->isRedirect() ) {
+               if ( !$title ) {
                        return null;
                }
 
index bda10b0..71e3b63 100644 (file)
@@ -186,7 +186,7 @@ class SearchPostgres extends SearchDatabase {
        function update( $pageid, $title, $text ) {
                ## We don't want to index older revisions
                $sql = "UPDATE pagecontent SET textvector = NULL WHERE textvector IS NOT NULL and old_id IN " .
-                               "(SELECT rev_text_id FROM revision WHERE rev_page = " . intval( $pageid ) .
+                               "(SELECT DISTINCT rev_text_id FROM revision WHERE rev_page = " . intval( $pageid ) .
                                " ORDER BY rev_text_id DESC OFFSET 1)";
                $this->db->query( $sql );
                return true;
index c55fa94..1754471 100644 (file)
@@ -356,7 +356,9 @@ class SpecialEmailUser extends UnlistedSpecialPage {
                        $replyTo = null;
                }
 
-               $status = UserMailer::send( $to, $mailFrom, $subject, $text, $replyTo );
+               $status = UserMailer::send( $to, $mailFrom, $subject, $text, array(
+                       'replyTo' => $replyTo,
+               ) );
 
                if ( !$status->isGood() ) {
                        return $status;
index 426c752..493df2e 100644 (file)
@@ -1935,7 +1935,7 @@ abstract class UploadBase {
        public static function getSessionStatus( User $user, $statusKey ) {
                $key = wfMemcKey( 'uploadstatus', $user->getId() ?: md5( $user->getName() ), $statusKey );
 
-               return wfGetCache( CACHE_ANYTHING )->get( $key );
+               return ObjectCache::getMainStashInstance()->get( $key );
        }
 
        /**
@@ -1951,7 +1951,7 @@ abstract class UploadBase {
        public static function setSessionStatus( User $user, $statusKey, $value ) {
                $key = wfMemcKey( 'uploadstatus', $user->getId() ?: md5( $user->getName() ), $statusKey );
 
-               $cache = wfGetCache( CACHE_ANYTHING );
+               $cache = ObjectCache::getMainStashInstance();
                if ( $value === false ) {
                        $cache->delete( $key );
                } else {
index 69427c5..2d69ed7 100644 (file)
@@ -40,7 +40,6 @@ class NamespaceInputWidget extends \OOUI\Widget {
         */
        public function __construct( array $config = array() ) {
                // Configuration initialization
-
                $config = array_merge(
                        array(
                                'nameNamespace' => 'namespace',
index 37c9d9c..d3e2851 100644 (file)
@@ -7,12 +7,10 @@
  */
 namespace MediaWiki\Widget;
 
-use OOUI\TextInputWidget;
-
 /**
  * Title input widget.
  */
-class TitleInputWidget extends TextInputWidget {
+class TitleInputWidget extends \OOUI\TextInputWidget {
 
        protected $namespace = null;
        protected $relative = null;
index 4147fca..e5663c3 100644 (file)
@@ -1,18 +1,17 @@
 <?php
 /**
- * MediaWiki Widgets \96 UserInputWidget class.
+ * MediaWiki Widgets  UserInputWidget class.
  *
  * @copyright 2011-2015 MediaWiki Widgets Team and others; see AUTHORS.txt
  * @license The MIT License (MIT); see LICENSE.txt
  */
 namespace MediaWiki\Widget;
 
-use OOUI\TextInputWidget;
-
 /**
  * User input widget.
  */
-class UserInputWidget extends TextInputWidget {
+class UserInputWidget extends \OOUI\TextInputWidget {
+
        /**
         * @param array $config Configuration options
         */
index ad2ae19..aa9f7ac 100644 (file)
@@ -51,7 +51,8 @@
                        "Khaled",
                        "Emara",
                        "Macofe",
-                       "Yahya Sakhnini"
+                       "Yahya Sakhnini",
+                       "Mervat Salman"
                ]
        },
        "tog-underline": "سطر تحت الوصلات:",
        "htmlform-cloner-create": "إضافة المزيد",
        "htmlform-cloner-delete": "إزالة",
        "htmlform-cloner-required": "مطلوب قيمة واحدة على الأقل.",
+       "htmlform-user-not-exists": "<strong>$1</strong> غير موجود",
+       "htmlform-user-not-valid": "اسم المستخدم <strong>$1</strong> غير صالح.",
        "sqlite-has-fts": "$1 بدعم البحث في كامل النص",
        "sqlite-no-fts": "$1 بدون دعم البحث في كامل النص",
        "logentry-delete-delete": "{{GENDER:$2|حذف|حذفت}} $1 صفحة $3",
index 2252d94..a6b5c69 100644 (file)
        "protectedinterface": "Esta páxina proporciona'l testu de la interfaz del software d'esta wiki, y ta candada pa torgar abusos.\nP'amestar o cambiar les traducciones de toles wikis, por favor usa [//translatewiki.net/translatewiki.net], el proyeutu de llocalización de MediaWiki.",
        "editinginterface": "<strong>Avisu:</strong> Tas editando una páxina que s'usa pa proporcionar el testu de la interfaz del programa.\nLos cambeos nesta páxina afeutarán al aspeutu de la interfaz pa otros usuarios d'esta wiki.",
        "translateinterface": "P'amestar o camudar les traducciones pa toles wikis, usa [//translatewiki.net/ translatewiki.net], el proyeutu de traducción de MediaWiki.",
-       "cascadeprotected": "Esta páxina ta protexida d'ediciones porque ta inxerta {{PLURAL:$1|na siguiente páxina, protexida|nes siguientes páxines, protexíes}} cola opción «en cascada» activada:\n$2",
+       "cascadeprotected": "Esta páxina ta protexida d'ediciones porque ta trescluída {{PLURAL:$1|na siguiente páxina, protexida|nes siguientes páxines, protexíes}} cola opción «en cascada» activada:\n$2",
        "namespaceprotected": "Nun tienes permisu pa editar páxines nel espaciu de nomes '''$1'''.",
        "customcssprotected": "Nun tienes permisu pa editar esta páxina CSS porque contien preferencies personales d'otru usuariu.",
        "customjsprotected": "Nun tienes permisu pa editar esta páxina de JavaScript porque contien preferencies personales d'otru usuariu.",
        "readonlywarning": "'''Avisu: La base de datos ta candada por mantenimientu, polo que nun vas poder guardar les tos ediciones nestos momentos.'''\nSeique habríes copiar y apegar el testu nun ficheru de testu y guardalu pa intentalo más sero.\n\nL'alministrador que la candó dio esta esplicación: $1",
        "protectedpagewarning": "'''Avisu: Esta páxina ta candada pa que sólo los alministradores puean editala.'''\nLa cabera entrada del rexistru s'ufre darréu pa referencia:",
        "semiprotectedpagewarning": "'''Nota:''' Esta páxina ta candada pa que nun puean editala namái que los usuarios rexistraos.\nLa cabera entrada del rexistru s'ufre darréu pa referencia:",
-       "cascadeprotectedwarning": "'''Avisu:''' Esta páxina ta candada pa que namái los alministradores puedan editala porque ta incluída {{PLURAL:$1|na siguiente páxina protexida|nes siguientes páxines protexíes}} en cascada:",
+       "cascadeprotectedwarning": "<strong>Avisu:</strong> Esta páxina ta candada pa que namái los alministradores puedan editala porque ta trescluída {{PLURAL:$1|na siguiente páxina protexida|nes siguientes páxines protexíes}} en cascada:",
        "titleprotectedwarning": "'''Avisu: Esta páxina ta candada pa que necesite [[Special:ListGroupRights|permisos especiales]] pa creala.'''\nLa cabera entrada del rexistru s'ufre darréu pa referencia:",
        "templatesused": "{{PLURAL:$1|Plantía usada|Plantíes usaes}} nesta páxina:",
        "templatesusedpreview": "{{PLURAL:$1|Plantía usada|Plantíes usaes}} nesta vista previa:",
        "protect-locked-blocked": "Nun pues camudar los niveles de proteición mentes teas bloquiáu. Esta\nye la configuración actual de la páxina '''$1''':",
        "protect-locked-dblock": "Los niveles de proteición nun puen ser camudaos pol mor d'un candáu activu de\nla base de datos. Esta ye la configuración actual de la páxina '''$1''':",
        "protect-locked-access": "La to cuenta nun tien permisu pa camudar los niveles de proteición de páxina.\nEsta ye la configuración actual pa la páxina '''$1''':",
-       "protect-cascadeon": "Esta páxina ta protexida nestos momentos porque ta incluída {{PLURAL:$1|na siguiente páxina, que tien|nes siguientes páxines, que tienen}} activada la proteición en cascada.\nLos cambios nel nivel de proteición d'esta páxina nun afeutarán a la proteición en cascada.",
+       "protect-cascadeon": "Esta páxina ta protexida nestos momentos porque ta trescluída {{PLURAL:$1|na siguiente páxina, que tien|nes siguientes páxines, que tienen}} activada la proteición en cascada.\nLos cambios nel nivel de proteición d'esta páxina nun afeutarán a la proteición en cascada.",
        "protect-default": "Permitir tolos usuarios",
        "protect-fallback": "Permitir namái usuarios con permisu \"$1\"",
        "protect-level-autoconfirmed": "Permitir namái usuarios autoconfirmaos",
        "htmlform-cloner-create": "Amestar más",
        "htmlform-cloner-delete": "Desaniciar",
        "htmlform-cloner-required": "Necesítase polo menos un valor.",
+       "htmlform-title-badnamespace": "[[:$1]] nun ta nel espaciu de nomes \"{{ns:$2}}\".",
+       "htmlform-title-not-creatable": "«$1» nun ye un títulu de páxina que pueda crease",
+       "htmlform-title-not-exists": "[[:$1]] nun esiste.",
+       "htmlform-user-not-exists": "<strong>$1</strong> nun esiste.",
+       "htmlform-user-not-valid": "<strong>$1</strong> nun ye un nome d'usuariu válidu.",
        "sqlite-has-fts": "$1 con sofitu pa busca de testu completu",
        "sqlite-no-fts": "$1 ensin sofitu pa busca de testu completu",
        "logentry-delete-delete": "$1 {{GENDER:$2|desanició}} la páxina $3",
index 1ee3b58..fd8a071 100644 (file)
        "log-name-contentmodel": "Журнал зьменаў мадэляў зьместу",
        "log-description-contentmodel": "Падзеі, зьвязаныя з мадэлямі зьместу старонак",
        "logentry-contentmodel-change": "$1 {{GENDER:$2|зьмяніў|зьмяніла}} мадэль зьместу старонкі $3 з «$4» на «$5»",
+       "logentry-contentmodel-change-revertlink": "адкаціць",
+       "logentry-contentmodel-change-revert": "адкат",
        "protectlogpage": "Журнал абаронаў",
        "protectlogtext": "Ніжэй пададзены сьпіс зьменаў абароны старонкі.\nГлядзіце [[Special:ProtectedPages|сьпіс абароненых старонак на цяперашні момант]].",
        "protectedarticle": "абароненая «[[$1]]»",
index c1d9a3c..511d8af 100644 (file)
        "badtitletext": "El títol de la pàgina que heu introduït no és correcte, és en blanc o conté un enllaç trencat amb un altre projecte. També podria contenir algun caràcter no acceptat als títols de pàgina.",
        "title-invalid-empty": "El títol de la pàgina sol·licitada és buit o només conté el nom d’un espai de noms.",
        "title-invalid-utf8": "El títol de la pàgina sol·licitada conté una seqüència UTF-8 no vàlida.",
-       "title-invalid-interwiki": "El títol conté un enllaç interwiki",
+       "title-invalid-interwiki": "El títol de la pàgina sol·licitada conté un enllaç interwiki que no pot ser utilitzat en títols.",
        "title-invalid-talk-namespace": "El títol de la pàgina sol·licitada fa referència a una pàgina de discussió impossible.",
        "title-invalid-characters": "El títol de la pàgina sol·licitada conté caràcters no vàlids: «$1».",
        "title-invalid-relative": "El títol conté un camí relatiu. Els títols relatius (./, ../) no són vàlids perquè els navegadors web sovint no poden arribar-hi.",
        "yourdiff": "Diferències",
        "copyrightwarning": "Si us plau, tingueu en compte que totes les contribucions per al projecte {{SITENAME}} es consideren com a publicades sota els termes de la llicència $2 (vegeu-ne més detalls a $1). Si no desitgeu la modificació i distribució lliure dels vostres escrits sense el vostre consentiment, no els poseu ací.<br />\nA més a més, en enviar el vostre text, doneu fe que és vostra l'autoria, o bé de fonts en el domini públic o recursos lliures similars. Heu de saber que aquest '''no''' és el cas de la majoria de pàgines que hi ha a Internet.\n'''No feu servir textos amb drets d'autor sense permís!'''",
        "copyrightwarning2": "Si us plau, tingueu en compte que totes les contribucions al projecte {{SITENAME}} poden ser corregides, alterades o esborrades per altres usuaris. Si no desitgeu la modificació i distribució lliure dels vostres escrits sense el vostre consentiment, no els poseu ací.<br />\nA més a més, en enviar el vostre text, doneu fe que és vostra l'autoria, o bé de fonts en el domini públic o altres recursos lliures similars (consulteu $1 per a més detalls).\n'''No feu servir textos amb drets d'autor sense permís!'''",
+       "editpage-cannot-use-custom-model": "El model de contingut d'aquesta pàgina no pot ser canviat.",
        "longpageerror": "'''Error: El text que heu introduït és {{PLURAL:$1|d'un kilobyte|de $1 kilobytes}} i sobrepassa el màxim permès de {{PLURAL:$2|one kilobyte|$2 kilobytes}}.'''\nNo es pot desar.",
        "readonlywarning": "'''Avís: La base de dades està tancada per manteniment, de manera que no podreu desar els canvis ara mateix.'''\nÉs possible que vulgueu copiar i enganxar el text en un arxiu de text i desar-ho més tard.\n\nL'administrador que l'ha bloquejada ha donat la següent explicació: $1",
        "protectedpagewarning": "'''ATENCIÓ: Aquesta pàgina està bloquejada i només els usuaris amb drets d'administrador la poden modificar.\nA continuació es mostra la darrera entrada del registre com a referència:",
        "badsig": "La signatura que heu inserit no és vàlida; verifiqueu les etiquetes HTML que heu emprat.",
        "badsiglength": "La signatura és massa llarga.\nHa de tenir com a molt {{PLURAL:$1|un caràcter|$1 caràcters}}.",
        "yourgender": "Sexe:",
-       "gender-unknown": "No especificat",
+       "gender-unknown": "En esmentar-vos, el software utilitzarà paraules de gènere neutre, sempre que sigui possible",
        "gender-male": "Masculí",
        "gender-female": "Femení",
        "prefs-help-gender": "Opcional: s'usa perquè el programari se us adreci amb missatges amb el gènere adient. Aquesta informació serà pública.",
        "userrights-lookup-user": "Gestiona els grups d'usuari",
        "userrights-user-editname": "Introduïu un nom d'usuari:",
        "editusergroup": "Edita els grups d'usuaris",
-       "editinguser": "Modificació dels permisos de {{GENDER:$1|l’usuari|la usuària}} '''[[User:$1|$1]]''' $2",
+       "editinguser": "Modificació dels permisos de {{GENDER:$1|l'usuari|la usuària}} <strong>[[User:$1|$1]]</strong>$2",
        "userrights-editusergroup": "Edita els grups d'usuaris",
        "saveusergroups": "Desa els grups d'usuari",
        "userrights-groupsmember": "Membre de:",
        "uploaddisabledtext": "S'ha inhabilitat la càrrega de fitxers.",
        "php-uploaddisabledtext": "La càrrega de fitxer està desactivada al PHP. Comproveu les opcions del fitxer file_uploads.",
        "uploadscripted": "Aquest fitxer conté codi HTML o de seqüències que pot ser interpretat equivocadament per un navegador.",
+       "upload-scripted-pi-callback": "No es poden carregar arxius que continguin instruccions de processament de pàgines d'estil XML",
        "uploadscriptednamespace": "Aquest fitxer SVG conté un espai de noms \"$1\" no autoritzat",
        "uploadinvalidxml": "No s'ha pogut analitzar l'XML del fitxer carregat.",
        "uploadvirus": "El fitxer conté un virus! Detalls: $1",
index 41b1bae..0759943 100644 (file)
@@ -15,7 +15,7 @@
        "tog-hideminor": "Къайладаха кигийра нисдарш оц могӀама керла хийцамехь",
        "tog-hidepatrolled": "Къайладаха гӀаролладина нисдарш оц могӀама керла нисдаршкахь",
        "tog-newpageshidepatrolled": "Къайлаяха гӀароллайина агӀонаш оьцу могӀама керла агӀонашкахь",
-       "tog-extendwatchlist": "Шорбина тӀехьажарна могӀам, ша беригге а хийцамаш чубогӀуш, тӀехьаббина боцурш а",
+       "tog-extendwatchlist": "Шорбина тӀехьажарна могӀам, ша беригге а, хийцамаш чубогӀуш, тӀехьаббина боцурш а",
        "tog-usenewrc": "Лелабе дика могӀам керла чу хийцамашна (оьшу JavaScript)",
        "tog-numberheadings": "Ша шех хlитто терахь корташна",
        "tog-showtoolbar": "Гайта лакхара гӀирсийн панель тадарш дечу хенахь",
        "laggedslavemode": "Тергам бе: агӀона чохь керла йаьхинарш ца хила мега.",
        "readonly": "Блоктоьхна дӀайаздар хаамийн бухе",
        "enterlockreason": "Билгалде блоктохаран бахьана а, и чекх йолу хан а.",
-       "readonlytext": "АгӀонаш тӀетохар а кхин хийцамаш барна а блоктоьхна:\nБлокоьхначо биттина хаам: $1.",
+       "readonlytext": "АгӀонаш тӀетохар а, кхин хийцамаш барна а блоктоьхна:\nБлокоьхначо биттина хаам: $1.",
        "missing-article": "ХӀокху чохь кароезаш йолу хьан дехарца йозан агӀонаш цакарийна «$1» $2.\n\nИштнарг наггахь хуьлу хьажорг дӀаяьккхина елахь я хийцам бина тиша хьажоргца дехьа гӀо гӀоьртича.\n\nНагахьсан гӀулкх цуьнах доьзна дацахь, хьуна карийна гӀирс латточехь гӀалат.\nДехар до, хаам бе оцуьнах [[Special:ListUsers/sysop|куьйгалхога]], гойтуш URL.",
        "missingarticle-rev": "(верси № $1)",
        "missingarticle-diff": "(башхалла: $1, $2)",
        "actionthrottledtext": "Спам цахилийта хӀара дешдерг кӀезиг хенахь дукху ца дайта дихкина ду. Дехар до массийта минот яьлча гӀорта.",
        "protectedpagetext": "ХӀара агӀо дӀакъоьвлина ю тадарш ца дайта.",
        "viewsourcetext": "Хьоьга далундерг хьажар а дезахь хlокху агlон чура йоза хьаэцар:",
-       "viewyourtext": "Хьан йиш ю '''хьой нисдинчу''' дӀадолалун йозе хьажа а цуна копи ян а:",
+       "viewyourtext": "Хьан йиш ю '''хьой нисдинчу''' дӀадолалун йозе хьажа а, цуна копи ян а:",
        "protectedinterface": "ХӀокху агӀона чохь интерфейсан программа латторан хаам бу. Зулам ца дайта цуна хийцам бан куьйгалхошна бен цало.\nХӀокху хааман гоч тӀетоха я хийца лелае локализацин сайт MediaWiki [//translatewiki.net/ translatewiki.net]",
        "editinginterface": "<strong>Тергам бе:</strong> Ахьа таеш ю интерфейсан йоза долу агӀо программин латторан.\nЦуна бина хийцам хьокху Википедин кхечу декъашхошна гур бу.",
        "translateinterface": "ХӀокху хааман гоч тӀетоха я хийца дехар до лелае локализацин сайт MediaWiki [//translatewiki.net/ translatewiki.net].",
        "wrongpasswordempty": "Дехар до, язъе еса йоцу пароль.",
        "passwordtooshort": "Пароль хилла еза $1 {{PLURAL:$1|символ|символаш}} йолуш.",
        "password-name-match": "Язъен пароль декъашхочун дӀаяздарал башха хила еза.",
-       "password-login-forbidden": "Иштта декъашхочун цӀе а пароль а лелаян цамаго.",
+       "password-login-forbidden": "Иштта декъашхочун цӀе а, пароль а лелаян цамаго.",
        "mailmypassword": "Пароль кхоссар",
        "passwordremindertitle": "Декъашхочун {{grammar:genitive|{{SITENAME}}}}  пароль дагайаийтар",
        "passwordremindertext": "Цхьам (ахь хила мега IP-адрес $1 тӀера) керла пароль кхоллар дехна {{grammar:genitive|{{SITENAME}}}} ($4) чохь. Декъашхочун $2\nкхоьллина керла хана пароль: $3. Иза дехар ахь динехь,\nсистемин чугӀой хийца пароль.\nХьан керла пароль белх беш хира ю $5 {{PLURAL:$5|дийнахь}}.\n\nХьой дехар дийна дацахь хӀума маде Ӏад бита хӀара хаам.",
        "mergehistory-submit": "Цхьаьнатоха нисдарш",
        "mergehistory-empty": "Цхьаьнатоха нисдарш цакарий.",
        "mergehistory-success": "$3 {{PLURAL:$3|нисдар|нисдарш}} [[:$1]] чура кхиамца {{PLURAL:$3|дехьа даьккхина|дехьа дехна}} [[:$2]] чу.",
-       "mergehistory-fail": "АгӀонийн истореш вовшахтоха цаделира, дехар до агӀона параметаршка а хене а хьажа.",
+       "mergehistory-fail": "АгӀонийн истореш вовшахтоха цаделира, дехар до агӀона параметаршка а, хене а хьажа.",
        "mergehistory-no-source": "Коьрта агӀо «$1» яц.",
        "mergehistory-no-destination": "Ӏалашон агӀо «$1» яц.",
        "mergehistory-invalid-source": "Хьостан нийса корта хила еза.",
        "yourlanguage": "Мотт:",
        "yourvariant": "Метта башхо:",
        "yournick": "Керла куьгтаӀор:",
-       "prefs-help-signature": "Дийцаре агӀонаш чохь къуьгтаӀо деза символшца «<nowiki>~~~~</nowiki>», цара гойтур ду хьан къуьгтаӀор а хан а.",
+       "prefs-help-signature": "Дийцаре агӀонаш чохь къуьгтаӀо деза символшца «<nowiki>~~~~</nowiki>», цара гойтур ду хьан къуьгтаӀор а, хан а.",
        "badsiglength": "ТӀех деха куьг.\nКуьйган $1 {{PLURAL:$1|символ}} дукха хила цамега.",
        "yourgender": "Стен-боьршалла",
        "gender-unknown": "хӀоттийна яц",
        "right-writeapi": "дӀаяздеш лелойо API",
        "right-delete": "агӀонаш дӀаяхар",
        "right-bigdelete": "еха хийцаман истори йолу агӀонаш дӀаяхар",
-       "right-deletelogentry": "тептар чура билгала дӀаяздарш дӀадахар а меттахӀиттадар а.",
-       "right-deleterevision": "агӀонийн билгала версеш дӀаяхар а меттахӀиттаяр а",
+       "right-deletelogentry": "тептар чура билгала дӀаяздарш дӀадахар а, меттахӀиттадар а.",
+       "right-deleterevision": "агӀонийн билгала версеш дӀаяхар а, меттахӀиттаяр а",
        "right-deletedhistory": "дӀаяьхна агӀонийн исторега хьажар дӀадаьккхина йоза тӀекхочехь доцуш",
-       "right-deletedtext": "дӀадаьккхина йозане а хийцамашка а хьажар агӀонийн дӀаяьхна версин юккъахь",
+       "right-deletedtext": "дӀадаьккхина йозане а, хийцамашка а хьажар агӀонийн дӀаяьхна версин юккъахь",
        "right-browsearchive": "дӀаяхна агӀонаш лахар",
        "right-undelete": "АгӀонаш меттахӀоттор",
        "right-suppressrevision": "куьйгалхойх хьулйина йолу агӀонийн версеш меттахӀиттаяр а хьажар а",
        "right-suppressionlog": "долара тептаршка хьажар",
        "right-block": "кхечу декъашхошка тадарш ца дайта дехкар хӀоттор",
        "right-blockemail": "Цамагдо декъашхошка хааман кехаташ кхехьийта",
-       "right-hideuser": "декъашхочун цӀе а и лечкъо а цамагор",
-       "right-ipblock-exempt": "IP блоктохаршна чекхбовлар, диапазонийн шаблоктохаршна а блоктохаршна а",
+       "right-hideuser": "декъашхочун цӀе а, и лечкъо а цамагор",
+       "right-ipblock-exempt": "IP блоктохаршна чекхбовлар, диапазонийн шаблоктохаршна а, блоктохаршна а",
        "right-proxyunbannable": "проксен автоматически блоктохаран чекхбовлар",
        "right-unblockself": "ша шин блокдӀаяккхар",
        "right-protect": "АгӀо ларъяран хийцар а, ларйина агӀо нисяр а",
        "right-editprotected": "«{{int:protect-level-sysop}}» бахьанца ларйина агӀонаш нисъяр",
        "right-editsemiprotected": "«{{int:protect-level-autoconfirmed}}» бахьанца ларйина агӀонаш нисъяр",
        "right-editinterface": "лелош йолу интерфейсан хийцам бар",
-       "right-editusercssjs": "кхечу декъашхойн CSS- а JS- а файлаш нисяр",
+       "right-editusercssjs": "кхечу декъашхойн CSS- а, JS- а файлаш нисяр",
        "right-editusercss": "кхечу декъашхойн CSS-файлаш нсяр",
        "right-edituserjs": "кхечу декъашхойн JavaScript-файлаш нисяр",
        "right-editmyusercss": "Декъашхочун CSS файлаш таяр",
        "right-mergehistory": "агӀонаш вовшахтохар",
        "right-userrights": "декъашхойн массо бакъонаш хийцар",
        "right-userrights-interwiki": "кхечу вики сайташкара декъашхойн бакъонаш хийцар",
-       "right-siteadmin": "хаамийн гуламан блоктохар а блокдӀаяккхар а",
+       "right-siteadmin": "хаамийн гуламан блоктохар а, блокдӀаяккхар а",
        "right-override-export-depth": "агӀонаш экспорт ян, 5 кхаччалц къорга агӀонаш цхьан",
        "right-sendemail": "кхечу декъашхошка электронан хаамаш кхехьийта",
        "right-passwordreset": "пароль хийцарца электроннан хаамашка хьажар",
-       "right-managechangetags": "Хаамийн базан чохь [[Special:Tags|билгалонаш]] кхолла а дӀаяха а",
+       "right-managechangetags": "Хаамийн базан чохь [[Special:Tags|билгалонаш]] кхолла а, дӀаяха а",
        "newuserlogpage": "Декъашхой дӀабазбина тептар",
        "newuserlogpagetext": "Дукху хан йоцуш дӀабазбелла декъашхойн могӀам",
        "rightslog": "Декъашхочун бакъона тéптар",
        "action-deletedhistory": "хӀокху агӀона дӀаяккхинцу исторега хьажар",
        "action-browsearchive": "ДӀаяхна агӀонаш лахар",
        "action-undelete": "хӀара агӀо меттахӀоттор",
-       "action-suppressrevision": "хӀокху къайлаха йолу агӀон версеш хьажар а меттахӀоттор а",
+       "action-suppressrevision": "хӀокху къайлаха йолу агӀон версеш хьажар а, меттахӀоттор а",
        "action-suppressionlog": "хӀокху долара тептаре хьажар",
        "action-block": "хӀокху декъашхошка тадарш ца дайта дехкар хӀоттор",
        "action-protect": "хӀокху агӀона гӀоралин хьал хийцар",
        "action-viewmywatchlist": "шен тергаме могӀане хьажар",
        "action-viewmyprivateinfo": "хьан долара хааме хьажар",
        "action-editmyprivateinfo": "хьан долара хаам табар",
-       "action-managechangetags": "хаамийн базан чохь билгалонаш кхоллар а дӀаяхар а",
+       "action-managechangetags": "хаамийн базан чохь билгалонаш кхоллар а, дӀаяхар а",
        "nchanges": "$1 {{PLURAL:$1|хийцам}}",
        "enhancedrc-since-last-visit": "$1 {{PLURAL:$1|тӀеххьара чудаларца}}",
        "enhancedrc-history": "истори",
        "file-exists-duplicate": "ХӀара файл лахарчу {{PLURAL:$1|1=файлан|файлийн}} дубликат ю:",
        "file-deleted-duplicate": "Иштта файл ([[:$1]]) хӀинцале дӀаяьккхина хилла. Дехар до, юху файл чуяккхале файл дӀаяккхаран историга хьажа.",
        "uploadwarning": "ДӀахьедар",
-       "uploadwarning-text": "Дехар до, лахара файлах лаьцнарг хийца а дай юху а гӀорта файл чуяккха.",
+       "uploadwarning-text": "Дехар до, лахара файлах лаьцнарг хийца а, дай юху а гӀорта файл чуяккха.",
        "savefile": "ДӀаязъе файл",
        "uploaddisabled": "Чуяккхар магийна дац",
        "copyuploaddisabled": "URL тӀера чуяккхар дӀадайина ду.",
        "restriction-level-autoconfirmed": "дуьззина доцуш лардар",
        "restriction-level-all": "массо барам",
        "undelete": "ДӀаяьхна агӀонашка хьажар",
-       "undeletepage": "ДӀаяьхна агӀонашка хьажар а меттахӀоттор а",
+       "undeletepage": "ДӀаяьхна агӀонашка хьажар а, меттахӀоттор а",
        "undeletepagetitle": "'''Лахахь гайтина хӀокху [[:$1]] агӀона дӀаяхина версеш'''.",
        "viewdeletedpage": "ДӀаяьхна йолу агӀонашка хьажар",
        "undelete-fieldset-title": "МеттахӀоттае версеш",
        "undeleteinvert": "Къастае массо",
        "undeletecomment": "Бахьана:",
        "undeletedrevisions": "{{PLURAL:$1|меттахӀоьттина}} $1 {{PLURAL:$1|хийцам}}",
-       "undeletedrevisions-files": "меттахӀоьттина $1 {{PLURAL:$1|верси}} а $2 {{PLURAL:$2|файл}} а",
+       "undeletedrevisions-files": "меттахӀоьттина $1 {{PLURAL:$1|верси}} а, $2 {{PLURAL:$2|файл}} а",
        "undeletedfiles": "$1 {{PLURAL:$1|файл меттахӀоттайина|файлаш меттахӀоттайина}}",
        "cannotundelete": "ГӀалат меттахӀоттайина:\n$1",
        "undeletedpage": "'''МеттахӀоттайина агӀо «$1».'''\n\nДӀадяхнарш долу могӀане [[Special:Log/delete|тéптаре хьажа]].",
        "ipbsubmit": "Блоктоха хӀокху декъашхочун/адресна",
        "ipbother": "Кхин хан:",
        "ipboptions": "2 сахьат:2 hours,1 де:1 day,3 де:3 days,1 кlиран:1 week,2 кlиран:2 weeks,1 бутт:1 month,3 бутт:3 months,6 бутт:6 months,1 шо:1 year,цӀкъа:infinite",
-       "ipbhidename": "Нисдарийн а могӀаман а чура декъашхочун цӀе хьул йе",
-       "ipbwatchuser": "ТӀетоха тергаме могӀам юкъа цуьнан долахь йолу агӀо а цуьнан дийцаре агӀо а",
+       "ipbhidename": "Нисдарийн а, могӀаман а чура декъашхочун цӀе хьул йе",
+       "ipbwatchuser": "ТӀетоха тергаме могӀам юкъа цуьнан долахь йолу агӀо а, цуьнан дийцаре агӀо а",
        "ipb-disableusertalk": "Цамагдо шин дийцаре агӀо та я блоктоьхна хан чекхъяллалц",
        "ipb-change-block": "Юхаблоктоха декъашхочун оьцу хийцамашца",
        "ipb-confirm": "Бакъде блоктохар",
        "articleexists": "ХӀарасанна цӀе йолу агӀо йолуш ю йа ахьа гойтуш йолу цӀе магош яц.\nДехар до, харжа кхин цӀе.",
        "movetalk": "Цуьнца йогӀуш йолу дийцаре агӀон цӀе хийцар",
        "move-subpages": "ЦӀерш хийца бухара агӀонийн ($1 кхаччалц)",
-       "move-talk-subpages": "ЦӀе хийца бухара агӀонийн а агӀонийн дийцаре а ($1  кхаччалц)",
+       "move-talk-subpages": "ЦӀе хийца бухара агӀонийн а, агӀонийн дийцаре а ($1  кхаччалц)",
        "movepage-page-exists": "Агӏо $1 йолуш ю цундела и ша юху дӏаязъян йиш яц.",
        "movepage-page-moved": "АгӀона $1 цӀе хийцина → $2.",
        "movelogpage": "ЦӀерш хийцаран тептар",
        "exif-orientation": "Суьртан хьал",
        "exif-samplesperpixel": "Беснийн компонентийн дукхалла",
        "exif-planarconfiguration": "Организацин хаамийн некъ",
-       "exif-ycbcrsubsampling": "Барамийн компонент Y а C а",
-       "exif-ycbcrpositioning": "Y а C а компонентин листаран кеп",
+       "exif-ycbcrsubsampling": "Барамийн компонент Y а, C а",
+       "exif-ycbcrpositioning": "Y а, C а компонентин листаран кеп",
        "exif-xresolution": "Шоралла",
        "exif-yresolution": "Локхалла",
        "exif-stripoffsets": "Суьртийн хаамаш болу меттиг",
        "exif-jpeginterchangeformatlength": "Сизан хааман барам preview",
        "exif-whitepoint": "Къайн тӀадаман бос",
        "exif-primarychromaticities": "Коьрта беснийн бос",
-       "exif-referenceblackwhite": "Ӏаьржа а къай а тӀадамийн меттиг",
+       "exif-referenceblackwhite": "Ӏаьржа а, къай а тӀадамийн меттиг",
        "exif-datetime": "Файлан хийцам бина терахь а, хан а",
        "exif-imagedescription": "Суьртан цӏе",
        "exif-make": "Камера арахоьцург",
        "exif-usercomment": "Кхин тӀе къамел",
        "exif-relatedsoundfile": "Къамелан аьзнийн файл",
        "exif-datetimeoriginal": "Дуьххьарлера терахь а хан",
-       "exif-datetimedigitized": "Оцифровк йина терахь а хан а",
+       "exif-datetimedigitized": "Оцифровк йина терахь а, хан а",
        "exif-subsectime": "Файлан хийцам баран хан секундашкахь",
        "exif-subsectimeoriginal": "Оригинал хенан секундан дакъа",
        "exif-subsectimedigitized": "Терахьийн хенан секундан дакъа",
        "exif-gpsdop-poor": "Во ($1)",
        "exif-objectcycle-a": "Ӏуьранна бен",
        "exif-objectcycle-p": "Суьйранна бен",
-       "exif-objectcycle-b": "Ӏуьранна а суьйранна а",
+       "exif-objectcycle-b": "Ӏуьранна а, суьйранна а",
        "exif-gpsdirection-t": "бакъалла",
        "exif-gpsdirection-m": "магнитан",
        "exif-ycbcrpositioning-1": "Юкъйина",
        "exif-dc-type": "Медиан тайп",
        "exif-rating-rejected": "ДӀайайина",
        "exif-isospeedratings-overflow": "65535 дукха",
-       "exif-iimcategory-ace": "Исбаьхьалла, культура а синкъерам а",
-       "exif-iimcategory-clj": "Зулам дар а Ӏедал а",
-       "exif-iimcategory-dis": "Ирча бохам а авари а",
-       "exif-iimcategory-fin": "Экономика а бизнес а",
+       "exif-iimcategory-ace": "Исбаьхьалла, культура а, синкъерам а",
+       "exif-iimcategory-clj": "Зулам дар а, Ӏедал а",
+       "exif-iimcategory-dis": "Ирча бохам а, авари а",
+       "exif-iimcategory-fin": "Экономика а, бизнес а",
        "exif-iimcategory-edu": "Дешна хилар",
        "exif-iimcategory-lab": "Къинхьегам",
-       "exif-iimcategory-rel": "Дин а тешар а",
-       "exif-iimcategory-sci": "Ӏилма а техника а",
+       "exif-iimcategory-rel": "Дин а, тешар а",
+       "exif-iimcategory-sci": "Ӏилма а, техника а",
        "exif-iimcategory-soi": "Социалан хаттарш",
        "exif-iimcategory-wea": "Хенан хӀоттам",
        "exif-urgency-normal": "Диканиг ($1)",
        "specialpages-group-highuse": "Уггаре дукха лелайо агӀонаш",
        "specialpages-group-pages": "АгӀонийн могӀанаш",
        "specialpages-group-pagetools": "ГӀирсаш агӀонашна",
-       "specialpages-group-wiki": "Хаамаш а гӀирсаш а",
+       "specialpages-group-wiki": "Хаамаш а, гӀирсаш а",
        "specialpages-group-redirects": "ДӀасахьажош йолу белхан агӀонаш",
        "specialpages-group-spam": "Спаман дуьхьала гӀирсаш",
        "blankpage": "Еса агӀо",
        "tags-deactivate": "дӀаяйа",
        "tags-hitcount": "$1 {{PLURAL:$1|хийцам}}",
        "tags-create-heading": "Кхолла керла билгало",
-       "tags-create-explanation": "Юха кхоьллина билгалонаш декъашхошна а боташна а Ӏад йтарца тӀекхочуш хира ю.",
+       "tags-create-explanation": "Юха кхоьллина билгалонаш декъашхошна а, боташна а Ӏад йтарца тӀекхочуш хира ю.",
        "tags-create-tag-name": "Билгалонна цӀе:",
        "tags-create-reason": "Бахьана:",
        "tags-create-submit": "Кхолла",
index cc5919b..e20c3eb 100644 (file)
        "protectedinterface": "Tato stránka obsahuje text softwarového rozhraní a je zamčena kvůli prevenci zneužití.\nPro přidávání a změny překladů pro všechny wiki použijte [//translatewiki.net/ translatewiki.net], projekt pro lokalizaci MediaWiki.",
        "editinginterface": "<strong>Upozornění:</strong> Editujete stránku, která definuje texty rozhraní.\nZměny této stránky ovlivní vzhled uživatelského rozhraní všem uživatelům této wiki.",
        "translateinterface": "Pro přidávání a změny překladů pro všechny wiki použijte [//translatewiki.net/ translatewiki.net], projekt pro lokalizaci MediaWiki.",
-       "cascadeprotected": "Tato stránka je zamčena, neboť je vložena do {{PLURAL:$1|následující stránky, zamčené|následujících stránek, zamčených|následujících stránek, zamčených}} kaskádovým zámkem:\n$2",
+       "cascadeprotected": "Tato stránka je zamčena, neboť je vložena na {{PLURAL:$1|následující stránku, zamčenou|následující stránky, zamčené}} kaskádovým zámkem:\n$2",
        "namespaceprotected": "Nemáte povoleno editovat stránky ve jmenném prostoru '''$1'''.",
        "customcssprotected": "Nemáte povoleno editovat tuto stránku s CSS, protože obsahuje osobní nastavení jiného uživatele.",
        "customjsprotected": "Nemáte povoleno editovat tuto stránku s JavaScriptem, protože obsahuje osobní nastavení jiného uživatele.",
        "readonlywarning": "<strong>Varování: Databáze byla uzamčena kvůli údržbě, takže momentálně nebudete moci uložit své změny.</strong>\nMůžete si okopírovat text do souboru a uložit si ho na později.\n\nSprávce serveru, který databázi zamkl, poskytl toto zdůvodnění: $1",
        "protectedpagewarning": "'''Varování: Tato stránka byla zamčena, takže ji mohou editovat pouze správci.'''\nNíže je pro přehled zobrazen nejnovější protokolovací záznam:",
        "semiprotectedpagewarning": "'''Poznámka:''' Tato stránka byla zamčena, takže ji mohou editovat pouze registrovaní uživatelé.\nNíže je pro přehled zobrazen nejnovější protokolovací záznam:",
-       "cascadeprotectedwarning": "<strong>Varování:</strong> Tato stránka byla zamčena, takže ji mohou editovat pouze správci, protože je vložena na následující, kaskádm zámkem {{PLURAL:$1|zamčenou, stránku|zamčené, stránky}}:",
+       "cascadeprotectedwarning": "<strong>Varování:</strong> Tato stránka byla zamčena, takže ji mohou editovat pouze správci, protože je vložena na následující, kaskádovým zámkem {{PLURAL:$1|zamčenou, stránku|zamčené, stránky}}:",
        "titleprotectedwarning": "'''Varování: Tato stránka byla uzamčena, takže k jejímu založení jsou potřeba [[Special:ListGroupRights|zvláštní oprávnění]].'''\nNíže je pro přehled zobrazen nejnovější protokolovací záznam:",
        "templatesused": "{{PLURAL:$1|Šablona použitá|Šablony použité}} na této stránce:",
        "templatesusedpreview": "{{PLURAL:$1|Šablona použitá|Šablony použité}} v tomto náhledu:",
        "htmlform-title-badnamespace": "Stránka [[:$1]] není ve jmenném prostoru „{{ns:$2}}“.",
        "htmlform-title-not-creatable": "Pod názvem „$1“ nelze vytvořit stránku",
        "htmlform-title-not-exists": "Stránka [[:$1]] neexistuje.",
+       "htmlform-user-not-exists": "Uživatel <strong>$1</strong> neexistuje.",
+       "htmlform-user-not-valid": "<strong>$1</strong> není platné uživatelské jméno.",
        "sqlite-has-fts": "$1 s podporou plnotextového vyhledávání",
        "sqlite-no-fts": "$1 bez podpory plnotextového vyhledávání",
        "logentry-delete-delete": "$1 {{GENDER:$2|smazal|smazala}} stránku $3",
index 5de7f78..3c0a78e 100644 (file)
        "emailccme": "Çыру копине ман пата ямалла",
        "emailsent": "Çырăва леçрĕмĕр",
        "emailsenttext": "Сирĕн электронлă çырăва леçрĕмĕр.",
-       "watchlist": "Ð\9fÄ\83Ñ\85Ñ\81а Ñ\82Ä\83Ñ\80акан Ñ\81Ñ\82Ñ\80аниÑ\86Ä\83Ñ\81ем Ñ\8fÑ\82-йÑ\8bÑ\88ĕ",
+       "watchlist": "Ð\9fÄ\83Ñ\85Ñ\81а Ñ\82Ä\83Ñ\80акан Ñ\81Ñ\82Ñ\80аниÑ\86Ä\83Ñ\81ен Ñ\81пиÑ\81окĕ",
        "mywatchlist": "Сăнаса тăракан списокĕ",
        "watchlistfor2": "$1 валли $2",
        "nowatchlist": "Эсир пăхса тăракан страницăсен списокĕ пушă.",
index f46ebde..4176884 100644 (file)
        "htmlform-title-badnamespace": "[[:$1]] ist nicht im Namensraum „{{ns:$2}}“.",
        "htmlform-title-not-creatable": "„$1“ ist kein erstellbarer Seitentitel",
        "htmlform-title-not-exists": "[[:$1]] ist nicht vorhanden.",
+       "htmlform-user-not-exists": "<strong>$1</strong> ist nicht vorhanden.",
+       "htmlform-user-not-valid": "<strong>$1</strong> ist kein gültiger Benutzername.",
        "sqlite-has-fts": "Version $1 mit Unterstützung für die Volltextsuche",
        "sqlite-no-fts": "Version $1 ohne Unterstützung für die Volltextsuche",
        "logentry-delete-delete": "$1 {{GENDER:$2|löschte}} Seite $3",
index b55d3e4..e39e8ce 100644 (file)
        "subject-preview": "Previsualización del asunto/encabezado:",
        "previewerrortext": "Se ha producido un error al intentar la vista previa de los cambios.",
        "blockedtitle": "El usuario está bloqueado",
-       "blockedtext": "<strong>Tu nombre de usuario o dirección IP ha sido bloqueada.</strong>\n\nEl bloqueo fue hecho por $1.\nLa razón dada es <em>$2</em>.\n\n* Inicio del bloqueo: $8\n* Caducidad del bloqueo: $6\n* Bloqueo destinado a: $7\n\nPuedes contactar a $1 o con otro de los [[{{MediaWiki:Grouppage-sysop}}|administradores]] para discutir el bloqueo.\nNo puedes utilizar la función «enviar correo electrónico a este usuario»  a menos que tengas una dirección de correo electrónico válida registrada en tus [[Special:Preferences|preferencias de usuario]] y que el bloqueo no haya inhabilitado esta función.\n\nTu dirección IP actual es $3, y el identificador del bloqueo es #$5.\nPor favor incluye todos los datos aquí mostrados en cualquier consulta que hagas.",
-       "autoblockedtext": "Tu dirección IP ha sido bloqueada automáticamente porque fue utilizada por otro usuario, que resultó bloqueado por $1.\n\nEl motivo dado es el siguiente:\n\n:<em>$2</em>\n\n* Inicio del bloqueo: $8\n* Caducidad del bloqueo: $6\n* Bloqueo destinado a: $7\n\nPuedes contactar con $1 o con otro de los [[{{MediaWiki:Grouppage-sysop}}|administradores]] para discutir el bloqueo.\n\nTen en cuenta que no podrás utilizar la herramienta de «enviar correo electrónico a este usuario» a menos que tengas una dirección de correo electrónico válida registrada en tus [[Special:Preferences|preferencias de usuario]] y la función no haya sido también bloqueada.\n\nTu dirección IP actual es $3, y el identificador del bloqueo es #$5.\nPor favor, incluye todos los datos aquí mostrados en cualquier consulta que hagas al respecto.",
+       "blockedtext": "<strong>Tu nombre de usuario o dirección IP ha sido bloqueada.</strong>\n\nEl bloqueo lo hizo $1.\nLa razón dada es <em>$2</em>.\n\n* Inicio del bloqueo: $8\n* Caducidad del bloqueo: $6\n* Bloqueo destinado a: $7\n\nPuedes contactar a $1 o con otro de los [[{{MediaWiki:Grouppage-sysop}}|administradores]] para discutir el bloqueo.\nNo puedes utilizar la función «enviar correo electrónico a este usuario» a menos que tengas una dirección de correo electrónico válida registrada en tus [[Special:Preferences|preferencias de usuario]] y la función no haya sido también bloqueada.\n\nTu dirección IP actual es $3, y el identificador del bloqueo es #$5.\nIncluye todos los datos aquí mostrados en cualquier consulta que hagas.",
+       "autoblockedtext": "Tu dirección IP ha sido bloqueada automáticamente porque fue utilizada por otro usuario, que resultó bloqueado por $1.\nEl motivo dado es el siguiente:\n\n:<em>$2</em>\n\n* Inicio del bloqueo: $8\n* Caducidad del bloqueo: $6\n* Bloqueo destinado a: $7\n\nPuedes contactar con $1 o con otro de los [[{{MediaWiki:Grouppage-sysop}}|administradores]] para discutir el bloqueo.\n\nTen en cuenta que no puedes utilizar la función «enviar correo electrónico a este usuario» a menos que tengas una dirección de correo electrónico válida registrada en tus [[Special:Preferences|preferencias de usuario]] y la función no haya sido también bloqueada.\n\nTu dirección IP actual es $3, y el identificador del bloqueo es #$5.\nIncluye todos los datos aquí mostrados en cualquier consulta que hagas.",
        "blockednoreason": "no se ha especificado el motivo",
        "whitelistedittext": "Tienes que $1 para editar páginas.",
        "confirmedittext": "Debes confirmar tu dirección de correo electrónico antes de poder editar páginas. Por favor, configura y confirma tu dirección de correo a través de tus [[Special:Preferences|preferencias de usuario]].",
        "largefileserver": "El tamaño de este archivo es mayor del que este servidor admite por configuración.",
        "emptyfile": "El archivo que has intentado subir parece estar vacío; por favor, verifica que realmente se trate del archivo que intentabas subir.",
        "windows-nonascii-filename": "Este wiki no admite nombres de archivo con caracteres especiales.",
-       "fileexists": "Ya existe un archivo con este nombre, por favor comprueba <strong>[[:$1]]</strong> si {{GENDER:|tú}} no estás seguro de querer cambiarlo.\n[[$1|thumb]]",
+       "fileexists": "Ya existe un archivo con este nombre. Comprueba <strong>[[:$1]]</strong> si {{GENDER:|tú}} no estás seguro de querer cambiarlo.\n[[$1|thumb]]",
        "filepageexists": "La página de descripción de este archivo ya ha sido creada en <strong>[[:$1]]</strong>, pero no existe actualmente ningún fichero con este nombre.\nEl resumen que ha ingresado no aparecerá en la página de descripción. Para que el sumario aparezca, deberá editarlo manualmente.\n[[$1|thumb]]",
        "fileexists-extension": "Existe un archivo con un nombre similar: [[$2|thumb]]\n* Nombre del archivo que se está subiendo: <strong>[[:$1]]</strong>\n* Nombre del archivo ya existente: <strong>[[:$2]]</strong>\n¿Quieres cambiar el nombre para que sea más distintivo?",
        "fileexists-thumbnail-yes": "El archivo parece ser una imagen de tamaño reducido ''(thumbnail)''. [[$1|thumb]]\nPor favor comprueba el archivo <strong>[[:$1]]</strong>.\nSi el archivo comprobado es la misma imagen a tamaño original no es necesario subir un thumbnail más.",
        "protect-expiring-local": "caduca el $1",
        "protect-expiry-indefinite": "indefinido",
        "protect-cascade": "Protección en cascada - proteger todas las páginas incluidas en ésta.",
-       "protect-cantedit": "No puedes cambiar el nivel de protección porque no tienes permiso para hacer ediciones.",
+       "protect-cantedit": "No puedes cambiar el nivel de protección de esta página porque no tienes permiso para editarla.",
        "protect-othertime": "Especificar caducidad:",
        "protect-othertime-op": "otra (especificar)",
        "protect-existing-expiry": "Fecha de caducidad actual: $2 a las $3",
        "file-no-thumb-animation": "'''Nota: debido a limitaciones técnicas, las miniaturas de este archivo no están animadas.'''",
        "file-no-thumb-animation-gif": "'''Nota: Debido a limitaciones técnicas, las miniaturas de imágenes GIF de alta resolución como esta no están animadas.'''",
        "newimages": "Galería de imágenes nuevas",
-       "imagelisttext": "Debajo hay una lista de '''$1''' {{PLURAL:$1|imagen|imágenes}} ordenadas $2.",
+       "imagelisttext": "Debajo hay una lista de <strong>$1</strong> {{PLURAL:$1|archivo ordenado|archivos ordenados}} $2.",
        "newimages-summary": "Esta página especial muestra una galería de los últimos archivos subidos.",
        "newimages-legend": "Nombre del fichero",
        "newimages-label": "Nombre del fichero (o una parte):",
        "noimages": "No hay nada que ver.",
        "ilsubmit": "Buscar",
        "bydate": "por fecha",
-       "sp-newimages-showfrom": "Mostrar nuevas imágenes empezando por $2, $1",
+       "sp-newimages-showfrom": "Mostrar archivos nuevos empezando desde $2, $1",
        "seconds-abbrev": "$1s",
        "minutes-abbrev": "$1m",
        "hours-abbrev": "$1h",
        "htmlform-title-badnamespace": "[[:$1]] no está en el espacio de nombres \"{{ns:$2}}\".",
        "htmlform-title-not-creatable": "\"$1\" no es un título de página que se pueda crear",
        "htmlform-title-not-exists": "[[:$1]] no existe.",
+       "htmlform-user-not-exists": "<strong>$1</strong> no existe.",
+       "htmlform-user-not-valid": "<strong>$1</strong> no es un nombre de usuario válido.",
        "sqlite-has-fts": "$1 con soporte para búsqueda de texto completo",
        "sqlite-no-fts": "$1 sin soporte para búsqueda de texto completo",
        "logentry-delete-delete": "$1 {{GENDER:$2|borró}} la página «$3»",
index 6aabe74..ff936ad 100644 (file)
        "readonlywarning": "'''Hoiatus: Andmebaas on lukustatud hooldustöödeks, nii et praegu ei saa parandusi salvestada.'''\nVõid teksti hilisemaks kasutamiseks alles hoida tekstifailina.\n\nAdministraator, kes andmebaasi lukustas, andis järgmise selgituse: $1",
        "protectedpagewarning": "'''Hoiatus: See lehekülg on lukustatud, nii et ainult administraatori õigustega kasutajad saavad seda redigeerida.'''\nAllpool on toodud uusim logisissekanne:",
        "semiprotectedpagewarning": "'''Märkus:''' See lehekülg on lukustatud, nii et üksnes registreeritud kasutajad saavad seda muuta.\nAllpool on toodud uusim logisissekanne:",
-       "cascadeprotectedwarning": "'''Hoiatus:''' See lehekülg on nii lukustatud, et ainult administraatori õigustega kasutajad saavad seda redigeerida, sest lehekülg on osa {{PLURAL:$1|järgmisest|järgmisest}} kaskaadkaitsega {{PLURAL:$1|leheküljest|lehekülgedest}}:",
+       "cascadeprotectedwarning": "<strong>Hoiatus:</strong> See lehekülg on nii lukustatud, et ainult administraatori õigustega kasutajad saavad seda redigeerida, sest lehekülg on osa {{PLURAL:$1|järgmisest|järgmistest}} kaskaadkaitsega {{PLURAL:$1|leheküljest|lehekülgedest}}:",
        "titleprotectedwarning": "'''Hoiatus: See lehekülg on nii lukustatud, et selle loomiseks on tarvis [[Special:ListGroupRights|eriõigusi]].'''\nAllpool on toodud uusim logisissekanne:",
        "templatesused": "Sellel leheküljel on kasutusel {{PLURAL:$1|järgmine mall|järgmised mallid}}:",
        "templatesusedpreview": "Eelvaates {{PLURAL:$1|kasutatav mall|kasutatavad mallid}}:",
        "rollback-success": "Tühistati muudatused, mille tegi $1;\npöörduti tagasi viimasele muudatusele, mille tegi $2.",
        "sessionfailure-title": "Seansiviga",
        "sessionfailure": "Sinu sisselogimisseansiga näib probleem olevat.\nSee toiming on seansiärandamise vastase ettevaatusabinõuna tühistatud.\nMine tagasi eelmisele leheküljele ja taaslaadi see, seejärel proovi uuesti.",
+       "changecontentmodel": "Lehekülje sisumudeli muutmine",
+       "changecontentmodel-legend": "Sisumudeli muutmine",
+       "changecontentmodel-title-label": "Lehekülje pealkiri",
+       "changecontentmodel-model-label": "Uus sisumudel",
+       "changecontentmodel-reason-label": "Põhjus:",
+       "changecontentmodel-success-title": "Sisumudel on muudetud",
+       "changecontentmodel-success-text": "Lehekülje [[:$1]] sisumudel on muudetud.",
+       "changecontentmodel-cannot-convert": "Lehekülje [[:$1]] sisumudelit ei saa teisendada tüübiks $2.",
+       "changecontentmodel-title-cantexist": "Lehekülg ei saa olla pealkirja \"$1\" all.",
+       "changecontentmodel-nodirectediting": "Sisumudel $1 ei võimalda otseredigeerimist.",
+       "log-name-contentmodel": "Sisumudeli muutmislogi",
+       "log-description-contentmodel": "Lehekülje sisumudelite muutmisega seotud sündmused",
+       "logentry-contentmodel-change": "$1 {{GENDER:$2|muutis}} lehekülje \"$3\" sisumudeli: \"$4\" → \"$5\"",
+       "logentry-contentmodel-change-revertlink": "võta tagasi",
+       "logentry-contentmodel-change-revert": "tagasi võetud",
        "protectlogpage": "Kaitsmislogi",
        "protectlogtext": "Allpool on loetletud lehekülgede kaitsetasemete muutmised. Praegu kaitstud lehekülgi vaata [[Special:ProtectedPages|kaitstud lehtede loetelust]].",
        "protectedarticle": "kaitses lehekülje \"[[$1]]\"",
        "tooltip-pt-logout": "Logi välja",
        "tooltip-pt-createaccount": "See pole küll kohustuslik, aga sul tasub konto luua ja sisse logida.",
        "tooltip-ca-talk": "Arutelu selle lehekülje sisu kohta",
-       "tooltip-ca-edit": "Sa saad seda lehekülge muuta. Palun kasuta enne salvestamist eelvaadet.",
+       "tooltip-ca-edit": "Muuda seda lehekülge",
        "tooltip-ca-addsection": "Lisa uus alaosa",
        "tooltip-ca-viewsource": "See lehekülg on kaitstud.\nSaad vaadata selle lähteteksti.",
        "tooltip-ca-history": "Selle lehekülje varasemad redaktsioonid",
        "pageinfo-robot-index": "Lubatud",
        "pageinfo-robot-noindex": "Keelatud",
        "pageinfo-watchers": "Lehekülje jälgijate arv",
+       "pageinfo-visiting-watchers": "Viimaseid muudatusi külastanud jälgijate arv",
        "pageinfo-few-watchers": "Alla {{PLURAL:$1|ühe jälgija|$1 jälgija}}",
+       "pageinfo-few-visiting-watchers": "Pole kindel, kas jälgijatest keegi külastab viimaseid muudatusi.",
        "pageinfo-redirects-name": "Sellele leheküljele suunatud lehekülgi",
        "pageinfo-subpages-name": "Selle lehekülje alamlehekülgi",
        "pageinfo-subpages-value": "$1 ($2 {{PLURAL:$2|ümbersuunamine|ümbersuunamist}}; $3 {{PLURAL:$3|mitteümbersuunamine|mitteümbersuunamist}})",
        "htmlform-cloner-create": "Lisa veel",
        "htmlform-cloner-delete": "Eemalda",
        "htmlform-cloner-required": "Vähemalt üks väärtus on nõutav.",
+       "htmlform-title-badnamespace": "[[:$1]] pole nimeruumis \"{{ns:$2}}\".",
+       "htmlform-title-not-creatable": "Pealkirja \"$1\" all ei saa lehekülge alustada.",
+       "htmlform-title-not-exists": "Lehekülge [[:$1]] pole olemas.",
+       "htmlform-user-not-exists": "Kasutajat <strong>$1</strong> pole olemas.",
+       "htmlform-user-not-valid": "<strong>$1</strong> pole sobiv kasutajanimi.",
        "sqlite-has-fts": "$1 koos täistekstiotsingu toega",
        "sqlite-no-fts": "$1 ilma täistekstiotsingu toeta",
        "logentry-delete-delete": "$1 {{GENDER:$2|kustutas}} lehekülje $3",
index aafc46d..4e6da13 100644 (file)
        "emailccsubject": "Zure mezuaren kopia $1(r)i: $2",
        "emailsent": "Mezua bidali egin da",
        "emailsenttext": "Zure e-posta mezua bidali egin da.",
-       "emailuserfooter": "E-posta hau $1(e)k bidali dio $2(r)i {{SITENAME}}ko \"E-posta bidali\" funtzioa erabiliz.",
+       "emailuserfooter": "E-posta hau $1(e)k bidali dio $2(r)i {{SITENAME}}ko \"{{int:emailpage}}\" funtzioa erabiliz.",
        "usermessage-summary": "Sistema mezua uzten.",
        "usermessage-editor": "Sistemako mezularia",
        "watchlist": "Jarraipen zerrenda",
        "feedback-bugnew": "Txekeatu dut. Bug berria bidaliko",
        "feedback-cancel": "Utzi",
        "feedback-close": "Egina",
+       "feedback-error-title": "Errorea",
        "feedback-error1": "Akatsa: APIaren emaitza ez ezagunak",
        "feedback-error2": "Akatsa: Aldaketa ez da egin",
        "feedback-error3": "Akatsa: APIaren erantzunik gabe",
        "feedback-message": "Mezua:",
        "feedback-subject": "Gaia:",
        "feedback-submit": "Bidali",
+       "feedback-thanks-title": "Eskerrik asko!",
        "searchsuggest-search": "Bilatu",
        "searchsuggest-containing": "edukian...",
        "api-error-badaccess-groups": "Ez duzu baimendik fitxategi hauek wiki honetara igotzeko.",
index 9967cff..5afd8b3 100644 (file)
        "htmlform-title-badnamespace": "[[:$1]] در فضای نام \"{{ns:$2}}\"  موجود نیست.",
        "htmlform-title-not-creatable": "\"$1\" عنوان قابل ایجاد نیست",
        "htmlform-title-not-exists": "[[:$1]] وجود ندارد.",
+       "htmlform-user-not-exists": "<strong>$1</strong> وجود ندارد.",
+       "htmlform-user-not-valid": "حساب کاربری <strong>$1</strong> معتبر نیست.",
        "sqlite-has-fts": "$1 با پشتیبانی از جستجو در متن کامل",
        "sqlite-no-fts": "$1 بدون پشتیبانی از جستجو در متن کامل",
        "logentry-delete-delete": "$1 صفحهٔ $3 را {{GENDER:$2|حذف کرد}}",
index cb91030..cc8537a 100644 (file)
        "searchrelated": "samankaltainen",
        "searchall": "kaikki",
        "showingresults": "Alla on vain {{PLURAL:$1|<strong>1</strong> hakutulos|<strong>$1</strong> hakutulosta}} alkaen tuloksesta nro <strong>$2</strong>.",
-       "showingresultsinrange": "Alla näytetään {{PLURAL:$1|<strong>1</strong> tulos|<strong>$1</strong> tulosta}} väliltä <strong>$2</strong> – <strong>$3</strong>.",
+       "showingresultsinrange": "Alla näytetään {{PLURAL:$1|<strong>1</strong> tulos|<strong>$1</strong> tulosta}} väliltä <strong>$2</strong><strong>$3</strong>.",
        "search-showingresults": "{{PLURAL:$4|Tulos <strong>$1</strong> enimmäismäärästä <strong>$3</strong>|Tulokset <strong>$1 – $2</strong> enimmäismäärästä <strong>$3</strong>}}",
        "search-nonefound": "Hakusi ei tuottanut tulosta.",
        "powersearch-legend": "Laajennettu haku",
        "changecontentmodel-nodirectediting": "Sisältömalli $1 ei tue suoraa muokkaamista",
        "log-name-contentmodel": "Sisältömallin muutosloki",
        "log-description-contentmodel": "Tapahtumat, jotka liittyvät sivun sisältömalleihin",
+       "logentry-contentmodel-change": "$1 {{GENDER:$2|muutti}} sivun $3 sisältömallia muodosta \"$4\" muotoon \"$5\"",
        "logentry-contentmodel-change-revertlink": "kumoa",
        "logentry-contentmodel-change-revert": "kumottu",
        "protectlogpage": "Suojausloki",
index 239aa3a..d6ab4d8 100644 (file)
        "htmlform-title-badnamespace": "[[:$1]] n'est pas dans l'espace de noms \"{{ns:$2}}\" .",
        "htmlform-title-not-creatable": "\"$1\" n'est pas un titre de page réalisable",
        "htmlform-title-not-exists": "[[:$1]] n’existe pas",
+       "htmlform-user-not-exists": "<strong>$1</strong> n’existe pas.",
+       "htmlform-user-not-valid": "<strong>$1</strong> n’est pas un nom d’utilisateur valide.",
        "sqlite-has-fts": "$1 avec recherche en texte intégral supportée",
        "sqlite-no-fts": "$1 sans recherche en texte intégral supportée",
        "logentry-delete-delete": "$1 {{GENDER:$2|a supprimé}} la page $3",
index 3533043..eb78841 100644 (file)
        "dellogpage": "काडून उडयिल्ल्यांची वळेरी",
        "rollbacklink": "फाटीं घेयात",
        "rollbacklinkcount": "$1 {{PLURAL:$1|संपादन}} फाटीं घेयात",
+       "changecontentmodel-title-label": "पानाचो माथाळो",
+       "changecontentmodel-reason-label": "Reason:कारण",
        "protectlogpage": "सुरक्षितेचें सोत्र",
        "protectedarticle": "राखिल्ले\"[[$1]]\"",
        "restriction-edit": "संस्करण",
        "specialpages": "खाशेलीं पानां",
        "tag-filter": "[[Special:Tags|कुर्वेचीट]] गाळणो:",
        "tag-list-wrapper": "([[Special:Tags|{{PLURAL:$1|कुरवेचीट|कुरवेचीटी}}]]: $2)",
+       "htmlform-title-not-exists": "[[:$1]] अस्तित्वांत ना.",
        "logentry-delete-delete": "$1 {{GENDER:$2|काडून उडयल्ले पान}} $3",
        "logentry-move-move": "$1 न $3 पानाचेर $4 {{GENDER:$2|हालयला}}",
        "logentry-newusers-create": "उपयोगकत्याचें $1 {{GENDER:$2|तयार केलें}}",
index 656f423..1093f27 100644 (file)
        "htmlform-title-badnamespace": "[[:$1]] אינו במרחב השם \"{{ns:$2}}\".",
        "htmlform-title-not-creatable": "\"$1\" אינו שם של דף שאפשר ליצור",
        "htmlform-title-not-exists": "[[:$1]] אינו קיים.",
+       "htmlform-user-not-exists": "<strong>$1</strong> אינו קיים.",
+       "htmlform-user-not-valid": "<strong>$1</strong> אינו שם משתמש תקין.",
        "sqlite-has-fts": "$1 עם תמיכה בחיפוש בטקסט מלא",
        "sqlite-no-fts": "$1 ללא תמיכה בחיפוש בטקסט מלא",
        "logentry-delete-delete": "$1 {{GENDER:$2|מחק|מחקה}} את הדף $3&rlm;",
index 3548dad..bb5dc9b 100644 (file)
        "disclaimers": "Ազատում պատասխանատվությունից",
        "disclaimerpage": "Project:Ազատում պատասխանատվությունից",
        "edithelp": "Խմբագրման ուղեցույց",
+       "helppage-top-gethelp": "Օգնություն",
        "mainpage": "Գլխավոր էջ",
        "mainpage-description": "Գլխավոր էջ",
        "policy-url": "Project:Կանոնակարգ",
        "showhideselectedversions": "Ցուցադրել/թաքցնել ընտրված խմբագրումները",
        "editundo": "հետ շրջել",
        "diff-empty": "(Տարբերություն չկա)",
+       "diff-multi-sameuser": "(Միևնույն մասնակցի {{PLURAL:$1|մեկ միջանկյալ տարբերակ|$1 միջանկյալ տարբերակներ}} թաքցրված է)",
        "searchresults": "Որոնման արդյունքներ",
        "searchresults-title": "«$1»-ի որոնման արդյունքներ",
        "titlematches": "Համընկած հոդվածների անվանումներ",
        "right-suppressredirect": "Էջը վերանավանելիս վերահղում չթողնել",
        "right-upload": "Նիշքերի բեռնում",
        "right-upload_by_url": "Բեռնել նիշքեր ինտերնետային հասցեից",
+       "right-writeapi": "API գրի օգտագործումը",
        "right-delete": "Էջերի ջնջում",
        "right-rollback": "Արագ հետ գլորել տվյալ էջը վերջին անգամ խմբագրած մասնակցի խմբագրումները",
        "newuserlogpage": "Մասնակիցների գրանցման տեղեկամատյան",
        "logentry-newusers-newusers": "$1 մասնակիցը ստեղծեց նոր հաշիվ",
        "logentry-newusers-create": "Ստեղծվեց $1 մասնակցի հաշիվ",
        "logentry-newusers-create2": "$1 Ստեղծեց նոր հաշիվ $3",
+       "logentry-upload-upload": "$1 {{GENDER:$2|ներբեռնել է}} $3",
        "rightsnone": "(ոչ մի)",
        "feedback-cancel": "Բեկանել",
        "feedback-close": "Արված է",
index e67d664..f16d239 100644 (file)
@@ -85,7 +85,8 @@
                        "TecnoMaster",
                        "Alexmar983",
                        "Federico Mugnaini",
-                       "Fpugliajno"
+                       "Fpugliajno",
+                       "Fringio"
                ]
        },
        "tog-underline": "Sottolinea i collegamenti:",
        "protectedinterface": "Questa pagina contiene un elemento che fa parte dell'interfaccia utente del software di questo sito ed è protetta per evitare possibili abusi.\nPer aggiungere o modificare le traduzioni valide su tutti i wiki, usa [//translatewiki.net/ translatewiki.net], il progetto di localizzazione di MediaWiki.",
        "editinginterface": "<strong>Attenzione:</strong> il testo di questa pagina fa parte dell'interfaccia utente del software di questo sito. Tutte le modifiche apportate a questa pagina si riflettono sui messaggi visualizzati per tutti gli utenti su questo wiki.",
        "translateinterface": "Per aggiungere o modificare le traduzioni valide su tutti i wiki, usa [//translatewiki.net/ translatewiki.net], il progetto MediaWiki per la localizzazione.",
-       "cascadeprotected": "Su questa pagina non è possibile effettuare modifiche perché è stata inclusa {{PLURAL:$1|nella pagina indicata di seguito, che è stata protetta|nelle pagine indicate di seguito, che sono state protette}} selezionando la protezione \"ricorsiva\":\n$2",
+       "cascadeprotected": "Su questa pagina non è possibile effettuare modifiche perché è inclusa {{PLURAL:$1|nella pagina indicata di seguito, che è stata protetta|nelle pagine indicate di seguito, che sono state protette}} selezionando la protezione \"ricorsiva\":\n$2",
        "namespaceprotected": "Non si dispone dei permessi necessari per modificare le pagine del namespace '''$1'''.",
        "customcssprotected": "Non si dispone dei permessi necessari alla modifica di questa pagina CSS, in quanto contiene le impostazioni personali di un altro utente.",
        "customjsprotected": "Non si dispone dei permessi necessari alla modifica di questa pagina JavaScript, in quanto contiene le impostazioni personali di un altro utente.",
        "readonlywarning": "<strong>ATTENZIONE</strong>: il database è bloccato per manutenzione, non è momentaneamente possibile salvare le modifiche effettuate.\nPer non perderle, copiale in un file di testo e salvalo in attesa dello sblocco del database.\n\nL'amministratore che impostato il blocco ha fornito questa spiegazione: $1.",
        "protectedpagewarning": "'''Attenzione: questa pagina è stata bloccata in modo che solo gli utenti con privilegi di amministratore possano modificarla.'''\nL'ultimo elemento del registro è riportato di seguito per informazione:",
        "semiprotectedpagewarning": "'''Nota:''' Questa pagina è stata bloccata in modo che solo gli utenti registrati possano modificarla.\nL'ultimo elemento del registro è riportato di seguito per informazione:",
-       "cascadeprotectedwarning": "'''Attenzione:''' Questa pagina è stata bloccata in modo che solo gli utenti con privilegi di amministratore possano modificarla. Ciò avviene perché la pagina è inclusa {{PLURAL:$1|nella pagina indicata di seguito, che è stata protetta|nelle pagine indicate di seguito, che sono state protette}} selezionando la protezione \"ricorsiva\":",
+       "cascadeprotectedwarning": "<strong>Attenzione:</strong> Questa pagina è stata bloccata in modo che solo gli utenti con privilegi di amministratore possano modificarla poiché è inclusa selezionando la protezione \"ricorsiva\" {{PLURAL:$1|nella pagina|nelle pagine}}:",
        "titleprotectedwarning": "'''Attenzione: questa pagina è stata bloccata in modo che siano necessari [[Special:ListGroupRights|diritti specifici]] per crearla.'''\nL'ultimo elemento del registro è riportato di seguito per informazione:",
        "templatesused": "{{PLURAL:$1|Template utilizzato|Template utilizzati}} in questa pagina:",
        "templatesusedpreview": "{{PLURAL:$1|Template utilizzato|Template utilizzati}} in questa anteprima:",
        "uploaded-href-attribute-svg": "Attributi href <code>&lt;$1 $2=\"$3\"&gt;</code> com un bersaglio non locale (e.g. http://, javascript:, etc) non sono permessi file SGV",
        "uploaded-href-unsafe-target-svg": "Trovati href ad un bersaglio non sicuro <code>&lt;$1 $2=\"$3\"&gt;</code> caricato nel file SVG",
        "uploaded-animate-svg": "Trovato il tag \"animate\" che potrebbe cambiare href, usando l'attributo \"from\" <code>&lt;$1 $2=\"$3\"&gt;</code> nel file SVG caricato.",
+       "uploaded-setting-href-svg": "Utilizzare il tag \"set\" per aggiungere l'attributo \"href\" all'elemento parentale è bloccato.",
        "uploaded-image-filter-svg": "Trovato filtro immagine con URL: <code>&lt;$1 $2=\"$3\"&gt;</code> nel file in formato SVG caricato.",
        "uploadscriptednamespace": "Questo file SVG contiene un namespace '$1' non consentito",
        "uploadinvalidxml": "Il codice XML nel file caricato non può essere elaborato.",
        "changecontentmodel-success-title": "Il modello di contenuto è stato modificato",
        "changecontentmodel-success-text": "Il tipo di contenuto di [[:$1]] è stato modificato.",
        "changecontentmodel-cannot-convert": "Il contenuto di [[:$1]] non può essere convertito in tipo $2.",
+       "changecontentmodel-title-cantexist": "Non è possibile avere una pagina in $1.",
+       "changecontentmodel-nodirectediting": "Il modello di contenuto $1 non supporta la modifica diretta",
+       "log-name-contentmodel": "Registro delle modifiche del modello contenuti",
        "log-description-contentmodel": "Eventi relativi al modello di contenuto di una pagina",
        "logentry-contentmodel-change": "$1 {{GENDER:$2|ha modificato}} il modello di contenuto della pagina $3 da \"$4\" a \"$5\"",
        "logentry-contentmodel-change-revertlink": "ripristina",
        "protect-locked-blocked": "Non è possibile modificare i livelli di protezione quando è attivo un blocco. Le impostazioni correnti per la pagina sono '''$1''':",
        "protect-locked-dblock": "Impossibile modificare i livelli di protezione durante un blocco del database.\nLe impostazioni correnti per la pagina sono '''$1''':",
        "protect-locked-access": "Non si dispone dei permessi necessari per modificare i livelli di protezione della pagina.\nLe impostazioni correnti per la pagina sono '''$1''':",
-       "protect-cascadeon": "Al momento questa pagina è bloccata perché viene inclusa {{PLURAL:$1|nella pagina indicata di seguito, per la quale|nelle pagine indicate di seguito, per le quali}} è attiva la protezione ricorsiva.\nLe modifiche al livello di protezione individuale della pagina, non avranno effetto sulle impostazioni derivanti dalla protezione ricorsiva.",
+       "protect-cascadeon": "Al momento questa pagina è bloccata perché inclusa {{PLURAL:$1|nella pagina indicata di seguito, per la quale|nelle pagine indicate di seguito, per le quali}} è attiva la protezione ricorsiva.\nLe modifiche al livello di protezione individuale della pagina, non avranno effetto sulle impostazioni derivanti dalla protezione ricorsiva.",
        "protect-default": "Autorizza tutti gli utenti",
        "protect-fallback": "Consentito solo agli utenti con permesso \"$1\"",
        "protect-level-autoconfirmed": "Consentito solo agli utenti autoconvalidati",
        "pageinfo-robot-index": "Consentito",
        "pageinfo-robot-noindex": "Non consentito",
        "pageinfo-watchers": "Numero di utenti che hanno la pagina nei loro osservati speciali",
+       "pageinfo-visiting-watchers": "Numero degli osservatori della pagina che hanno visitato le modifiche recenti",
        "pageinfo-few-watchers": "Meno di $1 {{PLURAL:$1|osservatore|osservatori}}",
+       "pageinfo-few-visiting-watchers": "Ci potrebbero essere o non essere utenti che hanno visualizzato le modifiche recenti",
        "pageinfo-redirects-name": "Numero di redirect a questa pagina",
        "pageinfo-subpages-name": "Sottopagine di questa pagina",
        "pageinfo-subpages-value": "$1 ($2 {{PLURAL:$2|redirect}}; $3 {{PLURAL:$3|non redirect}})",
        "htmlform-cloner-create": "Aggiungi altro",
        "htmlform-cloner-delete": "Rimuovi",
        "htmlform-cloner-required": "È necessario almeno un valore.",
+       "htmlform-title-badnamespace": "[[:$1]] non si trova nel namespace \"{{ns:$2}}\".",
+       "htmlform-title-not-creatable": "\"$1\" è il titolo di una pagina non creabile",
+       "htmlform-title-not-exists": "[[:$1]] non esiste.",
        "sqlite-has-fts": "$1 con la possibilità di ricerca completa nel testo",
        "sqlite-no-fts": "$1 senza la possibilità di ricerca completa nel testo",
        "logentry-delete-delete": "$1 {{GENDER:$2|ha cancellato}} la pagina $3",
index 9fa4ece..55188ea 100644 (file)
        "htmlform-cloner-delete": "除去",
        "htmlform-cloner-required": "少なくとも 1 つの値が必要です。",
        "htmlform-title-badnamespace": "[[:$1]]は、\"{{ns:$2}}\"名前空間にありません。",
-       "htmlform-title-not-creatable": "\"$1\" は、作成可能なページタイトルでは、ありません。",
+       "htmlform-title-not-creatable": "\"$1\" は、作成可能なページでは、ありません。",
        "htmlform-title-not-exists": "[[:$1]] は存在しません。",
        "sqlite-has-fts": "$1 (全文検索あり)",
        "sqlite-no-fts": "$1 (全文検索なし)",
        "log-description-managetags": "このページは[[Special:Tags|タグ]]に関係する管理タスクをリストアップしています。ログには管理者によって手動で実行された操作の記録しか記載されていません。ウィキ・ソフトウェアによって、ログを残さずにタグが作成・削除されている場合があります。",
        "logentry-managetags-create": "$1 がタグ「$4」を{{GENDER:$2|作成しました}}",
        "logentry-managetags-delete": "$1 がタグ \"$4\" を{{GENDER:$2|削除しました}}  ( $5 {{PLURAL:$5|版 または 記録項目|版 および/または 記録項目}} からの除去)",
-       "logentry-managetags-activate": "$1 ã\81\8cã\82¿ã\82° \"$4\" ã\82\92{{GENDER:$2|ã\82¢ã\82¯ã\83\81ã\81¹ã\83¼ã\83\88ã\81\97ã\81¾ã\81\97ã\81\9f}}ã\80\82å\88©ç\94¨è\80\85ã\81\8aã\82\88ã\81³ã\83\9cã\83\83ã\83\88ã\81®ä½¿ç\94¨ã\81®ã\81\9fã\82\81ã\81§ã\81\99。",
-       "logentry-managetags-deactivate": "$1 ã\81\8cã\82¿ã\82° \"$4\" ã\82\92{{GENDER:$2|ã\82¢ã\82¯ã\83\81ã\81¹ã\83¼ã\83\88ã\81\97ã\81¾ã\81\97ã\81\9f}}ã\80\82å\88©ç\94¨è\80\85ã\81\8aã\82\88ã\81³ã\83\9cã\83\83ã\83\88ã\81®ä½¿ç\94¨ã\81®ã\81\9fã\82\81ã\81§ã\81\99。",
+       "logentry-managetags-activate": "$1 ã\81\8cã\82¿ã\82° \"$4\" ã\81®å\88©ç\94¨è\80\85ã\81\8aã\82\88ã\81³ã\83\9cã\83\83ã\83\88ã\81«ã\82\88ã\82\8b使ç\94¨ã\82\92{{GENDER:$2|æ\9c\89å\8a¹å\8c\96ã\81\97ã\81¾ã\81\97ã\81\9f}}。",
+       "logentry-managetags-deactivate": "$1 ã\81\8cã\82¿ã\82° \"$4\" ã\81®å\88©ç\94¨è\80\85ã\81\8aã\82\88ã\81³ã\83\9cã\83\83ã\83\88ã\81«ã\82\88ã\82\8b使ç\94¨ã\82\92{{GENDER:$2|ç\84¡å\8a¹å\8c\96ã\81\97ã\81¾ã\81\97ã\81\9f}}。",
        "log-name-tag": "タグ記録",
        "logentry-tag-update-add-revision": "$1 がページ $3 の版 $4 に{{PLURAL:$7|タグ}} $6 を{{GENDER:$2|追加しました}}",
        "logentry-tag-update-add-logentry": "$1 がページ $3 の記録項目 $5 に{{PLURAL:$7|タグ}} $6 を{{GENDER:$2|追加しました}}",
index 8947bc3..d4d1ce9 100644 (file)
        "hiddencategories": "ಈ ಪುಟವು {{PLURAL:$1|೧ ಗುಪ್ತ ವರ್ಗಕ್ಕೆ|$1 ಗುಪ್ತ ವರ್ಗಗಳಿಗೆ}} ಸೇರಿದೆ:",
        "nocreatetext": "{{SITENAME}} ಅಲ್ಲಿ ಹೊಸ ಪುಟಗಳನ್ನು ಸೃಷ್ಟಿಸಲು ಕೆಲವು ನಿಬಂಧನೆಗಳಿವೆ.\nನೀವು ಹಿಂದಿರುಗಿ ಆಗಲೇ ಅಸ್ಥಿತ್ವದಲ್ಲಿರುವ ಪುಟವೊಂದನ್ನು ಸಂಪಾದಿಸಿ, ಅಥವ [[Special:UserLogin|ಲಾಗ್ ಇನ್ ಆಗಿ ಅಥವ ಹೊಸ ಸದಸ್ಯರಾಗಿ]].",
        "nocreate-loggedin": "ಹೊಸ ಪುಟಗಳನ್ನು ಸೃಷ್ಟಿಸಲು ನಿಮಗೆ ಅನುಮತಿ ಇಲ್ಲ.",
+       "sectioneditnotsupported-title": "ವಿಭಾಗ ಸಂಪಾದನೆಗೆ ಬೆಂಬಲವಿಲ್ಲ",
+       "sectioneditnotsupported-text": "ಈ ಪುಟದಲ್ಲಿ ವಿಭಾಗ ಸಂಪಾದನೆಗೆ ಬೆಂಬಲವಿಲ್ಲ.",
        "permissionserrors": "ಅನುಮತಿ ದೋಷ",
        "permissionserrorstext": "ನಿಮಗೆ ಅದನ್ನು ಮಾಡಲು ಅನುಮತಿ ಇಲ್ಲ, ಅದಕ್ಕೆ {{PLURAL:$1|ಕಾರಣ|ಕಾರಣಗಳು}}:",
        "permissionserrorstext-withaction": "$2 ನಿಮಗೆ ಅನುಮತಿ ಇಲ್ಲ, ಅದಕ್ಕೆ {{PLURAL:$1|ಕಾರಣ|ಕಾರಣಗಳು}}:",
        "right-suppressionlog": "ಖಾಸಗಿ ದಾಖಲೆಗಳು ವೀಕ್ಷಿಸಿ",
        "right-block": "ಬೇರೆ ಬಳಕೆದಾರರು ಸಂಪಾದಿಸದಂತೆ ನಿರ್ಬಂಧಿಸು",
        "right-blockemail": "ಬಳಕೆದಾರನು ಇ-ಅಂಚೆ ಕಳುಹಿಸುವುದನ್ನು ತಡೆಗಟ್ಟು",
+       "right-editmyoptions": "ನಿಮ್ಮ ಆದ್ಯತೆಗಳನ್ನು ಸಂಪಾದಿಸಿ",
        "right-import": "ಬೇರೆ ವಿಕಿಗಳಿಂದ ಪುಟಗಳನ್ನು ಆಮದು ಮಾಡು",
        "right-unwatchedpages": "ಪಹರೆಯಿಲ್ಲದ ಪುಟಗಳ ಪಟ್ಟಿಯನ್ನು ವೀಕ್ಷಿಸಿ",
        "right-mergehistory": "ಪುಟಗಳು ಇತಿಹಾಸದಲ್ಲಿ ವಿಲೀನಗೊಳಿಸಿ",
        "action-createpage": "ಪುಟಗಳನ್ನು ಸೃಷ್ಟಿಸು",
        "action-createtalk": "ಚರ್ಚಾ ಪುಟಗಳನ್ನು ಸೃಷ್ಟಿಸು",
        "action-createaccount": "ಈ ಬಳಕೆದಾರ ಖಾತೆಯನ್ನು ರಚಿಸಿ",
+       "action-history": "ಈ ಪುಟದ ಇತಿಹಾಸವನ್ನು ವೀಕ್ಷಿಸಿ",
        "action-minoredit": "ಈ ತಿದ್ದುಪಡಿಯನ್ನು ಚಿಕ್ಕದೆಂದು ಗುರುತಿಸಿ",
        "action-move": "ಈ ಪುಟವನ್ನು ಸ್ಥಳಾಂತರಿಸಿ",
        "action-move-subpages": "ಈ ಪುಟವನ್ನು ಮತ್ತು ಅದರ ಉಪಪುಟಗಳನ್ನು ಸ್ಥಳಾಂತರಿಸಿ",
        "license": "ಪರವಾನಗಿ:",
        "license-header": "ಪರವಾನಗಿ",
        "nolicense": "ಆಯ್ಕೆ ಇಲ್ಲ",
+       "licenses-edit": "ಪರವಾನಗಿ ಆಯ್ಕೆಗಳನ್ನು ಸಂಪಾದಿಸಿ",
        "license-nopreview": "(ಪೂರ್ವವೀಕ್ಷಣೆ ಲಭ್ಯವಿಲ್ಲ)",
        "upload_source_url": " (ಒಂದು ಮನ್ನಿತ, ಸಾರ್ವಜನಿಕವಾಗಿ ಎಟಕುವ URL)",
        "upload_source_file": " (ನಿಮ್ಮ ಗಣಕಯಂತ್ರದಲ್ಲಿರುವ ಒಂದು ಫೈಲು)",
        "listgrouprights-helppage": "Help:ಗುಂಪು ಹಕ್ಕುಗಳು",
        "listgrouprights-members": "(ಸದಸ್ಯರ ಪಟ್ಟಿ)",
        "listgrouprights-addgroup-all": "ಎಲ್ಲಾ ಗುಂಪುಗಳನ್ನು ಸೇರಿಸಿ",
+       "listgrouprights-removegroup-all": "ಎಲ್ಲಾ ಗುಂಪುಗಳನ್ನು ತೆಗೆದುಹಾಕಿ",
        "listgrouprights-namespaceprotection-namespace": "ನಾಮವರ್ಗ",
        "trackingcategories-name": "ಸಂದೇಶದ ಹೆಸರು",
        "trackingcategories-nodesc": "ಯಾವುದೇ ವಿವರಣೆಯಿಲ್ಲ.",
        "deletereason-dropdown": "*ಸಾಮಾನ್ಯ ಅಳಿಸುವಿಕೆಯ ಕಾರಣಗಳು\n** ಸಂಪಾದಕರ ಕೋರಿಕೆ\n** ಕೃತಿಸ್ವಾಮ್ಯತೆಯ ಉಲ್ಲಂಘನೆ\n** Vandalism",
        "delete-edit-reasonlist": "ಅಳಿಸುವಿಕೆ ಕಾರಣಗಳನ್ನು ಸಂಪಾದಿಸು",
        "rollbacklink": "ತೊಡೆದುಹಾಕು",
+       "changecontentmodel": "ಪುಟದ ವಿಷಯ ಮಾದರಿಯನ್ನು ಬದಲಾಯಿಸಿ",
+       "changecontentmodel-legend": "ವಿಷಯ ಮಾದರಿಯನ್ನು ಬದಲಾಯಿಸಿ",
        "changecontentmodel-title-label": "ಪುಟ ಶೀರ್ಷಿಕೆ",
+       "changecontentmodel-model-label": "ಹೊಸ ವಿಷಯ ಮಾದರಿ",
        "changecontentmodel-reason-label": "ಕಾರಣ:",
+       "changecontentmodel-success-title": "ವಿಷಯ ಮಾದರಿಯನ್ನು ಬದಲಾಯಿಸಲಾಗಿದೆ",
        "logentry-contentmodel-change-revertlink": "ಹಿಂದಿನಂತಾಗಿಸು",
        "logentry-contentmodel-change-revert": "ಹಿಂದಿನಂತಾಗಿಸು",
        "protectlogpage": "ಸಂರಕ್ಷಣೆ ದಿನಚರಿ",
        "htmlform-selectorother-other": "ಇತರ",
        "htmlform-no": "ಇಲ್ಲ",
        "htmlform-yes": "ಹೌದು",
+       "htmlform-title-not-exists": "[[:$1]] ಅಸ್ತಿತ್ವದಲ್ಲಿಲ್ಲ.",
        "logentry-delete-delete": "$1 {{GENDER:$2|ಅಳಿಸಲಾಯಿತು}} ಪುಟ $3",
        "revdelete-restricted": "ನಿರ್ವಾಹಕರಿಗೆ ನಿಬಂಧನೆಗಳನ್ನು ಅನ್ವಯಿಸಲಾಯಿತು",
        "revdelete-unrestricted": "ನಿರ್ವಾಹಕರ ನಿಬಂಧನೆಗಳನ್ನು ತೆಗೆಯಲಾಯಿತು",
index d2fb581..ebb128f 100644 (file)
        "htmlform-cloner-required": "Mindestens ee Wäert ass obligatoresch.",
        "htmlform-title-badnamespace": "[[:$1]] ass net am Nummraum \"{{ns:$2}}\".",
        "htmlform-title-not-exists": "[[:$1]] gëtt et net.",
+       "htmlform-user-not-exists": "<strong>$1</strong> gëtt et net.",
+       "htmlform-user-not-valid": "<strong>$1</strong> ass kee valabele Benotzernumm.",
        "sqlite-has-fts": "$1 ënnerstëtzt d'Volltextsich",
        "sqlite-no-fts": "$1 ënnerstëtzt d'Volltextsich net",
        "logentry-delete-delete": "$1 {{GENDER:$2|huet}} d'Säit $3 geläscht",
index a11fbb5..5a10de5 100644 (file)
        "protectedinterface": "Šiame puslapyje yra apsaugotas nuo piktnaudžiavimo programinės įrangos sąsajos tekstas. Norėdami pridėti ar pakeisti vertimus visose wiki, naudokite [//translatewiki.net/ translatewiki.net] MediaWiki vertimų projektą.",
        "editinginterface": "'''Dėmesio:''' Jūs redaguojate puslapį, kuris yra naudojamas programinės įrangos sąsajos tekste. Pakeitimai šiame puslapyje taip pat pakeis naudotojo sąsajos išvaizdą ir kitiems naudotojams šiame wiki.",
        "translateinterface": "Kad pridėtumėte vertimus visoms wiki, naudokitės  [//translatewiki.net/ translatewiki.net] – projektu, skirtu MediaWiki vertimams į vietines kalbas.",
-       "cascadeprotected": "Šis puslapis buvo apsaugotas nuo redagavimo, kadangi jis yra įtrauktas į {{PLURAL:$1|šį puslapį, apsaugotą|šiuos puslapius, apsaugotus}} „pakopinės apsaugos“ pasirinktimi:\n$2",
+       "cascadeprotected": "Šis puslapis buvo apsaugotas nuo redagavimo, kadangi jis yra įtrauktas į {{PLURAL:$1|šį puslapį, kuris yra apsaugotas|šiuos puslapius, kurie yra apsaugoti}} su „pakopinės apsaugos“ parinktimi:\n$2",
        "namespaceprotected": "Jūs neturite teisės redaguoti puslapių '''$1''' srityje.",
        "customcssprotected": "Jūs neturite teisės keisti šį CSS puslapį, nes jame yra kito naudotojo asmeniniai nustatymai.",
        "customjsprotected": "Jūs neturite teisės keisti šį JavaScript puslapį, nes jame yra kito naudotojo asmeniniai nustatymai.",
        "creating": "Kuriama $1",
        "editingsection": "Taisomas $1 (skyrelis)",
        "editingcomment": "Taisomas $1 (naujas skyrius)",
-       "editconflict": "Jūsų pakeitimai negali būti įrašyti dėl redagavimo konflikto. Ar norite išspręsti konfliktą rankiniu būdu?",
+       "editconflict": "Redaguoti konfliktą: $1",
        "explainconflict": "Kažkas kitas jau pakeitė puslapį nuo tada, kai jūs pradėjote jį redaguoti.\nViršutiniame tekstiniame lauke pateikta šiuo metu esanti puslapio versija.\nJūsų keitimai pateikti žemiau esančiame lauke.\nJums reikia sujungti jūsų pakeitimus su esančia versija.\nKai paspausite „{{int:savearticle}}“, bus įrašytas '''tik''' tekstas viršutiniame tekstiniame lauke.",
        "yourtext": "Jūsų tekstas",
        "storedversion": "Išsaugota versija",
        "readonlywarning": "'''Įspėjimas: Duomenų bazė buvo užrakinta techninei profilaktikai, todėl šiuo metu negalėsite išsaugoti savo pakeitimų. Siūlome nusikopijuoti tekstą į tekstinį failą ir vėliau jį čia išsaugoti.'''\n\nJą užrakinusio administratoriaus paaiškinimas: $1",
        "protectedpagewarning": "'''Dėmesio: Šis puslapis yra užrakintas taip, kad jį redaguoti gali tik administratoriaus teises turintys naudotojai.'''\nNaujausias įrašas žurnale yra pateiktas žemiau:",
        "semiprotectedpagewarning": "'''Pastaba:''' Šis puslapis buvo užrakintas, jį gali redaguoti tik registruoti naudotojai.\nNaujausias įrašas žurnale yra pateiktas žemiau:",
-       "cascadeprotectedwarning": "'''Dėmesio''': Šis puslapis buvo užrakintas taip, kad tik naudotojai su administratoriaus teisėmis galėtų jį redaguoti, nes jis yra įtrauktas į {{PLURAL:$1|šį puslapį, apsaugotą|šiuos puslapius, apsaugotus}} „pakopinės apsaugos“ pasirinktimi:",
+       "cascadeprotectedwarning": "<strong>Dėmesio:</strong> Šis puslapis buvo užrakintas taip, kad tik naudotojai su administratoriaus teisėmis galėtų jį redaguoti, nes jis yra įtrauktas į {{PLURAL:$1|šį puslapį, apsaugotą|šiuos puslapius, apsaugotus}} „pakopinės apsaugos“ pasirinktimi:",
        "titleprotectedwarning": "'''Dėmesio: Šis puslapis buvo užrakintas taip, kad tik [[Special:ListGroupRights|kai kurie naudotojai]] galėtų jį sukurti.'''\nNaujausias įrašas žurnale yra pateiktas žemiau:",
        "templatesused": "{{PLURAL:$1|Šablonas|Šablonai}}, naudojami puslapyje:",
        "templatesusedpreview": "{{PLURAL:$1|Šablonas|Šablonai}}, naudoti šioje peržiūroje:",
        "changecontentmodel-nodirectediting": "$1 turinio modelis nepalaiko tiesioginio redagavimo",
        "log-name-contentmodel": "Turinio modelio kaitos istorija",
        "log-description-contentmodel": "Įvykiai susiję su puslapio turinio modeliu",
-       "logentry-contentmodel-change": "$1 atnaujino puslapio $3 turinio modelį iš $4 į $5",
+       "logentry-contentmodel-change": "$1 {{GENDER:$2|atnaujino}} puslapio $3 turinio modelį iš $4 į $5",
        "logentry-contentmodel-change-revertlink": "atšaukti",
        "logentry-contentmodel-change-revert": "atšaukti",
        "protectlogpage": "Rakinimų sąrašas",
        "protect-locked-blocked": "Jūs negalite keisti apsaugos lygių, kol esate užbluokuotas.\nČia yra dabartiniai nustatymai puslapiui '''$1''':",
        "protect-locked-dblock": "Apsaugos lygiai negali būti pakeisti dėl duomenų bazės užrakinimo.\nČia yra dabartiniai nustatymai puslapiui '''$1''':",
        "protect-locked-access": "Jūsų paskyra neturi teisių keisti puslapių apsaugos lygių.\nČia yra dabartiniai nustatymai puslapiui '''$1''':",
-       "protect-cascadeon": "Šis puslapis dabar yra apsaugotas, nes jis yra įtrauktas į {{PLURAL:$1|šį puslapį, apsaugotą|šiuos puslapius, apsaugotus}} „pakopinės apsaugos“ pasirinktimi. Jūs galite pakeisti šio puslapio apsaugos lygį, bet tai nepaveiks pakopinės apsaugos.",
+       "protect-cascadeon": "Šis puslapis dabar yra apsaugotas, nes jis yra įtrauktas į {{PLURAL:$1|šį puslapį, apsaugotą|šiuos puslapius, apsaugotus}} „pakopinės apsaugos“ parinktimi.\nPuslapio apsaugos lygių pakeitimai neturės poveikio pakopinei apsaugai.",
        "protect-default": "Leisti visiems naudotojams",
        "protect-fallback": "Reikalauti „$1“ teisės",
        "protect-level-autoconfirmed": "Blokuoti naujai prisiregistravusius ir neregistruotus naudotojus",
        "pageinfo-robot-index": "Leidžiama",
        "pageinfo-robot-noindex": "Neleidžiama",
        "pageinfo-watchers": "Puslapio stebėtojų skaičius",
-       "pageinfo-visiting-watchers": "Skaičius puslapio stebėtojų, lankančių pastaruosius pakeitimus",
+       "pageinfo-visiting-watchers": "Skaičius puslapio stebėtojų, kurie aplankė pastaruosius pakeitimus",
        "pageinfo-few-watchers": "Mažiau nei $1 {{PLURAL:$1|stebėtojas|stebėtojų}}",
        "pageinfo-few-visiting-watchers": "Gali būti arba nebūti stebėtojų, lankančių pastaruosius pakeitimus",
        "pageinfo-redirects-name": "Nukreipimai į šį puslapį",
        "htmlform-cloner-create": "Pridėti dar",
        "htmlform-cloner-delete": "Pašalinti",
        "htmlform-cloner-required": "Bent viena reikšmė būtina.",
+       "htmlform-title-badnamespace": "[[:$1]] nėra \"{{ns:$2}}\" vardų srityje.",
+       "htmlform-title-not-creatable": "\"$1\" nėra tinkamas sukūrimui puslapio pavadinimas",
+       "htmlform-title-not-exists": "[[:$1]] neegzistuoja.",
+       "htmlform-user-not-exists": "<strong>$1</strong> neegzistuoja.",
+       "htmlform-user-not-valid": "<strong>$1</strong> nėra tinkamas naudotojo vardas.",
        "sqlite-has-fts": "$1 su visatekstės paieškos palaikymu",
        "sqlite-no-fts": "$1 be visatekstės paieškos palaikymo",
        "logentry-delete-delete": "$1 {{GENDER:$2|ištrynė}} puslapį $3",
index 07b93dc..c8dec2a 100644 (file)
        "htmlform-title-badnamespace": "[[:$1]] не се наоѓа во именскиот простор „{{ns:$2}}“.",
        "htmlform-title-not-creatable": "Насловот „$1“ не може да се создава",
        "htmlform-title-not-exists": "[[:$1]] не постои.",
+       "htmlform-user-not-exists": "<strong>$1</strong> не постои.",
+       "htmlform-user-not-valid": "<strong>$1</strong> не претставува важечко корисничко име.",
        "sqlite-has-fts": "$1 со поддршка за пребарување по цели текстови",
        "sqlite-no-fts": "$1 без поддршка за пребарување по цели текстови",
        "logentry-delete-delete": "$1 {{GENDER:$2|ја избриша}} страницата $3",
index f5373b2..ef2c4a0 100644 (file)
        "protectedinterface": "ഈ താൾ ഈ വിക്കിയുടെ സോഫ്റ്റ്‌വെയറിന്റെ സമ്പർക്കമുഖ എഴുത്തുകൾ നൽകുന്നു, അതുകൊണ്ട് ദുരുപയോഗം തടയാൻ ബന്ധിക്കപ്പെട്ടിരിക്കുന്നു. എല്ലാ വിക്കികൾക്കുമായി പരിഭാഷ കൂട്ടിച്ചേർക്കാനോ, പരിഭാഷയിൽ മാറ്റം വരുത്താനോ, ദയവായി മീഡിയവിക്കി പ്രാദേശീകരണ പദ്ധതിയായ [//translatewiki.net/ translatewiki.net] ഉപയോഗിക്കുക.",
        "editinginterface": "<strong>മുന്നറിയിപ്പ്:<strong> സോഫ്റ്റ്‌വെയറിൽ സമ്പർക്കമുഖം നിലനിർത്തുന്ന താളാണു താങ്കൾ തിരുത്തുവാൻ പോകുന്നത്.\nഈ താളിൽ താങ്കൾ വരുത്തുന്ന മാറ്റങ്ങൾ ഉപയോക്താക്കൾ വിക്കി കാണുന്ന വിധത്തെ മാറ്റിമറിച്ചേക്കാം.",
        "translateinterface": "എല്ലാ വിക്കികൾക്കും ഉപയോഗിക്കാനാവുംവിധം പരിഭാഷകൾ കൂട്ടിച്ചേർക്കാനും മാറ്റംവരുത്താനും മീഡിയവിക്കി സന്ദേശങ്ങളുടെ പ്രാദേശികവത്കരണ പദ്ധതിയായ [//translatewiki.net/ translatewiki.net] ഉപയോഗിക്കുവാൻ താല്പര്യപ്പെടുന്നു.",
-       "cascadeprotected": "നിർഝരിത (cascading) സൗകര്യം ഉപയോഗിച്ച് തിരുത്തൽ നടത്തുന്നതിനു സം‌രക്ഷണം ഏർപ്പെടുത്തിയിട്ടുള്ള {{PLURAL:$1|താഴെ കൊടുത്തിട്ടുള്ള താളിന്റെ|താഴെ കൊടുത്തിട്ടുള്ള താളുകളുടെ}} ഭാഗമാണ്‌ ഈ താൾ. അതിനാൽ ഈ താൾ തിരുത്താൻ സാധിക്കില്ല:\n$2",
+       "cascadeprotected": "\"നിർഝരിത\" (cascading) സൗകര്യം ഉപയോഗിച്ച് തിരുത്തൽ നടത്തുന്നതിനു സം‌രക്ഷണം ഏർപ്പെടുത്തിയിട്ടുള്ള {{PLURAL:$1|താഴെ കൊടുത്തിട്ടുള്ള താളിന്റെ|താഴെ കൊടുത്തിട്ടുള്ള താളുകളുടെ}} ഭാഗമാണ്‌ ഈ താൾ. അതിനാൽ ഈ താൾ തിരുത്താൻ സാധിക്കില്ല:\n$2",
        "namespaceprotected": "'''$1''' നാമമേഖലയിലുള്ള താളുകൾ തിരുത്താൻ താങ്കൾക്ക് അനുവാദമില്ല.",
        "customcssprotected": "ഈ സി.എസ്.എസ്. താളിൽ മറ്റൊരു ഉപയോക്താവിന്റെ സ്വകാര്യസജ്ജീകരണങ്ങൾ ഉൾക്കൊള്ളുന്നു, അതിനാൽ താങ്കൾക്ക് ഈ താൾ തിരുത്താൻ അനുവാദമില്ല.",
        "customjsprotected": "ഈ ജാവാസ്ക്രിപ്റ്റ് താളിൽ മറ്റൊരു ഉപയോക്താവിന്റെ സ്വകാര്യസജ്ജീകരണങ്ങൾ ഉൾക്കൊള്ളുന്നു, അതിനാൽ താങ്കൾക്ക് ഈ താൾ തിരുത്താൻ അനുവാദമില്ല.",
        "readonlywarning": "'''മുന്നറിയിപ്പ്: ഡേറ്റാബേസ് പരിപാലനത്തിനു വേണ്ടി ബന്ധിച്ചിരിക്കുന്നു, അതുകൊണ്ട് താങ്കളിപ്പോൾ വരുത്തിയ മാറ്റങ്ങൾ സേവ് ചെയ്യാൻ സാദ്ധ്യമല്ല.''' താങ്കൾ വരുത്തിയ മാറ്റങ്ങൾ ഒരു ടെക്സ്റ്റ് ഫയലിലേക്ക് പകർത്തി (കോപ്പി & പേസ്റ്റ്) പിന്നീടുപയോഗിക്കുന്നതിനായി കരുതിവക്കാൻ താല്പര്യപ്പെടുന്നു. ഡേറ്റാബേസ് ബന്ധിച്ച അഡ്മിനിസ്ട്രേറ്റർ നൽകിയ വിശദീകരണം: $1",
        "protectedpagewarning": "'''മുന്നറിയിപ്പ്:  ഈ താൾ കാര്യനിർവാഹക പദവിയുള്ളവർക്കു മാത്രം തിരുത്താൻ സാധിക്കാവുന്ന തരത്തിൽ സം‌രക്ഷിക്കപ്പെട്ടിരിക്കുന്നു.''' അവലംബമായി രേഖകളിൽ ലഭ്യമായ ഏറ്റവും പുതിയ വിവരം താഴെ നൽകിയിരിക്കുന്നു:",
        "semiprotectedpagewarning": "'''ശ്രദ്ധിക്കുക:'''അംഗത്വമെടുത്തിട്ടുള്ളവർക്കുമാത്രം തിരുത്താൻ സാധിക്കുന്ന വിധത്തിൽ ഈ താൾ സംരക്ഷിക്കപ്പെട്ടിരിക്കുന്നു. അവലംബമായി രേഖകളിലെ ഏറ്റവും പുതിയ വിവരം താഴെ കൊടുത്തിരിക്കുന്നു:",
-       "cascadeprotectedwarning": "'''മുന്നറിയിപ്പ്:''' ഈ താൾ കാര്യനിർവാഹക അവകാശമുള്ളവർക്കു മാത്രം തിരുത്തുവാൻ സാധിക്കുന്ന വിധത്തിൽ സം‌രക്ഷിക്കപ്പെട്ടിട്ടുള്ളതാണ്‌. {{PLURAL:$1|താൾ|താളുകൾ}} കാസ്കേഡ് സം‌രക്ഷണം ചെയ്തപ്പോൾ അതിന്റെ ഭാഗമായി സംരക്ഷിക്കപ്പെട്ടിട്ടുള്ളതാണ്‌ ഈ താൾ.",
+       "cascadeprotectedwarning": "<strong>മുന്നറിയിപ്പ്:</strong> ഈ താൾ കാര്യനിർവാഹക അവകാശമുള്ളവർക്കു മാത്രം തിരുത്തുവാൻ സാധിക്കുന്ന വിധത്തിൽ സം‌രക്ഷിക്കപ്പെട്ടിട്ടുള്ളതാണ്‌. ഇനിക്കൊടുക്കുന്ന {{PLURAL:$1|താൾ|താളുകൾ}} നിർഝരിത(cascade) സം‌രക്ഷണം ചെയ്തപ്പോൾ അതിന്റെ ഭാഗമായി സംരക്ഷിക്കപ്പെട്ടിട്ടുള്ളതാണ്‌ ഈ താൾ:",
        "titleprotectedwarning": "'''മുന്നറിയിപ്പ്: [[Special:ListGroupRights|പ്രത്യേക അവകാശമുള്ള]] ഉപയോക്താക്കൾക്ക് മാത്രം സൃഷ്ടിക്കാൻ സാധിക്കുന്ന വിധത്തിൽ ഈ താൾ സംരക്ഷിക്കപ്പെട്ടിരിക്കുന്നു.''' അവലംബമായി രേഖകളിൽ ലഭ്യമായ ഏറ്റവും പുതിയ വിവരം താഴെ നൽകിയിരിക്കുന്നു:",
        "templatesused": "ഈ താളിൽ ഉപയോഗിച്ചിരിക്കുന്ന {{PLURAL:$1|ഫലകം|ഫലകങ്ങൾ}}:",
        "templatesusedpreview": "ഈ പ്രിവ്യൂവിൽ ഉപയോഗിച്ചിരിക്കുന്ന {{PLURAL:$1|ഫലകം|ഫലകങ്ങൾ}}:",
        "uploaddisabledtext": "പ്രമാണം അപ്‌ലോഡ് ചെയ്യുന്നതു സാദ്ധ്യമല്ലാതാക്കിയിരിക്കുന്നു.",
        "php-uploaddisabledtext": "പി.എച്ച്.പി.യിൽ പ്രമാണ അപ്‌‌ലോഡുകൾ സാദ്ധ്യമല്ലാതാക്കിയിരിക്കുന്നു.\nദയവായി file_uploads ക്രമീകരണങ്ങൾ പരിശോധിക്കുക.",
        "uploadscripted": "ഈ പ്രമാണത്തിൽ വെബ് ബ്രൗസർ തെറ്റായി വ്യാഖ്യാനിച്ചേക്കാവുന്ന എച്ച്.റ്റി.എം.എൽ. അല്ലെങ്കിൽ സ്ക്രിപ്റ്റ് കോഡ് ഉണ്ട്.",
+       "upload-scripted-pi-callback": "എക്സ്.എം.എൽ.-സ്റ്റൈൽഷീറ്റ് പ്രോസസിങ് നിർദ്ദേശങ്ങളുള്ള പ്രമാണം അപ്‌ലോഡ് ചെയ്യാനാവില്ല.",
        "uploaded-script-svg": "അപ്‌ലോഡ് ചെയ്ത എസ്.വി.ജി. പ്രമാണത്തിൽ സ്ക്രിപ്റ്റ് ചെയ്യാവുന്ന ഭാഗമായ \"$1\" കണ്ടെത്തി.",
        "uploaded-hostile-svg": "അപ്‌ലോഡ് ചെയ്ത എസ്.വി.ജി. പ്രമാണത്തിൽ സുരക്ഷിതമല്ലാത്ത സി.എസ്.എസ്. സ്റ്റൈൽ ഭാഗം കണ്ടെത്താനായി.",
+       "uploaded-event-handler-on-svg": "എസ്.വി.ജി. പ്രമാണങ്ങളിൽ എവന്റ്-ഹാൻഡ്‌ലർ ആട്രിബ്യൂട്ടുകൾ <code>$1=\"$2\"</code>  എന്ന് സജ്ജീകരിച്ചിരിക്കുന്നവ അനുവദിച്ചിട്ടില്ല.",
+       "uploaded-href-attribute-svg": "എസ്.വി.ജി. പ്രമാണങ്ങളിൽ എച്ച്റെഫ് (href) ആട്രിബ്യൂട്ടുകൾ പ്രാദേശികമല്ലാത്ത ലക്ഷ്യങ്ങളിലേക്ക് <code>&lt;$1 $2=\"$3\"&gt;</code> എന്നുള്ളവ (ഉദാ: http://, javascript:, തുടങ്ങിയവ) അനുവദിച്ചിട്ടില്ല.",
        "uploaded-image-filter-svg": "യു.ആർ.എൽ. ഉൾപ്പെടെയുള്ള ചിത്ര അരിപ്പ : <code>&lt;$1 $2=\"$3\"&gt;</code>, അപ്‌ലോഡ് ചെയ്ത എസ്.വി.ജി. ചിത്രത്തിൽ കണ്ടെത്തി.",
        "uploadscriptednamespace": "ഈ എസ്.വി.ജി. പ്രമാണത്തിൽ ഉപയോഗിക്കാൻ പാടില്ലാത്ത നാമമേഖലയായ \"$1\" ഉണ്ട്",
        "uploadinvalidxml": "അപ്‌ലോഡ് ചെയ്ത പ്രമാണത്തിലെ എക്സ്.എം.എൽ. പാഴ്സ് ചെയ്യാൻ കഴിയില്ല.",
        "htmlform-cloner-create": "കൂടുതൽ ചേർക്കുക",
        "htmlform-cloner-delete": "നീക്കം ചെയ്യുക",
        "htmlform-cloner-required": "കുറഞ്ഞത് ഒരു വിലയെങ്കിലും നൽകിയിരിക്കണം.",
+       "htmlform-title-badnamespace": "[[:$1]] ഉള്ളത് \"{{ns:$2}}\" നാമമേഖലയിലല്ല.",
+       "htmlform-title-not-creatable": "\"$1\" സൃഷ്ടിക്കാനാവുന്ന തലക്കെട്ടല്ല.",
+       "htmlform-title-not-exists": "[[:$1]] നിലവിലില്ല.",
+       "htmlform-user-not-exists": "<strong>$1</strong> നിലവിലില്ല.",
+       "htmlform-user-not-valid": "<strong>$1</strong> സാധുതയുള്ള ഉപയോക്തൃനാമമല്ല.",
        "sqlite-has-fts": "പൂർണ്ണ-എഴുത്ത് തിരച്ചിൽ പിന്തുണയുള്ള $1",
        "sqlite-no-fts": "പൂർണ്ണ-എഴുത്ത് തിരച്ചിൽ പിന്തുണയില്ലാത്ത $1",
        "logentry-delete-delete": "$3 എന്ന താൾ $1 {{GENDER:$2|മായ്ച്ചിരിക്കുന്നു}}",
index abcdd1a..90d1f90 100644 (file)
        "htmlform-cloner-create": "Azzecca 'e cchiù",
        "htmlform-cloner-delete": "Lèva",
        "htmlform-cloner-required": "Servesse al minimo nu valore.",
+       "htmlform-title-badnamespace": "[[:$1]] nun è dint'a lu namespace \"{{ns:$2}}\".",
+       "htmlform-title-not-creatable": "\"$1\" nun è nu titolo criabbele 'e paggena",
        "htmlform-title-not-exists": "[[:$1]] nun esiste.",
+       "htmlform-user-not-exists": "<strong>$1</strong> nun esiste.",
+       "htmlform-user-not-valid": "<strong>$1</strong> nun è nu nomme buono.",
        "sqlite-has-fts": "$1 cu supporto 'e ricerche full-text",
        "sqlite-no-fts": "$1 senza supporto 'e ricerche full-text",
        "logentry-delete-delete": "$1 {{GENDER:$2|scancellaje}} 'a paggena $3",
index 6f9f927..1cf0f75 100644 (file)
        "readonlywarning": "'''Uwaga! Baza danych została zablokowana do celów administracyjnych. W tej chwili nie można zapisać nowej wersji strony. Jeśli chcesz, może skopiować ją do pliku, aby móc zapisać ją później.'''\n\nAdministrator, który zablokował bazę, podał następujące wyjaśnienie: $1",
        "protectedpagewarning": "'''Uwaga! Możliwość modyfikacji tej strony została zabezpieczona. Mogą ją edytować jedynie użytkownicy z uprawnieniami administratora.'''\nOstatni wpis z rejestru jest pokazany poniżej.",
        "semiprotectedpagewarning": "'''Uwaga!''' Ta strona została zabezpieczona i tylko zarejestrowani użytkownicy mogą ją edytować.\nOstatni wpis z rejestru jest pokazany poniżej.",
-       "cascadeprotectedwarning": "'''Uwaga!''' Ta strona została zabezpieczona i tylko użytkownicy z uprawnieniami administratora mogą ją edytować. Strona ta jest zawarta na {{PLURAL:$1|następującej stronie, która została zabezpieczona|następujących stronach, które zostały zabezpieczone}} z włączoną opcją dziedziczenia:",
+       "cascadeprotectedwarning": "<strong>Uwaga:<strong> Ta strona została zabezpieczona i tylko użytkownicy z uprawnieniami administratora mogą ją edytować. Została ona osadzona w {{PLURAL:$1|następującej stronie, która została zabezpieczona|następujących stronach, które zostały zabezpieczone}} z włączoną opcją dziedziczenia:",
        "titleprotectedwarning": "'''Uwaga! Utworzenie strony o tej nazwie zostało zabezpieczone. Do jej utworzenia wymagane są [[Special:ListGroupRights|specyficzne uprawnienia]].'''\nOstatni wpis z rejestru jest pokazany poniżej.",
        "templatesused": "{{PLURAL:$1|Szablon użyty|Szablony użyte}} w tym artykule:",
        "templatesusedpreview": "{{PLURAL:$1|Szablon użyty|Szablony użyte}} w tym podglądzie:",
        "htmlform-title-badnamespace": "[[:$1]] nie znajduje się w przestrzeni nazw „{{ns:$2}}”.",
        "htmlform-title-not-creatable": "Nie można użyć „$1” do utworzenia tytułu strony",
        "htmlform-title-not-exists": "[[:$1]] nie istnieje.",
+       "htmlform-user-not-exists": "<strong>$1</strong> nie istnieje.",
+       "htmlform-user-not-valid": "<strong>$1</strong> nie jest prawidłową nazwą użytkownika.",
        "sqlite-has-fts": "$1 z obsługą pełnotekstowego wyszukiwania",
        "sqlite-no-fts": "$1 bez obsługi pełnotekstowego wyszukiwania",
        "logentry-delete-delete": "$1 {{GENDER:$2|usunął|usunęła}} stronę $3",
index e6952c3..b207f10 100644 (file)
        "yourdiff": "Diferense",
        "copyrightwarning": "Che a ten-a për piasì da ment che tute le contribussion a {{SITENAME}} as consìdero dàite sota a na licensa ëd la sòrt $2 (che a varda $1 për avèj pì 'd detaj).\nSe a veul nen che sò test a peula esse modificà e distribuì da qualsëssìa përson-a sensa gnun-a limitassion ëd gnun-a sòrt, che a lo buta pa ambelessì.<br />\nËn mandand ës test-sì chiel as fa garant sota soa responsabilità che ël test a l'ha scrivusslo despërchiel, ò pura che a l'ha tracopialo da na sorgiss ëd pùblich domini, ò da n'àutra sorgiss dla midema sòrt.\n'''Anserì mai dël material coatà da drit d'autor sensa avèj n'autorisassion për felo!'''",
        "copyrightwarning2": "Për piasì, che a ten-a da ment che tute le contribussion a {{SITENAME}} a peulo esse modificà ò scancelà da d'àutri contributor. Se a veul nen che lòn che a scriv a ven-a modificà sensa limitassion ëd gnun-a sòrt, che a lo manda nen ambelessì.<br />\nAnt l'istess temp, ën mandand dël material un as pija la responsabilità dë dì che a l'ha scrivusslo daspërchiel, ò pura che a l'ha copialo da na sorgiss ëd domini pùblich, ò pura da 'nt n'àutra sorgiss dla midema sòrt (che a varda $1 për avèj pì d'anformassion).\n'''Che a manda pa dël material coata da drit d'autor sensa avèj avù ël përmess ëd felo!'''",
+       "editpage-cannot-use-custom-model": "Ël model ëd contnù ëd sa pàgina a peul nen esse modificà.",
        "longpageerror": "'''EROR: Ël test che a l'ha mandà a l'é longh {{PLURAL:$1|un kilobyte|$1 kilobytes}}, che a resta pì che ël lìmit màssim {{PLURAL:$2|d'un kilobyte|ëd $2 kilobyte}}.''' Parèj as peul pa salvesse.",
        "readonlywarning": "'''Avis: La base ëd dat a l'é stàita blocà për manutension, e donca a podrà pa salvesse soe modìfiche tut sùbit.'''\nA peul esse che a-j ven-a còmod copiesse via sò test e ancoless-lo an n'archivi ëd test e goernelo për pi tard.\n\nL'aministrator che a l'ha fàit ël blocagi a l'ha dàit costa spiegassion: $1",
        "protectedpagewarning": "'''Avis: costa pàgina-sì a l'é stàita protegiùa an manera che mach j'utent con la qualìfica da aministrator a peulo feje dle modìfiche.'''\nL'ùltima vos dël registr a l'é smonùa sì-sota për arferiment:",
        "semiprotectedpagewarning": "'''Nòta:''' Costa pàgina-sì a l'é stàita blocà an manera che mach j'utent registrà a peulo modifichela.\nL'ùltima vos dël registr a l'é smonùa sì-sota për arferiment:",
-       "cascadeprotectedwarning": "'''Tension:''' Sta pàgina a l'é stàita blocà an manera che mach j'utent con la qualìfica da aministrator a peulo modifichela, për via che a l'é comprèisa an {{PLURAL:$1|costa pàgina-sì|an coste pàgine-sì}} ch'a l'han ël sistema ëd protession a cascada:",
+       "cascadeprotectedwarning": "<strong>Tension:</strong> Sta pàgina a l'é stàita blocà an manera che mach j'utent con la qualìfica da aministrator a peulo modifichela, për via che a l'é comprèisa an {{PLURAL:$1|costa pàgina-sì|an coste pàgine-sì}} ch'a l'han ël sistema ëd protession a cascada:",
        "titleprotectedwarning": "'''Avis: sta pàgina-sì a l'é stàita blocà an manera che a-i é dabzògn ëd [[Special:ListGroupRights|drit specìfich]] për creela.'''\nL'ùltima vos dël registr a l'é smonùa sì-sota për arferiment:",
        "templatesused": "{{PLURAL:$1|Stamp}} dovrà da costa pàgina-sì:",
        "templatesusedpreview": "{{PLURAL:$1|Stamp}} dovrà an costa preuva:",
        "content-model-css": "CSS",
        "content-json-empty-object": "Oget veuid",
        "content-json-empty-array": "Tàula veuida",
+       "duplicate-args-warning": "<strong>Atension:</strong> [[:$1]] a arciama [[:$2]] con pe che un valor për ël paràmeter \"$3\". Mach l'ùltim valor fornì a sarà dovrà.",
        "duplicate-args-category": "Pàgine ch'a deuvro d'argoment dobi ant j'arceste dë stamp",
        "duplicate-args-category-desc": "La pàgina a conten cj'arceste dë stamp che deuvro ëd duplicà d'argoment, tanme <code><nowiki>{{foo|bar=1|bar=2}}</nowiki></code> o <code><nowiki>{{foo|bar|1=baz}}</nowiki></code>.",
        "expensive-parserfunction-warning": "'''Atension:''' Costa pàgina a l'ha tròpe ciamà costose a le fonsions d'anàlisi sintàtica.\n\nA dovrìa essnie men che {{PLURAL:$2|$2}}, adess a-i na j'é {{PLURAL:$1|$1}}.",
        "badsig": "Soa firma a l'é nen giusta, che a controla j'istrussion HTML.",
        "badsiglength": "Sò stranòm a l'é tròp longh.\nA deuv nen esse pì longh che $1 {{PLURAL:$1|caràter|caràter}}.",
        "yourgender": "'Me ch'a preferiss esse descrivù?",
-       "gender-unknown": "I preferisso nen dilo",
+       "gender-unknown": "Cand a parlërà ëd chiel, ël programa a dovrërà dle paròle ëd géner neutral, s'a l'é possìbil",
        "gender-male": "Chiel a modìfica dle pàgine dla wiki",
        "gender-female": "Chila a modìfica dle pàgine dla wiki",
        "prefs-help-gender": "Definì coste preferense a l'é opsional.\nËl programa a deuvra sò valor për adressesse a chiel e massionelo a j'àutri an dovrand ël géner gramatical giust.\nCosta anformassion a sarà pùblica.",
        "uploaddisabledtext": "La possibilità ëd carié dj'archivi a l'é staita disabilità.",
        "php-uploaddisabledtext": "Ij cariament d'archivi a son disabilità an PHP.\nPër piasì, ch'a controla l'ampostassion file_uploads.",
        "uploadscripted": "St'archivi-sì a l'ha andrinta chèich-còs (dël còdes HTML ò pura un senari) che a podrìa esse travajà mal da chèich programa ëd navigassion.",
+       "upload-scripted-pi-callback": "Impossìbil carié n'archivi ch'a conten d'anstrussion ëd tratament ëd feuj dë stil XML.",
+       "uploaded-script-svg": "Element ëscrivìbil «$1» trovà ant l'archivi SVG carià.",
+       "uploaded-hostile-svg": "CSS nen sigur trovà ant l'element dë stil ëd n'archivi SVG carià.",
+       "uploaded-event-handler-on-svg": "Fissé dj'atribù ëd gestion d'eveniment <code>$1=\"$2\"</code> a l'é nen përmëttù ant j'archivi SVG.",
+       "uploaded-href-attribute-svg": "J'atribù <code>&lt;$1 $2=\"$3\"&gt;</code> con un bërsaj nen local (për esempi http://, javascript:, e via fòrt) a son nen përmëttù ant j'archivi SVG.",
+       "uploaded-href-unsafe-target-svg": "href ver un bërsaj nen sigur <code>&lt;$1 $2=\"$3\"&gt;</code> trovà ant l'archivi SVG carià.",
+       "uploaded-animate-svg": "Trovà na tichëtta «animate», ch'a podrìa modifiché ël href an dovrand l'atribù «from» <code>&lt;$1 $2=\"$3\"&gt;</code> ant l'archivi SVG carià.",
        "uploadscriptednamespace": "S'archivi SVG a conten në spassi nominal «$1» nen autorisà",
        "uploadinvalidxml": "L'XML ant l'archivi carià a l'ha nen podù esse analisà.",
        "uploadvirus": "St'archivi-sì a l'han andrinta un '''vìrus!''' Detaj: $1",
index a8fe9cc..9a6e537 100644 (file)
        "htmlform-title-badnamespace": "[[:$1]] ni v imenskem prostoru »{{ns:$2}}«.",
        "htmlform-title-not-creatable": "»$1« je naslov strani, ki ga ni mogoče ustvariti",
        "htmlform-title-not-exists": "[[:$1]] ne obstaja.",
+       "htmlform-user-not-exists": "<strong>$1</strong> ne obstaja.",
+       "htmlform-user-not-valid": "<strong>$1</strong> ni veljavno uporabniško ime.",
        "sqlite-has-fts": "$1 s podporo iskanju polnih besedil",
        "sqlite-no-fts": "$1 brez podpore iskanju polnih besedil",
        "logentry-delete-delete": "$1 je {{GENDER:$2|izbrisal|izbrisala|izbrisal(-a)}} stran $3",
index 9ac28bb..c4fb1be 100644 (file)
        "htmlform-title-badnamespace": "[[:$1]] är inte i \"{{ns:$2}}\"-namnrymden.",
        "htmlform-title-not-creatable": "\"$1\" är inte en sidtitel som kan skapas",
        "htmlform-title-not-exists": "[[:$1]] finns inte.",
+       "htmlform-user-not-exists": "<strong>$1</strong> finns inte.",
+       "htmlform-user-not-valid": "<strong>$1</strong> är inte ett giltigt användarnamn.",
        "sqlite-has-fts": "$1 med stöd för fulltextsökning",
        "sqlite-no-fts": "$1 utan stöd för fulltextsökning",
        "logentry-delete-delete": "$1 {{GENDER:$2|raderade}} sidan $3",
index da61dda..e34fc5c 100644 (file)
@@ -75,7 +75,8 @@
                        "Watermelon juice",
                        "Ömer Berkay",
                        "Demircimehmed",
-                       "Uğurkent"
+                       "Uğurkent",
+                       "Kincki"
                ]
        },
        "tog-underline": "Bağlantıların altını çiz:",
        "htmlform-cloner-create": "Daha fazla ekle",
        "htmlform-cloner-delete": "Sil",
        "htmlform-cloner-required": "En az bir değer gereklidir.",
+       "htmlform-title-not-creatable": "\"$1\"oluşturulabilir bir sayfa ismi değil.",
+       "htmlform-title-not-exists": "[[:$1]] mevcut değil",
+       "htmlform-user-not-exists": "<strong>$1</strong> mevcut değil.",
+       "htmlform-user-not-valid": "<strong>$1</strong> geçerli bir kullanıcı ismi değildir.",
        "sqlite-has-fts": "$1 tam-metin arama desteği ile",
        "sqlite-no-fts": "$1 tam-metin arama desteği olmaksızın",
        "logentry-delete-delete": "$1 $3 sayfasını {{GENDER:$2|sildi}}",
index c6b0efe..9ae575c 100644 (file)
        "filedelete-submit": "Вилучити",
        "filedelete-success": "'''$1''' було вилучено.",
        "filedelete-success-old": "Версія '''[[Media:$1|$1]]''' від $3, $2 була вилучена.",
-       "filedelete-nofile": "Файл '''$1''' не існує.",
+       "filedelete-nofile": "<strong>$1</strong> не існує.",
        "filedelete-nofile-old": "Не існує архівної версії '''$1''' із зазначеними атрибутами.",
        "filedelete-otherreason": "Інша/додаткова причина:",
        "filedelete-reason-otherlist": "Інша причина",
        "htmlform-title-badnamespace": "[[:$1]] не в просторі назв «{{ns:$2}}».",
        "htmlform-title-not-creatable": "«$1» — назва сторінки, яку не можна створити",
        "htmlform-title-not-exists": "[[:$1]] не існує.",
+       "htmlform-user-not-exists": "<strong>$1</strong> не існує.",
+       "htmlform-user-not-valid": "<strong>$1</strong> не є дійсним іменем користувача.",
        "sqlite-has-fts": "$1 з підтримкою повнотекстового пошуку",
        "sqlite-no-fts": "$1 без підтримки повнотекстового пошуку",
        "logentry-delete-delete": "$1 {{GENDER:$2|вилучив|вилучила}} сторінку $3",
index 061ac9b..e385f4e 100644 (file)
@@ -30,7 +30,8 @@
                        "Dinhxuanduyet",
                        "Macofe",
                        "KhangND",
-                       "Darcy Le"
+                       "Darcy Le",
+                       "Quenhitran"
                ]
        },
        "tog-underline": "Gạch chân liên kết:",
        "edit": "Sửa đổi",
        "edit-local": "Sửa đổi miêu tả địa phương",
        "create": "Tạo",
-       "create-local": "Thêm miêu tả địa phương",
+       "create-local": "Thêm miêu tả trên wiki địa phương",
        "editthispage": "Sửa đổi trang này",
        "create-this-page": "Tạo trang này",
        "delete": "Xóa",
index 75dda9b..fa1931a 100644 (file)
        "htmlform-title-badnamespace": "[[:$1]]不在“{{ns:$2}}”名字空间中。",
        "htmlform-title-not-creatable": "“$1”不是一个可创建的页面标题",
        "htmlform-title-not-exists": "[[:$1]]不存在",
+       "htmlform-user-not-exists": "<strong>$1</strong>不存在。",
+       "htmlform-user-not-valid": "<strong>$1</strong>不是一个有效的用户名。",
        "sqlite-has-fts": "带全文搜索的版本$1",
        "sqlite-no-fts": "不带全文搜索的版本$1",
        "logentry-delete-delete": "$1{{GENDER:$2|删除}}页面$3",
index 760595d..bc9b314 100644 (file)
        "nopagetext": "您所指定的目標頁面並不存在。",
        "pager-newer-n": "較新 $1 筆",
        "pager-older-n": "較舊 $1 筆",
-       "suppress": "失職",
+       "suppress": "監督",
        "querypage-disabled": "此特殊頁面因考量效能問題已被停用。",
        "apihelp": "API 說明",
        "apihelp-no-such-module": "查無模組 \"$1\"。",
        "api-error-illegal-filename": "不允許使用的檔案名稱。",
        "api-error-internal-error": "內部錯誤:此 Wiki 在處理你的上傳時發生錯誤。",
        "api-error-invalid-file-key": "內部錯誤:於暫存儲存庫中查無檔案。",
-       "api-error-missingparam": "內部錯誤:請求缺少參數。",
+       "api-error-missingparam": "內部錯誤:請求缺少參數。",
        "api-error-missingresult": "內部錯誤:無法辨識複製是否成功。",
        "api-error-mustbeloggedin": "您必須登入方可上傳檔案。",
        "api-error-mustbeposted": "內部錯誤:請求需使用 HTTP POST。",
diff --git a/maintenance/migrateFileRepoLayout.php b/maintenance/migrateFileRepoLayout.php
new file mode 100644 (file)
index 0000000..78587ce
--- /dev/null
@@ -0,0 +1,232 @@
+<?php
+/**
+ * Copy all files in FileRepo to an originals container using SHA1 paths.
+ *
+ * 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 Maintenance
+ */
+
+require_once __DIR__ . '/Maintenance.php';
+
+/**
+ * Copy all files in FileRepo to an originals container using SHA1 paths.
+ *
+ * This script should be run while the repo is still set to the old layout.
+ *
+ * @ingroup Maintenance
+ */
+class MigrateFileRepoLayout extends Maintenance {
+       public function __construct() {
+               parent::__construct();
+               $this->mDescription = "Copy files in repo to a different layout.";
+               $this->addOption( 'oldlayout', "Old layout; one of 'name' or 'sha1'", true, true );
+               $this->addOption( 'newlayout', "New layout; one of 'name' or 'sha1'", true, true );
+               $this->addOption( 'since', "Copy only files from after this timestamp", false, true );
+               $this->setBatchSize( 50 );
+       }
+
+       public function execute() {
+               $oldLayout = $this->getOption( 'oldlayout' );
+               if ( !in_array( $oldLayout, array( 'name', 'sha1' ) ) ) {
+                       $this->error( "Invalid old layout.", 1 );
+               }
+               $newLayout = $this->getOption( 'newlayout' );
+               if ( !in_array( $newLayout, array( 'name', 'sha1' ) ) ) {
+                       $this->error( "Invalid new layout.", 1 );
+               }
+               $since = $this->getOption( 'since' );
+
+               $repo = $this->getRepo();
+
+               $be = $repo->getBackend();
+               if ( $be instanceof FileBackendDBRepoWrapper ) {
+                       $be = $be->getInternalBackend(); // avoid path translations for this script
+               }
+
+               $dbw = $repo->getMasterDB();
+
+               $origBase = $be->getContainerStoragePath( "{$repo->getName()}-original" );
+               $startTime = wfTimestampNow();
+
+               // Do current and archived versions...
+               $conds = array();
+               if ( $since ) {
+                       $conds[] = 'img_timestamp >= ' . $dbw->addQuotes( $dbw->timestamp( $since ) );
+               }
+
+               $batch = array();
+               $lastName = '';
+               do {
+                       $res = $dbw->select( 'image', array( 'img_name', 'img_sha1' ),
+                               array_merge( array( 'img_name > ' . $dbw->addQuotes( $lastName ) ), $conds ),
+                               __METHOD__,
+                               array( 'LIMIT' => $this->mBatchSize, 'ORDER BY' => 'img_name' )
+                       );
+
+                       foreach ( $res as $row ) {
+                               $lastName = $row->img_name;
+                               $sha1 = $row->img_sha1;
+                               if ( !strlen( $sha1 ) ) {
+                                       $this->error( "Image SHA-1 not set for {$row->img_name}." );
+                               } else {
+                                       $file = $repo->newFile( $row->img_name );
+
+                                       if ( $oldLayout === 'sha1' ) {
+                                               $spath = "{$origBase}/{$sha1[0]}/{$sha1[1]}/{$sha1[2]}/{$sha1}";
+                                       } else {
+                                               $spath = $file->getPath();
+                                       }
+
+                                       if ( $newLayout === 'sha1' ) {
+                                               $dpath = "{$origBase}/{$sha1[0]}/{$sha1[1]}/{$sha1[2]}/{$sha1}";
+                                       } else {
+                                               $dpath = $file->getPath();
+                                       }
+
+                                       $status = $be->prepare( array( 'dir' => dirname( $dpath ) ) );
+                                       if ( !$status->isOK() ) {
+                                               $this->error( print_r( $status->getErrorsArray(), true ) );
+                                       }
+
+                                       $batch[] = array( 'op' => 'copy', 'overwrite' => true,
+                                               'src' => $spath, 'dst' => $dpath, 'img' => $row->img_name );
+                               }
+
+                               foreach ( $file->getHistory() as $ofile ) {
+                                       $sha1 = $ofile->getSha1();
+                                       if ( !strlen( $sha1 ) ) {
+                                               $this->error( "Image SHA-1 not set for {$ofile->getArchiveName()}." );
+                                               continue;
+                                       }
+
+                                       if ( $oldLayout === 'sha1' ) {
+                                               $spath = "{$origBase}/{$sha1[0]}/{$sha1[1]}/{$sha1[2]}/{$sha1}";
+                                       } elseif ( $ofile->isDeleted( File::DELETED_FILE ) ) {
+                                               $spath = $be->getContainerStoragePath( "{$repo->getName()}-deleted" ) .
+                                                       '/' . $repo->getDeletedHashPath( $sha1 ) .
+                                                       $sha1 . '.' . $ofile->getExtension();
+                                       } else {
+                                               $spath = $ofile->getPath();
+                                       }
+
+                                       if ( $newLayout === 'sha1' ) {
+                                               $dpath = "{$origBase}/{$sha1[0]}/{$sha1[1]}/{$sha1[2]}/{$sha1}";
+                                       } else {
+                                               $dpath = $ofile->getPath();
+                                       }
+
+                                       $status = $be->prepare( array( 'dir' => dirname( $dpath ) ) );
+                                       if ( !$status->isOK() ) {
+                                               $this->error( print_r( $status->getErrorsArray(), true ) );
+                                       }
+                                       $batch[] = array( 'op' => 'copy', 'overwrite' => true,
+                                               'src' => $spath, 'dst' => $dpath, 'img' => $ofile->getArchiveName() );
+                               }
+
+                               if ( count( $batch ) >= $this->mBatchSize ) {
+                                       $this->runBatch( $batch, $be );
+                                       $batch = array();
+                               }
+                       }
+               } while ( $res->numRows() );
+
+               if ( count( $batch ) ) {
+                       $this->runBatch( $batch, $be );
+               }
+
+               // Do deleted versions...
+               $conds = array();
+               if ( $since ) {
+                       $conds[] = 'fa_deleted_timestamp >= ' . $dbw->addQuotes( $dbw->timestamp( $since ) );
+               }
+
+               $batch = array();
+               $lastId = 0;
+               do {
+                       $res = $dbw->select( 'filearchive', array( 'fa_storage_key', 'fa_id', 'fa_name' ),
+                               array_merge( array( 'fa_id > ' . $dbw->addQuotes( $lastId ) ), $conds ),
+                               __METHOD__,
+                               array( 'LIMIT' => $this->mBatchSize, 'ORDER BY' => 'fa_id' )
+                       );
+
+                       foreach ( $res as $row ) {
+                               $lastId = $row->fa_id;
+                               $sha1Key = $row->fa_storage_key;
+                               if ( !strlen( $sha1Key ) ) {
+                                       $this->error( "Image SHA-1 not set for file #{$row->fa_id} (deleted)." );
+                                       continue;
+                               }
+                               $sha1 = substr( $sha1Key, 0, strpos( $sha1Key, '.' ) );
+
+                               if ( $oldLayout === 'sha1' ) {
+                                       $spath = "{$origBase}/{$sha1[0]}/{$sha1[1]}/{$sha1[2]}/{$sha1}";
+                               } else {
+                                       $spath = $be->getContainerStoragePath( "{$repo->getName()}-deleted" ) .
+                                               '/' . $repo->getDeletedHashPath( $sha1Key ) . $sha1Key;
+                               }
+
+                               if ( $newLayout === 'sha1' ) {
+                                       $dpath = "{$origBase}/{$sha1[0]}/{$sha1[1]}/{$sha1[2]}/{$sha1}";
+                               } else {
+                                       $dpath = $be->getContainerStoragePath( "{$repo->getName()}-deleted" ) .
+                                               '/' . $repo->getDeletedHashPath( $sha1Key ) . $sha1Key;
+                               }
+
+                               $status = $be->prepare( array( 'dir' => dirname( $dpath ) ) );
+                               if ( !$status->isOK() ) {
+                                       $this->error( print_r( $status->getErrorsArray(), true ) );
+                               }
+
+                               $batch[] = array( 'op' => 'copy', 'src' => $spath, 'dst' => $dpath,
+                                       'overwriteSame' => true, 'img' => "(ID {$row->fa_id}) {$row->fa_name}" );
+
+                               if ( count( $batch ) >= $this->mBatchSize ) {
+                                       $this->runBatch( $batch, $be );
+                                       $batch = array();
+                               }
+                       }
+               } while ( $res->numRows() );
+
+               if ( count( $batch ) ) {
+                       $this->runBatch( $batch, $be );
+               }
+
+               $this->output( "Done (started $startTime)\n" );
+       }
+
+       protected function getRepo() {
+               return RepoGroup::singleton()->getLocalRepo();
+       }
+
+       protected function runBatch( array $ops, FileBackend $be ) {
+               $this->output( "Migrating file batch:\n" );
+               foreach ( $ops as $op ) {
+                       $this->output( "\"{$op['img']}\" (dest: {$op['dst']})\n" );
+               }
+
+               $status = $be->doOperations( $ops );
+               if ( !$status->isOK() ) {
+                       $this->output( print_r( $status->getErrorsArray(), true ) );
+               }
+
+               $this->output( "Batch done\n\n" );
+       }
+}
+
+$maintClass = 'MigrateFileRepoLayout';
+require_once RUN_MAINTENANCE_IF_MAIN;
diff --git a/maintenance/postgres/archives/patch-textsearch_bug66650.sql b/maintenance/postgres/archives/patch-textsearch_bug66650.sql
new file mode 100644 (file)
index 0000000..e4f5681
--- /dev/null
@@ -0,0 +1,5 @@
+UPDATE /*_*/pagecontent SET textvector=to_tsvector(old_text)
+WHERE textvector IS NULL AND old_id IN 
+(SELECT  max(rev_text_id) FROM revision GROUP BY rev_page);
+
+INSERT INTO /*_*/updatelog(ul_key) VALUES ('patch-textsearch_bug66650.sql');
index 7761d0c..b858551 100644 (file)
@@ -27,3 +27,8 @@ INSERT INTO /*_*/updatelog (ul_key, ul_value)
        VALUES( 'user_former_groups-ufg_group-patch-ufg_group-length-increase-255.sql', null );
 INSERT INTO /*_*/updatelog (ul_key, ul_value)
        VALUES( 'user_properties-up_property-patch-up_property.sql', null );
+
+-- PostgreSQL-specific patches.
+
+INSERT INTO /*_*/updatelog (ul_key, ul_value)
+       VALUES( 'patch-textsearch_bug66650.sql', null );
diff --git a/resources/lib/mustache/LICENSE b/resources/lib/mustache/LICENSE
new file mode 100644 (file)
index 0000000..aa1b831
--- /dev/null
@@ -0,0 +1,10 @@
+The MIT License
+
+Copyright (c) 2009 Chris Wanstrath (Ruby)
+Copyright (c) 2010-2014 Jan Lehnardt (JavaScript)
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
index 56b6811..16fd7ec 100644 (file)
 
        &:hover {
                // The inner bottom bevel should match the active background color.
-               box-shadow: 0 1px rgba(0, 0, 0, 10%), inset 0 -3px rgba(0, 0, 0, 20%);
-               border-bottom-color: @highlightColor;
+               background-color: @highlightColor;
        }
 
        &:focus {
-               border-color: rgba(0,0,0,0.2);
-               box-shadow: inset 0 0 0 1px rgba(0,0,0,0.2);
+               border-color: @colorWhite;
+               box-shadow: 0 0 0 1px @highlightColor;
 
                outline: none;
                // remove outline in Firefox
                color: @colorButtonText;
        }
 
+       &:focus {
+               background-color: @highlightColor;
+       }
+
        &:disabled {
                color: @colorDisabledText;
 
index 0558c32..05e6f27 100644 (file)
@@ -25,7 +25,7 @@
         */
        mw.widgets.NamespaceInputWidget = function MwWidgetsNamespaceInputWidget( config ) {
                // Parent constructor
-               OO.ui.Widget.call( this, config );
+               mw.widgets.NamespaceInputWidget.parent.call( this, config );
 
                // Properties
                this.namespace = config.namespace;
                this.allValue = config.allValue;
 
                // Events
-               config.namespace.connect( this, { change: 'updateCheckboxesState' } );
+               this.namespace.connect( this, { change: 'updateCheckboxesState' } );
 
                // Initialization
                this.$element
                        .addClass( 'mw-widget-namespaceInputWidget' )
                        .append(
-                               config.namespace.$element,
-                               config.invert ? config.invert.$element : '',
-                               config.associated ? config.associated.$element : ''
+                               this.namespace.$element,
+                               this.invert ? this.invert.$element : '',
+                               this.associated ? this.associated.$element : ''
                        );
                this.updateCheckboxesState();
        };
 
-       /* Inheritance */
+       /* Setup */
 
        OO.inheritClass( mw.widgets.NamespaceInputWidget, OO.ui.Widget );
 
index e715361..bee5920 100644 (file)
@@ -5,6 +5,7 @@
  * @license The MIT License (MIT); see LICENSE.txt
  */
 ( function ( $, mw ) {
+
        /**
         * Creates an mw.widgets.TitleInputWidget object.
         *
@@ -30,7 +31,7 @@
                config = config || {};
 
                // Parent constructor
-               OO.ui.TextInputWidget.call( this, $.extend( {}, config, { autocomplete: false } ) );
+               mw.widgets.TitleInputWidget.parent.call( this, $.extend( {}, config, { autocomplete: false } ) );
 
                // Mixin constructors
                OO.ui.mixin.LookupElement.call( this, config );
                } );
        };
 
-       /* Inheritance */
+       /* Setup */
 
        OO.inheritClass( mw.widgets.TitleInputWidget, OO.ui.TextInputWidget );
-
        OO.mixinClass( mw.widgets.TitleInputWidget, OO.ui.mixin.LookupElement );
 
        /* Methods */
@@ -95,7 +95,7 @@
                this.setLookupsDisabled( true );
 
                // Parent method
-               retval = OO.ui.TextInputWidget.prototype.focus.apply( this, arguments );
+               retval = mw.widgets.TitleInputWidget.parent.prototype.focus.apply( this, arguments );
 
                this.setLookupsDisabled( false );
 
         * Get lookup cache item from server response data.
         *
         * @method
-        * @param {Mixed} data Response from server
+        * @param {Mixed} response Response from server
         */
-       mw.widgets.TitleInputWidget.prototype.getLookupCacheDataFromResponse = function ( data ) {
-               return data.query || {};
+       mw.widgets.TitleInputWidget.prototype.getLookupCacheDataFromResponse = function ( response ) {
+               return response.query || {};
        };
 
        /**
index 6623aa7..ec0c935 100644 (file)
@@ -45,9 +45,9 @@
                }, config );
 
                // Parent constructor
-               OO.ui.MenuOptionWidget.call( this, config );
+               mw.widgets.TitleOptionWidget.parent.call( this, config );
 
-               // Intialization
+               // Initialization
                this.$label.wrap( '<a>' );
                this.$link = this.$label.parent();
                this.$link.attr( 'href', config.href );
@@ -75,7 +75,7 @@
                }
        };
 
-       /* Inheritance */
+       /* Setup */
 
        OO.inheritClass( mw.widgets.TitleOptionWidget, OO.ui.MenuOptionWidget );
 
index 903660a..d540877 100644 (file)
@@ -5,6 +5,7 @@
  * @license The MIT License (MIT); see LICENSE.txt
  */
 ( function ( $, mw ) {
+
        /**
         * Creates a mw.widgets.UserInputWidget object.
         *
@@ -21,7 +22,7 @@
                config = config || {};
 
                // Parent constructor
-               OO.ui.TextInputWidget.call( this, $.extend( {}, config, { autocomplete: false } ) );
+               mw.widgets.UserInputWidget.parent.call( this, $.extend( {}, config, { autocomplete: false } ) );
 
                // Mixin constructors
                OO.ui.mixin.LookupElement.call( this, config );
                this.lookupMenu.$element.addClass( 'mw-widget-userInputWidget-menu' );
        };
 
-       /* Inheritance */
+       /* Setup */
 
        OO.inheritClass( mw.widgets.UserInputWidget, OO.ui.TextInputWidget );
-
        OO.mixinClass( mw.widgets.UserInputWidget, OO.ui.mixin.LookupElement );
 
        /* Methods */
@@ -62,7 +62,7 @@
                this.setLookupsDisabled( true );
 
                // Parent method
-               retval = OO.ui.TextInputWidget.prototype.focus.apply( this, arguments );
+               retval = mw.widgets.UserInputWidget.parent.prototype.focus.apply( this, arguments );
 
                this.setLookupsDisabled( false );
 
         * Get lookup cache item from server response data.
         *
         * @method
-        * @param {Mixed} data Response from server
+        * @param {Mixed} response Response from server
         */
-       mw.widgets.UserInputWidget.prototype.getLookupCacheDataFromResponse = function ( data ) {
-               return data.query || {};
+       mw.widgets.UserInputWidget.prototype.getLookupCacheDataFromResponse = function ( response ) {
+               return response.query.allusers || {};
        };
 
        /**
         */
        mw.widgets.UserInputWidget.prototype.getLookupMenuOptionsFromData = function ( data ) {
                var len, i, user,
-                       users = data.allusers,
                        items = [];
 
-               for ( i = 0, len = users.length; i < len; i++ ) {
-                       user = users[i] || {};
+               for ( i = 0, len = data.length; i < len; i++ ) {
+                       user = data[i] || {};
                        items.push( new OO.ui.MenuOptionWidget( {
                                label: user.name,
                                data: user.name
index 2c88e93..c0b1642 100644 (file)
                        function addEmbeddedCSS( cssText, callback ) {
                                var $style, styleEl;
 
+                               function fireCallbacks() {
+                                       var oldCallbacks = cssCallbacks;
+                                       // Reset cssCallbacks variable so it's not polluted by any calls to
+                                       // addEmbeddedCSS() from one of the callbacks (T105973)
+                                       cssCallbacks = $.Callbacks();
+                                       oldCallbacks.fire().empty();
+                               }
+
                                if ( callback ) {
                                        cssCallbacks.add( callback );
                                }
                                                } else {
                                                        styleEl.appendChild( document.createTextNode( cssText ) );
                                                }
-                                               cssCallbacks.fire().empty();
+                                               fireCallbacks();
                                                return;
                                        }
                                }
 
                                $( newStyleTag( cssText, getMarker() ) ).data( 'ResourceLoaderDynamicStyleTag', true );
 
-                               cssCallbacks.fire().empty();
+                               fireCallbacks();
                        }
 
                        /**
index 80cc7d9..5ee295b 100644 (file)
@@ -6,6 +6,14 @@
 
 var mediaWikiLoadStart = ( new Date() ).getTime();
 
+if ( !window.performance ) {
+       window.performance = {};
+}
+if ( !performance.mark ) {
+       performance.mark = function () {};
+}
+performance.mark( 'mediaWikiStartUp' );
+
 /**
  * Returns false for Grade C supported browsers.
  *
index 0ce056f..43d8ce8 100644 (file)
@@ -204,9 +204,6 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase {
                        while ( $this->db->trxLevel() > 0 ) {
                                $this->db->rollback();
                        }
-
-                       // don't ignore DB errors
-                       $this->db->ignoreErrors( false );
                }
 
                DeferredUpdates::clearPendingUpdates();
@@ -233,9 +230,6 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase {
                        while ( $this->db->trxLevel() > 0 ) {
                                $this->db->rollback();
                        }
-
-                       // don't ignore DB errors
-                       $this->db->ignoreErrors( false );
                }
 
                // Restore mw globals
index cf08dbe..9c953a6 100644 (file)
@@ -21,6 +21,17 @@ class MessageTest extends MediaWikiLangTestCase {
                $this->assertEquals( $key, $message->getKey() );
                $this->assertEquals( $params, $message->getParams() );
                $this->assertEquals( $expectedLang, $message->getLanguage() );
+
+               $messageSpecifier = $this->getMockForAbstractClass( 'MessageSpecifier' );
+               $messageSpecifier->expects( $this->any() )
+                       ->method( 'getKey' )->will( $this->returnValue( $key ) );
+               $messageSpecifier->expects( $this->any() )
+                       ->method( 'getParams' )->will( $this->returnValue( $params ) );
+               $message = new Message( $messageSpecifier, array(), $language );
+
+               $this->assertEquals( $key, $message->getKey() );
+               $this->assertEquals( $params, $message->getParams() );
+               $this->assertEquals( $expectedLang, $message->getLanguage() );
        }
 
        public static function provideConstructor() {
index 40484d3..44427ba 100644 (file)
@@ -4,6 +4,8 @@
  * @group ContentHandler
  * @group Database
  *        ^--- needed, because we do need the database to test link updates
+ *
+ * @FIXME this should not extend JavaScriptContentTest.
  */
 class CssContentTest extends JavaScriptContentTest {
 
@@ -68,7 +70,28 @@ class CssContentTest extends JavaScriptContentTest {
                $this->assertEquals( CONTENT_MODEL_CSS, $content->getContentHandler()->getModelID() );
        }
 
-       public static function dataEquals() {
+       /**
+        * Redirects aren't supported
+        */
+       public static function provideUpdateRedirect() {
+               return array(
+                       array(
+                               '#REDIRECT [[Someplace]]',
+                               '#REDIRECT [[Someplace]]',
+                       ),
+               );
+       }
+
+       /**
+        * Override this since CssContent does not support redirects yet
+        */
+       public static function provideGetRedirectTarget() {
+               return array(
+                       array( null, '' ),
+               );
+       }
+
+               public static function dataEquals() {
                return array(
                        array( new CssContent( 'hallo' ), null, false ),
                        array( new CssContent( 'hallo' ), new CssContent( 'hallo' ), true ),
diff --git a/tests/phpunit/includes/content/JavaScriptContentHandlerTest.php b/tests/phpunit/includes/content/JavaScriptContentHandlerTest.php
new file mode 100644 (file)
index 0000000..0f41020
--- /dev/null
@@ -0,0 +1,30 @@
+<?php
+
+class JavaScriptContentHandlerTest extends MediaWikiTestCase {
+
+       /**
+        * @dataProvider provideMakeRedirectContent
+        * @covers JavaScriptContentHandler::makeRedirectContent
+        */
+       public function testMakeRedirectContent( $title, $expected ) {
+               $this->setMwGlobals( array(
+                       'wgServer' => '//example.org',
+                       'wgScript' => '/w/index.php',
+               ) );
+               $ch = new JavaScriptContentHandler();
+               $content = $ch->makeRedirectContent( Title::newFromText( $title ) );
+               $this->assertInstanceOf( 'JavaScriptContent', $content );
+               $this->assertEquals( $expected, $content->serialize( CONTENT_FORMAT_JAVASCRIPT ) );
+       }
+
+       /**
+        * Keep this in sync with JavaScriptContentTest::provideGetRedirectTarget()
+        */
+       public static function provideMakeRedirectContent() {
+               return array(
+                       array( 'MediaWiki:MonoBook.js', '/* #REDIRECT */mw.loader.load("//example.org/w/index.php?title=MediaWiki:MonoBook.js\u0026action=raw\u0026ctype=text/javascript");' ),
+                       array( 'User:FooBar/common.js', '/* #REDIRECT */mw.loader.load("//example.org/w/index.php?title=User:FooBar/common.js\u0026action=raw\u0026ctype=text/javascript");' ),
+                       array( 'Gadget:FooBaz.js', '/* #REDIRECT */mw.loader.load("//example.org/w/index.php?title=Gadget:FooBaz.js\u0026action=raw\u0026ctype=text/javascript");' ),
+               );
+       }
+}
index 7193ec9..0ee2712 100644 (file)
@@ -251,16 +251,31 @@ class JavaScriptContentTest extends TextContentTest {
 
        /**
         * @covers JavaScriptContent::updateRedirect
+        * @dataProvider provideUpdateRedirect
         */
-       public function testUpdateRedirect() {
+       public function testUpdateRedirect( $oldText, $expectedText) {
+               $this->setMwGlobals( array(
+                       'wgServer' => '//example.org',
+                       'wgScriptPath' => '/w/index.php',
+               ) );
                $target = Title::newFromText( "testUpdateRedirect_target" );
 
-               $content = $this->newContent( "#REDIRECT [[Someplace]]" );
+               $content = new JavaScriptContent( $oldText );
                $newContent = $content->updateRedirect( $target );
 
-               $this->assertTrue(
-                       $content->equals( $newContent ),
-                       "content should be unchanged since it's not wikitext"
+               $this->assertEquals( $expectedText, $newContent->getNativeData() );
+       }
+
+       public static function provideUpdateRedirect() {
+               return array(
+                       array(
+                               '#REDIRECT [[Someplace]]',
+                               '#REDIRECT [[Someplace]]',
+                       ),
+                       array(
+                               '/* #REDIRECT */mw.loader.load("//example.org/w/index.php?title=MediaWiki:MonoBook.js\u0026action=raw\u0026ctype=text/javascript");',
+                               '/* #REDIRECT */mw.loader.load("//example.org/w/index.php?title=TestUpdateRedirect_target\u0026action=raw\u0026ctype=text/javascript");'
+                       )
                );
        }
 
@@ -290,4 +305,32 @@ class JavaScriptContentTest extends TextContentTest {
                        array( new JavaScriptContent( "hallo" ), new JavaScriptContent( "HALLO" ), false ),
                );
        }
+
+       /**
+        * @dataProvider provideGetRedirectTarget
+        */
+       public function testGetRedirectTarget( $title, $text ) {
+               $this->setMwGlobals( array(
+                       'wgServer' => '//example.org',
+                       'wgScriptPath' => '/w/index.php',
+               ) );
+               $content = new JavaScriptContent( $text );
+               $target = $content->getRedirectTarget();
+               $this->assertEquals( $title, $target ? $target->getPrefixedText() : null );
+       }
+
+       /**
+        * Keep this in sync with JavaScriptContentHandlerTest::provideMakeRedirectContent()
+        */
+       public static function provideGetRedirectTarget() {
+               return array(
+                       array( 'MediaWiki:MonoBook.js', '/* #REDIRECT */mw.loader.load("//example.org/w/index.php?title=MediaWiki:MonoBook.js\u0026action=raw\u0026ctype=text/javascript");' ),
+                       array( 'User:FooBar/common.js', '/* #REDIRECT */mw.loader.load("//example.org/w/index.php?title=User:FooBar/common.js\u0026action=raw\u0026ctype=text/javascript");' ),
+                       array( 'Gadget:FooBaz.js', '/* #REDIRECT */mw.loader.load("//example.org/w/index.php?title=Gadget:FooBaz.js\u0026action=raw\u0026ctype=text/javascript");' ),
+                       // No #REDIRECT comment
+                       array( null, 'mw.loader.load("//example.org/w/index.php?title=MediaWiki:NoRedirect.js\u0026action=raw\u0026ctype=text/javascript");' ),
+                       // Different domain
+                       array( null, '/* #REDIRECT */mw.loader.load("//example.com/w/index.php?title=MediaWiki:OtherWiki.js\u0026action=raw\u0026ctype=text/javascript");' ),
+               );
+       }
 }
index 338d931..764560d 100644 (file)
@@ -68,25 +68,6 @@ class ORMTableTest extends MediaWikiTestCase {
                $this->assertInstanceOf( $class, $class::singleton() );
                $this->assertTrue( $class::singleton() === $class::singleton() );
        }
-
-       /**
-        * @since 1.21
-        */
-       public function testIgnoreErrorsOverride() {
-               $table = $this->getTable();
-
-               $db = $table->getReadDbConnection();
-               $db->ignoreErrors( true );
-
-               try {
-                       $table->rawSelect( "this is invalid" );
-                       $this->fail( "An invalid query should trigger a DBQueryError even if ignoreErrors is enabled." );
-               } catch ( DBQueryError $ex ) {
-                       $this->assertTrue( true, "just making phpunit happy" );
-               }
-
-               $db->ignoreErrors( false );
-       }
 }
 
 /**
diff --git a/tests/phpunit/includes/filerepo/FileBackendDBRepoWrapperTest.php b/tests/phpunit/includes/filerepo/FileBackendDBRepoWrapperTest.php
new file mode 100644 (file)
index 0000000..681e368
--- /dev/null
@@ -0,0 +1,138 @@
+<?php
+
+class FileBackendDBRepoWrapperTest extends MediaWikiTestCase {
+       protected $backendName = 'foo-backend';
+       protected $repoName = 'pureTestRepo';
+
+       /**
+        * @dataProvider getBackendPathsProvider
+        * @covers FileBackendDBRepoWrapper::getBackendPaths
+        */
+       public function testGetBackendPaths(
+               $mocks,
+               $latest,
+               $dbReadsExpected,
+               $dbReturnValue,
+               $originalPath,
+               $expectedBackendPath,
+               $message ) {
+               list( $dbMock, $backendMock, $wrapperMock ) = $mocks;
+
+               $dbMock->expects( $dbReadsExpected )
+                       ->method( 'selectField' )
+                       ->will( $this->returnValue( $dbReturnValue ) );
+
+               $newPaths = $wrapperMock->getBackendPaths( array( $originalPath ), $latest );
+
+               $this->assertEquals(
+                       $expectedBackendPath,
+                       $newPaths[0],
+                       $message );
+       }
+
+       public function getBackendPathsProvider() {
+               $prefix = 'mwstore://' . $this->backendName . '/' . $this->repoName;
+               $mocksForCaching = $this->getMocks();
+
+               return array(
+                       array(
+                               $mocksForCaching,
+                               false,
+                               $this->once(),
+                               '96246614d75ba1703bdfd5d7660bb57407aaf5d9',
+                               $prefix . '-public/f/o/foobar.jpg',
+                               $prefix . '-original/9/6/2/96246614d75ba1703bdfd5d7660bb57407aaf5d9',
+                               'Public path translated correctly',
+                       ),
+                       array(
+                               $mocksForCaching,
+                               false,
+                               $this->never(),
+                               '96246614d75ba1703bdfd5d7660bb57407aaf5d9',
+                               $prefix . '-public/f/o/foobar.jpg',
+                               $prefix . '-original/9/6/2/96246614d75ba1703bdfd5d7660bb57407aaf5d9',
+                               'LRU cache leveraged',
+                       ),
+                       array(
+                               $this->getMocks(),
+                               true,
+                               $this->once(),
+                               '96246614d75ba1703bdfd5d7660bb57407aaf5d9',
+                               $prefix . '-public/f/o/foobar.jpg',
+                               $prefix . '-original/9/6/2/96246614d75ba1703bdfd5d7660bb57407aaf5d9',
+                               'Latest obtained',
+                       ),
+                       array(
+                               $this->getMocks(),
+                               true,
+                               $this->never(),
+                               '96246614d75ba1703bdfd5d7660bb57407aaf5d9',
+                               $prefix . '-deleted/f/o/foobar.jpg',
+                               $prefix . '-original/f/o/o/foobar',
+                               'Deleted path translated correctly',
+                       ),
+                       array(
+                               $this->getMocks(),
+                               true,
+                               $this->once(),
+                               null,
+                               $prefix . '-public/b/a/baz.jpg',
+                               $prefix . '-public/b/a/baz.jpg',
+                               'Path left untouched if no sha1 can be found',
+                       ),
+               );
+       }
+
+       /**
+        * @covers FileBackendDBRepoWrapper::getFileContentsMulti
+        */
+       public function testGetFileContentsMulti() {
+               list( $dbMock, $backendMock, $wrapperMock ) = $this->getMocks();
+
+               $sha1Path = 'mwstore://' . $this->backendName . '/' . $this->repoName
+                       . '-original/9/6/2/96246614d75ba1703bdfd5d7660bb57407aaf5d9';
+               $filenamePath = 'mwstore://' . $this->backendName . '/' . $this->repoName
+                       . '-public/f/o/foobar.jpg';
+
+               $dbMock->expects( $this->once() )
+                       ->method( 'selectField' )
+                       ->will( $this->returnValue( '96246614d75ba1703bdfd5d7660bb57407aaf5d9' ) );
+
+               $backendMock->expects( $this->once() )
+                       ->method( 'getFileContentsMulti')
+                       ->will( $this->returnValue( array( $sha1Path => 'foo' ) ) );
+
+               $result = $wrapperMock->getFileContentsMulti( array( 'srcs' => array( $filenamePath ) ) );
+
+               $this->assertEquals(
+                       array( $filenamePath => 'foo' ),
+                       $result,
+                       'File contents paths translated properly'
+               );
+       }
+
+       protected function getMocks() {
+               $dbMock = $this->getMockBuilder( 'DatabaseMysql' )
+                       ->disableOriginalConstructor()
+                       ->getMock();
+
+               $backendMock = $this->getMock( 'FSFileBackend',
+                       array(),
+                       array( array(
+                               'name' => $this->backendName,
+                               'wikiId' => wfWikiId()
+                       ) ) );
+
+               $wrapperMock = $this->getMock( 'FileBackendDBRepoWrapper',
+                       array( 'getDB' ),
+                       array( array(
+                               'backend' => $backendMock,
+                               'repoName' => $this->repoName,
+                               'dbHandleFactory' => null
+                       ) ) );
+
+               $wrapperMock->expects( $this->any() )->method( 'getDB' )->will( $this->returnValue( $dbMock ) );
+
+               return array( $dbMock, $backendMock, $wrapperMock );
+       }
+}
diff --git a/tests/phpunit/includes/filerepo/MigrateFileRepoLayoutTest.php b/tests/phpunit/includes/filerepo/MigrateFileRepoLayoutTest.php
new file mode 100644 (file)
index 0000000..65db7e4
--- /dev/null
@@ -0,0 +1,114 @@
+<?php
+
+class MigrateFileRepoLayoutTest extends MediaWikiTestCase {
+       protected $tmpPrefix;
+       protected $migratorMock;
+       protected $tmpFilepath;
+       protected $text = 'testing';
+
+       protected function setUp() {
+               parent::setUp();
+
+               $filename = 'Foo.png';
+
+               $this->tmpPrefix = wfTempDir() . '/migratefilelayout-test-' . time() . '-' . mt_rand();
+
+               $backend = new FSFileBackend( array(
+                       'name' => 'local-migratefilerepolayouttest',
+                       'wikiId' => wfWikiID(),
+                       'containerPaths' => array(
+                               'migratefilerepolayouttest-original' => "{$this->tmpPrefix}-original",
+                               'migratefilerepolayouttest-public' => "{$this->tmpPrefix}-public",
+                               'migratefilerepolayouttest-thumb' => "{$this->tmpPrefix}-thumb",
+                               'migratefilerepolayouttest-temp' => "{$this->tmpPrefix}-temp",
+                               'migratefilerepolayouttest-deleted' => "{$this->tmpPrefix}-deleted",
+                       )
+               ) );
+
+               $dbMock = $this->getMockBuilder( 'DatabaseMysql' )
+                       ->disableOriginalConstructor()
+                       ->getMock();
+
+               $imageRow = new stdClass;
+               $imageRow->img_name = $filename;
+               $imageRow->img_sha1 = sha1( $this->text );
+
+               $dbMock->expects( $this->any() )
+                       ->method( 'select' )
+                       ->will( $this->onConsecutiveCalls(
+                               new FakeResultWrapper( array( $imageRow ) ), // image
+                               new FakeResultWrapper( array() ), // image
+                               new FakeResultWrapper( array() ) // filearchive
+                       ) );
+
+               $repoMock = $this->getMock( 'LocalRepo',
+                       array( 'getMasterDB' ),
+                       array( array(
+                               'name' => 'migratefilerepolayouttest',
+                               'backend' => $backend
+                       ) ) );
+
+               $repoMock->expects( $this->any() )->method( 'getMasterDB' )->will( $this->returnValue( $dbMock ) );
+
+               $this->migratorMock = $this->getMock( 'MigrateFileRepoLayout', array( 'getRepo' ) );
+               $this->migratorMock->expects( $this->any() )->method( 'getRepo' )->will( $this->returnValue( $repoMock ) );
+
+               $this->tmpFilepath = TempFSFile::factory( 'migratefilelayout-test-', 'png' )->getPath();
+
+               file_put_contents( $this->tmpFilepath, $this->text );
+
+               $hashPath = $repoMock->getHashPath( $filename );
+
+               $status = $repoMock->store( $this->tmpFilepath, 'public', $hashPath . $filename, FileRepo::OVERWRITE );
+       }
+
+       protected function deleteFilesRecursively( $directory ) {
+               foreach ( glob( $directory . '/*' ) as $file ) {
+               if ( is_dir( $file ) ) {
+                       $this->deleteFilesRecursively( $file );
+               } else {
+                       unlink( $file );
+               }
+               }
+
+               rmdir( $directory );
+       }
+
+       protected function tearDown() {
+       foreach ( glob( $this->tmpPrefix . '*' ) as $directory ) {
+               $this->deleteFilesRecursively( $directory );
+       }
+
+       unlink( $this->tmpFilepath );
+
+               parent::tearDown();
+       }
+
+       public function testMigration() {
+               $this->migratorMock->loadParamsAndArgs( null, array( 'oldlayout' => 'name', 'newlayout' => 'sha1' ) );
+
+               ob_start();
+
+               $this->migratorMock->execute();
+
+               ob_end_clean();
+
+               $sha1 = sha1( $this->text );
+
+               $expectedOriginalFilepath = $this->tmpPrefix
+                       . '-original/'
+                       . substr( $sha1, 0, 1 )
+                       . '/'
+                       . substr( $sha1, 1, 1 )
+                       . '/'
+                       . substr( $sha1, 2, 1 )
+                       . '/'
+                       . $sha1 ;
+
+               $this->assertEquals( file_get_contents( $expectedOriginalFilepath ), $this->text, 'New sha1 file should be exist and have the right contents' );
+
+               $expectedPublicFilepath = $this->tmpPrefix . '-public/f/f8/Foo.png';
+
+               $this->assertEquals( file_get_contents( $expectedPublicFilepath ), $this->text, 'Existing name file should still and have the right contents' );
+       }
+}
index 77fecb3..c8f0011 100644 (file)
 
        } );
 
+       QUnit.asyncTest( 'mw.loader.implement( dependency with styles )', 4, function ( assert ) {
+               var $element = $( '<div class="mw-test-implement-e"></div>' ).appendTo( '#qunit-fixture' ),
+                       $element2 = $( '<div class="mw-test-implement-e2"></div>' ).appendTo( '#qunit-fixture' );
+
+               assert.notEqual(
+                       $element.css( 'float' ),
+                       'right',
+                       'style is clear'
+               );
+               assert.notEqual(
+                       $element2.css( 'float' ),
+                       'left',
+                       'style is clear'
+               );
+
+               mw.loader.register( [
+                       [ 'test.implement.e', '0', ['test.implement.e2']],
+                       [ 'test.implement.e2', '0' ]
+               ] );
+
+               mw.loader.implement(
+                       'test.implement.e',
+                       function () {
+                               assert.equal(
+                                       $element.css( 'float' ),
+                                       'right',
+                                       'Depending module\'s style is applied'
+                               );
+                               QUnit.start();
+                       },
+                       {
+                               'all': '.mw-test-implement-e { float: right; }'
+                       }
+               );
+
+               mw.loader.implement(
+                       'test.implement.e2',
+                       function () {
+                               assert.equal(
+                                       $element2.css( 'float' ),
+                                       'left',
+                                       'Dependency\'s style is applied'
+                               );
+                       },
+                       {
+                               'all': '.mw-test-implement-e2 { float: left; }'
+                       }
+               );
+
+               mw.loader.load( [
+                       'test.implement.e'
+               ] );
+       } );
+
        QUnit.test( 'mw.loader.implement( only scripts )', 1, function ( assert ) {
                mw.loader.implement( 'test.onlyscripts', function () {} );
                assert.strictEqual( mw.loader.getState( 'test.onlyscripts' ), 'ready' );
index 5c4eea7..3b7ff43 100644 (file)
--- a/thumb.php
+++ b/thumb.php
@@ -309,6 +309,7 @@ function wfStreamThumb( array $params ) {
                        wfThumbError( 500, 'Could not stream the file' );
                } else {
                        RequestContext::getMain()->getStats()->timing( 'media.thumbnail.stream', $streamtime );
+                       wfDebugLog( 'thumbnailaccess', time() . ' ' . $thumbPath . ' ' . ob_get_length() . ' Streamed ' );
                }
                return;
        }