Merge "RCFilters: Init highlight button based on model state"
authorjenkins-bot <jenkins-bot@gerrit.wikimedia.org>
Tue, 3 Oct 2017 22:09:15 +0000 (22:09 +0000)
committerGerrit Code Review <gerrit@wikimedia.org>
Tue, 3 Oct 2017 22:09:15 +0000 (22:09 +0000)
100 files changed:
SECURITY [new file with mode: 0644]
includes/EditPage.php
includes/Message.php
includes/OutputPage.php
includes/Preferences.php
includes/Setup.php
includes/Status.php
includes/api/i18n/ko.json
includes/parser/CoreParserFunctions.php
includes/specials/SpecialBlock.php
languages/i18n/af.json
languages/i18n/ais.json
languages/i18n/ar.json
languages/i18n/az.json
languages/i18n/azb.json
languages/i18n/be-tarask.json
languages/i18n/bg.json
languages/i18n/bn.json
languages/i18n/bs.json
languages/i18n/ca.json
languages/i18n/cdo.json
languages/i18n/ce.json
languages/i18n/cs.json
languages/i18n/de.json
languages/i18n/el.json
languages/i18n/en.json
languages/i18n/es.json
languages/i18n/et.json
languages/i18n/eu.json
languages/i18n/fi.json
languages/i18n/fr.json
languages/i18n/gor.json
languages/i18n/got.json
languages/i18n/he.json
languages/i18n/hi.json
languages/i18n/hr.json
languages/i18n/hu.json
languages/i18n/ia.json
languages/i18n/inh.json
languages/i18n/it.json
languages/i18n/jv.json
languages/i18n/ka.json
languages/i18n/kab.json
languages/i18n/ko.json
languages/i18n/ku-latn.json
languages/i18n/lb.json
languages/i18n/lzh.json
languages/i18n/mk.json
languages/i18n/ms.json
languages/i18n/mwl.json
languages/i18n/my.json
languages/i18n/nan.json
languages/i18n/nb.json
languages/i18n/nl.json
languages/i18n/nn.json
languages/i18n/pl.json
languages/i18n/ps.json
languages/i18n/pt.json
languages/i18n/qqq.json
languages/i18n/roa-tara.json
languages/i18n/ru.json
languages/i18n/sat.json
languages/i18n/sco.json
languages/i18n/sd.json
languages/i18n/skr-arab.json
languages/i18n/sl.json
languages/i18n/sr-ec.json
languages/i18n/sr-el.json
languages/i18n/su.json
languages/i18n/sv.json
languages/i18n/tg-cyrl.json
languages/i18n/th.json
languages/i18n/tl.json
languages/i18n/ur.json
languages/i18n/yi.json
languages/i18n/zh-hans.json
languages/i18n/zh-hant.json
resources/Resources.php
resources/lib/html5shiv/html5shiv.min.js [deleted file]
resources/src/mediawiki.legacy/shared.css
resources/src/mediawiki.rcfilters/dm/mw.rcfilters.dm.FilterGroup.js
resources/src/mediawiki.rcfilters/dm/mw.rcfilters.dm.FiltersViewModel.js
resources/src/mediawiki.rcfilters/dm/mw.rcfilters.dm.SavedQueriesModel.js
resources/src/mediawiki.rcfilters/mw.rcfilters.Controller.js
resources/src/mediawiki.rcfilters/mw.rcfilters.init.js
resources/src/mediawiki.rcfilters/styles/mw.rcfilters.ui.FilterMenuHeaderWidget.less
resources/src/mediawiki.rcfilters/styles/mw.rcfilters.ui.FilterTagMultiselectWidget.less
resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.FilterMenuHeaderWidget.js
resources/src/mediawiki.special/mediawiki.special.block.js
resources/src/mediawiki.special/mediawiki.special.css
resources/src/mediawiki.widgets/mw.widgets.SearchInputWidget.js
resources/src/mediawiki.widgets/mw.widgets.TitleOptionWidget.js
resources/src/mediawiki.widgets/mw.widgets.TitleWidget.js
resources/src/mediawiki.widgets/mw.widgets.TitleWidget.less
resources/src/mediawiki/mediawiki.searchSuggest.js
tests/phpunit/includes/resourceloader/ResourceLoaderClientHtmlTest.php
tests/phpunit/structure/ResourcesTest.php
tests/qunit/QUnitTestResources.php
tests/qunit/suites/resources/mediawiki.rcfilters/dm.SavedQueriesModel.test.js [new file with mode: 0644]
tests/qunit/suites/resources/mediawiki.rcfilters/dm.SavedQueryItemModel.test.js [new file with mode: 0644]

diff --git a/SECURITY b/SECURITY
new file mode 100644 (file)
index 0000000..5c6a288
--- /dev/null
+++ b/SECURITY
@@ -0,0 +1,3 @@
+MediaWiki takes security very seriously. If you believe you have found a
+security issue, see <https://www.mediawiki.org/wiki/Reporting_security_bugs>
+for information on how to responsibly report it.
index f49157f..3fc12ce 100644 (file)
@@ -4664,7 +4664,6 @@ class EditPage {
                        ];
 
                // The following classes can be used here:
-               // * mw-editfont-default
                // * mw-editfont-monospace
                // * mw-editfont-sans-serif
                // * mw-editfont-serif
index 0240fa7..d119940 100644 (file)
@@ -732,8 +732,6 @@ class Message implements MessageSpecifier, Serializable {
                        if ( !$this->language instanceof Language || $this->language->getCode() != $lang ) {
                                $this->language = Language::factory( $lang );
                        }
-               } elseif ( $lang instanceof StubUserLang ) {
-                       $this->language = false;
                } else {
                        $type = gettype( $lang );
                        throw new MWException( __METHOD__ . " must be "
index 7c463b6..5d9006a 100644 (file)
@@ -2923,15 +2923,14 @@ class OutputPage extends ContextSource {
                $pieces = array_merge( $pieces, array_values( $this->getHeadLinksArray() ) );
                $pieces = array_merge( $pieces, array_values( $this->mHeadItems ) );
 
-               $min = ResourceLoader::inDebugMode() ? '' : '.min';
                // Use an IE conditional comment to serve the script only to old IE
                $pieces[] = '<!--[if lt IE 9]>' .
-                       Html::element( 'script', [
-                               'src' => self::transformResourcePath(
-                                       $this->getConfig(),
-                                       "/resources/lib/html5shiv/html5shiv{$min}.js"
-                               ),
-                       ) .
+                       ResourceLoaderClientHtml::makeLoad(
+                               ResourceLoaderContext::newDummyContext(),
+                               [ 'html5shiv' ],
+                               ResourceLoaderModule::TYPE_SCRIPTS,
+                               [ 'sync' => true ]
+                       ) .
                        '<![endif]-->';
 
                $pieces[] = Html::closeElement( 'head' );
index a7e6684..96b002b 100644 (file)
@@ -847,7 +847,6 @@ class Preferences {
                                        $context->msg( 'editfont-monospace' )->text() => 'monospace',
                                        $context->msg( 'editfont-sansserif' )->text() => 'sans-serif',
                                        $context->msg( 'editfont-serif' )->text() => 'serif',
-                                       $context->msg( 'editfont-default' )->text() => 'default',
                                ]
                        ];
                }
@@ -935,6 +934,12 @@ class Preferences {
                $defaultPreferences['rcfilters-wl-saved-queries'] = [
                        'type' => 'api',
                ];
+               $defaultPreferences['rcfilters-saved-queries-versionbackup'] = [
+                       'type' => 'api',
+               ];
+               $defaultPreferences['rcfilters-wl-saved-queries-versionbackup'] = [
+                       'type' => 'api',
+               ];
                $defaultPreferences['rcfilters-rclimit'] = [
                        'type' => 'api',
                ];
index 68e3d96..0be5c6e 100644 (file)
@@ -811,7 +811,7 @@ $wgUser = RequestContext::getMain()->getUser(); // BackCompat
 /**
  * @var Language $wgLang
  */
-$wgLang = new StubUserLang;
+$wgLang = RequestContext::getMain()->getLanguage(); // BackCompat
 
 /**
  * @var OutputPage $wgOut
index a35af6e..5456ed0 100644 (file)
@@ -153,12 +153,9 @@ class Status extends StatusValue {
         * @return Language
         */
        protected function languageFromParam( $lang ) {
-               global $wgLang;
-
                if ( $lang === null ) {
-                       // @todo: Use RequestContext::getMain()->getLanguage() instead
-                       return $wgLang;
-               } elseif ( $lang instanceof Language || $lang instanceof StubUserLang ) {
+                       return RequestContext::getMain()->getLanguage();
+               } elseif ( $lang instanceof Language ) {
                        return $lang;
                } else {
                        return Language::factory( $lang );
index edcd41b..df5a1ec 100644 (file)
        "apihelp-watch-example-watch": "<kbd>대문</kbd> 문서를 주시합니다.",
        "apihelp-watch-example-unwatch": "<kbd>대문</kbd> 문서의 주시를 해제합니다.",
        "apihelp-watch-example-generator": "일반 이름공간의 일부 첫 문서들을 주시합니다.",
+       "apihelp-format-example-generic": "쿼리 결과를 $1 포맷으로 반환합니다.",
        "apihelp-json-summary": "데이터를 JSON 형식으로 출력합니다.",
        "apihelp-json-param-formatversion": "출력 형식:\n;1:하위 호환 포맷 (XML 스타일 불린, 콘텐츠 노드를 위한 <samp>*</samp> 키 등).\n;2:실험적인 모던 포맷. 상세 내용은 바뀔 수 있습니다!\n;latest:최신 포맷(현재 <kbd>2</kbd>)을 이용하지만 경고 없이 바뀔 수 있습니다.",
        "apihelp-jsonfm-summary": "데이터를 JSON 포맷으로 출력합니다. (HTML의 가독성 증가)",
index 3d26262..bebf3f8 100644 (file)
@@ -493,7 +493,7 @@ class CoreParserFunctions {
         *
         * @param int|float $num
         * @param string $raw
-        * @param Language|StubUserLang $language
+        * @param Language $language
         * @return string
         */
        public static function formatRaw( $num, $raw, $language ) {
index c1a1f78..42e7040 100644 (file)
@@ -224,6 +224,7 @@ class SpecialBlock extends FormSpecialPage {
                        'type' => 'hidden',
                        'default' => '',
                        'label-message' => 'ipb-confirm',
+                       'cssclass' => 'mw-block-confirm',
                ];
 
                $this->maybeAlterFormDefaults( $a );
index 16890a2..dc93bb1 100644 (file)
@@ -70,7 +70,6 @@
        "underline-never": "Nooit",
        "underline-default": "Omslag of webblaaier se verstekwaarde",
        "editfont-style": "Lettertipe vir wysigingsvenster:",
-       "editfont-default": "Blaaierverstek",
        "editfont-monospace": "Monospaced lettertipe",
        "editfont-sansserif": "Sans-serif lettertipe",
        "editfont-serif": "Serif lettertipe",
index 9c209fe..8cdb2ce 100644 (file)
@@ -38,7 +38,6 @@
        "underline-never": "amana kanca caay",
        "underline-default": "Skin or browser default",
        "editfont-style": "mikawaway-kalumyiti subal kataci nu silit a yangse:",
-       "editfont-default": "saazih sakaluk pataayaw tu kawaw a sulyang",
        "editfont-monospace": "malecad ilaed a kataci nu silit",
        "editfont-sansserif": "pacabay tu telay a kataci nu sulit",
        "sunday": "pilipayan",
index c97f1f0..d157c87 100644 (file)
        "underline-never": "أبدا",
        "underline-default": "وفق المظهر أو المتصفح",
        "editfont-style": "طراز خط صندوق التحرير:",
-       "editfont-default": "وفق إعدادات المتصفح",
        "editfont-monospace": "خط ثابت العرض",
        "editfont-sansserif": "خط بلا زوائد",
        "editfont-serif": "خط بزوائد",
index b8ba45b..0c873d5 100644 (file)
        "tog-enotifminoredits": "Səhifələrdə kiçik dəyişikliklər olsa belə, mənə e-məktub göndər",
        "tog-enotifrevealaddr": "Xəbərdarlıq e-məktublarında mənim e-poçt ünvanımı göstər",
        "tog-shownumberswatching": "İzləyən istifadəçilərin sayını göstər",
-       "tog-oldsig": "İndiki imza:",
+       "tog-oldsig": "Sizin indiki imzanız:",
        "tog-fancysig": "Vikimətn şəklində imza (avtomatik keçid yaratmadan)",
-       "tog-uselivepreview": "Canlı sınaq baxışını istifadə et",
+       "tog-uselivepreview": "Səhifəni yenidən yükləmədən sınaq baxışını istifadə et",
        "tog-forceeditsummary": "Qısa məzmunu boş saxladıqda mənə bildir",
        "tog-watchlisthideown": "Mənim redaktələrimi izləmə siyahısında gizlət",
        "tog-watchlisthidebots": "Bot redaktələrini izləmə siyahısında gizlət",
        "tog-watchlisthideminor": "İzləmə səhifəmdə kiçik redaktələri gizlət",
        "tog-watchlisthideliu": "Qeydiyyatlı istifadəçilərin redaktələrini izləmə siyahısında gizlət",
+       "tog-watchlistreloadautomatically": "Hər dəfə filtr dəyişəndə, izləmə siyahısını avtomatik yenilə (JavaScript tələb olunur)",
+       "tog-watchlistunwatchlinks": "İzləmə siyahısındakı səhifələrə birbaşa izləmə/izlə keçidləri əlavə et (JavaScript tələb olunur)",
        "tog-watchlisthideanons": "Qeydiyyatdan keçməmiş istifadəçilərin redaktələrini izləmə siyahısında gizlət",
        "tog-watchlisthidepatrolled": "Yoxlanılmış redaktələri izləmə siyahısında gizlət",
+       "tog-watchlisthidecategorization": "Səhifələrin kateqoriyalaşdırmasını gizlət",
        "tog-ccmeonemails": "Göndərdiyim e-məktubun nüsxələrini mənə göndər",
        "tog-diffonly": "Versiyaların müqayisəsi zamanı səhifənin məzmununu göstərmə",
        "tog-showhiddencats": "Gizli kateqoriyaları göstər",
-       "tog-norollbackdiff": "Geri qaytardıqdan sonra, edilmiş dəyişikikləri dəyişikliklər siyahısından sil",
+       "tog-norollbackdiff": "Geri qaytardıqdan sonra dəyişikliklər arasındakı fərqi göstərmə",
        "tog-useeditwarning": "Qeyd edilməmiş dəyişikliyə sahib bir dəyişiklik səhifəsindən çıxarkən məni xəbərdar et",
-       "tog-prefershttps": "Sessiya açarkən hər zaman etibarlı bağlantıdan istifadə et.",
+       "tog-prefershttps": "Daxil olarkən hər zaman mühafizə edilən bağlantıdan istifadə et.",
        "underline-always": "Həmişə",
        "underline-never": "Heç vaxt",
        "underline-default": "Susmaya görə brouzer",
        "editfont-style": "Redaktə sahəsinin şrift növü:",
-       "editfont-default": "Brauzerin tənzimləmələrində təsdiq olunmuş şrift",
        "editfont-monospace": "Bərabərenli şrift",
        "editfont-sansserif": "Sans-serif şrifti",
        "editfont-serif": "Serif şrifti",
        "october-date": "$1 Oktyabr",
        "november-date": "$1 Noyabr",
        "december-date": "$1 Dekabr",
+       "period-am": "GƏ",
+       "period-pm": "GS",
        "pagecategories": "$1 {{PLURAL:$1|Kateqoriya|Kateqoriya}}",
        "category_header": "\"$1\" kateqoriyasındakı məqalələr",
        "subcategories": "Alt kateqoriyalar",
        "newwindow": "(yeni pəncərədə açılır)",
        "cancel": "Ləğv et",
        "moredotdotdot": "Daha çox...",
-       "morenotlisted": "Bu siyahı tam deyil.",
+       "morenotlisted": "Bu siyahı tam olmaya bilər.",
        "mypage": "Səhifə",
        "mytalk": "Müzakirə",
        "anontalk": "Müzakirə",
        "shown-title": "Səhifə üçün $1 {{PLURAL:$1|nəticə|nəticəyə}} bax",
        "viewprevnext": "Göstər ($1 {{int:pipe-separator}} $2) ($3).",
        "searchmenu-exists": "'''Bu vikidə \"[[:$1]]\" adında səhifə mövcuddur'''",
-       "searchmenu-new": "<strong>Bu vikidə \"[[:$1]]\" səhifəsini yarat!</strong> {{PLURAL:$2|0=|Həmçinin, axtarışınız əsasında çıxan səhifəyə baxın.|Həmçinin, axtarışınız əsasında çıxan nəticələrə baxın.}}",
+       "searchmenu-new": "<strong>Bu viki-layihədə \"[[:$1]]\" səhifəsini yaradın!</strong> {{PLURAL:$2|0=|Həmçinin, axtarışınız əsasında çıxan səhifəyə baxın.|Həmçinin, axtarışınız əsasında çıxan nəticələrə baxın.}}",
        "searchprofile-articles": "Məzmun səhifələri",
        "searchprofile-images": "Multimedia",
        "searchprofile-everything": "Hər şey",
        "rcfilters-savedqueries-remove": "Sil",
        "rcfilters-savedqueries-new-name-label": "Ad",
        "rcfilters-savedqueries-new-name-placeholder": "Filtrin məqsədini təsvir edin",
+       "rcfilters-savedqueries-apply-label": "Filtr yarat",
        "rcfilters-savedqueries-apply-and-setdefault-label": "Standart filtr yarat",
        "rcfilters-savedqueries-cancel-label": "Ləğv et",
        "rcfilters-savedqueries-add-new-title": "Hazırkı filtr nizamlamalarını yaddaşa ver",
index ea60820..6011c4e 100644 (file)
@@ -70,7 +70,6 @@
        "underline-never": "هئچ واخت",
        "underline-default": "وارساییلان قابیق یا براوزِر",
        "editfont-style": "دَییشدیرمه قۇتوسونون فوْنتو:",
-       "editfont-default": "براوزِر وارساییلانی",
        "editfont-monospace": "ثابیت آرالی فوْنت",
        "editfont-sansserif": "بۇجاق‌سیز فوْنت",
        "editfont-serif": "بۇجاق‌لی فوْنت",
index fefbfa6..438b3dc 100644 (file)
@@ -67,7 +67,6 @@
        "underline-never": "Ніколі",
        "underline-default": "Паводле браўзэра або афармленьня",
        "editfont-style": "Стыль шрыфту ў полі рэдагаваньня:",
-       "editfont-default": "Паводле браўзэра",
        "editfont-monospace": "Роўнашырокі шрыфт",
        "editfont-sansserif": "Шрыфт без засечак",
        "editfont-serif": "Шрыфт з засечкамі",
        "ipb_blocked_as_range": "Памылка: IP-адрас $1 быў заблякаваны наўпрост і ня можа быць разблякаваны.\nТым ня менш, ён належыць да дыяпазону $2, які можа быць разблякаваны.",
        "ip_range_invalid": "Некарэктны дыяпазон IP-адрасоў.",
        "ip_range_toolarge": "Блякаваньні дыяпазонаў, большых за /$1, не дазволеныя.",
+       "ip_range_exceeded": "IP-дыяпазон перавышае максымальна дазволены дыяпазон. Дазволены дыяпазон: /$1.",
        "proxyblocker": "Блякаваньне проксі",
        "proxyblockreason": "Ваш IP-адрас быў заблякаваны таму што ён належыць адкрытаму проксі.\nКалі ласка, зьвяжыцеся з Вашым Інтэрнэт-правайдарам альбо са службай тэхнічнай падтрымкі і паведаміце ім пра гэтую сур'ёзную праблему бясьпекі.",
        "sorbsreason": "Ваш IP-адрас знаходзіцца ў сьпісе адкрытых проксі ў DNSBL, якім карыстаецца {{SITENAME}}.",
index fa1a6eb..fdef7a5 100644 (file)
@@ -92,7 +92,6 @@
        "underline-never": "Никога",
        "underline-default": "Според настройките на облика или браузъра",
        "editfont-style": "Стил на шрифта в кутията за редактиране:",
-       "editfont-default": "По подразбиране за браузъра",
        "editfont-monospace": "Равноширок шрифт",
        "editfont-sansserif": "Несерифен шрифт",
        "editfont-serif": "Серифен шрифт",
        "right-override-export-depth": "Изнасяне на страници, включително свързаните с тях в дълбочина до пето ниво",
        "right-sendemail": "Изпращане на е-писма до другите потребители",
        "right-managechangetags": "Създаване и (де)активиране на [[Специални:Етикети|етикети]]",
+       "grant-group-page-interaction": "Взаимодействие със страници",
+       "grant-group-file-interaction": "Взаимодействие с медийни файлове",
+       "grant-group-watchlist-interaction": "Взаимодействие с вашия списък за наблюдение",
        "grant-group-email": "Изпращане на е-писмо",
+       "grant-group-high-volume": "Извършване на активност с голям обем",
+       "grant-group-customization": "Персонализиране и предпочитания",
        "grant-group-administration": "Извършване на административни действия",
+       "grant-group-private-information": "Достъп на лични данни за Вас",
+       "grant-group-other": "Смесена дейност",
        "grant-blockusers": "Блокиране и отблокиране на потребители",
        "grant-createaccount": "Създаване на сметки",
        "grant-createeditmovepage": "Създаване, редактиране и преместване на страници",
        "recentchanges-submit": "Показване",
        "rcfilters-tag-remove": "Премахване на '$1'",
        "rcfilters-legend-heading": "<strong>Списък на съкращенията:</strong>",
+       "rcfilters-other-review-tools": "<strong>Други инструменти за проверка</strong>",
+       "rcfilters-grouping-title": "Групиране",
        "rcfilters-activefilters": "Активни филтри",
+       "rcfilters-advancedfilters": "Разширени филтри",
+       "rcfilters-limit-title": "Промени за показване",
+       "rcfilters-limit-shownum": "Показване на {{PLURAL:$1|последна промяна|$1 последни промени}}",
+       "rcfilters-days-title": "Последните дни",
+       "rcfilters-hours-title": "Последните часове",
+       "rcfilters-days-show-days": "$1 {{PLURAL:$1|ден|дни}}",
+       "rcfilters-days-show-hours": "$1 {{PLURAL:$1|час|часа}}",
+       "rcfilters-highlighted-filters-list": "Маркирани: $1",
        "rcfilters-quickfilters": "Запазени филтри",
        "rcfilters-quickfilters-placeholder-title": "Няма запазени препратки",
        "rcfilters-quickfilters-placeholder-description": "За да запазите настройките на филтрите и да ги използвате повторно по-късно, щракнете върху иконката за отметки в блока „Активни филтри“ по-долу.",
        "rcfilters-filter-lastrevision-description": "Последната промяна на страница.",
        "rcfilters-filter-previousrevision-label": "По-ранни версии",
        "rcfilters-filter-previousrevision-description": "Всички редакции, които не са последните на страница.",
+       "rcfilters-view-advanced-filters-label": "Разширени филтри",
        "rcnotefrom": "{{PLURAL:$5|Дадена е промяната|Дадени са промените}} от <strong>$3, $4</strong> (до <strong>$1</strong> показани).",
        "rclistfrom": "Показване на промени, като се започва от $3 $2",
        "rcshowhideminor": "$1 на малки промени",
        "apisandbox-dynamic-parameters-add-label": "Добавяне на параметър:",
        "apisandbox-dynamic-parameters-add-placeholder": "Име на параметъра",
        "apisandbox-dynamic-error-exists": "Параметър с име „$1“ вече съществува.",
+       "apisandbox-submit-invalid-fields-title": "Някои полета са невалидни",
+       "apisandbox-submit-invalid-fields-message": "Моля, поправете маркираните полета и опитайте пак.",
        "apisandbox-results": "Резултати",
+       "apisandbox-sending-request": "Изпращане на API заявка...",
+       "apisandbox-loading-results": "Получаване на API резултати...",
        "apisandbox-request-url-label": "URL-адрес на заявката:",
+       "apisandbox-request-time": "Време на заявката: {{PLURAL:$1|$1 ms}}",
        "apisandbox-continue": "Продължаване",
        "apisandbox-continue-clear": "Изчистване",
        "apisandbox-multivalue-all-namespaces": "$1 (Всички именни пространства)",
        "logempty": "Дневникът не съдържа записи, отговарящи на избрания критерий.",
        "log-title-wildcard": "Търсене на заглавия, започващи със",
        "showhideselectedlogentries": "Промяна на видимостта на избраните записи",
+       "log-edit-tags": "Редактиране на етикетите на избраните записи в дневника",
        "checkbox-select": "Избор: $1",
        "checkbox-all": "Всички",
        "checkbox-none": "Никои",
        "enotif_lastdiff": "Преглед на тази промяна: $1.",
        "enotif_anon_editor": "анонимен потребител $1",
        "enotif_body": "Уважаеми(а) $WATCHINGUSERNAME,\n\n$PAGEINTRO $NEWPAGE\n\nРезюме на редакцията: $PAGESUMMARY $PAGEMINOREDIT\n\nВръзка с редактора:\n* електронна поща: $PAGEEDITOR_EMAIL\n* уики страница: $PAGEEDITOR_WIKI\n\nНяма да получавате други известия за последващи промени, докато не посетите страницата докато акаунтът ви е влязъл в системата.\nМожете да актуализиране настройките си за този вид известия за всички страници от вашия списък за наблюдение.\n\nСистемата за известяване на {{SITENAME}}\n\n--\nПромяна на настройките за известявания чрез електронна поща може да се извърши на\n{{canonicalurl:{{#special:Preferences}}}}\n\nПромяна на настройките на списъка за наблюдение се извършва на\n{{canonicalurl:{{#special:EditWatchlist}}}}\n\nИзтриването на тази страницата от списъка за наблюдение става чрез \n$UNWATCHURL\n\nЗа обратна връзка и помощ:\n$HELPPAGE",
+       "enotif_minoredit": "Това е малка промяна",
        "created": "създадена",
        "changed": "променена",
        "deletepage": "Изтриване",
        "changecontentmodel-success-text": "Типът на съдържанието на [[:$1]] е успешно променен.",
        "log-name-contentmodel": "Дневник на промените на модела на съдържанието",
        "log-description-contentmodel": "Страницата показва промените в модела на съдържанието на страниците и страниците, създадени с модел на съдържанието различен от този по подразбиране.",
+       "logentry-contentmodel-new": "$1 {{GENDER:$2|създаде}} страницата $3, използвайки модел на съдържанието „$5“, който не е по подразбиране",
        "logentry-contentmodel-change-revertlink": "връщане",
        "logentry-contentmodel-change-revert": "връщане",
        "protectlogpage": "Дневник на защитата",
        "modifiedarticleprotection": "смени нивото на защита на „[[$1]]“",
        "unprotectedarticle": "свали защитата на „[[$1]]“",
        "movedarticleprotection": "премести настройките на защита от „[[$2]]“ на „[[$1]]“",
+       "protectedarticle-comment": "{{GENDER:$2|Защити}} „[[$1]]“",
+       "modifiedarticleprotection-comment": "{{GENDER:$2|Промени нивото на защита}} за „[[$1]]“",
+       "unprotectedarticle-comment": "{{GENDER:$2|Премахна защитата}} от „[[$1]]“",
        "protect-title": "Смяна на нивото на защита на „$1“",
        "protect-title-notallowed": "Преглеждане нивото на защита за „$1“",
        "prot_1movedto2": "„[[$1]]“ преместена като „[[$2]]“",
        "protect-badnamespace-title": "Незащитимо именно пространство",
        "protect-badnamespace-text": "Страниците в това именно пространство не могат да бъдат защитени.",
+       "protect-norestrictiontypes-text": "Тази страница не може да бъде защитена, тъй като няма налични видове ограничение.",
        "protect-norestrictiontypes-title": "Незащитима страница",
        "protect-legend": "Потвърждение на защитата",
        "protectcomment": "Причина:",
        "undelete-search-title": "Търсене на изтрити страници",
        "undelete-search-box": "Търсене на изтрити страници",
        "undelete-search-prefix": "Показване на страници, започващи със:",
+       "undelete-search-full": "Показване на заглавия на страници, съдържащи:",
        "undelete-search-submit": "Търсене",
        "undelete-no-results": "Не са намерени страници, отговарящи на търсения критерий.",
        "undelete-filename-mismatch": "Не е възможно възстановяването на файловата версия с времева отметка $1: несъответствие в името на файла",
        "tooltip-pt-mycontris": "Списък на {{GENDER:|вашите}} приноси",
        "tooltip-pt-anoncontribs": "Списък на промените, направени от този IP адрес",
        "tooltip-pt-login": "Препоръчваме Ви да влезете, въпреки, че не е задължително.",
+       "tooltip-pt-login-private": "Трябва да се влезли, за да използвате това Уики",
        "tooltip-pt-logout": "Излизане",
        "tooltip-pt-createaccount": "Насърчаваме Ви да си създадете сметка и да влезете, въпреки че не е задължително.",
        "tooltip-ca-talk": "Беседа за страницата",
        "pageinfo-robot-index": "Позволено",
        "pageinfo-robot-noindex": "Непозволено",
        "pageinfo-watchers": "Брой наблюдаващи страницата",
+       "pageinfo-visiting-watchers": "Брой наблюдаващи страницата, които са посетили последните промени",
        "pageinfo-few-watchers": "Под $1 {{PLURAL:$1|наблюдаващ|наблюдаващи}}",
        "pageinfo-redirects-name": "Брой пренасочвания към тази страница",
        "pageinfo-subpages-name": "Подстраници на тази страница",
        "log-show-hide-patrol": "$1 на дневника на патрула",
        "log-show-hide-tag": "$1 на дневника на отбелязванията",
        "confirm-markpatrolled-button": "Добре",
+       "confirm-markpatrolled-top": "Маркиране на редакция $3 на $2 като патрулирана?",
        "deletedrevision": "Изтрита стара версия $1",
        "filedeleteerror-short": "Грешка при изтриване на файл: $1",
        "filedeleteerror-long": "Възникнаха грешки при изтриването на файла:\n\n$1",
        "newimages-legend": "Филтриране",
        "newimages-label": "Име на файл (или част от него):",
        "newimages-user": "IP-адрес или потребителско име",
+       "newimages-newbies": "Показване на приносите само на нови потребители",
        "newimages-showbots": "Показване на качвания от ботове",
        "newimages-hidepatrolled": "Скриване на проверените качвания",
        "noimages": "Няма нищо.",
        "confirm-unwatch-button": "Потвърждаване",
        "confirm-unwatch-top": "Премахване на страницата от списъка ви за наблюдение?",
        "confirm-rollback-button": "OK",
+       "confirm-rollback-top": "Отменяне на редакции по тази страница?",
        "quotation-marks": "„$1“",
        "imgmultipageprev": "← предишна страница",
        "imgmultipagenext": "следваща страница →",
        "tags-delete-reason": "Причина:",
        "tags-delete-submit": "Необратимо изтриване на етикета",
        "tags-delete-not-found": "Етикет „$1“ не съществува.",
+       "tags-delete-too-many-uses": "Етикетът „$1“ е приложен към повече от $2 {{PLURAL:$2|редакция|редакции}}, което означава, че не може да бъде изтрит.",
+       "tags-delete-no-permission": "Нямате права за изтриване на етикети на промените.",
        "tags-activate-title": "Активиране на етикета",
+       "tags-activate-question": "На път сте да активирате етикет „$1“.",
        "tags-activate-reason": "Причина:",
        "tags-activate-not-allowed": "Етикет „$1“ не може  да бъде активиран.",
        "tags-activate-not-found": "Етикет „$1“ не съществува.",
        "tags-edit-success": "Промените са приложени.",
        "tags-edit-failure": "Промените не могат да бъдат приложени:\n$1",
        "tags-edit-nooldid-title": "Не е зададена версия",
+       "tags-edit-none-selected": "Моля, изберете поне един етикет за добавяне или премахване.",
        "comparepages": "Сравняване на страници",
        "compare-page1": "Страница 1",
        "compare-page2": "Страница 2",
        "compare-title-not-exists": "Посоченото заглавие не съществува.",
        "compare-revision-not-exists": "Посочената версия не съществува.",
        "diff-form": "'''формуляр'''",
+       "permanentlink": "Постоянна препратка",
+       "permanentlink-revid": "ID на редакцията",
+       "permanentlink-submit": "Към редакцията",
        "dberr-problems": "Съжаляваме! Сайтът изпитва технически затруднения.",
        "dberr-again": "Изчакайте няколко минути и опитайте да презаредите.",
        "dberr-info": "(Няма достъп до базата от данни: $1)",
        "logentry-delete-delete": "$1 {{GENDER:$2|изтри}} страницата $3",
        "logentry-delete-delete_redir": "$1 {{GENDER:$2|изтри}} пренасочване $3 чрез препокриване",
        "logentry-delete-restore": "$1 {{GENDER:$2|възстанови}} страницата $3 ($4)",
+       "logentry-delete-restore-nocount": "$1 {{GENDER:$2|възстанови}} страница $3",
+       "restore-count-revisions": "{{PLURAL:$1|1 редакция|$1 редакции}}",
+       "restore-count-files": "{{PLURAL:$1|1 файл|$1 файла}}",
        "logentry-delete-event": "$1 {{GENDER:$2|промени}} видимостта на {{PLURAL:$5|едно събитие|$5 събития}} от дневника в $3: $4",
        "logentry-delete-revision": "$1 {{GENDER:$2|промени}} видимостта на {{PLURAL:$5|една редакция|$5 редакции}} в страница $3: $4",
        "logentry-delete-event-legacy": "$1 {{GENDER:$2|промени}} видимостта на събитията от дневниците за страница $3",
        "revdelete-restricted": "добавени ограничения за администраторите",
        "revdelete-unrestricted": "премахнати ограничения за администраторите",
        "logentry-block-block": "$1 {{GENDER:$2|блокира }} {{GENDER:$4|$3}} със срок на изтичане $5 $6",
+       "logentry-block-unblock": "$1 {{GENDER:$2|отблокира}} {{GENDER:$4|$3}}",
        "logentry-block-reblock": "$1 {{GENDER:$2|промени }} настройките на блокиране на {{GENDER:$4|$3}} със срок на изтичане $5 $6",
        "logentry-suppress-block": "$1 {{GENDER:$2|блокира}} {{GENDER:$4|$3}} със срок на изтичане $5 $6",
        "logentry-suppress-reblock": "$1 {{GENDER:$2|промени}} настройките на блокиране на {{GENDER:$4|$3}} със срок на изтичане $5 $6",
+       "logentry-merge-merge": "$1 {{GENDER:$2|сля}} $3 с $4 (редакции до $5)",
        "logentry-move-move": "$1 {{GENDER:$2|премести}} страница „$3“ като „$4“",
        "logentry-move-move-noredirect": "$1 {{GENDER:$2|премести}} страницата „$3“ като „$4“ без пренасочване",
        "logentry-move-move_redir": "$1 {{GENDER:$2|премести}} страницата $3 като $4 (върху пренасочване)",
        "log-name-managetags": "Дневник на управлението на етикети",
        "log-description-managetags": "На тази страница са изброени задачи, свързани с управлението на [[Special:Tags|етикети]]. Дневникът съдържа само действия, извършвани ръчно от администратор. Етикети могат да бъдат създавани или изтривани от уики софтуера без това да бъде отразено в този дневник.",
        "logentry-managetags-create": "$1 {{GENDER:$2|създаде}} етикета „$4“",
+       "logentry-managetags-delete": "$1 {{GENDER:$2|изтри}} етикета „$4“ (премахнат от $5 {{PLURAL:$5|редакция или запис в дневника|редакции и/или записа в дневника}})",
+       "logentry-managetags-activate": "$1 {{GENDER:$2|активира}} етикета „$4“ за използване от потребители и ботове",
+       "logentry-managetags-deactivate": "$1 {{GENDER:$2|деактивира}} етикета „$4“ за използване от потребители и ботове",
        "log-name-tag": "Дневник на етикетите",
        "log-description-tag": "Тази страница показва, кога потребителите са добавили или премахнали [[Special:Tags|етикети]] от отделни версии или записи. Списъкът не включва подобни действия, когато те се появяват, като част от процеса на редактиране, изтриване или подобни действия.",
+       "logentry-tag-update-add-revision": "$1 {{GENDER:$2|добави}} {{PLURAL:$7|етикета|етикетите}} $6 към редакция $4 на страница $3",
+       "logentry-tag-update-add-logentry": "$1 {{GENDER:$2|добави}} {{PLURAL:$7|етикета|етикетите}} $6 към записа в дневника $5 на страница $3",
        "rightsnone": "(никакви)",
        "feedback-adding": "Добавяне на коментар към страницата...",
        "feedback-back": "Обратно",
        "right-pagelang": "Промяна езика на страница",
        "action-pagelang": "промяна езика на страницата",
        "log-name-pagelang": "Дневник на езиковите промени",
+       "logentry-pagelang-pagelang": "$1 {{GENDER:$2|промени}} езика на $3 от $4 на $5",
        "default-skin-not-found-row-enabled": "* <code>$1</code> / $2 (включено)",
        "default-skin-not-found-row-disabled": "* <code>$1</code> / $2 (<strong>изключено</strong>)",
        "mediastatistics": "Статистика за файлове",
        "mw-widgets-usersmultiselect-placeholder": "Добавяне на още...",
        "date-range-from": "От дата:",
        "date-range-to": "До дата:",
+       "sessionprovider-generic": "$1 сесии",
        "randomrootpage": "Случайна основна страница",
        "log-action-filter-block": "Вид на блокирането:",
        "log-action-filter-delete": "Вид на изтриването:",
+       "log-action-filter-import": "Вид внасяне:",
+       "log-action-filter-managetags": "Вид на управлението на етикета:",
+       "log-action-filter-move": "Вид на преместването:",
        "log-action-filter-newusers": "Вид на създаването на акаунт:",
+       "log-action-filter-patrol": "Вид патрулиране:",
        "log-action-filter-protect": "Тип защита:",
        "log-action-filter-rights": "Вид на промяната на правата за достъп:",
        "log-action-filter-upload": "Тип качване:",
        "log-action-filter-contentmodel-change": "Промяна на модела на съдържанието",
        "log-action-filter-delete-delete": "Изтриване на страница",
        "log-action-filter-delete-restore": "Възстановяване на страница",
-       "log-action-filter-managetags-create": "Създаване на етикети",
+       "log-action-filter-managetags-create": "Създаване на етикет",
        "log-action-filter-managetags-delete": "Премахване на етикет",
        "log-action-filter-managetags-activate": "Активиране на етикет",
        "log-action-filter-managetags-deactivate": "Деактивиране на етикет",
        "log-action-filter-newusers-autocreate": "Автоматично създаване",
+       "log-action-filter-patrol-patrol": "Ръчно патрулиране",
+       "log-action-filter-patrol-autopatrol": "Автоматично патрулиране",
        "log-action-filter-protect-protect": "Защита",
        "log-action-filter-protect-unprotect": "Сваляне на защитата",
        "log-action-filter-rights-rights": "Ръчна промяна",
index 0cd2cac..574d73a 100644 (file)
@@ -34,7 +34,8 @@
                        "NahidSultan",
                        "Elias Ahmmad",
                        "Catrope",
-                       "Mohammed Galib Hasan"
+                       "Mohammed Galib Hasan",
+                       "এম আবু সাঈদ"
                ]
        },
        "tog-underline": "সংযোগের নিচে দাগ দেখানো হোক:",
@@ -85,7 +86,6 @@
        "underline-never": "কখনো নয়",
        "underline-default": "স্কিন অথবা ব্রাউজারে যেমনভাবে নির্দিষ্ট করা আছে",
        "editfont-style": "সম্পাদনা এলাকার ফন্ট শৈলী:",
-       "editfont-default": "ব্রাউজার দ্বারা পূর্বনির্ধারিত",
        "editfont-monospace": "মনোস্পেস ফন্ট",
        "editfont-sansserif": "স্যান্স-সেরিফ ফন্ট",
        "editfont-serif": "সেরিফ ফন্ট",
        "timezoneregion-indian": "ভারত মহাসাগর",
        "timezoneregion-pacific": "প্রশান্ত মহাসাগর",
        "allowemail": "অন্য ব্যবহারকারীদেরকে আপনাকে ই-মেইল পাঠানোর অনুমতি দিন।",
-       "email-blacklist-label": "à¦\86মাà¦\95à§\87 à¦\87মà§\87à¦\87ল à¦ªà¦¾à¦ à¦¾à¦¨à§\8b à¦¥à§\87à¦\95à§\87 à¦\8fà¦\87 à¦¬à§\8dযবহারà¦\95ারà§\80দà§\87র à¦¨à¦¿à¦·à¦¿à¦¦à§\8dধ à¦\95রুন:",
+       "email-blacklist-label": "à¦\86মাà¦\95à§\87 à¦\87মà§\87à¦\87ল à¦ªà¦¾à¦ à¦¾à¦¨à§\8b à¦¥à§\87à¦\95à§\87 à¦\8fà¦\87 à¦¬à§\8dযবহারà¦\95ারà§\80দà§\87র à¦¬à¦¿à¦°à¦¤ à¦°à¦¾à¦\96ুন:",
        "prefs-searchoptions": "অনুসন্ধান",
        "prefs-namespaces": "নামস্থানসমূহ",
        "default": "পূর্বনির্ধারিত",
index a207a60..fbf07bd 100644 (file)
@@ -77,7 +77,6 @@
        "underline-never": "Nikad",
        "underline-default": "Prema predodređenim postavkama teme ili preglednika",
        "editfont-style": "Stil fonta u okviru za uređivanje:",
-       "editfont-default": "Po postavkama preglednika",
        "editfont-monospace": "Neproporcionalni font",
        "editfont-sansserif": "Beserifni font",
        "editfont-serif": "Serifni font",
index 21a5555..da172aa 100644 (file)
        "underline-never": "Mai",
        "underline-default": "Per defecte del navegador",
        "editfont-style": "Estil de lletra en edició:",
-       "editfont-default": "Per defecte del navegador",
        "editfont-monospace": "Lletra monoespaiada",
        "editfont-sansserif": "Lletra de pal sec",
        "editfont-serif": "Lletra amb gràcia",
index 3262876..94c0132 100644 (file)
@@ -60,7 +60,6 @@
        "underline-never": "頭𡅏無",
        "underline-default": "皮膚或者瀏覽器默認其",
        "editfont-style": "編輯框其字體其樣式",
-       "editfont-default": "瀏覽器默認",
        "editfont-monospace": "蜀様寬其字體",
        "editfont-sansserif": "無襯線其字體",
        "editfont-serif": "有襯線其字體",
index 55c158a..508b3a6 100644 (file)
@@ -62,7 +62,6 @@
        "underline-never": "Цкъа а",
        "underline-default": "Лелае браузеран нисярца",
        "editfont-style": "Тадар чохь долу шрифт:",
-       "editfont-default": "Браузеран гӀирса чура шрифт",
        "editfont-monospace": "Цхьатерра доцу шрифт",
        "editfont-sansserif": "Аьтта доцу шрифт",
        "editfont-serif": "Аьтта долу шрифт",
index 4507c3a..59bb7f6 100644 (file)
@@ -87,7 +87,6 @@
        "underline-never": "Nikdy",
        "underline-default": "Podle nastavení prohlížeče nebo vzhledu",
        "editfont-style": "Druh písma v editačním poli:",
-       "editfont-default": "Podle nastavení prohlížeče",
        "editfont-monospace": "Neproporcionální písmo",
        "editfont-sansserif": "Bezpatkové písmo",
        "editfont-serif": "Patkové písmo",
        "ipb_blocked_as_range": "Chyba: IP adresa $1 není blokována přímo, a tak ji nelze odblokovat. Je částí zablokovaného rozsahu $2, který může být odblokován.",
        "ip_range_invalid": "Neplatný IP rozsah.",
        "ip_range_toolarge": "Blokování rozsahů větších než /$1 není dovoleno.",
+       "ip_range_exceeded": "Rozsah IP adres překročil maximální velikost. Dovolený rozsah: /$1.",
+       "ip_range_toolow": "Rozsahy IP adres jsou v podstatě zakázány.",
        "proxyblocker": "Blokování proxy serverů",
        "proxyblockreason": "Vaše IP adresa byla zablokována, protože funguje jako otevřený proxy server. Kontaktujte svého poskytovatele internetového připojení nebo technickou podporu a informujte je o tomto vážném bezpečnostním problému.",
        "sorbsreason": "Vaše IP adresa je uvedena na seznamu DNSBL jako otevřený proxy server.",
index 3c7a644..c5ee624 100644 (file)
        "underline-never": "nie",
        "underline-default": "abhängig von der Benutzeroberfläche oder Browsereinstellung",
        "editfont-style": "Schriftart für den Text im Bearbeitungsfenster:",
-       "editfont-default": "Browserstandard",
        "editfont-monospace": "Schrift mit fester Zeichenbreite",
        "editfont-sansserif": "Schrift ohne Serifen",
        "editfont-serif": "Schrift mit Serifen",
index ca88d80..4a2e3f5 100644 (file)
        "underline-never": "Ποτέ",
        "underline-default": "Προεπιλογή από θέμα εμφάνισης ή από περιηγητή",
        "editfont-style": "Στυλ γραμματοσειράς της περιοχής επεξεργασίας:",
-       "editfont-default": "Προεπιλογή περιηγητή",
        "editfont-monospace": "Γραμματοσειρά με σταθερό πλάτος χαρακτήρων",
        "editfont-sansserif": "Γραμματοσειρά χωρίς ουρές",
        "editfont-serif": "Γραμματοσειρά με ουρές",
        "addedwatchtext": "Η σελίδα «[[:$1]]» και η σελίδα συζήτησής της προστέθηκαν στη [[Special:Watchlist|λίστα παρακολούθησής σας]].",
        "addedwatchtext-short": "Η σελίδα «$1» έχει προστεθεί στην λίστα παρακολούθησής σας.",
        "removewatch": "Αφαίρεση από τη λίστα παρακολούθησης",
-       "removedwatchtext": "Το Î»Î®Î¼Î¼Î± Â«[[:$1]]» ÎºÎ±Î¹ Î· Ï\83ελίδα Ï\83Ï\85ζήÏ\84ηÏ\83ήÏ\82 Ï\84οÏ\85 Î­Ï\87οÏ\85ν Î±Ï\86αιÏ\81εθεί από τη [[Special:Watchlist|λίστα παρακολούθησής]] σας.",
+       "removedwatchtext": "Î\97 Ï\83ελίδα Â«[[:$1]]» ÎºÎ±Î¹ Î· Ï\83ελίδα Ï\83Ï\85ζήÏ\84ηÏ\83ήÏ\82 Ï\84ηÏ\82 Î±Ï\86αιÏ\81έθηκαν από τη [[Special:Watchlist|λίστα παρακολούθησής]] σας.",
        "removedwatchtext-short": "Η σελίδα «$1» έχει αφαιρεθεί από τη λίστα παρακολούθησής σας.",
        "watch": "Παρακολούθηση",
        "watchthispage": "Παρακολούθηση αυτής της σελίδας",
index 6a95ec4..282b906 100644 (file)
@@ -51,7 +51,6 @@
        "underline-never": "Never",
        "underline-default": "Skin or browser default",
        "editfont-style": "Edit area font style:",
-       "editfont-default": "Browser default",
        "editfont-monospace": "Monospaced font",
        "editfont-sansserif": "Sans-serif font",
        "editfont-serif": "Serif font",
        "rcfilters-view-namespaces-tooltip": "Filter results by namespace",
        "rcfilters-view-tags-tooltip": "Filter results using edit tags",
        "rcfilters-view-return-to-default-tooltip": "Return to main filter menu",
+       "rcfilters-view-tags-help-icon-tooltip": "Learn more about Tagged Edits",
        "rcfilters-liveupdates-button": "Live updates",
        "rcfilters-liveupdates-button-title-on": "Turn off live updates",
        "rcfilters-liveupdates-button-title-off": "Display new changes as they happen",
index b340aea..2b63f64 100644 (file)
        "underline-never": "Nunca",
        "underline-default": "Configuración predeterminada de la apariencia o el navegador",
        "editfont-style": "Tipo de letra del área de edición:",
-       "editfont-default": "Predeterminado del navegador",
        "editfont-monospace": "Tipo de letra monoespaciado",
        "editfont-sansserif": "Tipo de letra de palo seco",
        "editfont-serif": "Tipo de letra con serifas",
index 58c8917..e3e7cac 100644 (file)
@@ -80,7 +80,6 @@
        "underline-never": "Mitte kunagi",
        "underline-default": "Kujunduse või brauseri vaikeväärtus",
        "editfont-style": "Redigeerimisala kirjatüüp:",
-       "editfont-default": "Brauseri vaikesäte",
        "editfont-monospace": "Püsisammuga font",
        "editfont-sansserif": "Seriifideta kiri",
        "editfont-serif": "Seriifidega kiri",
index 89a3ad6..f9d5187 100644 (file)
@@ -81,7 +81,6 @@
        "underline-never": "Inoiz ez",
        "underline-default": "Lehenetsitako nabigatzailea",
        "editfont-style": "Aldatu eremuko letra tipoa:",
-       "editfont-default": "Nabigatzaileak aurretik zehaztua",
        "editfont-monospace": "Monospace iturria",
        "editfont-sansserif": "Sans-serif iturria",
        "editfont-serif": "Serif iturria",
        "resetpass-temp-password": "Behin-behineko pasahitza:",
        "resetpass-abort-generic": "Estentsio batek pasahitza aldatzea ekidin du.",
        "resetpass-expired": "Zure pasahitza iraungitu da. Sartzeko, pasahitz berria ezarri, mesedez.",
+       "resetpass-expired-soft": "Zure pasahitza iraungi da eta berrezarri egin behar da. Aukeratu pasahitz berria orain edo egin klik \"{{int:authprovider-resetpass-skip-label}}\"-n geroago berrarazteko.",
        "resetpass-validity-soft": "Zure pasahitzak ez du balio: $1\n\nAukeratu beste pasahitza berri bat orain mesedez, edo \"{{int:authprovider-resetpass-skip-label}}\" klikatu geroago berrezartzeko.",
        "passwordreset": "Pasahitzaren berrezarpena",
        "passwordreset-text-one": "Bete formulario hau zure pasahitza berrezartzeko.",
        "rcfilters-highlightmenu-help": "Aukeratu kolore bat propietate hau nabarmentzeko",
        "rcfilters-filterlist-noresults": "Ez da iragazkirik aurkitu",
        "rcfilters-noresults-conflict": "Ez da emaitzarik aurkitu bilaketa-irizpideak gatazkan daudelako",
+       "rcfilters-state-message-subset": "Iragazki honek ez du eraginik bere emaitz beste hauekin agertzen baitira, {{PLURAL:$2|iragazkia|iragazkiak}} zabalago (Saiatu nabarmenduz bereizten): $1",
        "rcfilters-state-message-fullcoverage": "Talde honetako iragazki guztiak hautatzea bat ere ez hautatzea bezala da, ondorioz iragazkiak ez du eraginik izango. Taldeak barne hartzen d(it)u: $1",
        "rcfilters-filtergroup-authorship": "Ekarpenaren egiletza",
        "rcfilters-filter-editsbyself-label": "Zuk egindako aldaketak",
        "uploadscripted": "Fitxategi honek web zerbitzariak modu ezegokian interpretatu lezakeen HTML edo script kodea dauka.",
        "upload-scripted-pi-callback": "Ezin da XML-styleheet prozesatzeko instrukzioa duen fitxategia igo.",
        "upload-scripted-dtd": "Ezin dira DTD deklarazio ez estandarra duten SVG fitxategiak igo.",
+       "uploadscriptednamespace": "SVG fitxategi hau legez kanpoko \"<nowiki>$1</nowiki>\" izen eremua dauka.",
        "uploadinvalidxml": "Ezin izan da analizatu XMLa igotako fitxategian.",
        "uploadvirus": "Fitxategiak birusa dauka! Xehetasunak: $1",
        "uploadjava": "Fitxategia ZIP bat da eta Java .class fitxategi bat du.\nJava fitxategiak igotzea ez dago baimendua, segurtasun muga batzuk hausteko aukera ematen duelako.",
        "upload-form-label-own-work": "Hau neure lana da",
        "upload-form-label-infoform-categories": "Kategoriak",
        "upload-form-label-infoform-date": "Data",
+       "upload-form-label-own-work-message-generic-local": "{{SITENAME}} zerbitzuaren eta lizentzien gidalerroen jarraipena egiten dudala baieztatzen dut fitxategi hau kargatzerakoan.",
+       "upload-form-label-not-own-work-message-generic-local": "Fitxategi hau {{SITENAME}} gidalerroen arabera kargatzeko aukera ez baduzu, itxi elkarrizketa hau eta saiatu beste metodo bat.",
        "upload-form-label-not-own-work-local-generic-local": "[[Special:Upload|the default upload page]] ere agian probatu nahi duzu.",
        "upload-form-label-own-work-message-generic-foreign": "Fitxategi hau partekatutako biltegian kargatzen ari naizela ulertzen dut. Zerbitzu-baldintzak eta lizentzien gidalerroen jarraipena egiten ari naizela egiaztatzen dut.",
        "upload-form-label-not-own-work-message-generic-foreign": "Fitxategi hau partekatutako biltegiko gidalerroen arabera kargatzeko aukera ez baduzu, itxi elkarrizketa hau eta saiatu beste metodo bat.",
        "backend-fail-read": "Ezin izan da \"$1\" fitxategia irakurri.",
        "backend-fail-create": "Ezin izan da \"$1\" fitxategia idatzi.",
        "backend-fail-maxsize": "Ezin izan da idatzi \"$1\" fitxategia {{PLURAL:$2|byte bat|$2 byte}} baino handiagoa delako.",
+       "backend-fail-readonly": "$1 biltegiratze motorea irakurtzeko soilik dago orain. Emandako arrazoia: <em>$2</em>",
        "backend-fail-connect": "Ezin izan da \"$1\" gordailuaren atzeko aldearekin konektatu.",
        "backend-fail-internal": "Akats ezezaguna gertatu da \"$1\" gordailuaren atzeko aldean.",
        "backend-fail-contenttype": "Ezin izan da $1n gordeko den artxiboaren eduki mota zehaztu.",
        "listgrants-grant": "Baimena eman",
        "listgrants-rights": "Eskubideak",
        "trackingcategories": "Jarraipen kategoriak",
+       "trackingcategories-summary": "Orrialde honetan MediaWiki softwarea automatikoki betetzen duten jarraipen-kategoriak zerrendatzen dira. Izenak aldatu egin daitezke sistemako mezuak aldatuz {{ns: 8}}izen eremuan.",
        "trackingcategories-msg": "Jarraipen kategoria",
        "trackingcategories-name": "Mezuaren izena",
        "trackingcategories-desc": "Kategoria inklusio irizpideak",
        "watchlist-options": "Jarraitze-zerrendaren aukerak",
        "watching": "Zerrendan gehitzen...",
        "unwatching": "Zerrendatik kentzen...",
+       "watcherrortext": "Errore bat gertatu da \"$1\"(r)entzako zure ikus zerrendaren ezarpenak aldatzean.",
        "enotif_reset": "Orrialde guztiak bisitatu bezala markatu",
        "enotif_impersonal_salutation": "{{SITENAME}} erabiltzailea",
        "enotif_subject_deleted": "{{SITENAME}}(e)ko $1 orrialdea {{GENDER:$2|ezabatu}} du $2 erabiltzaileak",
        "alreadyrolled": "Ezin da [[User:$2|$2]] ([[User talk:$2|eztabaida]]{{int:pipe-separator}}[[Special:Contributions/$2|{{int:contribslink}}]]) wikilariak «[[:$1]]» orrian egindako azken aldaketa desegin;\nbeste norbaitek editatu edo desegin du jadanik.\n\nAzken aldaketa [[User:$3|$3]] ([[User talk:$3|eztabaida]]{{int:pipe-separator}}[[Special:Contributions/$3|{{int:contribslink}}]]) wikilariak egin du.",
        "editcomment": "Aldaketaren laburpena: <em>$1</em>.",
        "revertpage": "[[Special:Contributions/$2|$2]] ([[User talk:$2|talk]]) wikilariaren aldaketak deseginda, edukia [[User:$1|$1]] wikilariaren azken bertsiora itzuli da.",
+       "revertpage-nouser": "{{GENDER:$1|[[User:$1|$1]]}}-n azken berrikuspena ezkutatutako erabiltzaile batek egindako leheneraketa aldaketak.",
        "rollback-success": "{{GENDER:$3|$1}}; wikilariaren aldaketak deseginda,\nedukia {{GENDER:$4|$2}} wikilariaren azken bertsiora itzuli da.",
        "sessionfailure-title": "Saio-akatsa",
        "sessionfailure": "Badirudi saioarekin arazoren bat dagoela; bandalismoak saihesteko ekintza hau ezeztatu egin da. Mesedez, nabigatzaileko \"atzera\" botoian klik egin, hona ekarri zaituen orrialde hori berriz kargatu, eta saiatu berriz.",
        "sp-contributions-newonly": "Orrialde sorkuntza direnak soilik erakutsi",
        "sp-contributions-hideminor": "Aldaketa txikiak ezkutatu",
        "sp-contributions-submit": "Bilatu",
+       "sp-contributions-outofrange": "Ezin dira emaitzak erakutsi. Eskatutako IParen eremua CIDR /$1 muga baino handiagoa da.",
        "whatlinkshere": "Honanzko lotura duten orriak",
        "whatlinkshere-title": "$1(e)ra lotura duten orriak",
        "whatlinkshere-page": "Orria:",
        "ipb_blocked_as_range": "Akatsa: $1 IPa ez dago zuzenean blokeatuta eta ezin da blokeoa kendu.\nHala ere, $2-(r)en parte denez, blokeoa kendu daiteke.",
        "ip_range_invalid": "Baliogabeko IP eremua.",
        "ip_range_toolarge": "/$1 baino handiagoak diren blokeo eremuak ezin dira eskuratu.",
+       "ip_range_exceeded": "IP barrutiak gehieneko bitartea gainditzen du. Onartutako sorta: /$1.",
+       "ip_range_toolow": "IP eremuak modu eraginkorrean ez dira onartzen.",
        "proxyblocker": "Proxy blokeatzailea",
        "proxyblockreason": "Zure IP helbidea blokeatu egin da proxy ireki baten zaudelako. Mesedez, zure Interneteko Zerbitzu Hornitzailearekin harremanetan jar zaitez segurtasun arazo honetaz ohartarazteko.",
        "sorbsreason": "Zure IP helbidea proxy ireki bezala zerrendatuta dago DNSBLan.",
        "sorbs_create_account_reason": "Zure IP helbidea proxy ireki bezala zerrendatuta dago DNSBLan. Ezin duzu kontua sortu.",
        "softblockrangesreason": "Ezin dira ekarpen anonimoak onartu zure $1 IP helbidetik. Hasi saioa mesedez.",
+       "xffblockreason": "X-Forwarded-For goiburuan agertzen den IP helbidea, zurea edo erabiltzen ari zaren proxy zerbitzariaren bat, blokeatua izan. Jatorrizko bloke arrazoia honako hau izan zen: $1",
        "cant-see-hidden-user": "Blokeatzen saiatzen ari zaren erabiltzailea blokeatu egin da eta ezkutuan egongo da.\nEzkutaridun eskubiderik ez duzunez gero, ezin duzu erabiltzaileen blokeoa ikusi edo editatu.",
        "ipbblocked": "Ezin dituzu beste erabiltzaileak blokeatu edo desblokeatu, zu zeu blokeatuta zaudelako",
        "ipbnounblockself": "Ez duzu baimenik zure buruari blokeoa kentzeko",
        "movepagetext-noredirectfixer": "Inprimaki hau erabiliz, orri baten izena aldatuko da, eta haren historia izen berrira eramango.\nIzenburu zaharra izenburu berrirantz birbideratutako orri bihurtuko da.\n[[Special:DoubleRedirects|bikoitzak]] eta [[Special:BrokenRedirects|apurtuak]] egiaztatzeaz arduratu.\nZure ardura da loturak behar den tokirantz bideratzea.\n\nGogoan izan ezazu ezazu: orriaren izena <strong>ez</strong> dela aldatuko baldin eta jarri nahi duzun izenburua duen orria dagoeneko sortuta badago, salbu eta historiarik gabeko birbideratze orri bat bada.\nHau da, nahasten baldin bazara, mugitu duzun orria lehengo izenburura itzultzeko modua badago, eta ezin duzun lehendik sortuta dagoen orri bat gainidatzi.\n\n<strong>Kontuan izan</strong>\nOso erabilia den orri batean, aldaketa hau bat-batekoa eta ustekabekoa izan liteke;\nzalantzarik baldin baduzu, lehenbizi adieraz ezazu zure asmoa eztabaida orrian, beste wikilarien iritziak jasotzeko.",
        "movepagetalktext": "Kutxa hau egiaztatzen baduzu, dagokion eztabaida orrialdea beste izenburu batera mugituko da, hutsik dagoen eztabaida orrialde bat izen berrian existitzen ez bada.\n\n\nKasu horietan orrialdea eskuz mugitu edo bestearekin bateratu beharko duzu.",
        "moveuserpage-warning": "'''Oharra:''' Lankide orrialde bat mugitzera zoaz. Kontutan izan orrialde bakarrik mugituko duzula eta '''ez''' duzula lankide izena aldatuko.",
+       "movecategorypage-warning": "<strong>Oharra:</strong> Kategoria orri bat mugizear zaude. Kontuan izan orri bakarra mugitu egingo dela eta kategoria zaharreko orrialdeak berriari <em>ez</em> zaizkiola berrezarriko.",
        "movenologintext": "Orrialde bat mugitzeko erregistratutako lankidea izan behar duzu eta [[Special:UserLogin|saioa hasi]].",
        "movenotallowed": "Ez daukazu orrialdeak mugitzeko baimenik.",
        "movenotallowedfile": "Ez duzu fitxategiak mugitzeko eskumenik.",
        "thumbnail_image-failure-limit": "Koadro txikiak sortzeko saiakera galduak ($1 edo gehiago) gehiegi izan dira. Saiatu berriz geroago mesedez.",
        "import": "Orrialdeak inportatu",
        "importinterwiki": "Beste wiki batetik inportatu",
-       "import-interwiki-text": "Aukeratu inportatzeko wiki eta orrialde izenburu bat. Berrikuspenen datak eta egileak gorde egingo dira. Inportazio ekintza guzti hauek [[Special:Log/import|inportazio erregistroan]] gordetzen dira.",
+       "import-interwiki-text": "Aukeratu inportatzeko wiki eta orrialde izenburu bat. Berrikuspenen datak eta egile izenak gorde egingo dira. Beste wikien inportazioak [[Special:Log/import|inportazio erregistroan]] gordetzen dira.",
        "import-interwiki-sourcewiki": "Jatorrizko wikia:",
        "import-interwiki-sourcepage": "Jatorrizko orria:",
        "import-interwiki-history": "Orrialde honen historiako bertsio guztiak kopiatu",
        "svg-long-error": "SVG fitxategi ez baliagarria: $1",
        "show-big-image": "Jatorrizko fitxategia",
        "show-big-image-preview": "Aurreikuspen honen neurria: $1.",
+       "show-big-image-preview-differ": "$2 fitxategi honen $3 aurreikuspenaren tamainia: $1.",
        "show-big-image-other": "Bestelako {{PLURAL:$2|bereizmena|bereizmenak}}: $1.",
        "show-big-image-size": "$1 × $2 pixel",
        "file-info-gif-looped": "kiribildua",
        "tags-deactivate-not-allowed": "Ezin izan da \"$1\" etiketa desaktibatu.",
        "tags-deactivate-submit": "Desaktibatu",
        "tags-apply-no-permission": "Ez duzu etiketak aldatzeko baimen nahikorik zure aldaketa baimenetan.",
+       "tags-apply-not-allowed-one": "\"$1\" etiketa ez dauka eskuz aplikatzeko baimenik.",
+       "tags-apply-not-allowed-multi": "Hurrengo {{PLURAL:$2|etiketa|etiketak}} ezin d(ir)a eskuz aplikatu: $1",
        "tags-update-no-permission": "Ez duzu aldaketaren etiketak gehitzeko edo kentzeko baimenik bakarkako berrikuspen edo erregistroko sarreretatik.",
+       "tags-update-add-not-allowed-one": "$1 etiketa ezin da eskuz gehitu.",
+       "tags-update-add-not-allowed-multi": "Hurrengo {{PLURAL:$2|etiketa|etiketak}} ezin d(ir)a eskuz gehitu: $1",
        "tags-update-remove-not-allowed-one": "$1 etiketa ezabatzeko baimenik ez dago.",
        "tags-update-remove-not-allowed-multi": "Hurrengo {{PLURAL:$2|etiketa|etiketak}} ezin d(ir)a eskuz ezabatu: $1",
        "tags-edit-title": "Etiketak aldatu",
        "tags-edit-manage-link": "Etiketak kudeatu",
        "tags-edit-revision-selected": "[[:$2]](r)en {{PLURAL:$1|aukeratutako berrikusketa|aukeratutako berrikusketak}}:",
        "tags-edit-logentry-selected": "{{PLURAL:$1|Aukeratutako log gertakaria|Aukeratutako log gertakariak}}:",
+       "tags-edit-revision-legend": "{{PLURAL:$1|Berrikusketa honetatik| $1 berrikuska guztietatik}} etiketak gehitu edo kendu",
        "tags-edit-existing-tags": "Existitzen diren etiketak:",
        "tags-edit-existing-tags-none": "<em>Bat ere ez</em>",
        "tags-edit-new-tags": "Etiketa berriak:",
        "tags-edit-chosen-placeholder": "Hautatu etiketa batzuk",
        "tags-edit-chosen-no-results": "Balio duen etiketarik ez da aurkitu",
        "tags-edit-reason": "Arrazoia:",
+       "tags-edit-logentry-submit": " {{PLURAL:$1|saio sarrera honetan|$1 saio sarreretan}} aldaketak aplikatu",
        "tags-edit-success": "Aldaketak ezarri dira.",
        "tags-edit-failure": "Ezin izan dira aldaketak ezarri:\n$1",
        "tags-edit-nooldid-title": "Baliogabeko berrikusketa helburua",
        "revdelete-restricted": "administratzaileentzako mugak ezarri dira",
        "revdelete-unrestricted": "administratzaileentzako mugak kendu dira",
        "logentry-block-block": "$1 {{GENDER:$2|administratzaileak}} {{GENDER:$4|$3}} blokeatu du. Iraupena: $5 $6",
+       "logentry-block-unblock": "$1 {{GENDER:$2|desblokeatuta}} {{GENDER:$4|$3}}",
        "logentry-block-reblock": "$1 administratzaileak {{GENDER:$4|$3}} wikilariaren blokeoa {{GENDER:$2|aldatu du}}. Blokeoaldia: $5 $6",
        "logentry-suppress-block": "$1 {{GENDER:$2|administratzaileak}} {{GENDER:$4|$3}} blokeatu du. Iraupena: $5 $6",
        "logentry-suppress-reblock": "$1 administratzaileak {{GENDER:$4|$3}} wikilariaren blokeoa {{GENDER:$2|aldatu du}}. Blokeoaldia: $5 $6",
        "json-error-depth": "Multzoaren gehienezko sakonera gainditu egin da",
        "json-error-ctrl-char": "Kontrol-karaktere errorea, ziurrenik gaizki kodeatzeagatik.",
        "json-error-syntax": "Sintaxi-errorea",
+       "json-error-recursion": "Erreferentzia errekurtsibo bat edo gehiago kodeatzeko balioan",
+       "json-error-inf-or-nan": "NAN edo INF bat edo gehiago kodeatzeko balioan",
+       "json-error-unsupported-type": "Kodeatu ezin daitekeen balio mota eman da",
        "headline-anchor-title": "Lotura sekzio honetara",
        "special-characters-group-latin": "Latina",
        "special-characters-group-latinextended": "Latin hedatua",
        "mw-widgets-usersmultiselect-placeholder": "Gehitu gehiago...",
        "date-range-from": "Data honetatik aurrera:",
        "date-range-to": "Data honetara arte:",
+       "sessionmanager-tie": "Ezin dira autentifikazio eskaera mota ugari konbinatu: $1.",
        "sessionprovider-generic": "$1 sesio",
        "sessionprovider-mediawiki-session-cookiesessionprovider": "Cookie-tan oinarritutako sesioak",
+       "sessionprovider-nocookies": "Agian cookie-ak desgaitu egin dira. Egiaztatu cookie-ak gaituak dituzula eta hasi berriro.",
        "randomrootpage": "Ausazko sustrai orria",
        "log-action-filter-block": "Blokeatze mota:",
        "log-action-filter-contentmodel": "Eduki eredu motaren aldaketa:",
        "log-action-filter-delete": "Ezabatze mota:",
        "log-action-filter-import": "Inportazio mota:",
+       "log-action-filter-managetags": "Etiketa kudeaketa akzio mota:",
        "log-action-filter-move": "Mugimendu mota:",
        "log-action-filter-newusers": "Kontu sortze-mota:",
        "log-action-filter-patrol": "Patruilatze mota:",
        "log-action-filter-protect": "Babes mota:",
+       "log-action-filter-rights": "Eskubide aldaketa mota:",
        "log-action-filter-suppress": "Ezabatze mota:",
        "log-action-filter-upload": "Igoera mota:",
        "log-action-filter-all": "Denak",
        "log-action-filter-block-reblock": "Blokeoa aldatu",
        "log-action-filter-block-unblock": "blokeoa kendu",
        "log-action-filter-contentmodel-change": "Aldatu eduki eredua",
+       "log-action-filter-contentmodel-new": "Eduki eredu ez-lehenetsiarekin orria sortzea",
        "log-action-filter-delete-delete": "Orri ezabaketa",
+       "log-action-filter-delete-delete_redir": "Gainidazketa birzuzendu",
        "log-action-filter-delete-restore": "Ezabatutako orria berreskuratu",
        "log-action-filter-delete-event": "Sarrera ezabaketa",
        "log-action-filter-delete-revision": "Berrikuspen ezabaketa",
        "log-action-filter-newusers-create": "Erabiltzaile anonimo batek sortua",
        "log-action-filter-newusers-create2": "Izena emandako erabiltzaile batek idatzia",
        "log-action-filter-newusers-autocreate": "Sorrera automatikoa",
+       "log-action-filter-newusers-byemail": "Posta elektroniko bidez bidalitako pasahitza sortzea",
        "log-action-filter-patrol-patrol": "Patruilaketa manuala",
        "log-action-filter-patrol-autopatrol": "Patruilaketa automatikoa",
        "log-action-filter-protect-protect": "Babesa",
        "log-action-filter-suppress-reblock": "Birblokoz kendutako erabiltzailea",
        "log-action-filter-upload-upload": "Igoera berria",
        "log-action-filter-upload-overwrite": "Birkargatu",
+       "authmanager-authn-not-in-progress": "Egiaztatzea ez dago prozesuan edo saioaren datuak galdu egin dira. Hasi berriro hasieratik mesedez.",
+       "authmanager-authn-no-primary": "Emandako kredentzialak ezin izan dira egiaztatu.",
+       "authmanager-authn-no-local-user": "Emandako kredentzialak ez dute lotura wiki honetako erabiltzaileekin.",
+       "authmanager-authn-no-local-user-link": "Hornitutako kredentzialak baliagarriak dira, baina ez dira lotzen wiki honetako erabiltzaileekin. Beste modu batean saioa hasi edo erabiltzaile berri bat sortu eta zure aurreko kredentzialak kontu horri lotzeko aukera izango duzu.",
+       "authmanager-change-not-supported": "Hornitutako kredentzialak ezin dira aldatu, erabiliko ez direlako.",
        "authmanager-create-disabled": "Auto-sorkuntza ezgaituta.",
        "authmanager-create-from-login": "Zure kontua sortzeko, bete itzazu eremu guztiak.",
        "authmanager-create-not-in-progress": "Kontua sortzea ez doa aurrera edo saioaren datuak galdu egin dira. Hasi berriro hasieratik mesedez.",
        "authmanager-create-no-primary": "Ezin izan dira hornitutako kredentzialak kontu-sortzerakoan erabili.",
+       "authmanager-link-no-primary": "Ezin izan dira hornitutako kredentzialak kontuari lotzeko erabili.",
+       "authmanager-link-not-in-progress": "Kontua sortzea ez doa aurrera edo saioaren datuak galdu egin dira. Hasi berriro hasieratik mesedez.",
        "authmanager-authplugin-setpass-failed-title": "Ezin izan da pasahitza aldatu",
        "authmanager-authplugin-setpass-failed-message": "Autentifikazio pluginak pasahitza aldatzea ukatu du.",
        "authmanager-authplugin-create-fail": "Autentifikazio pluginak kontua sortzea ukatu du.",
        "authmanager-provider-password-domain": "Pasahitza eta domeinuan oinarritutako baieztapena",
        "authmanager-provider-temporarypassword": "Behin-behineko pasahitza",
        "authprovider-confirmlink-request-label": "Linkatu beharko ziren kontuak",
+       "authprovider-confirmlink-success-line": "$1: ederki linkatu egin da.",
        "authprovider-resetpass-skip-label": "Utzi",
+       "authprovider-resetpass-skip-help": "Utzi pasahitzaren berrezartzeari.",
+       "authform-nosession-login": "Autentifikazioa arrakastatsua izan da, baina zure nabigatzaileak ezin du \"gogoratu\" saioa hasita izatea.\n\n$1",
+       "authform-nosession-signup": "Kontua sortu da, baina zure nabigatzaileak ezin du \"gogoratu\" saioa hasita izatea.\n\n$1",
        "authform-newtoken": "Falta den tokena. $1",
        "authform-notoken": "Falta den tokena",
        "authform-wrongtoken": "Token okerra",
        "specialpage-securitylevel-not-allowed-title": "Baimenik gabe",
+       "specialpage-securitylevel-not-allowed": "Barkatu, ez duzu orri hau erabiltzeko baimenik zure identitatea ezin izan delako egiaztatu.",
        "authpage-cannot-login": "Saio hasiera ezin izan da burutu.",
+       "authpage-cannot-login-continue": "Ezin izan da saio hasierarekin jarraitu. Zure saioak ziurrenik denbora-muga gainditu du.",
        "authpage-cannot-create": "Ezin izan da kontu sortzea hasi.",
+       "authpage-cannot-create-continue": "Ezin izan da kontu sortzearekin jarraitu. Zure saioak ziurrenik denbora-muga gainditu du.",
+       "authpage-cannot-link": "Ezin izan da kontu linkatzea hasi.",
+       "authpage-cannot-link-continue": "Ezin izan da kontua linkatzearekin jarraitu. Zure saioak ziurrenik denbora-muga gainditu du.",
        "cannotauth-not-allowed-title": "Ez da baimendu",
        "cannotauth-not-allowed": "Ez duzu baimenik orri hau erabiltzeko",
        "changecredentials": "Kredentzialak aldatu",
        "changecredentials-submit": "Kredentzialak aldatu",
+       "changecredentials-invalidsubpage": "$1 baliogabeko kredentzial mota bat da.",
        "changecredentials-success": "Zure kredentzialak aldatu egin dira.",
        "removecredentials": "Kredentzialak kendu",
        "removecredentials-submit": "Kredentzialak kendu",
        "restrictionsfield-label": "Onartutako IP eremuak:",
        "revid": "$1 berrikusi",
        "pageid": "$1 orri IDa",
+       "rawhtml-notallowed": "&lt;html&gt; etiketak ezin dira orri arruntetatik kanpo erabili.",
        "gotointerwiki": "{{SITENAME}}(e)tik irteten",
        "gotointerwiki-invalid": "Zehaztutako titulua baliogabea da.",
        "pagedata-title": "Orri data",
index fb1e472..293b3de 100644 (file)
        "underline-never": "Ei koskaan",
        "underline-default": "Ulkoasun tai selaimen oletustapa",
        "editfont-style": "Muokkauskentän kirjasintyyppi:",
-       "editfont-default": "Selaimen vakioasetus",
        "editfont-monospace": "Tasalevyinen kirjasin",
        "editfont-sansserif": "Sans-serif-kirjasin",
        "editfont-serif": "Serif-kirjasin",
index 20dbdc4..e566e9f 100644 (file)
        "underline-never": "Jamais",
        "underline-default": "Valeur par défaut du thème ou du navigateur",
        "editfont-style": "Style de police de la zone d’édition :",
-       "editfont-default": "Police par défaut du navigateur",
        "editfont-monospace": "Police à chasse fixe",
        "editfont-sansserif": "Police sans-serif",
        "editfont-serif": "Police serif",
index 6ce3fdf..a56016a 100644 (file)
@@ -57,7 +57,6 @@
        "underline-never": "Dila ta",
        "underline-default": "Alipo meyalo browser dudelo",
        "editfont-style": "Ubawa area gaya lo tuladu",
-       "editfont-default": "Browser dudelo",
        "editfont-monospace": "Tuladu Monospaced",
        "editfont-sansserif": "Tuladu San-serif",
        "editfont-serif": "Tuladu Serif",
index 2e82be7..e28581c 100644 (file)
        "minoredit": "𐌸𐌰𐍄𐌰 𐌹𐍃𐍄 𐌼𐌹𐌽𐌽𐌹𐌶𐌴𐌹 𐌹𐌽𐌼𐌰𐌹𐌳𐌴𐌹𐌽𐍃",
        "watchthis": "𐌰𐍄𐍅𐌹𐍄 𐌻𐌰𐌿𐌱𐌰",
        "savearticle": "𐌲𐌰𐍆𐌰𐍃𐍄 𐌻𐌰𐌿𐍆",
+       "savechanges": "𐌲𐌰𐍆𐌰𐍃𐍄 𐌹𐌽𐌼𐌰𐌹𐌳𐌹𐌽𐌹𐌽𐍃",
        "publishpage": "𐌼𐌴𐍂𐌴𐌹 𐌻𐌰𐌿𐍆",
+       "publishchanges": "𐌼𐌴𐍂𐌴𐌹 𐌹𐌽𐌼𐌰𐌹𐌳𐌹𐌽𐌹𐌽𐍃",
        "preview": "𐍆𐌰𐌿𐍂𐌰𐍃𐌹𐌿𐌽𐍃",
        "showpreview": "𐌱𐌰𐌽𐌳𐍅𐌴𐌹 𐍆𐌰𐌿𐍂𐌰𐍃𐌹𐌿𐌽",
        "showdiff": "𐌱𐌰𐌽𐌳𐍅𐌴𐌹 𐌹𐌽𐌼𐌰𐌹𐌳𐌹𐌽𐌹𐌽𐍃",
        "mypreferences": "𐌼𐌴𐌹𐌽𐍉𐍃 𐍆𐍂𐌹𐌾𐍉𐌽𐍉𐍃 𐍅𐌰𐌹𐌷𐍄𐍃",
        "prefs-skin": "𐍆𐌹𐌻𐌻",
        "skin-preview": "𐍆𐌰𐌿𐍂𐌰𐍃𐌰𐌹𐍈",
+       "prefs-rc": "𐌰𐍆𐍄𐌿𐌼𐌹𐍃𐍄𐍉𐍃 𐌹𐌽𐌼𐌰𐌹𐌳𐌴𐌹𐌽𐍉𐍃",
        "saveprefs": "𐌲𐌰𐍆𐌰𐍃𐍄",
        "searchresultshead": "𐍃𐍉𐌺𐌴𐌹",
        "grouppage-sysop": "{{ns:project}}:𐍂𐌴𐌹𐌺𐍃",
        "recentchanges-label-bot": "𐍃𐍉 𐌹𐌽𐌼𐌰𐌹𐌳𐌴𐌹𐌽𐍃 𐍄𐍉𐌾𐌰𐌳𐌰 𐍅𐌰𐍂𐌸 𐍆𐍂𐌰𐌼 𐌼𐌰𐌷𐍄𐌹𐍃𐌺𐌰𐌻𐌺𐌰 (𐌱𐌰𐌿𐍄)",
        "recentchanges-label-plusminus": "𐌻𐌰𐌿𐌱𐌰𐌼𐌹𐌺𐌹𐌻𐌴𐌹 𐌹𐌽𐌼𐌰𐌹𐌳𐌹𐌳𐌰 𐌼𐌹𐌸 𐌸𐌹𐌶𐌰𐌹 𐍂𐌰𐌸𐌾𐍉𐌽 𐌱𐌹𐍄𐍉",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (𐍃𐌰𐌹𐍈 𐌾𐌰𐌷[[Special:NewPages|𐍅𐌹𐌺𐍉 𐌽𐌹𐌿𐌾𐌰𐌹𐌶𐌴 𐌻𐌰𐌿𐌱𐌴]])",
+       "rcfilters-limit-title": "𐌹𐌽𐌼𐌰𐌹𐌳𐌴𐌹𐌽𐍉𐍃 𐌳𐌿 𐌱𐌰𐌽𐌳𐍅𐌾𐌰𐌽",
+       "rcfilters-show-new-changes": "𐌱𐌰𐌽𐌳𐍅𐌴𐌹 𐌽𐌹𐌿𐌾𐌰𐍃𐍄𐍉𐍃 𐌹𐌽𐌼𐌰𐌹𐌳𐌴𐌹𐌽𐌹𐌽𐍃",
+       "rcfilters-filter-editsbyself-label": "𐌹𐌽𐌼𐌰𐌹𐌳𐌴𐌹𐌽𐍉𐍃 𐍆𐍂𐌰𐌼 𐌸𐌿𐍃",
+       "rcfilters-filter-editsbyother-label": "𐌹𐌽𐌼𐌰𐌹𐌳𐌴𐌹𐌽𐍉𐍃 𐍆𐍂𐌰𐌼 𐌰𐌽𐌸𐌰𐍂𐌰𐌹𐌼",
        "rclistfrom": "𐌱𐌰𐌽𐌳𐍅𐌴𐌹 𐌽𐌹𐌿𐌾𐍉𐍃 𐌹𐌽𐌼𐌰𐌹𐌳𐌴𐌹𐌽𐌹𐌽𐍃 𐌰𐌽𐌰𐍃𐍄𐍉𐌳𐌾𐌰𐌽𐌳𐌴𐌹𐌽𐍃 𐍆𐍂𐌰𐌼 $2, $3",
        "rcshowhideminor": "$1 𐌼𐌹𐌽𐌽𐌹𐌶𐌴𐌹𐌽𐍃 𐌹𐌽𐌼𐌰𐌹𐌳𐌴𐌹𐌽𐍉𐍃",
        "rcshowhideminor-show": "𐌱𐌰𐌽𐌳𐍅𐌴𐌹",
        "tags-source-header": "𐌱𐍂𐌿𐌽𐌽𐌰",
        "tags-actions-header": "𐍄𐍉𐌾𐌰",
        "tags-source-none": "𐌽𐌹 𐌾𐌿 𐌱𐍂𐌿𐌺𐌾𐌰𐌳𐌰",
+       "tags-edit": "𐌹𐌽𐌼𐌰𐌹𐌳𐌴𐌹",
        "tags-delete": "𐌿𐍃𐌽𐌹𐌼",
        "tags-activate": "𐌲𐌰𐌵𐌹𐌿𐌴𐌹",
        "tags-deactivate": "𐌿𐌽𐌲𐌰𐌵𐌹𐌿𐌴𐌹",
index efd182c..bde25c2 100644 (file)
@@ -89,7 +89,6 @@
        "underline-never": "לעולם לא",
        "underline-default": "ברירת המחדל של העיצוב או הדפדפן",
        "editfont-style": "הגופן בתיבת העריכה:",
-       "editfont-default": "ברירת המחדל של הדפדפן",
        "editfont-monospace": "גופן ברוחב קבוע (monospace)",
        "editfont-sansserif": "גופן לא מעוצב (sans-serif)",
        "editfont-serif": "גופן מעוצב (serif)",
        "rcfilters-view-namespaces-tooltip": "סינון התוצאות לפי מרחב שם",
        "rcfilters-view-tags-tooltip": "סינון התוצאות לפי תגיות עריכה",
        "rcfilters-view-return-to-default-tooltip": "חזרה לתפריט המסננים הראשי",
+       "rcfilters-view-tags-help-icon-tooltip": "למידע נוסף על עריכות מתויגות",
        "rcfilters-liveupdates-button": "עדכונים חיים",
        "rcfilters-liveupdates-button-title-on": "כיבוי העדכונים החיים",
        "rcfilters-liveupdates-button-title-off": "הצגת שינויים חדשים כשהם מתרחשים",
        "ip_range_invalid": "טווח IP שגוי.",
        "ip_range_toolarge": "לא ניתן לחסום טווחים גדולים מ־<span dir=\"ltr\">/$1</span>.",
        "ip_range_exceeded": "טווח ה־IP חורג מהטווח המרבי. הטווח המותר: /$1.",
-       "ip_range_toolow": "×\98×\95×\95×\97×\99 IP ×\9c×\9eעש×\94 אינם מורשים.",
+       "ip_range_toolow": "×\91פ×\95×¢×\9c, ×\98×\95×\95×\97×\99 IP אינם מורשים.",
        "proxyblocker": "חוסם פרוקסי",
        "proxyblockreason": "כתובת ה־IP שלכם נחסמה משום שהיא כתובת של שרת פרוקסי פתוח.\nאנא צרו קשר עם ספק האינטרנט שלכם או עם התמיכה הטכנית של הארגון שלכם והודיעו להם על בעיית האבטחה החמורה הזאת.",
        "sorbsreason": "כתובת ה־IP שלך רשומה ככתובת פרוקסי פתוחה ב־DNSBL שאתר {{SITENAME}} משתמש בו.",
index 0bfe2b1..6ab714d 100644 (file)
        "underline-never": "कभी नहीं",
        "underline-default": "प्राथमिक त्वचा या ब्राउज़र",
        "editfont-style": "सम्पादन क्षेत्र की फॉन्ट शैली:",
-       "editfont-default": "प्राथमिक ब्राउज़र",
        "editfont-monospace": "एकल स्थल मुद्रलिपि",
        "editfont-sansserif": "बिना नोकों वाली मुद्रलिपि",
        "editfont-serif": "नोकों वाली मुद्रलिपि",
index b0617f8..1f9d122 100644 (file)
@@ -87,7 +87,6 @@
        "underline-never": "Nikad",
        "underline-default": "Prema postavkama preglednika",
        "editfont-style": "Font u okviru za uređivanje",
-       "editfont-default": "Prema postavkama preglednika",
        "editfont-monospace": "Font s jednakim razmakom",
        "editfont-sansserif": "Font Sans-serif",
        "editfont-serif": "Font Serif",
index 5695681..687e4ad 100644 (file)
@@ -99,7 +99,6 @@
        "underline-never": "soha",
        "underline-default": "Felület és böngésző alapértelmezése szerint",
        "editfont-style": "A szerkesztőterület betűtípusa:",
-       "editfont-default": "a böngésző alapértelmezett beállítása",
        "editfont-monospace": "fix szélességű betűtípus",
        "editfont-sansserif": "talpatlan (sans-serif) betűtípus",
        "editfont-serif": "talpas (serif) betűtípus",
index cf3c431..e676f76 100644 (file)
@@ -67,7 +67,6 @@
        "underline-never": "Nunquam",
        "underline-default": "Como definite per tu navigator o apparentia",
        "editfont-style": "Stilo de litteras del area de modification:",
-       "editfont-default": "Predefinite del navigator",
        "editfont-monospace": "Typo de litteras monospatial",
        "editfont-sansserif": "Typo de litteras sans-serif",
        "editfont-serif": "Typo de litteras serif",
index 1e312d3..abe2639 100644 (file)
@@ -57,7 +57,6 @@
        "underline-never": "ЦIаккха",
        "underline-default": "Браузера гIирсаш тоаяраш лелае",
        "editfont-style": "Хувцама моттиге шрифта тайпа:",
-       "editfont-default": "Браузерен гӀирса чура шрифт",
        "editfont-monospace": "Цхьатарра йоаца шрифт",
        "editfont-sansserif": "Белгало йоаца шрифт",
        "editfont-serif": "Белгало йола шрифт",
index eb7b5e7..c84237b 100644 (file)
        "underline-never": "Mai",
        "underline-default": "Impostazioni predefinite del browser o del tema",
        "editfont-style": "Stile del carattere nella casella di modifica:",
-       "editfont-default": "Predefinito del browser",
        "editfont-monospace": "Carattere a larghezza fissa",
        "editfont-sansserif": "Carattere Sans-serif",
        "editfont-serif": "Carattere Serif",
        "pt-login-button": "Entra",
        "pt-login-continue-button": "Continua l'accesso",
        "pt-createaccount": "registrati",
-       "pt-userlogout": "Esci",
+       "pt-userlogout": "esci",
        "php-mail-error-unknown": "Errore sconosciuto nella funzione PHP mail()",
        "user-mail-no-addy": "Hai cercato di inviare una e-mail senza un indirizzo.",
        "user-mail-no-body": "Tentato di inviare una e-mail con un testo vuoto o estremamente breve.",
index 9433ba4..f709e30 100644 (file)
@@ -46,7 +46,7 @@
        "tog-shownumberswatching": "Tuduhaké cacah wong sing ngawasi",
        "tog-oldsig": "Tapak asmané panjenengan sing ana:",
        "tog-fancysig": "Cakaké tapak asma minangka tèks wiki (tanpa pranala otomatis)",
-       "tog-uselivepreview": "Nganggo pratuduh langsung",
+       "tog-uselivepreview": "Tuduhaké pratuduh tanpa ngamot ulang kacané",
        "tog-forceeditsummary": "Kandhani aku manawa kothak ringkesané besutan isih kosong",
        "tog-watchlisthideown": "Dhelikaké besutanku saka pawawangan",
        "tog-watchlisthidebots": "Dhelikaké besutan bot saka pangawasan",
@@ -66,7 +66,6 @@
        "underline-never": "Ora tau",
        "underline-default": "Ules utawa pangluru gawan",
        "editfont-style": "Gagrag fon ing pambesutan:",
-       "editfont-default": "Baku pangluron",
        "editfont-monospace": "Fon monospasi",
        "editfont-sansserif": "Fon tansèrif",
        "editfont-serif": "Fon sèrif",
        "recentchanges-submit": "Tuduhaké",
        "rcfilters-legend-heading": "<strong>Pratélané cekakan:</strong>",
        "rcfilters-activefilters": "Saringan murub",
-       "rcfilters-quickfilters": "Pranala rikat",
+       "rcfilters-quickfilters": "Saringan sumimpen",
        "rcfilters-quickfilters-placeholder-title": "Durung ana pranala sing disimpen",
        "rcfilters-quickfilters-placeholder-description": "Saperlu nyimpen setèlan saringané panjenengan lan nganggo iku manèh ing tembé, kliken ikon markah bukuné ing babagan Saringan Murub ing ngisor.",
        "rcfilters-savedqueries-defaultlabel": "Saringan sumimpen",
        "rcfilters-savedqueries-unsetdefault": "Wutung ndadèkaké baku",
        "rcfilters-savedqueries-remove": "Busak",
        "rcfilters-savedqueries-new-name-label": "Jeneng",
-       "rcfilters-savedqueries-apply-label": "Gawé pranala rikat",
+       "rcfilters-savedqueries-apply-label": "Gawé saringan",
        "rcfilters-savedqueries-cancel-label": "Wurung",
-       "rcfilters-savedqueries-add-new-title": "Simpen saringan dadi pranala rikat",
+       "rcfilters-savedqueries-add-new-title": "Simpen setèlané saringan sing saiki",
        "rcfilters-restore-default-filters": "Pulihaké saringan gawan",
        "rcfilters-clear-all-filters": "Resiki kabèh saringan",
        "rcfilters-search-placeholder": "Saring owah-owahan anyar (lurua utawa wiwita ngetik)",
        "uploadstash-clear": "Busak berkas kadhelikaké",
        "uploadstash-nofiles": "Panjenengan ora duwé barkas simpenan.",
        "uploadstash-badtoken": "Nglakoni iki ora suksès, mungkin amarga hak panyuntingan Sampéyan wis kedaluwarsa. Jajal manèh.",
-       "uploadstash-errclear": "Ngresiki berkas ora suksès.",
+       "uploadstash-errclear": "Wurung ngresiki barkasé.",
        "uploadstash-refresh": "Segeraké daptar berkas",
        "invalid-chunk-offset": "Ganti rugi kethoka ora sah",
        "img-auth-accessdenied": "Aksès ditulak",
        "listfiles_size": "Ukuran (bita)",
        "listfiles_description": "Dèskripsi",
        "listfiles_count": "Vèrsi",
-       "listfiles-show-all": "Termasuk gambar versi lawas",
+       "listfiles-show-all": "Lebokaké barkasé sing vèrsi lawas",
        "listfiles-latestversion": "Versi saiki",
        "listfiles-latestversion-yes": "Iya",
        "listfiles-latestversion-no": "Ora",
        "alllogstext": "Pitontonan gabungan log-log sing ana ing {{SITENAME}}.\nPanjenengan bisa nyiyutaké sesawangané kanthi milih sawijining jinis log, jeneng panganggo (sènsitif-case), utawa kaca sing gegayutan (uga sènsitif-case).",
        "logempty": "Ora ditemokaké èntri log sing pas.",
        "log-title-wildcard": "Golèk sesirah sing diwiwiti tulisan iki",
-       "showhideselectedlogentries": "Tuduhalé/dhelikaké èntri log kapilih",
+       "showhideselectedlogentries": "Owah pakatonané èntri log sing dipilih",
        "log-edit-tags": "Besut tag saka isian log sing dipilih",
        "checkbox-select": "Pilih: $1",
        "checkbox-all": "Kabèh",
        "enotif_body_intro_restored": "Halaman $1 di {{SITENAME}} telah dikembalikan pada $PAGEEDITDATE oleh {{gender:$2|$2}}, lihat $3 untuk revisi terkini.",
        "enotif_body_intro_changed": "Halaman $1 di {{SITENAME}} telah diubah pada $PAGEEDITDATE oleh {{gender:$2|$2}}, lihat $3 untuk revisi terkini.",
        "enotif_lastvisited": "Deleng $1 kanggo kabèh owah-owahan wiwit pungkasan panjenengan niliki.",
-       "enotif_lastdiff": "Tilikana $1 kanggo mirsani owah-owahan iki.",
+       "enotif_lastdiff": "Saperlu ndeleng owahan iki, tilikana $1",
        "enotif_anon_editor": "panganggo anonim $1",
        "enotif_body": "Sing minulya $WATCHINGUSERNAME,\n\nKaca $PAGETITLE ing {{SITENAME}} wis $CHANGEDORCREATED ing $PAGEEDITDATE déning $PAGEEDITOR, mangga mirsani $PAGETITLE_URL kanggo vèrsi pungkasan.\n\n$NEWPAGE\n\nSajarah suntingan: $PAGESUMMARY $PAGEMINOREDIT\n\nHubungana panyunting:\nmail: $PAGEEDITOR_EMAIL\nwiki: $PAGEEDITOR_WIKI\n\nKita ora bakal ngandhani manèh yèn diowahi manèh, kejaba panjenengan wis mirsani kaca iku. Panjenengan uga bisa mbusak tandha notifikasi kanggo kabèh kaca pangawasan ing daftar pangawasan panjenengan.\n\n             Sistém notifikasi {{SITENAME}}\n\n--\nKanggo ngowahi préferènsi ing daftar pangawasan panjenengan, mangga mirsani\n{{canonicalurl:{{#special:EditWatchlist}}}}\n\nUmpan balik lan pitulung sabanjuré:\n$HELPPAGE",
        "created": "kadamel",
        "block": "Blokir panganggo",
        "unblock": "Uculaké blokirané panganggo",
        "blockip": "Palang {{GENDER:$1|panganggo}}",
-       "blockip-legend": "Blokir panganggo",
        "blockiptext": "Enggonen formulir ing ngisor iki saperlu mblokir aksès nulis lumantar alamat IP utawa panganggo mirunggan.\nIki kudu diayahi kanggo ngéndhani vandhalisme, lan minangkani [[{{MediaWiki:Policy-url}}|pranatan]].\nIsinen alesan sing mirunggan ing ngisor iki (contoné, nyitir kaca mirunggan sing dirusak).\nPanjenengan bisa mblokir saprangkat alamat IP lumantar sintaksis [https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing CIDR]; kèhé prangkat sing diidinaké ya iku /$1 kanggo IPv4 lan /$2 kanggo IPv6.",
        "ipaddressorusername": "Alamat IP utawa jeneng panganggo",
        "ipbexpiry": "Kadaluwarsa",
        "ipb-unblock-addr": "Copot blokiran tumrap $1",
        "ipb-unblock": "Copot blokiran tumrap jeneng panganggo utawa alamat IP",
        "ipb-blocklist": "Deleng blokiran sing ana",
-       "ipb-blocklist-contribs": "Kontribusi kanggo $1",
+       "ipb-blocklist-contribs": "Pasumbanging {{GENDER:$1|$1}}",
        "ipb-blocklist-duration-left": "Kari $1",
        "unblockip": "Copot blokiran panganggo",
        "unblockiptext": "Nggonen formulir ing ngisor iki kanggo mbalèkaké aksès nulis sawijining alamt IP utawa panganggo sing sadurungé diblokir.",
        "compare-invalid-title": "Sesirah sing kokawèhaké ora sah.",
        "compare-title-not-exists": "Sesirah sing kokawèhaké ora ana.",
        "compare-revision-not-exists": "Benahan sing Sampéyan jaluk ora ana.",
-       "diff-form": "sawijining '''formulir'''",
+       "diff-form": "Béda",
        "dberr-problems": "Nyuwun ngapura! Situs iki ngalami masalah tèknis.",
        "dberr-again": "Coba nunggu sawetara menit lan unggahna manèh.",
        "dberr-info": "(Ora bisa nggayut basis dhata: $1)",
        "logentry-newusers-create": "Akun panganggo $1 {{GENDER:$2|digawé}}",
        "logentry-newusers-create2": "Akun panganggo $3 {{GENDER:$2|digawé}} déning $1",
        "logentry-newusers-byemail": "Akun panganggo $3 {{GENDER:$2|digawé}} déning $1 lan tembung sandhine dikirim lewat layang elektronik",
-       "logentry-newusers-autocreate": "Akun $1 {{GENDER:$2|digawé}} otomatis",
+       "logentry-newusers-autocreate": "Akun panganggo $1 otomatis {{GENDER:$2|digawé}}",
        "logentry-protect-move_prot": "$1 {{GENDER:$2|ngalih}} setèlan rereksan saka $4 dadi $3",
        "logentry-protect-unprotect": "$1 {{GENDER:$2|njabud}} payomané $3",
        "logentry-protect-protect": "$1 {{GENDER:$2|ngreksa}} $3 $4",
index faee5b8..e292f05 100644 (file)
@@ -79,7 +79,6 @@
        "underline-never": "არასდროს",
        "underline-default": "დამოკიდებული მომხმარებელზე ან ბრაუზერის არჩევანზე",
        "editfont-style": "რედაქტირების არეალის შრიფტის ტიპი:",
-       "editfont-default": "ბრაუზერის უპირობო არჩევანი",
        "editfont-monospace": "მონოშირული შრიფტი",
        "editfont-sansserif": "შრიფტი სანს-სერიფი",
        "editfont-serif": "შრიფტი სერიფი",
index ae6dbaa..62203ba 100644 (file)
@@ -70,7 +70,6 @@
        "underline-never": "Werǧin",
        "underline-default": "Azal s lexṣas n iminig neɣ n usentel",
        "editfont-style": "Aɣanib n tasefsit n taɣzut ubeqqeḍ :",
-       "editfont-default": "Tasefsit n iminig s lexṣas",
        "editfont-monospace": "Tasefsit s lqedd usbiḍ",
        "editfont-sansserif": "Tasefsit \"Sans-serif\"",
        "editfont-serif": "Tasefsit \"Serif\"",
index 7004591..6a4554d 100644 (file)
        "underline-never": "항상 치지 않기",
        "underline-default": "스킨 또는 브라우저 기본값",
        "editfont-style": "편집 영역의 글꼴 형식:",
-       "editfont-default": "브라우저 기본값",
        "editfont-monospace": "고정폭 글꼴",
        "editfont-sansserif": "산세리프 글꼴",
        "editfont-serif": "세리프 글꼴",
index e61250f..467d9f1 100644 (file)
@@ -64,7 +64,6 @@
        "underline-always": "Hertim",
        "underline-never": "Qet",
        "underline-default": "Tercîhên lêgerokê",
-       "editfont-default": "Tercîhên lêgerokê",
        "editfont-sansserif": "Fonta Sans-serif'ê",
        "editfont-serif": "Fonta Serif'ê",
        "sunday": "yekşem",
index d089622..198cd3b 100644 (file)
@@ -67,7 +67,6 @@
        "underline-never": "Ni",
        "underline-default": "Skin oder Standard vum Browser",
        "editfont-style": "Schrëftfamill fir d'Ännerungsfënster:",
-       "editfont-default": "Standard vum Browser",
        "editfont-monospace": "Schrëft mat enger fixer Breet (fir all Zeechen)",
        "editfont-sansserif": "Schrëft ouni Serifen",
        "editfont-serif": "Schrëft mat Serifen",
index d880658..d4f0ae1 100644 (file)
@@ -72,7 +72,6 @@
        "underline-never": "絕",
        "underline-default": "慣",
        "editfont-style": "纂字樣:",
-       "editfont-default": "慣",
        "editfont-monospace": "固字",
        "editfont-sansserif": "哥特字",
        "editfont-serif": "宋明字",
index a8849fa..fb4a3f5 100644 (file)
@@ -72,7 +72,6 @@
        "underline-never": "Никогаш",
        "underline-default": "Според рувото или прелистувачот",
        "editfont-style": "Фонт во полето за уредување:",
-       "editfont-default": "Основен прелистувач:",
        "editfont-monospace": "Сразмерно широк фонт",
        "editfont-sansserif": "Бессерифен фонт",
        "editfont-serif": "Серифен фонт",
        "ipb_blocked_as_range": "Грешка: IP-адресата $1 не е непосредно блокирана и не може да се одблокира.\nТаа е блокирана како дел од блокот адреси $2, кој не може да се одблокира.",
        "ip_range_invalid": "Неважечки IP дијапазон на адреси.",
        "ip_range_toolarge": "Не се дозволени опсежни блокирања поголеми од /$1.",
+       "ip_range_exceeded": "IP-опсегот ја надминува горната граница. Допуштен опсег: /$1.",
+       "ip_range_toolow": "IP-опсезите не се дозволени.",
        "proxyblocker": "Блокер на застапници (proxy)",
        "proxyblockreason": "Вашата IP-адреса е блокирана бидејќи претставува отворен застапник (proxy).\nВе молиме контактирајте со вашиот семрежен услужник и или техничката поддршка и информирајте ги за овој сериозен безбедносен проблем.",
        "sorbs": "DNSBL",
index a991a5c..990ea6f 100644 (file)
@@ -75,7 +75,6 @@
        "underline-never": "Jangan",
        "underline-default": "Tetapan lalai kulit/pelayar",
        "editfont-style": "Gaya fon ruang sunting:",
-       "editfont-default": "Lalaian pelayar web",
        "editfont-monospace": "Fon monospace",
        "editfont-sansserif": "Fon sans-serif",
        "editfont-serif": "Fon serif",
index 20ecd97..e3d3422 100644 (file)
@@ -56,7 +56,6 @@
        "underline-never": "Nunca",
        "underline-default": "Outelizar la oupçon padron de la maçcarilha ó de l nabegador",
        "editfont-style": "Fuonte d'eidiçon:",
-       "editfont-default": "Fuonte por omisson, de l nabegador",
        "editfont-monospace": "Fuonte monospaçada",
        "editfont-sansserif": "Fuonte sin serifa",
        "editfont-serif": "Fuonte serifada",
index 51aadff..0e2bd64 100644 (file)
@@ -72,7 +72,6 @@
        "underline-never": "ဘယ်သောအခါမျှ",
        "underline-default": "ဘရောက်ဆာ သို့ Skin default အတိုင်း",
        "editfont-style": "ဖောင့်စတိုင်ကို ပြုပြင်ရန် -",
-       "editfont-default": "ဘရောက်ဆာ default အတိုင်း",
        "editfont-monospace": "စာလုံးတိုင်းအရွယ်ညီသောဖောင့်",
        "editfont-sansserif": "အတက်မပါသောဖောင့်",
        "editfont-serif": "အတက်ပါသောဖောင့်",
index b69d242..02ec826 100644 (file)
@@ -59,7 +59,6 @@
        "underline-never": "Tiāⁿ-tio̍h mài",
        "underline-default": "Tòe liû-lám-khì ê siat-piān",
        "editfont-style": "Pian-chi̍p sî ēng ê jī-thé hêng-sek:",
-       "editfont-default": "Tòe liû-lám-khì ê default",
        "editfont-monospace": "Kāng-khoán-khoah ê jī-thé",
        "editfont-sansserif": "Sans-serif jī-thé",
        "editfont-serif": "Serif jī-thé",
index c882caf..4d339b4 100644 (file)
        "underline-never": "Aldri",
        "underline-default": "Drakta eller nettleserens standardinnstillinger",
        "editfont-style": "Skrifttype i redigeringsboksen:",
-       "editfont-default": "Nettleserstandard",
        "editfont-monospace": "Fastbredde skrifttype",
        "editfont-sansserif": "Sans-serif skrifttype",
        "editfont-serif": "Serif skrifttype",
        "block": "Blokker bruker",
        "unblock": "Fjern blokkering av bruker",
        "blockip": "Blokker {{GENDER:$1|bruker}}",
-       "blockip-legend": "Blokker bruker",
        "blockiptext": "Bruk skjemaet under for å blokkere skrivetilgangen til en spesifikk IP-adresse eller et brukernavn.\nDette bør kun gjøres for å forhindre vandalisme, og i samsvar med [[{{MediaWiki:Policy-url}}|retningslinjene]].\nSkriv inn en spesifikk grunn nedenfor (for eksempel ved å angi hvilke sider som ble vandalisert).\nDu kan blokkere IP-intervaller med [https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing CIDR]-syntaks; det største tillatte intervallet er /$1 for IPv4 og /$2 for IPv6.",
        "ipaddressorusername": "IP-adresse eller brukernavn",
        "ipbexpiry": "Varighet:",
        "ipb_blocked_as_range": "Feil: IP-en $1 er ikke blokkert direkte, og kan ikke avblokkeres. Den er imidlertid blokkert som del av blokkeringa av IP-rangen $2, som kan avblokkeres.",
        "ip_range_invalid": "Ugyldig IP-rad.",
        "ip_range_toolarge": "Blokkering av IP-serier større enn /$1 er ikke tillatt.",
+       "ip_range_exceeded": "IP-intervallet er høyere enn det maksimalt tillatte. Tillatt intervall: /$1.",
+       "ip_range_toolow": "IP-intervaller er i praksis ikke tillatt.",
        "proxyblocker": "Proxyblokker",
        "proxyblockreason": "IP-adressen din ble blokkert fordi den er en åpen proxy. Kontakt internettleverandøren din eller teknisk støtte og informer dem om dette alvorlige sikkerhetsproblemet.",
        "sorbsreason": "IP-adressen din er listet som en åpen proxy i DNSBL-en brukt av {{SITENAME}}.",
        "delete_and_move_text": "Målsiden «[[:$1]]» finnes fra før.\nØnsker du å slette den for å muliggjøre flyttingen?",
        "delete_and_move_confirm": "Ja, slett siden",
        "delete_and_move_reason": "Slettet for å muliggjøre flytting fra \"[[$1]]\"",
-       "selfmove": "Kilde- og destinasjonstittel er den samme; kan ikke flytte siden.",
+       "selfmove": "Tittelen er den samme; kan ikke flytte en side til seg selv.",
        "immobile-source-namespace": "Kan ikke flytte sider i navnerommet «$1»",
        "immobile-target-namespace": "Kan ikke flytte sider til navnerommet «$1»",
        "immobile-target-namespace-iw": "Du kan ikke flytte en side til et navn som er en interwikilenke.",
index e3b38d8..fa7fd80 100644 (file)
        "underline-never": "Nooit",
        "underline-default": "Standaardgedrag van vormgeving of webbrowser",
        "editfont-style": "Lettertypestijl bewerkingsvenster:",
-       "editfont-default": "Webbrowser-standaard",
        "editfont-monospace": "Monospaced lettertype",
        "editfont-sansserif": "Sans-serif lettertype",
        "editfont-serif": "Serif lettertype",
index b46b0ad..4374ace 100644 (file)
@@ -76,7 +76,6 @@
        "underline-never": "Aldri",
        "underline-default": "Drakt- eller nettlesarstandard",
        "editfont-style": "Skrifttype i endringsboksen:",
-       "editfont-default": "Nettlesarstandard",
        "editfont-monospace": "Skrift med fast breidd",
        "editfont-sansserif": "Skrifttype utan seriffar",
        "editfont-serif": "Skrifttype med seriffar",
index 1c8b605..c74c197 100644 (file)
        "underline-never": "Nigdy",
        "underline-default": "według ustawień skórki lub przeglądarki",
        "editfont-style": "Styl czcionki w polu edycyjnym:",
-       "editfont-default": "Domyślny przeglądarki",
        "editfont-monospace": "czcionka o stałej szerokości",
        "editfont-sansserif": "czcionka bezszeryfowa",
        "editfont-serif": "czcionka szeryfowa",
index ac66c22..fa31330 100644 (file)
@@ -59,7 +59,6 @@
        "underline-never": "هېڅکله",
        "underline-default": "د کتنمل تلواليزې چارې",
        "editfont-style": "د سيمه ايزې ليکبڼې سمول:",
-       "editfont-default": "د کتنمل تلواليزې چارې",
        "editfont-monospace": "يو واټنيزه ليکبڼه",
        "editfont-sansserif": "سان سېرېف ليکبڼه",
        "editfont-serif": "سېرېف ليکبڼه",
index b8ce9d9..070ca9e 100644 (file)
@@ -78,7 +78,7 @@
                        "MokaAkashiyaPT"
                ]
        },
-       "tog-underline": "Sublinhar ligações:",
+       "tog-underline": "Sublinhar hiperligações:",
        "tog-hideminor": "Esconder edições menores nas mudanças recentes",
        "tog-hidepatrolled": "Esconder edições patrulhadas nas mudanças recentes",
        "tog-newpageshidepatrolled": "Esconder páginas patrulhadas na lista de páginas novas",
        "tog-watchlisthideminor": "Esconder edições menores ao listar mudanças às páginas vigiadas",
        "tog-watchlisthideliu": "Esconder edições de utilizadores autenticados ao listar mudanças às páginas vigiadas",
        "tog-watchlistreloadautomatically": "Recarregar a lista de páginas vigiadas automaticamente sempre que um filtro é alterado (requer JavaScript)",
-       "tog-watchlistunwatchlinks": "Adicionar links diretos para vigiar ou deixar de vigiar, às entradas da lista de páginas vigiadas (é necessário o JavaScript para alternar entre ambas)",
+       "tog-watchlistunwatchlinks": "Adicionar hiperligações diretas para vigiar ou deixar de vigiar, às entradas da lista de páginas vigiadas (é necessário o JavaScript para alternar entre ambas)",
        "tog-watchlisthideanons": "Esconder edições de utilizadores anónimos ao listar mudanças às páginas vigiadas",
        "tog-watchlisthidepatrolled": "Esconder edições patrulhadas ao listar mudanças às páginas vigiadas",
        "tog-watchlisthidecategorization": "Ocultar categorização de páginas",
        "underline-never": "Nunca",
        "underline-default": "Usar opção padrão do tema ou do navegador",
        "editfont-style": "Fonte de edição:",
-       "editfont-default": "Fonte por omissão, do navegador",
        "editfont-monospace": "Fonte monoespaçada",
        "editfont-sansserif": "Fonte sem serifa",
        "editfont-serif": "Fonte serifada",
        "listingcontinuesabbrev": "cont.",
        "index-category": "Páginas indexadas",
        "noindex-category": "Páginas não indexadas",
-       "broken-file-category": "Páginas com ligações quebradas para ficheiros",
+       "broken-file-category": "Páginas com hiperligações quebradas para ficheiros",
        "about": "Sobre",
        "article": "Página de conteúdo",
        "newwindow": "(abre numa janela nova)",
        "history_small": "histórico",
        "updatedmarker": "atualizado desde a minha última visita",
        "printableversion": "Versão para impressão",
-       "permalink": "Ligação permanente",
+       "permalink": "Hipeligação permanente",
        "print": "Imprimir",
        "view": "Ver",
        "view-foreign": "Ver em $1",
        "nstab-category": "Categoria",
        "mainpage-nstab": "Página principal",
        "nosuchaction": "Operação não existe",
-       "nosuchactiontext": "A operação especificada pelo URL é inválida.\nÉ possível que tenha escrito mal o URL ou seguido uma ligação incorreta.\nIsto pode também indicar um defeito no software da wiki {{SITENAME}}.",
+       "nosuchactiontext": "A operação especificada pelo URL é inválida.\nÉ possível que tenha escrito mal o URL ou seguido uma hiperligação incorreta.\nIsto pode também indicar um defeito no software da wiki {{SITENAME}}.",
        "nosuchspecialpage": "Esta página especial não existe",
        "nospecialpagetext": "<strong>Solicitou uma página especial inválida.</strong>\n\nEncontra uma lista das páginas especiais válidas em [[Special:SpecialPages|{{int:specialpages}}]].",
        "error": "Erro",
        "readonly": "Base de dados bloqueada (limitada a leituras)",
        "enterlockreason": "Introduza um motivo para bloquear, incluindo uma estimativa de quando será desbloqueada",
        "readonlytext": "A base de dados está atualmente bloqueada para novas entradas e outras modificações, provavelmente para uma manutenção de rotina, após a qual voltará à sua normalidade.\n\nO administrador que a bloqueou deu a seguinte explicação: $1",
-       "missing-article": "A base de dados não encontrou o texto de uma página que deveria ter encontrado, com o nome \"$1\" $2.\n\nGeralmente, esta situação ocorre ao clicar numa ligação para diferenças desatualizada ou para o histórico de uma página que tenha sido removida.\n\nSe nenhuma destas situações se verifica, pode ter encontrado um defeito no programa.\nAnote o URL e reporte este incidente a um [[Special:ListUsers/sysop|administrador]], por favor.",
+       "missing-article": "A base de dados não encontrou o texto de uma página que deveria ter encontrado, com o nome \"$1\" $2.\n\nGeralmente, esta situação ocorre ao clicar numa hiperligação para diferenças desatualizada ou para o histórico de uma página que tenha sido removida.\n\nSe nenhuma destas situações se verifica, pode ter encontrado um defeito no programa.\nAnote o URL e reporte este incidente a um [[Special:ListUsers/sysop|administrador]], por favor.",
        "missingarticle-rev": "(revisão#: $1)",
        "missingarticle-diff": "(Dif.: $1, $2)",
        "readonly_lag": "A base de dados foi automaticamente bloqueada enquanto os servidores secundários se sincronizam com o primário",
        "ipb_blocked_as_range": "Erro: O IP $1 não se encontra bloqueado de forma direta e não pode ser desbloqueado deste modo. No entanto, está bloqueado como parte da gama $2, a qual pode ser desbloqueada.",
        "ip_range_invalid": "Gama de endereços IP inválida.",
        "ip_range_toolarge": "Não são permitidas gamas de IP maiores do que /$1.",
+       "ip_range_exceeded": "A gama IP excede o intervalo máximo. Intervalo permitido: /$1.",
+       "ip_range_toolow": "Na prática, gamas IP não são permitidas.",
        "proxyblocker": "Bloqueador de proxies",
        "proxyblockreason": "O seu endereço IP foi bloqueado por ser um ''proxy'' público.\nContacte o seu fornecedor de internet ou o serviço de apoio técnico e informe-os deste grave problema de segurança, por favor.",
        "sorbsreason": "O seu endereço IP encontra-se listado como ''proxy'' aberto na DNSBL utilizada pela wiki {{SITENAME}}.",
index d4c150d..4d6cf93 100644 (file)
        "underline-never": "Used in [[Special:Preferences#mw-prefsection-rendering|Preferences]].\n\nThis option means \"never underline links\", there are also options {{msg-mw|Underline-always}} and {{msg-mw|Underline-default}}.\n\n{{Gender}}\n{{Identical|Never}}",
        "underline-default": "Used in [[Special:Preferences#mw-prefsection-rendering|Preferences]].\n\nThis option means \"underline links as in your user skin or your browser\", there are also options {{msg-mw|Underline-never}} and {{msg-mw|Underline-always}}.\n\n{{Gender}}\n{{Identical|Browser default}}",
        "editfont-style": "Used in [[Special:Preferences]], tab Editing. {{Gender}}",
-       "editfont-default": "Option used in [[Special:Preferences]], tab Editing. {{Gender}}\n{{Identical|Browser default}}",
        "editfont-monospace": "Option used in [[Special:Preferences]], tab Editing. {{Gender}}",
        "editfont-sansserif": "Option used in [[Special:Preferences]], tab Editing. {{Gender}}",
        "editfont-serif": "Option used in [[Special:Preferences]], tab Editing. {{Gender}}",
        "rcfilters-view-namespaces-tooltip": "Tooltip for the button that loads the namespace view in [[Special:RecentChanges]]",
        "rcfilters-view-tags-tooltip": "Tooltip for the button that loads the tags view in [[Special:RecentChanges]]",
        "rcfilters-view-return-to-default-tooltip": "Tooltip for the button that returns to the default filter view in [[Special:RecentChanges]]",
+       "rcfilters-view-tags-help-icon-tooltip": "Tooltip for the help button that leads user to [[mw:Special:MyLanguage/Help:New_filters_for_edit_review/Advanced_filters#tags|Help page]] for Tagged Edits",
        "rcfilters-liveupdates-button": "Label for the button to enable or disable live updates on [[Special:RecentChanges]]",
        "rcfilters-liveupdates-button-title-on": "Title for the button to enable or disable live updates on [[Special:RecentChanges]] when the feature is ON.",
        "rcfilters-liveupdates-button-title-off": "Title for the button to enable or disable live updates on [[Special:RecentChanges]] when the feature is OFF.",
index cb111be..c278468 100644 (file)
@@ -59,7 +59,6 @@
        "underline-never": "Maje",
        "underline-default": "Valore de default d'u browser o scheme",
        "editfont-style": "Stile d'u carattere jndr'à l'area de le cangiaminde:",
-       "editfont-default": "Valore de default d'u browser",
        "editfont-monospace": "Carattere Monospaced",
        "editfont-sansserif": "Carattere Sans-serif",
        "editfont-serif": "Carattere Serif",
index 0c56dc9..c80ad6a 100644 (file)
                        "Valeri'swiki",
                        "Marat-avgust",
                        "Ernác",
-                       "Wertuose"
+                       "Wertuose",
+                       "Helpau"
                ]
        },
        "tog-underline": "Подчёркивание ссылок:",
        "underline-never": "Никогда",
        "underline-default": "Использовать настройки браузера",
        "editfont-style": "Тип шрифта области редактирования:",
-       "editfont-default": "Шрифт из настроек браузера",
        "editfont-monospace": "Моноширинный шрифт",
        "editfont-sansserif": "Шрифт без засечек",
        "editfont-serif": "Шрифт с засечками",
        "nstab-template": "Шаблон",
        "nstab-help": "Справка",
        "nstab-category": "Категория",
-       "mainpage-nstab": "Ð\97аглавнаÑ\8f",
+       "mainpage-nstab": "Ð\93лавнаÑ\8f Ñ\81Ñ\82Ñ\80аниÑ\86а",
        "nosuchaction": "Такого действия нет",
        "nosuchactiontext": "Указанное в URL действие ошибочно.\nВозможно, вы допустили опечатку при наборе URL или перешли по ошибочной ссылке.\nЭто может также указывать на ошибку в проекте {{SITENAME}}.",
        "nosuchspecialpage": "Нет такой служебной страницы",
index c91fd2b..3940b1b 100644 (file)
@@ -58,7 +58,6 @@
        "underline-never": "Tis hõ ban̕",
        "underline-default": "Browjarre cetlekate em hoy akana",
        "editfont-style": "Sompadon ṭhại reaḱ fonṭ sṭayel:",
-       "editfont-default": "Sendra do sedaere ṭhikakana",
        "editfont-monospace": "Monoespeć fonṭ",
        "editfont-sansserif": "Sans-serif fonṭ",
        "editfont-serif": "Serif fonṭ",
index 55de6e8..c6d54eb 100644 (file)
@@ -75,7 +75,6 @@
        "underline-never": "Niver",
        "underline-default": "Skin or brouser defaut",
        "editfont-style": "Eidit area font style:",
-       "editfont-default": "Brouser defaut",
        "editfont-monospace": "Monospaced font",
        "editfont-sansserif": "Sans-serif font",
        "editfont-serif": "Serif font",
index 870fddc..be47107 100644 (file)
@@ -53,7 +53,6 @@
        "underline-never": "ڪڏهن بہ نہ",
        "underline-default": "پيش طَي چَم يا جھانگُو",
        "editfont-style": "ايراضي جو فونٽ اسٽائيل سنواريو:",
-       "editfont-default": "پيش طَي جھانگُو",
        "editfont-monospace": "يڪ وٺيل اِنڊو",
        "editfont-sansserif": "بي سريف اِنڊو",
        "editfont-serif": "باسريف اِنڊو",
index 6300370..593980e 100644 (file)
@@ -22,7 +22,6 @@
        "underline-never": "کݙاہیں وی کائناں",
        "underline-default": "سکن یا براؤزر دا طے شدہ",
        "editfont-style": "خانہ ترمیم دا فونٹ",
-       "editfont-default": "براؤزر دا طے شدہ",
        "editfont-monospace": "مونوسپیسڈ فونٹ",
        "editfont-sansserif": "سنس سیرف فونٹ",
        "editfont-serif": "سیرف فونٹ",
index 0db60f6..16f197f 100644 (file)
@@ -65,7 +65,6 @@
        "underline-never": "Nikoli",
        "underline-default": "Koža ali privzeto v brskalniku",
        "editfont-style": "Slog pisave urejevalnega polja:",
-       "editfont-default": "Privzeto po brskalniku",
        "editfont-monospace": "Pisava monospace",
        "editfont-sansserif": "Pisava sans-serif",
        "editfont-serif": "Pisava serif",
        "block": "Blokiraj uporabnika",
        "unblock": "Odblokiraj uporabnika",
        "blockip": "Blokiraj {{GENDER:$1|uporabnika|uporabnico}}",
-       "blockip-legend": "Blokiraj uporabnika",
        "blockiptext": "Naslednji obrazec vam omogoča, da določenemu IP-naslovu ali uporabniškemu imenu preprečite urejanje.\nTo storimo le zaradi zaščite pred nepotrebnim uničevanjem in po [[{{MediaWiki:Policy-url}}|pravilih]].\nVnesite tudi razlog (''na primer'' seznam strani, ki jih je uporabnik po nepotrebnem kvaril).\nBlokirate lahko razpone IP s skladnjo[https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing CIDR]; najširši dovoljen razpon je /$1 za IPv4 in /$2 za IPv6.",
        "ipaddressorusername": "IP-naslov ali uporabniško ime",
        "ipbexpiry": "Pretek",
        "ipb_blocked_as_range": "Napaka: IP-naslov $1 ni blokiran direktno in ga zato ni mogoče odblokirati.\nJe pa blokiran kot del območja $2, ki ga lahko odblokirate.",
        "ip_range_invalid": "Neveljaven IP-razpon.",
        "ip_range_toolarge": "Območja blokade večja od /$1 niso dovoljena.",
+       "ip_range_exceeded": "Območje IP presega največji dovoljen obseg. Dovoljen obseg: /$1.",
+       "ip_range_toolow": "Območja IP niso učinkovito dovoljena.",
        "proxyblocker": "Blokator posredniških strežnikov",
        "proxyblockreason": "Ker uporabljate odprti posredniški strežnik, je urejanje z vašega IP-naslova preprečeno.\nGre za resno varnostno težavo, o kateri obvestite svojega internetnega ponudnika ali tehnično podporo.",
        "sorbsreason": "Vaš IP-naslov je v DNSBL uvrščen med odprte posredniške strežnike.",
index c025ad3..04a15d5 100644 (file)
@@ -84,7 +84,6 @@
        "underline-never": "Никад не подвлачи",
        "underline-default": "Према теми или прегледачу",
        "editfont-style": "Изглед фонта у уређивачком оквиру:",
-       "editfont-default": "По поставкама прегледача",
        "editfont-monospace": "Сразмерно широк фонт",
        "editfont-sansserif": "Бесерифни фонт",
        "editfont-serif": "Серифни фонт",
index db4fbe8..aa099c1 100644 (file)
@@ -76,7 +76,6 @@
        "underline-never": "nikad ne podvlači",
        "underline-default": "prema temi ili pregledaču",
        "editfont-style": "Izgled fonta u uređivačkom okviru:",
-       "editfont-default": "po postavkama pregledača",
        "editfont-monospace": "srazmerno širok font",
        "editfont-sansserif": "beserifni font",
        "editfont-serif": "serifni font",
index cb74e1e..504aa6f 100644 (file)
@@ -64,7 +64,6 @@
        "underline-never": "Ulah",
        "underline-default": "Kalakop atawa panyungsi bawaan",
        "editfont-style": "Gaya tulisan komputer dina kotak éditan:",
-       "editfont-default": "Bawaan panyungsi",
        "editfont-monospace": "Tulisan monospasi",
        "editfont-sansserif": "Aksara Sans-serif",
        "editfont-serif": "Aksara Serif",
index 266d85f..9041296 100644 (file)
        "underline-never": "Aldrig",
        "underline-default": "Webbläsarens eller utseendets standardinställning",
        "editfont-style": "Typsnitt i redigeringsrutan:",
-       "editfont-default": "Webbläsarens standard",
        "editfont-monospace": "Fast bredd",
        "editfont-sansserif": "Sans-serif-teckensnitt",
        "editfont-serif": "Serif-teckensnitt",
        "ipb_blocked_as_range": "Fel: IP-adressen $1 är inte direkt blockerad, och kan därför inte avblockeras. Adressen är blockerad som en del av IP-intervallet $2, som kan avblockeras.",
        "ip_range_invalid": "Ogiltigt IP-intervall.",
        "ip_range_toolarge": "Blockering av block större än /$1 är inte tillåtna.",
+       "ip_range_exceeded": "Ett för stort intervall IP-adresser har valts. Intervallet får inte vara större än: /$1.",
+       "ip_range_toolow": "Intervall av IP-adresser tillåts inte.",
        "proxyblocker": "Proxy-block",
        "proxyblockreason": "Din IP-adress har blivit blockerad eftersom den tillhör en öppen proxy. Kontakta din internetleverantör eller din organisations eller företags tekniska support, och informera dem om denna allvarliga säkerhetsrisk.",
        "sorbsreason": "Din IP-adress är listad som öppen proxy i den DNSBL {{SITENAME}} använder.",
index 25c0457..69940f3 100644 (file)
@@ -60,7 +60,6 @@
        "underline-never": "Ҳеҷгоҳ",
        "underline-default": "Пӯст ё мурургари пешфарз",
        "editfont-style": "Сабки қалами ҷаъбаи вироиш:",
-       "editfont-default": "Пешфарзи мурургар",
        "editfont-monospace": "Қалами бо фосилаи собит",
        "editfont-sansserif": "Қалами бидуни гӯша",
        "editfont-serif": "Қалами гӯшадор",
        "disclaimers": "Такзибнома",
        "disclaimerpage": "Project:Такзибномаи умумӣ",
        "edithelp": "Роҳнамои вироиш",
-       "mainpage": "СаҳиÑ\84аи Ð\90слӣ",
-       "mainpage-description": "СаҳиÑ\84аи Ð\90слӣ",
+       "mainpage": "СаҳиÑ\84аи Ð°слӣ",
+       "mainpage-description": "СаҳиÑ\84аи Ð°слӣ",
        "policy-url": "Project:Сиёсатҳо",
        "portal": "Вуруди корбарон",
        "portal-url": "Project:Вуруди корбарон",
        "nstab-image": "Файл",
        "nstab-mediawiki": "Пайём",
        "nstab-template": "Шаблон",
-       "nstab-help": "Кӯмак",
+       "nstab-help": "Кумак",
        "nstab-category": "Гурӯҳ",
        "mainpage-nstab": "Саҳифаи аслӣ",
        "nosuchaction": "Чунин амале вуҷуд надорад",
        "explainconflict": "Аз вақте ки шумо вироиши ин саҳифаро оғоз кардаед, шахси дигаре онро тағйир дода аст.\nНоҳияи матни болои шомили матни саҳифа ба шакли феълии он аст.\nТағйироти шумо дар ноҳияи матни поёни нишон дода шудааст.\nШумо бояд тағйиротатонро бо матни феълӣ таркиб кунед.\n'''Фақат''', вақте, ки тугмаи \"$1\"-ро фишор диҳед матни ноҳияи матни болои захира хоҳад шуд.",
        "yourtext": "Матни Шумо",
        "storedversion": "Нусхаи сабтшуда",
-       "nonunicodebrowser": "'''Ҳушдор: Муругари шумо бо стандарти Юникод ҷавобгӯ нест. Аломатҳои ғайр аз ASC11 ба сурати адад ба коди шонздаҳ ба шумо нишон дода мешаванд.'''",
        "editingold": "'''ҲУШДОР: Шумо нусхаи кӯҳнаи ин саҳифаро вироиш карда истодаед.\nАгар шумо онро захира кунед, ҳар тағйире ки пас аз ин нусха анҷом шуда, аз байн хоҳад рафт.'''",
        "yourdiff": "Фарқиятҳо",
        "copyrightwarning": "Ҳамаи ҳиссагузорӣ ба {{SITENAME}} аз рӯи қонунҳои зерин $2 (нигаред $1 барои маълумоти бештар) ҳиссагузорӣ мешаванд. Агар Шумо намехоҳед, ки навиштаҷоти Шумо вироиш ва паҳн нашаванд, Шумо метавонед ин мақоларо нафиристед.<br /> Шумо ваъда медиҳед, ки худатон ин мақоларо навиштед ё ки аз сарчашмаҳои кушод нусхабардорӣ кардаед. '''АСАРҲОИ ҚОБИЛИ ҲУҚУҚИ МУАЛЛИФРО БЕ ИҶОЗАТ НАФИРИСТЕД!'''",
        "block": "Бастани корбар",
        "unblock": "Боз кардани корбар",
        "blockip": "Бастани корбар",
-       "blockip-legend": "Бастани корбар",
        "blockiptext": "Барои бастани дастрасии вироиши нишонаи IP ё номи корбарӣ мушаххас аз форми зерин истифода кунед.\nИн кор фақат бояд барои ҷилавгирӣ аз харобкори ва мувофиқи бо [[{{MediaWiki:Policy-url}}|сиёсати қатъи дастрасӣ]] анҷом шавад.\nДалели мушаххас барои ин корро дар зер зикр кунед (барои мисол, зикри саҳифаҳое, ки харобкорӣ шудаанд).",
        "ipaddressorusername": "IP нишона ё номи корбар:",
        "ipbexpiry": "Хотима:",
        "tooltip-search": "Ҷустуҷӯ дар {{SITENAME}}",
        "tooltip-search-go": "Гузаштан ба саҳифае, ки айнан чунин ном дорад, агар вуҷуд дошта бошад",
        "tooltip-search-fulltext": "Ҷустуҷӯи саҳифаҳое, ки чунин матн доранд",
-       "tooltip-p-logo": "СаҳиÑ\84аи Ð\90слӣ",
-       "tooltip-n-mainpage": "Ð\93Ñ\83заÑ\88Ñ\82ан Ð±Ð° Ð¡Ð°Ò³Ð¸Ñ\84аи Ð\90слӣ",
-       "tooltip-n-mainpage-description": "Ð\9cÑ\83Ñ\88оҳидаи саҳифаи аслӣ",
+       "tooltip-p-logo": "Ð\91озгаÑ\88Ñ\82 Ð±Ð° Ñ\81аҳиÑ\84аи Ð°слӣ",
+       "tooltip-n-mainpage": "Ð\91озгаÑ\88Ñ\82 Ð±Ð° Ñ\81аҳиÑ\84аи Ð°слӣ",
+       "tooltip-n-mainpage-description": "Ð\91озгаÑ\88Ñ\82 Ð±Ð° саҳифаи аслӣ",
        "tooltip-n-portal": "Дар бораи лоиҳа, чӣ корҳоро метавонед кард, ва дарёфти чизҳо",
        "tooltip-n-currentevents": "Ёфтани иттилооти пешзамина перомуни воқеаҳои кунунӣ",
        "tooltip-n-recentchanges": "Рӯйхати тағйирот дар Википедиа",
index 4acd5e9..afe61cd 100644 (file)
@@ -77,7 +77,6 @@
        "underline-never": "ไม่",
        "underline-default": "ค่าปริยายของหน้าตาหรือเบราว์เซอร์",
        "editfont-style": "รูปแบบชุดแบบอักษรในพื้นที่แก้ไข:",
-       "editfont-default": "ค่าปริยายของเบราว์เซอร์",
        "editfont-monospace": "ชุดอักษรแบบความกว้างคงที่",
        "editfont-sansserif": "ชุดอักษรแบบไม่มีเชิง",
        "editfont-serif": "ชุดอักษรแบบมีเชิง",
index 016051a..61ce439 100644 (file)
@@ -72,7 +72,6 @@
        "underline-never": "Hindi magpakailanman",
        "underline-default": "Tinakda ng pambasa-basa o balat",
        "editfont-style": "Baguhin ang estilong pantitik ng lugar:",
-       "editfont-default": "Tinakda ng pambasa-basa",
        "editfont-monospace": "Estilo ng titik na isahan ang puwang",
        "editfont-sansserif": "Estilo ng titik na walang gutli sa dulo",
        "editfont-serif": "Estilo ng titik na may gutli sa dulo",
index 696a46d..b169f3b 100644 (file)
@@ -82,7 +82,6 @@
        "underline-never": "کبھی نہیں",
        "underline-default": "پوشاک یا براؤزر کا طے شدہ",
        "editfont-style": "خانۂ ترمیم کا فانٹ:",
-       "editfont-default": "براؤزر کا طے شدہ",
        "editfont-monospace": "مونوسپیسڈ فونٹ",
        "editfont-sansserif": "سنس سیرف فونٹ",
        "editfont-serif": "سیرف فونٹ",
index 3daf3ce..0ab434b 100644 (file)
@@ -69,7 +69,6 @@
        "underline-never": "קיינמאל",
        "underline-default": "בלעטערער גרונטשטעלונג",
        "editfont-style": "רעדאקטירונג פאנט סטיל:",
-       "editfont-default": "בלעטערער גרונט־אויסווייל",
        "editfont-monospace": "פֿאנט מיט באשטימטער ברייט",
        "editfont-sansserif": "פאנטס אן קיין תגים (sans-serif)",
        "editfont-serif": "סעריף שריפֿט",
index 9df1f4c..82cbf5e 100644 (file)
        "underline-never": "从不",
        "underline-default": "皮肤或浏览器默认设置",
        "editfont-style": "编辑区字体样式:",
-       "editfont-default": "浏览器默认",
        "editfont-monospace": "等宽字体",
        "editfont-sansserif": "无衬线字体",
        "editfont-serif": "衬线字体",
        "ipb_blocked_as_range": "错误:IP地址$1未被直接封禁,故无法解除封禁。然而,它位于IP地址段$2的封禁范围内,后者可被解除封禁。",
        "ip_range_invalid": "无效的IP地址段。",
        "ip_range_toolarge": "不允许大于/$1的段封禁。",
+       "ip_range_exceeded": "IP段超过其最大范围。允许的范围:/$1。",
+       "ip_range_toolow": "这些IP段实际不允许。",
        "proxyblocker": "代理封禁器",
        "proxyblockreason": "您的IP地址为已被封禁的公开代理。请联系您的互联网服务提供商或技术支持者,并告知他们此严重的安全问题。",
        "sorbsreason": "在{{SITENAME}}使用的DNSBL中,您的IP地址被列为公开代理。",
index 6a1a7e2..4a73cab 100644 (file)
        "underline-never": "永不使用",
        "underline-default": "依外觀或瀏覽器預設值",
        "editfont-style": "編輯區字型樣式:",
-       "editfont-default": "瀏覽器預設值",
        "editfont-monospace": "等距字型",
        "editfont-sansserif": "無襯線字型",
        "editfont-serif": "襯線字型",
index 235bb59..b31926b 100644 (file)
@@ -1904,6 +1904,7 @@ return [
                        'rcfilters-view-namespaces-tooltip',
                        'rcfilters-view-tags-tooltip',
                        'rcfilters-view-return-to-default-tooltip',
+                       'rcfilters-view-tags-help-icon-tooltip',
                        'rcfilters-liveupdates-button',
                        'rcfilters-liveupdates-button-title-on',
                        'rcfilters-liveupdates-button-title-off',
@@ -2012,6 +2013,8 @@ return [
        'mediawiki.special.block' => [
                'scripts' => 'resources/src/mediawiki.special/mediawiki.special.block.js',
                'dependencies' => [
+                       'oojs-ui-core',
+                       'mediawiki.widgets.SelectWithInputWidget',
                        'mediawiki.util',
                        'mediawiki.htmlform',
                ],
@@ -2653,6 +2656,21 @@ return [
                'targets' => [ 'desktop', 'mobile' ],
        ],
 
+       /**
+        * html5shiv
+        *
+        * This library is intended to run on older browsers
+        * that MediaWiki no longer supports as Grade A, and
+        * is not loaded through the normal module loading
+        * system.
+        */
+       'html5shiv' => [
+               'scripts' => [
+                       'resources/lib/html5shiv/html5shiv.js'
+               ],
+               'raw' => true,
+       ],
+
        /* OOjs */
        'oojs' => [
                'scripts' => [
diff --git a/resources/lib/html5shiv/html5shiv.min.js b/resources/lib/html5shiv/html5shiv.min.js
deleted file mode 100644 (file)
index 355afd1..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-/**
-* @preserve HTML5 Shiv 3.7.3 | @afarkas @jdalton @jon_neal @rem | MIT/GPL2 Licensed
-*/
-!function(a,b){function c(a,b){var c=a.createElement("p"),d=a.getElementsByTagName("head")[0]||a.documentElement;return c.innerHTML="x<style>"+b+"</style>",d.insertBefore(c.lastChild,d.firstChild)}function d(){var a=t.elements;return"string"==typeof a?a.split(" "):a}function e(a,b){var c=t.elements;"string"!=typeof c&&(c=c.join(" ")),"string"!=typeof a&&(a=a.join(" ")),t.elements=c+" "+a,j(b)}function f(a){var b=s[a[q]];return b||(b={},r++,a[q]=r,s[r]=b),b}function g(a,c,d){if(c||(c=b),l)return c.createElement(a);d||(d=f(c));var e;return e=d.cache[a]?d.cache[a].cloneNode():p.test(a)?(d.cache[a]=d.createElem(a)).cloneNode():d.createElem(a),!e.canHaveChildren||o.test(a)||e.tagUrn?e:d.frag.appendChild(e)}function h(a,c){if(a||(a=b),l)return a.createDocumentFragment();c=c||f(a);for(var e=c.frag.cloneNode(),g=0,h=d(),i=h.length;i>g;g++)e.createElement(h[g]);return e}function i(a,b){b.cache||(b.cache={},b.createElem=a.createElement,b.createFrag=a.createDocumentFragment,b.frag=b.createFrag()),a.createElement=function(c){return t.shivMethods?g(c,a,b):b.createElem(c)},a.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+d().join().replace(/[\w\-:]+/g,function(a){return b.createElem(a),b.frag.createElement(a),'c("'+a+'")'})+");return n}")(t,b.frag)}function j(a){a||(a=b);var d=f(a);return!t.shivCSS||k||d.hasCSS||(d.hasCSS=!!c(a,"article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}mark{background:#FF0;color:#000}template{display:none}")),l||i(a,d),a}var k,l,m="3.7.3",n=a.html5||{},o=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,p=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,q="_html5shiv",r=0,s={};!function(){try{var a=b.createElement("a");a.innerHTML="<xyz></xyz>",k="hidden"in a,l=1==a.childNodes.length||function(){b.createElement("a");var a=b.createDocumentFragment();return"undefined"==typeof a.cloneNode||"undefined"==typeof a.createDocumentFragment||"undefined"==typeof a.createElement}()}catch(c){k=!0,l=!0}}();var t={elements:n.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output picture progress section summary template time video",version:m,shivCSS:n.shivCSS!==!1,supportsUnknownElements:l,shivMethods:n.shivMethods!==!1,type:"default",shivDocument:j,createElement:g,createDocumentFragment:h,addElements:e};a.html5=t,j(b),"object"==typeof module&&module.exports&&(module.exports=t)}("undefined"!=typeof window?window:this,document);
\ No newline at end of file
index 9930525..74233d6 100644 (file)
@@ -111,12 +111,6 @@ span.comment {
 }
 
 /* Edit font preference */
-/* TODO: for 'default' on non-textareas we could compute the default font of textarea in the client */
-.mw-editfont-default:not( textarea ) {
-       font-family: monospace;
-}
-
-/* Keep this rule separate from the :not rule above so it still works in older browsers */
 .mw-editfont-monospace {
        font-family: monospace;
 }
index 4dc86f6..309978f 100644 (file)
                return this.type;
        };
 
+       /**
+        * Check whether this group is represented by a single parameter
+        * or whether each item is its own parameter
+        *
+        * @return {boolean} This group is a single parameter
+        */
+       mw.rcfilters.dm.FilterGroup.prototype.isPerGroupRequestParameter = function () {
+               return (
+                       this.getType() === 'string_options' ||
+                       this.getType() === 'single_option'
+               );
+       };
+
        /**
         * Get display group
         *
index edb3d0f..5013c08 100644 (file)
                return result;
        };
 
+       /**
+        * Get the parameter names that represent filters that are excluded
+        * from saved queries.
+        *
+        * @return {string[]} Parameter names
+        */
+       mw.rcfilters.dm.FiltersViewModel.prototype.getExcludedParams = function () {
+               var result = [];
+
+               $.each( this.groups, function ( name, model ) {
+                       if ( model.isExcludedFromSavedQueries() ) {
+                               if ( model.isPerGroupRequestParameter() ) {
+                                       result.push( name );
+                               } else {
+                                       // Each filter is its own param
+                                       result = result.concat( model.getItems().map( function ( filterItem ) {
+                                               return filterItem.getParamName();
+                                       } ) );
+                               }
+                       }
+               } );
+
+               return result;
+       };
+
        /**
         * Analyze the groups and their filters and output an object representing
         * the state of the parameters they represent.
index f878941..2b17897 100644 (file)
@@ -7,10 +7,11 @@
         * @mixins OO.EmitterList
         *
         * @constructor
+        * @param {mw.rcfilters.dm.FiltersViewModel} filtersModel Filters model
         * @param {Object} [config] Configuration options
         * @cfg {string} [default] Default query ID
         */
-       mw.rcfilters.dm.SavedQueriesModel = function MwRcfiltersDmSavedQueriesModel( config ) {
+       mw.rcfilters.dm.SavedQueriesModel = function MwRcfiltersDmSavedQueriesModel( filtersModel, config ) {
                config = config || {};
 
                // Mixin constructor
@@ -18,7 +19,8 @@
                OO.EmitterList.call( this );
 
                this.default = config.default;
-               this.baseState = {};
+               this.filtersModel = filtersModel;
+               this.converted = false;
 
                // Events
                this.aggregate( { update: 'itemUpdate' } );
@@ -58,6 +60,9 @@
         * Initialize the saved queries model by reading it from the user's settings.
         * The structure of the saved queries is:
         * {
+        *    version: (string) Version number; if version 2, the query represents
+        *             parameters. Otherwise, the older version represented filters
+        *             and needs to be readjusted,
         *    default: (string) Query ID
         *    queries:{
         *       query_id_1: {
         *
         * @param {Object} [savedQueries] An object with the saved queries with
         *  the above structure.
-        * @param {Object} [baseState] An object representing the base state
-        *  so we can normalize the data
-        * @param {string[]} [ignoreFilters] Filters to ignore and remove from
-        *  the data
         * @fires initialize
         */
-       mw.rcfilters.dm.SavedQueriesModel.prototype.initialize = function ( savedQueries, baseState, ignoreFilters ) {
-               var items = [],
-                       defaultItem = null;
+       mw.rcfilters.dm.SavedQueriesModel.prototype.initialize = function ( savedQueries ) {
+               var model = this,
+                       excludedParams = this.filtersModel.getExcludedParams();
 
                savedQueries = savedQueries || {};
-               ignoreFilters = ignoreFilters || {};
-
-               this.baseState = baseState;
 
                this.clearItems();
+               this.default = null;
+               this.converted = false;
+
+               if ( savedQueries.version !== '2' ) {
+                       // Old version dealt with filter names. We need to migrate to the new structure
+                       // The new structure:
+                       // {
+                       //   version: (string) '2',
+                       //   default: (string) Query ID,
+                       //   queries: {
+                       //     query_id: {
+                       //       label: (string) Name of the query
+                       //       data: {
+                       //         params: (object) Representing all the parameter states
+                       //         highlights: (object) Representing all the filter highlight states
+                       //     }
+                       //   }
+                       // }
+                       $.each( savedQueries.queries || {}, function ( id, obj ) {
+                               if ( obj.data && obj.data.filters ) {
+                                       obj.data = model.convertToParameters( obj.data );
+                               }
+                       } );
+
+                       this.converted = true;
+                       savedQueries.version = '2';
+               }
+
+               // Initialize the query items
                $.each( savedQueries.queries || {}, function ( id, obj ) {
-                       var item,
-                               normalizedData = $.extend( true, {}, baseState, obj.data ),
+                       var normalizedData = obj.data,
                                isDefault = String( savedQueries.default ) === String( id );
 
-                       // Backwards-compat fix: We stored the 'highlight' state with
-                       // "1" and "0" instead of true/false; for already-stored states,
-                       // we need to fix that.
-                       // NOTE: Since this feature is only available in beta, we should
-                       // not need this line when we release this to the general wikis.
-                       // This method will automatically fix all saved queries anyways
-                       // for existing users, who are only betalabs users at the moment.
-                       normalizedData.highlights.highlight = !!Number( normalizedData.highlights.highlight );
-
-                       // Backwards-compat fix: Remove sticky parameters from the 'ignoreFilters' list
-                       ignoreFilters.forEach( function ( name ) {
-                               delete normalizedData.filters[ name ];
-                       } );
+                       if ( normalizedData && normalizedData.params ) {
+                               // Backwards-compat fix: Remove excluded parameters from
+                               // the given data, if they exist
+                               excludedParams.forEach( function ( name ) {
+                                       delete normalizedData.params[ name ];
+                               } );
 
-                       item = new mw.rcfilters.dm.SavedQueryItemModel(
-                               id,
-                               obj.label,
-                               normalizedData,
-                               { 'default': isDefault }
-                       );
+                               id = String( id );
+                               model.addNewQuery( obj.label, normalizedData, isDefault, id );
 
-                       if ( isDefault ) {
-                               defaultItem = item;
+                               if ( isDefault ) {
+                                       model.default = id;
+                               }
                        }
+               } );
 
-                       items.push( item );
+               this.emit( 'initialize' );
+       };
+
+       /**
+        * Convert from representation of filters to representation of parameters
+        *
+        * @param {Object} data Query data
+        * @return {Object} New converted query data
+        */
+       mw.rcfilters.dm.SavedQueriesModel.prototype.convertToParameters = function ( data ) {
+               var newData = {},
+                       defaultFilters = this.filtersModel.getFiltersFromParameters( this.filtersModel.getDefaultParams() ),
+                       fullFilterRepresentation = $.extend( true, {}, defaultFilters, data.filters ),
+                       highlightEnabled = data.highlights.highlight;
+
+               delete data.highlights.highlight;
+
+               // Filters
+               newData.params = this.filtersModel.getParametersFromFilters( fullFilterRepresentation );
+
+               // Highlights (taking out 'highlight' itself, appending _color to keys)
+               newData.highlights = {};
+               Object.keys( data.highlights ).forEach( function ( highlightedFilterName ) {
+                       newData.highlights[ highlightedFilterName + '_color' ] = data.highlights[ highlightedFilterName ];
                } );
 
-               if ( defaultItem ) {
-                       this.default = defaultItem.getID();
+               // Add highlight and invert toggles to params
+               newData.params.highlight = String( Number( highlightEnabled || 0 ) );
+               newData.params.invert = String( Number( data.invert || 0 ) );
+
+               return newData;
+       };
+
+       /**
+        * Get an object representing the base state of parameters
+        * and highlights.
+        *
+        * This is meant to make sure that the saved queries that are
+        * in memory are always the same structure as what we would get
+        * by calling the current model's "getSelectedState" and by checking
+        * highlight items.
+        *
+        * In cases where a user saved a query when the system had a certain
+        * set of params, and then a filter was added to the system, we want
+        * to make sure that the stored queries can still be comparable to
+        * the current state, which means that we need the base state for
+        * two operations:
+        *
+        * - Saved queries are stored in "minimal" view (only changed params
+        *   are stored); When we initialize the system, we merge each minimal
+        *   query with the base state (using 'getMinimalParamList') so all
+        *   saved queries have the exact same structure as what we would get
+        *   by checking the getSelectedState of the filter.
+        * - When we save the queries, we minimize the object to only represent
+        *   whatever has actually changed, rather than store the entire
+        *   object. To check what actually is different so we can store it,
+        *   we need to obtain a base state to compare against, this is
+        *   what #getMinimalParamList does
+        *
+        * @return {Object} Base parameter state
+        */
+       mw.rcfilters.dm.SavedQueriesModel.prototype.getBaseParamState = function () {
+               var allParams,
+                       highlightedItems = {};
+
+               if ( !this.baseParamState ) {
+                       allParams = this.filtersModel.getParametersFromFilters( {} );
+
+                       // Prepare highlights
+                       this.filtersModel.getItemsSupportingHighlights().forEach( function ( item ) {
+                               highlightedItems[ item.getName() + '_color' ] = null;
+                       } );
+
+                       this.baseParamState = {
+                               params: $.extend( true, { invert: '0', highlight: '0' }, allParams ),
+                               highlights: highlightedItems
+                       };
                }
 
-               this.addItems( items );
+               return this.baseParamState;
+       };
 
-               this.emit( 'initialize' );
+       /**
+        * Get an object that holds only the parameters and highlights that have
+        * values different than the base value.
+        *
+        * This is the reverse of the normalization we do initially on loading and
+        * initializing the saved queries model.
+        *
+        * @param {Object} valuesObject Object representing the state of both
+        *  filters and highlights in its normalized version, to be minimized.
+        * @return {Object} Minimal filters and highlights list
+        */
+       mw.rcfilters.dm.SavedQueriesModel.prototype.getMinimalParamList = function ( valuesObject ) {
+               var result = { params: {}, highlights: {} },
+                       baseState = this.getBaseParamState();
+
+               // XOR results
+               $.each( valuesObject.params, function ( name, value ) {
+                       if ( baseState.params !== undefined && baseState.params[ name ] !== value ) {
+                               result.params[ name ] = value;
+                       }
+               } );
+
+               $.each( valuesObject.highlights, function ( name, value ) {
+                       if ( baseState.highlights !== undefined && baseState.highlights[ name ] !== value ) {
+                               result.highlights[ name ] = value;
+                       }
+               } );
+
+               return result;
        };
 
        /**
         *
         * @param {string} label Label for the new query
         * @param {Object} data Data for the new query
+        * @param {boolean} isDefault Item is default
+        * @param {string} [id] Query ID, if exists. If this isn't given, a random
+        *  new ID will be created.
         * @return {string} ID of the newly added query
         */
-       mw.rcfilters.dm.SavedQueriesModel.prototype.addNewQuery = function ( label, data ) {
-               var randomID = ( new Date() ).getTime(),
-                       normalizedData = $.extend( true, {}, this.baseState, data );
+       mw.rcfilters.dm.SavedQueriesModel.prototype.addNewQuery = function ( label, data, isDefault, id ) {
+               var randomID = String( id || ( new Date() ).getTime() ),
+                       normalizedData = this.getMinimalParamList( data );
 
                // Add item
                this.addItems( [
                        new mw.rcfilters.dm.SavedQueryItemModel(
                                randomID,
                                label,
-                               normalizedData
+                               normalizedData,
+                               { 'default': isDefault }
                        )
                ] );
 
+               if ( isDefault ) {
+                       this.setDefault( randomID );
+               }
+
                return randomID;
        };
 
         * @return {mw.rcfilters.dm.SavedQueryItemModel} Matching item model
         */
        mw.rcfilters.dm.SavedQueriesModel.prototype.findMatchingQuery = function ( fullQueryComparison ) {
-               var model = this;
-
-               fullQueryComparison = this.getDifferenceFromBase( fullQueryComparison );
+               // Minimize before comparison
+               fullQueryComparison = this.getMinimalParamList( fullQueryComparison );
 
                return this.getItems().filter( function ( item ) {
-                       var comparedData = model.getDifferenceFromBase( item.getData() );
                        return OO.compare(
-                               comparedData,
+                               item.getData(),
                                fullQueryComparison
                        );
                } )[ 0 ];
        };
 
-       /**
-        * Get a minimal representation of the state for comparison
-        *
-        * @param {Object} state Given state
-        * @return {Object} Minimal state
-        */
-       mw.rcfilters.dm.SavedQueriesModel.prototype.getDifferenceFromBase = function ( state ) {
-               var result = { filters: {}, highlights: {}, invert: state.invert },
-                       baseState = this.baseState;
-
-               // XOR results
-               $.each( state.filters, function ( name, value ) {
-                       if ( baseState.filters !== undefined && baseState.filters[ name ] !== value ) {
-                               result.filters[ name ] = value;
-                       }
-               } );
-
-               $.each( state.highlights, function ( name, value ) {
-                       if ( baseState.highlights !== undefined && baseState.highlights[ name ] !== value && name !== 'highlight' ) {
-                               result.highlights[ name ] = value;
-                       }
-               } );
-
-               return result;
-       };
        /**
         * Get query by its identifier
         *
                } )[ 0 ];
        };
 
+       /**
+        * Get an item's full data
+        *
+        * @param {string} queryID Query identifier
+        * @return {Object} Item's full data
+        */
+       mw.rcfilters.dm.SavedQueriesModel.prototype.getItemFullData = function ( queryID ) {
+               var item = this.getItemByID( queryID );
+
+               // Fill in the base params
+               return item ? $.extend( true, {}, this.getBaseParamState(), item.getData() ) : {};
+       };
+
        /**
         * Get the object representing the state of the entire model and items
         *
         * @return {Object} Object representing the state of the model and items
         */
        mw.rcfilters.dm.SavedQueriesModel.prototype.getState = function () {
-               var obj = { queries: {} };
+               var model = this,
+                       obj = { queries: {}, version: '2' };
 
                // Translate the items to the saved object
                this.getItems().forEach( function ( item ) {
                        var itemState = item.getState();
 
+                       itemState.data = model.getMinimalParamList( itemState.data );
+
                        obj.queries[ item.getID() ] = itemState;
                } );
 
        mw.rcfilters.dm.SavedQueriesModel.prototype.getDefault = function () {
                return this.default;
        };
+
+       /**
+        * Check if the saved queries were converted
+        *
+        * @return {boolean} Saved queries were converted from the previous
+        *  version to the new version
+        */
+       mw.rcfilters.dm.SavedQueriesModel.prototype.isConverted = function () {
+               return this.converted;
+       };
 }( mediaWiki, jQuery ) );
index ed2a73f..685adb6 100644 (file)
@@ -21,6 +21,7 @@
                this.baseFilterState = {};
                this.uriProcessor = null;
                this.initializing = false;
+               this.wereSavedQueriesSaved = false;
 
                this.prevLoggedItems = [];
 
                // Initialize the model
                this.filtersModel.initializeFilters( filterStructure, views );
 
-               this._buildBaseFilterState();
-
                this.uriProcessor = new mw.rcfilters.UriProcessor(
                        this.filtersModel
                );
                                parsedSavedQueries = {};
                        }
 
-                       // The queries are saved in a minimized state, so we need
-                       // to send over the base state so the saved queries model
-                       // can normalize them per each query item
-                       this.savedQueriesModel.initialize(
-                               parsedSavedQueries,
-                               this._getBaseFilterState(),
-                               // This is for backwards compatibility - delete all excluded filter states
-                               Object.keys( this.filtersModel.getExcludedFiltersState() )
-                       );
+                       // Initialize saved queries
+                       this.savedQueriesModel.initialize( parsedSavedQueries );
+                       if ( this.savedQueriesModel.isConverted() ) {
+                               // Since we know we converted, we're going to re-save
+                               // the queries so they are now migrated to the new format
+                               this._saveSavedQueries();
+                       }
                }
 
                // Check whether we need to load defaults.
         * @return {boolean} Defaults are all false
         */
        mw.rcfilters.Controller.prototype.areDefaultsEmpty = function () {
-               var defaultFilters = this.filtersModel.getFiltersFromParameters( this._getDefaultParams() );
+               var defaultParams = this._getDefaultParams(),
+                       defaultFilters = this.filtersModel.getFiltersFromParameters( defaultParams );
 
                this._deleteExcludedValuesFromFilterState( defaultFilters );
 
+               if ( Object.keys( defaultParams ).some( function ( paramName ) {
+                       return paramName.endsWith( '_color' ) && defaultParams[ paramName ] !== null;
+               } ) ) {
+                       // There are highlights in the defaults, they're definitely
+                       // not empty
+                       return false;
+               }
+
                // Defaults can change in a session, so we need to do this every time
                return Object.keys( defaultFilters ).every( function ( filterName ) {
                        return !defaultFilters[ filterName ];
         * @param {boolean} [setAsDefault=false] This query should be set as the default
         */
        mw.rcfilters.Controller.prototype.saveCurrentQuery = function ( label, setAsDefault ) {
-               var queryID,
-                       highlightedItems = {},
+               var highlightedItems = {},
                        highlightEnabled = this.filtersModel.isHighlightEnabled(),
                        selectedState = this.filtersModel.getSelectedState();
 
                // Prepare highlights
                this.filtersModel.getHighlightedItems().forEach( function ( item ) {
-                       highlightedItems[ item.getName() ] = highlightEnabled ?
+                       highlightedItems[ item.getName() + '_color' ] = highlightEnabled ?
                                item.getHighlightColor() : null;
                } );
-               // These are filter states; highlight is stored as boolean
-               highlightedItems.highlight = this.filtersModel.isHighlightEnabled();
 
                // Delete all excluded filters
                this._deleteExcludedValuesFromFilterState( selectedState );
 
                // Add item
-               queryID = this.savedQueriesModel.addNewQuery(
+               this.savedQueriesModel.addNewQuery(
                        label || mw.msg( 'rcfilters-savedqueries-defaultlabel' ),
                        {
-                               filters: selectedState,
-                               highlights: highlightedItems,
-                               invert: this.filtersModel.areNamespacesInverted()
-                       }
+                               params: $.extend(
+                                       true,
+                                       {
+                                               invert: String( Number( this.filtersModel.areNamespacesInverted() ) ),
+                                               highlight: String( Number( this.filtersModel.isHighlightEnabled() ) )
+                                       },
+                                       this.filtersModel.getParametersFromFilters( selectedState )
+                               ),
+                               highlights: highlightedItems
+                       },
+                       setAsDefault
                );
 
-               if ( setAsDefault ) {
-                       this.savedQueriesModel.setDefault( queryID );
-               }
-
                // Save item
                this._saveSavedQueries();
        };
         * @param {string} queryID Query id
         */
        mw.rcfilters.Controller.prototype.applySavedQuery = function ( queryID ) {
-               var data, highlights,
+               var highlights,
                        queryItem = this.savedQueriesModel.getItemByID( queryID ),
+                       data = this.savedQueriesModel.getItemFullData( queryID ),
                        currentMatchingQuery = this.findQueryMatchingCurrentState();
 
                if (
                                currentMatchingQuery.getID() !== queryItem.getID()
                        )
                ) {
-                       data = queryItem.getData();
                        highlights = data.highlights;
 
-                       // Backwards compatibility; initial version mispelled 'highlight' with 'highlights'
-                       highlights.highlight = highlights.highlights || highlights.highlight;
-
                        // Update model state from filters
                        this.filtersModel.toggleFiltersSelected(
                                // Merge filters with excluded values
-                               $.extend( true, {}, data.filters, this.filtersModel.getExcludedFiltersState() )
+                               $.extend(
+                                       true,
+                                       {},
+                                       this.filtersModel.getFiltersFromParameters( data.params ),
+                                       this.filtersModel.getExcludedFiltersState()
+                               )
                        );
 
                        // Update namespace inverted property
-                       this.filtersModel.toggleInvertedNamespaces( !!Number( data.invert ) );
+                       this.filtersModel.toggleInvertedNamespaces( !!Number( data.params.invert ) );
 
                        // Update highlight state
-                       this.filtersModel.toggleHighlight( !!Number( highlights.highlight ) );
+                       this.filtersModel.toggleHighlight( !!Number( data.params.highlight ) );
                        this.filtersModel.getItems().forEach( function ( filterItem ) {
-                               var color = highlights[ filterItem.getName() ];
+                               var color = highlights[ filterItem.getName() + '_color' ];
                                if ( color ) {
                                        filterItem.setHighlightColor( color );
                                } else {
 
                // Prepare highlights of the current query
                this.filtersModel.getItemsSupportingHighlights().forEach( function ( item ) {
-                       highlightedItems[ item.getName() ] = item.getHighlightColor();
+                       highlightedItems[ item.getName() + '_color' ] = item.getHighlightColor();
                } );
-               highlightedItems.highlight = this.filtersModel.isHighlightEnabled();
 
                // Remove anything that should be excluded from the saved query
                // this includes sticky filters and filters marked with 'excludedFromSavedQueries'
 
                return this.savedQueriesModel.findMatchingQuery(
                        {
-                               filters: selectedState,
-                               highlights: highlightedItems,
-                               invert: this.filtersModel.areNamespacesInverted()
+                               params: $.extend(
+                                       true,
+                                       {
+                                               highlight: String( Number( this.filtersModel.isHighlightEnabled() ) ),
+                                               invert: String( Number( this.filtersModel.areNamespacesInverted() ) )
+                                       },
+                                       this.filtersModel.getParametersFromFilters( selectedState )
+                               ),
+                               highlights: highlightedItems
                        }
                );
        };
                } );
        };
 
-       /**
-        * Get an object representing the base state of parameters
-        * and highlights.
-        *
-        * This is meant to make sure that the saved queries that are
-        * in memory are always the same structure as what we would get
-        * by calling the current model's "getSelectedState" and by checking
-        * highlight items.
-        *
-        * In cases where a user saved a query when the system had a certain
-        * set of filters, and then a filter was added to the system, we want
-        * to make sure that the stored queries can still be comparable to
-        * the current state, which means that we need the base state for
-        * two operations:
-        *
-        * - Saved queries are stored in "minimal" view (only changed filters
-        *   are stored); When we initialize the system, we merge each minimal
-        *   query with the base state (using 'getNormalizedFilters') so all
-        *   saved queries have the exact same structure as what we would get
-        *   by checking the getSelectedState of the filter.
-        * - When we save the queries, we minimize the object to only represent
-        *   whatever has actually changed, rather than store the entire
-        *   object. To check what actually is different so we can store it,
-        *   we need to obtain a base state to compare against, this is
-        *   what #_getMinimalFilterList does
-        */
-       mw.rcfilters.Controller.prototype._buildBaseFilterState = function () {
-               var defaultParams = this.filtersModel.getDefaultParams(),
-                       highlightedItems = {};
-
-               // Prepare highlights
-               this.filtersModel.getItemsSupportingHighlights().forEach( function ( item ) {
-                       highlightedItems[ item.getName() ] = null;
-               } );
-               highlightedItems.highlight = false;
-
-               this.baseFilterState = {
-                       filters: this.filtersModel.getFiltersFromParameters( defaultParams ),
-                       highlights: highlightedItems,
-                       invert: false
-               };
-       };
-
-       /**
-        * Get an object representing the base filter state of both
-        * filters and highlights. The structure is similar to what we use
-        * to store each query in the saved queries object:
-        * {
-        *    filters: {
-        *        filterName: (bool)
-        *    },
-        *    highlights: {
-        *        filterName: (string|null)
-        *    }
-        * }
-        *
-        * @return {Object} Object representing the base state of
-        *  parameters and highlights
-        */
-       mw.rcfilters.Controller.prototype._getBaseFilterState = function () {
-               return this.baseFilterState;
-       };
-
-       /**
-        * Get an object that holds only the parameters and highlights that have
-        * values different than the base default value.
-        *
-        * This is the reverse of the normalization we do initially on loading and
-        * initializing the saved queries model.
-        *
-        * @param {Object} valuesObject Object representing the state of both
-        *  filters and highlights in its normalized version, to be minimized.
-        * @return {Object} Minimal filters and highlights list
-        */
-       mw.rcfilters.Controller.prototype._getMinimalFilterList = function ( valuesObject ) {
-               var result = { filters: {}, highlights: {}, invert: valuesObject.invert },
-                       baseState = this._getBaseFilterState();
-
-               // XOR results
-               $.each( valuesObject.filters, function ( name, value ) {
-                       if ( baseState.filters !== undefined && baseState.filters[ name ] !== value ) {
-                               result.filters[ name ] = value;
-                       }
-               } );
-
-               $.each( valuesObject.highlights, function ( name, value ) {
-                       if ( baseState.highlights !== undefined && baseState.highlights[ name ] !== value ) {
-                               result.highlights[ name ] = value;
-                       }
-               } );
-
-               return result;
-       };
-
        /**
         * Save the current state of the saved queries model with all
         * query item representation in the user settings.
         */
        mw.rcfilters.Controller.prototype._saveSavedQueries = function () {
-               var stringified,
-                       state = this.savedQueriesModel.getState(),
-                       controller = this;
-
-               // Minimize before save
-               $.each( state.queries, function ( queryID, info ) {
-                       state.queries[ queryID ].data = controller._getMinimalFilterList( info.data );
-               } );
+               var stringified, oldPrefValue,
+                       backupPrefName = this.savedQueriesPreferenceName + '-versionbackup',
+                       state = this.savedQueriesModel.getState();
 
                // Stringify state
                stringified = JSON.stringify( state );
                        return;
                }
 
+               if ( !this.wereSavedQueriesSaved && this.savedQueriesModel.isConverted() ) {
+                       // The queries were converted from the previous version
+                       // Keep the old string in the [prefname]-versionbackup
+                       oldPrefValue = mw.user.options.get( this.savedQueriesPreferenceName );
+
+                       // Save the old preference in the backup preference
+                       new mw.Api().saveOption( backupPrefName, oldPrefValue );
+                       // Update the preference for this session
+                       mw.user.options.set( backupPrefName, oldPrefValue );
+               }
+
                // Save the preference
                new mw.Api().saveOption( this.savedQueriesPreferenceName, stringified );
                // Update the preference for this session
                mw.user.options.set( this.savedQueriesPreferenceName, stringified );
+
+               // Tag as already saved so we don't do this again
+               this.wereSavedQueriesSaved = true;
        };
 
        /**
         * @return {Object} Default parameters
         */
        mw.rcfilters.Controller.prototype._getDefaultParams = function () {
-               var data, queryHighlights,
-                       savedParams = {},
-                       savedHighlights = {},
-                       defaultSavedQueryItem = !mw.user.isAnon() && this.savedQueriesModel.getItemByID( this.savedQueriesModel.getDefault() );
-
-               if ( defaultSavedQueryItem ) {
-                       data = defaultSavedQueryItem.getData();
-
-                       queryHighlights = data.highlights || {};
-                       savedParams = this.filtersModel.getParametersFromFilters(
-                               $.extend( true, {}, data.filters, this.filtersModel.getStickyFiltersState() )
+               var savedFilters,
+                       data = ( !mw.user.isAnon() && this.savedQueriesModel.getItemFullData( this.savedQueriesModel.getDefault() ) ) || {};
+
+               if ( !$.isEmptyObject( data ) ) {
+                       // Merge saved filter state with sticky filter values
+                       savedFilters = $.extend(
+                               true, {},
+                               this.filtersModel.getFiltersFromParameters( data.params ),
+                               this.filtersModel.getStickyFiltersState()
                        );
 
-                       // Translate highlights to parameters
-                       savedHighlights.highlight = String( Number( queryHighlights.highlight ) );
-                       $.each( queryHighlights, function ( filterName, color ) {
-                               if ( filterName !== 'highlights' ) {
-                                       savedHighlights[ filterName + '_color' ] = color;
-                               }
-                       } );
-
-                       return $.extend( true, {}, savedParams, savedHighlights, { invert: String( Number( data.invert || 0 ) ) } );
+                       // Return parameter representation
+                       return $.extend( true, {},
+                               this.filtersModel.getParametersFromFilters( savedFilters ),
+                               data.highlights,
+                               { highlight: data.params.highlight, invert: data.params.invert }
+                       );
                }
-
                return this.filtersModel.getDefaultParams();
        };
 
index 73259f6..b11322e 100644 (file)
@@ -15,7 +15,7 @@
                                savedQueriesPreferenceName = mw.config.get( 'wgStructuredChangeFiltersSavedQueriesPreferenceName' ),
                                filtersModel = new mw.rcfilters.dm.FiltersViewModel(),
                                changesListModel = new mw.rcfilters.dm.ChangesListViewModel(),
-                               savedQueriesModel = new mw.rcfilters.dm.SavedQueriesModel(),
+                               savedQueriesModel = new mw.rcfilters.dm.SavedQueriesModel( filtersModel ),
                                controller = new mw.rcfilters.Controller(
                                        filtersModel, changesListModel, savedQueriesModel,
                                        {
index d9c42ba..83fe189 100644 (file)
@@ -2,12 +2,19 @@
 
 .mw-rcfilters-ui-filterMenuHeaderWidget {
        &-title {
+               display: inline-block;
                font-size: 1.2em;
-               padding: 0.75em 0.5em;
+               padding: 0.75em 0 0.75em 0.5em;
                // TODO: Unify colors with official design palette
                color: #54595d;
        }
 
+       &-helpIcon {
+               position: absolute;
+               top: 50%;
+               .transform( translateY( -50% ) );
+       }
+
        &-header {
                border-bottom: 1px solid #c8ccd1;
                background: #f8f9fa;
@@ -29,6 +36,7 @@
                }
 
                &-title {
+                       position: relative;
                        width: 100%;
                        vertical-align: middle;
                }
index e7233a8..4ecc22e 100644 (file)
@@ -1,4 +1,5 @@
 @import 'mediawiki.mixins';
+@import 'mediawiki.ui/variables';
 
 .mw-rcfilters-ui-filterTagMultiselectWidget {
        max-width: none;
 
                                .oo-ui-labelElement.oo-ui-optionWidget.oo-ui-buttonElement:first-child {
                                        margin-left: 0;
+
+                                       .oo-ui-labelElement-label {
+                                               color: @colorGray5;
+                                               font-weight: bold;
+                                       }
                                }
                        }
                }
index eeb5ddc..1a0c5ff 100644 (file)
                } );
                this.backButton.toggle( this.model.getCurrentView() !== 'default' );
 
+               // Help icon for Tagged edits
+               this.helpIcon = new OO.ui.ButtonWidget( {
+                       icon: 'help',
+                       framed: false,
+                       title: mw.msg( 'rcfilters-view-tags-help-icon-tooltip' ),
+                       classes: [ 'mw-rcfilters-ui-filterMenuHeaderWidget-helpIcon' ],
+                       href: 'https://www.mediawiki.org/wiki/Special:MyLanguage/Help:New_filters_for_edit_review/Advanced_filters#tags',
+                       target: '_blank'
+               } );
+               this.helpIcon.toggle( this.model.getCurrentView() === 'tags' );
+
                // Highlight button
                this.highlightButton = new OO.ui.ToggleButtonWidget( {
                        icon: 'highlight',
@@ -80,7 +91,7 @@
                                                                $( '<div>' )
                                                                        .addClass( 'mw-rcfilters-ui-cell' )
                                                                        .addClass( 'mw-rcfilters-ui-filterMenuHeaderWidget-header-title' )
-                                                                       .append( this.$label ),
+                                                                       .append( this.$label, this.helpIcon.$element ),
                                                                $( '<div>' )
                                                                        .addClass( 'mw-rcfilters-ui-cell' )
                                                                        .addClass( 'mw-rcfilters-ui-filterMenuHeaderWidget-header-invert' )
 
                this.invertNamespacesButton.toggle( currentView === 'namespaces' );
                this.backButton.toggle( currentView !== 'default' );
+               this.helpIcon.toggle( currentView === 'tags' );
        };
 
        /**
index 8d88410..491a1ff 100644 (file)
@@ -2,57 +2,60 @@
  * JavaScript for Special:Block
  */
 ( function ( mw, $ ) {
+       // Like OO.ui.infuse(), but if the element doesn't exist, return null instead of throwing an exception.
+       function infuseOrNull( elem ) {
+               try {
+                       return OO.ui.infuse( elem );
+               } catch ( er ) {
+                       return null;
+               }
+       }
+
        $( function () {
-               var $blockTarget = $( '#mw-bi-target' ),
-                       $anonOnlyRow = $( '#mw-input-wpHardBlock' ).closest( 'tr' ),
-                       $enableAutoblockRow = $( '#mw-input-wpAutoBlock' ).closest( 'tr' ),
-                       $hideUser = $( '#mw-input-wpHideUser' ).closest( 'tr' ),
-                       $watchUser = $( '#mw-input-wpWatch' ).closest( 'tr' ),
-                       $expiry = $( '#mw-input-wpExpiry' ),
-                       $otherExpiry = $( '#mw-input-wpExpiry-other' );
+               // This code is also loaded on the "block succeeded" page where there is no form,
+               // so username and expiry fields might also be missing.
+               var blockTargetWidget = infuseOrNull( 'mw-bi-target' ),
+                       anonOnlyField = infuseOrNull( $( '#mw-input-wpHardBlock' ).closest( '.oo-ui-fieldLayout' ) ),
+                       enableAutoblockField = infuseOrNull( $( '#mw-input-wpAutoBlock' ).closest( '.oo-ui-fieldLayout' ) ),
+                       hideUserField = infuseOrNull( $( '#mw-input-wpHideUser' ).closest( '.oo-ui-fieldLayout' ) ),
+                       watchUserField = infuseOrNull( $( '#mw-input-wpWatch' ).closest( '.oo-ui-fieldLayout' ) ),
+                       // mw.widgets.SelectWithInputWidget
+                       expiryWidget = infuseOrNull( 'mw-input-wpExpiry' );
 
-               function updateBlockOptions( instant ) {
-                       var blocktarget = $.trim( $blockTarget.val() ),
+               function updateBlockOptions() {
+                       var blocktarget = $.trim( blockTargetWidget.getValue() ),
                                isEmpty = blocktarget === '',
                                isIp = mw.util.isIPAddress( blocktarget, true ),
                                isIpRange = isIp && blocktarget.match( /\/\d+$/ ),
                                isNonEmptyIp = isIp && !isEmpty,
-                               expiryValue = $expiry.val(),
+                               expiryValue = expiryWidget.dropdowninput.getValue(),
                                // infinityValues  are the values the SpecialBlock class accepts as infinity (sf. wfIsInfinity)
                                infinityValues = [ 'infinite', 'indefinite', 'infinity', 'never' ],
                                isIndefinite = $.inArray( expiryValue, infinityValues ) !== -1 ||
-                                       ( expiryValue === 'other' && $.inArray( $otherExpiry.val(), infinityValues ) !== -1 );
+                                       ( expiryValue === 'other' && $.inArray( expiryWidget.textinput.getValue(), infinityValues ) !== -1 );
 
-                       if ( isNonEmptyIp ) {
-                               $enableAutoblockRow.goOut( instant );
-                       } else {
-                               $enableAutoblockRow.goIn( instant );
+                       if ( enableAutoblockField ) {
+                               enableAutoblockField.toggle( !( isNonEmptyIp ) );
                        }
-                       if ( isNonEmptyIp || !isIndefinite ) {
-                               $hideUser.goOut( instant );
-                       } else {
-                               $hideUser.goIn( instant );
+                       if ( hideUserField ) {
+                               hideUserField.toggle( !( isNonEmptyIp || !isIndefinite ) );
                        }
-                       if ( !isIp && !isEmpty ) {
-                               $anonOnlyRow.goOut( instant );
-                       } else {
-                               $anonOnlyRow.goIn( instant );
+                       if ( anonOnlyField ) {
+                               anonOnlyField.toggle( !( !isIp && !isEmpty ) );
                        }
-                       if ( isIpRange && !isEmpty ) {
-                               $watchUser.goOut( instant );
-                       } else {
-                               $watchUser.goIn( instant );
+                       if ( watchUserField ) {
+                               watchUserField.toggle( !( isIpRange && !isEmpty ) );
                        }
                }
 
-               if ( $blockTarget.length ) {
+               if ( blockTargetWidget ) {
                        // Bind functions so they're checked whenever stuff changes
-                       $blockTarget.keyup( updateBlockOptions );
-                       $expiry.change( updateBlockOptions );
-                       $otherExpiry.keyup( updateBlockOptions );
+                       blockTargetWidget.on( 'change', updateBlockOptions );
+                       expiryWidget.dropdowninput.on( 'change', updateBlockOptions );
+                       expiryWidget.textinput.on( 'change', updateBlockOptions );
 
                        // Call them now to set initial state (ie. Special:Block/Foobar?wpBlockExpiry=2+hours)
-                       updateBlockOptions( /* instant= */ true );
+                       updateBlockOptions();
                }
        } );
 }( mediaWiki, jQuery ) );
index 9ea8019..7f3b09a 100644 (file)
        text-align: right;
 }
 
-label[for='mw-input-wpConfirm'] {
+.mw-block-hideuser,
+.mw-block-confirm {
        font-weight: bold;
 }
 
-.mw-block-hideuser {
-       font-weight: bold;
+#mw-input-wpReason .oo-ui-dropdownInputWidget,
+#mw-input-wpReason .oo-ui-textInputWidget {
+       display: block;
+       max-width: 50em;
+}
+
+#mw-input-wpReason .oo-ui-textInputWidget {
+       margin-top: 0.5em;
 }
 
 /* Special:BlockList */
index 08997aa..8707bfa 100644 (file)
                var items = [],
                        self = this;
 
-               // mw.widgets.TitleWidget does a lot more work here, because the TitleOptionWidgets can
-               // differ a lot, depending on the returned data from the request. With the request used here
-               // we get only the search results.
                $.each( data.data[ 1 ], function ( i, result ) {
                        items.push( new mw.widgets.TitleOptionWidget(
-                               // data[ 3 ][ i ] is the link for this result
-                               self.getOptionWidgetData( result, null, data.data[ 3 ][ i ] )
+                               self.getOptionWidgetData(
+                                       result,
+                                       // Create a result object that looks like the one from
+                                       // the parent's API query.
+                                       {
+                                               data: result,
+                                               // data[ 3 ][ i ] is the link for this result
+                                               url: data.data[ 3 ][ i ],
+                                               imageUrl: null,
+                                               description: null,
+                                               missing: false,
+                                               redirect: false,
+                                               disambiguation: false
+                                       }
+                               )
                        ) );
                } );
 
                return items;
        };
 
-       /**
-        * @inheritdoc mw.widgets.TitleWidget
-        *
-        * @param {string} title
-        * @param {Object} data
-        * @param {string} url The Url to the result
-        */
-       mw.widgets.SearchInputWidget.prototype.getOptionWidgetData = function ( title, data, url ) {
-               // the values used in mw.widgets-TitleWidget doesn't exist here, that's why
-               // the values are hard-coded here
-               return {
-                       data: title,
-                       url: url,
-                       imageUrl: null,
-                       description: null,
-                       missing: false,
-                       redirect: false,
-                       disambiguation: false,
-                       query: this.getQueryValue()
-               };
-       };
-
        /**
         * @inheritdoc
         */
index 0f1815b..638f461 100644 (file)
@@ -16,6 +16,7 @@
         * @param {Object} config Configuration options
         * @cfg {string} data Label to display
         * @cfg {string} url URL of page
+        * @cfg {boolean} [showImages] Whether to attempt to show images
         * @cfg {string} [imageUrl] Thumbnail image URL with URL encoding
         * @cfg {string} [description] Page description
         * @cfg {boolean} [missing] Page doesn't exist
@@ -26,7 +27,9 @@
        mw.widgets.TitleOptionWidget = function MwWidgetsTitleOptionWidget( config ) {
                var icon;
 
-               if ( config.missing ) {
+               if ( !config.showImages ) {
+                       icon = null;
+               } else if ( config.missing ) {
                        icon = 'page-not-found';
                } else if ( config.redirect ) {
                        icon = 'page-redirect';
@@ -78,7 +81,7 @@
                        this.$label.addClass( 'mw-disambig' );
                }
 
-               if ( config.imageUrl ) {
+               if ( config.showImages && config.imageUrl ) {
                        this.$icon
                                .addClass( 'mw-widget-titleOptionWidget-hasImage' )
                                .css( 'background-image', 'url(' + config.imageUrl + ')' );
index 8e7afd7..5fe094f 100644 (file)
                                mwTitle.getRelativeText( this.namespace ) :
                                title,
                        url: mwTitle.getUrl(),
+                       showImages: this.showImages,
                        imageUrl: this.showImages ? data.imageUrl : null,
                        description: this.showDescriptions ? description : null,
                        missing: data.missing,
index 3632a42..be3c10e 100644 (file)
@@ -9,8 +9,6 @@
 .mw-widget-titleWidget-menu {
        .mw-widget-titleOptionWidget {
                line-height: normal;
-               padding-top: 0.5em;
-               padding-bottom: 0.5em;
 
                &-description {
                        color: #72777d;
@@ -22,6 +20,8 @@
                        .box-sizing( border-box );
                        min-height: 3.75em;
                        padding-left: 4.75em;
+                       padding-top: 0.5em;
+                       padding-bottom: 0.5em;
 
                        &:not( :last-child ) {
                                margin-bottom: 2px;
index 1c1150e..e7859cf 100644 (file)
@@ -2,6 +2,12 @@
  * Add search suggestions to the search form.
  */
 ( function ( mw, $ ) {
+       var searchNS = $.map( mw.config.get( 'wgFormattedNamespaces' ), function ( nsName, nsID ) {
+               if ( nsID >= 0 && mw.user.options.get( 'searchNs' + nsID ) ) {
+                       // Cast string key to number
+                       return Number( nsID );
+               }
+       } );
        mw.searchSuggest = {
                // queries the wiki and calls response with the result
                request: function ( api, query, response, maxRows, namespace ) {
@@ -9,7 +15,7 @@
                                formatversion: 2,
                                action: 'opensearch',
                                search: query,
-                               namespace: namespace || 0,
+                               namespace: namespace || searchNS,
                                limit: maxRows,
                                suggest: true
                        } ).done( function ( data, jqXHR ) {
index eaae9dc..f75d67d 100644 (file)
@@ -275,6 +275,12 @@ class ResourceLoaderClientHtmlTest extends PHPUnit_Framework_TestCase {
                                'only' => ResourceLoaderModule::TYPE_SCRIPTS,
                                'output' => '<script async="" src="/w/load.php?debug=false&amp;lang=nl&amp;modules=test.scripts.raw&amp;only=scripts&amp;skin=fallback"></script>',
                        ],
+                       [
+                               'context' => [ 'sync' => true ],
+                               'modules' => [ 'test.scripts.raw' ],
+                               'only' => ResourceLoaderModule::TYPE_SCRIPTS,
+                               'output' => '<script src="/w/load.php?debug=false&amp;lang=nl&amp;modules=test.scripts.raw&amp;only=scripts&amp;skin=fallback&amp;sync=1"></script>',
+                       ],
                        [
                                'context' => [],
                                'modules' => [ 'test.scripts.user' ],
@@ -360,7 +366,7 @@ class ResourceLoaderClientHtmlTest extends PHPUnit_Framework_TestCase {
        public function testMakeLoad( array $extraQuery, array $modules, $type, $expected ) {
                $context = self::makeContext( $extraQuery );
                $context->getResourceLoader()->register( self::makeSampleModules() );
-               $actual = ResourceLoaderClientHtml::makeLoad( $context, $modules, $type );
+               $actual = ResourceLoaderClientHtml::makeLoad( $context, $modules, $type, $extraQuery );
                $expected = self::expandVariables( $expected );
                $this->assertEquals( $expected, (string)$actual );
        }
index 2fba76b..d31779d 100644 (file)
@@ -44,15 +44,24 @@ class ResourcesTest extends MediaWikiTestCase {
        }
 
        /**
-        * Verify that nothing explicitly depends on the 'jquery' and 'mediawiki' modules.
-        * They are always loaded, depending on them is unsupported and leads to unexpected behaviour.
+        * Verify that nothing explicitly depends on base modules, or other raw modules.
+        *
+        * Depending on them is unsupported as they are not registered client-side by the startup module.
+        *
         * TODO Modules can dynamically choose dependencies based on context. This method does not
         * test such dependencies. The same goes for testMissingDependencies() and
         * testUnsatisfiableDependencies().
         */
        public function testIllegalDependencies() {
                $data = self::getAllModules();
-               $illegalDeps = [ 'jquery', 'mediawiki' ];
+
+               $illegalDeps = ResourceLoaderStartupModule::getStartupModules();
+               foreach ( $data['modules'] as $moduleName => $module ) {
+                       if ( $module->isRaw() ) {
+                               $illegalDeps[] = $moduleName;
+                       }
+               }
+               $illegalDeps = array_unique( $illegalDeps );
 
                /** @var ResourceLoaderModule $module */
                foreach ( $data['modules'] as $moduleName => $module ) {
index 7367560..cd0ac15 100644 (file)
@@ -93,6 +93,8 @@ return [
                        'tests/qunit/suites/resources/mediawiki.special/mediawiki.special.recentchanges.test.js',
                        'tests/qunit/suites/resources/mediawiki.rcfilters/dm.FiltersViewModel.test.js',
                        'tests/qunit/suites/resources/mediawiki.rcfilters/dm.FilterItem.test.js',
+                       'tests/qunit/suites/resources/mediawiki.rcfilters/dm.SavedQueryItemModel.test.js',
+                       'tests/qunit/suites/resources/mediawiki.rcfilters/dm.SavedQueriesModel.test.js',
                        'tests/qunit/suites/resources/mediawiki.rcfilters/UriProcessor.test.js',
                        'tests/qunit/suites/resources/mediawiki/mediawiki.language.test.js',
                        'tests/qunit/suites/resources/mediawiki/mediawiki.cldr.test.js',
diff --git a/tests/qunit/suites/resources/mediawiki.rcfilters/dm.SavedQueriesModel.test.js b/tests/qunit/suites/resources/mediawiki.rcfilters/dm.SavedQueriesModel.test.js
new file mode 100644 (file)
index 0000000..324a652
--- /dev/null
@@ -0,0 +1,304 @@
+/* eslint-disable camelcase */
+( function ( mw ) {
+       var filterDefinition = [ {
+                       name: 'group1',
+                       type: 'send_unselected_if_any',
+                       filters: [
+                               // Note: The fact filter2 is default means that in the
+                               // filter representation, filter1 and filter3 are 'true'
+                               { name: 'filter1' },
+                               { name: 'filter2', default: true },
+                               { name: 'filter3' }
+                       ]
+               }, {
+                       name: 'group2',
+                       type: 'string_options',
+                       separator: ',',
+                       filters: [
+                               { name: 'filter4' },
+                               { name: 'filter5' },
+                               { name: 'filter6' }
+                       ]
+               }, {
+                       name: 'group3',
+                       type: 'boolean',
+                       isSticky: true,
+                       filters: [
+                               { name: 'group3option1' },
+                               { name: 'group3option2' },
+                               { name: 'group3option3' }
+                       ]
+               } ],
+               queriesFilterRepresentation = {
+                       queries: {
+                               1234: {
+                                       label: 'Item converted',
+                                       data: {
+                                               filters: {
+                                                       // - This value is true, but the original filter-representation
+                                                       // of the saved queries ran against defaults. Since filter1 was
+                                                       // set as default in the definition, the value would actually
+                                                       // not appear in the representation itself.
+                                                       // It is considered 'true', though, and should appear in the
+                                                       // converted result in its parameter representation.
+                                                       // >> group1__filter1: true,
+                                                       // - The reverse is true for filter3. Filter3 is set as default
+                                                       // but we don't want it in this representation of the saved query.
+                                                       // Since the filter representation ran against default values,
+                                                       // it will appear as 'false' value in this representation explicitly
+                                                       // and the resulting parameter representation should have that
+                                                       // as the result as well
+                                                       group1__filter3: false,
+                                                       group2__filter4: true,
+                                                       group3__group3option1: true
+                                               },
+                                               highlights: {
+                                                       highlight: true,
+                                                       filter1: 'c5',
+                                                       group3option1: 'c1'
+                                               },
+                                               invert: true
+                                       }
+                               }
+                       }
+               },
+               queriesParamRepresentation = {
+                       version: '2',
+                       queries: {
+                               1234: {
+                                       label: 'Item converted',
+                                       data: {
+                                               params: {
+                                                       // filter1 is 'true' so filter2 and filter3 are both '1'
+                                                       // in param representation
+                                                       filter2: '1', filter3: '1',
+                                                       // Group type string_options
+                                                       group2: 'filter4',
+                                                       // Note - Group3 is sticky, so it won't show in output
+                                                       // Invert/highlight toggles
+                                                       invert: '1',
+                                                       highlight: '1'
+                                               },
+                                               highlights: {
+                                                       filter1_color: 'c5',
+                                                       group3option1_color: 'c1'
+                                               }
+                                       }
+                               }
+                       }
+               };
+
+       QUnit.module( 'mediawiki.rcfilters - SavedQueriesModel' );
+
+       QUnit.test( 'Initializing queries', function ( assert ) {
+               var filtersModel = new mw.rcfilters.dm.FiltersViewModel(),
+                       queriesModel = new mw.rcfilters.dm.SavedQueriesModel( filtersModel ),
+                       exampleQueryStructure = {
+                               version: '2',
+                               default: '1234',
+                               queries: {
+                                       1234: {
+                                               label: 'Query 1234',
+                                               data: {
+                                                       params: {
+                                                               filter2: '1'
+                                                       },
+                                                       highlights: {
+                                                               filter5_color: 'c2'
+                                                       }
+                                               }
+                                       }
+                               }
+                       },
+                       cases = [
+                               {
+                                       input: {},
+                                       finalState: { version: '2', queries: {} },
+                                       msg: 'Empty initial query structure results in base saved queries structure.'
+                               },
+                               {
+                                       input: $.extend( true, {}, exampleQueryStructure ),
+                                       finalState: $.extend( true, {}, exampleQueryStructure ),
+                                       msg: 'Initialization of given query structure does not corrupt the structure.'
+                               },
+                               {
+                                       // Converting from old structure
+                                       input: $.extend( true, {}, queriesFilterRepresentation ),
+                                       finalState: $.extend( true, {}, queriesParamRepresentation ),
+                                       msg: 'Conversion from filter representation to parameters retains data.'
+                               },
+                               {
+                                       // Converting from old structure with default
+                                       input: $.extend( true, { default: '1234' }, queriesFilterRepresentation ),
+                                       finalState: $.extend( true, { default: '1234' }, queriesParamRepresentation ),
+                                       msg: 'Conversion from filter representation to parameters, with default set up, retains data.'
+                               },
+                               {
+                                       // New structure
+                                       input: $.extend( true, {}, queriesParamRepresentation ),
+                                       finalState: $.extend( true, {}, queriesParamRepresentation ),
+                                       msg: 'Parameter representation retains its queries structure'
+                               }
+                       ];
+
+               filtersModel.initializeFilters( filterDefinition );
+
+               cases.forEach( function ( testCase ) {
+                       queriesModel.initialize( testCase.input );
+                       assert.deepEqual(
+                               queriesModel.getState(),
+                               testCase.finalState,
+                               testCase.msg
+                       );
+               } );
+       } );
+
+       QUnit.test( 'Manipulating queries', function ( assert ) {
+               var id1, id2, item1, matchingItem,
+                       queriesStructure = {},
+                       filtersModel = new mw.rcfilters.dm.FiltersViewModel(),
+                       queriesModel = new mw.rcfilters.dm.SavedQueriesModel( filtersModel );
+
+               filtersModel.initializeFilters( filterDefinition );
+
+               // Start with an empty saved queries model
+               queriesModel.initialize( {} );
+
+               // Add items
+               id1 = queriesModel.addNewQuery(
+                       'New query 1',
+                       {
+                               params: {
+                                       group2: 'filter5',
+                                       highlight: '1'
+                               },
+                               highlights: {
+                                       filter1_color: 'c5',
+                                       group3option1_color: 'c1'
+                               }
+                       }
+               );
+               id2 = queriesModel.addNewQuery(
+                       'New query 2',
+                       {
+                               params: {
+                                       filter1: '1',
+                                       filter2: '1',
+                                       invert: '1'
+                               },
+                               highlights: {}
+                       }
+               );
+               item1 = queriesModel.getItemByID( id1 );
+
+               assert.equal(
+                       item1.getID(),
+                       id1,
+                       'Item created and its data retained successfully'
+               );
+
+               // NOTE: All other methods that the item itself returns are
+               // tested in the dm.SavedQueryItemModel.test.js file
+
+               // Build the query structure we expect per item
+               queriesStructure[ id1 ] = {
+                       label: 'New query 1',
+                       data: {
+                               params: {
+                                       group2: 'filter5',
+                                       highlight: '1'
+                               },
+                               highlights: {
+                                       filter1_color: 'c5',
+                                       group3option1_color: 'c1'
+                               }
+                       }
+               };
+               queriesStructure[ id2 ] = {
+                       label: 'New query 2',
+                       data: {
+                               params: {
+                                       filter1: '1',
+                                       filter2: '1',
+                                       invert: '1'
+                               },
+                               highlights: {}
+                       }
+               };
+
+               assert.deepEqual(
+                       queriesModel.getState(),
+                       {
+                               version: '2',
+                               queries: queriesStructure
+                       },
+                       'Full query represents current state of items'
+               );
+
+               // Add default
+               queriesModel.setDefault( id2 );
+
+               assert.deepEqual(
+                       queriesModel.getState(),
+                       {
+                               version: '2',
+                               default: id2,
+                               queries: queriesStructure
+                       },
+                       'Setting default is reflected in queries state'
+               );
+
+               // Remove default
+               queriesModel.setDefault( null );
+
+               assert.deepEqual(
+                       queriesModel.getState(),
+                       {
+                               version: '2',
+                               queries: queriesStructure
+                       },
+                       'Removing default is reflected in queries state'
+               );
+
+               // Find matching query
+               matchingItem = queriesModel.findMatchingQuery(
+                       {
+                               params: {
+                                       group2: 'filter5',
+                                       highlight: '1'
+                               },
+                               highlights: {
+                                       filter1_color: 'c5',
+                                       group3option1_color: 'c1'
+                               }
+                       }
+               );
+               assert.deepEqual(
+                       matchingItem.getID(),
+                       id1,
+                       'Finding matching item by identical state'
+               );
+
+               // Find matching query with 0-values (base state)
+               matchingItem = queriesModel.findMatchingQuery(
+                       {
+                               params: {
+                                       group2: 'filter5',
+                                       filter1: '0',
+                                       filter2: '0',
+                                       highlight: '1',
+                                       invert: '0'
+                               },
+                               highlights: {
+                                       filter1_color: 'c5',
+                                       group3option1_color: 'c1'
+                               }
+                       }
+               );
+               assert.deepEqual(
+                       matchingItem.getID(),
+                       id1,
+                       'Finding matching item by "dirty" state with 0-base values'
+               );
+       } );
+}( mediaWiki ) );
diff --git a/tests/qunit/suites/resources/mediawiki.rcfilters/dm.SavedQueryItemModel.test.js b/tests/qunit/suites/resources/mediawiki.rcfilters/dm.SavedQueryItemModel.test.js
new file mode 100644 (file)
index 0000000..a91dff9
--- /dev/null
@@ -0,0 +1,90 @@
+/* eslint-disable camelcase */
+( function ( mw ) {
+       var itemData = {
+               params: {
+                       param1: '1',
+                       param2: 'foo|bar',
+                       highlight: '1',
+                       invert: '0'
+               },
+               highlights: {
+                       param1_color: 'c1',
+                       param2_color: 'c2'
+               }
+       };
+
+       QUnit.module( 'mediawiki.rcfilters - SavedQueryItemModel' );
+
+       QUnit.test( 'Initializing and getters', function ( assert ) {
+               var model;
+
+               model = new mw.rcfilters.dm.SavedQueryItemModel(
+                       'randomID',
+                       'Some label',
+                       $.extend( true, {}, itemData )
+               );
+
+               assert.equal(
+                       model.getID(),
+                       'randomID',
+                       'Item ID is retained'
+               );
+
+               assert.equal(
+                       model.getLabel(),
+                       'Some label',
+                       'Item label is retained'
+               );
+
+               assert.deepEqual(
+                       model.getData(),
+                       itemData,
+                       'Item data is retained'
+               );
+
+               assert.ok(
+                       !model.isDefault(),
+                       'Item default state is retained.'
+               );
+       } );
+
+       QUnit.test( 'Default', function ( assert ) {
+               var model;
+
+               model = new mw.rcfilters.dm.SavedQueryItemModel(
+                       'randomID',
+                       'Some label',
+                       $.extend( true, {}, itemData )
+               );
+
+               assert.ok(
+                       !model.isDefault(),
+                       'Default state represented when item initialized with default:false.'
+               );
+
+               model.toggleDefault( true );
+               assert.ok(
+                       model.isDefault(),
+                       'Default state toggles to true successfully'
+               );
+
+               model.toggleDefault( false );
+               assert.ok(
+                       !model.isDefault(),
+                       'Default state toggles to false successfully'
+               );
+
+               // Reset
+               model = new mw.rcfilters.dm.SavedQueryItemModel(
+                       'randomID',
+                       'Some label',
+                       $.extend( true, {}, itemData ),
+                       { default: true }
+               );
+
+               assert.ok(
+                       model.isDefault(),
+                       'Default state represented when item initialized with default:true.'
+               );
+       } );
+}( mediaWiki ) );